ocf-20100325.patch 2.9 MB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105211062110721108211092111021111211122111321114211152111621117211182111921120211212112221123211242112521126211272112821129211302113121132211332113421135211362113721138211392114021141211422114321144211452114621147211482114921150211512115221153211542115521156211572115821159211602116121162211632116421165211662116721168211692117021171211722117321174211752117621177211782117921180211812118221183211842118521186211872118821189211902119121192211932119421195211962119721198211992120021201212022120321204212052120621207212082120921210212112121221213212142121521216212172121821219212202122121222212232122421225212262122721228212292123021231212322123321234212352123621237212382123921240212412124221243212442124521246212472124821249212502125121252212532125421255212562125721258212592126021261212622126321264212652126621267212682126921270212712127221273212742127521276212772127821279212802128121282212832128421285212862128721288212892129021291212922129321294212952129621297212982129921300213012130221303213042130521306213072130821309213102131121312213132131421315213162131721318213192132021321213222132321324213252132621327213282132921330213312133221333213342133521336213372133821339213402134121342213432134421345213462134721348213492135021351213522135321354213552135621357213582135921360213612136221363213642136521366213672136821369213702137121372213732137421375213762137721378213792138021381213822138321384213852138621387213882138921390213912139221393213942139521396213972139821399214002140121402214032140421405214062140721408214092141021411214122141321414214152141621417214182141921420214212142221423214242142521426214272142821429214302143121432214332143421435214362143721438214392144021441214422144321444214452144621447214482144921450214512145221453214542145521456214572145821459214602146121462214632146421465214662146721468214692147021471214722147321474214752147621477214782147921480214812148221483214842148521486214872148821489214902149121492214932149421495214962149721498214992150021501215022150321504215052150621507215082150921510215112151221513215142151521516215172151821519215202152121522215232152421525215262152721528215292153021531215322153321534215352153621537215382153921540215412154221543215442154521546215472154821549215502155121552215532155421555215562155721558215592156021561215622156321564215652156621567215682156921570215712157221573215742157521576215772157821579215802158121582215832158421585215862158721588215892159021591215922159321594215952159621597215982159921600216012160221603216042160521606216072160821609216102161121612216132161421615216162161721618216192162021621216222162321624216252162621627216282162921630216312163221633216342163521636216372163821639216402164121642216432164421645216462164721648216492165021651216522165321654216552165621657216582165921660216612166221663216642166521666216672166821669216702167121672216732167421675216762167721678216792168021681216822168321684216852168621687216882168921690216912169221693216942169521696216972169821699217002170121702217032170421705217062170721708217092171021711217122171321714217152171621717217182171921720217212172221723217242172521726217272172821729217302173121732217332173421735217362173721738217392174021741217422174321744217452174621747217482174921750217512175221753217542175521756217572175821759217602176121762217632176421765217662176721768217692177021771217722177321774217752177621777217782177921780217812178221783217842178521786217872178821789217902179121792217932179421795217962179721798217992180021801218022180321804218052180621807218082180921810218112181221813218142181521816218172181821819218202182121822218232182421825218262182721828218292183021831218322183321834218352183621837218382183921840218412184221843218442184521846218472184821849218502185121852218532185421855218562185721858218592186021861218622186321864218652186621867218682186921870218712187221873218742187521876218772187821879218802188121882218832188421885218862188721888218892189021891218922189321894218952189621897218982189921900219012190221903219042190521906219072190821909219102191121912219132191421915219162191721918219192192021921219222192321924219252192621927219282192921930219312193221933219342193521936219372193821939219402194121942219432194421945219462194721948219492195021951219522195321954219552195621957219582195921960219612196221963219642196521966219672196821969219702197121972219732197421975219762197721978219792198021981219822198321984219852198621987219882198921990219912199221993219942199521996219972199821999220002200122002220032200422005220062200722008220092201022011220122201322014220152201622017220182201922020220212202222023220242202522026220272202822029220302203122032220332203422035220362203722038220392204022041220422204322044220452204622047220482204922050220512205222053220542205522056220572205822059220602206122062220632206422065220662206722068220692207022071220722207322074220752207622077220782207922080220812208222083220842208522086220872208822089220902209122092220932209422095220962209722098220992210022101221022210322104221052210622107221082210922110221112211222113221142211522116221172211822119221202212122122221232212422125221262212722128221292213022131221322213322134221352213622137221382213922140221412214222143221442214522146221472214822149221502215122152221532215422155221562215722158221592216022161221622216322164221652216622167221682216922170221712217222173221742217522176221772217822179221802218122182221832218422185221862218722188221892219022191221922219322194221952219622197221982219922200222012220222203222042220522206222072220822209222102221122212222132221422215222162221722218222192222022221222222222322224222252222622227222282222922230222312223222233222342223522236222372223822239222402224122242222432224422245222462224722248222492225022251222522225322254222552225622257222582225922260222612226222263222642226522266222672226822269222702227122272222732227422275222762227722278222792228022281222822228322284222852228622287222882228922290222912229222293222942229522296222972229822299223002230122302223032230422305223062230722308223092231022311223122231322314223152231622317223182231922320223212232222323223242232522326223272232822329223302233122332223332233422335223362233722338223392234022341223422234322344223452234622347223482234922350223512235222353223542235522356223572235822359223602236122362223632236422365223662236722368223692237022371223722237322374223752237622377223782237922380223812238222383223842238522386223872238822389223902239122392223932239422395223962239722398223992240022401224022240322404224052240622407224082240922410224112241222413224142241522416224172241822419224202242122422224232242422425224262242722428224292243022431224322243322434224352243622437224382243922440224412244222443224442244522446224472244822449224502245122452224532245422455224562245722458224592246022461224622246322464224652246622467224682246922470224712247222473224742247522476224772247822479224802248122482224832248422485224862248722488224892249022491224922249322494224952249622497224982249922500225012250222503225042250522506225072250822509225102251122512225132251422515225162251722518225192252022521225222252322524225252252622527225282252922530225312253222533225342253522536225372253822539225402254122542225432254422545225462254722548225492255022551225522255322554225552255622557225582255922560225612256222563225642256522566225672256822569225702257122572225732257422575225762257722578225792258022581225822258322584225852258622587225882258922590225912259222593225942259522596225972259822599226002260122602226032260422605226062260722608226092261022611226122261322614226152261622617226182261922620226212262222623226242262522626226272262822629226302263122632226332263422635226362263722638226392264022641226422264322644226452264622647226482264922650226512265222653226542265522656226572265822659226602266122662226632266422665226662266722668226692267022671226722267322674226752267622677226782267922680226812268222683226842268522686226872268822689226902269122692226932269422695226962269722698226992270022701227022270322704227052270622707227082270922710227112271222713227142271522716227172271822719227202272122722227232272422725227262272722728227292273022731227322273322734227352273622737227382273922740227412274222743227442274522746227472274822749227502275122752227532275422755227562275722758227592276022761227622276322764227652276622767227682276922770227712277222773227742277522776227772277822779227802278122782227832278422785227862278722788227892279022791227922279322794227952279622797227982279922800228012280222803228042280522806228072280822809228102281122812228132281422815228162281722818228192282022821228222282322824228252282622827228282282922830228312283222833228342283522836228372283822839228402284122842228432284422845228462284722848228492285022851228522285322854228552285622857228582285922860228612286222863228642286522866228672286822869228702287122872228732287422875228762287722878228792288022881228822288322884228852288622887228882288922890228912289222893228942289522896228972289822899229002290122902229032290422905229062290722908229092291022911229122291322914229152291622917229182291922920229212292222923229242292522926229272292822929229302293122932229332293422935229362293722938229392294022941229422294322944229452294622947229482294922950229512295222953229542295522956229572295822959229602296122962229632296422965229662296722968229692297022971229722297322974229752297622977229782297922980229812298222983229842298522986229872298822989229902299122992229932299422995229962299722998229992300023001230022300323004230052300623007230082300923010230112301223013230142301523016230172301823019230202302123022230232302423025230262302723028230292303023031230322303323034230352303623037230382303923040230412304223043230442304523046230472304823049230502305123052230532305423055230562305723058230592306023061230622306323064230652306623067230682306923070230712307223073230742307523076230772307823079230802308123082230832308423085230862308723088230892309023091230922309323094230952309623097230982309923100231012310223103231042310523106231072310823109231102311123112231132311423115231162311723118231192312023121231222312323124231252312623127231282312923130231312313223133231342313523136231372313823139231402314123142231432314423145231462314723148231492315023151231522315323154231552315623157231582315923160231612316223163231642316523166231672316823169231702317123172231732317423175231762317723178231792318023181231822318323184231852318623187231882318923190231912319223193231942319523196231972319823199232002320123202232032320423205232062320723208232092321023211232122321323214232152321623217232182321923220232212322223223232242322523226232272322823229232302323123232232332323423235232362323723238232392324023241232422324323244232452324623247232482324923250232512325223253232542325523256232572325823259232602326123262232632326423265232662326723268232692327023271232722327323274232752327623277232782327923280232812328223283232842328523286232872328823289232902329123292232932329423295232962329723298232992330023301233022330323304233052330623307233082330923310233112331223313233142331523316233172331823319233202332123322233232332423325233262332723328233292333023331233322333323334233352333623337233382333923340233412334223343233442334523346233472334823349233502335123352233532335423355233562335723358233592336023361233622336323364233652336623367233682336923370233712337223373233742337523376233772337823379233802338123382233832338423385233862338723388233892339023391233922339323394233952339623397233982339923400234012340223403234042340523406234072340823409234102341123412234132341423415234162341723418234192342023421234222342323424234252342623427234282342923430234312343223433234342343523436234372343823439234402344123442234432344423445234462344723448234492345023451234522345323454234552345623457234582345923460234612346223463234642346523466234672346823469234702347123472234732347423475234762347723478234792348023481234822348323484234852348623487234882348923490234912349223493234942349523496234972349823499235002350123502235032350423505235062350723508235092351023511235122351323514235152351623517235182351923520235212352223523235242352523526235272352823529235302353123532235332353423535235362353723538235392354023541235422354323544235452354623547235482354923550235512355223553235542355523556235572355823559235602356123562235632356423565235662356723568235692357023571235722357323574235752357623577235782357923580235812358223583235842358523586235872358823589235902359123592235932359423595235962359723598235992360023601236022360323604236052360623607236082360923610236112361223613236142361523616236172361823619236202362123622236232362423625236262362723628236292363023631236322363323634236352363623637236382363923640236412364223643236442364523646236472364823649236502365123652236532365423655236562365723658236592366023661236622366323664236652366623667236682366923670236712367223673236742367523676236772367823679236802368123682236832368423685236862368723688236892369023691236922369323694236952369623697236982369923700237012370223703237042370523706237072370823709237102371123712237132371423715237162371723718237192372023721237222372323724237252372623727237282372923730237312373223733237342373523736237372373823739237402374123742237432374423745237462374723748237492375023751237522375323754237552375623757237582375923760237612376223763237642376523766237672376823769237702377123772237732377423775237762377723778237792378023781237822378323784237852378623787237882378923790237912379223793237942379523796237972379823799238002380123802238032380423805238062380723808238092381023811238122381323814238152381623817238182381923820238212382223823238242382523826238272382823829238302383123832238332383423835238362383723838238392384023841238422384323844238452384623847238482384923850238512385223853238542385523856238572385823859238602386123862238632386423865238662386723868238692387023871238722387323874238752387623877238782387923880238812388223883238842388523886238872388823889238902389123892238932389423895238962389723898238992390023901239022390323904239052390623907239082390923910239112391223913239142391523916239172391823919239202392123922239232392423925239262392723928239292393023931239322393323934239352393623937239382393923940239412394223943239442394523946239472394823949239502395123952239532395423955239562395723958239592396023961239622396323964239652396623967239682396923970239712397223973239742397523976239772397823979239802398123982239832398423985239862398723988239892399023991239922399323994239952399623997239982399924000240012400224003240042400524006240072400824009240102401124012240132401424015240162401724018240192402024021240222402324024240252402624027240282402924030240312403224033240342403524036240372403824039240402404124042240432404424045240462404724048240492405024051240522405324054240552405624057240582405924060240612406224063240642406524066240672406824069240702407124072240732407424075240762407724078240792408024081240822408324084240852408624087240882408924090240912409224093240942409524096240972409824099241002410124102241032410424105241062410724108241092411024111241122411324114241152411624117241182411924120241212412224123241242412524126241272412824129241302413124132241332413424135241362413724138241392414024141241422414324144241452414624147241482414924150241512415224153241542415524156241572415824159241602416124162241632416424165241662416724168241692417024171241722417324174241752417624177241782417924180241812418224183241842418524186241872418824189241902419124192241932419424195241962419724198241992420024201242022420324204242052420624207242082420924210242112421224213242142421524216242172421824219242202422124222242232422424225242262422724228242292423024231242322423324234242352423624237242382423924240242412424224243242442424524246242472424824249242502425124252242532425424255242562425724258242592426024261242622426324264242652426624267242682426924270242712427224273242742427524276242772427824279242802428124282242832428424285242862428724288242892429024291242922429324294242952429624297242982429924300243012430224303243042430524306243072430824309243102431124312243132431424315243162431724318243192432024321243222432324324243252432624327243282432924330243312433224333243342433524336243372433824339243402434124342243432434424345243462434724348243492435024351243522435324354243552435624357243582435924360243612436224363243642436524366243672436824369243702437124372243732437424375243762437724378243792438024381243822438324384243852438624387243882438924390243912439224393243942439524396243972439824399244002440124402244032440424405244062440724408244092441024411244122441324414244152441624417244182441924420244212442224423244242442524426244272442824429244302443124432244332443424435244362443724438244392444024441244422444324444244452444624447244482444924450244512445224453244542445524456244572445824459244602446124462244632446424465244662446724468244692447024471244722447324474244752447624477244782447924480244812448224483244842448524486244872448824489244902449124492244932449424495244962449724498244992450024501245022450324504245052450624507245082450924510245112451224513245142451524516245172451824519245202452124522245232452424525245262452724528245292453024531245322453324534245352453624537245382453924540245412454224543245442454524546245472454824549245502455124552245532455424555245562455724558245592456024561245622456324564245652456624567245682456924570245712457224573245742457524576245772457824579245802458124582245832458424585245862458724588245892459024591245922459324594245952459624597245982459924600246012460224603246042460524606246072460824609246102461124612246132461424615246162461724618246192462024621246222462324624246252462624627246282462924630246312463224633246342463524636246372463824639246402464124642246432464424645246462464724648246492465024651246522465324654246552465624657246582465924660246612466224663246642466524666246672466824669246702467124672246732467424675246762467724678246792468024681246822468324684246852468624687246882468924690246912469224693246942469524696246972469824699247002470124702247032470424705247062470724708247092471024711247122471324714247152471624717247182471924720247212472224723247242472524726247272472824729247302473124732247332473424735247362473724738247392474024741247422474324744247452474624747247482474924750247512475224753247542475524756247572475824759247602476124762247632476424765247662476724768247692477024771247722477324774247752477624777247782477924780247812478224783247842478524786247872478824789247902479124792247932479424795247962479724798247992480024801248022480324804248052480624807248082480924810248112481224813248142481524816248172481824819248202482124822248232482424825248262482724828248292483024831248322483324834248352483624837248382483924840248412484224843248442484524846248472484824849248502485124852248532485424855248562485724858248592486024861248622486324864248652486624867248682486924870248712487224873248742487524876248772487824879248802488124882248832488424885248862488724888248892489024891248922489324894248952489624897248982489924900249012490224903249042490524906249072490824909249102491124912249132491424915249162491724918249192492024921249222492324924249252492624927249282492924930249312493224933249342493524936249372493824939249402494124942249432494424945249462494724948249492495024951249522495324954249552495624957249582495924960249612496224963249642496524966249672496824969249702497124972249732497424975249762497724978249792498024981249822498324984249852498624987249882498924990249912499224993249942499524996249972499824999250002500125002250032500425005250062500725008250092501025011250122501325014250152501625017250182501925020250212502225023250242502525026250272502825029250302503125032250332503425035250362503725038250392504025041250422504325044250452504625047250482504925050250512505225053250542505525056250572505825059250602506125062250632506425065250662506725068250692507025071250722507325074250752507625077250782507925080250812508225083250842508525086250872508825089250902509125092250932509425095250962509725098250992510025101251022510325104251052510625107251082510925110251112511225113251142511525116251172511825119251202512125122251232512425125251262512725128251292513025131251322513325134251352513625137251382513925140251412514225143251442514525146251472514825149251502515125152251532515425155251562515725158251592516025161251622516325164251652516625167251682516925170251712517225173251742517525176251772517825179251802518125182251832518425185251862518725188251892519025191251922519325194251952519625197251982519925200252012520225203252042520525206252072520825209252102521125212252132521425215252162521725218252192522025221252222522325224252252522625227252282522925230252312523225233252342523525236252372523825239252402524125242252432524425245252462524725248252492525025251252522525325254252552525625257252582525925260252612526225263252642526525266252672526825269252702527125272252732527425275252762527725278252792528025281252822528325284252852528625287252882528925290252912529225293252942529525296252972529825299253002530125302253032530425305253062530725308253092531025311253122531325314253152531625317253182531925320253212532225323253242532525326253272532825329253302533125332253332533425335253362533725338253392534025341253422534325344253452534625347253482534925350253512535225353253542535525356253572535825359253602536125362253632536425365253662536725368253692537025371253722537325374253752537625377253782537925380253812538225383253842538525386253872538825389253902539125392253932539425395253962539725398253992540025401254022540325404254052540625407254082540925410254112541225413254142541525416254172541825419254202542125422254232542425425254262542725428254292543025431254322543325434254352543625437254382543925440254412544225443254442544525446254472544825449254502545125452254532545425455254562545725458254592546025461254622546325464254652546625467254682546925470254712547225473254742547525476254772547825479254802548125482254832548425485254862548725488254892549025491254922549325494254952549625497254982549925500255012550225503255042550525506255072550825509255102551125512255132551425515255162551725518255192552025521255222552325524255252552625527255282552925530255312553225533255342553525536255372553825539255402554125542255432554425545255462554725548255492555025551255522555325554255552555625557255582555925560255612556225563255642556525566255672556825569255702557125572255732557425575255762557725578255792558025581255822558325584255852558625587255882558925590255912559225593255942559525596255972559825599256002560125602256032560425605256062560725608256092561025611256122561325614256152561625617256182561925620256212562225623256242562525626256272562825629256302563125632256332563425635256362563725638256392564025641256422564325644256452564625647256482564925650256512565225653256542565525656256572565825659256602566125662256632566425665256662566725668256692567025671256722567325674256752567625677256782567925680256812568225683256842568525686256872568825689256902569125692256932569425695256962569725698256992570025701257022570325704257052570625707257082570925710257112571225713257142571525716257172571825719257202572125722257232572425725257262572725728257292573025731257322573325734257352573625737257382573925740257412574225743257442574525746257472574825749257502575125752257532575425755257562575725758257592576025761257622576325764257652576625767257682576925770257712577225773257742577525776257772577825779257802578125782257832578425785257862578725788257892579025791257922579325794257952579625797257982579925800258012580225803258042580525806258072580825809258102581125812258132581425815258162581725818258192582025821258222582325824258252582625827258282582925830258312583225833258342583525836258372583825839258402584125842258432584425845258462584725848258492585025851258522585325854258552585625857258582585925860258612586225863258642586525866258672586825869258702587125872258732587425875258762587725878258792588025881258822588325884258852588625887258882588925890258912589225893258942589525896258972589825899259002590125902259032590425905259062590725908259092591025911259122591325914259152591625917259182591925920259212592225923259242592525926259272592825929259302593125932259332593425935259362593725938259392594025941259422594325944259452594625947259482594925950259512595225953259542595525956259572595825959259602596125962259632596425965259662596725968259692597025971259722597325974259752597625977259782597925980259812598225983259842598525986259872598825989259902599125992259932599425995259962599725998259992600026001260022600326004260052600626007260082600926010260112601226013260142601526016260172601826019260202602126022260232602426025260262602726028260292603026031260322603326034260352603626037260382603926040260412604226043260442604526046260472604826049260502605126052260532605426055260562605726058260592606026061260622606326064260652606626067260682606926070260712607226073260742607526076260772607826079260802608126082260832608426085260862608726088260892609026091260922609326094260952609626097260982609926100261012610226103261042610526106261072610826109261102611126112261132611426115261162611726118261192612026121261222612326124261252612626127261282612926130261312613226133261342613526136261372613826139261402614126142261432614426145261462614726148261492615026151261522615326154261552615626157261582615926160261612616226163261642616526166261672616826169261702617126172261732617426175261762617726178261792618026181261822618326184261852618626187261882618926190261912619226193261942619526196261972619826199262002620126202262032620426205262062620726208262092621026211262122621326214262152621626217262182621926220262212622226223262242622526226262272622826229262302623126232262332623426235262362623726238262392624026241262422624326244262452624626247262482624926250262512625226253262542625526256262572625826259262602626126262262632626426265262662626726268262692627026271262722627326274262752627626277262782627926280262812628226283262842628526286262872628826289262902629126292262932629426295262962629726298262992630026301263022630326304263052630626307263082630926310263112631226313263142631526316263172631826319263202632126322263232632426325263262632726328263292633026331263322633326334263352633626337263382633926340263412634226343263442634526346263472634826349263502635126352263532635426355263562635726358263592636026361263622636326364263652636626367263682636926370263712637226373263742637526376263772637826379263802638126382263832638426385263862638726388263892639026391263922639326394263952639626397263982639926400264012640226403264042640526406264072640826409264102641126412264132641426415264162641726418264192642026421264222642326424264252642626427264282642926430264312643226433264342643526436264372643826439264402644126442264432644426445264462644726448264492645026451264522645326454264552645626457264582645926460264612646226463264642646526466264672646826469264702647126472264732647426475264762647726478264792648026481264822648326484264852648626487264882648926490264912649226493264942649526496264972649826499265002650126502265032650426505265062650726508265092651026511265122651326514265152651626517265182651926520265212652226523265242652526526265272652826529265302653126532265332653426535265362653726538265392654026541265422654326544265452654626547265482654926550265512655226553265542655526556265572655826559265602656126562265632656426565265662656726568265692657026571265722657326574265752657626577265782657926580265812658226583265842658526586265872658826589265902659126592265932659426595265962659726598265992660026601266022660326604266052660626607266082660926610266112661226613266142661526616266172661826619266202662126622266232662426625266262662726628266292663026631266322663326634266352663626637266382663926640266412664226643266442664526646266472664826649266502665126652266532665426655266562665726658266592666026661266622666326664266652666626667266682666926670266712667226673266742667526676266772667826679266802668126682266832668426685266862668726688266892669026691266922669326694266952669626697266982669926700267012670226703267042670526706267072670826709267102671126712267132671426715267162671726718267192672026721267222672326724267252672626727267282672926730267312673226733267342673526736267372673826739267402674126742267432674426745267462674726748267492675026751267522675326754267552675626757267582675926760267612676226763267642676526766267672676826769267702677126772267732677426775267762677726778267792678026781267822678326784267852678626787267882678926790267912679226793267942679526796267972679826799268002680126802268032680426805268062680726808268092681026811268122681326814268152681626817268182681926820268212682226823268242682526826268272682826829268302683126832268332683426835268362683726838268392684026841268422684326844268452684626847268482684926850268512685226853268542685526856268572685826859268602686126862268632686426865268662686726868268692687026871268722687326874268752687626877268782687926880268812688226883268842688526886268872688826889268902689126892268932689426895268962689726898268992690026901269022690326904269052690626907269082690926910269112691226913269142691526916269172691826919269202692126922269232692426925269262692726928269292693026931269322693326934269352693626937269382693926940269412694226943269442694526946269472694826949269502695126952269532695426955269562695726958269592696026961269622696326964269652696626967269682696926970269712697226973269742697526976269772697826979269802698126982269832698426985269862698726988269892699026991269922699326994269952699626997269982699927000270012700227003270042700527006270072700827009270102701127012270132701427015270162701727018270192702027021270222702327024270252702627027270282702927030270312703227033270342703527036270372703827039270402704127042270432704427045270462704727048270492705027051270522705327054270552705627057270582705927060270612706227063270642706527066270672706827069270702707127072270732707427075270762707727078270792708027081270822708327084270852708627087270882708927090270912709227093270942709527096270972709827099271002710127102271032710427105271062710727108271092711027111271122711327114271152711627117271182711927120271212712227123271242712527126271272712827129271302713127132271332713427135271362713727138271392714027141271422714327144271452714627147271482714927150271512715227153271542715527156271572715827159271602716127162271632716427165271662716727168271692717027171271722717327174271752717627177271782717927180271812718227183271842718527186271872718827189271902719127192271932719427195271962719727198271992720027201272022720327204272052720627207272082720927210272112721227213272142721527216272172721827219272202722127222272232722427225272262722727228272292723027231272322723327234272352723627237272382723927240272412724227243272442724527246272472724827249272502725127252272532725427255272562725727258272592726027261272622726327264272652726627267272682726927270272712727227273272742727527276272772727827279272802728127282272832728427285272862728727288272892729027291272922729327294272952729627297272982729927300273012730227303273042730527306273072730827309273102731127312273132731427315273162731727318273192732027321273222732327324273252732627327273282732927330273312733227333273342733527336273372733827339273402734127342273432734427345273462734727348273492735027351273522735327354273552735627357273582735927360273612736227363273642736527366273672736827369273702737127372273732737427375273762737727378273792738027381273822738327384273852738627387273882738927390273912739227393273942739527396273972739827399274002740127402274032740427405274062740727408274092741027411274122741327414274152741627417274182741927420274212742227423274242742527426274272742827429274302743127432274332743427435274362743727438274392744027441274422744327444274452744627447274482744927450274512745227453274542745527456274572745827459274602746127462274632746427465274662746727468274692747027471274722747327474274752747627477274782747927480274812748227483274842748527486274872748827489274902749127492274932749427495274962749727498274992750027501275022750327504275052750627507275082750927510275112751227513275142751527516275172751827519275202752127522275232752427525275262752727528275292753027531275322753327534275352753627537275382753927540275412754227543275442754527546275472754827549275502755127552275532755427555275562755727558275592756027561275622756327564275652756627567275682756927570275712757227573275742757527576275772757827579275802758127582275832758427585275862758727588275892759027591275922759327594275952759627597275982759927600276012760227603276042760527606276072760827609276102761127612276132761427615276162761727618276192762027621276222762327624276252762627627276282762927630276312763227633276342763527636276372763827639276402764127642276432764427645276462764727648276492765027651276522765327654276552765627657276582765927660276612766227663276642766527666276672766827669276702767127672276732767427675276762767727678276792768027681276822768327684276852768627687276882768927690276912769227693276942769527696276972769827699277002770127702277032770427705277062770727708277092771027711277122771327714277152771627717277182771927720277212772227723277242772527726277272772827729277302773127732277332773427735277362773727738277392774027741277422774327744277452774627747277482774927750277512775227753277542775527756277572775827759277602776127762277632776427765277662776727768277692777027771277722777327774277752777627777277782777927780277812778227783277842778527786277872778827789277902779127792277932779427795277962779727798277992780027801278022780327804278052780627807278082780927810278112781227813278142781527816278172781827819278202782127822278232782427825278262782727828278292783027831278322783327834278352783627837278382783927840278412784227843278442784527846278472784827849278502785127852278532785427855278562785727858278592786027861278622786327864278652786627867278682786927870278712787227873278742787527876278772787827879278802788127882278832788427885278862788727888278892789027891278922789327894278952789627897278982789927900279012790227903279042790527906279072790827909279102791127912279132791427915279162791727918279192792027921279222792327924279252792627927279282792927930279312793227933279342793527936279372793827939279402794127942279432794427945279462794727948279492795027951279522795327954279552795627957279582795927960279612796227963279642796527966279672796827969279702797127972279732797427975279762797727978279792798027981279822798327984279852798627987279882798927990279912799227993279942799527996279972799827999280002800128002280032800428005280062800728008280092801028011280122801328014280152801628017280182801928020280212802228023280242802528026280272802828029280302803128032280332803428035280362803728038280392804028041280422804328044280452804628047280482804928050280512805228053280542805528056280572805828059280602806128062280632806428065280662806728068280692807028071280722807328074280752807628077280782807928080280812808228083280842808528086280872808828089280902809128092280932809428095280962809728098280992810028101281022810328104281052810628107281082810928110281112811228113281142811528116281172811828119281202812128122281232812428125281262812728128281292813028131281322813328134281352813628137281382813928140281412814228143281442814528146281472814828149281502815128152281532815428155281562815728158281592816028161281622816328164281652816628167281682816928170281712817228173281742817528176281772817828179281802818128182281832818428185281862818728188281892819028191281922819328194281952819628197281982819928200282012820228203282042820528206282072820828209282102821128212282132821428215282162821728218282192822028221282222822328224282252822628227282282822928230282312823228233282342823528236282372823828239282402824128242282432824428245282462824728248282492825028251282522825328254282552825628257282582825928260282612826228263282642826528266282672826828269282702827128272282732827428275282762827728278282792828028281282822828328284282852828628287282882828928290282912829228293282942829528296282972829828299283002830128302283032830428305283062830728308283092831028311283122831328314283152831628317283182831928320283212832228323283242832528326283272832828329283302833128332283332833428335283362833728338283392834028341283422834328344283452834628347283482834928350283512835228353283542835528356283572835828359283602836128362283632836428365283662836728368283692837028371283722837328374283752837628377283782837928380283812838228383283842838528386283872838828389283902839128392283932839428395283962839728398283992840028401284022840328404284052840628407284082840928410284112841228413284142841528416284172841828419284202842128422284232842428425284262842728428284292843028431284322843328434284352843628437284382843928440284412844228443284442844528446284472844828449284502845128452284532845428455284562845728458284592846028461284622846328464284652846628467284682846928470284712847228473284742847528476284772847828479284802848128482284832848428485284862848728488284892849028491284922849328494284952849628497284982849928500285012850228503285042850528506285072850828509285102851128512285132851428515285162851728518285192852028521285222852328524285252852628527285282852928530285312853228533285342853528536285372853828539285402854128542285432854428545285462854728548285492855028551285522855328554285552855628557285582855928560285612856228563285642856528566285672856828569285702857128572285732857428575285762857728578285792858028581285822858328584285852858628587285882858928590285912859228593285942859528596285972859828599286002860128602286032860428605286062860728608286092861028611286122861328614286152861628617286182861928620286212862228623286242862528626286272862828629286302863128632286332863428635286362863728638286392864028641286422864328644286452864628647286482864928650286512865228653286542865528656286572865828659286602866128662286632866428665286662866728668286692867028671286722867328674286752867628677286782867928680286812868228683286842868528686286872868828689286902869128692286932869428695286962869728698286992870028701287022870328704287052870628707287082870928710287112871228713287142871528716287172871828719287202872128722287232872428725287262872728728287292873028731287322873328734287352873628737287382873928740287412874228743287442874528746287472874828749287502875128752287532875428755287562875728758287592876028761287622876328764287652876628767287682876928770287712877228773287742877528776287772877828779287802878128782287832878428785287862878728788287892879028791287922879328794287952879628797287982879928800288012880228803288042880528806288072880828809288102881128812288132881428815288162881728818288192882028821288222882328824288252882628827288282882928830288312883228833288342883528836288372883828839288402884128842288432884428845288462884728848288492885028851288522885328854288552885628857288582885928860288612886228863288642886528866288672886828869288702887128872288732887428875288762887728878288792888028881288822888328884288852888628887288882888928890288912889228893288942889528896288972889828899289002890128902289032890428905289062890728908289092891028911289122891328914289152891628917289182891928920289212892228923289242892528926289272892828929289302893128932289332893428935289362893728938289392894028941289422894328944289452894628947289482894928950289512895228953289542895528956289572895828959289602896128962289632896428965289662896728968289692897028971289722897328974289752897628977289782897928980289812898228983289842898528986289872898828989289902899128992289932899428995289962899728998289992900029001290022900329004290052900629007290082900929010290112901229013290142901529016290172901829019290202902129022290232902429025290262902729028290292903029031290322903329034290352903629037290382903929040290412904229043290442904529046290472904829049290502905129052290532905429055290562905729058290592906029061290622906329064290652906629067290682906929070290712907229073290742907529076290772907829079290802908129082290832908429085290862908729088290892909029091290922909329094290952909629097290982909929100291012910229103291042910529106291072910829109291102911129112291132911429115291162911729118291192912029121291222912329124291252912629127291282912929130291312913229133291342913529136291372913829139291402914129142291432914429145291462914729148291492915029151291522915329154291552915629157291582915929160291612916229163291642916529166291672916829169291702917129172291732917429175291762917729178291792918029181291822918329184291852918629187291882918929190291912919229193291942919529196291972919829199292002920129202292032920429205292062920729208292092921029211292122921329214292152921629217292182921929220292212922229223292242922529226292272922829229292302923129232292332923429235292362923729238292392924029241292422924329244292452924629247292482924929250292512925229253292542925529256292572925829259292602926129262292632926429265292662926729268292692927029271292722927329274292752927629277292782927929280292812928229283292842928529286292872928829289292902929129292292932929429295292962929729298292992930029301293022930329304293052930629307293082930929310293112931229313293142931529316293172931829319293202932129322293232932429325293262932729328293292933029331293322933329334293352933629337293382933929340293412934229343293442934529346293472934829349293502935129352293532935429355293562935729358293592936029361293622936329364293652936629367293682936929370293712937229373293742937529376293772937829379293802938129382293832938429385293862938729388293892939029391293922939329394293952939629397293982939929400294012940229403294042940529406294072940829409294102941129412294132941429415294162941729418294192942029421294222942329424294252942629427294282942929430294312943229433294342943529436294372943829439294402944129442294432944429445294462944729448294492945029451294522945329454294552945629457294582945929460294612946229463294642946529466294672946829469294702947129472294732947429475294762947729478294792948029481294822948329484294852948629487294882948929490294912949229493294942949529496294972949829499295002950129502295032950429505295062950729508295092951029511295122951329514295152951629517295182951929520295212952229523295242952529526295272952829529295302953129532295332953429535295362953729538295392954029541295422954329544295452954629547295482954929550295512955229553295542955529556295572955829559295602956129562295632956429565295662956729568295692957029571295722957329574295752957629577295782957929580295812958229583295842958529586295872958829589295902959129592295932959429595295962959729598295992960029601296022960329604296052960629607296082960929610296112961229613296142961529616296172961829619296202962129622296232962429625296262962729628296292963029631296322963329634296352963629637296382963929640296412964229643296442964529646296472964829649296502965129652296532965429655296562965729658296592966029661296622966329664296652966629667296682966929670296712967229673296742967529676296772967829679296802968129682296832968429685296862968729688296892969029691296922969329694296952969629697296982969929700297012970229703297042970529706297072970829709297102971129712297132971429715297162971729718297192972029721297222972329724297252972629727297282972929730297312973229733297342973529736297372973829739297402974129742297432974429745297462974729748297492975029751297522975329754297552975629757297582975929760297612976229763297642976529766297672976829769297702977129772297732977429775297762977729778297792978029781297822978329784297852978629787297882978929790297912979229793297942979529796297972979829799298002980129802298032980429805298062980729808298092981029811298122981329814298152981629817298182981929820298212982229823298242982529826298272982829829298302983129832298332983429835298362983729838298392984029841298422984329844298452984629847298482984929850298512985229853298542985529856298572985829859298602986129862298632986429865298662986729868298692987029871298722987329874298752987629877298782987929880298812988229883298842988529886298872988829889298902989129892298932989429895298962989729898298992990029901299022990329904299052990629907299082990929910299112991229913299142991529916299172991829919299202992129922299232992429925299262992729928299292993029931299322993329934299352993629937299382993929940299412994229943299442994529946299472994829949299502995129952299532995429955299562995729958299592996029961299622996329964299652996629967299682996929970299712997229973299742997529976299772997829979299802998129982299832998429985299862998729988299892999029991299922999329994299952999629997299982999930000300013000230003300043000530006300073000830009300103001130012300133001430015300163001730018300193002030021300223002330024300253002630027300283002930030300313003230033300343003530036300373003830039300403004130042300433004430045300463004730048300493005030051300523005330054300553005630057300583005930060300613006230063300643006530066300673006830069300703007130072300733007430075300763007730078300793008030081300823008330084300853008630087300883008930090300913009230093300943009530096300973009830099301003010130102301033010430105301063010730108301093011030111301123011330114301153011630117301183011930120301213012230123301243012530126301273012830129301303013130132301333013430135301363013730138301393014030141301423014330144301453014630147301483014930150301513015230153301543015530156301573015830159301603016130162301633016430165301663016730168301693017030171301723017330174301753017630177301783017930180301813018230183301843018530186301873018830189301903019130192301933019430195301963019730198301993020030201302023020330204302053020630207302083020930210302113021230213302143021530216302173021830219302203022130222302233022430225302263022730228302293023030231302323023330234302353023630237302383023930240302413024230243302443024530246302473024830249302503025130252302533025430255302563025730258302593026030261302623026330264302653026630267302683026930270302713027230273302743027530276302773027830279302803028130282302833028430285302863028730288302893029030291302923029330294302953029630297302983029930300303013030230303303043030530306303073030830309303103031130312303133031430315303163031730318303193032030321303223032330324303253032630327303283032930330303313033230333303343033530336303373033830339303403034130342303433034430345303463034730348303493035030351303523035330354303553035630357303583035930360303613036230363303643036530366303673036830369303703037130372303733037430375303763037730378303793038030381303823038330384303853038630387303883038930390303913039230393303943039530396303973039830399304003040130402304033040430405304063040730408304093041030411304123041330414304153041630417304183041930420304213042230423304243042530426304273042830429304303043130432304333043430435304363043730438304393044030441304423044330444304453044630447304483044930450304513045230453304543045530456304573045830459304603046130462304633046430465304663046730468304693047030471304723047330474304753047630477304783047930480304813048230483304843048530486304873048830489304903049130492304933049430495304963049730498304993050030501305023050330504305053050630507305083050930510305113051230513305143051530516305173051830519305203052130522305233052430525305263052730528305293053030531305323053330534305353053630537305383053930540305413054230543305443054530546305473054830549305503055130552305533055430555305563055730558305593056030561305623056330564305653056630567305683056930570305713057230573305743057530576305773057830579305803058130582305833058430585305863058730588305893059030591305923059330594305953059630597305983059930600306013060230603306043060530606306073060830609306103061130612306133061430615306163061730618306193062030621306223062330624306253062630627306283062930630306313063230633306343063530636306373063830639306403064130642306433064430645306463064730648306493065030651306523065330654306553065630657306583065930660306613066230663306643066530666306673066830669306703067130672306733067430675306763067730678306793068030681306823068330684306853068630687306883068930690306913069230693306943069530696306973069830699307003070130702307033070430705307063070730708307093071030711307123071330714307153071630717307183071930720307213072230723307243072530726307273072830729307303073130732307333073430735307363073730738307393074030741307423074330744307453074630747307483074930750307513075230753307543075530756307573075830759307603076130762307633076430765307663076730768307693077030771307723077330774307753077630777307783077930780307813078230783307843078530786307873078830789307903079130792307933079430795307963079730798307993080030801308023080330804308053080630807308083080930810308113081230813308143081530816308173081830819308203082130822308233082430825308263082730828308293083030831308323083330834308353083630837308383083930840308413084230843308443084530846308473084830849308503085130852308533085430855308563085730858308593086030861308623086330864308653086630867308683086930870308713087230873308743087530876308773087830879308803088130882308833088430885308863088730888308893089030891308923089330894308953089630897308983089930900309013090230903309043090530906309073090830909309103091130912309133091430915309163091730918309193092030921309223092330924309253092630927309283092930930309313093230933309343093530936309373093830939309403094130942309433094430945309463094730948309493095030951309523095330954309553095630957309583095930960309613096230963309643096530966309673096830969309703097130972309733097430975309763097730978309793098030981309823098330984309853098630987309883098930990309913099230993309943099530996309973099830999310003100131002310033100431005310063100731008310093101031011310123101331014310153101631017310183101931020310213102231023310243102531026310273102831029310303103131032310333103431035310363103731038310393104031041310423104331044310453104631047310483104931050310513105231053310543105531056310573105831059310603106131062310633106431065310663106731068310693107031071310723107331074310753107631077310783107931080310813108231083310843108531086310873108831089310903109131092310933109431095310963109731098310993110031101311023110331104311053110631107311083110931110311113111231113311143111531116311173111831119311203112131122311233112431125311263112731128311293113031131311323113331134311353113631137311383113931140311413114231143311443114531146311473114831149311503115131152311533115431155311563115731158311593116031161311623116331164311653116631167311683116931170311713117231173311743117531176311773117831179311803118131182311833118431185311863118731188311893119031191311923119331194311953119631197311983119931200312013120231203312043120531206312073120831209312103121131212312133121431215312163121731218312193122031221312223122331224312253122631227312283122931230312313123231233312343123531236312373123831239312403124131242312433124431245312463124731248312493125031251312523125331254312553125631257312583125931260312613126231263312643126531266312673126831269312703127131272312733127431275312763127731278312793128031281312823128331284312853128631287312883128931290312913129231293312943129531296312973129831299313003130131302313033130431305313063130731308313093131031311313123131331314313153131631317313183131931320313213132231323313243132531326313273132831329313303133131332313333133431335313363133731338313393134031341313423134331344313453134631347313483134931350313513135231353313543135531356313573135831359313603136131362313633136431365313663136731368313693137031371313723137331374313753137631377313783137931380313813138231383313843138531386313873138831389313903139131392313933139431395313963139731398313993140031401314023140331404314053140631407314083140931410314113141231413314143141531416314173141831419314203142131422314233142431425314263142731428314293143031431314323143331434314353143631437314383143931440314413144231443314443144531446314473144831449314503145131452314533145431455314563145731458314593146031461314623146331464314653146631467314683146931470314713147231473314743147531476314773147831479314803148131482314833148431485314863148731488314893149031491314923149331494314953149631497314983149931500315013150231503315043150531506315073150831509315103151131512315133151431515315163151731518315193152031521315223152331524315253152631527315283152931530315313153231533315343153531536315373153831539315403154131542315433154431545315463154731548315493155031551315523155331554315553155631557315583155931560315613156231563315643156531566315673156831569315703157131572315733157431575315763157731578315793158031581315823158331584315853158631587315883158931590315913159231593315943159531596315973159831599316003160131602316033160431605316063160731608316093161031611316123161331614316153161631617316183161931620316213162231623316243162531626316273162831629316303163131632316333163431635316363163731638316393164031641316423164331644316453164631647316483164931650316513165231653316543165531656316573165831659316603166131662316633166431665316663166731668316693167031671316723167331674316753167631677316783167931680316813168231683316843168531686316873168831689316903169131692316933169431695316963169731698316993170031701317023170331704317053170631707317083170931710317113171231713317143171531716317173171831719317203172131722317233172431725317263172731728317293173031731317323173331734317353173631737317383173931740317413174231743317443174531746317473174831749317503175131752317533175431755317563175731758317593176031761317623176331764317653176631767317683176931770317713177231773317743177531776317773177831779317803178131782317833178431785317863178731788317893179031791317923179331794317953179631797317983179931800318013180231803318043180531806318073180831809318103181131812318133181431815318163181731818318193182031821318223182331824318253182631827318283182931830318313183231833318343183531836318373183831839318403184131842318433184431845318463184731848318493185031851318523185331854318553185631857318583185931860318613186231863318643186531866318673186831869318703187131872318733187431875318763187731878318793188031881318823188331884318853188631887318883188931890318913189231893318943189531896318973189831899319003190131902319033190431905319063190731908319093191031911319123191331914319153191631917319183191931920319213192231923319243192531926319273192831929319303193131932319333193431935319363193731938319393194031941319423194331944319453194631947319483194931950319513195231953319543195531956319573195831959319603196131962319633196431965319663196731968319693197031971319723197331974319753197631977319783197931980319813198231983319843198531986319873198831989319903199131992319933199431995319963199731998319993200032001320023200332004320053200632007320083200932010320113201232013320143201532016320173201832019320203202132022320233202432025320263202732028320293203032031320323203332034320353203632037320383203932040320413204232043320443204532046320473204832049320503205132052320533205432055320563205732058320593206032061320623206332064320653206632067320683206932070320713207232073320743207532076320773207832079320803208132082320833208432085320863208732088320893209032091320923209332094320953209632097320983209932100321013210232103321043210532106321073210832109321103211132112321133211432115321163211732118321193212032121321223212332124321253212632127321283212932130321313213232133321343213532136321373213832139321403214132142321433214432145321463214732148321493215032151321523215332154321553215632157321583215932160321613216232163321643216532166321673216832169321703217132172321733217432175321763217732178321793218032181321823218332184321853218632187321883218932190321913219232193321943219532196321973219832199322003220132202322033220432205322063220732208322093221032211322123221332214322153221632217322183221932220322213222232223322243222532226322273222832229322303223132232322333223432235322363223732238322393224032241322423224332244322453224632247322483224932250322513225232253322543225532256322573225832259322603226132262322633226432265322663226732268322693227032271322723227332274322753227632277322783227932280322813228232283322843228532286322873228832289322903229132292322933229432295322963229732298322993230032301323023230332304323053230632307323083230932310323113231232313323143231532316323173231832319323203232132322323233232432325323263232732328323293233032331323323233332334323353233632337323383233932340323413234232343323443234532346323473234832349323503235132352323533235432355323563235732358323593236032361323623236332364323653236632367323683236932370323713237232373323743237532376323773237832379323803238132382323833238432385323863238732388323893239032391323923239332394323953239632397323983239932400324013240232403324043240532406324073240832409324103241132412324133241432415324163241732418324193242032421324223242332424324253242632427324283242932430324313243232433324343243532436324373243832439324403244132442324433244432445324463244732448324493245032451324523245332454324553245632457324583245932460324613246232463324643246532466324673246832469324703247132472324733247432475324763247732478324793248032481324823248332484324853248632487324883248932490324913249232493324943249532496324973249832499325003250132502325033250432505325063250732508325093251032511325123251332514325153251632517325183251932520325213252232523325243252532526325273252832529325303253132532325333253432535325363253732538325393254032541325423254332544325453254632547325483254932550325513255232553325543255532556325573255832559325603256132562325633256432565325663256732568325693257032571325723257332574325753257632577325783257932580325813258232583325843258532586325873258832589325903259132592325933259432595325963259732598325993260032601326023260332604326053260632607326083260932610326113261232613326143261532616326173261832619326203262132622326233262432625326263262732628326293263032631326323263332634326353263632637326383263932640326413264232643326443264532646326473264832649326503265132652326533265432655326563265732658326593266032661326623266332664326653266632667326683266932670326713267232673326743267532676326773267832679326803268132682326833268432685326863268732688326893269032691326923269332694326953269632697326983269932700327013270232703327043270532706327073270832709327103271132712327133271432715327163271732718327193272032721327223272332724327253272632727327283272932730327313273232733327343273532736327373273832739327403274132742327433274432745327463274732748327493275032751327523275332754327553275632757327583275932760327613276232763327643276532766327673276832769327703277132772327733277432775327763277732778327793278032781327823278332784327853278632787327883278932790327913279232793327943279532796327973279832799328003280132802328033280432805328063280732808328093281032811328123281332814328153281632817328183281932820328213282232823328243282532826328273282832829328303283132832328333283432835328363283732838328393284032841328423284332844328453284632847328483284932850328513285232853328543285532856328573285832859328603286132862328633286432865328663286732868328693287032871328723287332874328753287632877328783287932880328813288232883328843288532886328873288832889328903289132892328933289432895328963289732898328993290032901329023290332904329053290632907329083290932910329113291232913329143291532916329173291832919329203292132922329233292432925329263292732928329293293032931329323293332934329353293632937329383293932940329413294232943329443294532946329473294832949329503295132952329533295432955329563295732958329593296032961329623296332964329653296632967329683296932970329713297232973329743297532976329773297832979329803298132982329833298432985329863298732988329893299032991329923299332994329953299632997329983299933000330013300233003330043300533006330073300833009330103301133012330133301433015330163301733018330193302033021330223302333024330253302633027330283302933030330313303233033330343303533036330373303833039330403304133042330433304433045330463304733048330493305033051330523305333054330553305633057330583305933060330613306233063330643306533066330673306833069330703307133072330733307433075330763307733078330793308033081330823308333084330853308633087330883308933090330913309233093330943309533096330973309833099331003310133102331033310433105331063310733108331093311033111331123311333114331153311633117331183311933120331213312233123331243312533126331273312833129331303313133132331333313433135331363313733138331393314033141331423314333144331453314633147331483314933150331513315233153331543315533156331573315833159331603316133162331633316433165331663316733168331693317033171331723317333174331753317633177331783317933180331813318233183331843318533186331873318833189331903319133192331933319433195331963319733198331993320033201332023320333204332053320633207332083320933210332113321233213332143321533216332173321833219332203322133222332233322433225332263322733228332293323033231332323323333234332353323633237332383323933240332413324233243332443324533246332473324833249332503325133252332533325433255332563325733258332593326033261332623326333264332653326633267332683326933270332713327233273332743327533276332773327833279332803328133282332833328433285332863328733288332893329033291332923329333294332953329633297332983329933300333013330233303333043330533306333073330833309333103331133312333133331433315333163331733318333193332033321333223332333324333253332633327333283332933330333313333233333333343333533336333373333833339333403334133342333433334433345333463334733348333493335033351333523335333354333553335633357333583335933360333613336233363333643336533366333673336833369333703337133372333733337433375333763337733378333793338033381333823338333384333853338633387333883338933390333913339233393333943339533396333973339833399334003340133402334033340433405334063340733408334093341033411334123341333414334153341633417334183341933420334213342233423334243342533426334273342833429334303343133432334333343433435334363343733438334393344033441334423344333444334453344633447334483344933450334513345233453334543345533456334573345833459334603346133462334633346433465334663346733468334693347033471334723347333474334753347633477334783347933480334813348233483334843348533486334873348833489334903349133492334933349433495334963349733498334993350033501335023350333504335053350633507335083350933510335113351233513335143351533516335173351833519335203352133522335233352433525335263352733528335293353033531335323353333534335353353633537335383353933540335413354233543335443354533546335473354833549335503355133552335533355433555335563355733558335593356033561335623356333564335653356633567335683356933570335713357233573335743357533576335773357833579335803358133582335833358433585335863358733588335893359033591335923359333594335953359633597335983359933600336013360233603336043360533606336073360833609336103361133612336133361433615336163361733618336193362033621336223362333624336253362633627336283362933630336313363233633336343363533636336373363833639336403364133642336433364433645336463364733648336493365033651336523365333654336553365633657336583365933660336613366233663336643366533666336673366833669336703367133672336733367433675336763367733678336793368033681336823368333684336853368633687336883368933690336913369233693336943369533696336973369833699337003370133702337033370433705337063370733708337093371033711337123371333714337153371633717337183371933720337213372233723337243372533726337273372833729337303373133732337333373433735337363373733738337393374033741337423374333744337453374633747337483374933750337513375233753337543375533756337573375833759337603376133762337633376433765337663376733768337693377033771337723377333774337753377633777337783377933780337813378233783337843378533786337873378833789337903379133792337933379433795337963379733798337993380033801338023380333804338053380633807338083380933810338113381233813338143381533816338173381833819338203382133822338233382433825338263382733828338293383033831338323383333834338353383633837338383383933840338413384233843338443384533846338473384833849338503385133852338533385433855338563385733858338593386033861338623386333864338653386633867338683386933870338713387233873338743387533876338773387833879338803388133882338833388433885338863388733888338893389033891338923389333894338953389633897338983389933900339013390233903339043390533906339073390833909339103391133912339133391433915339163391733918339193392033921339223392333924339253392633927339283392933930339313393233933339343393533936339373393833939339403394133942339433394433945339463394733948339493395033951339523395333954339553395633957339583395933960339613396233963339643396533966339673396833969339703397133972339733397433975339763397733978339793398033981339823398333984339853398633987339883398933990339913399233993339943399533996339973399833999340003400134002340033400434005340063400734008340093401034011340123401334014340153401634017340183401934020340213402234023340243402534026340273402834029340303403134032340333403434035340363403734038340393404034041340423404334044340453404634047340483404934050340513405234053340543405534056340573405834059340603406134062340633406434065340663406734068340693407034071340723407334074340753407634077340783407934080340813408234083340843408534086340873408834089340903409134092340933409434095340963409734098340993410034101341023410334104341053410634107341083410934110341113411234113341143411534116341173411834119341203412134122341233412434125341263412734128341293413034131341323413334134341353413634137341383413934140341413414234143341443414534146341473414834149341503415134152341533415434155341563415734158341593416034161341623416334164341653416634167341683416934170341713417234173341743417534176341773417834179341803418134182341833418434185341863418734188341893419034191341923419334194341953419634197341983419934200342013420234203342043420534206342073420834209342103421134212342133421434215342163421734218342193422034221342223422334224342253422634227342283422934230342313423234233342343423534236342373423834239342403424134242342433424434245342463424734248342493425034251342523425334254342553425634257342583425934260342613426234263342643426534266342673426834269342703427134272342733427434275342763427734278342793428034281342823428334284342853428634287342883428934290342913429234293342943429534296342973429834299343003430134302343033430434305343063430734308343093431034311343123431334314343153431634317343183431934320343213432234323343243432534326343273432834329343303433134332343333433434335343363433734338343393434034341343423434334344343453434634347343483434934350343513435234353343543435534356343573435834359343603436134362343633436434365343663436734368343693437034371343723437334374343753437634377343783437934380343813438234383343843438534386343873438834389343903439134392343933439434395343963439734398343993440034401344023440334404344053440634407344083440934410344113441234413344143441534416344173441834419344203442134422344233442434425344263442734428344293443034431344323443334434344353443634437344383443934440344413444234443344443444534446344473444834449344503445134452344533445434455344563445734458344593446034461344623446334464344653446634467344683446934470344713447234473344743447534476344773447834479344803448134482344833448434485344863448734488344893449034491344923449334494344953449634497344983449934500345013450234503345043450534506345073450834509345103451134512345133451434515345163451734518345193452034521345223452334524345253452634527345283452934530345313453234533345343453534536345373453834539345403454134542345433454434545345463454734548345493455034551345523455334554345553455634557345583455934560345613456234563345643456534566345673456834569345703457134572345733457434575345763457734578345793458034581345823458334584345853458634587345883458934590345913459234593345943459534596345973459834599346003460134602346033460434605346063460734608346093461034611346123461334614346153461634617346183461934620346213462234623346243462534626346273462834629346303463134632346333463434635346363463734638346393464034641346423464334644346453464634647346483464934650346513465234653346543465534656346573465834659346603466134662346633466434665346663466734668346693467034671346723467334674346753467634677346783467934680346813468234683346843468534686346873468834689346903469134692346933469434695346963469734698346993470034701347023470334704347053470634707347083470934710347113471234713347143471534716347173471834719347203472134722347233472434725347263472734728347293473034731347323473334734347353473634737347383473934740347413474234743347443474534746347473474834749347503475134752347533475434755347563475734758347593476034761347623476334764347653476634767347683476934770347713477234773347743477534776347773477834779347803478134782347833478434785347863478734788347893479034791347923479334794347953479634797347983479934800348013480234803348043480534806348073480834809348103481134812348133481434815348163481734818348193482034821348223482334824348253482634827348283482934830348313483234833348343483534836348373483834839348403484134842348433484434845348463484734848348493485034851348523485334854348553485634857348583485934860348613486234863348643486534866348673486834869348703487134872348733487434875348763487734878348793488034881348823488334884348853488634887348883488934890348913489234893348943489534896348973489834899349003490134902349033490434905349063490734908349093491034911349123491334914349153491634917349183491934920349213492234923349243492534926349273492834929349303493134932349333493434935349363493734938349393494034941349423494334944349453494634947349483494934950349513495234953349543495534956349573495834959349603496134962349633496434965349663496734968349693497034971349723497334974349753497634977349783497934980349813498234983349843498534986349873498834989349903499134992349933499434995349963499734998349993500035001350023500335004350053500635007350083500935010350113501235013350143501535016350173501835019350203502135022350233502435025350263502735028350293503035031350323503335034350353503635037350383503935040350413504235043350443504535046350473504835049350503505135052350533505435055350563505735058350593506035061350623506335064350653506635067350683506935070350713507235073350743507535076350773507835079350803508135082350833508435085350863508735088350893509035091350923509335094350953509635097350983509935100351013510235103351043510535106351073510835109351103511135112351133511435115351163511735118351193512035121351223512335124351253512635127351283512935130351313513235133351343513535136351373513835139351403514135142351433514435145351463514735148351493515035151351523515335154351553515635157351583515935160351613516235163351643516535166351673516835169351703517135172351733517435175351763517735178351793518035181351823518335184351853518635187351883518935190351913519235193351943519535196351973519835199352003520135202352033520435205352063520735208352093521035211352123521335214352153521635217352183521935220352213522235223352243522535226352273522835229352303523135232352333523435235352363523735238352393524035241352423524335244352453524635247352483524935250352513525235253352543525535256352573525835259352603526135262352633526435265352663526735268352693527035271352723527335274352753527635277352783527935280352813528235283352843528535286352873528835289352903529135292352933529435295352963529735298352993530035301353023530335304353053530635307353083530935310353113531235313353143531535316353173531835319353203532135322353233532435325353263532735328353293533035331353323533335334353353533635337353383533935340353413534235343353443534535346353473534835349353503535135352353533535435355353563535735358353593536035361353623536335364353653536635367353683536935370353713537235373353743537535376353773537835379353803538135382353833538435385353863538735388353893539035391353923539335394353953539635397353983539935400354013540235403354043540535406354073540835409354103541135412354133541435415354163541735418354193542035421354223542335424354253542635427354283542935430354313543235433354343543535436354373543835439354403544135442354433544435445354463544735448354493545035451354523545335454354553545635457354583545935460354613546235463354643546535466354673546835469354703547135472354733547435475354763547735478354793548035481354823548335484354853548635487354883548935490354913549235493354943549535496354973549835499355003550135502355033550435505355063550735508355093551035511355123551335514355153551635517355183551935520355213552235523355243552535526355273552835529355303553135532355333553435535355363553735538355393554035541355423554335544355453554635547355483554935550355513555235553355543555535556355573555835559355603556135562355633556435565355663556735568355693557035571355723557335574355753557635577355783557935580355813558235583355843558535586355873558835589355903559135592355933559435595355963559735598355993560035601356023560335604356053560635607356083560935610356113561235613356143561535616356173561835619356203562135622356233562435625356263562735628356293563035631356323563335634356353563635637356383563935640356413564235643356443564535646356473564835649356503565135652356533565435655356563565735658356593566035661356623566335664356653566635667356683566935670356713567235673356743567535676356773567835679356803568135682356833568435685356863568735688356893569035691356923569335694356953569635697356983569935700357013570235703357043570535706357073570835709357103571135712357133571435715357163571735718357193572035721357223572335724357253572635727357283572935730357313573235733357343573535736357373573835739357403574135742357433574435745357463574735748357493575035751357523575335754357553575635757357583575935760357613576235763357643576535766357673576835769357703577135772357733577435775357763577735778357793578035781357823578335784357853578635787357883578935790357913579235793357943579535796357973579835799358003580135802358033580435805358063580735808358093581035811358123581335814358153581635817358183581935820358213582235823358243582535826358273582835829358303583135832358333583435835358363583735838358393584035841358423584335844358453584635847358483584935850358513585235853358543585535856358573585835859358603586135862358633586435865358663586735868358693587035871358723587335874358753587635877358783587935880358813588235883358843588535886358873588835889358903589135892358933589435895358963589735898358993590035901359023590335904359053590635907359083590935910359113591235913359143591535916359173591835919359203592135922359233592435925359263592735928359293593035931359323593335934359353593635937359383593935940359413594235943359443594535946359473594835949359503595135952359533595435955359563595735958359593596035961359623596335964359653596635967359683596935970359713597235973359743597535976359773597835979359803598135982359833598435985359863598735988359893599035991359923599335994359953599635997359983599936000360013600236003360043600536006360073600836009360103601136012360133601436015360163601736018360193602036021360223602336024360253602636027360283602936030360313603236033360343603536036360373603836039360403604136042360433604436045360463604736048360493605036051360523605336054360553605636057360583605936060360613606236063360643606536066360673606836069360703607136072360733607436075360763607736078360793608036081360823608336084360853608636087360883608936090360913609236093360943609536096360973609836099361003610136102361033610436105361063610736108361093611036111361123611336114361153611636117361183611936120361213612236123361243612536126361273612836129361303613136132361333613436135361363613736138361393614036141361423614336144361453614636147361483614936150361513615236153361543615536156361573615836159361603616136162361633616436165361663616736168361693617036171361723617336174361753617636177361783617936180361813618236183361843618536186361873618836189361903619136192361933619436195361963619736198361993620036201362023620336204362053620636207362083620936210362113621236213362143621536216362173621836219362203622136222362233622436225362263622736228362293623036231362323623336234362353623636237362383623936240362413624236243362443624536246362473624836249362503625136252362533625436255362563625736258362593626036261362623626336264362653626636267362683626936270362713627236273362743627536276362773627836279362803628136282362833628436285362863628736288362893629036291362923629336294362953629636297362983629936300363013630236303363043630536306363073630836309363103631136312363133631436315363163631736318363193632036321363223632336324363253632636327363283632936330363313633236333363343633536336363373633836339363403634136342363433634436345363463634736348363493635036351363523635336354363553635636357363583635936360363613636236363363643636536366363673636836369363703637136372363733637436375363763637736378363793638036381363823638336384363853638636387363883638936390363913639236393363943639536396363973639836399364003640136402364033640436405364063640736408364093641036411364123641336414364153641636417364183641936420364213642236423364243642536426364273642836429364303643136432364333643436435364363643736438364393644036441364423644336444364453644636447364483644936450364513645236453364543645536456364573645836459364603646136462364633646436465364663646736468364693647036471364723647336474364753647636477364783647936480364813648236483364843648536486364873648836489364903649136492364933649436495364963649736498364993650036501365023650336504365053650636507365083650936510365113651236513365143651536516365173651836519365203652136522365233652436525365263652736528365293653036531365323653336534365353653636537365383653936540365413654236543365443654536546365473654836549365503655136552365533655436555365563655736558365593656036561365623656336564365653656636567365683656936570365713657236573365743657536576365773657836579365803658136582365833658436585365863658736588365893659036591365923659336594365953659636597365983659936600366013660236603366043660536606366073660836609366103661136612366133661436615366163661736618366193662036621366223662336624366253662636627366283662936630366313663236633366343663536636366373663836639366403664136642366433664436645366463664736648366493665036651366523665336654366553665636657366583665936660366613666236663366643666536666366673666836669366703667136672366733667436675366763667736678366793668036681366823668336684366853668636687366883668936690366913669236693366943669536696366973669836699367003670136702367033670436705367063670736708367093671036711367123671336714367153671636717367183671936720367213672236723367243672536726367273672836729367303673136732367333673436735367363673736738367393674036741367423674336744367453674636747367483674936750367513675236753367543675536756367573675836759367603676136762367633676436765367663676736768367693677036771367723677336774367753677636777367783677936780367813678236783367843678536786367873678836789367903679136792367933679436795367963679736798367993680036801368023680336804368053680636807368083680936810368113681236813368143681536816368173681836819368203682136822368233682436825368263682736828368293683036831368323683336834368353683636837368383683936840368413684236843368443684536846368473684836849368503685136852368533685436855368563685736858368593686036861368623686336864368653686636867368683686936870368713687236873368743687536876368773687836879368803688136882368833688436885368863688736888368893689036891368923689336894368953689636897368983689936900369013690236903369043690536906369073690836909369103691136912369133691436915369163691736918369193692036921369223692336924369253692636927369283692936930369313693236933369343693536936369373693836939369403694136942369433694436945369463694736948369493695036951369523695336954369553695636957369583695936960369613696236963369643696536966369673696836969369703697136972369733697436975369763697736978369793698036981369823698336984369853698636987369883698936990369913699236993369943699536996369973699836999370003700137002370033700437005370063700737008370093701037011370123701337014370153701637017370183701937020370213702237023370243702537026370273702837029370303703137032370333703437035370363703737038370393704037041370423704337044370453704637047370483704937050370513705237053370543705537056370573705837059370603706137062370633706437065370663706737068370693707037071370723707337074370753707637077370783707937080370813708237083370843708537086370873708837089370903709137092370933709437095370963709737098370993710037101371023710337104371053710637107371083710937110371113711237113371143711537116371173711837119371203712137122371233712437125371263712737128371293713037131371323713337134371353713637137371383713937140371413714237143371443714537146371473714837149371503715137152371533715437155371563715737158371593716037161371623716337164371653716637167371683716937170371713717237173371743717537176371773717837179371803718137182371833718437185371863718737188371893719037191371923719337194371953719637197371983719937200372013720237203372043720537206372073720837209372103721137212372133721437215372163721737218372193722037221372223722337224372253722637227372283722937230372313723237233372343723537236372373723837239372403724137242372433724437245372463724737248372493725037251372523725337254372553725637257372583725937260372613726237263372643726537266372673726837269372703727137272372733727437275372763727737278372793728037281372823728337284372853728637287372883728937290372913729237293372943729537296372973729837299373003730137302373033730437305373063730737308373093731037311373123731337314373153731637317373183731937320373213732237323373243732537326373273732837329373303733137332373333733437335373363733737338373393734037341373423734337344373453734637347373483734937350373513735237353373543735537356373573735837359373603736137362373633736437365373663736737368373693737037371373723737337374373753737637377373783737937380373813738237383373843738537386373873738837389373903739137392373933739437395373963739737398373993740037401374023740337404374053740637407374083740937410374113741237413374143741537416374173741837419374203742137422374233742437425374263742737428374293743037431374323743337434374353743637437374383743937440374413744237443374443744537446374473744837449374503745137452374533745437455374563745737458374593746037461374623746337464374653746637467374683746937470374713747237473374743747537476374773747837479374803748137482374833748437485374863748737488374893749037491374923749337494374953749637497374983749937500375013750237503375043750537506375073750837509375103751137512375133751437515375163751737518375193752037521375223752337524375253752637527375283752937530375313753237533375343753537536375373753837539375403754137542375433754437545375463754737548375493755037551375523755337554375553755637557375583755937560375613756237563375643756537566375673756837569375703757137572375733757437575375763757737578375793758037581375823758337584375853758637587375883758937590375913759237593375943759537596375973759837599376003760137602376033760437605376063760737608376093761037611376123761337614376153761637617376183761937620376213762237623376243762537626376273762837629376303763137632376333763437635376363763737638376393764037641376423764337644376453764637647376483764937650376513765237653376543765537656376573765837659376603766137662376633766437665376663766737668376693767037671376723767337674376753767637677376783767937680376813768237683376843768537686376873768837689376903769137692376933769437695376963769737698376993770037701377023770337704377053770637707377083770937710377113771237713377143771537716377173771837719377203772137722377233772437725377263772737728377293773037731377323773337734377353773637737377383773937740377413774237743377443774537746377473774837749377503775137752377533775437755377563775737758377593776037761377623776337764377653776637767377683776937770377713777237773377743777537776377773777837779377803778137782377833778437785377863778737788377893779037791377923779337794377953779637797377983779937800378013780237803378043780537806378073780837809378103781137812378133781437815378163781737818378193782037821378223782337824378253782637827378283782937830378313783237833378343783537836378373783837839378403784137842378433784437845378463784737848378493785037851378523785337854378553785637857378583785937860378613786237863378643786537866378673786837869378703787137872378733787437875378763787737878378793788037881378823788337884378853788637887378883788937890378913789237893378943789537896378973789837899379003790137902379033790437905379063790737908379093791037911379123791337914379153791637917379183791937920379213792237923379243792537926379273792837929379303793137932379333793437935379363793737938379393794037941379423794337944379453794637947379483794937950379513795237953379543795537956379573795837959379603796137962379633796437965379663796737968379693797037971379723797337974379753797637977379783797937980379813798237983379843798537986379873798837989379903799137992379933799437995379963799737998379993800038001380023800338004380053800638007380083800938010380113801238013380143801538016380173801838019380203802138022380233802438025380263802738028380293803038031380323803338034380353803638037380383803938040380413804238043380443804538046380473804838049380503805138052380533805438055380563805738058380593806038061380623806338064380653806638067380683806938070380713807238073380743807538076380773807838079380803808138082380833808438085380863808738088380893809038091380923809338094380953809638097380983809938100381013810238103381043810538106381073810838109381103811138112381133811438115381163811738118381193812038121381223812338124381253812638127381283812938130381313813238133381343813538136381373813838139381403814138142381433814438145381463814738148381493815038151381523815338154381553815638157381583815938160381613816238163381643816538166381673816838169381703817138172381733817438175381763817738178381793818038181381823818338184381853818638187381883818938190381913819238193381943819538196381973819838199382003820138202382033820438205382063820738208382093821038211382123821338214382153821638217382183821938220382213822238223382243822538226382273822838229382303823138232382333823438235382363823738238382393824038241382423824338244382453824638247382483824938250382513825238253382543825538256382573825838259382603826138262382633826438265382663826738268382693827038271382723827338274382753827638277382783827938280382813828238283382843828538286382873828838289382903829138292382933829438295382963829738298382993830038301383023830338304383053830638307383083830938310383113831238313383143831538316383173831838319383203832138322383233832438325383263832738328383293833038331383323833338334383353833638337383383833938340383413834238343383443834538346383473834838349383503835138352383533835438355383563835738358383593836038361383623836338364383653836638367383683836938370383713837238373383743837538376383773837838379383803838138382383833838438385383863838738388383893839038391383923839338394383953839638397383983839938400384013840238403384043840538406384073840838409384103841138412384133841438415384163841738418384193842038421384223842338424384253842638427384283842938430384313843238433384343843538436384373843838439384403844138442384433844438445384463844738448384493845038451384523845338454384553845638457384583845938460384613846238463384643846538466384673846838469384703847138472384733847438475384763847738478384793848038481384823848338484384853848638487384883848938490384913849238493384943849538496384973849838499385003850138502385033850438505385063850738508385093851038511385123851338514385153851638517385183851938520385213852238523385243852538526385273852838529385303853138532385333853438535385363853738538385393854038541385423854338544385453854638547385483854938550385513855238553385543855538556385573855838559385603856138562385633856438565385663856738568385693857038571385723857338574385753857638577385783857938580385813858238583385843858538586385873858838589385903859138592385933859438595385963859738598385993860038601386023860338604386053860638607386083860938610386113861238613386143861538616386173861838619386203862138622386233862438625386263862738628386293863038631386323863338634386353863638637386383863938640386413864238643386443864538646386473864838649386503865138652386533865438655386563865738658386593866038661386623866338664386653866638667386683866938670386713867238673386743867538676386773867838679386803868138682386833868438685386863868738688386893869038691386923869338694386953869638697386983869938700387013870238703387043870538706387073870838709387103871138712387133871438715387163871738718387193872038721387223872338724387253872638727387283872938730387313873238733387343873538736387373873838739387403874138742387433874438745387463874738748387493875038751387523875338754387553875638757387583875938760387613876238763387643876538766387673876838769387703877138772387733877438775387763877738778387793878038781387823878338784387853878638787387883878938790387913879238793387943879538796387973879838799388003880138802388033880438805388063880738808388093881038811388123881338814388153881638817388183881938820388213882238823388243882538826388273882838829388303883138832388333883438835388363883738838388393884038841388423884338844388453884638847388483884938850388513885238853388543885538856388573885838859388603886138862388633886438865388663886738868388693887038871388723887338874388753887638877388783887938880388813888238883388843888538886388873888838889388903889138892388933889438895388963889738898388993890038901389023890338904389053890638907389083890938910389113891238913389143891538916389173891838919389203892138922389233892438925389263892738928389293893038931389323893338934389353893638937389383893938940389413894238943389443894538946389473894838949389503895138952389533895438955389563895738958389593896038961389623896338964389653896638967389683896938970389713897238973389743897538976389773897838979389803898138982389833898438985389863898738988389893899038991389923899338994389953899638997389983899939000390013900239003390043900539006390073900839009390103901139012390133901439015390163901739018390193902039021390223902339024390253902639027390283902939030390313903239033390343903539036390373903839039390403904139042390433904439045390463904739048390493905039051390523905339054390553905639057390583905939060390613906239063390643906539066390673906839069390703907139072390733907439075390763907739078390793908039081390823908339084390853908639087390883908939090390913909239093390943909539096390973909839099391003910139102391033910439105391063910739108391093911039111391123911339114391153911639117391183911939120391213912239123391243912539126391273912839129391303913139132391333913439135391363913739138391393914039141391423914339144391453914639147391483914939150391513915239153391543915539156391573915839159391603916139162391633916439165391663916739168391693917039171391723917339174391753917639177391783917939180391813918239183391843918539186391873918839189391903919139192391933919439195391963919739198391993920039201392023920339204392053920639207392083920939210392113921239213392143921539216392173921839219392203922139222392233922439225392263922739228392293923039231392323923339234392353923639237392383923939240392413924239243392443924539246392473924839249392503925139252392533925439255392563925739258392593926039261392623926339264392653926639267392683926939270392713927239273392743927539276392773927839279392803928139282392833928439285392863928739288392893929039291392923929339294392953929639297392983929939300393013930239303393043930539306393073930839309393103931139312393133931439315393163931739318393193932039321393223932339324393253932639327393283932939330393313933239333393343933539336393373933839339393403934139342393433934439345393463934739348393493935039351393523935339354393553935639357393583935939360393613936239363393643936539366393673936839369393703937139372393733937439375393763937739378393793938039381393823938339384393853938639387393883938939390393913939239393393943939539396393973939839399394003940139402394033940439405394063940739408394093941039411394123941339414394153941639417394183941939420394213942239423394243942539426394273942839429394303943139432394333943439435394363943739438394393944039441394423944339444394453944639447394483944939450394513945239453394543945539456394573945839459394603946139462394633946439465394663946739468394693947039471394723947339474394753947639477394783947939480394813948239483394843948539486394873948839489394903949139492394933949439495394963949739498394993950039501395023950339504395053950639507395083950939510395113951239513395143951539516395173951839519395203952139522395233952439525395263952739528395293953039531395323953339534395353953639537395383953939540395413954239543395443954539546395473954839549395503955139552395533955439555395563955739558395593956039561395623956339564395653956639567395683956939570395713957239573395743957539576395773957839579395803958139582395833958439585395863958739588395893959039591395923959339594395953959639597395983959939600396013960239603396043960539606396073960839609396103961139612396133961439615396163961739618396193962039621396223962339624396253962639627396283962939630396313963239633396343963539636396373963839639396403964139642396433964439645396463964739648396493965039651396523965339654396553965639657396583965939660396613966239663396643966539666396673966839669396703967139672396733967439675396763967739678396793968039681396823968339684396853968639687396883968939690396913969239693396943969539696396973969839699397003970139702397033970439705397063970739708397093971039711397123971339714397153971639717397183971939720397213972239723397243972539726397273972839729397303973139732397333973439735397363973739738397393974039741397423974339744397453974639747397483974939750397513975239753397543975539756397573975839759397603976139762397633976439765397663976739768397693977039771397723977339774397753977639777397783977939780397813978239783397843978539786397873978839789397903979139792397933979439795397963979739798397993980039801398023980339804398053980639807398083980939810398113981239813398143981539816398173981839819398203982139822398233982439825398263982739828398293983039831398323983339834398353983639837398383983939840398413984239843398443984539846398473984839849398503985139852398533985439855398563985739858398593986039861398623986339864398653986639867398683986939870398713987239873398743987539876398773987839879398803988139882398833988439885398863988739888398893989039891398923989339894398953989639897398983989939900399013990239903399043990539906399073990839909399103991139912399133991439915399163991739918399193992039921399223992339924399253992639927399283992939930399313993239933399343993539936399373993839939399403994139942399433994439945399463994739948399493995039951399523995339954399553995639957399583995939960399613996239963399643996539966399673996839969399703997139972399733997439975399763997739978399793998039981399823998339984399853998639987399883998939990399913999239993399943999539996399973999839999400004000140002400034000440005400064000740008400094001040011400124001340014400154001640017400184001940020400214002240023400244002540026400274002840029400304003140032400334003440035400364003740038400394004040041400424004340044400454004640047400484004940050400514005240053400544005540056400574005840059400604006140062400634006440065400664006740068400694007040071400724007340074400754007640077400784007940080400814008240083400844008540086400874008840089400904009140092400934009440095400964009740098400994010040101401024010340104401054010640107401084010940110401114011240113401144011540116401174011840119401204012140122401234012440125401264012740128401294013040131401324013340134401354013640137401384013940140401414014240143401444014540146401474014840149401504015140152401534015440155401564015740158401594016040161401624016340164401654016640167401684016940170401714017240173401744017540176401774017840179401804018140182401834018440185401864018740188401894019040191401924019340194401954019640197401984019940200402014020240203402044020540206402074020840209402104021140212402134021440215402164021740218402194022040221402224022340224402254022640227402284022940230402314023240233402344023540236402374023840239402404024140242402434024440245402464024740248402494025040251402524025340254402554025640257402584025940260402614026240263402644026540266402674026840269402704027140272402734027440275402764027740278402794028040281402824028340284402854028640287402884028940290402914029240293402944029540296402974029840299403004030140302403034030440305403064030740308403094031040311403124031340314403154031640317403184031940320403214032240323403244032540326403274032840329403304033140332403334033440335403364033740338403394034040341403424034340344403454034640347403484034940350403514035240353403544035540356403574035840359403604036140362403634036440365403664036740368403694037040371403724037340374403754037640377403784037940380403814038240383403844038540386403874038840389403904039140392403934039440395403964039740398403994040040401404024040340404404054040640407404084040940410404114041240413404144041540416404174041840419404204042140422404234042440425404264042740428404294043040431404324043340434404354043640437404384043940440404414044240443404444044540446404474044840449404504045140452404534045440455404564045740458404594046040461404624046340464404654046640467404684046940470404714047240473404744047540476404774047840479404804048140482404834048440485404864048740488404894049040491404924049340494404954049640497404984049940500405014050240503405044050540506405074050840509405104051140512405134051440515405164051740518405194052040521405224052340524405254052640527405284052940530405314053240533405344053540536405374053840539405404054140542405434054440545405464054740548405494055040551405524055340554405554055640557405584055940560405614056240563405644056540566405674056840569405704057140572405734057440575405764057740578405794058040581405824058340584405854058640587405884058940590405914059240593405944059540596405974059840599406004060140602406034060440605406064060740608406094061040611406124061340614406154061640617406184061940620406214062240623406244062540626406274062840629406304063140632406334063440635406364063740638406394064040641406424064340644406454064640647406484064940650406514065240653406544065540656406574065840659406604066140662406634066440665406664066740668406694067040671406724067340674406754067640677406784067940680406814068240683406844068540686406874068840689406904069140692406934069440695406964069740698406994070040701407024070340704407054070640707407084070940710407114071240713407144071540716407174071840719407204072140722407234072440725407264072740728407294073040731407324073340734407354073640737407384073940740407414074240743407444074540746407474074840749407504075140752407534075440755407564075740758407594076040761407624076340764407654076640767407684076940770407714077240773407744077540776407774077840779407804078140782407834078440785407864078740788407894079040791407924079340794407954079640797407984079940800408014080240803408044080540806408074080840809408104081140812408134081440815408164081740818408194082040821408224082340824408254082640827408284082940830408314083240833408344083540836408374083840839408404084140842408434084440845408464084740848408494085040851408524085340854408554085640857408584085940860408614086240863408644086540866408674086840869408704087140872408734087440875408764087740878408794088040881408824088340884408854088640887408884088940890408914089240893408944089540896408974089840899409004090140902409034090440905409064090740908409094091040911409124091340914409154091640917409184091940920409214092240923409244092540926409274092840929409304093140932409334093440935409364093740938409394094040941409424094340944409454094640947409484094940950409514095240953409544095540956409574095840959409604096140962409634096440965409664096740968409694097040971409724097340974409754097640977409784097940980409814098240983409844098540986409874098840989409904099140992409934099440995409964099740998409994100041001410024100341004410054100641007410084100941010410114101241013410144101541016410174101841019410204102141022410234102441025410264102741028410294103041031410324103341034410354103641037410384103941040410414104241043410444104541046410474104841049410504105141052410534105441055410564105741058410594106041061410624106341064410654106641067410684106941070410714107241073410744107541076410774107841079410804108141082410834108441085410864108741088410894109041091410924109341094410954109641097410984109941100411014110241103411044110541106411074110841109411104111141112411134111441115411164111741118411194112041121411224112341124411254112641127411284112941130411314113241133411344113541136411374113841139411404114141142411434114441145411464114741148411494115041151411524115341154411554115641157411584115941160411614116241163411644116541166411674116841169411704117141172411734117441175411764117741178411794118041181411824118341184411854118641187411884118941190411914119241193411944119541196411974119841199412004120141202412034120441205412064120741208412094121041211412124121341214412154121641217412184121941220412214122241223412244122541226412274122841229412304123141232412334123441235412364123741238412394124041241412424124341244412454124641247412484124941250412514125241253412544125541256412574125841259412604126141262412634126441265412664126741268412694127041271412724127341274412754127641277412784127941280412814128241283412844128541286412874128841289412904129141292412934129441295412964129741298412994130041301413024130341304413054130641307413084130941310413114131241313413144131541316413174131841319413204132141322413234132441325413264132741328413294133041331413324133341334413354133641337413384133941340413414134241343413444134541346413474134841349413504135141352413534135441355413564135741358413594136041361413624136341364413654136641367413684136941370413714137241373413744137541376413774137841379413804138141382413834138441385413864138741388413894139041391413924139341394413954139641397413984139941400414014140241403414044140541406414074140841409414104141141412414134141441415414164141741418414194142041421414224142341424414254142641427414284142941430414314143241433414344143541436414374143841439414404144141442414434144441445414464144741448414494145041451414524145341454414554145641457414584145941460414614146241463414644146541466414674146841469414704147141472414734147441475414764147741478414794148041481414824148341484414854148641487414884148941490414914149241493414944149541496414974149841499415004150141502415034150441505415064150741508415094151041511415124151341514415154151641517415184151941520415214152241523415244152541526415274152841529415304153141532415334153441535415364153741538415394154041541415424154341544415454154641547415484154941550415514155241553415544155541556415574155841559415604156141562415634156441565415664156741568415694157041571415724157341574415754157641577415784157941580415814158241583415844158541586415874158841589415904159141592415934159441595415964159741598415994160041601416024160341604416054160641607416084160941610416114161241613416144161541616416174161841619416204162141622416234162441625416264162741628416294163041631416324163341634416354163641637416384163941640416414164241643416444164541646416474164841649416504165141652416534165441655416564165741658416594166041661416624166341664416654166641667416684166941670416714167241673416744167541676416774167841679416804168141682416834168441685416864168741688416894169041691416924169341694416954169641697416984169941700417014170241703417044170541706417074170841709417104171141712417134171441715417164171741718417194172041721417224172341724417254172641727417284172941730417314173241733417344173541736417374173841739417404174141742417434174441745417464174741748417494175041751417524175341754417554175641757417584175941760417614176241763417644176541766417674176841769417704177141772417734177441775417764177741778417794178041781417824178341784417854178641787417884178941790417914179241793417944179541796417974179841799418004180141802418034180441805418064180741808418094181041811418124181341814418154181641817418184181941820418214182241823418244182541826418274182841829418304183141832418334183441835418364183741838418394184041841418424184341844418454184641847418484184941850418514185241853418544185541856418574185841859418604186141862418634186441865418664186741868418694187041871418724187341874418754187641877418784187941880418814188241883418844188541886418874188841889418904189141892418934189441895418964189741898418994190041901419024190341904419054190641907419084190941910419114191241913419144191541916419174191841919419204192141922419234192441925419264192741928419294193041931419324193341934419354193641937419384193941940419414194241943419444194541946419474194841949419504195141952419534195441955419564195741958419594196041961419624196341964419654196641967419684196941970419714197241973419744197541976419774197841979419804198141982419834198441985419864198741988419894199041991419924199341994419954199641997419984199942000420014200242003420044200542006420074200842009420104201142012420134201442015420164201742018420194202042021420224202342024420254202642027420284202942030420314203242033420344203542036420374203842039420404204142042420434204442045420464204742048420494205042051420524205342054420554205642057420584205942060420614206242063420644206542066420674206842069420704207142072420734207442075420764207742078420794208042081420824208342084420854208642087420884208942090420914209242093420944209542096420974209842099421004210142102421034210442105421064210742108421094211042111421124211342114421154211642117421184211942120421214212242123421244212542126421274212842129421304213142132421334213442135421364213742138421394214042141421424214342144421454214642147421484214942150421514215242153421544215542156421574215842159421604216142162421634216442165421664216742168421694217042171421724217342174421754217642177421784217942180421814218242183421844218542186421874218842189421904219142192421934219442195421964219742198421994220042201422024220342204422054220642207422084220942210422114221242213422144221542216422174221842219422204222142222422234222442225422264222742228422294223042231422324223342234422354223642237422384223942240422414224242243422444224542246422474224842249422504225142252422534225442255422564225742258422594226042261422624226342264422654226642267422684226942270422714227242273422744227542276422774227842279422804228142282422834228442285422864228742288422894229042291422924229342294422954229642297422984229942300423014230242303423044230542306423074230842309423104231142312423134231442315423164231742318423194232042321423224232342324423254232642327423284232942330423314233242333423344233542336423374233842339423404234142342423434234442345423464234742348423494235042351423524235342354423554235642357423584235942360423614236242363423644236542366423674236842369423704237142372423734237442375423764237742378423794238042381423824238342384423854238642387423884238942390423914239242393423944239542396423974239842399424004240142402424034240442405424064240742408424094241042411424124241342414424154241642417424184241942420424214242242423424244242542426424274242842429424304243142432424334243442435424364243742438424394244042441424424244342444424454244642447424484244942450424514245242453424544245542456424574245842459424604246142462424634246442465424664246742468424694247042471424724247342474424754247642477424784247942480424814248242483424844248542486424874248842489424904249142492424934249442495424964249742498424994250042501425024250342504425054250642507425084250942510425114251242513425144251542516425174251842519425204252142522425234252442525425264252742528425294253042531425324253342534425354253642537425384253942540425414254242543425444254542546425474254842549425504255142552425534255442555425564255742558425594256042561425624256342564425654256642567425684256942570425714257242573425744257542576425774257842579425804258142582425834258442585425864258742588425894259042591425924259342594425954259642597425984259942600426014260242603426044260542606426074260842609426104261142612426134261442615426164261742618426194262042621426224262342624426254262642627426284262942630426314263242633426344263542636426374263842639426404264142642426434264442645426464264742648426494265042651426524265342654426554265642657426584265942660426614266242663426644266542666426674266842669426704267142672426734267442675426764267742678426794268042681426824268342684426854268642687426884268942690426914269242693426944269542696426974269842699427004270142702427034270442705427064270742708427094271042711427124271342714427154271642717427184271942720427214272242723427244272542726427274272842729427304273142732427334273442735427364273742738427394274042741427424274342744427454274642747427484274942750427514275242753427544275542756427574275842759427604276142762427634276442765427664276742768427694277042771427724277342774427754277642777427784277942780427814278242783427844278542786427874278842789427904279142792427934279442795427964279742798427994280042801428024280342804428054280642807428084280942810428114281242813428144281542816428174281842819428204282142822428234282442825428264282742828428294283042831428324283342834428354283642837428384283942840428414284242843428444284542846428474284842849428504285142852428534285442855428564285742858428594286042861428624286342864428654286642867428684286942870428714287242873428744287542876428774287842879428804288142882428834288442885428864288742888428894289042891428924289342894428954289642897428984289942900429014290242903429044290542906429074290842909429104291142912429134291442915429164291742918429194292042921429224292342924429254292642927429284292942930429314293242933429344293542936429374293842939429404294142942429434294442945429464294742948429494295042951429524295342954429554295642957429584295942960429614296242963429644296542966429674296842969429704297142972429734297442975429764297742978429794298042981429824298342984429854298642987429884298942990429914299242993429944299542996429974299842999430004300143002430034300443005430064300743008430094301043011430124301343014430154301643017430184301943020430214302243023430244302543026430274302843029430304303143032430334303443035430364303743038430394304043041430424304343044430454304643047430484304943050430514305243053430544305543056430574305843059430604306143062430634306443065430664306743068430694307043071430724307343074430754307643077430784307943080430814308243083430844308543086430874308843089430904309143092430934309443095430964309743098430994310043101431024310343104431054310643107431084310943110431114311243113431144311543116431174311843119431204312143122431234312443125431264312743128431294313043131431324313343134431354313643137431384313943140431414314243143431444314543146431474314843149431504315143152431534315443155431564315743158431594316043161431624316343164431654316643167431684316943170431714317243173431744317543176431774317843179431804318143182431834318443185431864318743188431894319043191431924319343194431954319643197431984319943200432014320243203432044320543206432074320843209432104321143212432134321443215432164321743218432194322043221432224322343224432254322643227432284322943230432314323243233432344323543236432374323843239432404324143242432434324443245432464324743248432494325043251432524325343254432554325643257432584325943260432614326243263432644326543266432674326843269432704327143272432734327443275432764327743278432794328043281432824328343284432854328643287432884328943290432914329243293432944329543296432974329843299433004330143302433034330443305433064330743308433094331043311433124331343314433154331643317433184331943320433214332243323433244332543326433274332843329433304333143332433334333443335433364333743338433394334043341433424334343344433454334643347433484334943350433514335243353433544335543356433574335843359433604336143362433634336443365433664336743368433694337043371433724337343374433754337643377433784337943380433814338243383433844338543386433874338843389433904339143392433934339443395433964339743398433994340043401434024340343404434054340643407434084340943410434114341243413434144341543416434174341843419434204342143422434234342443425434264342743428434294343043431434324343343434434354343643437434384343943440434414344243443434444344543446434474344843449434504345143452434534345443455434564345743458434594346043461434624346343464434654346643467434684346943470434714347243473434744347543476434774347843479434804348143482434834348443485434864348743488434894349043491434924349343494434954349643497434984349943500435014350243503435044350543506435074350843509435104351143512435134351443515435164351743518435194352043521435224352343524435254352643527435284352943530435314353243533435344353543536435374353843539435404354143542435434354443545435464354743548435494355043551435524355343554435554355643557435584355943560435614356243563435644356543566435674356843569435704357143572435734357443575435764357743578435794358043581435824358343584435854358643587435884358943590435914359243593435944359543596435974359843599436004360143602436034360443605436064360743608436094361043611436124361343614436154361643617436184361943620436214362243623436244362543626436274362843629436304363143632436334363443635436364363743638436394364043641436424364343644436454364643647436484364943650436514365243653436544365543656436574365843659436604366143662436634366443665436664366743668436694367043671436724367343674436754367643677436784367943680436814368243683436844368543686436874368843689436904369143692436934369443695436964369743698436994370043701437024370343704437054370643707437084370943710437114371243713437144371543716437174371843719437204372143722437234372443725437264372743728437294373043731437324373343734437354373643737437384373943740437414374243743437444374543746437474374843749437504375143752437534375443755437564375743758437594376043761437624376343764437654376643767437684376943770437714377243773437744377543776437774377843779437804378143782437834378443785437864378743788437894379043791437924379343794437954379643797437984379943800438014380243803438044380543806438074380843809438104381143812438134381443815438164381743818438194382043821438224382343824438254382643827438284382943830438314383243833438344383543836438374383843839438404384143842438434384443845438464384743848438494385043851438524385343854438554385643857438584385943860438614386243863438644386543866438674386843869438704387143872438734387443875438764387743878438794388043881438824388343884438854388643887438884388943890438914389243893438944389543896438974389843899439004390143902439034390443905439064390743908439094391043911439124391343914439154391643917439184391943920439214392243923439244392543926439274392843929439304393143932439334393443935439364393743938439394394043941439424394343944439454394643947439484394943950439514395243953439544395543956439574395843959439604396143962439634396443965439664396743968439694397043971439724397343974439754397643977439784397943980439814398243983439844398543986439874398843989439904399143992439934399443995439964399743998439994400044001440024400344004440054400644007440084400944010440114401244013440144401544016440174401844019440204402144022440234402444025440264402744028440294403044031440324403344034440354403644037440384403944040440414404244043440444404544046440474404844049440504405144052440534405444055440564405744058440594406044061440624406344064440654406644067440684406944070440714407244073440744407544076440774407844079440804408144082440834408444085440864408744088440894409044091440924409344094440954409644097440984409944100441014410244103441044410544106441074410844109441104411144112441134411444115441164411744118441194412044121441224412344124441254412644127441284412944130441314413244133441344413544136441374413844139441404414144142441434414444145441464414744148441494415044151441524415344154441554415644157441584415944160441614416244163441644416544166441674416844169441704417144172441734417444175441764417744178441794418044181441824418344184441854418644187441884418944190441914419244193441944419544196441974419844199442004420144202442034420444205442064420744208442094421044211442124421344214442154421644217442184421944220442214422244223442244422544226442274422844229442304423144232442334423444235442364423744238442394424044241442424424344244442454424644247442484424944250442514425244253442544425544256442574425844259442604426144262442634426444265442664426744268442694427044271442724427344274442754427644277442784427944280442814428244283442844428544286442874428844289442904429144292442934429444295442964429744298442994430044301443024430344304443054430644307443084430944310443114431244313443144431544316443174431844319443204432144322443234432444325443264432744328443294433044331443324433344334443354433644337443384433944340443414434244343443444434544346443474434844349443504435144352443534435444355443564435744358443594436044361443624436344364443654436644367443684436944370443714437244373443744437544376443774437844379443804438144382443834438444385443864438744388443894439044391443924439344394443954439644397443984439944400444014440244403444044440544406444074440844409444104441144412444134441444415444164441744418444194442044421444224442344424444254442644427444284442944430444314443244433444344443544436444374443844439444404444144442444434444444445444464444744448444494445044451444524445344454444554445644457444584445944460444614446244463444644446544466444674446844469444704447144472444734447444475444764447744478444794448044481444824448344484444854448644487444884448944490444914449244493444944449544496444974449844499445004450144502445034450444505445064450744508445094451044511445124451344514445154451644517445184451944520445214452244523445244452544526445274452844529445304453144532445334453444535445364453744538445394454044541445424454344544445454454644547445484454944550445514455244553445544455544556445574455844559445604456144562445634456444565445664456744568445694457044571445724457344574445754457644577445784457944580445814458244583445844458544586445874458844589445904459144592445934459444595445964459744598445994460044601446024460344604446054460644607446084460944610446114461244613446144461544616446174461844619446204462144622446234462444625446264462744628446294463044631446324463344634446354463644637446384463944640446414464244643446444464544646446474464844649446504465144652446534465444655446564465744658446594466044661446624466344664446654466644667446684466944670446714467244673446744467544676446774467844679446804468144682446834468444685446864468744688446894469044691446924469344694446954469644697446984469944700447014470244703447044470544706447074470844709447104471144712447134471444715447164471744718447194472044721447224472344724447254472644727447284472944730447314473244733447344473544736447374473844739447404474144742447434474444745447464474744748447494475044751447524475344754447554475644757447584475944760447614476244763447644476544766447674476844769447704477144772447734477444775447764477744778447794478044781447824478344784447854478644787447884478944790447914479244793447944479544796447974479844799448004480144802448034480444805448064480744808448094481044811448124481344814448154481644817448184481944820448214482244823448244482544826448274482844829448304483144832448334483444835448364483744838448394484044841448424484344844448454484644847448484484944850448514485244853448544485544856448574485844859448604486144862448634486444865448664486744868448694487044871448724487344874448754487644877448784487944880448814488244883448844488544886448874488844889448904489144892448934489444895448964489744898448994490044901449024490344904449054490644907449084490944910449114491244913449144491544916449174491844919449204492144922449234492444925449264492744928449294493044931449324493344934449354493644937449384493944940449414494244943449444494544946449474494844949449504495144952449534495444955449564495744958449594496044961449624496344964449654496644967449684496944970449714497244973449744497544976449774497844979449804498144982449834498444985449864498744988449894499044991449924499344994449954499644997449984499945000450014500245003450044500545006450074500845009450104501145012450134501445015450164501745018450194502045021450224502345024450254502645027450284502945030450314503245033450344503545036450374503845039450404504145042450434504445045450464504745048450494505045051450524505345054450554505645057450584505945060450614506245063450644506545066450674506845069450704507145072450734507445075450764507745078450794508045081450824508345084450854508645087450884508945090450914509245093450944509545096450974509845099451004510145102451034510445105451064510745108451094511045111451124511345114451154511645117451184511945120451214512245123451244512545126451274512845129451304513145132451334513445135451364513745138451394514045141451424514345144451454514645147451484514945150451514515245153451544515545156451574515845159451604516145162451634516445165451664516745168451694517045171451724517345174451754517645177451784517945180451814518245183451844518545186451874518845189451904519145192451934519445195451964519745198451994520045201452024520345204452054520645207452084520945210452114521245213452144521545216452174521845219452204522145222452234522445225452264522745228452294523045231452324523345234452354523645237452384523945240452414524245243452444524545246452474524845249452504525145252452534525445255452564525745258452594526045261452624526345264452654526645267452684526945270452714527245273452744527545276452774527845279452804528145282452834528445285452864528745288452894529045291452924529345294452954529645297452984529945300453014530245303453044530545306453074530845309453104531145312453134531445315453164531745318453194532045321453224532345324453254532645327453284532945330453314533245333453344533545336453374533845339453404534145342453434534445345453464534745348453494535045351453524535345354453554535645357453584535945360453614536245363453644536545366453674536845369453704537145372453734537445375453764537745378453794538045381453824538345384453854538645387453884538945390453914539245393453944539545396453974539845399454004540145402454034540445405454064540745408454094541045411454124541345414454154541645417454184541945420454214542245423454244542545426454274542845429454304543145432454334543445435454364543745438454394544045441454424544345444454454544645447454484544945450454514545245453454544545545456454574545845459454604546145462454634546445465454664546745468454694547045471454724547345474454754547645477454784547945480454814548245483454844548545486454874548845489454904549145492454934549445495454964549745498454994550045501455024550345504455054550645507455084550945510455114551245513455144551545516455174551845519455204552145522455234552445525455264552745528455294553045531455324553345534455354553645537455384553945540455414554245543455444554545546455474554845549455504555145552455534555445555455564555745558455594556045561455624556345564455654556645567455684556945570455714557245573455744557545576455774557845579455804558145582455834558445585455864558745588455894559045591455924559345594455954559645597455984559945600456014560245603456044560545606456074560845609456104561145612456134561445615456164561745618456194562045621456224562345624456254562645627456284562945630456314563245633456344563545636456374563845639456404564145642456434564445645456464564745648456494565045651456524565345654456554565645657456584565945660456614566245663456644566545666456674566845669456704567145672456734567445675456764567745678456794568045681456824568345684456854568645687456884568945690456914569245693456944569545696456974569845699457004570145702457034570445705457064570745708457094571045711457124571345714457154571645717457184571945720457214572245723457244572545726457274572845729457304573145732457334573445735457364573745738457394574045741457424574345744457454574645747457484574945750457514575245753457544575545756457574575845759457604576145762457634576445765457664576745768457694577045771457724577345774457754577645777457784577945780457814578245783457844578545786457874578845789457904579145792457934579445795457964579745798457994580045801458024580345804458054580645807458084580945810458114581245813458144581545816458174581845819458204582145822458234582445825458264582745828458294583045831458324583345834458354583645837458384583945840458414584245843458444584545846458474584845849458504585145852458534585445855458564585745858458594586045861458624586345864458654586645867458684586945870458714587245873458744587545876458774587845879458804588145882458834588445885458864588745888458894589045891458924589345894458954589645897458984589945900459014590245903459044590545906459074590845909459104591145912459134591445915459164591745918459194592045921459224592345924459254592645927459284592945930459314593245933459344593545936459374593845939459404594145942459434594445945459464594745948459494595045951459524595345954459554595645957459584595945960459614596245963459644596545966459674596845969459704597145972459734597445975459764597745978459794598045981459824598345984459854598645987459884598945990459914599245993459944599545996459974599845999460004600146002460034600446005460064600746008460094601046011460124601346014460154601646017460184601946020460214602246023460244602546026460274602846029460304603146032460334603446035460364603746038460394604046041460424604346044460454604646047460484604946050460514605246053460544605546056460574605846059460604606146062460634606446065460664606746068460694607046071460724607346074460754607646077460784607946080460814608246083460844608546086460874608846089460904609146092460934609446095460964609746098460994610046101461024610346104461054610646107461084610946110461114611246113461144611546116461174611846119461204612146122461234612446125461264612746128461294613046131461324613346134461354613646137461384613946140461414614246143461444614546146461474614846149461504615146152461534615446155461564615746158461594616046161461624616346164461654616646167461684616946170461714617246173461744617546176461774617846179461804618146182461834618446185461864618746188461894619046191461924619346194461954619646197461984619946200462014620246203462044620546206462074620846209462104621146212462134621446215462164621746218462194622046221462224622346224462254622646227462284622946230462314623246233462344623546236462374623846239462404624146242462434624446245462464624746248462494625046251462524625346254462554625646257462584625946260462614626246263462644626546266462674626846269462704627146272462734627446275462764627746278462794628046281462824628346284462854628646287462884628946290462914629246293462944629546296462974629846299463004630146302463034630446305463064630746308463094631046311463124631346314463154631646317463184631946320463214632246323463244632546326463274632846329463304633146332463334633446335463364633746338463394634046341463424634346344463454634646347463484634946350463514635246353463544635546356463574635846359463604636146362463634636446365463664636746368463694637046371463724637346374463754637646377463784637946380463814638246383463844638546386463874638846389463904639146392463934639446395463964639746398463994640046401464024640346404464054640646407464084640946410464114641246413464144641546416464174641846419464204642146422464234642446425464264642746428464294643046431464324643346434464354643646437464384643946440464414644246443464444644546446464474644846449464504645146452464534645446455464564645746458464594646046461464624646346464464654646646467464684646946470464714647246473464744647546476464774647846479464804648146482464834648446485464864648746488464894649046491464924649346494464954649646497464984649946500465014650246503465044650546506465074650846509465104651146512465134651446515465164651746518465194652046521465224652346524465254652646527465284652946530465314653246533465344653546536465374653846539465404654146542465434654446545465464654746548465494655046551465524655346554465554655646557465584655946560465614656246563465644656546566465674656846569465704657146572465734657446575465764657746578465794658046581465824658346584465854658646587465884658946590465914659246593465944659546596465974659846599466004660146602466034660446605466064660746608466094661046611466124661346614466154661646617466184661946620466214662246623466244662546626466274662846629466304663146632466334663446635466364663746638466394664046641466424664346644466454664646647466484664946650466514665246653466544665546656466574665846659466604666146662466634666446665466664666746668466694667046671466724667346674466754667646677466784667946680466814668246683466844668546686466874668846689466904669146692466934669446695466964669746698466994670046701467024670346704467054670646707467084670946710467114671246713467144671546716467174671846719467204672146722467234672446725467264672746728467294673046731467324673346734467354673646737467384673946740467414674246743467444674546746467474674846749467504675146752467534675446755467564675746758467594676046761467624676346764467654676646767467684676946770467714677246773467744677546776467774677846779467804678146782467834678446785467864678746788467894679046791467924679346794467954679646797467984679946800468014680246803468044680546806468074680846809468104681146812468134681446815468164681746818468194682046821468224682346824468254682646827468284682946830468314683246833468344683546836468374683846839468404684146842468434684446845468464684746848468494685046851468524685346854468554685646857468584685946860468614686246863468644686546866468674686846869468704687146872468734687446875468764687746878468794688046881468824688346884468854688646887468884688946890468914689246893468944689546896468974689846899469004690146902469034690446905469064690746908469094691046911469124691346914469154691646917469184691946920469214692246923469244692546926469274692846929469304693146932469334693446935469364693746938469394694046941469424694346944469454694646947469484694946950469514695246953469544695546956469574695846959469604696146962469634696446965469664696746968469694697046971469724697346974469754697646977469784697946980469814698246983469844698546986469874698846989469904699146992469934699446995469964699746998469994700047001470024700347004470054700647007470084700947010470114701247013470144701547016470174701847019470204702147022470234702447025470264702747028470294703047031470324703347034470354703647037470384703947040470414704247043470444704547046470474704847049470504705147052470534705447055470564705747058470594706047061470624706347064470654706647067470684706947070470714707247073470744707547076470774707847079470804708147082470834708447085470864708747088470894709047091470924709347094470954709647097470984709947100471014710247103471044710547106471074710847109471104711147112471134711447115471164711747118471194712047121471224712347124471254712647127471284712947130471314713247133471344713547136471374713847139471404714147142471434714447145471464714747148471494715047151471524715347154471554715647157471584715947160471614716247163471644716547166471674716847169471704717147172471734717447175471764717747178471794718047181471824718347184471854718647187471884718947190471914719247193471944719547196471974719847199472004720147202472034720447205472064720747208472094721047211472124721347214472154721647217472184721947220472214722247223472244722547226472274722847229472304723147232472334723447235472364723747238472394724047241472424724347244472454724647247472484724947250472514725247253472544725547256472574725847259472604726147262472634726447265472664726747268472694727047271472724727347274472754727647277472784727947280472814728247283472844728547286472874728847289472904729147292472934729447295472964729747298472994730047301473024730347304473054730647307473084730947310473114731247313473144731547316473174731847319473204732147322473234732447325473264732747328473294733047331473324733347334473354733647337473384733947340473414734247343473444734547346473474734847349473504735147352473534735447355473564735747358473594736047361473624736347364473654736647367473684736947370473714737247373473744737547376473774737847379473804738147382473834738447385473864738747388473894739047391473924739347394473954739647397473984739947400474014740247403474044740547406474074740847409474104741147412474134741447415474164741747418474194742047421474224742347424474254742647427474284742947430474314743247433474344743547436474374743847439474404744147442474434744447445474464744747448474494745047451474524745347454474554745647457474584745947460474614746247463474644746547466474674746847469474704747147472474734747447475474764747747478474794748047481474824748347484474854748647487474884748947490474914749247493474944749547496474974749847499475004750147502475034750447505475064750747508475094751047511475124751347514475154751647517475184751947520475214752247523475244752547526475274752847529475304753147532475334753447535475364753747538475394754047541475424754347544475454754647547475484754947550475514755247553475544755547556475574755847559475604756147562475634756447565475664756747568475694757047571475724757347574475754757647577475784757947580475814758247583475844758547586475874758847589475904759147592475934759447595475964759747598475994760047601476024760347604476054760647607476084760947610476114761247613476144761547616476174761847619476204762147622476234762447625476264762747628476294763047631476324763347634476354763647637476384763947640476414764247643476444764547646476474764847649476504765147652476534765447655476564765747658476594766047661476624766347664476654766647667476684766947670476714767247673476744767547676476774767847679476804768147682476834768447685476864768747688476894769047691476924769347694476954769647697476984769947700477014770247703477044770547706477074770847709477104771147712477134771447715477164771747718477194772047721477224772347724477254772647727477284772947730477314773247733477344773547736477374773847739477404774147742477434774447745477464774747748477494775047751477524775347754477554775647757477584775947760477614776247763477644776547766477674776847769477704777147772477734777447775477764777747778477794778047781477824778347784477854778647787477884778947790477914779247793477944779547796477974779847799478004780147802478034780447805478064780747808478094781047811478124781347814478154781647817478184781947820478214782247823478244782547826478274782847829478304783147832478334783447835478364783747838478394784047841478424784347844478454784647847478484784947850478514785247853478544785547856478574785847859478604786147862478634786447865478664786747868478694787047871478724787347874478754787647877478784787947880478814788247883478844788547886478874788847889478904789147892478934789447895478964789747898478994790047901479024790347904479054790647907479084790947910479114791247913479144791547916479174791847919479204792147922479234792447925479264792747928479294793047931479324793347934479354793647937479384793947940479414794247943479444794547946479474794847949479504795147952479534795447955479564795747958479594796047961479624796347964479654796647967479684796947970479714797247973479744797547976479774797847979479804798147982479834798447985479864798747988479894799047991479924799347994479954799647997479984799948000480014800248003480044800548006480074800848009480104801148012480134801448015480164801748018480194802048021480224802348024480254802648027480284802948030480314803248033480344803548036480374803848039480404804148042480434804448045480464804748048480494805048051480524805348054480554805648057480584805948060480614806248063480644806548066480674806848069480704807148072480734807448075480764807748078480794808048081480824808348084480854808648087480884808948090480914809248093480944809548096480974809848099481004810148102481034810448105481064810748108481094811048111481124811348114481154811648117481184811948120481214812248123481244812548126481274812848129481304813148132481334813448135481364813748138481394814048141481424814348144481454814648147481484814948150481514815248153481544815548156481574815848159481604816148162481634816448165481664816748168481694817048171481724817348174481754817648177481784817948180481814818248183481844818548186481874818848189481904819148192481934819448195481964819748198481994820048201482024820348204482054820648207482084820948210482114821248213482144821548216482174821848219482204822148222482234822448225482264822748228482294823048231482324823348234482354823648237482384823948240482414824248243482444824548246482474824848249482504825148252482534825448255482564825748258482594826048261482624826348264482654826648267482684826948270482714827248273482744827548276482774827848279482804828148282482834828448285482864828748288482894829048291482924829348294482954829648297482984829948300483014830248303483044830548306483074830848309483104831148312483134831448315483164831748318483194832048321483224832348324483254832648327483284832948330483314833248333483344833548336483374833848339483404834148342483434834448345483464834748348483494835048351483524835348354483554835648357483584835948360483614836248363483644836548366483674836848369483704837148372483734837448375483764837748378483794838048381483824838348384483854838648387483884838948390483914839248393483944839548396483974839848399484004840148402484034840448405484064840748408484094841048411484124841348414484154841648417484184841948420484214842248423484244842548426484274842848429484304843148432484334843448435484364843748438484394844048441484424844348444484454844648447484484844948450484514845248453484544845548456484574845848459484604846148462484634846448465484664846748468484694847048471484724847348474484754847648477484784847948480484814848248483484844848548486484874848848489484904849148492484934849448495484964849748498484994850048501485024850348504485054850648507485084850948510485114851248513485144851548516485174851848519485204852148522485234852448525485264852748528485294853048531485324853348534485354853648537485384853948540485414854248543485444854548546485474854848549485504855148552485534855448555485564855748558485594856048561485624856348564485654856648567485684856948570485714857248573485744857548576485774857848579485804858148582485834858448585485864858748588485894859048591485924859348594485954859648597485984859948600486014860248603486044860548606486074860848609486104861148612486134861448615486164861748618486194862048621486224862348624486254862648627486284862948630486314863248633486344863548636486374863848639486404864148642486434864448645486464864748648486494865048651486524865348654486554865648657486584865948660486614866248663486644866548666486674866848669486704867148672486734867448675486764867748678486794868048681486824868348684486854868648687486884868948690486914869248693486944869548696486974869848699487004870148702487034870448705487064870748708487094871048711487124871348714487154871648717487184871948720487214872248723487244872548726487274872848729487304873148732487334873448735487364873748738487394874048741487424874348744487454874648747487484874948750487514875248753487544875548756487574875848759487604876148762487634876448765487664876748768487694877048771487724877348774487754877648777487784877948780487814878248783487844878548786487874878848789487904879148792487934879448795487964879748798487994880048801488024880348804488054880648807488084880948810488114881248813488144881548816488174881848819488204882148822488234882448825488264882748828488294883048831488324883348834488354883648837488384883948840488414884248843488444884548846488474884848849488504885148852488534885448855488564885748858488594886048861488624886348864488654886648867488684886948870488714887248873488744887548876488774887848879488804888148882488834888448885488864888748888488894889048891488924889348894488954889648897488984889948900489014890248903489044890548906489074890848909489104891148912489134891448915489164891748918489194892048921489224892348924489254892648927489284892948930489314893248933489344893548936489374893848939489404894148942489434894448945489464894748948489494895048951489524895348954489554895648957489584895948960489614896248963489644896548966489674896848969489704897148972489734897448975489764897748978489794898048981489824898348984489854898648987489884898948990489914899248993489944899548996489974899848999490004900149002490034900449005490064900749008490094901049011490124901349014490154901649017490184901949020490214902249023490244902549026490274902849029490304903149032490334903449035490364903749038490394904049041490424904349044490454904649047490484904949050490514905249053490544905549056490574905849059490604906149062490634906449065490664906749068490694907049071490724907349074490754907649077490784907949080490814908249083490844908549086490874908849089490904909149092490934909449095490964909749098490994910049101491024910349104491054910649107491084910949110491114911249113491144911549116491174911849119491204912149122491234912449125491264912749128491294913049131491324913349134491354913649137491384913949140491414914249143491444914549146491474914849149491504915149152491534915449155491564915749158491594916049161491624916349164491654916649167491684916949170491714917249173491744917549176491774917849179491804918149182491834918449185491864918749188491894919049191491924919349194491954919649197491984919949200492014920249203492044920549206492074920849209492104921149212492134921449215492164921749218492194922049221492224922349224492254922649227492284922949230492314923249233492344923549236492374923849239492404924149242492434924449245492464924749248492494925049251492524925349254492554925649257492584925949260492614926249263492644926549266492674926849269492704927149272492734927449275492764927749278492794928049281492824928349284492854928649287492884928949290492914929249293492944929549296492974929849299493004930149302493034930449305493064930749308493094931049311493124931349314493154931649317493184931949320493214932249323493244932549326493274932849329493304933149332493334933449335493364933749338493394934049341493424934349344493454934649347493484934949350493514935249353493544935549356493574935849359493604936149362493634936449365493664936749368493694937049371493724937349374493754937649377493784937949380493814938249383493844938549386493874938849389493904939149392493934939449395493964939749398493994940049401494024940349404494054940649407494084940949410494114941249413494144941549416494174941849419494204942149422494234942449425494264942749428494294943049431494324943349434494354943649437494384943949440494414944249443494444944549446494474944849449494504945149452494534945449455494564945749458494594946049461494624946349464494654946649467494684946949470494714947249473494744947549476494774947849479494804948149482494834948449485494864948749488494894949049491494924949349494494954949649497494984949949500495014950249503495044950549506495074950849509495104951149512495134951449515495164951749518495194952049521495224952349524495254952649527495284952949530495314953249533495344953549536495374953849539495404954149542495434954449545495464954749548495494955049551495524955349554495554955649557495584955949560495614956249563495644956549566495674956849569495704957149572495734957449575495764957749578495794958049581495824958349584495854958649587495884958949590495914959249593495944959549596495974959849599496004960149602496034960449605496064960749608496094961049611496124961349614496154961649617496184961949620496214962249623496244962549626496274962849629496304963149632496334963449635496364963749638496394964049641496424964349644496454964649647496484964949650496514965249653496544965549656496574965849659496604966149662496634966449665496664966749668496694967049671496724967349674496754967649677496784967949680496814968249683496844968549686496874968849689496904969149692496934969449695496964969749698496994970049701497024970349704497054970649707497084970949710497114971249713497144971549716497174971849719497204972149722497234972449725497264972749728497294973049731497324973349734497354973649737497384973949740497414974249743497444974549746497474974849749497504975149752497534975449755497564975749758497594976049761497624976349764497654976649767497684976949770497714977249773497744977549776497774977849779497804978149782497834978449785497864978749788497894979049791497924979349794497954979649797497984979949800498014980249803498044980549806498074980849809498104981149812498134981449815498164981749818498194982049821498224982349824498254982649827498284982949830498314983249833498344983549836498374983849839498404984149842498434984449845498464984749848498494985049851498524985349854498554985649857498584985949860498614986249863498644986549866498674986849869498704987149872498734987449875498764987749878498794988049881498824988349884498854988649887498884988949890498914989249893498944989549896498974989849899499004990149902499034990449905499064990749908499094991049911499124991349914499154991649917499184991949920499214992249923499244992549926499274992849929499304993149932499334993449935499364993749938499394994049941499424994349944499454994649947499484994949950499514995249953499544995549956499574995849959499604996149962499634996449965499664996749968499694997049971499724997349974499754997649977499784997949980499814998249983499844998549986499874998849989499904999149992499934999449995499964999749998499995000050001500025000350004500055000650007500085000950010500115001250013500145001550016500175001850019500205002150022500235002450025500265002750028500295003050031500325003350034500355003650037500385003950040500415004250043500445004550046500475004850049500505005150052500535005450055500565005750058500595006050061500625006350064500655006650067500685006950070500715007250073500745007550076500775007850079500805008150082500835008450085500865008750088500895009050091500925009350094500955009650097500985009950100501015010250103501045010550106501075010850109501105011150112501135011450115501165011750118501195012050121501225012350124501255012650127501285012950130501315013250133501345013550136501375013850139501405014150142501435014450145501465014750148501495015050151501525015350154501555015650157501585015950160501615016250163501645016550166501675016850169501705017150172501735017450175501765017750178501795018050181501825018350184501855018650187501885018950190501915019250193501945019550196501975019850199502005020150202502035020450205502065020750208502095021050211502125021350214502155021650217502185021950220502215022250223502245022550226502275022850229502305023150232502335023450235502365023750238502395024050241502425024350244502455024650247502485024950250502515025250253502545025550256502575025850259502605026150262502635026450265502665026750268502695027050271502725027350274502755027650277502785027950280502815028250283502845028550286502875028850289502905029150292502935029450295502965029750298502995030050301503025030350304503055030650307503085030950310503115031250313503145031550316503175031850319503205032150322503235032450325503265032750328503295033050331503325033350334503355033650337503385033950340503415034250343503445034550346503475034850349503505035150352503535035450355503565035750358503595036050361503625036350364503655036650367503685036950370503715037250373503745037550376503775037850379503805038150382503835038450385503865038750388503895039050391503925039350394503955039650397503985039950400504015040250403504045040550406504075040850409504105041150412504135041450415504165041750418504195042050421504225042350424504255042650427504285042950430504315043250433504345043550436504375043850439504405044150442504435044450445504465044750448504495045050451504525045350454504555045650457504585045950460504615046250463504645046550466504675046850469504705047150472504735047450475504765047750478504795048050481504825048350484504855048650487504885048950490504915049250493504945049550496504975049850499505005050150502505035050450505505065050750508505095051050511505125051350514505155051650517505185051950520505215052250523505245052550526505275052850529505305053150532505335053450535505365053750538505395054050541505425054350544505455054650547505485054950550505515055250553505545055550556505575055850559505605056150562505635056450565505665056750568505695057050571505725057350574505755057650577505785057950580505815058250583505845058550586505875058850589505905059150592505935059450595505965059750598505995060050601506025060350604506055060650607506085060950610506115061250613506145061550616506175061850619506205062150622506235062450625506265062750628506295063050631506325063350634506355063650637506385063950640506415064250643506445064550646506475064850649506505065150652506535065450655506565065750658506595066050661506625066350664506655066650667506685066950670506715067250673506745067550676506775067850679506805068150682506835068450685506865068750688506895069050691506925069350694506955069650697506985069950700507015070250703507045070550706507075070850709507105071150712507135071450715507165071750718507195072050721507225072350724507255072650727507285072950730507315073250733507345073550736507375073850739507405074150742507435074450745507465074750748507495075050751507525075350754507555075650757507585075950760507615076250763507645076550766507675076850769507705077150772507735077450775507765077750778507795078050781507825078350784507855078650787507885078950790507915079250793507945079550796507975079850799508005080150802508035080450805508065080750808508095081050811508125081350814508155081650817508185081950820508215082250823508245082550826508275082850829508305083150832508335083450835508365083750838508395084050841508425084350844508455084650847508485084950850508515085250853508545085550856508575085850859508605086150862508635086450865508665086750868508695087050871508725087350874508755087650877508785087950880508815088250883508845088550886508875088850889508905089150892508935089450895508965089750898508995090050901509025090350904509055090650907509085090950910509115091250913509145091550916509175091850919509205092150922509235092450925509265092750928509295093050931509325093350934509355093650937509385093950940509415094250943509445094550946509475094850949509505095150952509535095450955509565095750958509595096050961509625096350964509655096650967509685096950970509715097250973509745097550976509775097850979509805098150982509835098450985509865098750988509895099050991509925099350994509955099650997509985099951000510015100251003510045100551006510075100851009510105101151012510135101451015510165101751018510195102051021510225102351024510255102651027510285102951030510315103251033510345103551036510375103851039510405104151042510435104451045510465104751048510495105051051510525105351054510555105651057510585105951060510615106251063510645106551066510675106851069510705107151072510735107451075510765107751078510795108051081510825108351084510855108651087510885108951090510915109251093510945109551096510975109851099511005110151102511035110451105511065110751108511095111051111511125111351114511155111651117511185111951120511215112251123511245112551126511275112851129511305113151132511335113451135511365113751138511395114051141511425114351144511455114651147511485114951150511515115251153511545115551156511575115851159511605116151162511635116451165511665116751168511695117051171511725117351174511755117651177511785117951180511815118251183511845118551186511875118851189511905119151192511935119451195511965119751198511995120051201512025120351204512055120651207512085120951210512115121251213512145121551216512175121851219512205122151222512235122451225512265122751228512295123051231512325123351234512355123651237512385123951240512415124251243512445124551246512475124851249512505125151252512535125451255512565125751258512595126051261512625126351264512655126651267512685126951270512715127251273512745127551276512775127851279512805128151282512835128451285512865128751288512895129051291512925129351294512955129651297512985129951300513015130251303513045130551306513075130851309513105131151312513135131451315513165131751318513195132051321513225132351324513255132651327513285132951330513315133251333513345133551336513375133851339513405134151342513435134451345513465134751348513495135051351513525135351354513555135651357513585135951360513615136251363513645136551366513675136851369513705137151372513735137451375513765137751378513795138051381513825138351384513855138651387513885138951390513915139251393513945139551396513975139851399514005140151402514035140451405514065140751408514095141051411514125141351414514155141651417514185141951420514215142251423514245142551426514275142851429514305143151432514335143451435514365143751438514395144051441514425144351444514455144651447514485144951450514515145251453514545145551456514575145851459514605146151462514635146451465514665146751468514695147051471514725147351474514755147651477514785147951480514815148251483514845148551486514875148851489514905149151492514935149451495514965149751498514995150051501515025150351504515055150651507515085150951510515115151251513515145151551516515175151851519515205152151522515235152451525515265152751528515295153051531515325153351534515355153651537515385153951540515415154251543515445154551546515475154851549515505155151552515535155451555515565155751558515595156051561515625156351564515655156651567515685156951570515715157251573515745157551576515775157851579515805158151582515835158451585515865158751588515895159051591515925159351594515955159651597515985159951600516015160251603516045160551606516075160851609516105161151612516135161451615516165161751618516195162051621516225162351624516255162651627516285162951630516315163251633516345163551636516375163851639516405164151642516435164451645516465164751648516495165051651516525165351654516555165651657516585165951660516615166251663516645166551666516675166851669516705167151672516735167451675516765167751678516795168051681516825168351684516855168651687516885168951690516915169251693516945169551696516975169851699517005170151702517035170451705517065170751708517095171051711517125171351714517155171651717517185171951720517215172251723517245172551726517275172851729517305173151732517335173451735517365173751738517395174051741517425174351744517455174651747517485174951750517515175251753517545175551756517575175851759517605176151762517635176451765517665176751768517695177051771517725177351774517755177651777517785177951780517815178251783517845178551786517875178851789517905179151792517935179451795517965179751798517995180051801518025180351804518055180651807518085180951810518115181251813518145181551816518175181851819518205182151822518235182451825518265182751828518295183051831518325183351834518355183651837518385183951840518415184251843518445184551846518475184851849518505185151852518535185451855518565185751858518595186051861518625186351864518655186651867518685186951870518715187251873518745187551876518775187851879518805188151882518835188451885518865188751888518895189051891518925189351894518955189651897518985189951900519015190251903519045190551906519075190851909519105191151912519135191451915519165191751918519195192051921519225192351924519255192651927519285192951930519315193251933519345193551936519375193851939519405194151942519435194451945519465194751948519495195051951519525195351954519555195651957519585195951960519615196251963519645196551966519675196851969519705197151972519735197451975519765197751978519795198051981519825198351984519855198651987519885198951990519915199251993519945199551996519975199851999520005200152002520035200452005520065200752008520095201052011520125201352014520155201652017520185201952020520215202252023520245202552026520275202852029520305203152032520335203452035520365203752038520395204052041520425204352044520455204652047520485204952050520515205252053520545205552056520575205852059520605206152062520635206452065520665206752068520695207052071520725207352074520755207652077520785207952080520815208252083520845208552086520875208852089520905209152092520935209452095520965209752098520995210052101521025210352104521055210652107521085210952110521115211252113521145211552116521175211852119521205212152122521235212452125521265212752128521295213052131521325213352134521355213652137521385213952140521415214252143521445214552146521475214852149521505215152152521535215452155521565215752158521595216052161521625216352164521655216652167521685216952170521715217252173521745217552176521775217852179521805218152182521835218452185521865218752188521895219052191521925219352194521955219652197521985219952200522015220252203522045220552206522075220852209522105221152212522135221452215522165221752218522195222052221522225222352224522255222652227522285222952230522315223252233522345223552236522375223852239522405224152242522435224452245522465224752248522495225052251522525225352254522555225652257522585225952260522615226252263522645226552266522675226852269522705227152272522735227452275522765227752278522795228052281522825228352284522855228652287522885228952290522915229252293522945229552296522975229852299523005230152302523035230452305523065230752308523095231052311523125231352314523155231652317523185231952320523215232252323523245232552326523275232852329523305233152332523335233452335523365233752338523395234052341523425234352344523455234652347523485234952350523515235252353523545235552356523575235852359523605236152362523635236452365523665236752368523695237052371523725237352374523755237652377523785237952380523815238252383523845238552386523875238852389523905239152392523935239452395523965239752398523995240052401524025240352404524055240652407524085240952410524115241252413524145241552416524175241852419524205242152422524235242452425524265242752428524295243052431524325243352434524355243652437524385243952440524415244252443524445244552446524475244852449524505245152452524535245452455524565245752458524595246052461524625246352464524655246652467524685246952470524715247252473524745247552476524775247852479524805248152482524835248452485524865248752488524895249052491524925249352494524955249652497524985249952500525015250252503525045250552506525075250852509525105251152512525135251452515525165251752518525195252052521525225252352524525255252652527525285252952530525315253252533525345253552536525375253852539525405254152542525435254452545525465254752548525495255052551525525255352554525555255652557525585255952560525615256252563525645256552566525675256852569525705257152572525735257452575525765257752578525795258052581525825258352584525855258652587525885258952590525915259252593525945259552596525975259852599526005260152602526035260452605526065260752608526095261052611526125261352614526155261652617526185261952620526215262252623526245262552626526275262852629526305263152632526335263452635526365263752638526395264052641526425264352644526455264652647526485264952650526515265252653526545265552656526575265852659526605266152662526635266452665526665266752668526695267052671526725267352674526755267652677526785267952680526815268252683526845268552686526875268852689526905269152692526935269452695526965269752698526995270052701527025270352704527055270652707527085270952710527115271252713527145271552716527175271852719527205272152722527235272452725527265272752728527295273052731527325273352734527355273652737527385273952740527415274252743527445274552746527475274852749527505275152752527535275452755527565275752758527595276052761527625276352764527655276652767527685276952770527715277252773527745277552776527775277852779527805278152782527835278452785527865278752788527895279052791527925279352794527955279652797527985279952800528015280252803528045280552806528075280852809528105281152812528135281452815528165281752818528195282052821528225282352824528255282652827528285282952830528315283252833528345283552836528375283852839528405284152842528435284452845528465284752848528495285052851528525285352854528555285652857528585285952860528615286252863528645286552866528675286852869528705287152872528735287452875528765287752878528795288052881528825288352884528855288652887528885288952890528915289252893528945289552896528975289852899529005290152902529035290452905529065290752908529095291052911529125291352914529155291652917529185291952920529215292252923529245292552926529275292852929529305293152932529335293452935529365293752938529395294052941529425294352944529455294652947529485294952950529515295252953529545295552956529575295852959529605296152962529635296452965529665296752968529695297052971529725297352974529755297652977529785297952980529815298252983529845298552986529875298852989529905299152992529935299452995529965299752998529995300053001530025300353004530055300653007530085300953010530115301253013530145301553016530175301853019530205302153022530235302453025530265302753028530295303053031530325303353034530355303653037530385303953040530415304253043530445304553046530475304853049530505305153052530535305453055530565305753058530595306053061530625306353064530655306653067530685306953070530715307253073530745307553076530775307853079530805308153082530835308453085530865308753088530895309053091530925309353094530955309653097530985309953100531015310253103531045310553106531075310853109531105311153112531135311453115531165311753118531195312053121531225312353124531255312653127531285312953130531315313253133531345313553136531375313853139531405314153142531435314453145531465314753148531495315053151531525315353154531555315653157531585315953160531615316253163531645316553166531675316853169531705317153172531735317453175531765317753178531795318053181531825318353184531855318653187531885318953190531915319253193531945319553196531975319853199532005320153202532035320453205532065320753208532095321053211532125321353214532155321653217532185321953220532215322253223532245322553226532275322853229532305323153232532335323453235532365323753238532395324053241532425324353244532455324653247532485324953250532515325253253532545325553256532575325853259532605326153262532635326453265532665326753268532695327053271532725327353274532755327653277532785327953280532815328253283532845328553286532875328853289532905329153292532935329453295532965329753298532995330053301533025330353304533055330653307533085330953310533115331253313533145331553316533175331853319533205332153322533235332453325533265332753328533295333053331533325333353334533355333653337533385333953340533415334253343533445334553346533475334853349533505335153352533535335453355533565335753358533595336053361533625336353364533655336653367533685336953370533715337253373533745337553376533775337853379533805338153382533835338453385533865338753388533895339053391533925339353394533955339653397533985339953400534015340253403534045340553406534075340853409534105341153412534135341453415534165341753418534195342053421534225342353424534255342653427534285342953430534315343253433534345343553436534375343853439534405344153442534435344453445534465344753448534495345053451534525345353454534555345653457534585345953460534615346253463534645346553466534675346853469534705347153472534735347453475534765347753478534795348053481534825348353484534855348653487534885348953490534915349253493534945349553496534975349853499535005350153502535035350453505535065350753508535095351053511535125351353514535155351653517535185351953520535215352253523535245352553526535275352853529535305353153532535335353453535535365353753538535395354053541535425354353544535455354653547535485354953550535515355253553535545355553556535575355853559535605356153562535635356453565535665356753568535695357053571535725357353574535755357653577535785357953580535815358253583535845358553586535875358853589535905359153592535935359453595535965359753598535995360053601536025360353604536055360653607536085360953610536115361253613536145361553616536175361853619536205362153622536235362453625536265362753628536295363053631536325363353634536355363653637536385363953640536415364253643536445364553646536475364853649536505365153652536535365453655536565365753658536595366053661536625366353664536655366653667536685366953670536715367253673536745367553676536775367853679536805368153682536835368453685536865368753688536895369053691536925369353694536955369653697536985369953700537015370253703537045370553706537075370853709537105371153712537135371453715537165371753718537195372053721537225372353724537255372653727537285372953730537315373253733537345373553736537375373853739537405374153742537435374453745537465374753748537495375053751537525375353754537555375653757537585375953760537615376253763537645376553766537675376853769537705377153772537735377453775537765377753778537795378053781537825378353784537855378653787537885378953790537915379253793537945379553796537975379853799538005380153802538035380453805538065380753808538095381053811538125381353814538155381653817538185381953820538215382253823538245382553826538275382853829538305383153832538335383453835538365383753838538395384053841538425384353844538455384653847538485384953850538515385253853538545385553856538575385853859538605386153862538635386453865538665386753868538695387053871538725387353874538755387653877538785387953880538815388253883538845388553886538875388853889538905389153892538935389453895538965389753898538995390053901539025390353904539055390653907539085390953910539115391253913539145391553916539175391853919539205392153922539235392453925539265392753928539295393053931539325393353934539355393653937539385393953940539415394253943539445394553946539475394853949539505395153952539535395453955539565395753958539595396053961539625396353964539655396653967539685396953970539715397253973539745397553976539775397853979539805398153982539835398453985539865398753988539895399053991539925399353994539955399653997539985399954000540015400254003540045400554006540075400854009540105401154012540135401454015540165401754018540195402054021540225402354024540255402654027540285402954030540315403254033540345403554036540375403854039540405404154042540435404454045540465404754048540495405054051540525405354054540555405654057540585405954060540615406254063540645406554066540675406854069540705407154072540735407454075540765407754078540795408054081540825408354084540855408654087540885408954090540915409254093540945409554096540975409854099541005410154102541035410454105541065410754108541095411054111541125411354114541155411654117541185411954120541215412254123541245412554126541275412854129541305413154132541335413454135541365413754138541395414054141541425414354144541455414654147541485414954150541515415254153541545415554156541575415854159541605416154162541635416454165541665416754168541695417054171541725417354174541755417654177541785417954180541815418254183541845418554186541875418854189541905419154192541935419454195541965419754198541995420054201542025420354204542055420654207542085420954210542115421254213542145421554216542175421854219542205422154222542235422454225542265422754228542295423054231542325423354234542355423654237542385423954240542415424254243542445424554246542475424854249542505425154252542535425454255542565425754258542595426054261542625426354264542655426654267542685426954270542715427254273542745427554276542775427854279542805428154282542835428454285542865428754288542895429054291542925429354294542955429654297542985429954300543015430254303543045430554306543075430854309543105431154312543135431454315543165431754318543195432054321543225432354324543255432654327543285432954330543315433254333543345433554336543375433854339543405434154342543435434454345543465434754348543495435054351543525435354354543555435654357543585435954360543615436254363543645436554366543675436854369543705437154372543735437454375543765437754378543795438054381543825438354384543855438654387543885438954390543915439254393543945439554396543975439854399544005440154402544035440454405544065440754408544095441054411544125441354414544155441654417544185441954420544215442254423544245442554426544275442854429544305443154432544335443454435544365443754438544395444054441544425444354444544455444654447544485444954450544515445254453544545445554456544575445854459544605446154462544635446454465544665446754468544695447054471544725447354474544755447654477544785447954480544815448254483544845448554486544875448854489544905449154492544935449454495544965449754498544995450054501545025450354504545055450654507545085450954510545115451254513545145451554516545175451854519545205452154522545235452454525545265452754528545295453054531545325453354534545355453654537545385453954540545415454254543545445454554546545475454854549545505455154552545535455454555545565455754558545595456054561545625456354564545655456654567545685456954570545715457254573545745457554576545775457854579545805458154582545835458454585545865458754588545895459054591545925459354594545955459654597545985459954600546015460254603546045460554606546075460854609546105461154612546135461454615546165461754618546195462054621546225462354624546255462654627546285462954630546315463254633546345463554636546375463854639546405464154642546435464454645546465464754648546495465054651546525465354654546555465654657546585465954660546615466254663546645466554666546675466854669546705467154672546735467454675546765467754678546795468054681546825468354684546855468654687546885468954690546915469254693546945469554696546975469854699547005470154702547035470454705547065470754708547095471054711547125471354714547155471654717547185471954720547215472254723547245472554726547275472854729547305473154732547335473454735547365473754738547395474054741547425474354744547455474654747547485474954750547515475254753547545475554756547575475854759547605476154762547635476454765547665476754768547695477054771547725477354774547755477654777547785477954780547815478254783547845478554786547875478854789547905479154792547935479454795547965479754798547995480054801548025480354804548055480654807548085480954810548115481254813548145481554816548175481854819548205482154822548235482454825548265482754828548295483054831548325483354834548355483654837548385483954840548415484254843548445484554846548475484854849548505485154852548535485454855548565485754858548595486054861548625486354864548655486654867548685486954870548715487254873548745487554876548775487854879548805488154882548835488454885548865488754888548895489054891548925489354894548955489654897548985489954900549015490254903549045490554906549075490854909549105491154912549135491454915549165491754918549195492054921549225492354924549255492654927549285492954930549315493254933549345493554936549375493854939549405494154942549435494454945549465494754948549495495054951549525495354954549555495654957549585495954960549615496254963549645496554966549675496854969549705497154972549735497454975549765497754978549795498054981549825498354984549855498654987549885498954990549915499254993549945499554996549975499854999550005500155002550035500455005550065500755008550095501055011550125501355014550155501655017550185501955020550215502255023550245502555026550275502855029550305503155032550335503455035550365503755038550395504055041550425504355044550455504655047550485504955050550515505255053550545505555056550575505855059550605506155062550635506455065550665506755068550695507055071550725507355074550755507655077550785507955080550815508255083550845508555086550875508855089550905509155092550935509455095550965509755098550995510055101551025510355104551055510655107551085510955110551115511255113551145511555116551175511855119551205512155122551235512455125551265512755128551295513055131551325513355134551355513655137551385513955140551415514255143551445514555146551475514855149551505515155152551535515455155551565515755158551595516055161551625516355164551655516655167551685516955170551715517255173551745517555176551775517855179551805518155182551835518455185551865518755188551895519055191551925519355194551955519655197551985519955200552015520255203552045520555206552075520855209552105521155212552135521455215552165521755218552195522055221552225522355224552255522655227552285522955230552315523255233552345523555236552375523855239552405524155242552435524455245552465524755248552495525055251552525525355254552555525655257552585525955260552615526255263552645526555266552675526855269552705527155272552735527455275552765527755278552795528055281552825528355284552855528655287552885528955290552915529255293552945529555296552975529855299553005530155302553035530455305553065530755308553095531055311553125531355314553155531655317553185531955320553215532255323553245532555326553275532855329553305533155332553335533455335553365533755338553395534055341553425534355344553455534655347553485534955350553515535255353553545535555356553575535855359553605536155362553635536455365553665536755368553695537055371553725537355374553755537655377553785537955380553815538255383553845538555386553875538855389553905539155392553935539455395553965539755398553995540055401554025540355404554055540655407554085540955410554115541255413554145541555416554175541855419554205542155422554235542455425554265542755428554295543055431554325543355434554355543655437554385543955440554415544255443554445544555446554475544855449554505545155452554535545455455554565545755458554595546055461554625546355464554655546655467554685546955470554715547255473554745547555476554775547855479554805548155482554835548455485554865548755488554895549055491554925549355494554955549655497554985549955500555015550255503555045550555506555075550855509555105551155512555135551455515555165551755518555195552055521555225552355524555255552655527555285552955530555315553255533555345553555536555375553855539555405554155542555435554455545555465554755548555495555055551555525555355554555555555655557555585555955560555615556255563555645556555566555675556855569555705557155572555735557455575555765557755578555795558055581555825558355584555855558655587555885558955590555915559255593555945559555596555975559855599556005560155602556035560455605556065560755608556095561055611556125561355614556155561655617556185561955620556215562255623556245562555626556275562855629556305563155632556335563455635556365563755638556395564055641556425564355644556455564655647556485564955650556515565255653556545565555656556575565855659556605566155662556635566455665556665566755668556695567055671556725567355674556755567655677556785567955680556815568255683556845568555686556875568855689556905569155692556935569455695556965569755698556995570055701557025570355704557055570655707557085570955710557115571255713557145571555716557175571855719557205572155722557235572455725557265572755728557295573055731557325573355734557355573655737557385573955740557415574255743557445574555746557475574855749557505575155752557535575455755557565575755758557595576055761557625576355764557655576655767557685576955770557715577255773557745577555776557775577855779557805578155782557835578455785557865578755788557895579055791557925579355794557955579655797557985579955800558015580255803558045580555806558075580855809558105581155812558135581455815558165581755818558195582055821558225582355824558255582655827558285582955830558315583255833558345583555836558375583855839558405584155842558435584455845558465584755848558495585055851558525585355854558555585655857558585585955860558615586255863558645586555866558675586855869558705587155872558735587455875558765587755878558795588055881558825588355884558855588655887558885588955890558915589255893558945589555896558975589855899559005590155902559035590455905559065590755908559095591055911559125591355914559155591655917559185591955920559215592255923559245592555926559275592855929559305593155932559335593455935559365593755938559395594055941559425594355944559455594655947559485594955950559515595255953559545595555956559575595855959559605596155962559635596455965559665596755968559695597055971559725597355974559755597655977559785597955980559815598255983559845598555986559875598855989559905599155992559935599455995559965599755998559995600056001560025600356004560055600656007560085600956010560115601256013560145601556016560175601856019560205602156022560235602456025560265602756028560295603056031560325603356034560355603656037560385603956040560415604256043560445604556046560475604856049560505605156052560535605456055560565605756058560595606056061560625606356064560655606656067560685606956070560715607256073560745607556076560775607856079560805608156082560835608456085560865608756088560895609056091560925609356094560955609656097560985609956100561015610256103561045610556106561075610856109561105611156112561135611456115561165611756118561195612056121561225612356124561255612656127561285612956130561315613256133561345613556136561375613856139561405614156142561435614456145561465614756148561495615056151561525615356154561555615656157561585615956160561615616256163561645616556166561675616856169561705617156172561735617456175561765617756178561795618056181561825618356184561855618656187561885618956190561915619256193561945619556196561975619856199562005620156202562035620456205562065620756208562095621056211562125621356214562155621656217562185621956220562215622256223562245622556226562275622856229562305623156232562335623456235562365623756238562395624056241562425624356244562455624656247562485624956250562515625256253562545625556256562575625856259562605626156262562635626456265562665626756268562695627056271562725627356274562755627656277562785627956280562815628256283562845628556286562875628856289562905629156292562935629456295562965629756298562995630056301563025630356304563055630656307563085630956310563115631256313563145631556316563175631856319563205632156322563235632456325563265632756328563295633056331563325633356334563355633656337563385633956340563415634256343563445634556346563475634856349563505635156352563535635456355563565635756358563595636056361563625636356364563655636656367563685636956370563715637256373563745637556376563775637856379563805638156382563835638456385563865638756388563895639056391563925639356394563955639656397563985639956400564015640256403564045640556406564075640856409564105641156412564135641456415564165641756418564195642056421564225642356424564255642656427564285642956430564315643256433564345643556436564375643856439564405644156442564435644456445564465644756448564495645056451564525645356454564555645656457564585645956460564615646256463564645646556466564675646856469564705647156472564735647456475564765647756478564795648056481564825648356484564855648656487564885648956490564915649256493564945649556496564975649856499565005650156502565035650456505565065650756508565095651056511565125651356514565155651656517565185651956520565215652256523565245652556526565275652856529565305653156532565335653456535565365653756538565395654056541565425654356544565455654656547565485654956550565515655256553565545655556556565575655856559565605656156562565635656456565565665656756568565695657056571565725657356574565755657656577565785657956580565815658256583565845658556586565875658856589565905659156592565935659456595565965659756598565995660056601566025660356604566055660656607566085660956610566115661256613566145661556616566175661856619566205662156622566235662456625566265662756628566295663056631566325663356634566355663656637566385663956640566415664256643566445664556646566475664856649566505665156652566535665456655566565665756658566595666056661566625666356664566655666656667566685666956670566715667256673566745667556676566775667856679566805668156682566835668456685566865668756688566895669056691566925669356694566955669656697566985669956700567015670256703567045670556706567075670856709567105671156712567135671456715567165671756718567195672056721567225672356724567255672656727567285672956730567315673256733567345673556736567375673856739567405674156742567435674456745567465674756748567495675056751567525675356754567555675656757567585675956760567615676256763567645676556766567675676856769567705677156772567735677456775567765677756778567795678056781567825678356784567855678656787567885678956790567915679256793567945679556796567975679856799568005680156802568035680456805568065680756808568095681056811568125681356814568155681656817568185681956820568215682256823568245682556826568275682856829568305683156832568335683456835568365683756838568395684056841568425684356844568455684656847568485684956850568515685256853568545685556856568575685856859568605686156862568635686456865568665686756868568695687056871568725687356874568755687656877568785687956880568815688256883568845688556886568875688856889568905689156892568935689456895568965689756898568995690056901569025690356904569055690656907569085690956910569115691256913569145691556916569175691856919569205692156922569235692456925569265692756928569295693056931569325693356934569355693656937569385693956940569415694256943569445694556946569475694856949569505695156952569535695456955569565695756958569595696056961569625696356964569655696656967569685696956970569715697256973569745697556976569775697856979569805698156982569835698456985569865698756988569895699056991569925699356994569955699656997569985699957000570015700257003570045700557006570075700857009570105701157012570135701457015570165701757018570195702057021570225702357024570255702657027570285702957030570315703257033570345703557036570375703857039570405704157042570435704457045570465704757048570495705057051570525705357054570555705657057570585705957060570615706257063570645706557066570675706857069570705707157072570735707457075570765707757078570795708057081570825708357084570855708657087570885708957090570915709257093570945709557096570975709857099571005710157102571035710457105571065710757108571095711057111571125711357114571155711657117571185711957120571215712257123571245712557126571275712857129571305713157132571335713457135571365713757138571395714057141571425714357144571455714657147571485714957150571515715257153571545715557156571575715857159571605716157162571635716457165571665716757168571695717057171571725717357174571755717657177571785717957180571815718257183571845718557186571875718857189571905719157192571935719457195571965719757198571995720057201572025720357204572055720657207572085720957210572115721257213572145721557216572175721857219572205722157222572235722457225572265722757228572295723057231572325723357234572355723657237572385723957240572415724257243572445724557246572475724857249572505725157252572535725457255572565725757258572595726057261572625726357264572655726657267572685726957270572715727257273572745727557276572775727857279572805728157282572835728457285572865728757288572895729057291572925729357294572955729657297572985729957300573015730257303573045730557306573075730857309573105731157312573135731457315573165731757318573195732057321573225732357324573255732657327573285732957330573315733257333573345733557336573375733857339573405734157342573435734457345573465734757348573495735057351573525735357354573555735657357573585735957360573615736257363573645736557366573675736857369573705737157372573735737457375573765737757378573795738057381573825738357384573855738657387573885738957390573915739257393573945739557396573975739857399574005740157402574035740457405574065740757408574095741057411574125741357414574155741657417574185741957420574215742257423574245742557426574275742857429574305743157432574335743457435574365743757438574395744057441574425744357444574455744657447574485744957450574515745257453574545745557456574575745857459574605746157462574635746457465574665746757468574695747057471574725747357474574755747657477574785747957480574815748257483574845748557486574875748857489574905749157492574935749457495574965749757498574995750057501575025750357504575055750657507575085750957510575115751257513575145751557516575175751857519575205752157522575235752457525575265752757528575295753057531575325753357534575355753657537575385753957540575415754257543575445754557546575475754857549575505755157552575535755457555575565755757558575595756057561575625756357564575655756657567575685756957570575715757257573575745757557576575775757857579575805758157582575835758457585575865758757588575895759057591575925759357594575955759657597575985759957600576015760257603576045760557606576075760857609576105761157612576135761457615576165761757618576195762057621576225762357624576255762657627576285762957630576315763257633576345763557636576375763857639576405764157642576435764457645576465764757648576495765057651576525765357654576555765657657576585765957660576615766257663576645766557666576675766857669576705767157672576735767457675576765767757678576795768057681576825768357684576855768657687576885768957690576915769257693576945769557696576975769857699577005770157702577035770457705577065770757708577095771057711577125771357714577155771657717577185771957720577215772257723577245772557726577275772857729577305773157732577335773457735577365773757738577395774057741577425774357744577455774657747577485774957750577515775257753577545775557756577575775857759577605776157762577635776457765577665776757768577695777057771577725777357774577755777657777577785777957780577815778257783577845778557786577875778857789577905779157792577935779457795577965779757798577995780057801578025780357804578055780657807578085780957810578115781257813578145781557816578175781857819578205782157822578235782457825578265782757828578295783057831578325783357834578355783657837578385783957840578415784257843578445784557846578475784857849578505785157852578535785457855578565785757858578595786057861578625786357864578655786657867578685786957870578715787257873578745787557876578775787857879578805788157882578835788457885578865788757888578895789057891578925789357894578955789657897578985789957900579015790257903579045790557906579075790857909579105791157912579135791457915579165791757918579195792057921579225792357924579255792657927579285792957930579315793257933579345793557936579375793857939579405794157942579435794457945579465794757948579495795057951579525795357954579555795657957579585795957960579615796257963579645796557966579675796857969579705797157972579735797457975579765797757978579795798057981579825798357984579855798657987579885798957990579915799257993579945799557996579975799857999580005800158002580035800458005580065800758008580095801058011580125801358014580155801658017580185801958020580215802258023580245802558026580275802858029580305803158032580335803458035580365803758038580395804058041580425804358044580455804658047580485804958050580515805258053580545805558056580575805858059580605806158062580635806458065580665806758068580695807058071580725807358074580755807658077580785807958080580815808258083580845808558086580875808858089580905809158092580935809458095580965809758098580995810058101581025810358104581055810658107581085810958110581115811258113581145811558116581175811858119581205812158122581235812458125581265812758128581295813058131581325813358134581355813658137581385813958140581415814258143581445814558146581475814858149581505815158152581535815458155581565815758158581595816058161581625816358164581655816658167581685816958170581715817258173581745817558176581775817858179581805818158182581835818458185581865818758188581895819058191581925819358194581955819658197581985819958200582015820258203582045820558206582075820858209582105821158212582135821458215582165821758218582195822058221582225822358224582255822658227582285822958230582315823258233582345823558236582375823858239582405824158242582435824458245582465824758248582495825058251582525825358254582555825658257582585825958260582615826258263582645826558266582675826858269582705827158272582735827458275582765827758278582795828058281582825828358284582855828658287582885828958290582915829258293582945829558296582975829858299583005830158302583035830458305583065830758308583095831058311583125831358314583155831658317583185831958320583215832258323583245832558326583275832858329583305833158332583335833458335583365833758338583395834058341583425834358344583455834658347583485834958350583515835258353583545835558356583575835858359583605836158362583635836458365583665836758368583695837058371583725837358374583755837658377583785837958380583815838258383583845838558386583875838858389583905839158392583935839458395583965839758398583995840058401584025840358404584055840658407584085840958410584115841258413584145841558416584175841858419584205842158422584235842458425584265842758428584295843058431584325843358434584355843658437584385843958440584415844258443584445844558446584475844858449584505845158452584535845458455584565845758458584595846058461584625846358464584655846658467584685846958470584715847258473584745847558476584775847858479584805848158482584835848458485584865848758488584895849058491584925849358494584955849658497584985849958500585015850258503585045850558506585075850858509585105851158512585135851458515585165851758518585195852058521585225852358524585255852658527585285852958530585315853258533585345853558536585375853858539585405854158542585435854458545585465854758548585495855058551585525855358554585555855658557585585855958560585615856258563585645856558566585675856858569585705857158572585735857458575585765857758578585795858058581585825858358584585855858658587585885858958590585915859258593585945859558596585975859858599586005860158602586035860458605586065860758608586095861058611586125861358614586155861658617586185861958620586215862258623586245862558626586275862858629586305863158632586335863458635586365863758638586395864058641586425864358644586455864658647586485864958650586515865258653586545865558656586575865858659586605866158662586635866458665586665866758668586695867058671586725867358674586755867658677586785867958680586815868258683586845868558686586875868858689586905869158692586935869458695586965869758698586995870058701587025870358704587055870658707587085870958710587115871258713587145871558716587175871858719587205872158722587235872458725587265872758728587295873058731587325873358734587355873658737587385873958740587415874258743587445874558746587475874858749587505875158752587535875458755587565875758758587595876058761587625876358764587655876658767587685876958770587715877258773587745877558776587775877858779587805878158782587835878458785587865878758788587895879058791587925879358794587955879658797587985879958800588015880258803588045880558806588075880858809588105881158812588135881458815588165881758818588195882058821588225882358824588255882658827588285882958830588315883258833588345883558836588375883858839588405884158842588435884458845588465884758848588495885058851588525885358854588555885658857588585885958860588615886258863588645886558866588675886858869588705887158872588735887458875588765887758878588795888058881588825888358884588855888658887588885888958890588915889258893588945889558896588975889858899589005890158902589035890458905589065890758908589095891058911589125891358914589155891658917589185891958920589215892258923589245892558926589275892858929589305893158932589335893458935589365893758938589395894058941589425894358944589455894658947589485894958950589515895258953589545895558956589575895858959589605896158962589635896458965589665896758968589695897058971589725897358974589755897658977589785897958980589815898258983589845898558986589875898858989589905899158992589935899458995589965899758998589995900059001590025900359004590055900659007590085900959010590115901259013590145901559016590175901859019590205902159022590235902459025590265902759028590295903059031590325903359034590355903659037590385903959040590415904259043590445904559046590475904859049590505905159052590535905459055590565905759058590595906059061590625906359064590655906659067590685906959070590715907259073590745907559076590775907859079590805908159082590835908459085590865908759088590895909059091590925909359094590955909659097590985909959100591015910259103591045910559106591075910859109591105911159112591135911459115591165911759118591195912059121591225912359124591255912659127591285912959130591315913259133591345913559136591375913859139591405914159142591435914459145591465914759148591495915059151591525915359154591555915659157591585915959160591615916259163591645916559166591675916859169591705917159172591735917459175591765917759178591795918059181591825918359184591855918659187591885918959190591915919259193591945919559196591975919859199592005920159202592035920459205592065920759208592095921059211592125921359214592155921659217592185921959220592215922259223592245922559226592275922859229592305923159232592335923459235592365923759238592395924059241592425924359244592455924659247592485924959250592515925259253592545925559256592575925859259592605926159262592635926459265592665926759268592695927059271592725927359274592755927659277592785927959280592815928259283592845928559286592875928859289592905929159292592935929459295592965929759298592995930059301593025930359304593055930659307593085930959310593115931259313593145931559316593175931859319593205932159322593235932459325593265932759328593295933059331593325933359334593355933659337593385933959340593415934259343593445934559346593475934859349593505935159352593535935459355593565935759358593595936059361593625936359364593655936659367593685936959370593715937259373593745937559376593775937859379593805938159382593835938459385593865938759388593895939059391593925939359394593955939659397593985939959400594015940259403594045940559406594075940859409594105941159412594135941459415594165941759418594195942059421594225942359424594255942659427594285942959430594315943259433594345943559436594375943859439594405944159442594435944459445594465944759448594495945059451594525945359454594555945659457594585945959460594615946259463594645946559466594675946859469594705947159472594735947459475594765947759478594795948059481594825948359484594855948659487594885948959490594915949259493594945949559496594975949859499595005950159502595035950459505595065950759508595095951059511595125951359514595155951659517595185951959520595215952259523595245952559526595275952859529595305953159532595335953459535595365953759538595395954059541595425954359544595455954659547595485954959550595515955259553595545955559556595575955859559595605956159562595635956459565595665956759568595695957059571595725957359574595755957659577595785957959580595815958259583595845958559586595875958859589595905959159592595935959459595595965959759598595995960059601596025960359604596055960659607596085960959610596115961259613596145961559616596175961859619596205962159622596235962459625596265962759628596295963059631596325963359634596355963659637596385963959640596415964259643596445964559646596475964859649596505965159652596535965459655596565965759658596595966059661596625966359664596655966659667596685966959670596715967259673596745967559676596775967859679596805968159682596835968459685596865968759688596895969059691596925969359694596955969659697596985969959700597015970259703597045970559706597075970859709597105971159712597135971459715597165971759718597195972059721597225972359724597255972659727597285972959730597315973259733597345973559736597375973859739597405974159742597435974459745597465974759748597495975059751597525975359754597555975659757597585975959760597615976259763597645976559766597675976859769597705977159772597735977459775597765977759778597795978059781597825978359784597855978659787597885978959790597915979259793597945979559796597975979859799598005980159802598035980459805598065980759808598095981059811598125981359814598155981659817598185981959820598215982259823598245982559826598275982859829598305983159832598335983459835598365983759838598395984059841598425984359844598455984659847598485984959850598515985259853598545985559856598575985859859598605986159862598635986459865598665986759868598695987059871598725987359874598755987659877598785987959880598815988259883598845988559886598875988859889598905989159892598935989459895598965989759898598995990059901599025990359904599055990659907599085990959910599115991259913599145991559916599175991859919599205992159922599235992459925599265992759928599295993059931599325993359934599355993659937599385993959940599415994259943599445994559946599475994859949599505995159952599535995459955599565995759958599595996059961599625996359964599655996659967599685996959970599715997259973599745997559976599775997859979599805998159982599835998459985599865998759988599895999059991599925999359994599955999659997599985999960000600016000260003600046000560006600076000860009600106001160012600136001460015600166001760018600196002060021600226002360024600256002660027600286002960030600316003260033600346003560036600376003860039600406004160042600436004460045600466004760048600496005060051600526005360054600556005660057600586005960060600616006260063600646006560066600676006860069600706007160072600736007460075600766007760078600796008060081600826008360084600856008660087600886008960090600916009260093600946009560096600976009860099601006010160102601036010460105601066010760108601096011060111601126011360114601156011660117601186011960120601216012260123601246012560126601276012860129601306013160132601336013460135601366013760138601396014060141601426014360144601456014660147601486014960150601516015260153601546015560156601576015860159601606016160162601636016460165601666016760168601696017060171601726017360174601756017660177601786017960180601816018260183601846018560186601876018860189601906019160192601936019460195601966019760198601996020060201602026020360204602056020660207602086020960210602116021260213602146021560216602176021860219602206022160222602236022460225602266022760228602296023060231602326023360234602356023660237602386023960240602416024260243602446024560246602476024860249602506025160252602536025460255602566025760258602596026060261602626026360264602656026660267602686026960270602716027260273602746027560276602776027860279602806028160282602836028460285602866028760288602896029060291602926029360294602956029660297602986029960300603016030260303603046030560306603076030860309603106031160312603136031460315603166031760318603196032060321603226032360324603256032660327603286032960330603316033260333603346033560336603376033860339603406034160342603436034460345603466034760348603496035060351603526035360354603556035660357603586035960360603616036260363603646036560366603676036860369603706037160372603736037460375603766037760378603796038060381603826038360384603856038660387603886038960390603916039260393603946039560396603976039860399604006040160402604036040460405604066040760408604096041060411604126041360414604156041660417604186041960420604216042260423604246042560426604276042860429604306043160432604336043460435604366043760438604396044060441604426044360444604456044660447604486044960450604516045260453604546045560456604576045860459604606046160462604636046460465604666046760468604696047060471604726047360474604756047660477604786047960480604816048260483604846048560486604876048860489604906049160492604936049460495604966049760498604996050060501605026050360504605056050660507605086050960510605116051260513605146051560516605176051860519605206052160522605236052460525605266052760528605296053060531605326053360534605356053660537605386053960540605416054260543605446054560546605476054860549605506055160552605536055460555605566055760558605596056060561605626056360564605656056660567605686056960570605716057260573605746057560576605776057860579605806058160582605836058460585605866058760588605896059060591605926059360594605956059660597605986059960600606016060260603606046060560606606076060860609606106061160612606136061460615606166061760618606196062060621606226062360624606256062660627606286062960630606316063260633606346063560636606376063860639606406064160642606436064460645606466064760648606496065060651606526065360654606556065660657606586065960660606616066260663606646066560666606676066860669606706067160672606736067460675606766067760678606796068060681606826068360684606856068660687606886068960690606916069260693606946069560696606976069860699607006070160702607036070460705607066070760708607096071060711607126071360714607156071660717607186071960720607216072260723607246072560726607276072860729607306073160732607336073460735607366073760738607396074060741607426074360744607456074660747607486074960750607516075260753607546075560756607576075860759607606076160762607636076460765607666076760768607696077060771607726077360774607756077660777607786077960780607816078260783607846078560786607876078860789607906079160792607936079460795607966079760798607996080060801608026080360804608056080660807608086080960810608116081260813608146081560816608176081860819608206082160822608236082460825608266082760828608296083060831608326083360834608356083660837608386083960840608416084260843608446084560846608476084860849608506085160852608536085460855608566085760858608596086060861608626086360864608656086660867608686086960870608716087260873608746087560876608776087860879608806088160882608836088460885608866088760888608896089060891608926089360894608956089660897608986089960900609016090260903609046090560906609076090860909609106091160912609136091460915609166091760918609196092060921609226092360924609256092660927609286092960930609316093260933609346093560936609376093860939609406094160942609436094460945609466094760948609496095060951609526095360954609556095660957609586095960960609616096260963609646096560966609676096860969609706097160972609736097460975609766097760978609796098060981609826098360984609856098660987609886098960990609916099260993609946099560996609976099860999610006100161002610036100461005610066100761008610096101061011610126101361014610156101661017610186101961020610216102261023610246102561026610276102861029610306103161032610336103461035610366103761038610396104061041610426104361044610456104661047610486104961050610516105261053610546105561056610576105861059610606106161062610636106461065610666106761068610696107061071610726107361074610756107661077610786107961080610816108261083610846108561086610876108861089610906109161092610936109461095610966109761098610996110061101611026110361104611056110661107611086110961110611116111261113611146111561116611176111861119611206112161122611236112461125611266112761128611296113061131611326113361134611356113661137611386113961140611416114261143611446114561146611476114861149611506115161152611536115461155611566115761158611596116061161611626116361164611656116661167611686116961170611716117261173611746117561176611776117861179611806118161182611836118461185611866118761188611896119061191611926119361194611956119661197611986119961200612016120261203612046120561206612076120861209612106121161212612136121461215612166121761218612196122061221612226122361224612256122661227612286122961230612316123261233612346123561236612376123861239612406124161242612436124461245612466124761248612496125061251612526125361254612556125661257612586125961260612616126261263612646126561266612676126861269612706127161272612736127461275612766127761278612796128061281612826128361284612856128661287612886128961290612916129261293612946129561296612976129861299613006130161302613036130461305613066130761308613096131061311613126131361314613156131661317613186131961320613216132261323613246132561326613276132861329613306133161332613336133461335613366133761338613396134061341613426134361344613456134661347613486134961350613516135261353613546135561356613576135861359613606136161362613636136461365613666136761368613696137061371613726137361374613756137661377613786137961380613816138261383613846138561386613876138861389613906139161392613936139461395613966139761398613996140061401614026140361404614056140661407614086140961410614116141261413614146141561416614176141861419614206142161422614236142461425614266142761428614296143061431614326143361434614356143661437614386143961440614416144261443614446144561446614476144861449614506145161452614536145461455614566145761458614596146061461614626146361464614656146661467614686146961470614716147261473614746147561476614776147861479614806148161482614836148461485614866148761488614896149061491614926149361494614956149661497614986149961500615016150261503615046150561506615076150861509615106151161512615136151461515615166151761518615196152061521615226152361524615256152661527615286152961530615316153261533615346153561536615376153861539615406154161542615436154461545615466154761548615496155061551615526155361554615556155661557615586155961560615616156261563615646156561566615676156861569615706157161572615736157461575615766157761578615796158061581615826158361584615856158661587615886158961590615916159261593615946159561596615976159861599616006160161602616036160461605616066160761608616096161061611616126161361614616156161661617616186161961620616216162261623616246162561626616276162861629616306163161632616336163461635616366163761638616396164061641616426164361644616456164661647616486164961650616516165261653616546165561656616576165861659616606166161662616636166461665616666166761668616696167061671616726167361674616756167661677616786167961680616816168261683616846168561686616876168861689616906169161692616936169461695616966169761698616996170061701617026170361704617056170661707617086170961710617116171261713617146171561716617176171861719617206172161722617236172461725617266172761728617296173061731617326173361734617356173661737617386173961740617416174261743617446174561746617476174861749617506175161752617536175461755617566175761758617596176061761617626176361764617656176661767617686176961770617716177261773617746177561776617776177861779617806178161782617836178461785617866178761788617896179061791617926179361794617956179661797617986179961800618016180261803618046180561806618076180861809618106181161812618136181461815618166181761818618196182061821618226182361824618256182661827618286182961830618316183261833618346183561836618376183861839618406184161842618436184461845618466184761848618496185061851618526185361854618556185661857618586185961860618616186261863618646186561866618676186861869618706187161872618736187461875618766187761878618796188061881618826188361884618856188661887618886188961890618916189261893618946189561896618976189861899619006190161902619036190461905619066190761908619096191061911619126191361914619156191661917619186191961920619216192261923619246192561926619276192861929619306193161932619336193461935619366193761938619396194061941619426194361944619456194661947619486194961950619516195261953619546195561956619576195861959619606196161962619636196461965619666196761968619696197061971619726197361974619756197661977619786197961980619816198261983619846198561986619876198861989619906199161992619936199461995619966199761998619996200062001620026200362004620056200662007620086200962010620116201262013620146201562016620176201862019620206202162022620236202462025620266202762028620296203062031620326203362034620356203662037620386203962040620416204262043620446204562046620476204862049620506205162052620536205462055620566205762058620596206062061620626206362064620656206662067620686206962070620716207262073620746207562076620776207862079620806208162082620836208462085620866208762088620896209062091620926209362094620956209662097620986209962100621016210262103621046210562106621076210862109621106211162112621136211462115621166211762118621196212062121621226212362124621256212662127621286212962130621316213262133621346213562136621376213862139621406214162142621436214462145621466214762148621496215062151621526215362154621556215662157621586215962160621616216262163621646216562166621676216862169621706217162172621736217462175621766217762178621796218062181621826218362184621856218662187621886218962190621916219262193621946219562196621976219862199622006220162202622036220462205622066220762208622096221062211622126221362214622156221662217622186221962220622216222262223622246222562226622276222862229622306223162232622336223462235622366223762238622396224062241622426224362244622456224662247622486224962250622516225262253622546225562256622576225862259622606226162262622636226462265622666226762268622696227062271622726227362274622756227662277622786227962280622816228262283622846228562286622876228862289622906229162292622936229462295622966229762298622996230062301623026230362304623056230662307623086230962310623116231262313623146231562316623176231862319623206232162322623236232462325623266232762328623296233062331623326233362334623356233662337623386233962340623416234262343623446234562346623476234862349623506235162352623536235462355623566235762358623596236062361623626236362364623656236662367623686236962370623716237262373623746237562376623776237862379623806238162382623836238462385623866238762388623896239062391623926239362394623956239662397623986239962400624016240262403624046240562406624076240862409624106241162412624136241462415624166241762418624196242062421624226242362424624256242662427624286242962430624316243262433624346243562436624376243862439624406244162442624436244462445624466244762448624496245062451624526245362454624556245662457624586245962460624616246262463624646246562466624676246862469624706247162472624736247462475624766247762478624796248062481624826248362484624856248662487624886248962490624916249262493624946249562496624976249862499625006250162502625036250462505625066250762508625096251062511625126251362514625156251662517625186251962520625216252262523625246252562526625276252862529625306253162532625336253462535625366253762538625396254062541625426254362544625456254662547625486254962550625516255262553625546255562556625576255862559625606256162562625636256462565625666256762568625696257062571625726257362574625756257662577625786257962580625816258262583625846258562586625876258862589625906259162592625936259462595625966259762598625996260062601626026260362604626056260662607626086260962610626116261262613626146261562616626176261862619626206262162622626236262462625626266262762628626296263062631626326263362634626356263662637626386263962640626416264262643626446264562646626476264862649626506265162652626536265462655626566265762658626596266062661626626266362664626656266662667626686266962670626716267262673626746267562676626776267862679626806268162682626836268462685626866268762688626896269062691626926269362694626956269662697626986269962700627016270262703627046270562706627076270862709627106271162712627136271462715627166271762718627196272062721627226272362724627256272662727627286272962730627316273262733627346273562736627376273862739627406274162742627436274462745627466274762748627496275062751627526275362754627556275662757627586275962760627616276262763627646276562766627676276862769627706277162772627736277462775627766277762778627796278062781627826278362784627856278662787627886278962790627916279262793627946279562796627976279862799628006280162802628036280462805628066280762808628096281062811628126281362814628156281662817628186281962820628216282262823628246282562826628276282862829628306283162832628336283462835628366283762838628396284062841628426284362844628456284662847628486284962850628516285262853628546285562856628576285862859628606286162862628636286462865628666286762868628696287062871628726287362874628756287662877628786287962880628816288262883628846288562886628876288862889628906289162892628936289462895628966289762898628996290062901629026290362904629056290662907629086290962910629116291262913629146291562916629176291862919629206292162922629236292462925629266292762928629296293062931629326293362934629356293662937629386293962940629416294262943629446294562946629476294862949629506295162952629536295462955629566295762958629596296062961629626296362964629656296662967629686296962970629716297262973629746297562976629776297862979629806298162982629836298462985629866298762988629896299062991629926299362994629956299662997629986299963000630016300263003630046300563006630076300863009630106301163012630136301463015630166301763018630196302063021630226302363024630256302663027630286302963030630316303263033630346303563036630376303863039630406304163042630436304463045630466304763048630496305063051630526305363054630556305663057630586305963060630616306263063630646306563066630676306863069630706307163072630736307463075630766307763078630796308063081630826308363084630856308663087630886308963090630916309263093630946309563096630976309863099631006310163102631036310463105631066310763108631096311063111631126311363114631156311663117631186311963120631216312263123631246312563126631276312863129631306313163132631336313463135631366313763138631396314063141631426314363144631456314663147631486314963150631516315263153631546315563156631576315863159631606316163162631636316463165631666316763168631696317063171631726317363174631756317663177631786317963180631816318263183631846318563186631876318863189631906319163192631936319463195631966319763198631996320063201632026320363204632056320663207632086320963210632116321263213632146321563216632176321863219632206322163222632236322463225632266322763228632296323063231632326323363234632356323663237632386323963240632416324263243632446324563246632476324863249632506325163252632536325463255632566325763258632596326063261632626326363264632656326663267632686326963270632716327263273632746327563276632776327863279632806328163282632836328463285632866328763288632896329063291632926329363294632956329663297632986329963300633016330263303633046330563306633076330863309633106331163312633136331463315633166331763318633196332063321633226332363324633256332663327633286332963330633316333263333633346333563336633376333863339633406334163342633436334463345633466334763348633496335063351633526335363354633556335663357633586335963360633616336263363633646336563366633676336863369633706337163372633736337463375633766337763378633796338063381633826338363384633856338663387633886338963390633916339263393633946339563396633976339863399634006340163402634036340463405634066340763408634096341063411634126341363414634156341663417634186341963420634216342263423634246342563426634276342863429634306343163432634336343463435634366343763438634396344063441634426344363444634456344663447634486344963450634516345263453634546345563456634576345863459634606346163462634636346463465634666346763468634696347063471634726347363474634756347663477634786347963480634816348263483634846348563486634876348863489634906349163492634936349463495634966349763498634996350063501635026350363504635056350663507635086350963510635116351263513635146351563516635176351863519635206352163522635236352463525635266352763528635296353063531635326353363534635356353663537635386353963540635416354263543635446354563546635476354863549635506355163552635536355463555635566355763558635596356063561635626356363564635656356663567635686356963570635716357263573635746357563576635776357863579635806358163582635836358463585635866358763588635896359063591635926359363594635956359663597635986359963600636016360263603636046360563606636076360863609636106361163612636136361463615636166361763618636196362063621636226362363624636256362663627636286362963630636316363263633636346363563636636376363863639636406364163642636436364463645636466364763648636496365063651636526365363654636556365663657636586365963660636616366263663636646366563666636676366863669636706367163672636736367463675636766367763678636796368063681636826368363684636856368663687636886368963690636916369263693636946369563696636976369863699637006370163702637036370463705637066370763708637096371063711637126371363714637156371663717637186371963720637216372263723637246372563726637276372863729637306373163732637336373463735637366373763738637396374063741637426374363744637456374663747637486374963750637516375263753637546375563756637576375863759637606376163762637636376463765637666376763768637696377063771637726377363774637756377663777637786377963780637816378263783637846378563786637876378863789637906379163792637936379463795637966379763798637996380063801638026380363804638056380663807638086380963810638116381263813638146381563816638176381863819638206382163822638236382463825638266382763828638296383063831638326383363834638356383663837638386383963840638416384263843638446384563846638476384863849638506385163852638536385463855638566385763858638596386063861638626386363864638656386663867638686386963870638716387263873638746387563876638776387863879638806388163882638836388463885638866388763888638896389063891638926389363894638956389663897638986389963900639016390263903639046390563906639076390863909639106391163912639136391463915639166391763918639196392063921639226392363924639256392663927639286392963930639316393263933639346393563936639376393863939639406394163942639436394463945639466394763948639496395063951639526395363954639556395663957639586395963960639616396263963639646396563966639676396863969639706397163972639736397463975639766397763978639796398063981639826398363984639856398663987639886398963990639916399263993639946399563996639976399863999640006400164002640036400464005640066400764008640096401064011640126401364014640156401664017640186401964020640216402264023640246402564026640276402864029640306403164032640336403464035640366403764038640396404064041640426404364044640456404664047640486404964050640516405264053640546405564056640576405864059640606406164062640636406464065640666406764068640696407064071640726407364074640756407664077640786407964080640816408264083640846408564086640876408864089640906409164092640936409464095640966409764098640996410064101641026410364104641056410664107641086410964110641116411264113641146411564116641176411864119641206412164122641236412464125641266412764128641296413064131641326413364134641356413664137641386413964140641416414264143641446414564146641476414864149641506415164152641536415464155641566415764158641596416064161641626416364164641656416664167641686416964170641716417264173641746417564176641776417864179641806418164182641836418464185641866418764188641896419064191641926419364194641956419664197641986419964200642016420264203642046420564206642076420864209642106421164212642136421464215642166421764218642196422064221642226422364224642256422664227642286422964230642316423264233642346423564236642376423864239642406424164242642436424464245642466424764248642496425064251642526425364254642556425664257642586425964260642616426264263642646426564266642676426864269642706427164272642736427464275642766427764278642796428064281642826428364284642856428664287642886428964290642916429264293642946429564296642976429864299643006430164302643036430464305643066430764308643096431064311643126431364314643156431664317643186431964320643216432264323643246432564326643276432864329643306433164332643336433464335643366433764338643396434064341643426434364344643456434664347643486434964350643516435264353643546435564356643576435864359643606436164362643636436464365643666436764368643696437064371643726437364374643756437664377643786437964380643816438264383643846438564386643876438864389643906439164392643936439464395643966439764398643996440064401644026440364404644056440664407644086440964410644116441264413644146441564416644176441864419644206442164422644236442464425644266442764428644296443064431644326443364434644356443664437644386443964440644416444264443644446444564446644476444864449644506445164452644536445464455644566445764458644596446064461644626446364464644656446664467644686446964470644716447264473644746447564476644776447864479644806448164482644836448464485644866448764488644896449064491644926449364494644956449664497644986449964500645016450264503645046450564506645076450864509645106451164512645136451464515645166451764518645196452064521645226452364524645256452664527645286452964530645316453264533645346453564536645376453864539645406454164542645436454464545645466454764548645496455064551645526455364554645556455664557645586455964560645616456264563645646456564566645676456864569645706457164572645736457464575645766457764578645796458064581645826458364584645856458664587645886458964590645916459264593645946459564596645976459864599646006460164602646036460464605646066460764608646096461064611646126461364614646156461664617646186461964620646216462264623646246462564626646276462864629646306463164632646336463464635646366463764638646396464064641646426464364644646456464664647646486464964650646516465264653646546465564656646576465864659646606466164662646636466464665646666466764668646696467064671646726467364674646756467664677646786467964680646816468264683646846468564686646876468864689646906469164692646936469464695646966469764698646996470064701647026470364704647056470664707647086470964710647116471264713647146471564716647176471864719647206472164722647236472464725647266472764728647296473064731647326473364734647356473664737647386473964740647416474264743647446474564746647476474864749647506475164752647536475464755647566475764758647596476064761647626476364764647656476664767647686476964770647716477264773647746477564776647776477864779647806478164782647836478464785647866478764788647896479064791647926479364794647956479664797647986479964800648016480264803648046480564806648076480864809648106481164812648136481464815648166481764818648196482064821648226482364824648256482664827648286482964830648316483264833648346483564836648376483864839648406484164842648436484464845648466484764848648496485064851648526485364854648556485664857648586485964860648616486264863648646486564866648676486864869648706487164872648736487464875648766487764878648796488064881648826488364884648856488664887648886488964890648916489264893648946489564896648976489864899649006490164902649036490464905649066490764908649096491064911649126491364914649156491664917649186491964920649216492264923649246492564926649276492864929649306493164932649336493464935649366493764938649396494064941649426494364944649456494664947649486494964950649516495264953649546495564956649576495864959649606496164962649636496464965649666496764968649696497064971649726497364974649756497664977649786497964980649816498264983649846498564986649876498864989649906499164992649936499464995649966499764998649996500065001650026500365004650056500665007650086500965010650116501265013650146501565016650176501865019650206502165022650236502465025650266502765028650296503065031650326503365034650356503665037650386503965040650416504265043650446504565046650476504865049650506505165052650536505465055650566505765058650596506065061650626506365064650656506665067650686506965070650716507265073650746507565076650776507865079650806508165082650836508465085650866508765088650896509065091650926509365094650956509665097650986509965100651016510265103651046510565106651076510865109651106511165112651136511465115651166511765118651196512065121651226512365124651256512665127651286512965130651316513265133651346513565136651376513865139651406514165142651436514465145651466514765148651496515065151651526515365154651556515665157651586515965160651616516265163651646516565166651676516865169651706517165172651736517465175651766517765178651796518065181651826518365184651856518665187651886518965190651916519265193651946519565196651976519865199652006520165202652036520465205652066520765208652096521065211652126521365214652156521665217652186521965220652216522265223652246522565226652276522865229652306523165232652336523465235652366523765238652396524065241652426524365244652456524665247652486524965250652516525265253652546525565256652576525865259652606526165262652636526465265652666526765268652696527065271652726527365274652756527665277652786527965280652816528265283652846528565286652876528865289652906529165292652936529465295652966529765298652996530065301653026530365304653056530665307653086530965310653116531265313653146531565316653176531865319653206532165322653236532465325653266532765328653296533065331653326533365334653356533665337653386533965340653416534265343653446534565346653476534865349653506535165352653536535465355653566535765358653596536065361653626536365364653656536665367653686536965370653716537265373653746537565376653776537865379653806538165382653836538465385653866538765388653896539065391653926539365394653956539665397653986539965400654016540265403654046540565406654076540865409654106541165412654136541465415654166541765418654196542065421654226542365424654256542665427654286542965430654316543265433654346543565436654376543865439654406544165442654436544465445654466544765448654496545065451654526545365454654556545665457654586545965460654616546265463654646546565466654676546865469654706547165472654736547465475654766547765478654796548065481654826548365484654856548665487654886548965490654916549265493654946549565496654976549865499655006550165502655036550465505655066550765508655096551065511655126551365514655156551665517655186551965520655216552265523655246552565526655276552865529655306553165532655336553465535655366553765538655396554065541655426554365544655456554665547655486554965550655516555265553655546555565556655576555865559655606556165562655636556465565655666556765568655696557065571655726557365574655756557665577655786557965580655816558265583655846558565586655876558865589655906559165592655936559465595655966559765598655996560065601656026560365604656056560665607656086560965610656116561265613656146561565616656176561865619656206562165622656236562465625656266562765628656296563065631656326563365634656356563665637656386563965640656416564265643656446564565646656476564865649656506565165652656536565465655656566565765658656596566065661656626566365664656656566665667656686566965670656716567265673656746567565676656776567865679656806568165682656836568465685656866568765688656896569065691656926569365694656956569665697656986569965700657016570265703657046570565706657076570865709657106571165712657136571465715657166571765718657196572065721657226572365724657256572665727657286572965730657316573265733657346573565736657376573865739657406574165742657436574465745657466574765748657496575065751657526575365754657556575665757657586575965760657616576265763657646576565766657676576865769657706577165772657736577465775657766577765778657796578065781657826578365784657856578665787657886578965790657916579265793657946579565796657976579865799658006580165802658036580465805658066580765808658096581065811658126581365814658156581665817658186581965820658216582265823658246582565826658276582865829658306583165832658336583465835658366583765838658396584065841658426584365844658456584665847658486584965850658516585265853658546585565856658576585865859658606586165862658636586465865658666586765868658696587065871658726587365874658756587665877658786587965880658816588265883658846588565886658876588865889658906589165892658936589465895658966589765898658996590065901659026590365904659056590665907659086590965910659116591265913659146591565916659176591865919659206592165922659236592465925659266592765928659296593065931659326593365934659356593665937659386593965940659416594265943659446594565946659476594865949659506595165952659536595465955659566595765958659596596065961659626596365964659656596665967659686596965970659716597265973659746597565976659776597865979659806598165982659836598465985659866598765988659896599065991659926599365994659956599665997659986599966000660016600266003660046600566006660076600866009660106601166012660136601466015660166601766018660196602066021660226602366024660256602666027660286602966030660316603266033660346603566036660376603866039660406604166042660436604466045660466604766048660496605066051660526605366054660556605666057660586605966060660616606266063660646606566066660676606866069660706607166072660736607466075660766607766078660796608066081660826608366084660856608666087660886608966090660916609266093660946609566096660976609866099661006610166102661036610466105661066610766108661096611066111661126611366114661156611666117661186611966120661216612266123661246612566126661276612866129661306613166132661336613466135661366613766138661396614066141661426614366144661456614666147661486614966150661516615266153661546615566156661576615866159661606616166162661636616466165661666616766168661696617066171661726617366174661756617666177661786617966180661816618266183661846618566186661876618866189661906619166192661936619466195661966619766198661996620066201662026620366204662056620666207662086620966210662116621266213662146621566216662176621866219662206622166222662236622466225662266622766228662296623066231662326623366234662356623666237662386623966240662416624266243662446624566246662476624866249662506625166252662536625466255662566625766258662596626066261662626626366264662656626666267662686626966270662716627266273662746627566276662776627866279662806628166282662836628466285662866628766288662896629066291662926629366294662956629666297662986629966300663016630266303663046630566306663076630866309663106631166312663136631466315663166631766318663196632066321663226632366324663256632666327663286632966330663316633266333663346633566336663376633866339663406634166342663436634466345663466634766348663496635066351663526635366354663556635666357663586635966360663616636266363663646636566366663676636866369663706637166372663736637466375663766637766378663796638066381663826638366384663856638666387663886638966390663916639266393663946639566396663976639866399664006640166402664036640466405664066640766408664096641066411664126641366414664156641666417664186641966420664216642266423664246642566426664276642866429664306643166432664336643466435664366643766438664396644066441664426644366444664456644666447664486644966450664516645266453664546645566456664576645866459664606646166462664636646466465664666646766468664696647066471664726647366474664756647666477664786647966480664816648266483664846648566486664876648866489664906649166492664936649466495664966649766498664996650066501665026650366504665056650666507665086650966510665116651266513665146651566516665176651866519665206652166522665236652466525665266652766528665296653066531665326653366534665356653666537665386653966540665416654266543665446654566546665476654866549665506655166552665536655466555665566655766558665596656066561665626656366564665656656666567665686656966570665716657266573665746657566576665776657866579665806658166582665836658466585665866658766588665896659066591665926659366594665956659666597665986659966600666016660266603666046660566606666076660866609666106661166612666136661466615666166661766618666196662066621666226662366624666256662666627666286662966630666316663266633666346663566636666376663866639666406664166642666436664466645666466664766648666496665066651666526665366654666556665666657666586665966660666616666266663666646666566666666676666866669666706667166672666736667466675666766667766678666796668066681666826668366684666856668666687666886668966690666916669266693666946669566696666976669866699667006670166702667036670466705667066670766708667096671066711667126671366714667156671666717667186671966720667216672266723667246672566726667276672866729667306673166732667336673466735667366673766738667396674066741667426674366744667456674666747667486674966750667516675266753667546675566756667576675866759667606676166762667636676466765667666676766768667696677066771667726677366774667756677666777667786677966780667816678266783667846678566786667876678866789667906679166792667936679466795667966679766798667996680066801668026680366804668056680666807668086680966810668116681266813668146681566816668176681866819668206682166822668236682466825668266682766828668296683066831668326683366834668356683666837668386683966840668416684266843668446684566846668476684866849668506685166852668536685466855668566685766858668596686066861668626686366864668656686666867668686686966870668716687266873668746687566876668776687866879668806688166882668836688466885668866688766888668896689066891668926689366894668956689666897668986689966900669016690266903669046690566906669076690866909669106691166912669136691466915669166691766918669196692066921669226692366924669256692666927669286692966930669316693266933669346693566936669376693866939669406694166942669436694466945669466694766948669496695066951669526695366954669556695666957669586695966960669616696266963669646696566966669676696866969669706697166972669736697466975669766697766978669796698066981669826698366984669856698666987669886698966990669916699266993669946699566996669976699866999670006700167002670036700467005670066700767008670096701067011670126701367014670156701667017670186701967020670216702267023670246702567026670276702867029670306703167032670336703467035670366703767038670396704067041670426704367044670456704667047670486704967050670516705267053670546705567056670576705867059670606706167062670636706467065670666706767068670696707067071670726707367074670756707667077670786707967080670816708267083670846708567086670876708867089670906709167092670936709467095670966709767098670996710067101671026710367104671056710667107671086710967110671116711267113671146711567116671176711867119671206712167122671236712467125671266712767128671296713067131671326713367134671356713667137671386713967140671416714267143671446714567146671476714867149671506715167152671536715467155671566715767158671596716067161671626716367164671656716667167671686716967170671716717267173671746717567176671776717867179671806718167182671836718467185671866718767188671896719067191671926719367194671956719667197671986719967200672016720267203672046720567206672076720867209672106721167212672136721467215672166721767218672196722067221672226722367224672256722667227672286722967230672316723267233672346723567236672376723867239672406724167242672436724467245672466724767248672496725067251672526725367254672556725667257672586725967260672616726267263672646726567266672676726867269672706727167272672736727467275672766727767278672796728067281672826728367284672856728667287672886728967290672916729267293672946729567296672976729867299673006730167302673036730467305673066730767308673096731067311673126731367314673156731667317673186731967320673216732267323673246732567326673276732867329673306733167332673336733467335673366733767338673396734067341673426734367344673456734667347673486734967350673516735267353673546735567356673576735867359673606736167362673636736467365673666736767368673696737067371673726737367374673756737667377673786737967380673816738267383673846738567386673876738867389673906739167392673936739467395673966739767398673996740067401674026740367404674056740667407674086740967410674116741267413674146741567416674176741867419674206742167422674236742467425674266742767428674296743067431674326743367434674356743667437674386743967440674416744267443674446744567446674476744867449674506745167452674536745467455674566745767458674596746067461674626746367464674656746667467674686746967470674716747267473674746747567476674776747867479674806748167482674836748467485674866748767488674896749067491674926749367494674956749667497674986749967500675016750267503675046750567506675076750867509675106751167512675136751467515675166751767518675196752067521675226752367524675256752667527675286752967530675316753267533675346753567536675376753867539675406754167542675436754467545675466754767548675496755067551675526755367554675556755667557675586755967560675616756267563675646756567566675676756867569675706757167572675736757467575675766757767578675796758067581675826758367584675856758667587675886758967590675916759267593675946759567596675976759867599676006760167602676036760467605676066760767608676096761067611676126761367614676156761667617676186761967620676216762267623676246762567626676276762867629676306763167632676336763467635676366763767638676396764067641676426764367644676456764667647676486764967650676516765267653676546765567656676576765867659676606766167662676636766467665676666766767668676696767067671676726767367674676756767667677676786767967680676816768267683676846768567686676876768867689676906769167692676936769467695676966769767698676996770067701677026770367704677056770667707677086770967710677116771267713677146771567716677176771867719677206772167722677236772467725677266772767728677296773067731677326773367734677356773667737677386773967740677416774267743677446774567746677476774867749677506775167752677536775467755677566775767758677596776067761677626776367764677656776667767677686776967770677716777267773677746777567776677776777867779677806778167782677836778467785677866778767788677896779067791677926779367794677956779667797677986779967800678016780267803678046780567806678076780867809678106781167812678136781467815678166781767818678196782067821678226782367824678256782667827678286782967830678316783267833678346783567836678376783867839678406784167842678436784467845678466784767848678496785067851678526785367854678556785667857678586785967860678616786267863678646786567866678676786867869678706787167872678736787467875678766787767878678796788067881678826788367884678856788667887678886788967890678916789267893678946789567896678976789867899679006790167902679036790467905679066790767908679096791067911679126791367914679156791667917679186791967920679216792267923679246792567926679276792867929679306793167932679336793467935679366793767938679396794067941679426794367944679456794667947679486794967950679516795267953679546795567956679576795867959679606796167962679636796467965679666796767968679696797067971679726797367974679756797667977679786797967980679816798267983679846798567986679876798867989679906799167992679936799467995679966799767998679996800068001680026800368004680056800668007680086800968010680116801268013680146801568016680176801868019680206802168022680236802468025680266802768028680296803068031680326803368034680356803668037680386803968040680416804268043680446804568046680476804868049680506805168052680536805468055680566805768058680596806068061680626806368064680656806668067680686806968070680716807268073680746807568076680776807868079680806808168082680836808468085680866808768088680896809068091680926809368094680956809668097680986809968100681016810268103681046810568106681076810868109681106811168112681136811468115681166811768118681196812068121681226812368124681256812668127681286812968130681316813268133681346813568136681376813868139681406814168142681436814468145681466814768148681496815068151681526815368154681556815668157681586815968160681616816268163681646816568166681676816868169681706817168172681736817468175681766817768178681796818068181681826818368184681856818668187681886818968190681916819268193681946819568196681976819868199682006820168202682036820468205682066820768208682096821068211682126821368214682156821668217682186821968220682216822268223682246822568226682276822868229682306823168232682336823468235682366823768238682396824068241682426824368244682456824668247682486824968250682516825268253682546825568256682576825868259682606826168262682636826468265682666826768268682696827068271682726827368274682756827668277682786827968280682816828268283682846828568286682876828868289682906829168292682936829468295682966829768298682996830068301683026830368304683056830668307683086830968310683116831268313683146831568316683176831868319683206832168322683236832468325683266832768328683296833068331683326833368334683356833668337683386833968340683416834268343683446834568346683476834868349683506835168352683536835468355683566835768358683596836068361683626836368364683656836668367683686836968370683716837268373683746837568376683776837868379683806838168382683836838468385683866838768388683896839068391683926839368394683956839668397683986839968400684016840268403684046840568406684076840868409684106841168412684136841468415684166841768418684196842068421684226842368424684256842668427684286842968430684316843268433684346843568436684376843868439684406844168442684436844468445684466844768448684496845068451684526845368454684556845668457684586845968460684616846268463684646846568466684676846868469684706847168472684736847468475684766847768478684796848068481684826848368484684856848668487684886848968490684916849268493684946849568496684976849868499685006850168502685036850468505685066850768508685096851068511685126851368514685156851668517685186851968520685216852268523685246852568526685276852868529685306853168532685336853468535685366853768538685396854068541685426854368544685456854668547685486854968550685516855268553685546855568556685576855868559685606856168562685636856468565685666856768568685696857068571685726857368574685756857668577685786857968580685816858268583685846858568586685876858868589685906859168592685936859468595685966859768598685996860068601686026860368604686056860668607686086860968610686116861268613686146861568616686176861868619686206862168622686236862468625686266862768628686296863068631686326863368634686356863668637686386863968640686416864268643686446864568646686476864868649686506865168652686536865468655686566865768658686596866068661686626866368664686656866668667686686866968670686716867268673686746867568676686776867868679686806868168682686836868468685686866868768688686896869068691686926869368694686956869668697686986869968700687016870268703687046870568706687076870868709687106871168712687136871468715687166871768718687196872068721687226872368724687256872668727687286872968730687316873268733687346873568736687376873868739687406874168742687436874468745687466874768748687496875068751687526875368754687556875668757687586875968760687616876268763687646876568766687676876868769687706877168772687736877468775687766877768778687796878068781687826878368784687856878668787687886878968790687916879268793687946879568796687976879868799688006880168802688036880468805688066880768808688096881068811688126881368814688156881668817688186881968820688216882268823688246882568826688276882868829688306883168832688336883468835688366883768838688396884068841688426884368844688456884668847688486884968850688516885268853688546885568856688576885868859688606886168862688636886468865688666886768868688696887068871688726887368874688756887668877688786887968880688816888268883688846888568886688876888868889688906889168892688936889468895688966889768898688996890068901689026890368904689056890668907689086890968910689116891268913689146891568916689176891868919689206892168922689236892468925689266892768928689296893068931689326893368934689356893668937689386893968940689416894268943689446894568946689476894868949689506895168952689536895468955689566895768958689596896068961689626896368964689656896668967689686896968970689716897268973689746897568976689776897868979689806898168982689836898468985689866898768988689896899068991689926899368994689956899668997689986899969000690016900269003690046900569006690076900869009690106901169012690136901469015690166901769018690196902069021690226902369024690256902669027690286902969030690316903269033690346903569036690376903869039690406904169042690436904469045690466904769048690496905069051690526905369054690556905669057690586905969060690616906269063690646906569066690676906869069690706907169072690736907469075690766907769078690796908069081690826908369084690856908669087690886908969090690916909269093690946909569096690976909869099691006910169102691036910469105691066910769108691096911069111691126911369114691156911669117691186911969120691216912269123691246912569126691276912869129691306913169132691336913469135691366913769138691396914069141691426914369144691456914669147691486914969150691516915269153691546915569156691576915869159691606916169162691636916469165691666916769168691696917069171691726917369174691756917669177691786917969180691816918269183691846918569186691876918869189691906919169192691936919469195691966919769198691996920069201692026920369204692056920669207692086920969210692116921269213692146921569216692176921869219692206922169222692236922469225692266922769228692296923069231692326923369234692356923669237692386923969240692416924269243692446924569246692476924869249692506925169252692536925469255692566925769258692596926069261692626926369264692656926669267692686926969270692716927269273692746927569276692776927869279692806928169282692836928469285692866928769288692896929069291692926929369294692956929669297692986929969300693016930269303693046930569306693076930869309693106931169312693136931469315693166931769318693196932069321693226932369324693256932669327693286932969330693316933269333693346933569336693376933869339693406934169342693436934469345693466934769348693496935069351693526935369354693556935669357693586935969360693616936269363693646936569366693676936869369693706937169372693736937469375693766937769378693796938069381693826938369384693856938669387693886938969390693916939269393693946939569396693976939869399694006940169402694036940469405694066940769408694096941069411694126941369414694156941669417694186941969420694216942269423694246942569426694276942869429694306943169432694336943469435694366943769438694396944069441694426944369444694456944669447694486944969450694516945269453694546945569456694576945869459694606946169462694636946469465694666946769468694696947069471694726947369474694756947669477694786947969480694816948269483694846948569486694876948869489694906949169492694936949469495694966949769498694996950069501695026950369504695056950669507695086950969510695116951269513695146951569516695176951869519695206952169522695236952469525695266952769528695296953069531695326953369534695356953669537695386953969540695416954269543695446954569546695476954869549695506955169552695536955469555695566955769558695596956069561695626956369564695656956669567695686956969570695716957269573695746957569576695776957869579695806958169582695836958469585695866958769588695896959069591695926959369594695956959669597695986959969600696016960269603696046960569606696076960869609696106961169612696136961469615696166961769618696196962069621696226962369624696256962669627696286962969630696316963269633696346963569636696376963869639696406964169642696436964469645696466964769648696496965069651696526965369654696556965669657696586965969660696616966269663696646966569666696676966869669696706967169672696736967469675696766967769678696796968069681696826968369684696856968669687696886968969690696916969269693696946969569696696976969869699697006970169702697036970469705697066970769708697096971069711697126971369714697156971669717697186971969720697216972269723697246972569726697276972869729697306973169732697336973469735697366973769738697396974069741697426974369744697456974669747697486974969750697516975269753697546975569756697576975869759697606976169762697636976469765697666976769768697696977069771697726977369774697756977669777697786977969780697816978269783697846978569786697876978869789697906979169792697936979469795697966979769798697996980069801698026980369804698056980669807698086980969810698116981269813698146981569816698176981869819698206982169822698236982469825698266982769828698296983069831698326983369834698356983669837698386983969840698416984269843698446984569846698476984869849698506985169852698536985469855698566985769858698596986069861698626986369864698656986669867698686986969870698716987269873698746987569876698776987869879698806988169882698836988469885698866988769888698896989069891698926989369894698956989669897698986989969900699016990269903699046990569906699076990869909699106991169912699136991469915699166991769918699196992069921699226992369924699256992669927699286992969930699316993269933699346993569936699376993869939699406994169942699436994469945699466994769948699496995069951699526995369954699556995669957699586995969960699616996269963699646996569966699676996869969699706997169972699736997469975699766997769978699796998069981699826998369984699856998669987699886998969990699916999269993699946999569996699976999869999700007000170002700037000470005700067000770008700097001070011700127001370014700157001670017700187001970020700217002270023700247002570026700277002870029700307003170032700337003470035700367003770038700397004070041700427004370044700457004670047700487004970050700517005270053700547005570056700577005870059700607006170062700637006470065700667006770068700697007070071700727007370074700757007670077700787007970080700817008270083700847008570086700877008870089700907009170092700937009470095700967009770098700997010070101701027010370104701057010670107701087010970110701117011270113701147011570116701177011870119701207012170122701237012470125701267012770128701297013070131701327013370134701357013670137701387013970140701417014270143701447014570146701477014870149701507015170152701537015470155701567015770158701597016070161701627016370164701657016670167701687016970170701717017270173701747017570176701777017870179701807018170182701837018470185701867018770188701897019070191701927019370194701957019670197701987019970200702017020270203702047020570206702077020870209702107021170212702137021470215702167021770218702197022070221702227022370224702257022670227702287022970230702317023270233702347023570236702377023870239702407024170242702437024470245702467024770248702497025070251702527025370254702557025670257702587025970260702617026270263702647026570266702677026870269702707027170272702737027470275702767027770278702797028070281702827028370284702857028670287702887028970290702917029270293702947029570296702977029870299703007030170302703037030470305703067030770308703097031070311703127031370314703157031670317703187031970320703217032270323703247032570326703277032870329703307033170332703337033470335703367033770338703397034070341703427034370344703457034670347703487034970350703517035270353703547035570356703577035870359703607036170362703637036470365703667036770368703697037070371703727037370374703757037670377703787037970380703817038270383703847038570386703877038870389703907039170392703937039470395703967039770398703997040070401704027040370404704057040670407704087040970410704117041270413704147041570416704177041870419704207042170422704237042470425704267042770428704297043070431704327043370434704357043670437704387043970440704417044270443704447044570446704477044870449704507045170452704537045470455704567045770458704597046070461704627046370464704657046670467704687046970470704717047270473704747047570476704777047870479704807048170482704837048470485704867048770488704897049070491704927049370494704957049670497704987049970500705017050270503705047050570506705077050870509705107051170512705137051470515705167051770518705197052070521705227052370524705257052670527705287052970530705317053270533705347053570536705377053870539705407054170542705437054470545705467054770548705497055070551705527055370554705557055670557705587055970560705617056270563705647056570566705677056870569705707057170572705737057470575705767057770578705797058070581705827058370584705857058670587705887058970590705917059270593705947059570596705977059870599706007060170602706037060470605706067060770608706097061070611706127061370614706157061670617706187061970620706217062270623706247062570626706277062870629706307063170632706337063470635706367063770638706397064070641706427064370644706457064670647706487064970650706517065270653706547065570656706577065870659706607066170662706637066470665706667066770668706697067070671706727067370674706757067670677706787067970680706817068270683706847068570686706877068870689706907069170692706937069470695706967069770698706997070070701707027070370704707057070670707707087070970710707117071270713707147071570716707177071870719707207072170722707237072470725707267072770728707297073070731707327073370734707357073670737707387073970740707417074270743707447074570746707477074870749707507075170752707537075470755707567075770758707597076070761707627076370764707657076670767707687076970770707717077270773707747077570776707777077870779707807078170782707837078470785707867078770788707897079070791707927079370794707957079670797707987079970800708017080270803708047080570806708077080870809708107081170812708137081470815708167081770818708197082070821708227082370824708257082670827708287082970830708317083270833708347083570836708377083870839708407084170842708437084470845708467084770848708497085070851708527085370854708557085670857708587085970860708617086270863708647086570866708677086870869708707087170872708737087470875708767087770878708797088070881708827088370884708857088670887708887088970890708917089270893708947089570896708977089870899709007090170902709037090470905709067090770908709097091070911709127091370914709157091670917709187091970920709217092270923709247092570926709277092870929709307093170932709337093470935709367093770938709397094070941709427094370944709457094670947709487094970950709517095270953709547095570956709577095870959709607096170962709637096470965709667096770968709697097070971709727097370974709757097670977709787097970980709817098270983709847098570986709877098870989709907099170992709937099470995709967099770998709997100071001710027100371004710057100671007710087100971010710117101271013710147101571016710177101871019710207102171022710237102471025710267102771028710297103071031710327103371034710357103671037710387103971040710417104271043710447104571046710477104871049710507105171052710537105471055710567105771058710597106071061710627106371064710657106671067710687106971070710717107271073710747107571076710777107871079710807108171082710837108471085710867108771088710897109071091710927109371094710957109671097710987109971100711017110271103711047110571106711077110871109711107111171112711137111471115711167111771118711197112071121711227112371124711257112671127711287112971130711317113271133711347113571136711377113871139711407114171142711437114471145711467114771148711497115071151711527115371154711557115671157711587115971160711617116271163711647116571166711677116871169711707117171172711737117471175711767117771178711797118071181711827118371184711857118671187711887118971190711917119271193711947119571196711977119871199712007120171202712037120471205712067120771208712097121071211712127121371214712157121671217712187121971220712217122271223712247122571226712277122871229712307123171232712337123471235712367123771238712397124071241712427124371244712457124671247712487124971250712517125271253712547125571256712577125871259712607126171262712637126471265712667126771268712697127071271712727127371274712757127671277712787127971280712817128271283712847128571286712877128871289712907129171292712937129471295712967129771298712997130071301713027130371304713057130671307713087130971310713117131271313713147131571316713177131871319713207132171322713237132471325713267132771328713297133071331713327133371334713357133671337713387133971340713417134271343713447134571346713477134871349713507135171352713537135471355713567135771358713597136071361713627136371364713657136671367713687136971370713717137271373713747137571376713777137871379713807138171382713837138471385713867138771388713897139071391713927139371394713957139671397713987139971400714017140271403714047140571406714077140871409714107141171412714137141471415714167141771418714197142071421714227142371424714257142671427714287142971430714317143271433714347143571436714377143871439714407144171442714437144471445714467144771448714497145071451714527145371454714557145671457714587145971460714617146271463714647146571466714677146871469714707147171472714737147471475714767147771478714797148071481714827148371484714857148671487714887148971490714917149271493714947149571496714977149871499715007150171502715037150471505715067150771508715097151071511715127151371514715157151671517715187151971520715217152271523715247152571526715277152871529715307153171532715337153471535715367153771538715397154071541715427154371544715457154671547715487154971550715517155271553715547155571556715577155871559715607156171562715637156471565715667156771568715697157071571715727157371574715757157671577715787157971580715817158271583715847158571586715877158871589715907159171592715937159471595715967159771598715997160071601716027160371604716057160671607716087160971610716117161271613716147161571616716177161871619716207162171622716237162471625716267162771628716297163071631716327163371634716357163671637716387163971640716417164271643716447164571646716477164871649716507165171652716537165471655716567165771658716597166071661716627166371664716657166671667716687166971670716717167271673716747167571676716777167871679716807168171682716837168471685716867168771688716897169071691716927169371694716957169671697716987169971700717017170271703717047170571706717077170871709717107171171712717137171471715717167171771718717197172071721717227172371724717257172671727717287172971730717317173271733717347173571736717377173871739717407174171742717437174471745717467174771748717497175071751717527175371754717557175671757717587175971760717617176271763717647176571766717677176871769717707177171772717737177471775717767177771778717797178071781717827178371784717857178671787717887178971790717917179271793717947179571796717977179871799718007180171802718037180471805718067180771808718097181071811718127181371814718157181671817718187181971820718217182271823718247182571826718277182871829718307183171832718337183471835718367183771838718397184071841718427184371844718457184671847718487184971850718517185271853718547185571856718577185871859718607186171862718637186471865718667186771868718697187071871718727187371874718757187671877718787187971880718817188271883718847188571886718877188871889718907189171892718937189471895718967189771898718997190071901719027190371904719057190671907719087190971910719117191271913719147191571916719177191871919719207192171922719237192471925719267192771928719297193071931719327193371934719357193671937719387193971940719417194271943719447194571946719477194871949719507195171952719537195471955719567195771958719597196071961719627196371964719657196671967719687196971970719717197271973719747197571976719777197871979719807198171982719837198471985719867198771988719897199071991719927199371994719957199671997719987199972000720017200272003720047200572006720077200872009720107201172012720137201472015720167201772018720197202072021720227202372024720257202672027720287202972030720317203272033720347203572036720377203872039720407204172042720437204472045720467204772048720497205072051720527205372054720557205672057720587205972060720617206272063720647206572066720677206872069720707207172072720737207472075720767207772078720797208072081720827208372084720857208672087720887208972090720917209272093720947209572096720977209872099721007210172102721037210472105721067210772108721097211072111721127211372114721157211672117721187211972120721217212272123721247212572126721277212872129721307213172132721337213472135721367213772138721397214072141721427214372144721457214672147721487214972150721517215272153721547215572156721577215872159721607216172162721637216472165721667216772168721697217072171721727217372174721757217672177721787217972180721817218272183721847218572186721877218872189721907219172192721937219472195721967219772198721997220072201722027220372204722057220672207722087220972210722117221272213722147221572216722177221872219722207222172222722237222472225722267222772228722297223072231722327223372234722357223672237722387223972240722417224272243722447224572246722477224872249722507225172252722537225472255722567225772258722597226072261722627226372264722657226672267722687226972270722717227272273722747227572276722777227872279722807228172282722837228472285722867228772288722897229072291722927229372294722957229672297722987229972300723017230272303723047230572306723077230872309723107231172312723137231472315723167231772318723197232072321723227232372324723257232672327723287232972330723317233272333723347233572336723377233872339723407234172342723437234472345723467234772348723497235072351723527235372354723557235672357723587235972360723617236272363723647236572366723677236872369723707237172372723737237472375723767237772378723797238072381723827238372384723857238672387723887238972390723917239272393723947239572396723977239872399724007240172402724037240472405724067240772408724097241072411724127241372414724157241672417724187241972420724217242272423724247242572426724277242872429724307243172432724337243472435724367243772438724397244072441724427244372444724457244672447724487244972450724517245272453724547245572456724577245872459724607246172462724637246472465724667246772468724697247072471724727247372474724757247672477724787247972480724817248272483724847248572486724877248872489724907249172492724937249472495724967249772498724997250072501725027250372504725057250672507725087250972510725117251272513725147251572516725177251872519725207252172522725237252472525725267252772528725297253072531725327253372534725357253672537725387253972540725417254272543725447254572546725477254872549725507255172552725537255472555725567255772558725597256072561725627256372564725657256672567725687256972570725717257272573725747257572576725777257872579725807258172582725837258472585725867258772588725897259072591725927259372594725957259672597725987259972600726017260272603726047260572606726077260872609726107261172612726137261472615726167261772618726197262072621726227262372624726257262672627726287262972630726317263272633726347263572636726377263872639726407264172642726437264472645726467264772648726497265072651726527265372654726557265672657726587265972660726617266272663726647266572666726677266872669726707267172672726737267472675726767267772678726797268072681726827268372684726857268672687726887268972690726917269272693726947269572696726977269872699727007270172702727037270472705727067270772708727097271072711727127271372714727157271672717727187271972720727217272272723727247272572726727277272872729727307273172732727337273472735727367273772738727397274072741727427274372744727457274672747727487274972750727517275272753727547275572756727577275872759727607276172762727637276472765727667276772768727697277072771727727277372774727757277672777727787277972780727817278272783727847278572786727877278872789727907279172792727937279472795727967279772798727997280072801728027280372804728057280672807728087280972810728117281272813728147281572816728177281872819728207282172822728237282472825728267282772828728297283072831728327283372834728357283672837728387283972840728417284272843728447284572846728477284872849728507285172852728537285472855728567285772858728597286072861728627286372864728657286672867728687286972870728717287272873728747287572876728777287872879728807288172882728837288472885728867288772888728897289072891728927289372894728957289672897728987289972900729017290272903729047290572906729077290872909729107291172912729137291472915729167291772918729197292072921729227292372924729257292672927729287292972930729317293272933729347293572936729377293872939729407294172942729437294472945729467294772948729497295072951729527295372954729557295672957729587295972960729617296272963729647296572966729677296872969729707297172972729737297472975729767297772978729797298072981729827298372984729857298672987729887298972990729917299272993729947299572996729977299872999730007300173002730037300473005730067300773008730097301073011730127301373014730157301673017730187301973020730217302273023730247302573026730277302873029730307303173032730337303473035730367303773038730397304073041730427304373044730457304673047730487304973050730517305273053730547305573056730577305873059730607306173062730637306473065730667306773068730697307073071730727307373074730757307673077730787307973080730817308273083730847308573086730877308873089730907309173092730937309473095730967309773098730997310073101731027310373104731057310673107731087310973110731117311273113731147311573116731177311873119731207312173122731237312473125731267312773128731297313073131731327313373134731357313673137731387313973140731417314273143731447314573146731477314873149731507315173152731537315473155731567315773158731597316073161731627316373164731657316673167731687316973170731717317273173731747317573176731777317873179731807318173182731837318473185731867318773188731897319073191731927319373194731957319673197731987319973200732017320273203732047320573206732077320873209732107321173212732137321473215732167321773218732197322073221732227322373224732257322673227732287322973230732317323273233732347323573236732377323873239732407324173242732437324473245732467324773248732497325073251732527325373254732557325673257732587325973260732617326273263732647326573266732677326873269732707327173272732737327473275732767327773278732797328073281732827328373284732857328673287732887328973290732917329273293732947329573296732977329873299733007330173302733037330473305733067330773308733097331073311733127331373314733157331673317733187331973320733217332273323733247332573326733277332873329733307333173332733337333473335733367333773338733397334073341733427334373344733457334673347733487334973350733517335273353733547335573356733577335873359733607336173362733637336473365733667336773368733697337073371733727337373374733757337673377733787337973380733817338273383733847338573386733877338873389733907339173392733937339473395733967339773398733997340073401734027340373404734057340673407734087340973410734117341273413734147341573416734177341873419734207342173422734237342473425734267342773428734297343073431734327343373434734357343673437734387343973440734417344273443734447344573446734477344873449734507345173452734537345473455734567345773458734597346073461734627346373464734657346673467734687346973470734717347273473734747347573476734777347873479734807348173482734837348473485734867348773488734897349073491734927349373494734957349673497734987349973500735017350273503735047350573506735077350873509735107351173512735137351473515735167351773518735197352073521735227352373524735257352673527735287352973530735317353273533735347353573536735377353873539735407354173542735437354473545735467354773548735497355073551735527355373554735557355673557735587355973560735617356273563735647356573566735677356873569735707357173572735737357473575735767357773578735797358073581735827358373584735857358673587735887358973590735917359273593735947359573596735977359873599736007360173602736037360473605736067360773608736097361073611736127361373614736157361673617736187361973620736217362273623736247362573626736277362873629736307363173632736337363473635736367363773638736397364073641736427364373644736457364673647736487364973650736517365273653736547365573656736577365873659736607366173662736637366473665736667366773668736697367073671736727367373674736757367673677736787367973680736817368273683736847368573686736877368873689736907369173692736937369473695736967369773698736997370073701737027370373704737057370673707737087370973710737117371273713737147371573716737177371873719737207372173722737237372473725737267372773728737297373073731737327373373734737357373673737737387373973740737417374273743737447374573746737477374873749737507375173752737537375473755737567375773758737597376073761737627376373764737657376673767737687376973770737717377273773737747377573776737777377873779737807378173782737837378473785737867378773788737897379073791737927379373794737957379673797737987379973800738017380273803738047380573806738077380873809738107381173812738137381473815738167381773818738197382073821738227382373824738257382673827738287382973830738317383273833738347383573836738377383873839738407384173842738437384473845738467384773848738497385073851738527385373854738557385673857738587385973860738617386273863738647386573866738677386873869738707387173872738737387473875738767387773878738797388073881738827388373884738857388673887738887388973890738917389273893738947389573896738977389873899739007390173902739037390473905739067390773908739097391073911739127391373914739157391673917739187391973920739217392273923739247392573926739277392873929739307393173932739337393473935739367393773938739397394073941739427394373944739457394673947739487394973950739517395273953739547395573956739577395873959739607396173962739637396473965739667396773968739697397073971739727397373974739757397673977739787397973980739817398273983739847398573986739877398873989739907399173992739937399473995739967399773998739997400074001740027400374004740057400674007740087400974010740117401274013740147401574016740177401874019740207402174022740237402474025740267402774028740297403074031740327403374034740357403674037740387403974040740417404274043740447404574046740477404874049740507405174052740537405474055740567405774058740597406074061740627406374064740657406674067740687406974070740717407274073740747407574076740777407874079740807408174082740837408474085740867408774088740897409074091740927409374094740957409674097740987409974100741017410274103741047410574106741077410874109741107411174112741137411474115741167411774118741197412074121741227412374124741257412674127741287412974130741317413274133741347413574136741377413874139741407414174142741437414474145741467414774148741497415074151741527415374154741557415674157741587415974160741617416274163741647416574166741677416874169741707417174172741737417474175741767417774178741797418074181741827418374184741857418674187741887418974190741917419274193741947419574196741977419874199742007420174202742037420474205742067420774208742097421074211742127421374214742157421674217742187421974220742217422274223742247422574226742277422874229742307423174232742337423474235742367423774238742397424074241742427424374244742457424674247742487424974250742517425274253742547425574256742577425874259742607426174262742637426474265742667426774268742697427074271742727427374274742757427674277742787427974280742817428274283742847428574286742877428874289742907429174292742937429474295742967429774298742997430074301743027430374304743057430674307743087430974310743117431274313743147431574316743177431874319743207432174322743237432474325743267432774328743297433074331743327433374334743357433674337743387433974340743417434274343743447434574346743477434874349743507435174352743537435474355743567435774358743597436074361743627436374364743657436674367743687436974370743717437274373743747437574376743777437874379743807438174382743837438474385743867438774388743897439074391743927439374394743957439674397743987439974400744017440274403744047440574406744077440874409744107441174412744137441474415744167441774418744197442074421744227442374424744257442674427744287442974430744317443274433744347443574436744377443874439744407444174442744437444474445744467444774448744497445074451744527445374454744557445674457744587445974460744617446274463744647446574466744677446874469744707447174472744737447474475744767447774478744797448074481744827448374484744857448674487744887448974490744917449274493744947449574496744977449874499745007450174502745037450474505745067450774508745097451074511745127451374514745157451674517745187451974520745217452274523745247452574526745277452874529745307453174532745337453474535745367453774538745397454074541745427454374544745457454674547745487454974550745517455274553745547455574556745577455874559745607456174562745637456474565745667456774568745697457074571745727457374574745757457674577745787457974580745817458274583745847458574586745877458874589745907459174592745937459474595745967459774598745997460074601746027460374604746057460674607746087460974610746117461274613746147461574616746177461874619746207462174622746237462474625746267462774628746297463074631746327463374634746357463674637746387463974640746417464274643746447464574646746477464874649746507465174652746537465474655746567465774658746597466074661746627466374664746657466674667746687466974670746717467274673746747467574676746777467874679746807468174682746837468474685746867468774688746897469074691746927469374694746957469674697746987469974700747017470274703747047470574706747077470874709747107471174712747137471474715747167471774718747197472074721747227472374724747257472674727747287472974730747317473274733747347473574736747377473874739747407474174742747437474474745747467474774748747497475074751747527475374754747557475674757747587475974760747617476274763747647476574766747677476874769747707477174772747737477474775747767477774778747797478074781747827478374784747857478674787747887478974790747917479274793747947479574796747977479874799748007480174802748037480474805748067480774808748097481074811748127481374814748157481674817748187481974820748217482274823748247482574826748277482874829748307483174832748337483474835748367483774838748397484074841748427484374844748457484674847748487484974850748517485274853748547485574856748577485874859748607486174862748637486474865748667486774868748697487074871748727487374874748757487674877748787487974880748817488274883748847488574886748877488874889748907489174892748937489474895748967489774898748997490074901749027490374904749057490674907749087490974910749117491274913749147491574916749177491874919749207492174922749237492474925749267492774928749297493074931749327493374934749357493674937749387493974940749417494274943749447494574946749477494874949749507495174952749537495474955749567495774958749597496074961749627496374964749657496674967749687496974970749717497274973749747497574976749777497874979749807498174982749837498474985749867498774988749897499074991749927499374994749957499674997749987499975000750017500275003750047500575006750077500875009750107501175012750137501475015750167501775018750197502075021750227502375024750257502675027750287502975030750317503275033750347503575036750377503875039750407504175042750437504475045750467504775048750497505075051750527505375054750557505675057750587505975060750617506275063750647506575066750677506875069750707507175072750737507475075750767507775078750797508075081750827508375084750857508675087750887508975090750917509275093750947509575096750977509875099751007510175102751037510475105751067510775108751097511075111751127511375114751157511675117751187511975120751217512275123751247512575126751277512875129751307513175132751337513475135751367513775138751397514075141751427514375144751457514675147751487514975150751517515275153751547515575156751577515875159751607516175162751637516475165751667516775168751697517075171751727517375174751757517675177751787517975180751817518275183751847518575186751877518875189751907519175192751937519475195751967519775198751997520075201752027520375204752057520675207752087520975210752117521275213752147521575216752177521875219752207522175222752237522475225752267522775228752297523075231752327523375234752357523675237752387523975240752417524275243752447524575246752477524875249752507525175252752537525475255752567525775258752597526075261752627526375264752657526675267752687526975270752717527275273752747527575276752777527875279752807528175282752837528475285752867528775288752897529075291752927529375294752957529675297752987529975300753017530275303753047530575306753077530875309753107531175312753137531475315753167531775318753197532075321753227532375324753257532675327753287532975330753317533275333753347533575336753377533875339753407534175342753437534475345753467534775348753497535075351753527535375354753557535675357753587535975360753617536275363753647536575366753677536875369753707537175372753737537475375753767537775378753797538075381753827538375384753857538675387753887538975390753917539275393753947539575396753977539875399754007540175402754037540475405754067540775408754097541075411754127541375414754157541675417754187541975420754217542275423754247542575426754277542875429754307543175432754337543475435754367543775438754397544075441754427544375444754457544675447754487544975450754517545275453754547545575456754577545875459754607546175462754637546475465754667546775468754697547075471754727547375474754757547675477754787547975480754817548275483754847548575486754877548875489754907549175492754937549475495754967549775498754997550075501755027550375504755057550675507755087550975510755117551275513755147551575516755177551875519755207552175522755237552475525755267552775528755297553075531755327553375534755357553675537755387553975540755417554275543755447554575546755477554875549755507555175552755537555475555755567555775558755597556075561755627556375564755657556675567755687556975570755717557275573755747557575576755777557875579755807558175582755837558475585755867558775588755897559075591755927559375594755957559675597755987559975600756017560275603756047560575606756077560875609756107561175612756137561475615756167561775618756197562075621756227562375624756257562675627756287562975630756317563275633756347563575636756377563875639756407564175642756437564475645756467564775648756497565075651756527565375654756557565675657756587565975660756617566275663756647566575666756677566875669756707567175672756737567475675756767567775678756797568075681756827568375684756857568675687756887568975690756917569275693756947569575696756977569875699757007570175702757037570475705757067570775708757097571075711757127571375714757157571675717757187571975720757217572275723757247572575726757277572875729757307573175732757337573475735757367573775738757397574075741757427574375744757457574675747757487574975750757517575275753757547575575756757577575875759757607576175762757637576475765757667576775768757697577075771757727577375774757757577675777757787577975780757817578275783757847578575786757877578875789757907579175792757937579475795757967579775798757997580075801758027580375804758057580675807758087580975810758117581275813758147581575816758177581875819758207582175822758237582475825758267582775828758297583075831758327583375834758357583675837758387583975840758417584275843758447584575846758477584875849758507585175852758537585475855758567585775858758597586075861758627586375864758657586675867758687586975870758717587275873758747587575876758777587875879758807588175882758837588475885758867588775888758897589075891758927589375894758957589675897758987589975900759017590275903759047590575906759077590875909759107591175912759137591475915759167591775918759197592075921759227592375924759257592675927759287592975930759317593275933759347593575936759377593875939759407594175942759437594475945759467594775948759497595075951759527595375954759557595675957759587595975960759617596275963759647596575966759677596875969759707597175972759737597475975759767597775978759797598075981759827598375984759857598675987759887598975990759917599275993759947599575996759977599875999760007600176002760037600476005760067600776008760097601076011760127601376014760157601676017760187601976020760217602276023760247602576026760277602876029760307603176032760337603476035760367603776038760397604076041760427604376044760457604676047760487604976050760517605276053760547605576056760577605876059760607606176062760637606476065760667606776068760697607076071760727607376074760757607676077760787607976080760817608276083760847608576086760877608876089760907609176092760937609476095760967609776098760997610076101761027610376104761057610676107761087610976110761117611276113761147611576116761177611876119761207612176122761237612476125761267612776128761297613076131761327613376134761357613676137761387613976140761417614276143761447614576146761477614876149761507615176152761537615476155761567615776158761597616076161761627616376164761657616676167761687616976170761717617276173761747617576176761777617876179761807618176182761837618476185761867618776188761897619076191761927619376194761957619676197761987619976200762017620276203762047620576206762077620876209762107621176212762137621476215762167621776218762197622076221762227622376224762257622676227762287622976230762317623276233762347623576236762377623876239762407624176242762437624476245762467624776248762497625076251762527625376254762557625676257762587625976260762617626276263762647626576266762677626876269762707627176272762737627476275762767627776278762797628076281762827628376284762857628676287762887628976290762917629276293762947629576296762977629876299763007630176302763037630476305763067630776308763097631076311763127631376314763157631676317763187631976320763217632276323763247632576326763277632876329763307633176332763337633476335763367633776338763397634076341763427634376344763457634676347763487634976350763517635276353763547635576356763577635876359763607636176362763637636476365763667636776368763697637076371763727637376374763757637676377763787637976380763817638276383763847638576386763877638876389763907639176392763937639476395763967639776398763997640076401764027640376404764057640676407764087640976410764117641276413764147641576416764177641876419764207642176422764237642476425764267642776428764297643076431764327643376434764357643676437764387643976440764417644276443764447644576446764477644876449764507645176452764537645476455764567645776458764597646076461764627646376464764657646676467764687646976470764717647276473764747647576476764777647876479764807648176482764837648476485764867648776488764897649076491764927649376494764957649676497764987649976500765017650276503765047650576506765077650876509765107651176512765137651476515765167651776518765197652076521765227652376524765257652676527765287652976530765317653276533765347653576536765377653876539765407654176542765437654476545765467654776548765497655076551765527655376554765557655676557765587655976560765617656276563765647656576566765677656876569765707657176572765737657476575765767657776578765797658076581765827658376584765857658676587765887658976590765917659276593765947659576596765977659876599766007660176602766037660476605766067660776608766097661076611766127661376614766157661676617766187661976620766217662276623766247662576626766277662876629766307663176632766337663476635766367663776638766397664076641766427664376644766457664676647766487664976650766517665276653766547665576656766577665876659766607666176662766637666476665766667666776668766697667076671766727667376674766757667676677766787667976680766817668276683766847668576686766877668876689766907669176692766937669476695766967669776698766997670076701767027670376704767057670676707767087670976710767117671276713767147671576716767177671876719767207672176722767237672476725767267672776728767297673076731767327673376734767357673676737767387673976740767417674276743767447674576746767477674876749767507675176752767537675476755767567675776758767597676076761767627676376764767657676676767767687676976770767717677276773767747677576776767777677876779767807678176782767837678476785767867678776788767897679076791767927679376794767957679676797767987679976800768017680276803768047680576806768077680876809768107681176812768137681476815768167681776818768197682076821768227682376824768257682676827768287682976830768317683276833768347683576836768377683876839768407684176842768437684476845768467684776848768497685076851768527685376854768557685676857768587685976860768617686276863768647686576866768677686876869768707687176872768737687476875768767687776878768797688076881768827688376884768857688676887768887688976890768917689276893768947689576896768977689876899769007690176902769037690476905769067690776908769097691076911769127691376914769157691676917769187691976920769217692276923769247692576926769277692876929769307693176932769337693476935769367693776938769397694076941769427694376944769457694676947769487694976950769517695276953769547695576956769577695876959769607696176962769637696476965769667696776968769697697076971769727697376974769757697676977769787697976980769817698276983769847698576986769877698876989769907699176992769937699476995769967699776998769997700077001770027700377004770057700677007770087700977010770117701277013770147701577016770177701877019770207702177022770237702477025770267702777028770297703077031770327703377034770357703677037770387703977040770417704277043770447704577046770477704877049770507705177052770537705477055770567705777058770597706077061770627706377064770657706677067770687706977070770717707277073770747707577076770777707877079770807708177082770837708477085770867708777088770897709077091770927709377094770957709677097770987709977100771017710277103771047710577106771077710877109771107711177112771137711477115771167711777118771197712077121771227712377124771257712677127771287712977130771317713277133771347713577136771377713877139771407714177142771437714477145771467714777148771497715077151771527715377154771557715677157771587715977160771617716277163771647716577166771677716877169771707717177172771737717477175771767717777178771797718077181771827718377184771857718677187771887718977190771917719277193771947719577196771977719877199772007720177202772037720477205772067720777208772097721077211772127721377214772157721677217772187721977220772217722277223772247722577226772277722877229772307723177232772337723477235772367723777238772397724077241772427724377244772457724677247772487724977250772517725277253772547725577256772577725877259772607726177262772637726477265772667726777268772697727077271772727727377274772757727677277772787727977280772817728277283772847728577286772877728877289772907729177292772937729477295772967729777298772997730077301773027730377304773057730677307773087730977310773117731277313773147731577316773177731877319773207732177322773237732477325773267732777328773297733077331773327733377334773357733677337773387733977340773417734277343773447734577346773477734877349773507735177352773537735477355773567735777358773597736077361773627736377364773657736677367773687736977370773717737277373773747737577376773777737877379773807738177382773837738477385773867738777388773897739077391773927739377394773957739677397773987739977400774017740277403774047740577406774077740877409774107741177412774137741477415774167741777418774197742077421774227742377424774257742677427774287742977430774317743277433774347743577436774377743877439774407744177442774437744477445774467744777448774497745077451774527745377454774557745677457774587745977460774617746277463774647746577466774677746877469774707747177472774737747477475774767747777478774797748077481774827748377484774857748677487774887748977490774917749277493774947749577496774977749877499775007750177502775037750477505775067750777508775097751077511775127751377514775157751677517775187751977520775217752277523775247752577526775277752877529775307753177532775337753477535775367753777538775397754077541775427754377544775457754677547775487754977550775517755277553775547755577556775577755877559775607756177562775637756477565775667756777568775697757077571775727757377574775757757677577775787757977580775817758277583775847758577586775877758877589775907759177592775937759477595775967759777598775997760077601776027760377604776057760677607776087760977610776117761277613776147761577616776177761877619776207762177622776237762477625776267762777628776297763077631776327763377634776357763677637776387763977640776417764277643776447764577646776477764877649776507765177652776537765477655776567765777658776597766077661776627766377664776657766677667776687766977670776717767277673776747767577676776777767877679776807768177682776837768477685776867768777688776897769077691776927769377694776957769677697776987769977700777017770277703777047770577706777077770877709777107771177712777137771477715777167771777718777197772077721777227772377724777257772677727777287772977730777317773277733777347773577736777377773877739777407774177742777437774477745777467774777748777497775077751777527775377754777557775677757777587775977760777617776277763777647776577766777677776877769777707777177772777737777477775777767777777778777797778077781777827778377784777857778677787777887778977790777917779277793777947779577796777977779877799778007780177802778037780477805778067780777808778097781077811778127781377814778157781677817778187781977820778217782277823778247782577826778277782877829778307783177832778337783477835778367783777838778397784077841778427784377844778457784677847778487784977850778517785277853778547785577856778577785877859778607786177862778637786477865778667786777868778697787077871778727787377874778757787677877778787787977880778817788277883778847788577886778877788877889778907789177892778937789477895778967789777898778997790077901779027790377904779057790677907779087790977910779117791277913779147791577916779177791877919779207792177922779237792477925779267792777928779297793077931779327793377934779357793677937779387793977940779417794277943779447794577946779477794877949779507795177952779537795477955779567795777958779597796077961779627796377964779657796677967779687796977970779717797277973779747797577976779777797877979779807798177982779837798477985779867798777988779897799077991779927799377994779957799677997779987799978000780017800278003780047800578006780077800878009780107801178012780137801478015780167801778018780197802078021780227802378024780257802678027780287802978030780317803278033780347803578036780377803878039780407804178042780437804478045780467804778048780497805078051780527805378054780557805678057780587805978060780617806278063780647806578066780677806878069780707807178072780737807478075780767807778078780797808078081780827808378084780857808678087780887808978090780917809278093780947809578096780977809878099781007810178102781037810478105781067810778108781097811078111781127811378114781157811678117781187811978120781217812278123781247812578126781277812878129781307813178132781337813478135781367813778138781397814078141781427814378144781457814678147781487814978150781517815278153781547815578156781577815878159781607816178162781637816478165781667816778168781697817078171781727817378174781757817678177781787817978180781817818278183781847818578186781877818878189781907819178192781937819478195781967819778198781997820078201782027820378204782057820678207782087820978210782117821278213782147821578216782177821878219782207822178222782237822478225782267822778228782297823078231782327823378234782357823678237782387823978240782417824278243782447824578246782477824878249782507825178252782537825478255782567825778258782597826078261782627826378264782657826678267782687826978270782717827278273782747827578276782777827878279782807828178282782837828478285782867828778288782897829078291782927829378294782957829678297782987829978300783017830278303783047830578306783077830878309783107831178312783137831478315783167831778318783197832078321783227832378324783257832678327783287832978330783317833278333783347833578336783377833878339783407834178342783437834478345783467834778348783497835078351783527835378354783557835678357783587835978360783617836278363783647836578366783677836878369783707837178372783737837478375783767837778378783797838078381783827838378384783857838678387783887838978390783917839278393783947839578396783977839878399784007840178402784037840478405784067840778408784097841078411784127841378414784157841678417784187841978420784217842278423784247842578426784277842878429784307843178432784337843478435784367843778438784397844078441784427844378444784457844678447784487844978450784517845278453784547845578456784577845878459784607846178462784637846478465784667846778468784697847078471784727847378474784757847678477784787847978480784817848278483784847848578486784877848878489784907849178492784937849478495784967849778498784997850078501785027850378504785057850678507785087850978510785117851278513785147851578516785177851878519785207852178522785237852478525785267852778528785297853078531785327853378534785357853678537785387853978540785417854278543785447854578546785477854878549785507855178552785537855478555785567855778558785597856078561785627856378564785657856678567785687856978570785717857278573785747857578576785777857878579785807858178582785837858478585785867858778588785897859078591785927859378594785957859678597785987859978600786017860278603786047860578606786077860878609786107861178612786137861478615786167861778618786197862078621786227862378624786257862678627786287862978630786317863278633786347863578636786377863878639786407864178642786437864478645786467864778648786497865078651786527865378654786557865678657786587865978660786617866278663786647866578666786677866878669786707867178672786737867478675786767867778678786797868078681786827868378684786857868678687786887868978690786917869278693786947869578696786977869878699787007870178702787037870478705787067870778708787097871078711787127871378714787157871678717787187871978720787217872278723787247872578726787277872878729787307873178732787337873478735787367873778738787397874078741787427874378744787457874678747787487874978750787517875278753787547875578756787577875878759787607876178762787637876478765787667876778768787697877078771787727877378774787757877678777787787877978780787817878278783787847878578786787877878878789787907879178792787937879478795787967879778798787997880078801788027880378804788057880678807788087880978810788117881278813788147881578816788177881878819788207882178822788237882478825788267882778828788297883078831788327883378834788357883678837788387883978840788417884278843788447884578846788477884878849788507885178852788537885478855788567885778858788597886078861788627886378864788657886678867788687886978870788717887278873788747887578876788777887878879788807888178882788837888478885788867888778888788897889078891788927889378894788957889678897788987889978900789017890278903789047890578906789077890878909789107891178912789137891478915789167891778918789197892078921789227892378924789257892678927789287892978930789317893278933789347893578936789377893878939789407894178942789437894478945789467894778948789497895078951789527895378954789557895678957789587895978960789617896278963789647896578966789677896878969789707897178972789737897478975789767897778978789797898078981789827898378984789857898678987789887898978990789917899278993789947899578996789977899878999790007900179002790037900479005790067900779008790097901079011790127901379014790157901679017790187901979020790217902279023790247902579026790277902879029790307903179032790337903479035790367903779038790397904079041790427904379044790457904679047790487904979050790517905279053790547905579056790577905879059790607906179062790637906479065790667906779068790697907079071790727907379074790757907679077790787907979080790817908279083790847908579086790877908879089790907909179092790937909479095790967909779098790997910079101791027910379104791057910679107791087910979110791117911279113791147911579116791177911879119791207912179122791237912479125791267912779128791297913079131791327913379134791357913679137791387913979140791417914279143791447914579146791477914879149791507915179152791537915479155791567915779158791597916079161791627916379164791657916679167791687916979170791717917279173791747917579176791777917879179791807918179182791837918479185791867918779188791897919079191791927919379194791957919679197791987919979200792017920279203792047920579206792077920879209792107921179212792137921479215792167921779218792197922079221792227922379224792257922679227792287922979230792317923279233792347923579236792377923879239792407924179242792437924479245792467924779248792497925079251792527925379254792557925679257792587925979260792617926279263792647926579266792677926879269792707927179272792737927479275792767927779278792797928079281792827928379284792857928679287792887928979290792917929279293792947929579296792977929879299793007930179302793037930479305793067930779308793097931079311793127931379314793157931679317793187931979320793217932279323793247932579326793277932879329793307933179332793337933479335793367933779338793397934079341793427934379344793457934679347793487934979350793517935279353793547935579356793577935879359793607936179362793637936479365793667936779368793697937079371793727937379374793757937679377793787937979380793817938279383793847938579386793877938879389793907939179392793937939479395793967939779398793997940079401794027940379404794057940679407794087940979410794117941279413794147941579416794177941879419794207942179422794237942479425794267942779428794297943079431794327943379434794357943679437794387943979440794417944279443794447944579446794477944879449794507945179452794537945479455794567945779458794597946079461794627946379464794657946679467794687946979470794717947279473794747947579476794777947879479794807948179482794837948479485794867948779488794897949079491794927949379494794957949679497794987949979500795017950279503795047950579506795077950879509795107951179512795137951479515795167951779518795197952079521795227952379524795257952679527795287952979530795317953279533795347953579536795377953879539795407954179542795437954479545795467954779548795497955079551795527955379554795557955679557795587955979560795617956279563795647956579566795677956879569795707957179572795737957479575795767957779578795797958079581795827958379584795857958679587795887958979590795917959279593795947959579596795977959879599796007960179602796037960479605796067960779608796097961079611796127961379614796157961679617796187961979620796217962279623796247962579626796277962879629796307963179632796337963479635796367963779638796397964079641796427964379644796457964679647796487964979650796517965279653796547965579656796577965879659796607966179662796637966479665796667966779668796697967079671796727967379674796757967679677796787967979680796817968279683796847968579686796877968879689796907969179692796937969479695796967969779698796997970079701797027970379704797057970679707797087970979710797117971279713797147971579716797177971879719797207972179722797237972479725797267972779728797297973079731797327973379734797357973679737797387973979740797417974279743797447974579746797477974879749797507975179752797537975479755797567975779758797597976079761797627976379764797657976679767797687976979770797717977279773797747977579776797777977879779797807978179782797837978479785797867978779788797897979079791797927979379794797957979679797797987979979800798017980279803798047980579806798077980879809798107981179812798137981479815798167981779818798197982079821798227982379824798257982679827798287982979830798317983279833798347983579836798377983879839798407984179842798437984479845798467984779848798497985079851798527985379854798557985679857798587985979860798617986279863798647986579866798677986879869798707987179872798737987479875798767987779878798797988079881798827988379884798857988679887798887988979890798917989279893798947989579896798977989879899799007990179902799037990479905799067990779908799097991079911799127991379914799157991679917799187991979920799217992279923799247992579926799277992879929799307993179932799337993479935799367993779938799397994079941799427994379944799457994679947799487994979950799517995279953799547995579956799577995879959799607996179962799637996479965799667996779968799697997079971799727997379974799757997679977799787997979980799817998279983799847998579986799877998879989799907999179992799937999479995799967999779998799998000080001800028000380004800058000680007800088000980010800118001280013800148001580016800178001880019800208002180022800238002480025800268002780028800298003080031800328003380034800358003680037800388003980040800418004280043800448004580046800478004880049800508005180052800538005480055800568005780058800598006080061800628006380064800658006680067800688006980070800718007280073800748007580076800778007880079800808008180082800838008480085800868008780088800898009080091800928009380094800958009680097800988009980100801018010280103801048010580106801078010880109801108011180112801138011480115801168011780118801198012080121801228012380124801258012680127801288012980130801318013280133801348013580136801378013880139801408014180142801438014480145801468014780148801498015080151801528015380154801558015680157801588015980160801618016280163801648016580166801678016880169801708017180172801738017480175801768017780178801798018080181801828018380184801858018680187801888018980190801918019280193801948019580196801978019880199802008020180202802038020480205802068020780208802098021080211802128021380214802158021680217802188021980220802218022280223802248022580226802278022880229802308023180232802338023480235802368023780238802398024080241802428024380244802458024680247802488024980250802518025280253802548025580256802578025880259802608026180262802638026480265802668026780268802698027080271802728027380274802758027680277802788027980280802818028280283802848028580286802878028880289802908029180292802938029480295802968029780298802998030080301803028030380304803058030680307803088030980310803118031280313803148031580316803178031880319803208032180322803238032480325803268032780328803298033080331803328033380334803358033680337803388033980340803418034280343803448034580346803478034880349803508035180352803538035480355803568035780358803598036080361803628036380364803658036680367803688036980370803718037280373803748037580376803778037880379803808038180382803838038480385803868038780388803898039080391803928039380394803958039680397803988039980400804018040280403804048040580406804078040880409804108041180412804138041480415804168041780418804198042080421804228042380424804258042680427804288042980430804318043280433804348043580436804378043880439804408044180442804438044480445804468044780448804498045080451804528045380454804558045680457804588045980460804618046280463804648046580466804678046880469804708047180472804738047480475804768047780478804798048080481804828048380484804858048680487804888048980490804918049280493804948049580496804978049880499805008050180502805038050480505805068050780508805098051080511805128051380514805158051680517805188051980520805218052280523805248052580526805278052880529805308053180532805338053480535805368053780538805398054080541805428054380544805458054680547805488054980550805518055280553805548055580556805578055880559805608056180562805638056480565805668056780568805698057080571805728057380574805758057680577805788057980580805818058280583805848058580586805878058880589805908059180592805938059480595805968059780598805998060080601806028060380604806058060680607806088060980610806118061280613806148061580616806178061880619806208062180622806238062480625806268062780628806298063080631806328063380634806358063680637806388063980640806418064280643806448064580646806478064880649806508065180652806538065480655806568065780658806598066080661806628066380664806658066680667806688066980670806718067280673806748067580676806778067880679806808068180682806838068480685806868068780688806898069080691806928069380694806958069680697806988069980700807018070280703807048070580706807078070880709807108071180712807138071480715807168071780718807198072080721807228072380724807258072680727807288072980730807318073280733807348073580736807378073880739807408074180742807438074480745807468074780748807498075080751807528075380754807558075680757807588075980760807618076280763807648076580766807678076880769807708077180772807738077480775807768077780778807798078080781807828078380784807858078680787807888078980790807918079280793807948079580796807978079880799808008080180802808038080480805808068080780808808098081080811808128081380814808158081680817808188081980820808218082280823808248082580826808278082880829808308083180832808338083480835808368083780838808398084080841808428084380844808458084680847808488084980850808518085280853808548085580856808578085880859808608086180862808638086480865808668086780868808698087080871808728087380874808758087680877808788087980880808818088280883808848088580886808878088880889808908089180892808938089480895808968089780898808998090080901809028090380904809058090680907809088090980910809118091280913809148091580916809178091880919809208092180922809238092480925809268092780928809298093080931809328093380934809358093680937809388093980940809418094280943809448094580946809478094880949809508095180952809538095480955809568095780958809598096080961809628096380964809658096680967809688096980970809718097280973809748097580976809778097880979809808098180982809838098480985809868098780988809898099080991809928099380994809958099680997809988099981000810018100281003810048100581006810078100881009810108101181012810138101481015810168101781018810198102081021810228102381024810258102681027810288102981030810318103281033810348103581036810378103881039810408104181042810438104481045810468104781048810498105081051810528105381054810558105681057810588105981060810618106281063810648106581066810678106881069810708107181072810738107481075810768107781078810798108081081810828108381084810858108681087810888108981090810918109281093810948109581096810978109881099811008110181102811038110481105811068110781108811098111081111811128111381114811158111681117811188111981120811218112281123811248112581126811278112881129811308113181132811338113481135811368113781138811398114081141811428114381144811458114681147811488114981150811518115281153811548115581156811578115881159811608116181162811638116481165811668116781168811698117081171811728117381174811758117681177811788117981180811818118281183811848118581186811878118881189811908119181192811938119481195811968119781198811998120081201812028120381204812058120681207812088120981210812118121281213812148121581216812178121881219812208122181222812238122481225812268122781228812298123081231812328123381234812358123681237812388123981240812418124281243812448124581246812478124881249812508125181252812538125481255812568125781258812598126081261812628126381264812658126681267812688126981270812718127281273812748127581276812778127881279812808128181282812838128481285812868128781288812898129081291812928129381294812958129681297812988129981300813018130281303813048130581306813078130881309813108131181312813138131481315813168131781318813198132081321813228132381324813258132681327813288132981330813318133281333813348133581336813378133881339813408134181342813438134481345813468134781348813498135081351813528135381354813558135681357813588135981360813618136281363813648136581366813678136881369813708137181372813738137481375813768137781378813798138081381813828138381384813858138681387813888138981390813918139281393813948139581396813978139881399814008140181402814038140481405814068140781408814098141081411814128141381414814158141681417814188141981420814218142281423814248142581426814278142881429814308143181432814338143481435814368143781438814398144081441814428144381444814458144681447814488144981450814518145281453814548145581456814578145881459814608146181462814638146481465814668146781468814698147081471814728147381474814758147681477814788147981480814818148281483814848148581486814878148881489814908149181492814938149481495814968149781498814998150081501815028150381504815058150681507815088150981510815118151281513815148151581516815178151881519815208152181522815238152481525815268152781528815298153081531815328153381534815358153681537815388153981540815418154281543815448154581546815478154881549815508155181552815538155481555815568155781558815598156081561815628156381564815658156681567815688156981570815718157281573815748157581576815778157881579815808158181582815838158481585815868158781588815898159081591815928159381594815958159681597815988159981600816018160281603816048160581606816078160881609816108161181612816138161481615816168161781618816198162081621816228162381624816258162681627816288162981630816318163281633816348163581636816378163881639816408164181642816438164481645816468164781648816498165081651816528165381654816558165681657816588165981660816618166281663816648166581666816678166881669816708167181672816738167481675816768167781678816798168081681816828168381684816858168681687816888168981690816918169281693816948169581696816978169881699817008170181702817038170481705817068170781708817098171081711817128171381714817158171681717817188171981720817218172281723817248172581726817278172881729817308173181732817338173481735817368173781738817398174081741817428174381744817458174681747817488174981750817518175281753817548175581756817578175881759817608176181762817638176481765817668176781768817698177081771817728177381774817758177681777817788177981780817818178281783817848178581786817878178881789817908179181792817938179481795817968179781798817998180081801818028180381804818058180681807818088180981810818118181281813818148181581816818178181881819818208182181822818238182481825818268182781828818298183081831818328183381834818358183681837818388183981840818418184281843818448184581846818478184881849818508185181852818538185481855818568185781858818598186081861818628186381864818658186681867818688186981870818718187281873818748187581876818778187881879818808188181882818838188481885818868188781888818898189081891818928189381894818958189681897818988189981900819018190281903819048190581906819078190881909819108191181912819138191481915819168191781918819198192081921819228192381924819258192681927819288192981930819318193281933819348193581936819378193881939819408194181942819438194481945819468194781948819498195081951819528195381954819558195681957819588195981960819618196281963819648196581966819678196881969819708197181972819738197481975819768197781978819798198081981819828198381984819858198681987819888198981990819918199281993819948199581996819978199881999820008200182002820038200482005820068200782008820098201082011820128201382014820158201682017820188201982020820218202282023820248202582026820278202882029820308203182032820338203482035820368203782038820398204082041820428204382044820458204682047820488204982050820518205282053820548205582056820578205882059820608206182062820638206482065820668206782068820698207082071820728207382074820758207682077820788207982080820818208282083820848208582086820878208882089820908209182092820938209482095820968209782098820998210082101821028210382104821058210682107821088210982110821118211282113821148211582116821178211882119821208212182122821238212482125821268212782128821298213082131821328213382134821358213682137821388213982140821418214282143821448214582146821478214882149821508215182152821538215482155821568215782158821598216082161821628216382164821658216682167821688216982170821718217282173821748217582176821778217882179821808218182182821838218482185821868218782188821898219082191821928219382194821958219682197821988219982200822018220282203822048220582206822078220882209822108221182212822138221482215822168221782218822198222082221822228222382224822258222682227822288222982230822318223282233822348223582236822378223882239822408224182242822438224482245822468224782248822498225082251822528225382254822558225682257822588225982260822618226282263822648226582266822678226882269822708227182272822738227482275822768227782278822798228082281822828228382284822858228682287822888228982290822918229282293822948229582296822978229882299823008230182302823038230482305823068230782308823098231082311823128231382314823158231682317823188231982320823218232282323823248232582326823278232882329823308233182332823338233482335823368233782338823398234082341823428234382344823458234682347823488234982350823518235282353823548235582356823578235882359823608236182362823638236482365823668236782368823698237082371823728237382374823758237682377823788237982380823818238282383823848238582386823878238882389823908239182392823938239482395823968239782398823998240082401824028240382404824058240682407824088240982410824118241282413824148241582416824178241882419824208242182422824238242482425824268242782428824298243082431824328243382434824358243682437824388243982440824418244282443824448244582446824478244882449824508245182452824538245482455824568245782458824598246082461824628246382464824658246682467824688246982470824718247282473824748247582476824778247882479824808248182482824838248482485824868248782488824898249082491824928249382494824958249682497824988249982500825018250282503825048250582506825078250882509825108251182512825138251482515825168251782518825198252082521825228252382524825258252682527825288252982530825318253282533825348253582536825378253882539825408254182542825438254482545825468254782548825498255082551825528255382554825558255682557825588255982560825618256282563825648256582566825678256882569825708257182572825738257482575825768257782578825798258082581825828258382584825858258682587825888258982590825918259282593825948259582596825978259882599826008260182602826038260482605826068260782608826098261082611826128261382614826158261682617826188261982620826218262282623826248262582626826278262882629826308263182632826338263482635826368263782638826398264082641826428264382644826458264682647826488264982650826518265282653826548265582656826578265882659826608266182662826638266482665826668266782668826698267082671826728267382674826758267682677826788267982680826818268282683826848268582686826878268882689826908269182692826938269482695826968269782698826998270082701827028270382704827058270682707827088270982710827118271282713827148271582716827178271882719827208272182722827238272482725827268272782728827298273082731827328273382734827358273682737827388273982740827418274282743827448274582746827478274882749827508275182752827538275482755827568275782758827598276082761827628276382764827658276682767827688276982770827718277282773827748277582776827778277882779827808278182782827838278482785827868278782788827898279082791827928279382794827958279682797827988279982800828018280282803828048280582806828078280882809828108281182812828138281482815828168281782818828198282082821828228282382824828258282682827828288282982830828318283282833828348283582836828378283882839828408284182842828438284482845828468284782848828498285082851828528285382854828558285682857828588285982860828618286282863828648286582866828678286882869828708287182872828738287482875828768287782878828798288082881828828288382884828858288682887828888288982890828918289282893828948289582896828978289882899829008290182902829038290482905829068290782908829098291082911829128291382914829158291682917829188291982920829218292282923829248292582926829278292882929829308293182932829338293482935829368293782938829398294082941829428294382944829458294682947829488294982950829518295282953829548295582956829578295882959829608296182962829638296482965829668296782968829698297082971829728297382974829758297682977829788297982980829818298282983829848298582986829878298882989829908299182992829938299482995829968299782998829998300083001830028300383004830058300683007830088300983010830118301283013830148301583016830178301883019830208302183022830238302483025830268302783028830298303083031830328303383034830358303683037830388303983040830418304283043830448304583046830478304883049830508305183052830538305483055830568305783058830598306083061830628306383064830658306683067830688306983070830718307283073830748307583076830778307883079830808308183082830838308483085830868308783088830898309083091830928309383094830958309683097830988309983100831018310283103831048310583106831078310883109831108311183112831138311483115831168311783118831198312083121831228312383124831258312683127831288312983130831318313283133831348313583136831378313883139831408314183142831438314483145831468314783148831498315083151831528315383154831558315683157831588315983160831618316283163831648316583166831678316883169831708317183172831738317483175831768317783178831798318083181831828318383184831858318683187831888318983190831918319283193831948319583196831978319883199832008320183202832038320483205832068320783208832098321083211832128321383214832158321683217832188321983220832218322283223832248322583226832278322883229832308323183232832338323483235832368323783238832398324083241832428324383244832458324683247832488324983250832518325283253832548325583256832578325883259832608326183262832638326483265832668326783268832698327083271832728327383274832758327683277832788327983280832818328283283832848328583286832878328883289832908329183292832938329483295832968329783298832998330083301833028330383304833058330683307833088330983310833118331283313833148331583316833178331883319833208332183322833238332483325833268332783328833298333083331833328333383334833358333683337833388333983340833418334283343833448334583346833478334883349833508335183352833538335483355833568335783358833598336083361833628336383364833658336683367833688336983370833718337283373833748337583376833778337883379833808338183382833838338483385833868338783388833898339083391833928339383394833958339683397833988339983400834018340283403834048340583406834078340883409834108341183412834138341483415834168341783418834198342083421834228342383424834258342683427834288342983430834318343283433834348343583436834378343883439834408344183442834438344483445834468344783448834498345083451834528345383454834558345683457834588345983460834618346283463834648346583466834678346883469834708347183472834738347483475834768347783478834798348083481834828348383484834858348683487834888348983490834918349283493834948349583496834978349883499835008350183502835038350483505835068350783508835098351083511835128351383514835158351683517835188351983520835218352283523835248352583526835278352883529835308353183532835338353483535835368353783538835398354083541835428354383544835458354683547835488354983550835518355283553835548355583556835578355883559835608356183562835638356483565835668356783568835698357083571835728357383574835758357683577835788357983580835818358283583835848358583586835878358883589835908359183592835938359483595835968359783598835998360083601836028360383604836058360683607836088360983610836118361283613836148361583616836178361883619836208362183622836238362483625836268362783628836298363083631836328363383634836358363683637836388363983640836418364283643836448364583646836478364883649836508365183652836538365483655836568365783658836598366083661836628366383664836658366683667836688366983670836718367283673836748367583676836778367883679836808368183682836838368483685836868368783688836898369083691836928369383694836958369683697836988369983700837018370283703837048370583706837078370883709837108371183712837138371483715837168371783718837198372083721837228372383724837258372683727837288372983730837318373283733837348373583736837378373883739837408374183742837438374483745837468374783748837498375083751837528375383754837558375683757837588375983760837618376283763837648376583766837678376883769837708377183772837738377483775837768377783778837798378083781837828378383784837858378683787837888378983790837918379283793837948379583796837978379883799838008380183802838038380483805838068380783808838098381083811838128381383814838158381683817838188381983820838218382283823838248382583826838278382883829838308383183832838338383483835838368383783838838398384083841838428384383844838458384683847838488384983850838518385283853838548385583856838578385883859838608386183862838638386483865838668386783868838698387083871838728387383874838758387683877838788387983880838818388283883838848388583886838878388883889838908389183892838938389483895838968389783898838998390083901839028390383904839058390683907839088390983910839118391283913839148391583916839178391883919839208392183922839238392483925839268392783928839298393083931839328393383934839358393683937839388393983940839418394283943839448394583946839478394883949839508395183952839538395483955839568395783958839598396083961839628396383964839658396683967839688396983970839718397283973839748397583976839778397883979839808398183982839838398483985839868398783988839898399083991839928399383994839958399683997839988399984000840018400284003840048400584006840078400884009840108401184012840138401484015840168401784018840198402084021840228402384024840258402684027840288402984030840318403284033840348403584036840378403884039840408404184042840438404484045840468404784048840498405084051840528405384054840558405684057840588405984060840618406284063840648406584066840678406884069840708407184072840738407484075840768407784078840798408084081840828408384084840858408684087840888408984090840918409284093840948409584096840978409884099841008410184102841038410484105841068410784108841098411084111841128411384114841158411684117841188411984120841218412284123841248412584126841278412884129841308413184132841338413484135841368413784138841398414084141841428414384144841458414684147841488414984150841518415284153841548415584156841578415884159841608416184162841638416484165841668416784168841698417084171841728417384174841758417684177841788417984180841818418284183841848418584186841878418884189841908419184192841938419484195841968419784198841998420084201842028420384204842058420684207842088420984210842118421284213842148421584216842178421884219842208422184222842238422484225842268422784228842298423084231842328423384234842358423684237842388423984240842418424284243842448424584246842478424884249842508425184252842538425484255842568425784258842598426084261842628426384264842658426684267842688426984270842718427284273842748427584276842778427884279842808428184282842838428484285842868428784288842898429084291842928429384294842958429684297842988429984300843018430284303843048430584306843078430884309843108431184312843138431484315843168431784318843198432084321843228432384324843258432684327843288432984330843318433284333843348433584336843378433884339843408434184342843438434484345843468434784348843498435084351843528435384354843558435684357843588435984360843618436284363843648436584366843678436884369843708437184372843738437484375843768437784378843798438084381843828438384384843858438684387843888438984390843918439284393843948439584396843978439884399844008440184402844038440484405844068440784408844098441084411844128441384414844158441684417844188441984420844218442284423844248442584426844278442884429844308443184432844338443484435844368443784438844398444084441844428444384444844458444684447844488444984450844518445284453844548445584456844578445884459844608446184462844638446484465844668446784468844698447084471844728447384474844758447684477844788447984480844818448284483844848448584486844878448884489844908449184492844938449484495844968449784498844998450084501845028450384504845058450684507845088450984510845118451284513845148451584516845178451884519845208452184522845238452484525845268452784528845298453084531845328453384534845358453684537845388453984540845418454284543845448454584546845478454884549845508455184552845538455484555845568455784558845598456084561845628456384564845658456684567845688456984570845718457284573845748457584576845778457884579845808458184582845838458484585845868458784588845898459084591845928459384594845958459684597845988459984600846018460284603846048460584606846078460884609846108461184612846138461484615846168461784618846198462084621846228462384624846258462684627846288462984630846318463284633846348463584636846378463884639846408464184642846438464484645846468464784648846498465084651846528465384654846558465684657846588465984660846618466284663846648466584666846678466884669846708467184672846738467484675846768467784678846798468084681846828468384684846858468684687846888468984690846918469284693846948469584696846978469884699847008470184702847038470484705847068470784708847098471084711847128471384714847158471684717847188471984720847218472284723847248472584726847278472884729847308473184732847338473484735847368473784738847398474084741847428474384744847458474684747847488474984750847518475284753847548475584756847578475884759847608476184762847638476484765847668476784768847698477084771847728477384774847758477684777847788477984780847818478284783847848478584786847878478884789847908479184792847938479484795847968479784798847998480084801848028480384804848058480684807848088480984810848118481284813848148481584816848178481884819848208482184822848238482484825848268482784828848298483084831848328483384834848358483684837848388483984840848418484284843848448484584846848478484884849848508485184852848538485484855848568485784858848598486084861848628486384864848658486684867848688486984870848718487284873848748487584876848778487884879848808488184882848838488484885848868488784888848898489084891848928489384894848958489684897848988489984900849018490284903849048490584906849078490884909849108491184912849138491484915849168491784918849198492084921849228492384924849258492684927849288492984930849318493284933849348493584936849378493884939849408494184942849438494484945849468494784948849498495084951849528495384954849558495684957849588495984960849618496284963849648496584966849678496884969849708497184972849738497484975849768497784978849798498084981849828498384984849858498684987849888498984990849918499284993849948499584996849978499884999850008500185002850038500485005850068500785008850098501085011850128501385014850158501685017850188501985020850218502285023850248502585026850278502885029850308503185032850338503485035850368503785038850398504085041850428504385044850458504685047850488504985050850518505285053850548505585056850578505885059850608506185062850638506485065850668506785068850698507085071850728507385074850758507685077850788507985080850818508285083850848508585086850878508885089850908509185092850938509485095850968509785098850998510085101851028510385104851058510685107851088510985110851118511285113851148511585116851178511885119851208512185122851238512485125851268512785128851298513085131851328513385134851358513685137851388513985140851418514285143851448514585146851478514885149851508515185152851538515485155851568515785158851598516085161851628516385164851658516685167851688516985170851718517285173851748517585176851778517885179851808518185182851838518485185851868518785188851898519085191851928519385194851958519685197851988519985200852018520285203852048520585206852078520885209852108521185212852138521485215852168521785218852198522085221852228522385224852258522685227852288522985230852318523285233852348523585236852378523885239852408524185242852438524485245852468524785248852498525085251852528525385254852558525685257852588525985260852618526285263852648526585266852678526885269852708527185272852738527485275852768527785278852798528085281852828528385284852858528685287852888528985290852918529285293852948529585296852978529885299853008530185302853038530485305853068530785308853098531085311853128531385314853158531685317853188531985320853218532285323853248532585326853278532885329853308533185332853338533485335853368533785338853398534085341853428534385344853458534685347853488534985350853518535285353853548535585356853578535885359853608536185362853638536485365853668536785368853698537085371853728537385374853758537685377853788537985380853818538285383853848538585386853878538885389853908539185392853938539485395853968539785398853998540085401854028540385404854058540685407854088540985410854118541285413854148541585416854178541885419854208542185422854238542485425854268542785428854298543085431854328543385434854358543685437854388543985440854418544285443854448544585446854478544885449854508545185452854538545485455854568545785458854598546085461854628546385464854658546685467854688546985470854718547285473854748547585476854778547885479854808548185482854838548485485854868548785488854898549085491854928549385494854958549685497854988549985500855018550285503855048550585506855078550885509855108551185512855138551485515855168551785518855198552085521855228552385524855258552685527855288552985530855318553285533855348553585536855378553885539855408554185542855438554485545855468554785548855498555085551855528555385554855558555685557855588555985560855618556285563855648556585566855678556885569855708557185572855738557485575855768557785578855798558085581855828558385584855858558685587855888558985590855918559285593855948559585596855978559885599856008560185602856038560485605856068560785608856098561085611856128561385614856158561685617856188561985620856218562285623856248562585626856278562885629856308563185632856338563485635856368563785638856398564085641856428564385644856458564685647856488564985650856518565285653856548565585656856578565885659856608566185662856638566485665856668566785668856698567085671856728567385674856758567685677856788567985680856818568285683856848568585686856878568885689856908569185692856938569485695856968569785698856998570085701857028570385704857058570685707857088570985710857118571285713857148571585716857178571885719857208572185722857238572485725857268572785728857298573085731857328573385734857358573685737857388573985740857418574285743857448574585746857478574885749857508575185752857538575485755857568575785758857598576085761857628576385764857658576685767857688576985770857718577285773857748577585776857778577885779857808578185782857838578485785857868578785788857898579085791857928579385794857958579685797857988579985800858018580285803858048580585806858078580885809858108581185812858138581485815858168581785818858198582085821858228582385824858258582685827858288582985830858318583285833858348583585836858378583885839858408584185842858438584485845858468584785848858498585085851858528585385854858558585685857858588585985860858618586285863858648586585866858678586885869858708587185872858738587485875858768587785878858798588085881858828588385884858858588685887858888588985890858918589285893858948589585896858978589885899859008590185902859038590485905859068590785908859098591085911859128591385914859158591685917859188591985920859218592285923859248592585926859278592885929859308593185932859338593485935859368593785938859398594085941859428594385944859458594685947859488594985950859518595285953859548595585956859578595885959859608596185962859638596485965859668596785968859698597085971859728597385974859758597685977859788597985980859818598285983859848598585986859878598885989859908599185992859938599485995859968599785998859998600086001860028600386004860058600686007860088600986010860118601286013860148601586016860178601886019860208602186022860238602486025860268602786028860298603086031860328603386034860358603686037860388603986040860418604286043860448604586046860478604886049860508605186052860538605486055860568605786058860598606086061860628606386064860658606686067860688606986070860718607286073860748607586076860778607886079860808608186082860838608486085860868608786088860898609086091860928609386094860958609686097860988609986100861018610286103861048610586106861078610886109861108611186112861138611486115861168611786118861198612086121861228612386124861258612686127861288612986130861318613286133861348613586136861378613886139861408614186142861438614486145861468614786148861498615086151861528615386154861558615686157861588615986160861618616286163861648616586166861678616886169861708617186172861738617486175861768617786178861798618086181861828618386184861858618686187861888618986190861918619286193861948619586196861978619886199862008620186202862038620486205862068620786208862098621086211862128621386214862158621686217862188621986220862218622286223862248622586226862278622886229862308623186232862338623486235862368623786238862398624086241862428624386244862458624686247862488624986250862518625286253862548625586256862578625886259862608626186262862638626486265862668626786268862698627086271862728627386274862758627686277862788627986280862818628286283862848628586286862878628886289862908629186292862938629486295862968629786298862998630086301863028630386304863058630686307863088630986310863118631286313863148631586316863178631886319863208632186322863238632486325863268632786328863298633086331863328633386334863358633686337863388633986340863418634286343863448634586346863478634886349863508635186352863538635486355863568635786358863598636086361863628636386364863658636686367863688636986370863718637286373863748637586376863778637886379863808638186382863838638486385863868638786388863898639086391863928639386394863958639686397863988639986400864018640286403864048640586406864078640886409864108641186412864138641486415864168641786418864198642086421864228642386424864258642686427864288642986430864318643286433864348643586436864378643886439864408644186442864438644486445864468644786448864498645086451864528645386454864558645686457864588645986460864618646286463864648646586466864678646886469864708647186472864738647486475864768647786478864798648086481864828648386484864858648686487864888648986490864918649286493864948649586496864978649886499865008650186502865038650486505865068650786508865098651086511865128651386514865158651686517865188651986520865218652286523865248652586526865278652886529865308653186532865338653486535865368653786538865398654086541865428654386544865458654686547865488654986550865518655286553865548655586556865578655886559865608656186562865638656486565865668656786568865698657086571865728657386574865758657686577865788657986580865818658286583865848658586586865878658886589865908659186592865938659486595865968659786598865998660086601866028660386604866058660686607866088660986610866118661286613866148661586616866178661886619866208662186622866238662486625866268662786628866298663086631866328663386634866358663686637866388663986640866418664286643866448664586646866478664886649866508665186652866538665486655866568665786658866598666086661866628666386664866658666686667866688666986670866718667286673866748667586676866778667886679866808668186682866838668486685866868668786688866898669086691866928669386694866958669686697866988669986700867018670286703867048670586706867078670886709867108671186712867138671486715867168671786718867198672086721867228672386724867258672686727867288672986730867318673286733867348673586736867378673886739867408674186742867438674486745867468674786748867498675086751867528675386754867558675686757867588675986760867618676286763867648676586766867678676886769867708677186772867738677486775867768677786778867798678086781867828678386784867858678686787867888678986790867918679286793867948679586796867978679886799868008680186802868038680486805868068680786808868098681086811868128681386814868158681686817868188681986820868218682286823868248682586826868278682886829868308683186832868338683486835868368683786838868398684086841868428684386844868458684686847868488684986850868518685286853868548685586856868578685886859868608686186862868638686486865868668686786868868698687086871868728687386874868758687686877868788687986880868818688286883868848688586886868878688886889868908689186892868938689486895868968689786898868998690086901869028690386904869058690686907869088690986910869118691286913869148691586916869178691886919869208692186922869238692486925869268692786928869298693086931869328693386934869358693686937869388693986940869418694286943869448694586946869478694886949869508695186952869538695486955869568695786958869598696086961869628696386964869658696686967869688696986970869718697286973869748697586976869778697886979869808698186982869838698486985869868698786988869898699086991869928699386994869958699686997869988699987000870018700287003870048700587006870078700887009870108701187012870138701487015870168701787018870198702087021870228702387024870258702687027870288702987030870318703287033870348703587036870378703887039870408704187042870438704487045870468704787048870498705087051870528705387054870558705687057870588705987060870618706287063870648706587066870678706887069870708707187072870738707487075870768707787078870798708087081870828708387084870858708687087870888708987090870918709287093870948709587096870978709887099871008710187102871038710487105871068710787108871098711087111871128711387114871158711687117871188711987120871218712287123871248712587126871278712887129871308713187132871338713487135871368713787138871398714087141871428714387144871458714687147871488714987150871518715287153871548715587156871578715887159871608716187162871638716487165871668716787168871698717087171871728717387174871758717687177871788717987180871818718287183871848718587186871878718887189871908719187192871938719487195871968719787198871998720087201872028720387204872058720687207872088720987210872118721287213872148721587216872178721887219872208722187222872238722487225872268722787228872298723087231872328723387234872358723687237872388723987240872418724287243872448724587246872478724887249872508725187252872538725487255872568725787258872598726087261872628726387264872658726687267872688726987270872718727287273872748727587276872778727887279872808728187282872838728487285872868728787288872898729087291872928729387294872958729687297872988729987300873018730287303873048730587306873078730887309873108731187312873138731487315873168731787318873198732087321873228732387324873258732687327873288732987330873318733287333873348733587336873378733887339873408734187342873438734487345873468734787348873498735087351873528735387354873558735687357873588735987360873618736287363873648736587366873678736887369873708737187372873738737487375873768737787378873798738087381873828738387384873858738687387873888738987390873918739287393873948739587396873978739887399874008740187402874038740487405874068740787408874098741087411874128741387414874158741687417874188741987420874218742287423874248742587426874278742887429874308743187432874338743487435874368743787438874398744087441874428744387444874458744687447874488744987450874518745287453874548745587456874578745887459874608746187462874638746487465874668746787468874698747087471874728747387474874758747687477874788747987480874818748287483874848748587486874878748887489874908749187492874938749487495874968749787498874998750087501875028750387504875058750687507875088750987510875118751287513875148751587516875178751887519875208752187522875238752487525875268752787528875298753087531875328753387534875358753687537875388753987540875418754287543875448754587546
  1. diff -Nur linux-2.6.35.orig/crypto/Kconfig linux-2.6.35/crypto/Kconfig
  2. --- linux-2.6.35.orig/crypto/Kconfig 2010-08-02 00:11:14.000000000 +0200
  3. +++ linux-2.6.35/crypto/Kconfig 2010-08-05 22:02:04.194867989 +0200
  4. @@ -832,3 +832,6 @@
  5. source "drivers/crypto/Kconfig"
  6. endif # if CRYPTO
  7. +
  8. +source "crypto/ocf/Kconfig"
  9. +
  10. diff -Nur linux-2.6.35.orig/crypto/Makefile linux-2.6.35/crypto/Makefile
  11. --- linux-2.6.35.orig/crypto/Makefile 2010-08-02 00:11:14.000000000 +0200
  12. +++ linux-2.6.35/crypto/Makefile 2010-08-05 22:02:04.963633162 +0200
  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.35.orig/crypto/ocf/c7108/aes-7108.c linux-2.6.35/crypto/ocf/c7108/aes-7108.c
  22. --- linux-2.6.35.orig/crypto/ocf/c7108/aes-7108.c 1970-01-01 01:00:00.000000000 +0100
  23. +++ linux-2.6.35/crypto/ocf/c7108/aes-7108.c 2010-08-05 22:02:05.163624527 +0200
  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.35.orig/crypto/ocf/c7108/aes-7108.h linux-2.6.35/crypto/ocf/c7108/aes-7108.h
  865. --- linux-2.6.35.orig/crypto/ocf/c7108/aes-7108.h 1970-01-01 01:00:00.000000000 +0100
  866. +++ linux-2.6.35/crypto/ocf/c7108/aes-7108.h 2010-08-05 22:02:05.803621195 +0200
  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.35.orig/crypto/ocf/c7108/Makefile linux-2.6.35/crypto/ocf/c7108/Makefile
  1003. --- linux-2.6.35.orig/crypto/ocf/c7108/Makefile 1970-01-01 01:00:00.000000000 +0100
  1004. +++ linux-2.6.35/crypto/ocf/c7108/Makefile 2010-08-05 22:02:06.013994644 +0200
  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.35.orig/crypto/ocf/Config.in linux-2.6.35/crypto/ocf/Config.in
  1019. --- linux-2.6.35.orig/crypto/ocf/Config.in 1970-01-01 01:00:00.000000000 +0100
  1020. +++ linux-2.6.35/crypto/ocf/Config.in 2010-08-05 22:02:06.243623186 +0200
  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.35.orig/crypto/ocf/criov.c linux-2.6.35/crypto/ocf/criov.c
  1059. --- linux-2.6.35.orig/crypto/ocf/criov.c 1970-01-01 01:00:00.000000000 +0100
  1060. +++ linux-2.6.35/crypto/ocf/criov.c 2010-08-05 22:02:06.423623237 +0200
  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.35.orig/crypto/ocf/crypto.c linux-2.6.35/crypto/ocf/crypto.c
  1278. --- linux-2.6.35.orig/crypto/ocf/crypto.c 1970-01-01 01:00:00.000000000 +0100
  1279. +++ linux-2.6.35/crypto/ocf/crypto.c 2010-08-05 22:02:06.573619803 +0200
  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.35.orig/crypto/ocf/cryptocteon/cavium_crypto.c linux-2.6.35/crypto/ocf/cryptocteon/cavium_crypto.c
  3066. --- linux-2.6.35.orig/crypto/ocf/cryptocteon/cavium_crypto.c 1970-01-01 01:00:00.000000000 +0100
  3067. +++ linux-2.6.35/crypto/ocf/cryptocteon/cavium_crypto.c 2010-08-05 22:02:06.743619324 +0200
  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.35.orig/crypto/ocf/cryptocteon/cryptocteon.c linux-2.6.35/crypto/ocf/cryptocteon/cryptocteon.c
  5353. --- linux-2.6.35.orig/crypto/ocf/cryptocteon/cryptocteon.c 1970-01-01 01:00:00.000000000 +0100
  5354. +++ linux-2.6.35/crypto/ocf/cryptocteon/cryptocteon.c 2010-08-05 22:02:06.943623256 +0200
  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.35.orig/crypto/ocf/cryptocteon/Makefile linux-2.6.35/crypto/ocf/cryptocteon/Makefile
  5931. --- linux-2.6.35.orig/crypto/ocf/cryptocteon/Makefile 1970-01-01 01:00:00.000000000 +0100
  5932. +++ linux-2.6.35/crypto/ocf/cryptocteon/Makefile 2010-08-05 22:02:07.103628242 +0200
  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.35.orig/crypto/ocf/cryptodev.c linux-2.6.35/crypto/ocf/cryptodev.c
  5952. --- linux-2.6.35.orig/crypto/ocf/cryptodev.c 1970-01-01 01:00:00.000000000 +0100
  5953. +++ linux-2.6.35/crypto/ocf/cryptodev.c 2010-08-05 22:02:07.343633579 +0200
  5954. @@ -0,0 +1,1061 @@
  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. + .ioctl = cryptodev_ioctl,
  6977. +#ifdef HAVE_UNLOCKED_IOCTL
  6978. + .unlocked_ioctl = cryptodev_unlocked_ioctl,
  6979. +#endif
  6980. +};
  6981. +
  6982. +static struct miscdevice cryptodev = {
  6983. + .minor = CRYPTODEV_MINOR,
  6984. + .name = "crypto",
  6985. + .fops = &cryptodev_fops,
  6986. +};
  6987. +
  6988. +static int __init
  6989. +cryptodev_init(void)
  6990. +{
  6991. + int rc;
  6992. +
  6993. + dprintk("%s(%p)\n", __FUNCTION__, cryptodev_init);
  6994. + rc = misc_register(&cryptodev);
  6995. + if (rc) {
  6996. + printk(KERN_ERR "cryptodev: registration of /dev/crypto failed\n");
  6997. + return(rc);
  6998. + }
  6999. +
  7000. + return(0);
  7001. +}
  7002. +
  7003. +static void __exit
  7004. +cryptodev_exit(void)
  7005. +{
  7006. + dprintk("%s()\n", __FUNCTION__);
  7007. + misc_deregister(&cryptodev);
  7008. +}
  7009. +
  7010. +module_init(cryptodev_init);
  7011. +module_exit(cryptodev_exit);
  7012. +
  7013. +MODULE_LICENSE("BSD");
  7014. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  7015. +MODULE_DESCRIPTION("Cryptodev (user interface to OCF)");
  7016. diff -Nur linux-2.6.35.orig/crypto/ocf/cryptodev.h linux-2.6.35/crypto/ocf/cryptodev.h
  7017. --- linux-2.6.35.orig/crypto/ocf/cryptodev.h 1970-01-01 01:00:00.000000000 +0100
  7018. +++ linux-2.6.35/crypto/ocf/cryptodev.h 2010-08-05 22:02:07.523632533 +0200
  7019. @@ -0,0 +1,479 @@
  7020. +/* $FreeBSD: src/sys/opencrypto/cryptodev.h,v 1.25 2007/05/09 19:37:02 gnn Exp $ */
  7021. +/* $OpenBSD: cryptodev.h,v 1.31 2002/06/11 11:14:29 beck Exp $ */
  7022. +
  7023. +/*-
  7024. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  7025. + * Copyright (C) 2006-2010 David McCullough
  7026. + * Copyright (C) 2004-2005 Intel Corporation.
  7027. + * The license and original author are listed below.
  7028. + *
  7029. + * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
  7030. + * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
  7031. + *
  7032. + * This code was written by Angelos D. Keromytis in Athens, Greece, in
  7033. + * February 2000. Network Security Technologies Inc. (NSTI) kindly
  7034. + * supported the development of this code.
  7035. + *
  7036. + * Copyright (c) 2000 Angelos D. Keromytis
  7037. + *
  7038. + * Permission to use, copy, and modify this software with or without fee
  7039. + * is hereby granted, provided that this entire notice is included in
  7040. + * all source code copies of any software which is or includes a copy or
  7041. + * modification of this software.
  7042. + *
  7043. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
  7044. + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
  7045. + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
  7046. + * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
  7047. + * PURPOSE.
  7048. + *
  7049. + * Copyright (c) 2001 Theo de Raadt
  7050. + *
  7051. + * Redistribution and use in source and binary forms, with or without
  7052. + * modification, are permitted provided that the following conditions
  7053. + * are met:
  7054. + *
  7055. + * 1. Redistributions of source code must retain the above copyright
  7056. + * notice, this list of conditions and the following disclaimer.
  7057. + * 2. Redistributions in binary form must reproduce the above copyright
  7058. + * notice, this list of conditions and the following disclaimer in the
  7059. + * documentation and/or other materials provided with the distribution.
  7060. + * 3. The name of the author may not be used to endorse or promote products
  7061. + * derived from this software without specific prior written permission.
  7062. + *
  7063. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  7064. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  7065. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  7066. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  7067. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  7068. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  7069. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  7070. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  7071. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  7072. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  7073. + *
  7074. + * Effort sponsored in part by the Defense Advanced Research Projects
  7075. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  7076. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  7077. + *
  7078. + */
  7079. +
  7080. +#ifndef _CRYPTO_CRYPTO_H_
  7081. +#define _CRYPTO_CRYPTO_H_
  7082. +
  7083. +/* Some initial values */
  7084. +#define CRYPTO_DRIVERS_INITIAL 4
  7085. +#define CRYPTO_SW_SESSIONS 32
  7086. +
  7087. +/* Hash values */
  7088. +#define NULL_HASH_LEN 0
  7089. +#define MD5_HASH_LEN 16
  7090. +#define SHA1_HASH_LEN 20
  7091. +#define RIPEMD160_HASH_LEN 20
  7092. +#define SHA2_256_HASH_LEN 32
  7093. +#define SHA2_384_HASH_LEN 48
  7094. +#define SHA2_512_HASH_LEN 64
  7095. +#define MD5_KPDK_HASH_LEN 16
  7096. +#define SHA1_KPDK_HASH_LEN 20
  7097. +/* Maximum hash algorithm result length */
  7098. +#define HASH_MAX_LEN SHA2_512_HASH_LEN /* Keep this updated */
  7099. +
  7100. +/* HMAC values */
  7101. +#define NULL_HMAC_BLOCK_LEN 1
  7102. +#define MD5_HMAC_BLOCK_LEN 64
  7103. +#define SHA1_HMAC_BLOCK_LEN 64
  7104. +#define RIPEMD160_HMAC_BLOCK_LEN 64
  7105. +#define SHA2_256_HMAC_BLOCK_LEN 64
  7106. +#define SHA2_384_HMAC_BLOCK_LEN 128
  7107. +#define SHA2_512_HMAC_BLOCK_LEN 128
  7108. +/* Maximum HMAC block length */
  7109. +#define HMAC_MAX_BLOCK_LEN SHA2_512_HMAC_BLOCK_LEN /* Keep this updated */
  7110. +#define HMAC_IPAD_VAL 0x36
  7111. +#define HMAC_OPAD_VAL 0x5C
  7112. +
  7113. +/* Encryption algorithm block sizes */
  7114. +#define NULL_BLOCK_LEN 1
  7115. +#define DES_BLOCK_LEN 8
  7116. +#define DES3_BLOCK_LEN 8
  7117. +#define BLOWFISH_BLOCK_LEN 8
  7118. +#define SKIPJACK_BLOCK_LEN 8
  7119. +#define CAST128_BLOCK_LEN 8
  7120. +#define RIJNDAEL128_BLOCK_LEN 16
  7121. +#define AES_BLOCK_LEN RIJNDAEL128_BLOCK_LEN
  7122. +#define CAMELLIA_BLOCK_LEN 16
  7123. +#define ARC4_BLOCK_LEN 1
  7124. +#define EALG_MAX_BLOCK_LEN AES_BLOCK_LEN /* Keep this updated */
  7125. +
  7126. +/* Encryption algorithm min and max key sizes */
  7127. +#define NULL_MIN_KEY_LEN 0
  7128. +#define NULL_MAX_KEY_LEN 0
  7129. +#define DES_MIN_KEY_LEN 8
  7130. +#define DES_MAX_KEY_LEN 8
  7131. +#define DES3_MIN_KEY_LEN 24
  7132. +#define DES3_MAX_KEY_LEN 24
  7133. +#define BLOWFISH_MIN_KEY_LEN 4
  7134. +#define BLOWFISH_MAX_KEY_LEN 56
  7135. +#define SKIPJACK_MIN_KEY_LEN 10
  7136. +#define SKIPJACK_MAX_KEY_LEN 10
  7137. +#define CAST128_MIN_KEY_LEN 5
  7138. +#define CAST128_MAX_KEY_LEN 16
  7139. +#define RIJNDAEL128_MIN_KEY_LEN 16
  7140. +#define RIJNDAEL128_MAX_KEY_LEN 32
  7141. +#define AES_MIN_KEY_LEN RIJNDAEL128_MIN_KEY_LEN
  7142. +#define AES_MAX_KEY_LEN RIJNDAEL128_MAX_KEY_LEN
  7143. +#define CAMELLIA_MIN_KEY_LEN 16
  7144. +#define CAMELLIA_MAX_KEY_LEN 32
  7145. +#define ARC4_MIN_KEY_LEN 1
  7146. +#define ARC4_MAX_KEY_LEN 256
  7147. +
  7148. +/* Max size of data that can be processed */
  7149. +#define CRYPTO_MAX_DATA_LEN 64*1024 - 1
  7150. +
  7151. +#define CRYPTO_ALGORITHM_MIN 1
  7152. +#define CRYPTO_DES_CBC 1
  7153. +#define CRYPTO_3DES_CBC 2
  7154. +#define CRYPTO_BLF_CBC 3
  7155. +#define CRYPTO_CAST_CBC 4
  7156. +#define CRYPTO_SKIPJACK_CBC 5
  7157. +#define CRYPTO_MD5_HMAC 6
  7158. +#define CRYPTO_SHA1_HMAC 7
  7159. +#define CRYPTO_RIPEMD160_HMAC 8
  7160. +#define CRYPTO_MD5_KPDK 9
  7161. +#define CRYPTO_SHA1_KPDK 10
  7162. +#define CRYPTO_RIJNDAEL128_CBC 11 /* 128 bit blocksize */
  7163. +#define CRYPTO_AES_CBC 11 /* 128 bit blocksize -- the same as above */
  7164. +#define CRYPTO_ARC4 12
  7165. +#define CRYPTO_MD5 13
  7166. +#define CRYPTO_SHA1 14
  7167. +#define CRYPTO_NULL_HMAC 15
  7168. +#define CRYPTO_NULL_CBC 16
  7169. +#define CRYPTO_DEFLATE_COMP 17 /* Deflate compression algorithm */
  7170. +#define CRYPTO_SHA2_256_HMAC 18
  7171. +#define CRYPTO_SHA2_384_HMAC 19
  7172. +#define CRYPTO_SHA2_512_HMAC 20
  7173. +#define CRYPTO_CAMELLIA_CBC 21
  7174. +#define CRYPTO_SHA2_256 22
  7175. +#define CRYPTO_SHA2_384 23
  7176. +#define CRYPTO_SHA2_512 24
  7177. +#define CRYPTO_RIPEMD160 25
  7178. +#define CRYPTO_ALGORITHM_MAX 25 /* Keep updated - see below */
  7179. +
  7180. +/* Algorithm flags */
  7181. +#define CRYPTO_ALG_FLAG_SUPPORTED 0x01 /* Algorithm is supported */
  7182. +#define CRYPTO_ALG_FLAG_RNG_ENABLE 0x02 /* Has HW RNG for DH/DSA */
  7183. +#define CRYPTO_ALG_FLAG_DSA_SHA 0x04 /* Can do SHA on msg */
  7184. +
  7185. +/*
  7186. + * Crypto driver/device flags. They can set in the crid
  7187. + * parameter when creating a session or submitting a key
  7188. + * op to affect the device/driver assigned. If neither
  7189. + * of these are specified then the crid is assumed to hold
  7190. + * the driver id of an existing (and suitable) device that
  7191. + * must be used to satisfy the request.
  7192. + */
  7193. +#define CRYPTO_FLAG_HARDWARE 0x01000000 /* hardware accelerated */
  7194. +#define CRYPTO_FLAG_SOFTWARE 0x02000000 /* software implementation */
  7195. +
  7196. +/* NB: deprecated */
  7197. +struct session_op {
  7198. + u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
  7199. + u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
  7200. +
  7201. + u_int32_t keylen; /* cipher key */
  7202. + caddr_t key;
  7203. + int mackeylen; /* mac key */
  7204. + caddr_t mackey;
  7205. +
  7206. + u_int32_t ses; /* returns: session # */
  7207. +};
  7208. +
  7209. +struct session2_op {
  7210. + u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
  7211. + u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
  7212. +
  7213. + u_int32_t keylen; /* cipher key */
  7214. + caddr_t key;
  7215. + int mackeylen; /* mac key */
  7216. + caddr_t mackey;
  7217. +
  7218. + u_int32_t ses; /* returns: session # */
  7219. + int crid; /* driver id + flags (rw) */
  7220. + int pad[4]; /* for future expansion */
  7221. +};
  7222. +
  7223. +struct crypt_op {
  7224. + u_int32_t ses;
  7225. + u_int16_t op; /* i.e. COP_ENCRYPT */
  7226. +#define COP_NONE 0
  7227. +#define COP_ENCRYPT 1
  7228. +#define COP_DECRYPT 2
  7229. + u_int16_t flags;
  7230. +#define COP_F_BATCH 0x0008 /* Batch op if possible */
  7231. + u_int len;
  7232. + caddr_t src, dst; /* become iov[] inside kernel */
  7233. + caddr_t mac; /* must be big enough for chosen MAC */
  7234. + caddr_t iv;
  7235. +};
  7236. +
  7237. +/*
  7238. + * Parameters for looking up a crypto driver/device by
  7239. + * device name or by id. The latter are returned for
  7240. + * created sessions (crid) and completed key operations.
  7241. + */
  7242. +struct crypt_find_op {
  7243. + int crid; /* driver id + flags */
  7244. + char name[32]; /* device/driver name */
  7245. +};
  7246. +
  7247. +/* bignum parameter, in packed bytes, ... */
  7248. +struct crparam {
  7249. + caddr_t crp_p;
  7250. + u_int crp_nbits;
  7251. +};
  7252. +
  7253. +#define CRK_MAXPARAM 8
  7254. +
  7255. +struct crypt_kop {
  7256. + u_int crk_op; /* ie. CRK_MOD_EXP or other */
  7257. + u_int crk_status; /* return status */
  7258. + u_short crk_iparams; /* # of input parameters */
  7259. + u_short crk_oparams; /* # of output parameters */
  7260. + u_int crk_crid; /* NB: only used by CIOCKEY2 (rw) */
  7261. + struct crparam crk_param[CRK_MAXPARAM];
  7262. +};
  7263. +#define CRK_ALGORITM_MIN 0
  7264. +#define CRK_MOD_EXP 0
  7265. +#define CRK_MOD_EXP_CRT 1
  7266. +#define CRK_DSA_SIGN 2
  7267. +#define CRK_DSA_VERIFY 3
  7268. +#define CRK_DH_COMPUTE_KEY 4
  7269. +#define CRK_ALGORITHM_MAX 4 /* Keep updated - see below */
  7270. +
  7271. +#define CRF_MOD_EXP (1 << CRK_MOD_EXP)
  7272. +#define CRF_MOD_EXP_CRT (1 << CRK_MOD_EXP_CRT)
  7273. +#define CRF_DSA_SIGN (1 << CRK_DSA_SIGN)
  7274. +#define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY)
  7275. +#define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY)
  7276. +
  7277. +/*
  7278. + * done against open of /dev/crypto, to get a cloned descriptor.
  7279. + * Please use F_SETFD against the cloned descriptor.
  7280. + */
  7281. +#define CRIOGET _IOWR('c', 100, u_int32_t)
  7282. +#define CRIOASYMFEAT CIOCASYMFEAT
  7283. +#define CRIOFINDDEV CIOCFINDDEV
  7284. +
  7285. +/* the following are done against the cloned descriptor */
  7286. +#define CIOCGSESSION _IOWR('c', 101, struct session_op)
  7287. +#define CIOCFSESSION _IOW('c', 102, u_int32_t)
  7288. +#define CIOCCRYPT _IOWR('c', 103, struct crypt_op)
  7289. +#define CIOCKEY _IOWR('c', 104, struct crypt_kop)
  7290. +#define CIOCASYMFEAT _IOR('c', 105, u_int32_t)
  7291. +#define CIOCGSESSION2 _IOWR('c', 106, struct session2_op)
  7292. +#define CIOCKEY2 _IOWR('c', 107, struct crypt_kop)
  7293. +#define CIOCFINDDEV _IOWR('c', 108, struct crypt_find_op)
  7294. +
  7295. +struct cryptotstat {
  7296. + struct timespec acc; /* total accumulated time */
  7297. + struct timespec min; /* min time */
  7298. + struct timespec max; /* max time */
  7299. + u_int32_t count; /* number of observations */
  7300. +};
  7301. +
  7302. +struct cryptostats {
  7303. + u_int32_t cs_ops; /* symmetric crypto ops submitted */
  7304. + u_int32_t cs_errs; /* symmetric crypto ops that failed */
  7305. + u_int32_t cs_kops; /* asymetric/key ops submitted */
  7306. + u_int32_t cs_kerrs; /* asymetric/key ops that failed */
  7307. + u_int32_t cs_intrs; /* crypto swi thread activations */
  7308. + u_int32_t cs_rets; /* crypto return thread activations */
  7309. + u_int32_t cs_blocks; /* symmetric op driver block */
  7310. + u_int32_t cs_kblocks; /* symmetric op driver block */
  7311. + /*
  7312. + * When CRYPTO_TIMING is defined at compile time and the
  7313. + * sysctl debug.crypto is set to 1, the crypto system will
  7314. + * accumulate statistics about how long it takes to process
  7315. + * crypto requests at various points during processing.
  7316. + */
  7317. + struct cryptotstat cs_invoke; /* crypto_dipsatch -> crypto_invoke */
  7318. + struct cryptotstat cs_done; /* crypto_invoke -> crypto_done */
  7319. + struct cryptotstat cs_cb; /* crypto_done -> callback */
  7320. + struct cryptotstat cs_finis; /* callback -> callback return */
  7321. +
  7322. + u_int32_t cs_drops; /* crypto ops dropped due to congestion */
  7323. +};
  7324. +
  7325. +#ifdef __KERNEL__
  7326. +
  7327. +/* Standard initialization structure beginning */
  7328. +struct cryptoini {
  7329. + int cri_alg; /* Algorithm to use */
  7330. + int cri_klen; /* Key length, in bits */
  7331. + int cri_mlen; /* Number of bytes we want from the
  7332. + entire hash. 0 means all. */
  7333. + caddr_t cri_key; /* key to use */
  7334. + u_int8_t cri_iv[EALG_MAX_BLOCK_LEN]; /* IV to use */
  7335. + struct cryptoini *cri_next;
  7336. +};
  7337. +
  7338. +/* Describe boundaries of a single crypto operation */
  7339. +struct cryptodesc {
  7340. + int crd_skip; /* How many bytes to ignore from start */
  7341. + int crd_len; /* How many bytes to process */
  7342. + int crd_inject; /* Where to inject results, if applicable */
  7343. + int crd_flags;
  7344. +
  7345. +#define CRD_F_ENCRYPT 0x01 /* Set when doing encryption */
  7346. +#define CRD_F_IV_PRESENT 0x02 /* When encrypting, IV is already in
  7347. + place, so don't copy. */
  7348. +#define CRD_F_IV_EXPLICIT 0x04 /* IV explicitly provided */
  7349. +#define CRD_F_DSA_SHA_NEEDED 0x08 /* Compute SHA-1 of buffer for DSA */
  7350. +#define CRD_F_KEY_EXPLICIT 0x10 /* Key explicitly provided */
  7351. +#define CRD_F_COMP 0x0f /* Set when doing compression */
  7352. +
  7353. + struct cryptoini CRD_INI; /* Initialization/context data */
  7354. +#define crd_iv CRD_INI.cri_iv
  7355. +#define crd_key CRD_INI.cri_key
  7356. +#define crd_alg CRD_INI.cri_alg
  7357. +#define crd_klen CRD_INI.cri_klen
  7358. +#define crd_mlen CRD_INI.cri_mlen
  7359. +
  7360. + struct cryptodesc *crd_next;
  7361. +};
  7362. +
  7363. +/* Structure describing complete operation */
  7364. +struct cryptop {
  7365. + struct list_head crp_next;
  7366. + wait_queue_head_t crp_waitq;
  7367. +
  7368. + u_int64_t crp_sid; /* Session ID */
  7369. + int crp_ilen; /* Input data total length */
  7370. + int crp_olen; /* Result total length */
  7371. +
  7372. + int crp_etype; /*
  7373. + * Error type (zero means no error).
  7374. + * All error codes except EAGAIN
  7375. + * indicate possible data corruption (as in,
  7376. + * the data have been touched). On all
  7377. + * errors, the crp_sid may have changed
  7378. + * (reset to a new one), so the caller
  7379. + * should always check and use the new
  7380. + * value on future requests.
  7381. + */
  7382. + int crp_flags;
  7383. +
  7384. +#define CRYPTO_F_SKBUF 0x0001 /* Input/output are skbuf chains */
  7385. +#define CRYPTO_F_IOV 0x0002 /* Input/output are uio */
  7386. +#define CRYPTO_F_REL 0x0004 /* Must return data in same place */
  7387. +#define CRYPTO_F_BATCH 0x0008 /* Batch op if possible */
  7388. +#define CRYPTO_F_CBIMM 0x0010 /* Do callback immediately */
  7389. +#define CRYPTO_F_DONE 0x0020 /* Operation completed */
  7390. +#define CRYPTO_F_CBIFSYNC 0x0040 /* Do CBIMM if op is synchronous */
  7391. +
  7392. + caddr_t crp_buf; /* Data to be processed */
  7393. + caddr_t crp_opaque; /* Opaque pointer, passed along */
  7394. + struct cryptodesc *crp_desc; /* Linked list of processing descriptors */
  7395. +
  7396. + int (*crp_callback)(struct cryptop *); /* Callback function */
  7397. +};
  7398. +
  7399. +#define CRYPTO_BUF_CONTIG 0x0
  7400. +#define CRYPTO_BUF_IOV 0x1
  7401. +#define CRYPTO_BUF_SKBUF 0x2
  7402. +
  7403. +#define CRYPTO_OP_DECRYPT 0x0
  7404. +#define CRYPTO_OP_ENCRYPT 0x1
  7405. +
  7406. +/*
  7407. + * Hints passed to process methods.
  7408. + */
  7409. +#define CRYPTO_HINT_MORE 0x1 /* more ops coming shortly */
  7410. +
  7411. +struct cryptkop {
  7412. + struct list_head krp_next;
  7413. + wait_queue_head_t krp_waitq;
  7414. +
  7415. + int krp_flags;
  7416. +#define CRYPTO_KF_DONE 0x0001 /* Operation completed */
  7417. +#define CRYPTO_KF_CBIMM 0x0002 /* Do callback immediately */
  7418. +
  7419. + u_int krp_op; /* ie. CRK_MOD_EXP or other */
  7420. + u_int krp_status; /* return status */
  7421. + u_short krp_iparams; /* # of input parameters */
  7422. + u_short krp_oparams; /* # of output parameters */
  7423. + u_int krp_crid; /* desired device, etc. */
  7424. + u_int32_t krp_hid;
  7425. + struct crparam krp_param[CRK_MAXPARAM]; /* kvm */
  7426. + int (*krp_callback)(struct cryptkop *);
  7427. +};
  7428. +
  7429. +#include <ocf-compat.h>
  7430. +
  7431. +/*
  7432. + * Session ids are 64 bits. The lower 32 bits contain a "local id" which
  7433. + * is a driver-private session identifier. The upper 32 bits contain a
  7434. + * "hardware id" used by the core crypto code to identify the driver and
  7435. + * a copy of the driver's capabilities that can be used by client code to
  7436. + * optimize operation.
  7437. + */
  7438. +#define CRYPTO_SESID2HID(_sid) (((_sid) >> 32) & 0x00ffffff)
  7439. +#define CRYPTO_SESID2CAPS(_sid) (((_sid) >> 32) & 0xff000000)
  7440. +#define CRYPTO_SESID2LID(_sid) (((u_int32_t) (_sid)) & 0xffffffff)
  7441. +
  7442. +extern int crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard);
  7443. +extern int crypto_freesession(u_int64_t sid);
  7444. +#define CRYPTOCAP_F_HARDWARE CRYPTO_FLAG_HARDWARE
  7445. +#define CRYPTOCAP_F_SOFTWARE CRYPTO_FLAG_SOFTWARE
  7446. +#define CRYPTOCAP_F_SYNC 0x04000000 /* operates synchronously */
  7447. +extern int32_t crypto_get_driverid(device_t dev, int flags);
  7448. +extern int crypto_find_driver(const char *);
  7449. +extern device_t crypto_find_device_byhid(int hid);
  7450. +extern int crypto_getcaps(int hid);
  7451. +extern int crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
  7452. + u_int32_t flags);
  7453. +extern int crypto_kregister(u_int32_t, int, u_int32_t);
  7454. +extern int crypto_unregister(u_int32_t driverid, int alg);
  7455. +extern int crypto_unregister_all(u_int32_t driverid);
  7456. +extern int crypto_dispatch(struct cryptop *crp);
  7457. +extern int crypto_kdispatch(struct cryptkop *);
  7458. +#define CRYPTO_SYMQ 0x1
  7459. +#define CRYPTO_ASYMQ 0x2
  7460. +extern int crypto_unblock(u_int32_t, int);
  7461. +extern void crypto_done(struct cryptop *crp);
  7462. +extern void crypto_kdone(struct cryptkop *);
  7463. +extern int crypto_getfeat(int *);
  7464. +
  7465. +extern void crypto_freereq(struct cryptop *crp);
  7466. +extern struct cryptop *crypto_getreq(int num);
  7467. +
  7468. +extern int crypto_usercrypto; /* userland may do crypto requests */
  7469. +extern int crypto_userasymcrypto; /* userland may do asym crypto reqs */
  7470. +extern int crypto_devallowsoft; /* only use hardware crypto */
  7471. +
  7472. +/*
  7473. + * random number support, crypto_unregister_all will unregister
  7474. + */
  7475. +extern int crypto_rregister(u_int32_t driverid,
  7476. + int (*read_random)(void *arg, u_int32_t *buf, int len), void *arg);
  7477. +extern int crypto_runregister_all(u_int32_t driverid);
  7478. +
  7479. +/*
  7480. + * Crypto-related utility routines used mainly by drivers.
  7481. + *
  7482. + * XXX these don't really belong here; but for now they're
  7483. + * kept apart from the rest of the system.
  7484. + */
  7485. +struct uio;
  7486. +extern void cuio_copydata(struct uio* uio, int off, int len, caddr_t cp);
  7487. +extern void cuio_copyback(struct uio* uio, int off, int len, caddr_t cp);
  7488. +extern struct iovec *cuio_getptr(struct uio *uio, int loc, int *off);
  7489. +
  7490. +extern void crypto_copyback(int flags, caddr_t buf, int off, int size,
  7491. + caddr_t in);
  7492. +extern void crypto_copydata(int flags, caddr_t buf, int off, int size,
  7493. + caddr_t out);
  7494. +extern int crypto_apply(int flags, caddr_t buf, int off, int len,
  7495. + int (*f)(void *, void *, u_int), void *arg);
  7496. +
  7497. +#endif /* __KERNEL__ */
  7498. +#endif /* _CRYPTO_CRYPTO_H_ */
  7499. diff -Nur linux-2.6.35.orig/crypto/ocf/cryptosoft.c linux-2.6.35/crypto/ocf/cryptosoft.c
  7500. --- linux-2.6.35.orig/crypto/ocf/cryptosoft.c 1970-01-01 01:00:00.000000000 +0100
  7501. +++ linux-2.6.35/crypto/ocf/cryptosoft.c 2010-08-05 22:02:07.973709724 +0200
  7502. @@ -0,0 +1,1210 @@
  7503. +/*
  7504. + * An OCF module that uses the linux kernel cryptoapi, based on the
  7505. + * original cryptosoft for BSD by Angelos D. Keromytis (angelos@cis.upenn.edu)
  7506. + * but is mostly unrecognisable,
  7507. + *
  7508. + * Written by David McCullough <david_mccullough@mcafee.com>
  7509. + * Copyright (C) 2004-2010 David McCullough
  7510. + * Copyright (C) 2004-2005 Intel Corporation.
  7511. + *
  7512. + * LICENSE TERMS
  7513. + *
  7514. + * The free distribution and use of this software in both source and binary
  7515. + * form is allowed (with or without changes) provided that:
  7516. + *
  7517. + * 1. distributions of this source code include the above copyright
  7518. + * notice, this list of conditions and the following disclaimer;
  7519. + *
  7520. + * 2. distributions in binary form include the above copyright
  7521. + * notice, this list of conditions and the following disclaimer
  7522. + * in the documentation and/or other associated materials;
  7523. + *
  7524. + * 3. the copyright holder's name is not used to endorse products
  7525. + * built using this software without specific written permission.
  7526. + *
  7527. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  7528. + * may be distributed under the terms of the GNU General Public License (GPL),
  7529. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  7530. + *
  7531. + * DISCLAIMER
  7532. + *
  7533. + * This software is provided 'as is' with no explicit or implied warranties
  7534. + * in respect of its properties, including, but not limited to, correctness
  7535. + * and/or fitness for purpose.
  7536. + * ---------------------------------------------------------------------------
  7537. + */
  7538. +
  7539. +#ifndef AUTOCONF_INCLUDED
  7540. +#include <linux/config.h>
  7541. +#endif
  7542. +#include <linux/module.h>
  7543. +#include <linux/init.h>
  7544. +#include <linux/list.h>
  7545. +#include <linux/slab.h>
  7546. +#include <linux/sched.h>
  7547. +#include <linux/wait.h>
  7548. +#include <linux/crypto.h>
  7549. +#include <linux/mm.h>
  7550. +#include <linux/skbuff.h>
  7551. +#include <linux/random.h>
  7552. +#include <linux/version.h>
  7553. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
  7554. +#include <linux/scatterlist.h>
  7555. +#endif
  7556. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
  7557. +#include <crypto/hash.h>
  7558. +#endif
  7559. +
  7560. +#include <cryptodev.h>
  7561. +#include <uio.h>
  7562. +
  7563. +struct {
  7564. + softc_device_decl sc_dev;
  7565. +} swcr_softc;
  7566. +
  7567. +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
  7568. +
  7569. +#define SW_TYPE_CIPHER 0x01
  7570. +#define SW_TYPE_HMAC 0x02
  7571. +#define SW_TYPE_HASH 0x04
  7572. +#define SW_TYPE_COMP 0x08
  7573. +#define SW_TYPE_BLKCIPHER 0x10
  7574. +#define SW_TYPE_ALG_MASK 0x1f
  7575. +
  7576. +#define SW_TYPE_ASYNC 0x8000
  7577. +
  7578. +/* We change some of the above if we have an async interface */
  7579. +
  7580. +#define SW_TYPE_ALG_AMASK (SW_TYPE_ALG_MASK | SW_TYPE_ASYNC)
  7581. +
  7582. +#define SW_TYPE_ABLKCIPHER (SW_TYPE_BLKCIPHER | SW_TYPE_ASYNC)
  7583. +#define SW_TYPE_AHASH (SW_TYPE_HASH | SW_TYPE_ASYNC)
  7584. +#define SW_TYPE_AHMAC (SW_TYPE_HMAC | SW_TYPE_ASYNC)
  7585. +
  7586. +#define SCATTERLIST_MAX 16
  7587. +
  7588. +struct swcr_data {
  7589. + int sw_type;
  7590. + int sw_alg;
  7591. + struct crypto_tfm *sw_tfm;
  7592. + union {
  7593. + struct {
  7594. + char *sw_key;
  7595. + int sw_klen;
  7596. + int sw_mlen;
  7597. + } hmac;
  7598. + void *sw_comp_buf;
  7599. + } u;
  7600. + struct swcr_data *sw_next;
  7601. +};
  7602. +
  7603. +struct swcr_req {
  7604. + struct swcr_data *sw_head;
  7605. + struct swcr_data *sw;
  7606. + struct cryptop *crp;
  7607. + struct cryptodesc *crd;
  7608. + struct scatterlist sg[SCATTERLIST_MAX];
  7609. + unsigned char iv[EALG_MAX_BLOCK_LEN];
  7610. + char result[HASH_MAX_LEN];
  7611. + void *crypto_req;
  7612. +};
  7613. +
  7614. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  7615. +static kmem_cache_t *swcr_req_cache;
  7616. +#else
  7617. +static struct kmem_cache *swcr_req_cache;
  7618. +#endif
  7619. +
  7620. +#ifndef CRYPTO_TFM_MODE_CBC
  7621. +/*
  7622. + * As of linux-2.6.21 this is no longer defined, and presumably no longer
  7623. + * needed to be passed into the crypto core code.
  7624. + */
  7625. +#define CRYPTO_TFM_MODE_CBC 0
  7626. +#define CRYPTO_TFM_MODE_ECB 0
  7627. +#endif
  7628. +
  7629. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
  7630. + /*
  7631. + * Linux 2.6.19 introduced a new Crypto API, setup macro's to convert new
  7632. + * API into old API.
  7633. + */
  7634. +
  7635. + /* Symmetric/Block Cipher */
  7636. + struct blkcipher_desc
  7637. + {
  7638. + struct crypto_tfm *tfm;
  7639. + void *info;
  7640. + };
  7641. + #define ecb(X) #X , CRYPTO_TFM_MODE_ECB
  7642. + #define cbc(X) #X , CRYPTO_TFM_MODE_CBC
  7643. + #define crypto_has_blkcipher(X, Y, Z) crypto_alg_available(X, 0)
  7644. + #define crypto_blkcipher_cast(X) X
  7645. + #define crypto_blkcipher_tfm(X) X
  7646. + #define crypto_alloc_blkcipher(X, Y, Z) crypto_alloc_tfm(X, mode)
  7647. + #define crypto_blkcipher_ivsize(X) crypto_tfm_alg_ivsize(X)
  7648. + #define crypto_blkcipher_blocksize(X) crypto_tfm_alg_blocksize(X)
  7649. + #define crypto_blkcipher_setkey(X, Y, Z) crypto_cipher_setkey(X, Y, Z)
  7650. + #define crypto_blkcipher_encrypt_iv(W, X, Y, Z) \
  7651. + crypto_cipher_encrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
  7652. + #define crypto_blkcipher_decrypt_iv(W, X, Y, Z) \
  7653. + crypto_cipher_decrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
  7654. + #define crypto_blkcipher_set_flags(x, y) /* nop */
  7655. +
  7656. + /* Hash/HMAC/Digest */
  7657. + struct hash_desc
  7658. + {
  7659. + struct crypto_tfm *tfm;
  7660. + };
  7661. + #define hmac(X) #X , 0
  7662. + #define crypto_has_hash(X, Y, Z) crypto_alg_available(X, 0)
  7663. + #define crypto_hash_cast(X) X
  7664. + #define crypto_hash_tfm(X) X
  7665. + #define crypto_alloc_hash(X, Y, Z) crypto_alloc_tfm(X, mode)
  7666. + #define crypto_hash_digestsize(X) crypto_tfm_alg_digestsize(X)
  7667. + #define crypto_hash_digest(W, X, Y, Z) \
  7668. + crypto_digest_digest((W)->tfm, X, sg_num, Z)
  7669. +
  7670. + /* Asymmetric Cipher */
  7671. + #define crypto_has_cipher(X, Y, Z) crypto_alg_available(X, 0)
  7672. +
  7673. + /* Compression */
  7674. + #define crypto_has_comp(X, Y, Z) crypto_alg_available(X, 0)
  7675. + #define crypto_comp_tfm(X) X
  7676. + #define crypto_comp_cast(X) X
  7677. + #define crypto_alloc_comp(X, Y, Z) crypto_alloc_tfm(X, mode)
  7678. + #define plain(X) #X , 0
  7679. +#else
  7680. + #define ecb(X) "ecb(" #X ")" , 0
  7681. + #define cbc(X) "cbc(" #X ")" , 0
  7682. + #define hmac(X) "hmac(" #X ")" , 0
  7683. + #define plain(X) #X , 0
  7684. +#endif /* if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
  7685. +
  7686. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
  7687. +/* no ablkcipher in older kernels */
  7688. +#define crypto_alloc_ablkcipher(a,b,c) (NULL)
  7689. +#define crypto_ablkcipher_tfm(x) ((struct crypto_tfm *)(x))
  7690. +#define crypto_ablkcipher_set_flags(a, b) /* nop */
  7691. +#define crypto_ablkcipher_setkey(x, y, z) (-EINVAL)
  7692. +#define crypto_has_ablkcipher(a,b,c) (0)
  7693. +#else
  7694. +#define HAVE_ABLKCIPHER
  7695. +#endif
  7696. +
  7697. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
  7698. +/* no ahash in older kernels */
  7699. +#define crypto_ahash_tfm(x) ((struct crypto_tfm *)(x))
  7700. +#define crypto_alloc_ahash(a,b,c) (NULL)
  7701. +#define crypto_ahash_digestsize(x) 0
  7702. +#else
  7703. +#define HAVE_AHASH
  7704. +#endif
  7705. +
  7706. +struct crypto_details {
  7707. + char *alg_name;
  7708. + int mode;
  7709. + int sw_type;
  7710. +};
  7711. +
  7712. +static struct crypto_details crypto_details[] = {
  7713. + [CRYPTO_DES_CBC] = { cbc(des), SW_TYPE_BLKCIPHER, },
  7714. + [CRYPTO_3DES_CBC] = { cbc(des3_ede), SW_TYPE_BLKCIPHER, },
  7715. + [CRYPTO_BLF_CBC] = { cbc(blowfish), SW_TYPE_BLKCIPHER, },
  7716. + [CRYPTO_CAST_CBC] = { cbc(cast5), SW_TYPE_BLKCIPHER, },
  7717. + [CRYPTO_SKIPJACK_CBC] = { cbc(skipjack), SW_TYPE_BLKCIPHER, },
  7718. + [CRYPTO_MD5_HMAC] = { hmac(md5), SW_TYPE_HMAC, },
  7719. + [CRYPTO_SHA1_HMAC] = { hmac(sha1), SW_TYPE_HMAC, },
  7720. + [CRYPTO_RIPEMD160_HMAC] = { hmac(ripemd160), SW_TYPE_HMAC, },
  7721. + [CRYPTO_MD5_KPDK] = { plain(md5-kpdk), SW_TYPE_HASH, },
  7722. + [CRYPTO_SHA1_KPDK] = { plain(sha1-kpdk), SW_TYPE_HASH, },
  7723. + [CRYPTO_AES_CBC] = { cbc(aes), SW_TYPE_BLKCIPHER, },
  7724. + [CRYPTO_ARC4] = { ecb(arc4), SW_TYPE_BLKCIPHER, },
  7725. + [CRYPTO_MD5] = { plain(md5), SW_TYPE_HASH, },
  7726. + [CRYPTO_SHA1] = { plain(sha1), SW_TYPE_HASH, },
  7727. + [CRYPTO_NULL_HMAC] = { hmac(digest_null), SW_TYPE_HMAC, },
  7728. + [CRYPTO_NULL_CBC] = { cbc(cipher_null), SW_TYPE_BLKCIPHER, },
  7729. + [CRYPTO_DEFLATE_COMP] = { plain(deflate), SW_TYPE_COMP, },
  7730. + [CRYPTO_SHA2_256_HMAC] = { hmac(sha256), SW_TYPE_HMAC, },
  7731. + [CRYPTO_SHA2_384_HMAC] = { hmac(sha384), SW_TYPE_HMAC, },
  7732. + [CRYPTO_SHA2_512_HMAC] = { hmac(sha512), SW_TYPE_HMAC, },
  7733. + [CRYPTO_CAMELLIA_CBC] = { cbc(camellia), SW_TYPE_BLKCIPHER, },
  7734. + [CRYPTO_SHA2_256] = { plain(sha256), SW_TYPE_HASH, },
  7735. + [CRYPTO_SHA2_384] = { plain(sha384), SW_TYPE_HASH, },
  7736. + [CRYPTO_SHA2_512] = { plain(sha512), SW_TYPE_HASH, },
  7737. + [CRYPTO_RIPEMD160] = { plain(ripemd160), SW_TYPE_HASH, },
  7738. +};
  7739. +
  7740. +int32_t swcr_id = -1;
  7741. +module_param(swcr_id, int, 0444);
  7742. +MODULE_PARM_DESC(swcr_id, "Read-Only OCF ID for cryptosoft driver");
  7743. +
  7744. +int swcr_fail_if_compression_grows = 1;
  7745. +module_param(swcr_fail_if_compression_grows, int, 0644);
  7746. +MODULE_PARM_DESC(swcr_fail_if_compression_grows,
  7747. + "Treat compression that results in more data as a failure");
  7748. +
  7749. +int swcr_no_ahash = 0;
  7750. +module_param(swcr_no_ahash, int, 0644);
  7751. +MODULE_PARM_DESC(swcr_no_ahash,
  7752. + "Do not use async hash/hmac even if available");
  7753. +
  7754. +int swcr_no_ablk = 0;
  7755. +module_param(swcr_no_ablk, int, 0644);
  7756. +MODULE_PARM_DESC(swcr_no_ablk,
  7757. + "Do not use async blk ciphers even if available");
  7758. +
  7759. +static struct swcr_data **swcr_sessions = NULL;
  7760. +static u_int32_t swcr_sesnum = 0;
  7761. +
  7762. +static int swcr_process(device_t, struct cryptop *, int);
  7763. +static int swcr_newsession(device_t, u_int32_t *, struct cryptoini *);
  7764. +static int swcr_freesession(device_t, u_int64_t);
  7765. +
  7766. +static device_method_t swcr_methods = {
  7767. + /* crypto device methods */
  7768. + DEVMETHOD(cryptodev_newsession, swcr_newsession),
  7769. + DEVMETHOD(cryptodev_freesession,swcr_freesession),
  7770. + DEVMETHOD(cryptodev_process, swcr_process),
  7771. +};
  7772. +
  7773. +#define debug swcr_debug
  7774. +int swcr_debug = 0;
  7775. +module_param(swcr_debug, int, 0644);
  7776. +MODULE_PARM_DESC(swcr_debug, "Enable debug");
  7777. +
  7778. +static void swcr_process_req(struct swcr_req *req);
  7779. +
  7780. +/*
  7781. + * Generate a new software session.
  7782. + */
  7783. +static int
  7784. +swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  7785. +{
  7786. + struct swcr_data **swd;
  7787. + u_int32_t i;
  7788. + int error;
  7789. + char *algo;
  7790. + int mode;
  7791. +
  7792. + dprintk("%s()\n", __FUNCTION__);
  7793. + if (sid == NULL || cri == NULL) {
  7794. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  7795. + return EINVAL;
  7796. + }
  7797. +
  7798. + if (swcr_sessions) {
  7799. + for (i = 1; i < swcr_sesnum; i++)
  7800. + if (swcr_sessions[i] == NULL)
  7801. + break;
  7802. + } else
  7803. + i = 1; /* NB: to silence compiler warning */
  7804. +
  7805. + if (swcr_sessions == NULL || i == swcr_sesnum) {
  7806. + if (swcr_sessions == NULL) {
  7807. + i = 1; /* We leave swcr_sessions[0] empty */
  7808. + swcr_sesnum = CRYPTO_SW_SESSIONS;
  7809. + } else
  7810. + swcr_sesnum *= 2;
  7811. +
  7812. + swd = kmalloc(swcr_sesnum * sizeof(struct swcr_data *), SLAB_ATOMIC);
  7813. + if (swd == NULL) {
  7814. + /* Reset session number */
  7815. + if (swcr_sesnum == CRYPTO_SW_SESSIONS)
  7816. + swcr_sesnum = 0;
  7817. + else
  7818. + swcr_sesnum /= 2;
  7819. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  7820. + return ENOBUFS;
  7821. + }
  7822. + memset(swd, 0, swcr_sesnum * sizeof(struct swcr_data *));
  7823. +
  7824. + /* Copy existing sessions */
  7825. + if (swcr_sessions) {
  7826. + memcpy(swd, swcr_sessions,
  7827. + (swcr_sesnum / 2) * sizeof(struct swcr_data *));
  7828. + kfree(swcr_sessions);
  7829. + }
  7830. +
  7831. + swcr_sessions = swd;
  7832. + }
  7833. +
  7834. + swd = &swcr_sessions[i];
  7835. + *sid = i;
  7836. +
  7837. + while (cri) {
  7838. + *swd = (struct swcr_data *) kmalloc(sizeof(struct swcr_data),
  7839. + SLAB_ATOMIC);
  7840. + if (*swd == NULL) {
  7841. + swcr_freesession(NULL, i);
  7842. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  7843. + return ENOBUFS;
  7844. + }
  7845. + memset(*swd, 0, sizeof(struct swcr_data));
  7846. +
  7847. + if (cri->cri_alg < 0 ||
  7848. + cri->cri_alg>=sizeof(crypto_details)/sizeof(crypto_details[0])){
  7849. + printk("cryptosoft: Unknown algorithm 0x%x\n", cri->cri_alg);
  7850. + swcr_freesession(NULL, i);
  7851. + return EINVAL;
  7852. + }
  7853. +
  7854. + algo = crypto_details[cri->cri_alg].alg_name;
  7855. + if (!algo || !*algo) {
  7856. + printk("cryptosoft: Unsupported algorithm 0x%x\n", cri->cri_alg);
  7857. + swcr_freesession(NULL, i);
  7858. + return EINVAL;
  7859. + }
  7860. +
  7861. + mode = crypto_details[cri->cri_alg].mode;
  7862. + (*swd)->sw_type = crypto_details[cri->cri_alg].sw_type;
  7863. + (*swd)->sw_alg = cri->cri_alg;
  7864. +
  7865. + /* Algorithm specific configuration */
  7866. + switch (cri->cri_alg) {
  7867. + case CRYPTO_NULL_CBC:
  7868. + cri->cri_klen = 0; /* make it work with crypto API */
  7869. + break;
  7870. + default:
  7871. + break;
  7872. + }
  7873. +
  7874. + if ((*swd)->sw_type & SW_TYPE_BLKCIPHER) {
  7875. + dprintk("%s crypto_alloc_*blkcipher(%s, 0x%x)\n", __FUNCTION__,
  7876. + algo, mode);
  7877. +
  7878. + /* try async first */
  7879. + (*swd)->sw_tfm = swcr_no_ablk ? NULL :
  7880. + crypto_ablkcipher_tfm(crypto_alloc_ablkcipher(algo, 0, 0));
  7881. + if ((*swd)->sw_tfm) {
  7882. + dprintk("%s %s cipher is async\n", __FUNCTION__, algo);
  7883. + (*swd)->sw_type |= SW_TYPE_ASYNC;
  7884. + } else {
  7885. + dprintk("%s %s cipher is sync\n", __FUNCTION__, algo);
  7886. + (*swd)->sw_tfm = crypto_blkcipher_tfm(
  7887. + crypto_alloc_blkcipher(algo, 0, CRYPTO_ALG_ASYNC));
  7888. + }
  7889. + if (!(*swd)->sw_tfm) {
  7890. + dprintk("cryptosoft: crypto_alloc_blkcipher failed(%s, 0x%x)\n",
  7891. + algo,mode);
  7892. + swcr_freesession(NULL, i);
  7893. + return EINVAL;
  7894. + }
  7895. +
  7896. + if (debug) {
  7897. + dprintk("%s key:cri->cri_klen=%d,(cri->cri_klen + 7)/8=%d",
  7898. + __FUNCTION__, cri->cri_klen, (cri->cri_klen + 7) / 8);
  7899. + for (i = 0; i < (cri->cri_klen + 7) / 8; i++)
  7900. + dprintk("%s0x%x", (i % 8) ? " " : "\n ",
  7901. + cri->cri_key[i] & 0xff);
  7902. + dprintk("\n");
  7903. + }
  7904. + if ((*swd)->sw_type & SW_TYPE_ASYNC) {
  7905. + /* OCF doesn't enforce keys */
  7906. + crypto_ablkcipher_set_flags(
  7907. + __crypto_ablkcipher_cast((*swd)->sw_tfm),
  7908. + CRYPTO_TFM_REQ_WEAK_KEY);
  7909. + error = crypto_ablkcipher_setkey(
  7910. + __crypto_ablkcipher_cast((*swd)->sw_tfm),
  7911. + cri->cri_key, (cri->cri_klen + 7) / 8);
  7912. + } else {
  7913. + /* OCF doesn't enforce keys */
  7914. + crypto_blkcipher_set_flags(
  7915. + crypto_blkcipher_cast((*swd)->sw_tfm),
  7916. + CRYPTO_TFM_REQ_WEAK_KEY);
  7917. + error = crypto_blkcipher_setkey(
  7918. + crypto_blkcipher_cast((*swd)->sw_tfm),
  7919. + cri->cri_key, (cri->cri_klen + 7) / 8);
  7920. + }
  7921. + if (error) {
  7922. + printk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n", error,
  7923. + (*swd)->sw_tfm->crt_flags);
  7924. + swcr_freesession(NULL, i);
  7925. + return error;
  7926. + }
  7927. + } else if ((*swd)->sw_type & (SW_TYPE_HMAC | SW_TYPE_HASH)) {
  7928. + dprintk("%s crypto_alloc_*hash(%s, 0x%x)\n", __FUNCTION__,
  7929. + algo, mode);
  7930. +
  7931. + /* try async first */
  7932. + (*swd)->sw_tfm = swcr_no_ahash ? NULL :
  7933. + crypto_ahash_tfm(crypto_alloc_ahash(algo, 0, 0));
  7934. + if ((*swd)->sw_tfm) {
  7935. + dprintk("%s %s hash is async\n", __FUNCTION__, algo);
  7936. + (*swd)->sw_type |= SW_TYPE_ASYNC;
  7937. + } else {
  7938. + dprintk("%s %s hash is sync\n", __FUNCTION__, algo);
  7939. + (*swd)->sw_tfm = crypto_hash_tfm(
  7940. + crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC));
  7941. + }
  7942. +
  7943. + if (!(*swd)->sw_tfm) {
  7944. + dprintk("cryptosoft: crypto_alloc_hash failed(%s,0x%x)\n",
  7945. + algo, mode);
  7946. + swcr_freesession(NULL, i);
  7947. + return EINVAL;
  7948. + }
  7949. +
  7950. + (*swd)->u.hmac.sw_klen = (cri->cri_klen + 7) / 8;
  7951. + (*swd)->u.hmac.sw_key = (char *)kmalloc((*swd)->u.hmac.sw_klen,
  7952. + SLAB_ATOMIC);
  7953. + if ((*swd)->u.hmac.sw_key == NULL) {
  7954. + swcr_freesession(NULL, i);
  7955. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  7956. + return ENOBUFS;
  7957. + }
  7958. + memcpy((*swd)->u.hmac.sw_key, cri->cri_key, (*swd)->u.hmac.sw_klen);
  7959. + if (cri->cri_mlen) {
  7960. + (*swd)->u.hmac.sw_mlen = cri->cri_mlen;
  7961. + } else if ((*swd)->sw_type & SW_TYPE_ASYNC) {
  7962. + (*swd)->u.hmac.sw_mlen = crypto_ahash_digestsize(
  7963. + __crypto_ahash_cast((*swd)->sw_tfm));
  7964. + } else {
  7965. + (*swd)->u.hmac.sw_mlen = crypto_hash_digestsize(
  7966. + crypto_hash_cast((*swd)->sw_tfm));
  7967. + }
  7968. + } else if ((*swd)->sw_type & SW_TYPE_COMP) {
  7969. + (*swd)->sw_tfm = crypto_comp_tfm(
  7970. + crypto_alloc_comp(algo, 0, CRYPTO_ALG_ASYNC));
  7971. + if (!(*swd)->sw_tfm) {
  7972. + dprintk("cryptosoft: crypto_alloc_comp failed(%s,0x%x)\n",
  7973. + algo, mode);
  7974. + swcr_freesession(NULL, i);
  7975. + return EINVAL;
  7976. + }
  7977. + (*swd)->u.sw_comp_buf = kmalloc(CRYPTO_MAX_DATA_LEN, SLAB_ATOMIC);
  7978. + if ((*swd)->u.sw_comp_buf == NULL) {
  7979. + swcr_freesession(NULL, i);
  7980. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  7981. + return ENOBUFS;
  7982. + }
  7983. + } else {
  7984. + printk("cryptosoft: Unhandled sw_type %d\n", (*swd)->sw_type);
  7985. + swcr_freesession(NULL, i);
  7986. + return EINVAL;
  7987. + }
  7988. +
  7989. + cri = cri->cri_next;
  7990. + swd = &((*swd)->sw_next);
  7991. + }
  7992. + return 0;
  7993. +}
  7994. +
  7995. +/*
  7996. + * Free a session.
  7997. + */
  7998. +static int
  7999. +swcr_freesession(device_t dev, u_int64_t tid)
  8000. +{
  8001. + struct swcr_data *swd;
  8002. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  8003. +
  8004. + dprintk("%s()\n", __FUNCTION__);
  8005. + if (sid > swcr_sesnum || swcr_sessions == NULL ||
  8006. + swcr_sessions[sid] == NULL) {
  8007. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  8008. + return(EINVAL);
  8009. + }
  8010. +
  8011. + /* Silently accept and return */
  8012. + if (sid == 0)
  8013. + return(0);
  8014. +
  8015. + while ((swd = swcr_sessions[sid]) != NULL) {
  8016. + swcr_sessions[sid] = swd->sw_next;
  8017. + if (swd->sw_tfm) {
  8018. + switch (swd->sw_type & SW_TYPE_ALG_AMASK) {
  8019. +#ifdef HAVE_AHASH
  8020. + case SW_TYPE_AHMAC:
  8021. + case SW_TYPE_AHASH:
  8022. + crypto_free_ahash(__crypto_ahash_cast(swd->sw_tfm));
  8023. + break;
  8024. +#endif
  8025. +#ifdef HAVE_ABLKCIPHER
  8026. + case SW_TYPE_ABLKCIPHER:
  8027. + crypto_free_ablkcipher(__crypto_ablkcipher_cast(swd->sw_tfm));
  8028. + break;
  8029. +#endif
  8030. + case SW_TYPE_BLKCIPHER:
  8031. + crypto_free_blkcipher(crypto_blkcipher_cast(swd->sw_tfm));
  8032. + break;
  8033. + case SW_TYPE_HMAC:
  8034. + case SW_TYPE_HASH:
  8035. + crypto_free_hash(crypto_hash_cast(swd->sw_tfm));
  8036. + break;
  8037. + case SW_TYPE_COMP:
  8038. + crypto_free_comp(crypto_comp_cast(swd->sw_tfm));
  8039. + default:
  8040. + crypto_free_tfm(swd->sw_tfm);
  8041. + break;
  8042. + }
  8043. + swd->sw_tfm = NULL;
  8044. + }
  8045. + if (swd->sw_type & SW_TYPE_COMP) {
  8046. + if (swd->u.sw_comp_buf)
  8047. + kfree(swd->u.sw_comp_buf);
  8048. + } else {
  8049. + if (swd->u.hmac.sw_key)
  8050. + kfree(swd->u.hmac.sw_key);
  8051. + }
  8052. + kfree(swd);
  8053. + }
  8054. + return 0;
  8055. +}
  8056. +
  8057. +#if defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH)
  8058. +/* older kernels had no async interface */
  8059. +
  8060. +static void swcr_process_callback(struct crypto_async_request *creq, int err)
  8061. +{
  8062. + struct swcr_req *req = creq->data;
  8063. +
  8064. + dprintk("%s()\n", __FUNCTION__);
  8065. + if (err) {
  8066. + if (err == -EINPROGRESS)
  8067. + return;
  8068. + dprintk("%s() fail %d\n", __FUNCTION__, -err);
  8069. + req->crp->crp_etype = -err;
  8070. + goto done;
  8071. + }
  8072. +
  8073. + switch (req->sw->sw_type & SW_TYPE_ALG_AMASK) {
  8074. + case SW_TYPE_AHMAC:
  8075. + case SW_TYPE_AHASH:
  8076. + crypto_copyback(req->crp->crp_flags, req->crp->crp_buf,
  8077. + req->crd->crd_inject, req->sw->u.hmac.sw_mlen, req->result);
  8078. + ahash_request_free(req->crypto_req);
  8079. + break;
  8080. + case SW_TYPE_ABLKCIPHER:
  8081. + ablkcipher_request_free(req->crypto_req);
  8082. + break;
  8083. + default:
  8084. + req->crp->crp_etype = EINVAL;
  8085. + goto done;
  8086. + }
  8087. +
  8088. + req->crd = req->crd->crd_next;
  8089. + if (req->crd) {
  8090. + swcr_process_req(req);
  8091. + return;
  8092. + }
  8093. +
  8094. +done:
  8095. + dprintk("%s crypto_done %p\n", __FUNCTION__, req);
  8096. + crypto_done(req->crp);
  8097. + kmem_cache_free(swcr_req_cache, req);
  8098. +}
  8099. +#endif /* defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH) */
  8100. +
  8101. +
  8102. +static void swcr_process_req(struct swcr_req *req)
  8103. +{
  8104. + struct swcr_data *sw;
  8105. + struct cryptop *crp = req->crp;
  8106. + struct cryptodesc *crd = req->crd;
  8107. + struct sk_buff *skb = (struct sk_buff *) crp->crp_buf;
  8108. + struct uio *uiop = (struct uio *) crp->crp_buf;
  8109. + int sg_num, sg_len, skip;
  8110. +
  8111. + dprintk("%s()\n", __FUNCTION__);
  8112. +
  8113. + /*
  8114. + * Find the crypto context.
  8115. + *
  8116. + * XXX Note that the logic here prevents us from having
  8117. + * XXX the same algorithm multiple times in a session
  8118. + * XXX (or rather, we can but it won't give us the right
  8119. + * XXX results). To do that, we'd need some way of differentiating
  8120. + * XXX between the various instances of an algorithm (so we can
  8121. + * XXX locate the correct crypto context).
  8122. + */
  8123. + for (sw = req->sw_head; sw && sw->sw_alg != crd->crd_alg; sw = sw->sw_next)
  8124. + ;
  8125. +
  8126. + /* No such context ? */
  8127. + if (sw == NULL) {
  8128. + crp->crp_etype = EINVAL;
  8129. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  8130. + goto done;
  8131. + }
  8132. +
  8133. + req->sw = sw;
  8134. + skip = crd->crd_skip;
  8135. +
  8136. + /*
  8137. + * setup the SG list skip from the start of the buffer
  8138. + */
  8139. + memset(req->sg, 0, sizeof(req->sg));
  8140. + sg_init_table(req->sg, SCATTERLIST_MAX);
  8141. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  8142. + int i, len;
  8143. +
  8144. + sg_num = 0;
  8145. + sg_len = 0;
  8146. +
  8147. + if (skip < skb_headlen(skb)) {
  8148. + len = skb_headlen(skb) - skip;
  8149. + if (len + sg_len > crd->crd_len)
  8150. + len = crd->crd_len - sg_len;
  8151. + sg_set_page(&req->sg[sg_num],
  8152. + virt_to_page(skb->data + skip), len,
  8153. + offset_in_page(skb->data + skip));
  8154. + sg_len += len;
  8155. + sg_num++;
  8156. + skip = 0;
  8157. + } else
  8158. + skip -= skb_headlen(skb);
  8159. +
  8160. + for (i = 0; sg_len < crd->crd_len &&
  8161. + i < skb_shinfo(skb)->nr_frags &&
  8162. + sg_num < SCATTERLIST_MAX; i++) {
  8163. + if (skip < skb_shinfo(skb)->frags[i].size) {
  8164. + len = skb_shinfo(skb)->frags[i].size - skip;
  8165. + if (len + sg_len > crd->crd_len)
  8166. + len = crd->crd_len - sg_len;
  8167. + sg_set_page(&req->sg[sg_num],
  8168. + skb_shinfo(skb)->frags[i].page,
  8169. + len,
  8170. + skb_shinfo(skb)->frags[i].page_offset + skip);
  8171. + sg_len += len;
  8172. + sg_num++;
  8173. + skip = 0;
  8174. + } else
  8175. + skip -= skb_shinfo(skb)->frags[i].size;
  8176. + }
  8177. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  8178. + int len;
  8179. +
  8180. + sg_len = 0;
  8181. + for (sg_num = 0; sg_len < crd->crd_len &&
  8182. + sg_num < uiop->uio_iovcnt &&
  8183. + sg_num < SCATTERLIST_MAX; sg_num++) {
  8184. + if (skip <= uiop->uio_iov[sg_num].iov_len) {
  8185. + len = uiop->uio_iov[sg_num].iov_len - skip;
  8186. + if (len + sg_len > crd->crd_len)
  8187. + len = crd->crd_len - sg_len;
  8188. + sg_set_page(&req->sg[sg_num],
  8189. + virt_to_page(uiop->uio_iov[sg_num].iov_base+skip),
  8190. + len,
  8191. + offset_in_page(uiop->uio_iov[sg_num].iov_base+skip));
  8192. + sg_len += len;
  8193. + skip = 0;
  8194. + } else
  8195. + skip -= uiop->uio_iov[sg_num].iov_len;
  8196. + }
  8197. + } else {
  8198. + sg_len = (crp->crp_ilen - skip);
  8199. + if (sg_len > crd->crd_len)
  8200. + sg_len = crd->crd_len;
  8201. + sg_set_page(&req->sg[0], virt_to_page(crp->crp_buf + skip),
  8202. + sg_len, offset_in_page(crp->crp_buf + skip));
  8203. + sg_num = 1;
  8204. + }
  8205. +
  8206. + switch (sw->sw_type & SW_TYPE_ALG_AMASK) {
  8207. +
  8208. +#ifdef HAVE_AHASH
  8209. + case SW_TYPE_AHMAC:
  8210. + case SW_TYPE_AHASH:
  8211. + {
  8212. + int ret;
  8213. +
  8214. + /* check we have room for the result */
  8215. + if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
  8216. + dprintk("cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d "
  8217. + "digestsize=%d\n", crp->crp_ilen, crd->crd_skip + sg_len,
  8218. + crd->crd_inject, sw->u.hmac.sw_mlen);
  8219. + crp->crp_etype = EINVAL;
  8220. + goto done;
  8221. + }
  8222. +
  8223. + req->crypto_req =
  8224. + ahash_request_alloc(__crypto_ahash_cast(sw->sw_tfm),GFP_KERNEL);
  8225. + if (!req->crypto_req) {
  8226. + crp->crp_etype = ENOMEM;
  8227. + dprintk("%s,%d: ENOMEM ahash_request_alloc", __FILE__, __LINE__);
  8228. + goto done;
  8229. + }
  8230. +
  8231. + ahash_request_set_callback(req->crypto_req,
  8232. + CRYPTO_TFM_REQ_MAY_BACKLOG, swcr_process_callback, req);
  8233. +
  8234. + memset(req->result, 0, sizeof(req->result));
  8235. +
  8236. + if (sw->sw_type & SW_TYPE_AHMAC)
  8237. + crypto_ahash_setkey(__crypto_ahash_cast(sw->sw_tfm),
  8238. + sw->u.hmac.sw_key, sw->u.hmac.sw_klen);
  8239. + ahash_request_set_crypt(req->crypto_req, req->sg, req->result, sg_len);
  8240. + ret = crypto_ahash_digest(req->crypto_req);
  8241. + switch (ret) {
  8242. + case -EINPROGRESS:
  8243. + case -EBUSY:
  8244. + return;
  8245. + default:
  8246. + case 0:
  8247. + dprintk("hash OP %s %d\n", ret ? "failed" : "success", ret);
  8248. + crp->crp_etype = ret;
  8249. + ahash_request_free(req->crypto_req);
  8250. + goto done;
  8251. + }
  8252. + } break;
  8253. +#endif /* HAVE_AHASH */
  8254. +
  8255. +#ifdef HAVE_ABLKCIPHER
  8256. + case SW_TYPE_ABLKCIPHER: {
  8257. + int ret;
  8258. + unsigned char *ivp = req->iv;
  8259. + int ivsize =
  8260. + crypto_ablkcipher_ivsize(__crypto_ablkcipher_cast(sw->sw_tfm));
  8261. +
  8262. + if (sg_len < crypto_ablkcipher_blocksize(
  8263. + __crypto_ablkcipher_cast(sw->sw_tfm))) {
  8264. + crp->crp_etype = EINVAL;
  8265. + dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
  8266. + sg_len, crypto_ablkcipher_blocksize(
  8267. + __crypto_ablkcipher_cast(sw->sw_tfm)));
  8268. + goto done;
  8269. + }
  8270. +
  8271. + if (ivsize > sizeof(req->iv)) {
  8272. + crp->crp_etype = EINVAL;
  8273. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  8274. + goto done;
  8275. + }
  8276. +
  8277. + req->crypto_req = ablkcipher_request_alloc(
  8278. + __crypto_ablkcipher_cast(sw->sw_tfm), GFP_KERNEL);
  8279. + if (!req->crypto_req) {
  8280. + crp->crp_etype = ENOMEM;
  8281. + dprintk("%s,%d: ENOMEM ablkcipher_request_alloc",
  8282. + __FILE__, __LINE__);
  8283. + goto done;
  8284. + }
  8285. +
  8286. + ablkcipher_request_set_callback(req->crypto_req,
  8287. + CRYPTO_TFM_REQ_MAY_BACKLOG, swcr_process_callback, req);
  8288. +
  8289. + if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
  8290. + int i, error;
  8291. +
  8292. + if (debug) {
  8293. + dprintk("%s key:", __FUNCTION__);
  8294. + for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
  8295. + dprintk("%s0x%x", (i % 8) ? " " : "\n ",
  8296. + crd->crd_key[i] & 0xff);
  8297. + dprintk("\n");
  8298. + }
  8299. + /* OCF doesn't enforce keys */
  8300. + crypto_ablkcipher_set_flags(__crypto_ablkcipher_cast(sw->sw_tfm),
  8301. + CRYPTO_TFM_REQ_WEAK_KEY);
  8302. + error = crypto_ablkcipher_setkey(
  8303. + __crypto_ablkcipher_cast(sw->sw_tfm), crd->crd_key,
  8304. + (crd->crd_klen + 7) / 8);
  8305. + if (error) {
  8306. + dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
  8307. + error, sw->sw_tfm->crt_flags);
  8308. + crp->crp_etype = -error;
  8309. + }
  8310. + }
  8311. +
  8312. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  8313. +
  8314. + if (crd->crd_flags & CRD_F_IV_EXPLICIT)
  8315. + ivp = crd->crd_iv;
  8316. + else
  8317. + get_random_bytes(ivp, ivsize);
  8318. + /*
  8319. + * do we have to copy the IV back to the buffer ?
  8320. + */
  8321. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  8322. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  8323. + crd->crd_inject, ivsize, (caddr_t)ivp);
  8324. + }
  8325. + ablkcipher_request_set_crypt(req->crypto_req, req->sg, req->sg,
  8326. + sg_len, ivp);
  8327. + ret = crypto_ablkcipher_encrypt(req->crypto_req);
  8328. +
  8329. + } else { /*decrypt */
  8330. +
  8331. + if (crd->crd_flags & CRD_F_IV_EXPLICIT)
  8332. + ivp = crd->crd_iv;
  8333. + else
  8334. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  8335. + crd->crd_inject, ivsize, (caddr_t)ivp);
  8336. + ablkcipher_request_set_crypt(req->crypto_req, req->sg, req->sg,
  8337. + sg_len, ivp);
  8338. + ret = crypto_ablkcipher_decrypt(req->crypto_req);
  8339. + }
  8340. +
  8341. + switch (ret) {
  8342. + case -EINPROGRESS:
  8343. + case -EBUSY:
  8344. + return;
  8345. + default:
  8346. + case 0:
  8347. + dprintk("crypto OP %s %d\n", ret ? "failed" : "success", ret);
  8348. + crp->crp_etype = ret;
  8349. + goto done;
  8350. + }
  8351. + } break;
  8352. +#endif /* HAVE_ABLKCIPHER */
  8353. +
  8354. + case SW_TYPE_BLKCIPHER: {
  8355. + unsigned char iv[EALG_MAX_BLOCK_LEN];
  8356. + unsigned char *ivp = iv;
  8357. + struct blkcipher_desc desc;
  8358. + int ivsize = crypto_blkcipher_ivsize(crypto_blkcipher_cast(sw->sw_tfm));
  8359. +
  8360. + if (sg_len < crypto_blkcipher_blocksize(
  8361. + crypto_blkcipher_cast(sw->sw_tfm))) {
  8362. + crp->crp_etype = EINVAL;
  8363. + dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
  8364. + sg_len, crypto_blkcipher_blocksize(
  8365. + crypto_blkcipher_cast(sw->sw_tfm)));
  8366. + goto done;
  8367. + }
  8368. +
  8369. + if (ivsize > sizeof(iv)) {
  8370. + crp->crp_etype = EINVAL;
  8371. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  8372. + goto done;
  8373. + }
  8374. +
  8375. + if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
  8376. + int i, error;
  8377. +
  8378. + if (debug) {
  8379. + dprintk("%s key:", __FUNCTION__);
  8380. + for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
  8381. + dprintk("%s0x%x", (i % 8) ? " " : "\n ",
  8382. + crd->crd_key[i] & 0xff);
  8383. + dprintk("\n");
  8384. + }
  8385. + /* OCF doesn't enforce keys */
  8386. + crypto_blkcipher_set_flags(crypto_blkcipher_cast(sw->sw_tfm),
  8387. + CRYPTO_TFM_REQ_WEAK_KEY);
  8388. + error = crypto_blkcipher_setkey(
  8389. + crypto_blkcipher_cast(sw->sw_tfm), crd->crd_key,
  8390. + (crd->crd_klen + 7) / 8);
  8391. + if (error) {
  8392. + dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
  8393. + error, sw->sw_tfm->crt_flags);
  8394. + crp->crp_etype = -error;
  8395. + }
  8396. + }
  8397. +
  8398. + memset(&desc, 0, sizeof(desc));
  8399. + desc.tfm = crypto_blkcipher_cast(sw->sw_tfm);
  8400. +
  8401. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  8402. +
  8403. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  8404. + ivp = crd->crd_iv;
  8405. + } else {
  8406. + get_random_bytes(ivp, ivsize);
  8407. + }
  8408. + /*
  8409. + * do we have to copy the IV back to the buffer ?
  8410. + */
  8411. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  8412. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  8413. + crd->crd_inject, ivsize, (caddr_t)ivp);
  8414. + }
  8415. + desc.info = ivp;
  8416. + crypto_blkcipher_encrypt_iv(&desc, req->sg, req->sg, sg_len);
  8417. +
  8418. + } else { /*decrypt */
  8419. +
  8420. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  8421. + ivp = crd->crd_iv;
  8422. + } else {
  8423. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  8424. + crd->crd_inject, ivsize, (caddr_t)ivp);
  8425. + }
  8426. + desc.info = ivp;
  8427. + crypto_blkcipher_decrypt_iv(&desc, req->sg, req->sg, sg_len);
  8428. + }
  8429. + } break;
  8430. +
  8431. + case SW_TYPE_HMAC:
  8432. + case SW_TYPE_HASH:
  8433. + {
  8434. + char result[HASH_MAX_LEN];
  8435. + struct hash_desc desc;
  8436. +
  8437. + /* check we have room for the result */
  8438. + if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
  8439. + dprintk("cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d "
  8440. + "digestsize=%d\n", crp->crp_ilen, crd->crd_skip + sg_len,
  8441. + crd->crd_inject, sw->u.hmac.sw_mlen);
  8442. + crp->crp_etype = EINVAL;
  8443. + goto done;
  8444. + }
  8445. +
  8446. + memset(&desc, 0, sizeof(desc));
  8447. + desc.tfm = crypto_hash_cast(sw->sw_tfm);
  8448. +
  8449. + memset(result, 0, sizeof(result));
  8450. +
  8451. + if (sw->sw_type & SW_TYPE_HMAC) {
  8452. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
  8453. + crypto_hmac(sw->sw_tfm, sw->u.hmac.sw_key, &sw->u.hmac.sw_klen,
  8454. + req->sg, sg_num, result);
  8455. +#else
  8456. + crypto_hash_setkey(desc.tfm, sw->u.hmac.sw_key,
  8457. + sw->u.hmac.sw_klen);
  8458. + crypto_hash_digest(&desc, req->sg, sg_len, result);
  8459. +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
  8460. +
  8461. + } else { /* SW_TYPE_HASH */
  8462. + crypto_hash_digest(&desc, req->sg, sg_len, result);
  8463. + }
  8464. +
  8465. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  8466. + crd->crd_inject, sw->u.hmac.sw_mlen, result);
  8467. + }
  8468. + break;
  8469. +
  8470. + case SW_TYPE_COMP: {
  8471. + void *ibuf = NULL;
  8472. + void *obuf = sw->u.sw_comp_buf;
  8473. + int ilen = sg_len, olen = CRYPTO_MAX_DATA_LEN;
  8474. + int ret = 0;
  8475. +
  8476. + /*
  8477. + * we need to use an additional copy if there is more than one
  8478. + * input chunk since the kernel comp routines do not handle
  8479. + * SG yet. Otherwise we just use the input buffer as is.
  8480. + * Rather than allocate another buffer we just split the tmp
  8481. + * buffer we already have.
  8482. + * Perhaps we should just use zlib directly ?
  8483. + */
  8484. + if (sg_num > 1) {
  8485. + int blk;
  8486. +
  8487. + ibuf = obuf;
  8488. + for (blk = 0; blk < sg_num; blk++) {
  8489. + memcpy(obuf, sg_virt(&req->sg[blk]),
  8490. + req->sg[blk].length);
  8491. + obuf += req->sg[blk].length;
  8492. + }
  8493. + olen -= sg_len;
  8494. + } else
  8495. + ibuf = sg_virt(&req->sg[0]);
  8496. +
  8497. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* compress */
  8498. + ret = crypto_comp_compress(crypto_comp_cast(sw->sw_tfm),
  8499. + ibuf, ilen, obuf, &olen);
  8500. + if (!ret && olen > crd->crd_len) {
  8501. + dprintk("cryptosoft: ERANGE compress %d into %d\n",
  8502. + crd->crd_len, olen);
  8503. + if (swcr_fail_if_compression_grows)
  8504. + ret = ERANGE;
  8505. + }
  8506. + } else { /* decompress */
  8507. + ret = crypto_comp_decompress(crypto_comp_cast(sw->sw_tfm),
  8508. + ibuf, ilen, obuf, &olen);
  8509. + if (!ret && (olen + crd->crd_inject) > crp->crp_olen) {
  8510. + dprintk("cryptosoft: ETOOSMALL decompress %d into %d, "
  8511. + "space for %d,at offset %d\n",
  8512. + crd->crd_len, olen, crp->crp_olen, crd->crd_inject);
  8513. + ret = ETOOSMALL;
  8514. + }
  8515. + }
  8516. + if (ret)
  8517. + dprintk("%s,%d: ret = %d\n", __FILE__, __LINE__, ret);
  8518. +
  8519. + /*
  8520. + * on success copy result back,
  8521. + * linux crpyto API returns -errno, we need to fix that
  8522. + */
  8523. + crp->crp_etype = ret < 0 ? -ret : ret;
  8524. + if (ret == 0) {
  8525. + /* copy back the result and return it's size */
  8526. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  8527. + crd->crd_inject, olen, obuf);
  8528. + crp->crp_olen = olen;
  8529. + }
  8530. +
  8531. +
  8532. + } break;
  8533. +
  8534. + default:
  8535. + /* Unknown/unsupported algorithm */
  8536. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  8537. + crp->crp_etype = EINVAL;
  8538. + goto done;
  8539. + }
  8540. +
  8541. +done:
  8542. + crypto_done(crp);
  8543. + kmem_cache_free(swcr_req_cache, req);
  8544. +}
  8545. +
  8546. +
  8547. +/*
  8548. + * Process a crypto request.
  8549. + */
  8550. +static int
  8551. +swcr_process(device_t dev, struct cryptop *crp, int hint)
  8552. +{
  8553. + struct swcr_req *req = NULL;
  8554. + u_int32_t lid;
  8555. +
  8556. + dprintk("%s()\n", __FUNCTION__);
  8557. + /* Sanity check */
  8558. + if (crp == NULL) {
  8559. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  8560. + return EINVAL;
  8561. + }
  8562. +
  8563. + crp->crp_etype = 0;
  8564. +
  8565. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  8566. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  8567. + crp->crp_etype = EINVAL;
  8568. + goto done;
  8569. + }
  8570. +
  8571. + lid = crp->crp_sid & 0xffffffff;
  8572. + if (lid >= swcr_sesnum || lid == 0 || swcr_sessions == NULL ||
  8573. + swcr_sessions[lid] == NULL) {
  8574. + crp->crp_etype = ENOENT;
  8575. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  8576. + goto done;
  8577. + }
  8578. +
  8579. + /*
  8580. + * do some error checking outside of the loop for SKB and IOV processing
  8581. + * this leaves us with valid skb or uiop pointers for later
  8582. + */
  8583. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  8584. + struct sk_buff *skb = (struct sk_buff *) crp->crp_buf;
  8585. + if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
  8586. + printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__,
  8587. + skb_shinfo(skb)->nr_frags);
  8588. + goto done;
  8589. + }
  8590. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  8591. + struct uio *uiop = (struct uio *) crp->crp_buf;
  8592. + if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
  8593. + printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__,
  8594. + uiop->uio_iovcnt);
  8595. + goto done;
  8596. + }
  8597. + }
  8598. +
  8599. + /*
  8600. + * setup a new request ready for queuing
  8601. + */
  8602. + req = kmem_cache_alloc(swcr_req_cache, SLAB_ATOMIC);
  8603. + if (req == NULL) {
  8604. + dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);
  8605. + crp->crp_etype = ENOMEM;
  8606. + goto done;
  8607. + }
  8608. + memset(req, 0, sizeof(*req));
  8609. +
  8610. + req->sw_head = swcr_sessions[lid];
  8611. + req->crp = crp;
  8612. + req->crd = crp->crp_desc;
  8613. +
  8614. + swcr_process_req(req);
  8615. + return 0;
  8616. +
  8617. +done:
  8618. + crypto_done(crp);
  8619. + if (req)
  8620. + kmem_cache_free(swcr_req_cache, req);
  8621. + return 0;
  8622. +}
  8623. +
  8624. +
  8625. +static int
  8626. +cryptosoft_init(void)
  8627. +{
  8628. + int i, sw_type, mode;
  8629. + char *algo;
  8630. +
  8631. + dprintk("%s(%p)\n", __FUNCTION__, cryptosoft_init);
  8632. +
  8633. + swcr_req_cache = kmem_cache_create("cryptosoft_req",
  8634. + sizeof(struct swcr_req), 0, SLAB_HWCACHE_ALIGN, NULL
  8635. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  8636. + , NULL
  8637. +#endif
  8638. + );
  8639. + if (!swcr_req_cache) {
  8640. + printk("cryptosoft: failed to create request cache\n");
  8641. + return -ENOENT;
  8642. + }
  8643. +
  8644. + softc_device_init(&swcr_softc, "cryptosoft", 0, swcr_methods);
  8645. +
  8646. + swcr_id = crypto_get_driverid(softc_get_device(&swcr_softc),
  8647. + CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
  8648. + if (swcr_id < 0) {
  8649. + printk("cryptosoft: Software crypto device cannot initialize!");
  8650. + return -ENODEV;
  8651. + }
  8652. +
  8653. +#define REGISTER(alg) \
  8654. + crypto_register(swcr_id, alg, 0,0)
  8655. +
  8656. + for (i = 0; i < sizeof(crypto_details)/sizeof(crypto_details[0]); i++) {
  8657. + int found;
  8658. +
  8659. + algo = crypto_details[i].alg_name;
  8660. + if (!algo || !*algo) {
  8661. + dprintk("%s:Algorithm %d not supported\n", __FUNCTION__, i);
  8662. + continue;
  8663. + }
  8664. +
  8665. + mode = crypto_details[i].mode;
  8666. + sw_type = crypto_details[i].sw_type;
  8667. +
  8668. + found = 0;
  8669. + switch (sw_type & SW_TYPE_ALG_MASK) {
  8670. + case SW_TYPE_CIPHER:
  8671. + found = crypto_has_cipher(algo, 0, CRYPTO_ALG_ASYNC);
  8672. + break;
  8673. + case SW_TYPE_HMAC:
  8674. + found = crypto_has_hash(algo, 0, swcr_no_ahash?CRYPTO_ALG_ASYNC:0);
  8675. + break;
  8676. + case SW_TYPE_HASH:
  8677. + found = crypto_has_hash(algo, 0, swcr_no_ahash?CRYPTO_ALG_ASYNC:0);
  8678. + break;
  8679. + case SW_TYPE_COMP:
  8680. + found = crypto_has_comp(algo, 0, CRYPTO_ALG_ASYNC);
  8681. + break;
  8682. + case SW_TYPE_BLKCIPHER:
  8683. + found = crypto_has_blkcipher(algo, 0, CRYPTO_ALG_ASYNC);
  8684. + if (!found && !swcr_no_ablk)
  8685. + found = crypto_has_ablkcipher(algo, 0, 0);
  8686. + break;
  8687. + }
  8688. + if (found) {
  8689. + REGISTER(i);
  8690. + } else {
  8691. + dprintk("%s:Algorithm Type %d not supported (algorithm %d:'%s')\n",
  8692. + __FUNCTION__, sw_type, i, algo);
  8693. + }
  8694. + }
  8695. + return 0;
  8696. +}
  8697. +
  8698. +static void
  8699. +cryptosoft_exit(void)
  8700. +{
  8701. + dprintk("%s()\n", __FUNCTION__);
  8702. + crypto_unregister_all(swcr_id);
  8703. + swcr_id = -1;
  8704. + kmem_cache_destroy(swcr_req_cache);
  8705. +}
  8706. +
  8707. +late_initcall(cryptosoft_init);
  8708. +module_exit(cryptosoft_exit);
  8709. +
  8710. +MODULE_LICENSE("Dual BSD/GPL");
  8711. +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
  8712. +MODULE_DESCRIPTION("Cryptosoft (OCF module for kernel crypto)");
  8713. diff -Nur linux-2.6.35.orig/crypto/ocf/ep80579/icp_asym.c linux-2.6.35/crypto/ocf/ep80579/icp_asym.c
  8714. --- linux-2.6.35.orig/crypto/ocf/ep80579/icp_asym.c 1970-01-01 01:00:00.000000000 +0100
  8715. +++ linux-2.6.35/crypto/ocf/ep80579/icp_asym.c 2010-08-05 22:02:08.223699500 +0200
  8716. @@ -0,0 +1,1334 @@
  8717. +/***************************************************************************
  8718. + *
  8719. + * This file is provided under a dual BSD/GPLv2 license. When using or
  8720. + * redistributing this file, you may do so under either license.
  8721. + *
  8722. + * GPL LICENSE SUMMARY
  8723. + *
  8724. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  8725. + *
  8726. + * This program is free software; you can redistribute it and/or modify
  8727. + * it under the terms of version 2 of the GNU General Public License as
  8728. + * published by the Free Software Foundation.
  8729. + *
  8730. + * This program is distributed in the hope that it will be useful, but
  8731. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  8732. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  8733. + * General Public License for more details.
  8734. + *
  8735. + * You should have received a copy of the GNU General Public License
  8736. + * along with this program; if not, write to the Free Software
  8737. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  8738. + * The full GNU General Public License is included in this distribution
  8739. + * in the file called LICENSE.GPL.
  8740. + *
  8741. + * Contact Information:
  8742. + * Intel Corporation
  8743. + *
  8744. + * BSD LICENSE
  8745. + *
  8746. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  8747. + * All rights reserved.
  8748. + *
  8749. + * Redistribution and use in source and binary forms, with or without
  8750. + * modification, are permitted provided that the following conditions
  8751. + * are met:
  8752. + *
  8753. + * * Redistributions of source code must retain the above copyright
  8754. + * notice, this list of conditions and the following disclaimer.
  8755. + * * Redistributions in binary form must reproduce the above copyright
  8756. + * notice, this list of conditions and the following disclaimer in
  8757. + * the documentation and/or other materials provided with the
  8758. + * distribution.
  8759. + * * Neither the name of Intel Corporation nor the names of its
  8760. + * contributors may be used to endorse or promote products derived
  8761. + * from this software without specific prior written permission.
  8762. + *
  8763. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  8764. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  8765. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  8766. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  8767. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  8768. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  8769. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  8770. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  8771. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  8772. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  8773. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  8774. + *
  8775. + *
  8776. + * version: Security.L.1.0.2-229
  8777. + *
  8778. + ***************************************************************************/
  8779. +
  8780. +#include "icp_ocf.h"
  8781. +
  8782. +/*The following define values (containing the word 'INDEX') are used to find
  8783. +the index of each input buffer of the crypto_kop struct (see OCF cryptodev.h).
  8784. +These values were found through analysis of the OCF OpenSSL patch. If the
  8785. +calling program uses different input buffer positions, these defines will have
  8786. +to be changed.*/
  8787. +
  8788. +/*DIFFIE HELLMAN buffer index values*/
  8789. +#define ICP_DH_KRP_PARAM_PRIME_INDEX (0)
  8790. +#define ICP_DH_KRP_PARAM_BASE_INDEX (1)
  8791. +#define ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX (2)
  8792. +#define ICP_DH_KRP_PARAM_RESULT_INDEX (3)
  8793. +
  8794. +/*MOD EXP buffer index values*/
  8795. +#define ICP_MOD_EXP_KRP_PARAM_BASE_INDEX (0)
  8796. +#define ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX (1)
  8797. +#define ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX (2)
  8798. +#define ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX (3)
  8799. +
  8800. +/*MOD EXP CRT buffer index values*/
  8801. +#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX (0)
  8802. +#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX (1)
  8803. +#define ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX (2)
  8804. +#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX (3)
  8805. +#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX (4)
  8806. +#define ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX (5)
  8807. +#define ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX (6)
  8808. +
  8809. +/*DSA sign buffer index values*/
  8810. +#define ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX (0)
  8811. +#define ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX (1)
  8812. +#define ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX (2)
  8813. +#define ICP_DSA_SIGN_KRP_PARAM_G_INDEX (3)
  8814. +#define ICP_DSA_SIGN_KRP_PARAM_X_INDEX (4)
  8815. +#define ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX (5)
  8816. +#define ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX (6)
  8817. +
  8818. +/*DSA verify buffer index values*/
  8819. +#define ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX (0)
  8820. +#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX (1)
  8821. +#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX (2)
  8822. +#define ICP_DSA_VERIFY_KRP_PARAM_G_INDEX (3)
  8823. +#define ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX (4)
  8824. +#define ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX (5)
  8825. +#define ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX (6)
  8826. +
  8827. +/*DSA sign prime Q vs random number K size check values*/
  8828. +#define DONT_RUN_LESS_THAN_CHECK (0)
  8829. +#define FAIL_A_IS_GREATER_THAN_B (1)
  8830. +#define FAIL_A_IS_EQUAL_TO_B (1)
  8831. +#define SUCCESS_A_IS_LESS_THAN_B (0)
  8832. +#define DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS (500)
  8833. +
  8834. +/* We need to set a cryptokp success value just in case it is set or allocated
  8835. + and not set to zero outside of this module */
  8836. +#define CRYPTO_OP_SUCCESS (0)
  8837. +
  8838. +/*Function to compute Diffie Hellman (DH) phase 1 or phase 2 key values*/
  8839. +static int icp_ocfDrvDHComputeKey(struct cryptkop *krp);
  8840. +
  8841. +/*Function to compute a Modular Exponentiation (Mod Exp)*/
  8842. +static int icp_ocfDrvModExp(struct cryptkop *krp);
  8843. +
  8844. +/*Function to compute a Mod Exp using the Chinease Remainder Theorem*/
  8845. +static int icp_ocfDrvModExpCRT(struct cryptkop *krp);
  8846. +
  8847. +/*Helper function to compute whether the first big number argument is less than
  8848. + the second big number argument */
  8849. +static int
  8850. +icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck);
  8851. +
  8852. +/*Function to sign an input with DSA R and S keys*/
  8853. +static int icp_ocfDrvDsaSign(struct cryptkop *krp);
  8854. +
  8855. +/*Function to Verify a DSA buffer signature*/
  8856. +static int icp_ocfDrvDsaVerify(struct cryptkop *krp);
  8857. +
  8858. +/*Callback function for DH operation*/
  8859. +static void
  8860. +icp_ocfDrvDhP1CallBack(void *callbackTag,
  8861. + CpaStatus status,
  8862. + void *pOpData, CpaFlatBuffer * pLocalOctetStringPV);
  8863. +
  8864. +/*Callback function for ME operation*/
  8865. +static void
  8866. +icp_ocfDrvModExpCallBack(void *callbackTag,
  8867. + CpaStatus status,
  8868. + void *pOpData, CpaFlatBuffer * pResult);
  8869. +
  8870. +/*Callback function for ME CRT operation*/
  8871. +static void
  8872. +icp_ocfDrvModExpCRTCallBack(void *callbackTag,
  8873. + CpaStatus status,
  8874. + void *pOpData, CpaFlatBuffer * pOutputData);
  8875. +
  8876. +/*Callback function for DSA sign operation*/
  8877. +static void
  8878. +icp_ocfDrvDsaRSSignCallBack(void *callbackTag,
  8879. + CpaStatus status,
  8880. + void *pOpData,
  8881. + CpaBoolean protocolStatus,
  8882. + CpaFlatBuffer * pR, CpaFlatBuffer * pS);
  8883. +
  8884. +/*Callback function for DSA Verify operation*/
  8885. +static void
  8886. +icp_ocfDrvDsaVerifyCallBack(void *callbackTag,
  8887. + CpaStatus status,
  8888. + void *pOpData, CpaBoolean verifyStatus);
  8889. +
  8890. +/* Name : icp_ocfDrvPkeProcess
  8891. + *
  8892. + * Description : This function will choose which PKE process to follow
  8893. + * based on the input arguments
  8894. + */
  8895. +int icp_ocfDrvPkeProcess(icp_device_t dev, struct cryptkop *krp, int hint)
  8896. +{
  8897. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  8898. +
  8899. + if (NULL == krp) {
  8900. + DPRINTK("%s(): Invalid input parameters, cryptkop = %p\n",
  8901. + __FUNCTION__, krp);
  8902. + return EINVAL;
  8903. + }
  8904. +
  8905. + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  8906. + krp->krp_status = ECANCELED;
  8907. + return ECANCELED;
  8908. + }
  8909. +
  8910. + switch (krp->krp_op) {
  8911. + case CRK_DH_COMPUTE_KEY:
  8912. + DPRINTK("%s() doing DH_COMPUTE_KEY\n", __FUNCTION__);
  8913. + lacStatus = icp_ocfDrvDHComputeKey(krp);
  8914. + if (CPA_STATUS_SUCCESS != lacStatus) {
  8915. + EPRINTK("%s(): icp_ocfDrvDHComputeKey failed "
  8916. + "(%d).\n", __FUNCTION__, lacStatus);
  8917. + krp->krp_status = ECANCELED;
  8918. + return ECANCELED;
  8919. + }
  8920. +
  8921. + break;
  8922. +
  8923. + case CRK_MOD_EXP:
  8924. + DPRINTK("%s() doing MOD_EXP \n", __FUNCTION__);
  8925. + lacStatus = icp_ocfDrvModExp(krp);
  8926. + if (CPA_STATUS_SUCCESS != lacStatus) {
  8927. + EPRINTK("%s(): icp_ocfDrvModExp failed (%d).\n",
  8928. + __FUNCTION__, lacStatus);
  8929. + krp->krp_status = ECANCELED;
  8930. + return ECANCELED;
  8931. + }
  8932. +
  8933. + break;
  8934. +
  8935. + case CRK_MOD_EXP_CRT:
  8936. + DPRINTK("%s() doing MOD_EXP_CRT \n", __FUNCTION__);
  8937. + lacStatus = icp_ocfDrvModExpCRT(krp);
  8938. + if (CPA_STATUS_SUCCESS != lacStatus) {
  8939. + EPRINTK("%s(): icp_ocfDrvModExpCRT "
  8940. + "failed (%d).\n", __FUNCTION__, lacStatus);
  8941. + krp->krp_status = ECANCELED;
  8942. + return ECANCELED;
  8943. + }
  8944. +
  8945. + break;
  8946. +
  8947. + case CRK_DSA_SIGN:
  8948. + DPRINTK("%s() doing DSA_SIGN \n", __FUNCTION__);
  8949. + lacStatus = icp_ocfDrvDsaSign(krp);
  8950. + if (CPA_STATUS_SUCCESS != lacStatus) {
  8951. + EPRINTK("%s(): icp_ocfDrvDsaSign "
  8952. + "failed (%d).\n", __FUNCTION__, lacStatus);
  8953. + krp->krp_status = ECANCELED;
  8954. + return ECANCELED;
  8955. + }
  8956. +
  8957. + break;
  8958. +
  8959. + case CRK_DSA_VERIFY:
  8960. + DPRINTK("%s() doing DSA_VERIFY \n", __FUNCTION__);
  8961. + lacStatus = icp_ocfDrvDsaVerify(krp);
  8962. + if (CPA_STATUS_SUCCESS != lacStatus) {
  8963. + EPRINTK("%s(): icp_ocfDrvDsaVerify "
  8964. + "failed (%d).\n", __FUNCTION__, lacStatus);
  8965. + krp->krp_status = ECANCELED;
  8966. + return ECANCELED;
  8967. + }
  8968. +
  8969. + break;
  8970. +
  8971. + default:
  8972. + EPRINTK("%s(): Asymettric function not "
  8973. + "supported (%d).\n", __FUNCTION__, krp->krp_op);
  8974. + krp->krp_status = EOPNOTSUPP;
  8975. + return EOPNOTSUPP;
  8976. + }
  8977. +
  8978. + return ICP_OCF_DRV_STATUS_SUCCESS;
  8979. +}
  8980. +
  8981. +/* Name : icp_ocfDrvSwapBytes
  8982. + *
  8983. + * Description : This function is used to swap the byte order of a buffer.
  8984. + * It has been seen that in general we are passed little endian byte order
  8985. + * buffers, but LAC only accepts big endian byte order buffers.
  8986. + */
  8987. +static void inline icp_ocfDrvSwapBytes(u_int8_t * num, u_int32_t buff_len_bytes)
  8988. +{
  8989. +
  8990. + int i;
  8991. + u_int8_t *end_ptr;
  8992. + u_int8_t hold_val;
  8993. +
  8994. + end_ptr = num + (buff_len_bytes - 1);
  8995. + buff_len_bytes = buff_len_bytes >> 1;
  8996. + for (i = 0; i < buff_len_bytes; i++) {
  8997. + hold_val = *num;
  8998. + *num = *end_ptr;
  8999. + num++;
  9000. + *end_ptr = hold_val;
  9001. + end_ptr--;
  9002. + }
  9003. +}
  9004. +
  9005. +/* Name : icp_ocfDrvDHComputeKey
  9006. + *
  9007. + * Description : This function will map Diffie Hellman calls from OCF
  9008. + * to the LAC API. OCF uses this function for Diffie Hellman Phase1 and
  9009. + * Phase2. LAC has a separate Diffie Hellman Phase2 call, however both phases
  9010. + * break down to a modular exponentiation.
  9011. + */
  9012. +static int icp_ocfDrvDHComputeKey(struct cryptkop *krp)
  9013. +{
  9014. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  9015. + void *callbackTag = NULL;
  9016. + CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;
  9017. + CpaFlatBuffer *pLocalOctetStringPV = NULL;
  9018. + uint32_t dh_prime_len_bytes = 0, dh_prime_len_bits = 0;
  9019. +
  9020. + /* Input checks - check prime is a multiple of 8 bits to allow for
  9021. + allocation later */
  9022. + dh_prime_len_bits =
  9023. + (krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_nbits);
  9024. +
  9025. + /* LAC can reject prime lengths based on prime key sizes, we just
  9026. + need to make sure we can allocate space for the base and
  9027. + exponent buffers correctly */
  9028. + if ((dh_prime_len_bits % NUM_BITS_IN_BYTE) != 0) {
  9029. + APRINTK("%s(): Warning Prime number buffer size is not a "
  9030. + "multiple of 8 bits\n", __FUNCTION__);
  9031. + }
  9032. +
  9033. + /* Result storage space should be the same size as the prime as this
  9034. + value can take up the same amount of storage space */
  9035. + if (dh_prime_len_bits !=
  9036. + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits) {
  9037. + DPRINTK("%s(): Return Buffer must be the same size "
  9038. + "as the Prime buffer\n", __FUNCTION__);
  9039. + krp->krp_status = EINVAL;
  9040. + return EINVAL;
  9041. + }
  9042. + /* Switch to size in bytes */
  9043. + BITS_TO_BYTES(dh_prime_len_bytes, dh_prime_len_bits);
  9044. +
  9045. + callbackTag = krp;
  9046. +
  9047. +/*All allocations are set to ICP_M_NOWAIT due to the possibility of getting
  9048. +called in interrupt context*/
  9049. + pPhase1OpData = icp_kmem_cache_zalloc(drvDH_zone, ICP_M_NOWAIT);
  9050. + if (NULL == pPhase1OpData) {
  9051. + APRINTK("%s():Failed to get memory for key gen data\n",
  9052. + __FUNCTION__);
  9053. + krp->krp_status = ENOMEM;
  9054. + return ENOMEM;
  9055. + }
  9056. +
  9057. + pLocalOctetStringPV =
  9058. + icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  9059. + if (NULL == pLocalOctetStringPV) {
  9060. + APRINTK("%s():Failed to get memory for pLocalOctetStringPV\n",
  9061. + __FUNCTION__);
  9062. + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
  9063. + krp->krp_status = ENOMEM;
  9064. + return ENOMEM;
  9065. + }
  9066. +
  9067. + /* Link parameters */
  9068. + pPhase1OpData->primeP.pData =
  9069. + krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_p;
  9070. +
  9071. + pPhase1OpData->primeP.dataLenInBytes = dh_prime_len_bytes;
  9072. +
  9073. + icp_ocfDrvSwapBytes(pPhase1OpData->primeP.pData, dh_prime_len_bytes);
  9074. +
  9075. + pPhase1OpData->baseG.pData =
  9076. + krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_p;
  9077. +
  9078. + BITS_TO_BYTES(pPhase1OpData->baseG.dataLenInBytes,
  9079. + krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_nbits);
  9080. +
  9081. + icp_ocfDrvSwapBytes(pPhase1OpData->baseG.pData,
  9082. + pPhase1OpData->baseG.dataLenInBytes);
  9083. +
  9084. + pPhase1OpData->privateValueX.pData =
  9085. + krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].crp_p;
  9086. +
  9087. + BITS_TO_BYTES(pPhase1OpData->privateValueX.dataLenInBytes,
  9088. + krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].
  9089. + crp_nbits);
  9090. +
  9091. + icp_ocfDrvSwapBytes(pPhase1OpData->privateValueX.pData,
  9092. + pPhase1OpData->privateValueX.dataLenInBytes);
  9093. +
  9094. + /* Output parameters */
  9095. + pLocalOctetStringPV->pData =
  9096. + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_p;
  9097. +
  9098. + BITS_TO_BYTES(pLocalOctetStringPV->dataLenInBytes,
  9099. + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits);
  9100. +
  9101. + lacStatus = cpaCyDhKeyGenPhase1(CPA_INSTANCE_HANDLE_SINGLE,
  9102. + icp_ocfDrvDhP1CallBack,
  9103. + callbackTag, pPhase1OpData,
  9104. + pLocalOctetStringPV);
  9105. +
  9106. + if (CPA_STATUS_SUCCESS != lacStatus) {
  9107. + EPRINTK("%s(): DH Phase 1 Key Gen failed (%d).\n",
  9108. + __FUNCTION__, lacStatus);
  9109. + icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);
  9110. + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
  9111. + }
  9112. +
  9113. + return lacStatus;
  9114. +}
  9115. +
  9116. +/* Name : icp_ocfDrvModExp
  9117. + *
  9118. + * Description : This function will map ordinary Modular Exponentiation calls
  9119. + * from OCF to the LAC API.
  9120. + *
  9121. + */
  9122. +static int icp_ocfDrvModExp(struct cryptkop *krp)
  9123. +{
  9124. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  9125. + void *callbackTag = NULL;
  9126. + CpaCyLnModExpOpData *pModExpOpData = NULL;
  9127. + CpaFlatBuffer *pResult = NULL;
  9128. +
  9129. + if ((krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits %
  9130. + NUM_BITS_IN_BYTE) != 0) {
  9131. + DPRINTK("%s(): Warning - modulus buffer size (%d) is not a "
  9132. + "multiple of 8 bits\n", __FUNCTION__,
  9133. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].
  9134. + crp_nbits);
  9135. + }
  9136. +
  9137. + /* Result storage space should be the same size as the prime as this
  9138. + value can take up the same amount of storage space */
  9139. + if (krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits >
  9140. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_nbits) {
  9141. + APRINTK("%s(): Return Buffer size must be the same or"
  9142. + " greater than the Modulus buffer\n", __FUNCTION__);
  9143. + krp->krp_status = EINVAL;
  9144. + return EINVAL;
  9145. + }
  9146. +
  9147. + callbackTag = krp;
  9148. +
  9149. + pModExpOpData = icp_kmem_cache_zalloc(drvLnModExp_zone, ICP_M_NOWAIT);
  9150. + if (NULL == pModExpOpData) {
  9151. + APRINTK("%s():Failed to get memory for key gen data\n",
  9152. + __FUNCTION__);
  9153. + krp->krp_status = ENOMEM;
  9154. + return ENOMEM;
  9155. + }
  9156. +
  9157. + pResult = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  9158. + if (NULL == pResult) {
  9159. + APRINTK("%s():Failed to get memory for ModExp result\n",
  9160. + __FUNCTION__);
  9161. + ICP_CACHE_FREE(drvLnModExp_zone, pModExpOpData);
  9162. + krp->krp_status = ENOMEM;
  9163. + return ENOMEM;
  9164. + }
  9165. +
  9166. + /* Link parameters */
  9167. + pModExpOpData->modulus.pData =
  9168. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_p;
  9169. + BITS_TO_BYTES(pModExpOpData->modulus.dataLenInBytes,
  9170. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].
  9171. + crp_nbits);
  9172. +
  9173. + icp_ocfDrvSwapBytes(pModExpOpData->modulus.pData,
  9174. + pModExpOpData->modulus.dataLenInBytes);
  9175. +
  9176. + DPRINTK("%s : base (%d)\n", __FUNCTION__, krp->
  9177. + krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_nbits);
  9178. + pModExpOpData->base.pData =
  9179. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_p;
  9180. + BITS_TO_BYTES(pModExpOpData->base.dataLenInBytes,
  9181. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
  9182. + crp_nbits);
  9183. + icp_ocfDrvSwapBytes(pModExpOpData->base.pData,
  9184. + pModExpOpData->base.dataLenInBytes);
  9185. +
  9186. + pModExpOpData->exponent.pData =
  9187. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].crp_p;
  9188. + BITS_TO_BYTES(pModExpOpData->exponent.dataLenInBytes,
  9189. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].
  9190. + crp_nbits);
  9191. +
  9192. + icp_ocfDrvSwapBytes(pModExpOpData->exponent.pData,
  9193. + pModExpOpData->exponent.dataLenInBytes);
  9194. + /* Output parameters */
  9195. + pResult->pData =
  9196. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_p,
  9197. + BITS_TO_BYTES(pResult->dataLenInBytes,
  9198. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].
  9199. + crp_nbits);
  9200. +
  9201. + lacStatus = cpaCyLnModExp(CPA_INSTANCE_HANDLE_SINGLE,
  9202. + icp_ocfDrvModExpCallBack,
  9203. + callbackTag, pModExpOpData, pResult);
  9204. +
  9205. + if (CPA_STATUS_SUCCESS != lacStatus) {
  9206. + EPRINTK("%s(): Mod Exp Operation failed (%d).\n",
  9207. + __FUNCTION__, lacStatus);
  9208. + krp->krp_status = ECANCELED;
  9209. + icp_ocfDrvFreeFlatBuffer(pResult);
  9210. + ICP_CACHE_FREE(drvLnModExp_zone, pModExpOpData);
  9211. + }
  9212. +
  9213. + return lacStatus;
  9214. +}
  9215. +
  9216. +/* Name : icp_ocfDrvModExpCRT
  9217. + *
  9218. + * Description : This function will map ordinary Modular Exponentiation Chinese
  9219. + * Remainder Theorem implementaion calls from OCF to the LAC API.
  9220. + *
  9221. + * Note : Mod Exp CRT for this driver is accelerated through LAC RSA type 2
  9222. + * decrypt operation. Therefore P and Q input values must always be prime
  9223. + * numbers. Although basic primality checks are done in LAC, it is up to the
  9224. + * user to do any correct prime number checking before passing the inputs.
  9225. + */
  9226. +static int icp_ocfDrvModExpCRT(struct cryptkop *krp)
  9227. +{
  9228. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  9229. + CpaCyRsaDecryptOpData *rsaDecryptOpData = NULL;
  9230. + void *callbackTag = NULL;
  9231. + CpaFlatBuffer *pOutputData = NULL;
  9232. +
  9233. + /*Parameter input checks are all done by LAC, no need to repeat
  9234. + them here. */
  9235. + callbackTag = krp;
  9236. +
  9237. + rsaDecryptOpData =
  9238. + icp_kmem_cache_zalloc(drvRSADecrypt_zone, ICP_M_NOWAIT);
  9239. + if (NULL == rsaDecryptOpData) {
  9240. + APRINTK("%s():Failed to get memory"
  9241. + " for MOD EXP CRT Op data struct\n", __FUNCTION__);
  9242. + krp->krp_status = ENOMEM;
  9243. + return ENOMEM;
  9244. + }
  9245. +
  9246. + rsaDecryptOpData->pRecipientPrivateKey
  9247. + = icp_kmem_cache_zalloc(drvRSAPrivateKey_zone, ICP_M_NOWAIT);
  9248. + if (NULL == rsaDecryptOpData->pRecipientPrivateKey) {
  9249. + APRINTK("%s():Failed to get memory for MOD EXP CRT"
  9250. + " private key values struct\n", __FUNCTION__);
  9251. + ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);
  9252. + krp->krp_status = ENOMEM;
  9253. + return ENOMEM;
  9254. + }
  9255. +
  9256. + rsaDecryptOpData->pRecipientPrivateKey->
  9257. + version = CPA_CY_RSA_VERSION_TWO_PRIME;
  9258. + rsaDecryptOpData->pRecipientPrivateKey->
  9259. + privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
  9260. +
  9261. + pOutputData = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  9262. + if (NULL == pOutputData) {
  9263. + APRINTK("%s():Failed to get memory"
  9264. + " for MOD EXP CRT output data\n", __FUNCTION__);
  9265. + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
  9266. + rsaDecryptOpData->pRecipientPrivateKey);
  9267. + ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);
  9268. + krp->krp_status = ENOMEM;
  9269. + return ENOMEM;
  9270. + }
  9271. +
  9272. + rsaDecryptOpData->pRecipientPrivateKey->
  9273. + version = CPA_CY_RSA_VERSION_TWO_PRIME;
  9274. + rsaDecryptOpData->pRecipientPrivateKey->
  9275. + privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
  9276. +
  9277. + /* Link parameters */
  9278. + rsaDecryptOpData->inputData.pData =
  9279. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].crp_p;
  9280. + BITS_TO_BYTES(rsaDecryptOpData->inputData.dataLenInBytes,
  9281. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].
  9282. + crp_nbits);
  9283. +
  9284. + icp_ocfDrvSwapBytes(rsaDecryptOpData->inputData.pData,
  9285. + rsaDecryptOpData->inputData.dataLenInBytes);
  9286. +
  9287. + rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime1P.pData =
  9288. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].crp_p;
  9289. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
  9290. + prime1P.dataLenInBytes,
  9291. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].
  9292. + crp_nbits);
  9293. +
  9294. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  9295. + privateKeyRep2.prime1P.pData,
  9296. + rsaDecryptOpData->pRecipientPrivateKey->
  9297. + privateKeyRep2.prime1P.dataLenInBytes);
  9298. +
  9299. + rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime2Q.pData =
  9300. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].crp_p;
  9301. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
  9302. + prime2Q.dataLenInBytes,
  9303. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].
  9304. + crp_nbits);
  9305. +
  9306. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  9307. + privateKeyRep2.prime2Q.pData,
  9308. + rsaDecryptOpData->pRecipientPrivateKey->
  9309. + privateKeyRep2.prime2Q.dataLenInBytes);
  9310. +
  9311. + rsaDecryptOpData->pRecipientPrivateKey->
  9312. + privateKeyRep2.exponent1Dp.pData =
  9313. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].crp_p;
  9314. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
  9315. + exponent1Dp.dataLenInBytes,
  9316. + krp->
  9317. + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].
  9318. + crp_nbits);
  9319. +
  9320. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  9321. + privateKeyRep2.exponent1Dp.pData,
  9322. + rsaDecryptOpData->pRecipientPrivateKey->
  9323. + privateKeyRep2.exponent1Dp.dataLenInBytes);
  9324. +
  9325. + rsaDecryptOpData->pRecipientPrivateKey->
  9326. + privateKeyRep2.exponent2Dq.pData =
  9327. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].crp_p;
  9328. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->
  9329. + privateKeyRep2.exponent2Dq.dataLenInBytes,
  9330. + krp->
  9331. + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].
  9332. + crp_nbits);
  9333. +
  9334. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  9335. + privateKeyRep2.exponent2Dq.pData,
  9336. + rsaDecryptOpData->pRecipientPrivateKey->
  9337. + privateKeyRep2.exponent2Dq.dataLenInBytes);
  9338. +
  9339. + rsaDecryptOpData->pRecipientPrivateKey->
  9340. + privateKeyRep2.coefficientQInv.pData =
  9341. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].crp_p;
  9342. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->
  9343. + privateKeyRep2.coefficientQInv.dataLenInBytes,
  9344. + krp->
  9345. + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].
  9346. + crp_nbits);
  9347. +
  9348. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  9349. + privateKeyRep2.coefficientQInv.pData,
  9350. + rsaDecryptOpData->pRecipientPrivateKey->
  9351. + privateKeyRep2.coefficientQInv.dataLenInBytes);
  9352. +
  9353. + /* Output Parameter */
  9354. + pOutputData->pData =
  9355. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].crp_p;
  9356. + BITS_TO_BYTES(pOutputData->dataLenInBytes,
  9357. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].
  9358. + crp_nbits);
  9359. +
  9360. + lacStatus = cpaCyRsaDecrypt(CPA_INSTANCE_HANDLE_SINGLE,
  9361. + icp_ocfDrvModExpCRTCallBack,
  9362. + callbackTag, rsaDecryptOpData, pOutputData);
  9363. +
  9364. + if (CPA_STATUS_SUCCESS != lacStatus) {
  9365. + EPRINTK("%s(): Mod Exp CRT Operation failed (%d).\n",
  9366. + __FUNCTION__, lacStatus);
  9367. + krp->krp_status = ECANCELED;
  9368. + icp_ocfDrvFreeFlatBuffer(pOutputData);
  9369. + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
  9370. + rsaDecryptOpData->pRecipientPrivateKey);
  9371. + ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);
  9372. + }
  9373. +
  9374. + return lacStatus;
  9375. +}
  9376. +
  9377. +/* Name : icp_ocfDrvCheckALessThanB
  9378. + *
  9379. + * Description : This function will check whether the first argument is less
  9380. + * than the second. It is used to check whether the DSA RS sign Random K
  9381. + * value is less than the Prime Q value (as defined in the specification)
  9382. + *
  9383. + */
  9384. +static int
  9385. +icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck)
  9386. +{
  9387. +
  9388. + uint8_t *MSB_K = pK->pData;
  9389. + uint8_t *MSB_Q = pQ->pData;
  9390. + uint32_t buffer_lengths_in_bytes = pQ->dataLenInBytes;
  9391. +
  9392. + if (DONT_RUN_LESS_THAN_CHECK == *doCheck) {
  9393. + return FAIL_A_IS_GREATER_THAN_B;
  9394. + }
  9395. +
  9396. +/*Check MSBs
  9397. +if A == B, check next MSB
  9398. +if A > B, return A_IS_GREATER_THAN_B
  9399. +if A < B, return A_IS_LESS_THAN_B (success)
  9400. +*/
  9401. + while (*MSB_K == *MSB_Q) {
  9402. + MSB_K++;
  9403. + MSB_Q++;
  9404. +
  9405. + buffer_lengths_in_bytes--;
  9406. + if (0 == buffer_lengths_in_bytes) {
  9407. + DPRINTK("%s() Buffers have equal value!!\n",
  9408. + __FUNCTION__);
  9409. + return FAIL_A_IS_EQUAL_TO_B;
  9410. + }
  9411. +
  9412. + }
  9413. +
  9414. + if (*MSB_K < *MSB_Q) {
  9415. + return SUCCESS_A_IS_LESS_THAN_B;
  9416. + } else {
  9417. + return FAIL_A_IS_GREATER_THAN_B;
  9418. + }
  9419. +
  9420. +}
  9421. +
  9422. +/* Name : icp_ocfDrvDsaSign
  9423. + *
  9424. + * Description : This function will map DSA RS Sign from OCF to the LAC API.
  9425. + *
  9426. + * NOTE: From looking at OCF patch to OpenSSL and even the number of input
  9427. + * parameters, OCF expects us to generate the random seed value. This value
  9428. + * is generated and passed to LAC, however the number is discared in the
  9429. + * callback and not returned to the user.
  9430. + */
  9431. +static int icp_ocfDrvDsaSign(struct cryptkop *krp)
  9432. +{
  9433. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  9434. + CpaCyDsaRSSignOpData *dsaRsSignOpData = NULL;
  9435. + void *callbackTag = NULL;
  9436. + CpaCyRandGenOpData randGenOpData;
  9437. + int primeQSizeInBytes = 0;
  9438. + int doCheck = 0;
  9439. + CpaFlatBuffer randData;
  9440. + CpaBoolean protocolStatus = CPA_FALSE;
  9441. + CpaFlatBuffer *pR = NULL;
  9442. + CpaFlatBuffer *pS = NULL;
  9443. +
  9444. + callbackTag = krp;
  9445. +
  9446. + BITS_TO_BYTES(primeQSizeInBytes,
  9447. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].
  9448. + crp_nbits);
  9449. +
  9450. + if (DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES != primeQSizeInBytes) {
  9451. + APRINTK("%s(): DSA PRIME Q size not equal to the "
  9452. + "FIPS defined 20bytes, = %d\n",
  9453. + __FUNCTION__, primeQSizeInBytes);
  9454. + krp->krp_status = EDOM;
  9455. + return EDOM;
  9456. + }
  9457. +
  9458. + dsaRsSignOpData =
  9459. + icp_kmem_cache_zalloc(drvDSARSSign_zone, ICP_M_NOWAIT);
  9460. + if (NULL == dsaRsSignOpData) {
  9461. + APRINTK("%s():Failed to get memory"
  9462. + " for DSA RS Sign Op data struct\n", __FUNCTION__);
  9463. + krp->krp_status = ENOMEM;
  9464. + return ENOMEM;
  9465. + }
  9466. +
  9467. + dsaRsSignOpData->K.pData =
  9468. + icp_kmem_cache_alloc(drvDSARSSignKValue_zone, ICP_M_NOWAIT);
  9469. +
  9470. + if (NULL == dsaRsSignOpData->K.pData) {
  9471. + APRINTK("%s():Failed to get memory"
  9472. + " for DSA RS Sign Op Random value\n", __FUNCTION__);
  9473. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  9474. + krp->krp_status = ENOMEM;
  9475. + return ENOMEM;
  9476. + }
  9477. +
  9478. + pR = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  9479. + if (NULL == pR) {
  9480. + APRINTK("%s():Failed to get memory"
  9481. + " for DSA signature R\n", __FUNCTION__);
  9482. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  9483. + dsaRsSignOpData->K.pData);
  9484. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  9485. + krp->krp_status = ENOMEM;
  9486. + return ENOMEM;
  9487. + }
  9488. +
  9489. + pS = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  9490. + if (NULL == pS) {
  9491. + APRINTK("%s():Failed to get memory"
  9492. + " for DSA signature S\n", __FUNCTION__);
  9493. + icp_ocfDrvFreeFlatBuffer(pR);
  9494. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  9495. + dsaRsSignOpData->K.pData);
  9496. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  9497. + krp->krp_status = ENOMEM;
  9498. + return ENOMEM;
  9499. + }
  9500. +
  9501. + /*link prime number parameter for ease of processing */
  9502. + dsaRsSignOpData->P.pData =
  9503. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].crp_p;
  9504. + BITS_TO_BYTES(dsaRsSignOpData->P.dataLenInBytes,
  9505. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].
  9506. + crp_nbits);
  9507. +
  9508. + icp_ocfDrvSwapBytes(dsaRsSignOpData->P.pData,
  9509. + dsaRsSignOpData->P.dataLenInBytes);
  9510. +
  9511. + dsaRsSignOpData->Q.pData =
  9512. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].crp_p;
  9513. + BITS_TO_BYTES(dsaRsSignOpData->Q.dataLenInBytes,
  9514. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].
  9515. + crp_nbits);
  9516. +
  9517. + icp_ocfDrvSwapBytes(dsaRsSignOpData->Q.pData,
  9518. + dsaRsSignOpData->Q.dataLenInBytes);
  9519. +
  9520. + /*generate random number with equal buffer size to Prime value Q,
  9521. + but value less than Q */
  9522. + dsaRsSignOpData->K.dataLenInBytes = dsaRsSignOpData->Q.dataLenInBytes;
  9523. +
  9524. + randGenOpData.generateBits = CPA_TRUE;
  9525. + randGenOpData.lenInBytes = dsaRsSignOpData->K.dataLenInBytes;
  9526. +
  9527. + icp_ocfDrvPtrAndLenToFlatBuffer(dsaRsSignOpData->K.pData,
  9528. + dsaRsSignOpData->K.dataLenInBytes,
  9529. + &randData);
  9530. +
  9531. + doCheck = 0;
  9532. + while (icp_ocfDrvCheckALessThanB(&(dsaRsSignOpData->K),
  9533. + &(dsaRsSignOpData->Q), &doCheck)) {
  9534. +
  9535. + if (CPA_STATUS_SUCCESS
  9536. + != cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
  9537. + NULL, NULL, &randGenOpData, &randData)) {
  9538. + APRINTK("%s(): ERROR - Failed to generate DSA RS Sign K"
  9539. + "value\n", __FUNCTION__);
  9540. + icp_ocfDrvFreeFlatBuffer(pS);
  9541. + icp_ocfDrvFreeFlatBuffer(pR);
  9542. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  9543. + dsaRsSignOpData->K.pData);
  9544. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  9545. + krp->krp_status = EAGAIN;
  9546. + return EAGAIN;
  9547. + }
  9548. +
  9549. + doCheck++;
  9550. + if (DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS == doCheck) {
  9551. + APRINTK("%s(): ERROR - Failed to find DSA RS Sign K "
  9552. + "value less than Q value\n", __FUNCTION__);
  9553. + icp_ocfDrvFreeFlatBuffer(pS);
  9554. + icp_ocfDrvFreeFlatBuffer(pR);
  9555. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  9556. + dsaRsSignOpData->K.pData);
  9557. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  9558. + krp->krp_status = EAGAIN;
  9559. + return EAGAIN;
  9560. + }
  9561. +
  9562. + }
  9563. + /*Rand Data - no need to swap bytes for pK */
  9564. +
  9565. + /* Link parameters */
  9566. + dsaRsSignOpData->G.pData =
  9567. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_p;
  9568. + BITS_TO_BYTES(dsaRsSignOpData->G.dataLenInBytes,
  9569. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_nbits);
  9570. +
  9571. + icp_ocfDrvSwapBytes(dsaRsSignOpData->G.pData,
  9572. + dsaRsSignOpData->G.dataLenInBytes);
  9573. +
  9574. + dsaRsSignOpData->X.pData =
  9575. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_p;
  9576. + BITS_TO_BYTES(dsaRsSignOpData->X.dataLenInBytes,
  9577. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_nbits);
  9578. + icp_ocfDrvSwapBytes(dsaRsSignOpData->X.pData,
  9579. + dsaRsSignOpData->X.dataLenInBytes);
  9580. +
  9581. + /*OpenSSL dgst parameter is left in big endian byte order,
  9582. + therefore no byte swap is required */
  9583. + dsaRsSignOpData->M.pData =
  9584. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].crp_p;
  9585. + BITS_TO_BYTES(dsaRsSignOpData->M.dataLenInBytes,
  9586. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].
  9587. + crp_nbits);
  9588. +
  9589. + /* Output Parameters */
  9590. + pS->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].crp_p;
  9591. + BITS_TO_BYTES(pS->dataLenInBytes,
  9592. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].
  9593. + crp_nbits);
  9594. +
  9595. + pR->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].crp_p;
  9596. + BITS_TO_BYTES(pR->dataLenInBytes,
  9597. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].
  9598. + crp_nbits);
  9599. +
  9600. + lacStatus = cpaCyDsaSignRS(CPA_INSTANCE_HANDLE_SINGLE,
  9601. + icp_ocfDrvDsaRSSignCallBack,
  9602. + callbackTag, dsaRsSignOpData,
  9603. + &protocolStatus, pR, pS);
  9604. +
  9605. + if (CPA_STATUS_SUCCESS != lacStatus) {
  9606. + EPRINTK("%s(): DSA RS Sign Operation failed (%d).\n",
  9607. + __FUNCTION__, lacStatus);
  9608. + krp->krp_status = ECANCELED;
  9609. + icp_ocfDrvFreeFlatBuffer(pS);
  9610. + icp_ocfDrvFreeFlatBuffer(pR);
  9611. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  9612. + dsaRsSignOpData->K.pData);
  9613. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  9614. + }
  9615. +
  9616. + return lacStatus;
  9617. +}
  9618. +
  9619. +/* Name : icp_ocfDrvDsaVerify
  9620. + *
  9621. + * Description : This function will map DSA RS Verify from OCF to the LAC API.
  9622. + *
  9623. + */
  9624. +static int icp_ocfDrvDsaVerify(struct cryptkop *krp)
  9625. +{
  9626. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  9627. + CpaCyDsaVerifyOpData *dsaVerifyOpData = NULL;
  9628. + void *callbackTag = NULL;
  9629. + CpaBoolean verifyStatus = CPA_FALSE;
  9630. +
  9631. + callbackTag = krp;
  9632. +
  9633. + dsaVerifyOpData =
  9634. + icp_kmem_cache_zalloc(drvDSAVerify_zone, ICP_M_NOWAIT);
  9635. + if (NULL == dsaVerifyOpData) {
  9636. + APRINTK("%s():Failed to get memory"
  9637. + " for DSA Verify Op data struct\n", __FUNCTION__);
  9638. + krp->krp_status = ENOMEM;
  9639. + return ENOMEM;
  9640. + }
  9641. +
  9642. + /* Link parameters */
  9643. + dsaVerifyOpData->P.pData =
  9644. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].crp_p;
  9645. + BITS_TO_BYTES(dsaVerifyOpData->P.dataLenInBytes,
  9646. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].
  9647. + crp_nbits);
  9648. + icp_ocfDrvSwapBytes(dsaVerifyOpData->P.pData,
  9649. + dsaVerifyOpData->P.dataLenInBytes);
  9650. +
  9651. + dsaVerifyOpData->Q.pData =
  9652. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].crp_p;
  9653. + BITS_TO_BYTES(dsaVerifyOpData->Q.dataLenInBytes,
  9654. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].
  9655. + crp_nbits);
  9656. + icp_ocfDrvSwapBytes(dsaVerifyOpData->Q.pData,
  9657. + dsaVerifyOpData->Q.dataLenInBytes);
  9658. +
  9659. + dsaVerifyOpData->G.pData =
  9660. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].crp_p;
  9661. + BITS_TO_BYTES(dsaVerifyOpData->G.dataLenInBytes,
  9662. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].
  9663. + crp_nbits);
  9664. + icp_ocfDrvSwapBytes(dsaVerifyOpData->G.pData,
  9665. + dsaVerifyOpData->G.dataLenInBytes);
  9666. +
  9667. + dsaVerifyOpData->Y.pData =
  9668. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].crp_p;
  9669. + BITS_TO_BYTES(dsaVerifyOpData->Y.dataLenInBytes,
  9670. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].
  9671. + crp_nbits);
  9672. + icp_ocfDrvSwapBytes(dsaVerifyOpData->Y.pData,
  9673. + dsaVerifyOpData->Y.dataLenInBytes);
  9674. +
  9675. + /*OpenSSL dgst parameter is left in big endian byte order,
  9676. + therefore no byte swap is required */
  9677. + dsaVerifyOpData->M.pData =
  9678. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].crp_p;
  9679. + BITS_TO_BYTES(dsaVerifyOpData->M.dataLenInBytes,
  9680. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].
  9681. + crp_nbits);
  9682. +
  9683. + dsaVerifyOpData->R.pData =
  9684. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].crp_p;
  9685. + BITS_TO_BYTES(dsaVerifyOpData->R.dataLenInBytes,
  9686. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].
  9687. + crp_nbits);
  9688. + icp_ocfDrvSwapBytes(dsaVerifyOpData->R.pData,
  9689. + dsaVerifyOpData->R.dataLenInBytes);
  9690. +
  9691. + dsaVerifyOpData->S.pData =
  9692. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].crp_p;
  9693. + BITS_TO_BYTES(dsaVerifyOpData->S.dataLenInBytes,
  9694. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].
  9695. + crp_nbits);
  9696. + icp_ocfDrvSwapBytes(dsaVerifyOpData->S.pData,
  9697. + dsaVerifyOpData->S.dataLenInBytes);
  9698. +
  9699. + lacStatus = cpaCyDsaVerify(CPA_INSTANCE_HANDLE_SINGLE,
  9700. + icp_ocfDrvDsaVerifyCallBack,
  9701. + callbackTag, dsaVerifyOpData, &verifyStatus);
  9702. +
  9703. + if (CPA_STATUS_SUCCESS != lacStatus) {
  9704. + EPRINTK("%s(): DSA Verify Operation failed (%d).\n",
  9705. + __FUNCTION__, lacStatus);
  9706. + ICP_CACHE_FREE(drvDSAVerify_zone, dsaVerifyOpData);
  9707. + krp->krp_status = ECANCELED;
  9708. + }
  9709. +
  9710. + return lacStatus;
  9711. +}
  9712. +
  9713. +/* Name : icp_ocfDrvDhP1Callback
  9714. + *
  9715. + * Description : When this function returns it signifies that the LAC
  9716. + * component has completed the DH operation.
  9717. + */
  9718. +static void
  9719. +icp_ocfDrvDhP1CallBack(void *callbackTag,
  9720. + CpaStatus status,
  9721. + void *pOpData, CpaFlatBuffer * pLocalOctetStringPV)
  9722. +{
  9723. + struct cryptkop *krp = NULL;
  9724. + CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;
  9725. +
  9726. + if (NULL == callbackTag) {
  9727. + DPRINTK("%s(): Invalid input parameters - "
  9728. + "callbackTag data is NULL\n", __FUNCTION__);
  9729. + return;
  9730. + }
  9731. + krp = (struct cryptkop *)callbackTag;
  9732. +
  9733. + if (NULL == pOpData) {
  9734. + DPRINTK("%s(): Invalid input parameters - "
  9735. + "Operation Data is NULL\n", __FUNCTION__);
  9736. + krp->krp_status = ECANCELED;
  9737. + crypto_kdone(krp);
  9738. + return;
  9739. + }
  9740. + pPhase1OpData = (CpaCyDhPhase1KeyGenOpData *) pOpData;
  9741. +
  9742. + if (NULL == pLocalOctetStringPV) {
  9743. + DPRINTK("%s(): Invalid input parameters - "
  9744. + "pLocalOctetStringPV Data is NULL\n", __FUNCTION__);
  9745. + memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));
  9746. + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
  9747. + krp->krp_status = ECANCELED;
  9748. + crypto_kdone(krp);
  9749. + return;
  9750. + }
  9751. +
  9752. + if (CPA_STATUS_SUCCESS == status) {
  9753. + krp->krp_status = CRYPTO_OP_SUCCESS;
  9754. + } else {
  9755. + APRINTK("%s(): Diffie Hellman Phase1 Key Gen failed - "
  9756. + "Operation Status = %d\n", __FUNCTION__, status);
  9757. + krp->krp_status = ECANCELED;
  9758. + }
  9759. +
  9760. + icp_ocfDrvSwapBytes(pLocalOctetStringPV->pData,
  9761. + pLocalOctetStringPV->dataLenInBytes);
  9762. +
  9763. + icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);
  9764. + memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));
  9765. + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
  9766. +
  9767. + crypto_kdone(krp);
  9768. +
  9769. + return;
  9770. +}
  9771. +
  9772. +/* Name : icp_ocfDrvModExpCallBack
  9773. + *
  9774. + * Description : When this function returns it signifies that the LAC
  9775. + * component has completed the Mod Exp operation.
  9776. + */
  9777. +static void
  9778. +icp_ocfDrvModExpCallBack(void *callbackTag,
  9779. + CpaStatus status,
  9780. + void *pOpdata, CpaFlatBuffer * pResult)
  9781. +{
  9782. + struct cryptkop *krp = NULL;
  9783. + CpaCyLnModExpOpData *pLnModExpOpData = NULL;
  9784. +
  9785. + if (NULL == callbackTag) {
  9786. + DPRINTK("%s(): Invalid input parameters - "
  9787. + "callbackTag data is NULL\n", __FUNCTION__);
  9788. + return;
  9789. + }
  9790. + krp = (struct cryptkop *)callbackTag;
  9791. +
  9792. + if (NULL == pOpdata) {
  9793. + DPRINTK("%s(): Invalid Mod Exp input parameters - "
  9794. + "Operation Data is NULL\n", __FUNCTION__);
  9795. + krp->krp_status = ECANCELED;
  9796. + crypto_kdone(krp);
  9797. + return;
  9798. + }
  9799. + pLnModExpOpData = (CpaCyLnModExpOpData *) pOpdata;
  9800. +
  9801. + if (NULL == pResult) {
  9802. + DPRINTK("%s(): Invalid input parameters - "
  9803. + "pResult data is NULL\n", __FUNCTION__);
  9804. + krp->krp_status = ECANCELED;
  9805. + memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));
  9806. + ICP_CACHE_FREE(drvLnModExp_zone, pLnModExpOpData);
  9807. + crypto_kdone(krp);
  9808. + return;
  9809. + }
  9810. +
  9811. + if (CPA_STATUS_SUCCESS == status) {
  9812. + krp->krp_status = CRYPTO_OP_SUCCESS;
  9813. + } else {
  9814. + APRINTK("%s(): LAC Mod Exp Operation failed - "
  9815. + "Operation Status = %d\n", __FUNCTION__, status);
  9816. + krp->krp_status = ECANCELED;
  9817. + }
  9818. +
  9819. + icp_ocfDrvSwapBytes(pResult->pData, pResult->dataLenInBytes);
  9820. +
  9821. + /*switch base size value back to original */
  9822. + if (pLnModExpOpData->base.pData ==
  9823. + (uint8_t *) & (krp->
  9824. + krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
  9825. + crp_nbits)) {
  9826. + *((uint32_t *) pLnModExpOpData->base.pData) =
  9827. + ntohl(*((uint32_t *) pLnModExpOpData->base.pData));
  9828. + }
  9829. + icp_ocfDrvFreeFlatBuffer(pResult);
  9830. + memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));
  9831. + ICP_CACHE_FREE(drvLnModExp_zone, pLnModExpOpData);
  9832. +
  9833. + crypto_kdone(krp);
  9834. +
  9835. + return;
  9836. +
  9837. +}
  9838. +
  9839. +/* Name : icp_ocfDrvModExpCRTCallBack
  9840. + *
  9841. + * Description : When this function returns it signifies that the LAC
  9842. + * component has completed the Mod Exp CRT operation.
  9843. + */
  9844. +static void
  9845. +icp_ocfDrvModExpCRTCallBack(void *callbackTag,
  9846. + CpaStatus status,
  9847. + void *pOpData, CpaFlatBuffer * pOutputData)
  9848. +{
  9849. + struct cryptkop *krp = NULL;
  9850. + CpaCyRsaDecryptOpData *pDecryptData = NULL;
  9851. +
  9852. + if (NULL == callbackTag) {
  9853. + DPRINTK("%s(): Invalid input parameters - "
  9854. + "callbackTag data is NULL\n", __FUNCTION__);
  9855. + return;
  9856. + }
  9857. +
  9858. + krp = (struct cryptkop *)callbackTag;
  9859. +
  9860. + if (NULL == pOpData) {
  9861. + DPRINTK("%s(): Invalid input parameters - "
  9862. + "Operation Data is NULL\n", __FUNCTION__);
  9863. + krp->krp_status = ECANCELED;
  9864. + crypto_kdone(krp);
  9865. + return;
  9866. + }
  9867. + pDecryptData = (CpaCyRsaDecryptOpData *) pOpData;
  9868. +
  9869. + if (NULL == pOutputData) {
  9870. + DPRINTK("%s(): Invalid input parameter - "
  9871. + "pOutputData is NULL\n", __FUNCTION__);
  9872. + memset(pDecryptData->pRecipientPrivateKey, 0,
  9873. + sizeof(CpaCyRsaPrivateKey));
  9874. + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
  9875. + pDecryptData->pRecipientPrivateKey);
  9876. + memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));
  9877. + ICP_CACHE_FREE(drvRSADecrypt_zone, pDecryptData);
  9878. + krp->krp_status = ECANCELED;
  9879. + crypto_kdone(krp);
  9880. + return;
  9881. + }
  9882. +
  9883. + if (CPA_STATUS_SUCCESS == status) {
  9884. + krp->krp_status = CRYPTO_OP_SUCCESS;
  9885. + } else {
  9886. + APRINTK("%s(): LAC Mod Exp CRT operation failed - "
  9887. + "Operation Status = %d\n", __FUNCTION__, status);
  9888. + krp->krp_status = ECANCELED;
  9889. + }
  9890. +
  9891. + icp_ocfDrvSwapBytes(pOutputData->pData, pOutputData->dataLenInBytes);
  9892. +
  9893. + icp_ocfDrvFreeFlatBuffer(pOutputData);
  9894. + memset(pDecryptData->pRecipientPrivateKey, 0,
  9895. + sizeof(CpaCyRsaPrivateKey));
  9896. + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
  9897. + pDecryptData->pRecipientPrivateKey);
  9898. + memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));
  9899. + ICP_CACHE_FREE(drvRSADecrypt_zone, pDecryptData);
  9900. +
  9901. + crypto_kdone(krp);
  9902. +
  9903. + return;
  9904. +}
  9905. +
  9906. +/* Name : icp_ocfDrvDsaRSSignCallBack
  9907. + *
  9908. + * Description : When this function returns it signifies that the LAC
  9909. + * component has completed the DSA RS sign operation.
  9910. + */
  9911. +static void
  9912. +icp_ocfDrvDsaRSSignCallBack(void *callbackTag,
  9913. + CpaStatus status,
  9914. + void *pOpData,
  9915. + CpaBoolean protocolStatus,
  9916. + CpaFlatBuffer * pR, CpaFlatBuffer * pS)
  9917. +{
  9918. + struct cryptkop *krp = NULL;
  9919. + CpaCyDsaRSSignOpData *pSignData = NULL;
  9920. +
  9921. + if (NULL == callbackTag) {
  9922. + DPRINTK("%s(): Invalid input parameters - "
  9923. + "callbackTag data is NULL\n", __FUNCTION__);
  9924. + return;
  9925. + }
  9926. +
  9927. + krp = (struct cryptkop *)callbackTag;
  9928. +
  9929. + if (NULL == pOpData) {
  9930. + DPRINTK("%s(): Invalid input parameters - "
  9931. + "Operation Data is NULL\n", __FUNCTION__);
  9932. + krp->krp_status = ECANCELED;
  9933. + crypto_kdone(krp);
  9934. + return;
  9935. + }
  9936. + pSignData = (CpaCyDsaRSSignOpData *) pOpData;
  9937. +
  9938. + if (NULL == pR) {
  9939. + DPRINTK("%s(): Invalid input parameter - "
  9940. + "pR sign is NULL\n", __FUNCTION__);
  9941. + icp_ocfDrvFreeFlatBuffer(pS);
  9942. + ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);
  9943. + krp->krp_status = ECANCELED;
  9944. + crypto_kdone(krp);
  9945. + return;
  9946. + }
  9947. +
  9948. + if (NULL == pS) {
  9949. + DPRINTK("%s(): Invalid input parameter - "
  9950. + "pS sign is NULL\n", __FUNCTION__);
  9951. + icp_ocfDrvFreeFlatBuffer(pR);
  9952. + ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);
  9953. + krp->krp_status = ECANCELED;
  9954. + crypto_kdone(krp);
  9955. + return;
  9956. + }
  9957. +
  9958. + if (CPA_STATUS_SUCCESS != status) {
  9959. + APRINTK("%s(): LAC DSA RS Sign operation failed - "
  9960. + "Operation Status = %d\n", __FUNCTION__, status);
  9961. + krp->krp_status = ECANCELED;
  9962. + } else {
  9963. + krp->krp_status = CRYPTO_OP_SUCCESS;
  9964. +
  9965. + if (CPA_TRUE != protocolStatus) {
  9966. + DPRINTK("%s(): LAC DSA RS Sign operation failed due "
  9967. + "to protocol error\n", __FUNCTION__);
  9968. + krp->krp_status = EIO;
  9969. + }
  9970. + }
  9971. +
  9972. + /* Swap bytes only when the callback status is successful and
  9973. + protocolStatus is set to true */
  9974. + if (CPA_STATUS_SUCCESS == status && CPA_TRUE == protocolStatus) {
  9975. + icp_ocfDrvSwapBytes(pR->pData, pR->dataLenInBytes);
  9976. + icp_ocfDrvSwapBytes(pS->pData, pS->dataLenInBytes);
  9977. + }
  9978. +
  9979. + icp_ocfDrvFreeFlatBuffer(pR);
  9980. + icp_ocfDrvFreeFlatBuffer(pS);
  9981. + memset(pSignData->K.pData, 0, pSignData->K.dataLenInBytes);
  9982. + ICP_CACHE_FREE(drvDSARSSignKValue_zone, pSignData->K.pData);
  9983. + memset(pSignData, 0, sizeof(CpaCyDsaRSSignOpData));
  9984. + ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);
  9985. + crypto_kdone(krp);
  9986. +
  9987. + return;
  9988. +}
  9989. +
  9990. +/* Name : icp_ocfDrvDsaVerifyCallback
  9991. + *
  9992. + * Description : When this function returns it signifies that the LAC
  9993. + * component has completed the DSA Verify operation.
  9994. + */
  9995. +static void
  9996. +icp_ocfDrvDsaVerifyCallBack(void *callbackTag,
  9997. + CpaStatus status,
  9998. + void *pOpData, CpaBoolean verifyStatus)
  9999. +{
  10000. +
  10001. + struct cryptkop *krp = NULL;
  10002. + CpaCyDsaVerifyOpData *pVerData = NULL;
  10003. +
  10004. + if (NULL == callbackTag) {
  10005. + DPRINTK("%s(): Invalid input parameters - "
  10006. + "callbackTag data is NULL\n", __FUNCTION__);
  10007. + return;
  10008. + }
  10009. +
  10010. + krp = (struct cryptkop *)callbackTag;
  10011. +
  10012. + if (NULL == pOpData) {
  10013. + DPRINTK("%s(): Invalid input parameters - "
  10014. + "Operation Data is NULL\n", __FUNCTION__);
  10015. + krp->krp_status = ECANCELED;
  10016. + crypto_kdone(krp);
  10017. + return;
  10018. + }
  10019. + pVerData = (CpaCyDsaVerifyOpData *) pOpData;
  10020. +
  10021. + if (CPA_STATUS_SUCCESS != status) {
  10022. + APRINTK("%s(): LAC DSA Verify operation failed - "
  10023. + "Operation Status = %d\n", __FUNCTION__, status);
  10024. + krp->krp_status = ECANCELED;
  10025. + } else {
  10026. + krp->krp_status = CRYPTO_OP_SUCCESS;
  10027. +
  10028. + if (CPA_TRUE != verifyStatus) {
  10029. + DPRINTK("%s(): DSA signature invalid\n", __FUNCTION__);
  10030. + krp->krp_status = EIO;
  10031. + }
  10032. + }
  10033. +
  10034. + /* Swap bytes only when the callback status is successful and
  10035. + verifyStatus is set to true */
  10036. + /*Just swapping back the key values for now. Possibly all
  10037. + swapped buffers need to be reverted */
  10038. + if (CPA_STATUS_SUCCESS == status && CPA_TRUE == verifyStatus) {
  10039. + icp_ocfDrvSwapBytes(pVerData->R.pData,
  10040. + pVerData->R.dataLenInBytes);
  10041. + icp_ocfDrvSwapBytes(pVerData->S.pData,
  10042. + pVerData->S.dataLenInBytes);
  10043. + }
  10044. +
  10045. + memset(pVerData, 0, sizeof(CpaCyDsaVerifyOpData));
  10046. + ICP_CACHE_FREE(drvDSAVerify_zone, pVerData);
  10047. + crypto_kdone(krp);
  10048. +
  10049. + return;
  10050. +}
  10051. diff -Nur linux-2.6.35.orig/crypto/ocf/ep80579/icp_common.c linux-2.6.35/crypto/ocf/ep80579/icp_common.c
  10052. --- linux-2.6.35.orig/crypto/ocf/ep80579/icp_common.c 1970-01-01 01:00:00.000000000 +0100
  10053. +++ linux-2.6.35/crypto/ocf/ep80579/icp_common.c 2010-08-05 22:02:08.383824886 +0200
  10054. @@ -0,0 +1,773 @@
  10055. +/*************************************************************************
  10056. + *
  10057. + * This file is provided under a dual BSD/GPLv2 license. When using or
  10058. + * redistributing this file, you may do so under either license.
  10059. + *
  10060. + * GPL LICENSE SUMMARY
  10061. + *
  10062. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  10063. + *
  10064. + * This program is free software; you can redistribute it and/or modify
  10065. + * it under the terms of version 2 of the GNU General Public License as
  10066. + * published by the Free Software Foundation.
  10067. + *
  10068. + * This program is distributed in the hope that it will be useful, but
  10069. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  10070. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10071. + * General Public License for more details.
  10072. + *
  10073. + * You should have received a copy of the GNU General Public License
  10074. + * along with this program; if not, write to the Free Software
  10075. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  10076. + * The full GNU General Public License is included in this distribution
  10077. + * in the file called LICENSE.GPL.
  10078. + *
  10079. + * Contact Information:
  10080. + * Intel Corporation
  10081. + *
  10082. + * BSD LICENSE
  10083. + *
  10084. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  10085. + * All rights reserved.
  10086. + *
  10087. + * Redistribution and use in source and binary forms, with or without
  10088. + * modification, are permitted provided that the following conditions
  10089. + * are met:
  10090. + *
  10091. + * * Redistributions of source code must retain the above copyright
  10092. + * notice, this list of conditions and the following disclaimer.
  10093. + * * Redistributions in binary form must reproduce the above copyright
  10094. + * notice, this list of conditions and the following disclaimer in
  10095. + * the documentation and/or other materials provided with the
  10096. + * distribution.
  10097. + * * Neither the name of Intel Corporation nor the names of its
  10098. + * contributors may be used to endorse or promote products derived
  10099. + * from this software without specific prior written permission.
  10100. + *
  10101. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  10102. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  10103. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  10104. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  10105. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10106. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  10107. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10108. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  10109. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  10110. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  10111. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  10112. + *
  10113. + *
  10114. + * version: Security.L.1.0.2-229
  10115. + *
  10116. + ***************************************************************************/
  10117. +
  10118. +/*
  10119. + * An OCF module that uses Intel® QuickAssist Integrated Accelerator to do the
  10120. + * crypto.
  10121. + *
  10122. + * This driver requires the ICP Access Library that is available from Intel in
  10123. + * order to operate.
  10124. + */
  10125. +
  10126. +#include "icp_ocf.h"
  10127. +
  10128. +#define ICP_OCF_COMP_NAME "ICP_OCF"
  10129. +#define ICP_OCF_VER_MAIN (2)
  10130. +#define ICP_OCF_VER_MJR (1)
  10131. +#define ICP_OCF_VER_MNR (0)
  10132. +
  10133. +#define MAX_DEREG_RETRIES (100)
  10134. +#define DEFAULT_DEREG_RETRIES (10)
  10135. +#define DEFAULT_DEREG_DELAY_IN_JIFFIES (10)
  10136. +
  10137. +/* This defines the maximum number of sessions possible between OCF
  10138. + and the OCF EP80579 Driver. If set to zero, there is no limit. */
  10139. +#define DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT (0)
  10140. +#define NUM_SUPPORTED_CAPABILITIES (21)
  10141. +
  10142. +/*Slab zone names*/
  10143. +#define ICP_SESSION_DATA_NAME "icp_ocf.SesDat"
  10144. +#define ICP_OP_DATA_NAME "icp_ocf.OpDat"
  10145. +#define ICP_DH_NAME "icp_ocf.DH"
  10146. +#define ICP_MODEXP_NAME "icp_ocf.ModExp"
  10147. +#define ICP_RSA_DECRYPT_NAME "icp_ocf.RSAdec"
  10148. +#define ICP_RSA_PKEY_NAME "icp_ocf.RSApk"
  10149. +#define ICP_DSA_SIGN_NAME "icp_ocf.DSAsg"
  10150. +#define ICP_DSA_VER_NAME "icp_ocf.DSAver"
  10151. +#define ICP_RAND_VAL_NAME "icp_ocf.DSArnd"
  10152. +#define ICP_FLAT_BUFF_NAME "icp_ocf.FB"
  10153. +
  10154. +/*Slabs zones*/
  10155. +icp_kmem_cache drvSessionData_zone = NULL;
  10156. +icp_kmem_cache drvOpData_zone = NULL;
  10157. +icp_kmem_cache drvDH_zone = NULL;
  10158. +icp_kmem_cache drvLnModExp_zone = NULL;
  10159. +icp_kmem_cache drvRSADecrypt_zone = NULL;
  10160. +icp_kmem_cache drvRSAPrivateKey_zone = NULL;
  10161. +icp_kmem_cache drvDSARSSign_zone = NULL;
  10162. +icp_kmem_cache drvDSARSSignKValue_zone = NULL;
  10163. +icp_kmem_cache drvDSAVerify_zone = NULL;
  10164. +
  10165. +/*Slab zones for flatbuffers and bufferlist*/
  10166. +icp_kmem_cache drvFlatBuffer_zone = NULL;
  10167. +
  10168. +static inline int icp_cache_null_check(void)
  10169. +{
  10170. + return (drvSessionData_zone && drvOpData_zone
  10171. + && drvDH_zone && drvLnModExp_zone && drvRSADecrypt_zone
  10172. + && drvRSAPrivateKey_zone && drvDSARSSign_zone
  10173. + && drvDSARSSign_zone && drvDSARSSignKValue_zone
  10174. + && drvDSAVerify_zone && drvFlatBuffer_zone);
  10175. +}
  10176. +
  10177. +/*Function to free all allocated slab caches before exiting the module*/
  10178. +static void icp_ocfDrvFreeCaches(void);
  10179. +
  10180. +int32_t icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  10181. +
  10182. +/* Module parameter - gives the number of times LAC deregistration shall be
  10183. + re-tried */
  10184. +int num_dereg_retries = DEFAULT_DEREG_RETRIES;
  10185. +
  10186. +/* Module parameter - gives the delay time in jiffies before a LAC session
  10187. + shall be attempted to be deregistered again */
  10188. +int dereg_retry_delay_in_jiffies = DEFAULT_DEREG_DELAY_IN_JIFFIES;
  10189. +
  10190. +/* Module parameter - gives the maximum number of sessions possible between
  10191. + OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/
  10192. +int max_sessions = DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT;
  10193. +
  10194. +/* This is set when the module is removed from the system, no further
  10195. + processing can take place if this is set */
  10196. +icp_atomic_t icp_ocfDrvIsExiting = ICP_ATOMIC_INIT(0);
  10197. +
  10198. +/* This is used to show how many lac sessions were not deregistered*/
  10199. +icp_atomic_t lac_session_failed_dereg_count = ICP_ATOMIC_INIT(0);
  10200. +
  10201. +/* This is used to track the number of registered sessions between OCF and
  10202. + * and the OCF EP80579 driver, when max_session is set to value other than
  10203. + * zero. This ensures that the max_session set for the OCF and the driver
  10204. + * is equal to the LAC registered sessions */
  10205. +icp_atomic_t num_ocf_to_drv_registered_sessions = ICP_ATOMIC_INIT(0);
  10206. +
  10207. +/* Head of linked list used to store session data */
  10208. +icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead;
  10209. +icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList;
  10210. +
  10211. +icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock;
  10212. +
  10213. +/*Below pointer is only used in linux, FreeBSD uses the name to
  10214. +create its own variable name*/
  10215. +icp_workqueue *icp_ocfDrvFreeLacSessionWorkQ = NULL;
  10216. +ICP_WORKQUEUE_DEFINE_THREAD(icp_ocfDrvFreeLacSessionWorkQ);
  10217. +
  10218. +struct icp_drvBuffListInfo defBuffListInfo;
  10219. +
  10220. +/* Name : icp_ocfDrvInit
  10221. + *
  10222. + * Description : This function will register all the symmetric and asymmetric
  10223. + * functionality that will be accelerated by the hardware. It will also
  10224. + * get a unique driver ID from the OCF and initialise all slab caches
  10225. + */
  10226. +ICP_MODULE_INIT_FUNC(icp_ocfDrvInit)
  10227. +{
  10228. + int ocfStatus = 0;
  10229. +
  10230. + IPRINTK("=== %s ver %d.%d.%d ===\n", ICP_OCF_COMP_NAME,
  10231. + ICP_OCF_VER_MAIN, ICP_OCF_VER_MJR, ICP_OCF_VER_MNR);
  10232. +
  10233. + if (MAX_DEREG_RETRIES < num_dereg_retries) {
  10234. + EPRINTK("Session deregistration retry count set to greater "
  10235. + "than %d", MAX_DEREG_RETRIES);
  10236. + icp_module_return_code(EINVAL);
  10237. + }
  10238. +
  10239. + /* Initialize and Start the Cryptographic component */
  10240. + if (CPA_STATUS_SUCCESS !=
  10241. + cpaCyStartInstance(CPA_INSTANCE_HANDLE_SINGLE)) {
  10242. + EPRINTK("Failed to initialize and start the instance "
  10243. + "of the Cryptographic component.\n");
  10244. + return icp_module_return_code(EINVAL);
  10245. + }
  10246. +
  10247. + icp_spin_lock_init(&icp_ocfDrvSymSessInfoListSpinlock);
  10248. +
  10249. + /* Set the default size of BufferList to allocate */
  10250. + memset(&defBuffListInfo, 0, sizeof(struct icp_drvBuffListInfo));
  10251. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  10252. + icp_ocfDrvBufferListMemInfo(ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS,
  10253. + &defBuffListInfo)) {
  10254. + EPRINTK("Failed to get bufferlist memory info.\n");
  10255. + return icp_module_return_code(ENOMEM);
  10256. + }
  10257. +
  10258. + /*Register OCF EP80579 Driver with OCF */
  10259. + icp_ocfDrvDriverId = ICP_CRYPTO_GET_DRIVERID();
  10260. +
  10261. + if (icp_ocfDrvDriverId < 0) {
  10262. + EPRINTK("%s : ICP driver failed to register with OCF!\n",
  10263. + __FUNCTION__);
  10264. + return icp_module_return_code(ENODEV);
  10265. + }
  10266. +
  10267. + /*Create all the slab caches used by the OCF EP80579 Driver */
  10268. + drvSessionData_zone =
  10269. + ICP_CACHE_CREATE(ICP_SESSION_DATA_NAME, struct icp_drvSessionData);
  10270. +
  10271. + /*
  10272. + * Allocation of the OpData includes the allocation space for meta data.
  10273. + * The memory after the opData structure is reserved for this meta data.
  10274. + */
  10275. + drvOpData_zone =
  10276. + icp_kmem_cache_create(ICP_OP_DATA_NAME,
  10277. + sizeof(struct icp_drvOpData) +
  10278. + defBuffListInfo.metaSize,
  10279. + ICP_KERNEL_CACHE_ALIGN,
  10280. + ICP_KERNEL_CACHE_NOINIT);
  10281. +
  10282. + drvDH_zone = ICP_CACHE_CREATE(ICP_DH_NAME, CpaCyDhPhase1KeyGenOpData);
  10283. +
  10284. + drvLnModExp_zone =
  10285. + ICP_CACHE_CREATE(ICP_MODEXP_NAME, CpaCyLnModExpOpData);
  10286. +
  10287. + drvRSADecrypt_zone =
  10288. + ICP_CACHE_CREATE(ICP_RSA_DECRYPT_NAME, CpaCyRsaDecryptOpData);
  10289. +
  10290. + drvRSAPrivateKey_zone =
  10291. + ICP_CACHE_CREATE(ICP_RSA_PKEY_NAME, CpaCyRsaPrivateKey);
  10292. +
  10293. + drvDSARSSign_zone =
  10294. + ICP_CACHE_CREATE(ICP_DSA_SIGN_NAME, CpaCyDsaRSSignOpData);
  10295. +
  10296. + /*too awkward to use a macro here */
  10297. + drvDSARSSignKValue_zone =
  10298. + ICP_CACHE_CREATE(ICP_RAND_VAL_NAME,
  10299. + DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES);
  10300. +
  10301. + drvDSAVerify_zone =
  10302. + ICP_CACHE_CREATE(ICP_DSA_VER_NAME, CpaCyDsaVerifyOpData);
  10303. +
  10304. + drvFlatBuffer_zone =
  10305. + ICP_CACHE_CREATE(ICP_FLAT_BUFF_NAME, CpaFlatBuffer);
  10306. +
  10307. + if (0 == icp_cache_null_check()) {
  10308. + icp_ocfDrvFreeCaches();
  10309. + EPRINTK("%s() line %d: Not enough memory!\n",
  10310. + __FUNCTION__, __LINE__);
  10311. + return ENOMEM;
  10312. + }
  10313. +
  10314. + /* Register the ICP symmetric crypto support. */
  10315. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_NULL_CBC, ocfStatus);
  10316. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_DES_CBC, ocfStatus);
  10317. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_3DES_CBC, ocfStatus);
  10318. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_AES_CBC, ocfStatus);
  10319. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_ARC4, ocfStatus);
  10320. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5, ocfStatus);
  10321. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5_HMAC, ocfStatus);
  10322. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1, ocfStatus);
  10323. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1_HMAC, ocfStatus);
  10324. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256, ocfStatus);
  10325. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256_HMAC,
  10326. + ocfStatus);
  10327. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384, ocfStatus);
  10328. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384_HMAC,
  10329. + ocfStatus);
  10330. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512, ocfStatus);
  10331. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512_HMAC,
  10332. + ocfStatus);
  10333. +
  10334. + /* Register the ICP asymmetric algorithm support */
  10335. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DH_COMPUTE_KEY,
  10336. + ocfStatus);
  10337. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP, ocfStatus);
  10338. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP_CRT, ocfStatus);
  10339. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_SIGN, ocfStatus);
  10340. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_VERIFY, ocfStatus);
  10341. +
  10342. + /* Register the ICP random number generator support */
  10343. + ICP_REG_RAND_WITH_OCF(icp_ocfDrvDriverId,
  10344. + icp_ocfDrvReadRandom, NULL, ocfStatus);
  10345. +
  10346. + if (OCF_ZERO_FUNCTIONALITY_REGISTERED == ocfStatus) {
  10347. + DPRINTK("%s: Failed to register any device capabilities\n",
  10348. + __FUNCTION__);
  10349. + icp_ocfDrvFreeCaches();
  10350. + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  10351. + return icp_module_return_code(ECANCELED);
  10352. + }
  10353. +
  10354. + DPRINTK("%s: Registered %d of %d device capabilities\n",
  10355. + __FUNCTION__, ocfStatus, NUM_SUPPORTED_CAPABILITIES);
  10356. +
  10357. + /*Session data linked list used during module exit */
  10358. + ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead);
  10359. + ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead_FreeMemList);
  10360. +
  10361. + ICP_WORKQUEUE_CREATE(icp_ocfDrvFreeLacSessionWorkQ, "icpwq");
  10362. + if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {
  10363. + EPRINTK("%s: Failed to create single "
  10364. + "thread workqueue\n", __FUNCTION__);
  10365. + icp_ocfDrvFreeCaches();
  10366. + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  10367. + return icp_module_return_code(ENOMEM);
  10368. + }
  10369. +
  10370. + return icp_module_return_code(0);
  10371. +}
  10372. +
  10373. +/* Name : icp_ocfDrvExit
  10374. + *
  10375. + * Description : This function will deregister all the symmetric sessions
  10376. + * registered with the LAC component. It will also deregister all symmetric
  10377. + * and asymmetric functionality that can be accelerated by the hardware via OCF
  10378. + * and random number generation if it is enabled.
  10379. + */
  10380. +ICP_MODULE_EXIT_FUNC(icp_ocfDrvExit)
  10381. +{
  10382. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  10383. + struct icp_drvSessionData *sessionData = NULL;
  10384. + struct icp_drvSessionData *tempSessionData = NULL;
  10385. + int i, remaining_delay_time_in_jiffies = 0;
  10386. +
  10387. + /* For FreeBSD the invariant macro below makes function to return */
  10388. + /* with EBUSY value in the case of any session which has been regi- */
  10389. + /* stered with LAC not being deregistered. */
  10390. + /* The Linux implementation is empty since it is purely to compensate */
  10391. + /* for a limitation of the FreeBSD 7.1 Opencrypto framework. */
  10392. +
  10393. + ICP_MODULE_EXIT_INV();
  10394. +
  10395. + /* There is a possibility of a process or new session command being */
  10396. + /* sent before this variable is incremented. The aim of this variable */
  10397. + /* is to stop a loop of calls creating a deadlock situation which */
  10398. + /* would prevent the driver from exiting. */
  10399. + icp_atomic_set(&icp_ocfDrvIsExiting, 1);
  10400. +
  10401. + /*Existing sessions will be routed to another driver after these calls */
  10402. + crypto_unregister_all(icp_ocfDrvDriverId);
  10403. + crypto_runregister_all(icp_ocfDrvDriverId);
  10404. +
  10405. + if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {
  10406. + DPRINTK("%s: workqueue already "
  10407. + "destroyed, therefore module exit "
  10408. + " function already called. Exiting.\n", __FUNCTION__);
  10409. + return ICP_MODULE_EXIT_FUNC_RETURN_VAL;
  10410. + }
  10411. + /*If any sessions are waiting to be deregistered, do that. This also
  10412. + flushes the work queue */
  10413. + ICP_WORKQUEUE_DESTROY(icp_ocfDrvFreeLacSessionWorkQ);
  10414. +
  10415. + /*ENTER CRITICAL SECTION */
  10416. + icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
  10417. +
  10418. + ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,
  10419. + &icp_ocfDrvGlobalSymListHead, listNode) {
  10420. + for (i = 0; i < num_dereg_retries; i++) {
  10421. + /*No harm if bad input - LAC will handle error cases */
  10422. + if (ICP_SESSION_RUNNING == tempSessionData->inUse) {
  10423. + lacStatus =
  10424. + cpaCySymRemoveSession
  10425. + (CPA_INSTANCE_HANDLE_SINGLE,
  10426. + tempSessionData->sessHandle);
  10427. + if (CPA_STATUS_SUCCESS == lacStatus) {
  10428. + /* Succesfully deregistered */
  10429. + break;
  10430. + } else if (CPA_STATUS_RETRY != lacStatus) {
  10431. + icp_atomic_inc
  10432. + (&lac_session_failed_dereg_count);
  10433. + break;
  10434. + }
  10435. +
  10436. + /*schedule_timout returns the time left for completion if
  10437. + * this task is set to TASK_INTERRUPTIBLE */
  10438. + remaining_delay_time_in_jiffies =
  10439. + dereg_retry_delay_in_jiffies;
  10440. + while (0 > remaining_delay_time_in_jiffies) {
  10441. + remaining_delay_time_in_jiffies =
  10442. + icp_schedule_timeout
  10443. + (&icp_ocfDrvSymSessInfoListSpinlock,
  10444. + remaining_delay_time_in_jiffies);
  10445. + }
  10446. +
  10447. + DPRINTK
  10448. + ("%s(): Retry %d to deregistrate the session\n",
  10449. + __FUNCTION__, i);
  10450. + }
  10451. + }
  10452. +
  10453. + /*remove from current list */
  10454. + ICP_LIST_DEL(tempSessionData, listNode);
  10455. + /*add to free mem linked list */
  10456. + ICP_LIST_ADD(tempSessionData,
  10457. + &icp_ocfDrvGlobalSymListHead_FreeMemList,
  10458. + listNode);
  10459. +
  10460. + }
  10461. +
  10462. + /*EXIT CRITICAL SECTION */
  10463. + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  10464. +
  10465. + /*set back to initial values */
  10466. + sessionData = NULL;
  10467. + /*still have a reference in our list! */
  10468. + tempSessionData = NULL;
  10469. + /*free memory */
  10470. +
  10471. + ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,
  10472. + &icp_ocfDrvGlobalSymListHead_FreeMemList,
  10473. + listNode) {
  10474. +
  10475. + ICP_LIST_DEL(tempSessionData, listNode);
  10476. + /* Free allocated CpaCySymSessionCtx */
  10477. + if (NULL != tempSessionData->sessHandle) {
  10478. + icp_kfree(tempSessionData->sessHandle);
  10479. + }
  10480. + memset(tempSessionData, 0, sizeof(struct icp_drvSessionData));
  10481. + ICP_CACHE_FREE(drvSessionData_zone, tempSessionData);
  10482. + }
  10483. +
  10484. + if (0 != icp_atomic_read(&lac_session_failed_dereg_count)) {
  10485. + DPRINTK("%s(): %d LAC sessions were not deregistered "
  10486. + "correctly. This is not a clean exit! \n",
  10487. + __FUNCTION__,
  10488. + icp_atomic_read(&lac_session_failed_dereg_count));
  10489. + }
  10490. +
  10491. + icp_ocfDrvFreeCaches();
  10492. + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  10493. +
  10494. + icp_spin_lock_destroy(&icp_ocfDrvSymSessInfoListSpinlock);
  10495. +
  10496. + /* Shutdown the Cryptographic component */
  10497. + lacStatus = cpaCyStopInstance(CPA_INSTANCE_HANDLE_SINGLE);
  10498. + if (CPA_STATUS_SUCCESS != lacStatus) {
  10499. + DPRINTK("%s(): Failed to stop instance of the "
  10500. + "Cryptographic component.(status == %d)\n",
  10501. + __FUNCTION__, lacStatus);
  10502. + }
  10503. +
  10504. + return ICP_MODULE_EXIT_FUNC_RETURN_VAL;
  10505. +}
  10506. +
  10507. +/* Name : icp_ocfDrvFreeCaches
  10508. + *
  10509. + * Description : This function deregisters all slab caches
  10510. + */
  10511. +static void icp_ocfDrvFreeCaches(void)
  10512. +{
  10513. + icp_atomic_set(&icp_ocfDrvIsExiting, 1);
  10514. +
  10515. + /*Sym Zones */
  10516. + ICP_CACHE_DESTROY(drvSessionData_zone);
  10517. + ICP_CACHE_DESTROY(drvOpData_zone);
  10518. +
  10519. + /*Asym zones */
  10520. + ICP_CACHE_DESTROY(drvDH_zone);
  10521. + ICP_CACHE_DESTROY(drvLnModExp_zone);
  10522. + ICP_CACHE_DESTROY(drvRSADecrypt_zone);
  10523. + ICP_CACHE_DESTROY(drvRSAPrivateKey_zone);
  10524. + ICP_CACHE_DESTROY(drvDSARSSignKValue_zone);
  10525. + ICP_CACHE_DESTROY(drvDSARSSign_zone);
  10526. + ICP_CACHE_DESTROY(drvDSAVerify_zone);
  10527. +
  10528. + /*FlatBuffer and BufferList Zones */
  10529. + ICP_CACHE_DESTROY(drvFlatBuffer_zone);
  10530. +
  10531. +}
  10532. +
  10533. +/* Name : icp_ocfDrvDeregRetry
  10534. + *
  10535. + * Description : This function will try to farm the session deregistration
  10536. + * off to a work queue. If it fails, nothing more can be done and it
  10537. + * returns an error
  10538. + */
  10539. +int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister)
  10540. +{
  10541. + struct icp_ocfDrvFreeLacSession *workstore = NULL;
  10542. +
  10543. + DPRINTK("%s(): Retry - Deregistering session (%p)\n",
  10544. + __FUNCTION__, sessionToDeregister);
  10545. +
  10546. + /*make sure the session is not available to be allocated during this
  10547. + process */
  10548. + icp_atomic_inc(&lac_session_failed_dereg_count);
  10549. +
  10550. + /*Farm off to work queue */
  10551. + workstore =
  10552. + icp_kmalloc(sizeof(struct icp_ocfDrvFreeLacSession), ICP_M_NOWAIT);
  10553. + if (NULL == workstore) {
  10554. + DPRINTK("%s(): unable to free session - no memory available "
  10555. + "for work queue\n", __FUNCTION__);
  10556. + return ENOMEM;
  10557. + }
  10558. +
  10559. + workstore->sessionToDeregister = sessionToDeregister;
  10560. +
  10561. + icp_init_work(&(workstore->work),
  10562. + icp_ocfDrvDeferedFreeLacSessionTaskFn, workstore);
  10563. +
  10564. + ICP_WORKQUEUE_ENQUEUE(icp_ocfDrvFreeLacSessionWorkQ,
  10565. + &(workstore->work));
  10566. +
  10567. + return ICP_OCF_DRV_STATUS_SUCCESS;
  10568. +
  10569. +}
  10570. +
  10571. +/* Name : icp_ocfDrvDeferedFreeLacSessionProcess
  10572. + *
  10573. + * Description : This function will retry (module input parameter)
  10574. + * 'num_dereg_retries' times to deregister any symmetric session that recieves a
  10575. + * CPA_STATUS_RETRY message from the LAC component. This function is run in
  10576. + * Thread context because it is called from a worker thread
  10577. + */
  10578. +void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg)
  10579. +{
  10580. + struct icp_ocfDrvFreeLacSession *workstore = NULL;
  10581. + CpaCySymSessionCtx sessionToDeregister = NULL;
  10582. + int i = 0;
  10583. + int remaining_delay_time_in_jiffies = 0;
  10584. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  10585. +
  10586. + workstore = (struct icp_ocfDrvFreeLacSession *)arg;
  10587. + if (NULL == workstore) {
  10588. + DPRINTK("%s() function called with null parameter \n",
  10589. + __FUNCTION__);
  10590. + return;
  10591. + }
  10592. +
  10593. + sessionToDeregister = workstore->sessionToDeregister;
  10594. + icp_kfree(workstore);
  10595. +
  10596. + /*if exiting, give deregistration one more blast only */
  10597. + if (icp_atomic_read(&icp_ocfDrvIsExiting) == CPA_TRUE) {
  10598. + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  10599. + sessionToDeregister);
  10600. +
  10601. + if (lacStatus != CPA_STATUS_SUCCESS) {
  10602. + DPRINTK("%s() Failed to Dereg LAC session %p "
  10603. + "during module exit\n", __FUNCTION__,
  10604. + sessionToDeregister);
  10605. + return;
  10606. + }
  10607. +
  10608. + icp_atomic_dec(&lac_session_failed_dereg_count);
  10609. + return;
  10610. + }
  10611. +
  10612. + for (i = 0; i <= num_dereg_retries; i++) {
  10613. + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  10614. + sessionToDeregister);
  10615. +
  10616. + if (lacStatus == CPA_STATUS_SUCCESS) {
  10617. + icp_atomic_dec(&lac_session_failed_dereg_count);
  10618. + return;
  10619. + }
  10620. + if (lacStatus != CPA_STATUS_RETRY) {
  10621. + DPRINTK("%s() Failed to deregister session - lacStatus "
  10622. + " = %d", __FUNCTION__, lacStatus);
  10623. + break;
  10624. + }
  10625. +
  10626. + /*schedule_timout returns the time left for completion if this
  10627. + task is set to TASK_INTERRUPTIBLE */
  10628. + remaining_delay_time_in_jiffies = dereg_retry_delay_in_jiffies;
  10629. + while (0 < remaining_delay_time_in_jiffies) {
  10630. + remaining_delay_time_in_jiffies =
  10631. + icp_schedule_timeout(NULL,
  10632. + remaining_delay_time_in_jiffies);
  10633. + }
  10634. +
  10635. + }
  10636. +
  10637. + DPRINTK("%s(): Unable to deregister session\n", __FUNCTION__);
  10638. + DPRINTK("%s(): Number of unavailable LAC sessions = %d\n", __FUNCTION__,
  10639. + icp_atomic_read(&lac_session_failed_dereg_count));
  10640. +}
  10641. +
  10642. +/* Name : icp_ocfDrvPtrAndLenToFlatBuffer
  10643. + *
  10644. + * Description : This function converts a "pointer and length" buffer
  10645. + * structure to Fredericksburg Flat Buffer (CpaFlatBuffer) format.
  10646. + *
  10647. + * This function assumes that the data passed in are valid.
  10648. + */
  10649. +inline void
  10650. +icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
  10651. + CpaFlatBuffer * pFlatBuffer)
  10652. +{
  10653. + pFlatBuffer->pData = pData;
  10654. + pFlatBuffer->dataLenInBytes = len;
  10655. +}
  10656. +
  10657. +/* Name : icp_ocfDrvPtrAndLenToBufferList
  10658. + *
  10659. + * Description : This function converts a "pointer and length" buffer
  10660. + * structure to Fredericksburg Scatter/Gather Buffer (CpaBufferList) format.
  10661. + *
  10662. + * This function assumes that the data passed in are valid.
  10663. + */
  10664. +inline void
  10665. +icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
  10666. + CpaBufferList * pBufferList)
  10667. +{
  10668. + pBufferList->numBuffers = 1;
  10669. + pBufferList->pBuffers->pData = pDataIn;
  10670. + pBufferList->pBuffers->dataLenInBytes = length;
  10671. +}
  10672. +
  10673. +/* Name : icp_ocfDrvBufferListToPtrAndLen
  10674. + *
  10675. + * Description : This function converts Fredericksburg Scatter/Gather Buffer
  10676. + * (CpaBufferList) format to a "pointer and length" buffer structure.
  10677. + *
  10678. + * This function assumes that the data passed in are valid.
  10679. + */
  10680. +inline void
  10681. +icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
  10682. + void **ppDataOut, uint32_t * pLength)
  10683. +{
  10684. + *ppDataOut = pBufferList->pBuffers->pData;
  10685. + *pLength = pBufferList->pBuffers->dataLenInBytes;
  10686. +}
  10687. +
  10688. +/* Name : icp_ocfDrvBufferListMemInfo
  10689. + *
  10690. + * Description : This function will set the number of flat buffers in
  10691. + * bufferlist, the size of memory to allocate for the pPrivateMetaData
  10692. + * member of the CpaBufferList.
  10693. + */
  10694. +int
  10695. +icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
  10696. + struct icp_drvBuffListInfo *buffListInfo)
  10697. +{
  10698. + buffListInfo->numBuffers = numBuffers;
  10699. +
  10700. + if (CPA_STATUS_SUCCESS !=
  10701. + cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
  10702. + buffListInfo->numBuffers,
  10703. + &(buffListInfo->metaSize))) {
  10704. + EPRINTK("%s() Failed to get buffer list meta size.\n",
  10705. + __FUNCTION__);
  10706. + return ICP_OCF_DRV_STATUS_FAIL;
  10707. + }
  10708. +
  10709. + return ICP_OCF_DRV_STATUS_SUCCESS;
  10710. +}
  10711. +
  10712. +/* Name : icp_ocfDrvFreeFlatBuffer
  10713. + *
  10714. + * Description : This function will deallocate flat buffer.
  10715. + */
  10716. +inline void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer)
  10717. +{
  10718. + if (pFlatBuffer != NULL) {
  10719. + memset(pFlatBuffer, 0, sizeof(CpaFlatBuffer));
  10720. + ICP_CACHE_FREE(drvFlatBuffer_zone, pFlatBuffer);
  10721. + }
  10722. +}
  10723. +
  10724. +/* Name : icp_ocfDrvAllocMetaData
  10725. + *
  10726. + * Description : This function will allocate memory for the
  10727. + * pPrivateMetaData member of CpaBufferList.
  10728. + */
  10729. +inline int
  10730. +icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
  10731. + struct icp_drvOpData *pOpData)
  10732. +{
  10733. + Cpa32U metaSize = 0;
  10734. +
  10735. + if (pBufferList->numBuffers <= ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  10736. + uint8_t *pOpDataStartAddr = (uint8_t *) pOpData;
  10737. +
  10738. + if (0 == defBuffListInfo.metaSize) {
  10739. + pBufferList->pPrivateMetaData = NULL;
  10740. + return ICP_OCF_DRV_STATUS_SUCCESS;
  10741. + }
  10742. + /*
  10743. + * The meta data allocation has been included as part of the
  10744. + * op data. It has been pre-allocated in memory just after the
  10745. + * icp_drvOpData structure.
  10746. + */
  10747. + pBufferList->pPrivateMetaData = (void *)(pOpDataStartAddr +
  10748. + sizeof(struct
  10749. + icp_drvOpData));
  10750. + } else {
  10751. + if (CPA_STATUS_SUCCESS !=
  10752. + cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
  10753. + pBufferList->numBuffers,
  10754. + &metaSize)) {
  10755. + EPRINTK("%s() Failed to get buffer list meta size.\n",
  10756. + __FUNCTION__);
  10757. + return ICP_OCF_DRV_STATUS_FAIL;
  10758. + }
  10759. +
  10760. + if (0 == metaSize) {
  10761. + pBufferList->pPrivateMetaData = NULL;
  10762. + return ICP_OCF_DRV_STATUS_SUCCESS;
  10763. + }
  10764. +
  10765. + pBufferList->pPrivateMetaData =
  10766. + icp_kmalloc(metaSize, ICP_M_NOWAIT);
  10767. + }
  10768. + if (NULL == pBufferList->pPrivateMetaData) {
  10769. + EPRINTK("%s() Failed to allocate pPrivateMetaData.\n",
  10770. + __FUNCTION__);
  10771. + return ICP_OCF_DRV_STATUS_FAIL;
  10772. + }
  10773. +
  10774. + return ICP_OCF_DRV_STATUS_SUCCESS;
  10775. +}
  10776. +
  10777. +/* Name : icp_ocfDrvFreeMetaData
  10778. + *
  10779. + * Description : This function will deallocate pPrivateMetaData memory.
  10780. + */
  10781. +inline void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList)
  10782. +{
  10783. + if (NULL == pBufferList->pPrivateMetaData) {
  10784. + return;
  10785. + }
  10786. +
  10787. + /*
  10788. + * Only free the meta data if the BufferList has more than
  10789. + * ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS number of buffers.
  10790. + * Otherwise, the meta data shall be freed when the icp_drvOpData is
  10791. + * freed.
  10792. + */
  10793. + if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < pBufferList->numBuffers) {
  10794. + icp_kfree(pBufferList->pPrivateMetaData);
  10795. + }
  10796. +}
  10797. +
  10798. +/* Module declaration, init and exit functions */
  10799. +ICP_DECLARE_MODULE(icp_ocf, icp_ocfDrvInit, icp_ocfDrvExit);
  10800. +ICP_MODULE_DESCRIPTION("OCF Driver for Intel Quick Assist crypto acceleration");
  10801. +ICP_MODULE_VERSION(icp_ocf, ICP_OCF_VER_MJR);
  10802. +ICP_MODULE_LICENSE("Dual BSD/GPL");
  10803. +ICP_MODULE_AUTHOR("Intel");
  10804. +
  10805. +/* Module parameters */
  10806. +ICP_MODULE_PARAM_INT(icp_ocf, num_dereg_retries,
  10807. + "Number of times to retry LAC Sym Session Deregistration. "
  10808. + "Default 10, Max 100");
  10809. +ICP_MODULE_PARAM_INT(icp_ocf, dereg_retry_delay_in_jiffies, "Delay in jiffies "
  10810. + "(added to a schedule() function call) before a LAC Sym "
  10811. + "Session Dereg is retried. Default 10");
  10812. +ICP_MODULE_PARAM_INT(icp_ocf, max_sessions,
  10813. + "This sets the maximum number of sessions "
  10814. + "between OCF and this driver. If this value is set to zero,"
  10815. + "max session count checking is disabled. Default is zero(0)");
  10816. +
  10817. +/* Module dependencies */
  10818. +#define MODULE_MIN_VER 1
  10819. +#define CRYPTO_MAX_VER 3
  10820. +#define LAC_MAX_VER 2
  10821. +
  10822. +ICP_MODULE_DEPEND(icp_ocf, crypto, MODULE_MIN_VER, MODULE_MIN_VER,
  10823. + CRYPTO_MAX_VER);
  10824. +ICP_MODULE_DEPEND(icp_ocf, cryptodev, MODULE_MIN_VER, MODULE_MIN_VER,
  10825. + CRYPTO_MAX_VER);
  10826. +ICP_MODULE_DEPEND(icp_ocf, icp_crypto, MODULE_MIN_VER, MODULE_MIN_VER,
  10827. + LAC_MAX_VER);
  10828. diff -Nur linux-2.6.35.orig/crypto/ocf/ep80579/icp_ocf.h linux-2.6.35/crypto/ocf/ep80579/icp_ocf.h
  10829. --- linux-2.6.35.orig/crypto/ocf/ep80579/icp_ocf.h 1970-01-01 01:00:00.000000000 +0100
  10830. +++ linux-2.6.35/crypto/ocf/ep80579/icp_ocf.h 2010-08-05 22:02:08.604056628 +0200
  10831. @@ -0,0 +1,376 @@
  10832. +/***************************************************************************
  10833. + *
  10834. + * This file is provided under a dual BSD/GPLv2 license. When using or
  10835. + * redistributing this file, you may do so under either license.
  10836. + *
  10837. + * GPL LICENSE SUMMARY
  10838. + *
  10839. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  10840. + *
  10841. + * This program is free software; you can redistribute it and/or modify
  10842. + * it under the terms of version 2 of the GNU General Public License as
  10843. + * published by the Free Software Foundation.
  10844. + *
  10845. + * This program is distributed in the hope that it will be useful, but
  10846. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  10847. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10848. + * General Public License for more details.
  10849. + *
  10850. + * You should have received a copy of the GNU General Public License
  10851. + * along with this program; if not, write to the Free Software
  10852. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  10853. + * The full GNU General Public License is included in this distribution
  10854. + * in the file called LICENSE.GPL.
  10855. + *
  10856. + * Contact Information:
  10857. + * Intel Corporation
  10858. + *
  10859. + * BSD LICENSE
  10860. + *
  10861. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  10862. + * All rights reserved.
  10863. + *
  10864. + * Redistribution and use in source and binary forms, with or without
  10865. + * modification, are permitted provided that the following conditions
  10866. + * are met:
  10867. + *
  10868. + * * Redistributions of source code must retain the above copyright
  10869. + * notice, this list of conditions and the following disclaimer.
  10870. + * * Redistributions in binary form must reproduce the above copyright
  10871. + * notice, this list of conditions and the following disclaimer in
  10872. + * the documentation and/or other materials provided with the
  10873. + * distribution.
  10874. + * * Neither the name of Intel Corporation nor the names of its
  10875. + * contributors may be used to endorse or promote products derived
  10876. + * from this software without specific prior written permission.
  10877. + *
  10878. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  10879. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  10880. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  10881. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  10882. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10883. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  10884. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10885. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  10886. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  10887. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  10888. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  10889. + *
  10890. + *
  10891. + * version: Security.L.1.0.2-229
  10892. + *
  10893. + ***************************************************************************/
  10894. +
  10895. +/*
  10896. + * OCF driver header file for the Intel ICP processor.
  10897. + */
  10898. +
  10899. +#ifndef ICP_OCF_H_
  10900. +#define ICP_OCF_H_
  10901. +
  10902. +#include <cpa.h>
  10903. +#include <cpa_cy_im.h>
  10904. +#include <cpa_cy_sym.h>
  10905. +#include <cpa_cy_rand.h>
  10906. +#include <cpa_cy_dh.h>
  10907. +#include <cpa_cy_rsa.h>
  10908. +#include <cpa_cy_ln.h>
  10909. +#include <cpa_cy_common.h>
  10910. +#include <cpa_cy_dsa.h>
  10911. +
  10912. +#include "icp_os.h"
  10913. +
  10914. +#define NUM_BITS_IN_BYTE (8)
  10915. +#define NUM_BITS_IN_BYTE_MINUS_ONE (NUM_BITS_IN_BYTE -1)
  10916. +#define INVALID_DRIVER_ID (-1)
  10917. +#define RETURN_RAND_NUM_GEN_FAILED (-1)
  10918. +
  10919. +/*This is the max block cipher initialisation vector*/
  10920. +#define MAX_IV_LEN_IN_BYTES (20)
  10921. +/*This is used to check whether the OCF to this driver session limit has
  10922. + been disabled*/
  10923. +#define NO_OCF_TO_DRV_MAX_SESSIONS (0)
  10924. +
  10925. +/*OCF values mapped here*/
  10926. +#define ICP_SHA1_DIGEST_SIZE_IN_BYTES (SHA1_HASH_LEN)
  10927. +#define ICP_SHA256_DIGEST_SIZE_IN_BYTES (SHA2_256_HASH_LEN)
  10928. +#define ICP_SHA384_DIGEST_SIZE_IN_BYTES (SHA2_384_HASH_LEN)
  10929. +#define ICP_SHA512_DIGEST_SIZE_IN_BYTES (SHA2_512_HASH_LEN)
  10930. +#define ICP_MD5_DIGEST_SIZE_IN_BYTES (MD5_HASH_LEN)
  10931. +#define ARC4_COUNTER_LEN (ARC4_BLOCK_LEN)
  10932. +
  10933. +#define OCF_REGISTRATION_STATUS_SUCCESS (0)
  10934. +#define OCF_ZERO_FUNCTIONALITY_REGISTERED (0)
  10935. +#define ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR (0)
  10936. +#define ICP_OCF_DRV_STATUS_SUCCESS (0)
  10937. +#define ICP_OCF_DRV_STATUS_FAIL (1)
  10938. +
  10939. +/*Turn on/off debug options*/
  10940. +#define ICP_OCF_PRINT_DEBUG_MESSAGES (0)
  10941. +#define ICP_OCF_PRINT_KERN_ALERT (1)
  10942. +#define ICP_OCF_PRINT_KERN_ERRS (1)
  10943. +
  10944. +#if ICP_OCF_PRINT_DEBUG_MESSAGES == 1
  10945. +#define DPRINTK(args...) \
  10946. +{ \
  10947. + ICP_IPRINTK(args); \
  10948. +}
  10949. +
  10950. +#else //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
  10951. +
  10952. +#define DPRINTK(args...)
  10953. +
  10954. +#endif //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
  10955. +
  10956. +#if ICP_OCF_PRINT_KERN_ALERT == 1
  10957. +#define APRINTK(args...) \
  10958. +{ \
  10959. + ICP_APRINTK(args); \
  10960. +}
  10961. +
  10962. +#else //ICP_OCF_PRINT_KERN_ALERT == 1
  10963. +
  10964. +#define APRINTK(args...)
  10965. +
  10966. +#endif //ICP_OCF_PRINT_KERN_ALERT == 1
  10967. +
  10968. +#if ICP_OCF_PRINT_KERN_ERRS == 1
  10969. +#define EPRINTK(args...) \
  10970. +{ \
  10971. + ICP_EPRINTK(args); \
  10972. +}
  10973. +
  10974. +#else //ICP_OCF_PRINT_KERN_ERRS == 1
  10975. +
  10976. +#define EPRINTK(args...)
  10977. +
  10978. +#endif //ICP_OCF_PRINT_KERN_ERRS == 1
  10979. +
  10980. +#define IPRINTK(args...) \
  10981. +{ \
  10982. + ICP_IPRINTK(args); \
  10983. +}
  10984. +
  10985. +/*DSA Prime Q size in bytes (as defined in the standard) */
  10986. +#define DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES (20)
  10987. +
  10988. +#define BITS_TO_BYTES(bytes, bits) \
  10989. + bytes = (bits + NUM_BITS_IN_BYTE_MINUS_ONE) / NUM_BITS_IN_BYTE
  10990. +
  10991. +typedef enum {
  10992. + ICP_OCF_DRV_ALG_CIPHER = 0,
  10993. + ICP_OCF_DRV_ALG_HASH
  10994. +} icp_ocf_drv_alg_type_t;
  10995. +
  10996. +typedef ICP_LIST_HEAD(icp_drvSessionListHead_s,
  10997. + icp_drvSessionData) icp_drvSessionListHead_t;
  10998. +
  10999. +/*Values used to derisk chances of performs being called against
  11000. +deregistered sessions (for which the slab page has been reclaimed)
  11001. +This is not a fix - since page frames are reclaimed from a slab, one cannot
  11002. +rely on that memory not being re-used by another app.*/
  11003. +typedef enum {
  11004. + ICP_SESSION_INITIALISED = 0x5C5C5C,
  11005. + ICP_SESSION_RUNNING = 0x005C00,
  11006. + ICP_SESSION_DEREGISTERED = 0xC5C5C5
  11007. +} usage_derisk;
  11008. +
  11009. +/* This struct is required for deferred session
  11010. + deregistration as a work queue function can
  11011. + only have one argument*/
  11012. +struct icp_ocfDrvFreeLacSession {
  11013. + CpaCySymSessionCtx sessionToDeregister;
  11014. + icp_workstruct work;
  11015. +};
  11016. +
  11017. +/*
  11018. +This is the OCF<->OCF_DRV session object:
  11019. +
  11020. +1.listNode
  11021. + The first member is a listNode. These session objects are added to a linked
  11022. + list in order to make it easier to remove them all at session exit time.
  11023. +
  11024. +2.inUse
  11025. + The second member is used to give the session object state and derisk the
  11026. + possibility of OCF batch calls executing against a deregistered session (as
  11027. + described above).
  11028. +
  11029. +3.sessHandle
  11030. + The third member is a LAC<->OCF_DRV session handle (initialised with the first
  11031. + perform request for that session).
  11032. +
  11033. +4.lacSessCtx
  11034. + The fourth is the LAC session context. All the parameters for this structure
  11035. + are only known when the first perform request for this session occurs. That is
  11036. + why the OCF EP80579 Driver only registers a new LAC session at perform time
  11037. +*/
  11038. +struct icp_drvSessionData {
  11039. + ICP_LIST_ENTRY(icp_drvSessionData) listNode;
  11040. + usage_derisk inUse;
  11041. + CpaCySymSessionCtx sessHandle;
  11042. + CpaCySymSessionSetupData lacSessCtx;
  11043. +};
  11044. +
  11045. +/* These are all defined in icp_common.c */
  11046. +extern icp_atomic_t lac_session_failed_dereg_count;
  11047. +extern icp_atomic_t icp_ocfDrvIsExiting;
  11048. +extern icp_atomic_t num_ocf_to_drv_registered_sessions;
  11049. +
  11050. +extern int32_t icp_ocfDrvDriverId;
  11051. +
  11052. +extern icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead;
  11053. +extern icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList;
  11054. +extern icp_workqueue *icp_ocfDrvFreeLacSessionWorkQ;
  11055. +extern icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock;
  11056. +
  11057. +/*Slab zones for symettric functionality, instantiated in icp_common.c*/
  11058. +extern icp_kmem_cache drvSessionData_zone;
  11059. +extern icp_kmem_cache drvOpData_zone;
  11060. +
  11061. +/*Slabs zones for asymettric functionality, instantiated in icp_common.c*/
  11062. +extern icp_kmem_cache drvDH_zone;
  11063. +extern icp_kmem_cache drvLnModExp_zone;
  11064. +extern icp_kmem_cache drvRSADecrypt_zone;
  11065. +extern icp_kmem_cache drvRSAPrivateKey_zone;
  11066. +extern icp_kmem_cache drvDSARSSign_zone;
  11067. +extern icp_kmem_cache drvDSARSSignKValue_zone;
  11068. +extern icp_kmem_cache drvDSAVerify_zone;
  11069. +
  11070. +/* Module parameters defined in icp_cpmmon.c*/
  11071. +
  11072. +/* Module parameters - gives the number of times LAC deregistration shall be
  11073. + re-tried */
  11074. +extern int num_dereg_retries;
  11075. +
  11076. +/* Module parameter - gives the delay time in jiffies before a LAC session
  11077. + shall be attempted to be deregistered again */
  11078. +extern int dereg_retry_delay_in_jiffies;
  11079. +
  11080. +/* Module parameter - gives the maximum number of sessions possible between
  11081. + OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/
  11082. +extern int max_sessions;
  11083. +
  11084. +/*Slab zones for flatbuffers and bufferlist*/
  11085. +extern icp_kmem_cache drvFlatBuffer_zone;
  11086. +
  11087. +#define ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS (16)
  11088. +
  11089. +struct icp_drvBuffListInfo {
  11090. + Cpa16U numBuffers;
  11091. + Cpa32U metaSize;
  11092. + Cpa32U metaOffset;
  11093. + Cpa32U buffListSize;
  11094. +};
  11095. +
  11096. +extern struct icp_drvBuffListInfo defBuffListInfo;
  11097. +
  11098. +/* This struct is used to keep a reference to the relevant node in the list
  11099. + of sessionData structs, to the buffer type required by OCF and to the OCF
  11100. + provided crp struct that needs to be returned. All this info is needed in
  11101. + the callback function.*/
  11102. +struct icp_drvOpData {
  11103. + CpaCySymOpData lacOpData;
  11104. + uint32_t digestSizeInBytes;
  11105. + struct cryptop *crp;
  11106. + uint8_t bufferType;
  11107. + uint8_t ivData[MAX_IV_LEN_IN_BYTES];
  11108. + uint16_t numBufferListArray;
  11109. + CpaBufferList srcBuffer;
  11110. + CpaFlatBuffer bufferListArray[ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS];
  11111. + CpaBoolean verifyResult;
  11112. +};
  11113. +
  11114. +/* Create a new session between OCF and this driver*/
  11115. +int icp_ocfDrvNewSession(icp_device_t dev, uint32_t * sild,
  11116. + struct cryptoini *cri);
  11117. +
  11118. +/* Free a session between this driver and the Quick Assist Framework*/
  11119. +int icp_ocfDrvFreeLACSession(icp_device_t dev, uint64_t sid);
  11120. +
  11121. +/* Defer freeing a Quick Assist session*/
  11122. +void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg);
  11123. +
  11124. +/* Process OCF cryptographic request for a symmetric algorithm*/
  11125. +int icp_ocfDrvSymProcess(icp_device_t dev, struct cryptop *crp, int hint);
  11126. +
  11127. +/* Process OCF cryptographic request for an asymmetric algorithm*/
  11128. +int icp_ocfDrvPkeProcess(icp_device_t dev, struct cryptkop *krp, int hint);
  11129. +
  11130. +/* Populate a buffer with random data*/
  11131. +int icp_ocfDrvReadRandom(void *arg, uint32_t * buf, int maxwords);
  11132. +
  11133. +/* Retry Quick Assist session deregistration*/
  11134. +int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister);
  11135. +
  11136. +/* Convert an OS scatter gather list to a CPA buffer list*/
  11137. +int icp_ocfDrvPacketBuffToBufferList(icp_packet_buffer_t * pPacketBuffer,
  11138. + CpaBufferList * bufferList);
  11139. +
  11140. +/* Convert a CPA buffer list to an OS scatter gather list*/
  11141. +int icp_ocfDrvBufferListToPacketBuff(CpaBufferList * bufferList,
  11142. + icp_packet_buffer_t ** pPacketBuffer);
  11143. +
  11144. +/* Get the number of buffers in an OS scatter gather list*/
  11145. +uint16_t icp_ocfDrvGetPacketBuffFrags(icp_packet_buffer_t * pPacketBuffer);
  11146. +
  11147. +/* Convert a single OS buffer to a CPA Flat Buffer*/
  11148. +void icp_ocfDrvSinglePacketBuffToFlatBuffer(icp_packet_buffer_t * pPacketBuffer,
  11149. + CpaFlatBuffer * pFlatBuffer);
  11150. +
  11151. +/* Add pointer and length to a CPA Flat Buffer structure*/
  11152. +void icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
  11153. + CpaFlatBuffer * pFlatBuffer);
  11154. +
  11155. +/* Convert pointer and length values to a CPA buffer list*/
  11156. +void icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
  11157. + CpaBufferList * pBufferList);
  11158. +
  11159. +/* Convert a CPA buffer list to pointer and length values*/
  11160. +void icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
  11161. + void **ppDataOut, uint32_t * pLength);
  11162. +
  11163. +/* Set the number of flat buffers in bufferlist and the size of memory
  11164. + to allocate for the pPrivateMetaData member of the CpaBufferList.*/
  11165. +int icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
  11166. + struct icp_drvBuffListInfo *buffListInfo);
  11167. +
  11168. +/* Find pointer position of the digest within an OS scatter gather list*/
  11169. +uint8_t *icp_ocfDrvPacketBufferDigestPointerFind(struct icp_drvOpData
  11170. + *drvOpData,
  11171. + int offsetInBytes,
  11172. + uint32_t digestSizeInBytes);
  11173. +
  11174. +/*This top level function is used to find a pointer to where a digest is
  11175. + stored/needs to be inserted. */
  11176. +uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData *drvOpData,
  11177. + struct cryptodesc *crp_desc);
  11178. +
  11179. +/* Free a CPA flat buffer*/
  11180. +void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer);
  11181. +
  11182. +/* This function will allocate memory for the pPrivateMetaData
  11183. + member of CpaBufferList. */
  11184. +int icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
  11185. + struct icp_drvOpData *pOpData);
  11186. +
  11187. +/* Free data allocated for the pPrivateMetaData
  11188. + member of CpaBufferList.*/
  11189. +void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList);
  11190. +
  11191. +#define ICP_CACHE_CREATE(cache_ID, cache_name) \
  11192. + icp_kmem_cache_create(cache_ID, sizeof(cache_name),ICP_KERNEL_CACHE_ALIGN,\
  11193. + ICP_KERNEL_CACHE_NOINIT)
  11194. +
  11195. +#define ICP_CACHE_FREE(args...) \
  11196. + icp_kmem_cache_free (args)
  11197. +
  11198. +#define ICP_CACHE_DESTROY(slab_zone)\
  11199. +{\
  11200. + if(NULL != slab_zone){\
  11201. + icp_kmem_cache_destroy(slab_zone);\
  11202. + slab_zone = NULL;\
  11203. + }\
  11204. +}
  11205. +
  11206. +#endif
  11207. +/* ICP_OCF_H_ */
  11208. diff -Nur linux-2.6.35.orig/crypto/ocf/ep80579/icp_sym.c linux-2.6.35/crypto/ocf/ep80579/icp_sym.c
  11209. --- linux-2.6.35.orig/crypto/ocf/ep80579/icp_sym.c 1970-01-01 01:00:00.000000000 +0100
  11210. +++ linux-2.6.35/crypto/ocf/ep80579/icp_sym.c 2010-08-05 22:02:08.804353174 +0200
  11211. @@ -0,0 +1,1153 @@
  11212. +/***************************************************************************
  11213. + *
  11214. + * This file is provided under a dual BSD/GPLv2 license. When using or
  11215. + * redistributing this file, you may do so under either license.
  11216. + *
  11217. + * GPL LICENSE SUMMARY
  11218. + *
  11219. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  11220. + *
  11221. + * This program is free software; you can redistribute it and/or modify
  11222. + * it under the terms of version 2 of the GNU General Public License as
  11223. + * published by the Free Software Foundation.
  11224. + *
  11225. + * This program is distributed in the hope that it will be useful, but
  11226. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  11227. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11228. + * General Public License for more details.
  11229. + *
  11230. + * You should have received a copy of the GNU General Public License
  11231. + * along with this program; if not, write to the Free Software
  11232. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  11233. + * The full GNU General Public License is included in this distribution
  11234. + * in the file called LICENSE.GPL.
  11235. + *
  11236. + * Contact Information:
  11237. + * Intel Corporation
  11238. + *
  11239. + * BSD LICENSE
  11240. + *
  11241. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  11242. + * All rights reserved.
  11243. + *
  11244. + * Redistribution and use in source and binary forms, with or without
  11245. + * modification, are permitted provided that the following conditions
  11246. + * are met:
  11247. + *
  11248. + * * Redistributions of source code must retain the above copyright
  11249. + * notice, this list of conditions and the following disclaimer.
  11250. + * * Redistributions in binary form must reproduce the above copyright
  11251. + * notice, this list of conditions and the following disclaimer in
  11252. + * the documentation and/or other materials provided with the
  11253. + * distribution.
  11254. + * * Neither the name of Intel Corporation nor the names of its
  11255. + * contributors may be used to endorse or promote products derived
  11256. + * from this software without specific prior written permission.
  11257. + *
  11258. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  11259. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  11260. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  11261. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  11262. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  11263. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11264. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  11265. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11266. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  11267. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  11268. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  11269. + *
  11270. + *
  11271. + * version: Security.L.1.0.2-229
  11272. + *
  11273. + ***************************************************************************/
  11274. +/*
  11275. + * An OCF module that uses the API for Intel® QuickAssist Technology to do the
  11276. + * cryptography.
  11277. + *
  11278. + * This driver requires the ICP Access Library that is available from Intel in
  11279. + * order to operate.
  11280. + */
  11281. +
  11282. +#include "icp_ocf.h"
  11283. +
  11284. +/*This is the call back function for all symmetric cryptographic processes.
  11285. + Its main functionality is to free driver crypto operation structure and to
  11286. + call back to OCF*/
  11287. +static void
  11288. +icp_ocfDrvSymCallBack(void *callbackTag,
  11289. + CpaStatus status,
  11290. + const CpaCySymOp operationType,
  11291. + void *pOpData,
  11292. + CpaBufferList * pDstBuffer, CpaBoolean verifyResult);
  11293. +
  11294. +/*This function is used to extract crypto processing information from the OCF
  11295. + inputs, so as that it may be passed onto LAC*/
  11296. +static int
  11297. +icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
  11298. + struct cryptodesc *crp_desc);
  11299. +
  11300. +/*This function checks whether the crp_desc argument pertains to a digest or a
  11301. + cipher operation*/
  11302. +static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc);
  11303. +
  11304. +/*This function copies all the passed in session context information and stores
  11305. + it in a LAC context structure*/
  11306. +static int
  11307. +icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
  11308. + CpaCySymSessionSetupData * lacSessCtx);
  11309. +
  11310. +/*This function is used to free an OCF->OCF_DRV session object*/
  11311. +static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData);
  11312. +
  11313. +/*max IOV buffs supported in a UIO structure*/
  11314. +#define NUM_IOV_SUPPORTED (1)
  11315. +
  11316. +/* Name : icp_ocfDrvSymCallBack
  11317. + *
  11318. + * Description : When this function returns it signifies that the LAC
  11319. + * component has completed the relevant symmetric operation.
  11320. + *
  11321. + * Notes : The callbackTag is a pointer to an icp_drvOpData. This memory
  11322. + * object was passed to LAC for the cryptographic processing and contains all
  11323. + * the relevant information for cleaning up buffer handles etc. so that the
  11324. + * OCF EP80579 Driver portion of this crypto operation can be fully completed.
  11325. + */
  11326. +static void
  11327. +icp_ocfDrvSymCallBack(void *callbackTag,
  11328. + CpaStatus status,
  11329. + const CpaCySymOp operationType,
  11330. + void *pOpData,
  11331. + CpaBufferList * pDstBuffer, CpaBoolean verifyResult)
  11332. +{
  11333. + struct cryptop *crp = NULL;
  11334. + struct icp_drvOpData *temp_drvOpData =
  11335. + (struct icp_drvOpData *)callbackTag;
  11336. + uint64_t *tempBasePtr = NULL;
  11337. + uint32_t tempLen = 0;
  11338. +
  11339. + if (NULL == temp_drvOpData) {
  11340. + DPRINTK("%s(): The callback from the LAC component"
  11341. + " has failed due to Null userOpaque data"
  11342. + "(status == %d).\n", __FUNCTION__, status);
  11343. + DPRINTK("%s(): Unable to call OCF back! \n", __FUNCTION__);
  11344. + return;
  11345. + }
  11346. +
  11347. + crp = temp_drvOpData->crp;
  11348. + crp->crp_etype = ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR;
  11349. +
  11350. + if (NULL == pOpData) {
  11351. + DPRINTK("%s(): The callback from the LAC component"
  11352. + " has failed due to Null Symmetric Op data"
  11353. + "(status == %d).\n", __FUNCTION__, status);
  11354. + crp->crp_etype = ECANCELED;
  11355. + crypto_done(crp);
  11356. + return;
  11357. + }
  11358. +
  11359. + if (NULL == pDstBuffer) {
  11360. + DPRINTK("%s(): The callback from the LAC component"
  11361. + " has failed due to Null Dst Bufferlist data"
  11362. + "(status == %d).\n", __FUNCTION__, status);
  11363. + crp->crp_etype = ECANCELED;
  11364. + crypto_done(crp);
  11365. + return;
  11366. + }
  11367. +
  11368. + if (CPA_STATUS_SUCCESS == status) {
  11369. +
  11370. + if (temp_drvOpData->bufferType == ICP_CRYPTO_F_PACKET_BUF) {
  11371. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  11372. + icp_ocfDrvBufferListToPacketBuff(pDstBuffer,
  11373. + (icp_packet_buffer_t
  11374. + **)
  11375. + & (crp->crp_buf))) {
  11376. + EPRINTK("%s(): BufferList to SkBuff "
  11377. + "conversion error.\n", __FUNCTION__);
  11378. + crp->crp_etype = EPERM;
  11379. + }
  11380. + } else {
  11381. + icp_ocfDrvBufferListToPtrAndLen(pDstBuffer,
  11382. + (void **)&tempBasePtr,
  11383. + &tempLen);
  11384. + crp->crp_olen = (int)tempLen;
  11385. + }
  11386. +
  11387. + } else {
  11388. + DPRINTK("%s(): The callback from the LAC component has failed"
  11389. + "(status == %d).\n", __FUNCTION__, status);
  11390. +
  11391. + crp->crp_etype = ECANCELED;
  11392. + }
  11393. +
  11394. + if (temp_drvOpData->numBufferListArray >
  11395. + ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  11396. + icp_kfree(pDstBuffer->pBuffers);
  11397. + }
  11398. + icp_ocfDrvFreeMetaData(pDstBuffer);
  11399. + ICP_CACHE_FREE(drvOpData_zone, temp_drvOpData);
  11400. +
  11401. + /* Invoke the OCF callback function */
  11402. + crypto_done(crp);
  11403. +
  11404. + return;
  11405. +}
  11406. +
  11407. +/* Name : icp_ocfDrvNewSession
  11408. + *
  11409. + * Description : This function will create a new Driver<->OCF session
  11410. + *
  11411. + * Notes : LAC session registration happens during the first perform call.
  11412. + * That is the first time we know all information about a given session.
  11413. + */
  11414. +int icp_ocfDrvNewSession(icp_device_t dev, uint32_t * sid,
  11415. + struct cryptoini *cri)
  11416. +{
  11417. + struct icp_drvSessionData *sessionData = NULL;
  11418. + uint32_t delete_session = 0;
  11419. +
  11420. + /* The SID passed in should be our driver ID. We can return the */
  11421. + /* local ID (LID) which is a unique identifier which we can use */
  11422. + /* to differentiate between the encrypt/decrypt LAC session handles */
  11423. + if (NULL == sid) {
  11424. + EPRINTK("%s(): Invalid input parameters - NULL sid.\n",
  11425. + __FUNCTION__);
  11426. + return EINVAL;
  11427. + }
  11428. +
  11429. + if (NULL == cri) {
  11430. + EPRINTK("%s(): Invalid input parameters - NULL cryptoini.\n",
  11431. + __FUNCTION__);
  11432. + return EINVAL;
  11433. + }
  11434. +
  11435. + if (icp_ocfDrvDriverId != *sid) {
  11436. + EPRINTK("%s(): Invalid input parameters - bad driver ID\n",
  11437. + __FUNCTION__);
  11438. + EPRINTK("\t sid = 0x08%p \n \t cri = 0x08%p \n", sid, cri);
  11439. + return EINVAL;
  11440. + }
  11441. +
  11442. + sessionData = icp_kmem_cache_zalloc(drvSessionData_zone, ICP_M_NOWAIT);
  11443. + if (NULL == sessionData) {
  11444. + DPRINTK("%s():No memory for Session Data\n", __FUNCTION__);
  11445. + return ENOMEM;
  11446. + }
  11447. +
  11448. + /*ENTER CRITICAL SECTION */
  11449. + icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
  11450. + /*put this check in the spinlock so no new sessions can be added to the
  11451. + linked list when we are exiting */
  11452. + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  11453. + delete_session++;
  11454. +
  11455. + } else if (NO_OCF_TO_DRV_MAX_SESSIONS != max_sessions) {
  11456. + if (icp_atomic_read(&num_ocf_to_drv_registered_sessions) >=
  11457. + (max_sessions -
  11458. + icp_atomic_read(&lac_session_failed_dereg_count))) {
  11459. + delete_session++;
  11460. + } else {
  11461. + icp_atomic_inc(&num_ocf_to_drv_registered_sessions);
  11462. + /* Add to session data linked list */
  11463. + ICP_LIST_ADD(sessionData, &icp_ocfDrvGlobalSymListHead,
  11464. + listNode);
  11465. + }
  11466. +
  11467. + } else if (NO_OCF_TO_DRV_MAX_SESSIONS == max_sessions) {
  11468. + ICP_LIST_ADD(sessionData, &icp_ocfDrvGlobalSymListHead,
  11469. + listNode);
  11470. + }
  11471. +
  11472. + sessionData->inUse = ICP_SESSION_INITIALISED;
  11473. +
  11474. + /*EXIT CRITICAL SECTION */
  11475. + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  11476. +
  11477. + if (delete_session) {
  11478. + DPRINTK("%s():No Session handles available\n", __FUNCTION__);
  11479. + ICP_CACHE_FREE(drvSessionData_zone, sessionData);
  11480. + return EPERM;
  11481. + }
  11482. +
  11483. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  11484. + icp_ocfDrvAlgorithmSetup(cri, &(sessionData->lacSessCtx))) {
  11485. + DPRINTK("%s():algorithm not supported\n", __FUNCTION__);
  11486. + icp_ocfDrvFreeOCFSession(sessionData);
  11487. + return EINVAL;
  11488. + }
  11489. +
  11490. + if (cri->cri_next) {
  11491. + if (cri->cri_next->cri_next != NULL) {
  11492. + DPRINTK("%s():only two chained algorithms supported\n",
  11493. + __FUNCTION__);
  11494. + icp_ocfDrvFreeOCFSession(sessionData);
  11495. + return EPERM;
  11496. + }
  11497. +
  11498. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  11499. + icp_ocfDrvAlgorithmSetup(cri->cri_next,
  11500. + &(sessionData->lacSessCtx))) {
  11501. + DPRINTK("%s():second algorithm not supported\n",
  11502. + __FUNCTION__);
  11503. + icp_ocfDrvFreeOCFSession(sessionData);
  11504. + return EINVAL;
  11505. + }
  11506. +
  11507. + sessionData->lacSessCtx.symOperation =
  11508. + CPA_CY_SYM_OP_ALGORITHM_CHAINING;
  11509. + }
  11510. +
  11511. + *sid = (uint32_t) sessionData;
  11512. +
  11513. + return ICP_OCF_DRV_STATUS_SUCCESS;
  11514. +}
  11515. +
  11516. +/* Name : icp_ocfDrvAlgorithmSetup
  11517. + *
  11518. + * Description : This function builds the session context data from the
  11519. + * information supplied through OCF. Algorithm chain order and whether the
  11520. + * session is Encrypt/Decrypt can only be found out at perform time however, so
  11521. + * the session is registered with LAC at that time.
  11522. + */
  11523. +static int
  11524. +icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
  11525. + CpaCySymSessionSetupData * lacSessCtx)
  11526. +{
  11527. +
  11528. + lacSessCtx->sessionPriority = CPA_CY_PRIORITY_NORMAL;
  11529. +
  11530. + switch (cri->cri_alg) {
  11531. +
  11532. + case CRYPTO_NULL_CBC:
  11533. + DPRINTK("%s(): NULL CBC\n", __FUNCTION__);
  11534. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  11535. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  11536. + CPA_CY_SYM_CIPHER_NULL;
  11537. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  11538. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11539. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  11540. + break;
  11541. +
  11542. + case CRYPTO_DES_CBC:
  11543. + DPRINTK("%s(): DES CBC\n", __FUNCTION__);
  11544. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  11545. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  11546. + CPA_CY_SYM_CIPHER_DES_CBC;
  11547. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  11548. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11549. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  11550. + break;
  11551. +
  11552. + case CRYPTO_3DES_CBC:
  11553. + DPRINTK("%s(): 3DES CBC\n", __FUNCTION__);
  11554. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  11555. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  11556. + CPA_CY_SYM_CIPHER_3DES_CBC;
  11557. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  11558. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11559. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  11560. + break;
  11561. +
  11562. + case CRYPTO_AES_CBC:
  11563. + DPRINTK("%s(): AES CBC\n", __FUNCTION__);
  11564. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  11565. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  11566. + CPA_CY_SYM_CIPHER_AES_CBC;
  11567. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  11568. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11569. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  11570. + break;
  11571. +
  11572. + case CRYPTO_ARC4:
  11573. + DPRINTK("%s(): ARC4\n", __FUNCTION__);
  11574. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  11575. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  11576. + CPA_CY_SYM_CIPHER_ARC4;
  11577. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  11578. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11579. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  11580. + break;
  11581. +
  11582. + case CRYPTO_SHA1:
  11583. + DPRINTK("%s(): SHA1\n", __FUNCTION__);
  11584. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11585. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
  11586. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  11587. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11588. + (cri->cri_mlen ?
  11589. + cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
  11590. +
  11591. + break;
  11592. +
  11593. + case CRYPTO_SHA1_HMAC:
  11594. + DPRINTK("%s(): SHA1_HMAC\n", __FUNCTION__);
  11595. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11596. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
  11597. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  11598. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11599. + (cri->cri_mlen ?
  11600. + cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
  11601. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  11602. + cri->cri_key;
  11603. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  11604. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11605. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  11606. +
  11607. + break;
  11608. +
  11609. + case CRYPTO_SHA2_256:
  11610. + DPRINTK("%s(): SHA256\n", __FUNCTION__);
  11611. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11612. + lacSessCtx->hashSetupData.hashAlgorithm =
  11613. + CPA_CY_SYM_HASH_SHA256;
  11614. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  11615. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11616. + (cri->cri_mlen ?
  11617. + cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
  11618. +
  11619. + break;
  11620. +
  11621. + case CRYPTO_SHA2_256_HMAC:
  11622. + DPRINTK("%s(): SHA256_HMAC\n", __FUNCTION__);
  11623. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11624. + lacSessCtx->hashSetupData.hashAlgorithm =
  11625. + CPA_CY_SYM_HASH_SHA256;
  11626. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  11627. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11628. + (cri->cri_mlen ?
  11629. + cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
  11630. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  11631. + cri->cri_key;
  11632. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  11633. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11634. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  11635. +
  11636. + break;
  11637. +
  11638. + case CRYPTO_SHA2_384:
  11639. + DPRINTK("%s(): SHA384\n", __FUNCTION__);
  11640. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11641. + lacSessCtx->hashSetupData.hashAlgorithm =
  11642. + CPA_CY_SYM_HASH_SHA384;
  11643. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  11644. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11645. + (cri->cri_mlen ?
  11646. + cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
  11647. +
  11648. + break;
  11649. +
  11650. + case CRYPTO_SHA2_384_HMAC:
  11651. + DPRINTK("%s(): SHA384_HMAC\n", __FUNCTION__);
  11652. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11653. + lacSessCtx->hashSetupData.hashAlgorithm =
  11654. + CPA_CY_SYM_HASH_SHA384;
  11655. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  11656. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11657. + (cri->cri_mlen ?
  11658. + cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
  11659. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  11660. + cri->cri_key;
  11661. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  11662. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11663. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  11664. +
  11665. + break;
  11666. +
  11667. + case CRYPTO_SHA2_512:
  11668. + DPRINTK("%s(): SHA512\n", __FUNCTION__);
  11669. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11670. + lacSessCtx->hashSetupData.hashAlgorithm =
  11671. + CPA_CY_SYM_HASH_SHA512;
  11672. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  11673. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11674. + (cri->cri_mlen ?
  11675. + cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
  11676. +
  11677. + break;
  11678. +
  11679. + case CRYPTO_SHA2_512_HMAC:
  11680. + DPRINTK("%s(): SHA512_HMAC\n", __FUNCTION__);
  11681. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11682. + lacSessCtx->hashSetupData.hashAlgorithm =
  11683. + CPA_CY_SYM_HASH_SHA512;
  11684. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  11685. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11686. + (cri->cri_mlen ?
  11687. + cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
  11688. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  11689. + cri->cri_key;
  11690. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  11691. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11692. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  11693. +
  11694. + break;
  11695. +
  11696. + case CRYPTO_MD5:
  11697. + DPRINTK("%s(): MD5\n", __FUNCTION__);
  11698. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11699. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
  11700. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  11701. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11702. + (cri->cri_mlen ?
  11703. + cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
  11704. +
  11705. + break;
  11706. +
  11707. + case CRYPTO_MD5_HMAC:
  11708. + DPRINTK("%s(): MD5_HMAC\n", __FUNCTION__);
  11709. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  11710. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
  11711. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  11712. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  11713. + (cri->cri_mlen ?
  11714. + cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
  11715. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  11716. + cri->cri_key;
  11717. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  11718. + cri->cri_klen / NUM_BITS_IN_BYTE;
  11719. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  11720. +
  11721. + break;
  11722. +
  11723. + default:
  11724. + DPRINTK("%s(): ALG Setup FAIL\n", __FUNCTION__);
  11725. + return ICP_OCF_DRV_STATUS_FAIL;
  11726. + }
  11727. +
  11728. + return ICP_OCF_DRV_STATUS_SUCCESS;
  11729. +}
  11730. +
  11731. +/* Name : icp_ocfDrvFreeOCFSession
  11732. + *
  11733. + * Description : This function deletes all existing Session data representing
  11734. + * the Cryptographic session established between OCF and this driver. This
  11735. + * also includes freeing the memory allocated for the session context. The
  11736. + * session object is also removed from the session linked list.
  11737. + */
  11738. +static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData)
  11739. +{
  11740. +
  11741. + sessionData->inUse = ICP_SESSION_DEREGISTERED;
  11742. +
  11743. + /*ENTER CRITICAL SECTION */
  11744. + icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
  11745. +
  11746. + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  11747. + /*If the Driver is exiting, allow that process to
  11748. + handle any deletions */
  11749. + /*EXIT CRITICAL SECTION */
  11750. + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  11751. + return;
  11752. + }
  11753. +
  11754. + icp_atomic_dec(&num_ocf_to_drv_registered_sessions);
  11755. +
  11756. + ICP_LIST_DEL(sessionData, listNode);
  11757. +
  11758. + /*EXIT CRITICAL SECTION */
  11759. + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  11760. +
  11761. + if (NULL != sessionData->sessHandle) {
  11762. + icp_kfree(sessionData->sessHandle);
  11763. + }
  11764. + ICP_CACHE_FREE(drvSessionData_zone, sessionData);
  11765. +}
  11766. +
  11767. +/* Name : icp_ocfDrvFreeLACSession
  11768. + *
  11769. + * Description : This attempts to deregister a LAC session. If it fails, the
  11770. + * deregistation retry function is called.
  11771. + */
  11772. +int icp_ocfDrvFreeLACSession(icp_device_t dev, uint64_t sid)
  11773. +{
  11774. + CpaCySymSessionCtx sessionToDeregister = NULL;
  11775. + struct icp_drvSessionData *sessionData = NULL;
  11776. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  11777. + int retval = 0;
  11778. +
  11779. + sessionData = (struct icp_drvSessionData *)CRYPTO_SESID2LID(sid);
  11780. + if (NULL == sessionData) {
  11781. + EPRINTK("%s(): OCF Free session called with Null Session ID.\n",
  11782. + __FUNCTION__);
  11783. + return EINVAL;
  11784. + }
  11785. +
  11786. + sessionToDeregister = sessionData->sessHandle;
  11787. +
  11788. + if ((ICP_SESSION_INITIALISED != sessionData->inUse) &&
  11789. + (ICP_SESSION_RUNNING != sessionData->inUse) &&
  11790. + (ICP_SESSION_DEREGISTERED != sessionData->inUse)) {
  11791. + DPRINTK("%s() Session not initialised.\n", __FUNCTION__);
  11792. + return EINVAL;
  11793. + }
  11794. +
  11795. + if (ICP_SESSION_RUNNING == sessionData->inUse) {
  11796. + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  11797. + sessionToDeregister);
  11798. + if (CPA_STATUS_RETRY == lacStatus) {
  11799. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  11800. + icp_ocfDrvDeregRetry(&sessionToDeregister)) {
  11801. + /* the retry function increments the
  11802. + dereg failed count */
  11803. + DPRINTK("%s(): LAC failed to deregister the "
  11804. + "session. (localSessionId= %p)\n",
  11805. + __FUNCTION__, sessionToDeregister);
  11806. + retval = EPERM;
  11807. + }
  11808. +
  11809. + } else if (CPA_STATUS_SUCCESS != lacStatus) {
  11810. + DPRINTK("%s(): LAC failed to deregister the session. "
  11811. + "localSessionId= %p, lacStatus = %d\n",
  11812. + __FUNCTION__, sessionToDeregister, lacStatus);
  11813. + icp_atomic_inc(&lac_session_failed_dereg_count);
  11814. + retval = EPERM;
  11815. + }
  11816. + } else {
  11817. + DPRINTK("%s() Session not registered with LAC.\n",
  11818. + __FUNCTION__);
  11819. + }
  11820. +
  11821. + icp_ocfDrvFreeOCFSession(sessionData);
  11822. + return retval;
  11823. +
  11824. +}
  11825. +
  11826. +/* Name : icp_ocfDrvAlgCheck
  11827. + *
  11828. + * Description : This function checks whether the cryptodesc argument pertains
  11829. + * to a sym or hash function
  11830. + */
  11831. +static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc)
  11832. +{
  11833. +
  11834. + if (crp_desc->crd_alg == CRYPTO_3DES_CBC ||
  11835. + crp_desc->crd_alg == CRYPTO_AES_CBC ||
  11836. + crp_desc->crd_alg == CRYPTO_DES_CBC ||
  11837. + crp_desc->crd_alg == CRYPTO_NULL_CBC ||
  11838. + crp_desc->crd_alg == CRYPTO_ARC4) {
  11839. + return ICP_OCF_DRV_ALG_CIPHER;
  11840. + }
  11841. +
  11842. + return ICP_OCF_DRV_ALG_HASH;
  11843. +}
  11844. +
  11845. +/* Name : icp_ocfDrvSymProcess
  11846. + *
  11847. + * Description : This function will map symmetric functionality calls from OCF
  11848. + * to the LAC API. It will also allocate memory to store the session context.
  11849. + *
  11850. + * Notes: If it is the first perform call for a given session, then a LAC
  11851. + * session is registered. After the session is registered, no checks as
  11852. + * to whether session paramaters have changed (e.g. alg chain order) are
  11853. + * done.
  11854. + */
  11855. +int icp_ocfDrvSymProcess(icp_device_t dev, struct cryptop *crp, int hint)
  11856. +{
  11857. + struct icp_drvSessionData *sessionData = NULL;
  11858. + struct icp_drvOpData *drvOpData = NULL;
  11859. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  11860. + Cpa32U sessionCtxSizeInBytes = 0;
  11861. +
  11862. + if (NULL == crp) {
  11863. + DPRINTK("%s(): Invalid input parameters, cryptop is NULL\n",
  11864. + __FUNCTION__);
  11865. + return EINVAL;
  11866. + }
  11867. +
  11868. + if (NULL == crp->crp_desc) {
  11869. + DPRINTK("%s(): Invalid input parameters, no crp_desc attached "
  11870. + "to crp\n", __FUNCTION__);
  11871. + crp->crp_etype = EINVAL;
  11872. + return EINVAL;
  11873. + }
  11874. +
  11875. + if (NULL == crp->crp_buf) {
  11876. + DPRINTK("%s(): Invalid input parameters, no buffer attached "
  11877. + "to crp\n", __FUNCTION__);
  11878. + crp->crp_etype = EINVAL;
  11879. + return EINVAL;
  11880. + }
  11881. +
  11882. + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  11883. + crp->crp_etype = EFAULT;
  11884. + return EFAULT;
  11885. + }
  11886. +
  11887. + sessionData = (struct icp_drvSessionData *)
  11888. + (CRYPTO_SESID2LID(crp->crp_sid));
  11889. + if (NULL == sessionData) {
  11890. + DPRINTK("%s(): Invalid input parameters, Null Session ID \n",
  11891. + __FUNCTION__);
  11892. + crp->crp_etype = EINVAL;
  11893. + return EINVAL;
  11894. + }
  11895. +
  11896. +/*If we get a request against a deregisted session, cancel operation*/
  11897. + if (ICP_SESSION_DEREGISTERED == sessionData->inUse) {
  11898. + DPRINTK("%s(): Session ID %d was deregistered \n",
  11899. + __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));
  11900. + crp->crp_etype = EFAULT;
  11901. + return EFAULT;
  11902. + }
  11903. +
  11904. +/*If none of the session states are set, then the session structure was either
  11905. + not initialised properly or we are reading from a freed memory area (possible
  11906. + due to OCF batch mode not removing queued requests against deregistered
  11907. + sessions*/
  11908. + if (ICP_SESSION_INITIALISED != sessionData->inUse &&
  11909. + ICP_SESSION_RUNNING != sessionData->inUse) {
  11910. + DPRINTK("%s(): Session - ID %d - not properly initialised or "
  11911. + "memory freed back to the kernel \n",
  11912. + __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));
  11913. + crp->crp_etype = EINVAL;
  11914. + return EINVAL;
  11915. + }
  11916. +
  11917. + /*For the below checks, remember error checking is already done in LAC.
  11918. + We're not validating inputs subsequent to registration */
  11919. + if (sessionData->inUse == ICP_SESSION_INITIALISED) {
  11920. + DPRINTK("%s(): Initialising session\n", __FUNCTION__);
  11921. +
  11922. + if (NULL != crp->crp_desc->crd_next) {
  11923. + if (ICP_OCF_DRV_ALG_CIPHER ==
  11924. + icp_ocfDrvAlgCheck(crp->crp_desc)) {
  11925. +
  11926. + sessionData->lacSessCtx.algChainOrder =
  11927. + CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH;
  11928. +
  11929. + if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
  11930. + sessionData->lacSessCtx.cipherSetupData.
  11931. + cipherDirection =
  11932. + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  11933. + } else {
  11934. + sessionData->lacSessCtx.cipherSetupData.
  11935. + cipherDirection =
  11936. + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  11937. + }
  11938. + } else {
  11939. + sessionData->lacSessCtx.algChainOrder =
  11940. + CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER;
  11941. +
  11942. + if (crp->crp_desc->crd_next->crd_flags &
  11943. + CRD_F_ENCRYPT) {
  11944. + sessionData->lacSessCtx.cipherSetupData.
  11945. + cipherDirection =
  11946. + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  11947. + } else {
  11948. + sessionData->lacSessCtx.cipherSetupData.
  11949. + cipherDirection =
  11950. + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  11951. + }
  11952. +
  11953. + }
  11954. +
  11955. + } else if (ICP_OCF_DRV_ALG_CIPHER ==
  11956. + icp_ocfDrvAlgCheck(crp->crp_desc)) {
  11957. + if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
  11958. + sessionData->lacSessCtx.cipherSetupData.
  11959. + cipherDirection =
  11960. + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  11961. + } else {
  11962. + sessionData->lacSessCtx.cipherSetupData.
  11963. + cipherDirection =
  11964. + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  11965. + }
  11966. +
  11967. + }
  11968. +
  11969. + /*No action required for standalone Auth here */
  11970. +
  11971. + /* Allocate memory for SymSessionCtx before the Session Registration */
  11972. + lacStatus =
  11973. + cpaCySymSessionCtxGetSize(CPA_INSTANCE_HANDLE_SINGLE,
  11974. + &(sessionData->lacSessCtx),
  11975. + &sessionCtxSizeInBytes);
  11976. + if (CPA_STATUS_SUCCESS != lacStatus) {
  11977. + EPRINTK("%s(): cpaCySymSessionCtxGetSize failed - %d\n",
  11978. + __FUNCTION__, lacStatus);
  11979. + crp->crp_etype = EINVAL;
  11980. + return EINVAL;
  11981. + }
  11982. + sessionData->sessHandle =
  11983. + icp_kmalloc(sessionCtxSizeInBytes, ICP_M_NOWAIT);
  11984. + if (NULL == sessionData->sessHandle) {
  11985. + EPRINTK
  11986. + ("%s(): Failed to get memory for SymSessionCtx\n",
  11987. + __FUNCTION__);
  11988. + crp->crp_etype = ENOMEM;
  11989. + return ENOMEM;
  11990. + }
  11991. +
  11992. + lacStatus = cpaCySymInitSession(CPA_INSTANCE_HANDLE_SINGLE,
  11993. + icp_ocfDrvSymCallBack,
  11994. + &(sessionData->lacSessCtx),
  11995. + sessionData->sessHandle);
  11996. +
  11997. + if (CPA_STATUS_SUCCESS != lacStatus) {
  11998. + EPRINTK("%s(): cpaCySymInitSession failed -%d \n",
  11999. + __FUNCTION__, lacStatus);
  12000. + crp->crp_etype = EFAULT;
  12001. + return EFAULT;
  12002. + }
  12003. +
  12004. + sessionData->inUse = ICP_SESSION_RUNNING;
  12005. + }
  12006. +
  12007. + drvOpData = icp_kmem_cache_zalloc(drvOpData_zone, ICP_M_NOWAIT);
  12008. + if (NULL == drvOpData) {
  12009. + EPRINTK("%s():Failed to get memory for drvOpData\n",
  12010. + __FUNCTION__);
  12011. + crp->crp_etype = ENOMEM;
  12012. + return ENOMEM;
  12013. + }
  12014. +
  12015. + drvOpData->lacOpData.pSessionCtx = sessionData->sessHandle;
  12016. + drvOpData->digestSizeInBytes = sessionData->lacSessCtx.hashSetupData.
  12017. + digestResultLenInBytes;
  12018. + drvOpData->crp = crp;
  12019. +
  12020. + /* Set the default buffer list array memory allocation */
  12021. + drvOpData->srcBuffer.pBuffers = drvOpData->bufferListArray;
  12022. + drvOpData->numBufferListArray = ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS;
  12023. +
  12024. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  12025. + icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->crp_desc)) {
  12026. + crp->crp_etype = EINVAL;
  12027. + goto err;
  12028. + }
  12029. +
  12030. + if (drvOpData->crp->crp_desc->crd_next != NULL) {
  12031. + if (icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->
  12032. + crp_desc->crd_next)) {
  12033. + crp->crp_etype = EINVAL;
  12034. + goto err;
  12035. + }
  12036. +
  12037. + }
  12038. +
  12039. + /*
  12040. + * Allocate buffer list array memory if the data fragment is more than
  12041. + * the default number (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) and not
  12042. + * calculated already
  12043. + */
  12044. + if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
  12045. + if (NULL == drvOpData->lacOpData.pDigestResult) {
  12046. + drvOpData->numBufferListArray =
  12047. + icp_ocfDrvGetPacketBuffFrags((icp_packet_buffer_t *)
  12048. + crp->crp_buf);
  12049. + }
  12050. +
  12051. + if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS <
  12052. + drvOpData->numBufferListArray) {
  12053. + DPRINTK("%s() numBufferListArray more than default\n",
  12054. + __FUNCTION__);
  12055. + drvOpData->srcBuffer.pBuffers = NULL;
  12056. + drvOpData->srcBuffer.pBuffers =
  12057. + icp_kmalloc(drvOpData->numBufferListArray *
  12058. + sizeof(CpaFlatBuffer), ICP_M_NOWAIT);
  12059. + if (NULL == drvOpData->srcBuffer.pBuffers) {
  12060. + EPRINTK("%s() Failed to get memory for "
  12061. + "pBuffers\n", __FUNCTION__);
  12062. + ICP_CACHE_FREE(drvOpData_zone, drvOpData);
  12063. + crp->crp_etype = ENOMEM;
  12064. + return ENOMEM;
  12065. + }
  12066. + }
  12067. + }
  12068. +
  12069. + /*
  12070. + * Check the type of buffer structure we got and convert it into
  12071. + * CpaBufferList format.
  12072. + */
  12073. + if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
  12074. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  12075. + icp_ocfDrvPacketBuffToBufferList((icp_packet_buffer_t *)
  12076. + crp->crp_buf,
  12077. + &(drvOpData->srcBuffer))) {
  12078. + EPRINTK("%s():Failed to translate from packet buffer "
  12079. + "to bufferlist\n", __FUNCTION__);
  12080. + crp->crp_etype = EINVAL;
  12081. + goto err;
  12082. + }
  12083. +
  12084. + drvOpData->bufferType = ICP_CRYPTO_F_PACKET_BUF;
  12085. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  12086. + /* OCF only supports IOV of one entry. */
  12087. + if (NUM_IOV_SUPPORTED ==
  12088. + ((struct uio *)(crp->crp_buf))->uio_iovcnt) {
  12089. +
  12090. + icp_ocfDrvPtrAndLenToBufferList(((struct uio *)(crp->
  12091. + crp_buf))->
  12092. + uio_iov[0].iov_base,
  12093. + ((struct uio *)(crp->
  12094. + crp_buf))->
  12095. + uio_iov[0].iov_len,
  12096. + &(drvOpData->
  12097. + srcBuffer));
  12098. +
  12099. + drvOpData->bufferType = CRYPTO_F_IOV;
  12100. +
  12101. + } else {
  12102. + DPRINTK("%s():Unable to handle IOVs with lengths of "
  12103. + "greater than one!\n", __FUNCTION__);
  12104. + crp->crp_etype = EINVAL;
  12105. + goto err;
  12106. + }
  12107. +
  12108. + } else {
  12109. + icp_ocfDrvPtrAndLenToBufferList(crp->crp_buf,
  12110. + crp->crp_ilen,
  12111. + &(drvOpData->srcBuffer));
  12112. +
  12113. + drvOpData->bufferType = CRYPTO_BUF_CONTIG;
  12114. + }
  12115. +
  12116. + /* Allocate srcBuffer's private meta data */
  12117. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  12118. + icp_ocfDrvAllocMetaData(&(drvOpData->srcBuffer), drvOpData)) {
  12119. + EPRINTK("%s() icp_ocfDrvAllocMetaData failed\n", __FUNCTION__);
  12120. + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  12121. + crp->crp_etype = EINVAL;
  12122. + goto err;
  12123. + }
  12124. +
  12125. + /* Perform "in-place" crypto operation */
  12126. + lacStatus = cpaCySymPerformOp(CPA_INSTANCE_HANDLE_SINGLE,
  12127. + (void *)drvOpData,
  12128. + &(drvOpData->lacOpData),
  12129. + &(drvOpData->srcBuffer),
  12130. + &(drvOpData->srcBuffer),
  12131. + &(drvOpData->verifyResult));
  12132. + if (CPA_STATUS_RETRY == lacStatus) {
  12133. + DPRINTK("%s(): cpaCySymPerformOp retry, lacStatus = %d\n",
  12134. + __FUNCTION__, lacStatus);
  12135. + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  12136. + crp->crp_etype = ERESTART;
  12137. + goto err;
  12138. + }
  12139. + if (CPA_STATUS_SUCCESS != lacStatus) {
  12140. + EPRINTK("%s(): cpaCySymPerformOp failed, lacStatus = %d\n",
  12141. + __FUNCTION__, lacStatus);
  12142. + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  12143. + crp->crp_etype = EINVAL;
  12144. + goto err;
  12145. + }
  12146. +
  12147. + return 0; //OCF success status value
  12148. +
  12149. + err:
  12150. + if (drvOpData->numBufferListArray > ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  12151. + icp_kfree(drvOpData->srcBuffer.pBuffers);
  12152. + }
  12153. + icp_ocfDrvFreeMetaData(&(drvOpData->srcBuffer));
  12154. + ICP_CACHE_FREE(drvOpData_zone, drvOpData);
  12155. +
  12156. + return crp->crp_etype;
  12157. +}
  12158. +
  12159. +/* Name : icp_ocfDrvProcessDataSetup
  12160. + *
  12161. + * Description : This function will setup all the cryptographic operation data
  12162. + * that is required by LAC to execute the operation.
  12163. + */
  12164. +static int icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
  12165. + struct cryptodesc *crp_desc)
  12166. +{
  12167. + CpaCyRandGenOpData randGenOpData;
  12168. + CpaFlatBuffer randData;
  12169. +
  12170. + drvOpData->lacOpData.packetType = CPA_CY_SYM_PACKET_TYPE_FULL;
  12171. +
  12172. + /* Convert from the cryptop to the ICP LAC crypto parameters */
  12173. + switch (crp_desc->crd_alg) {
  12174. + case CRYPTO_NULL_CBC:
  12175. + drvOpData->lacOpData.
  12176. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  12177. + drvOpData->lacOpData.
  12178. + messageLenToCipherInBytes = crp_desc->crd_len;
  12179. + drvOpData->verifyResult = CPA_FALSE;
  12180. + drvOpData->lacOpData.ivLenInBytes = NULL_BLOCK_LEN;
  12181. + break;
  12182. + case CRYPTO_DES_CBC:
  12183. + drvOpData->lacOpData.
  12184. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  12185. + drvOpData->lacOpData.
  12186. + messageLenToCipherInBytes = crp_desc->crd_len;
  12187. + drvOpData->verifyResult = CPA_FALSE;
  12188. + drvOpData->lacOpData.ivLenInBytes = DES_BLOCK_LEN;
  12189. + break;
  12190. + case CRYPTO_3DES_CBC:
  12191. + drvOpData->lacOpData.
  12192. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  12193. + drvOpData->lacOpData.
  12194. + messageLenToCipherInBytes = crp_desc->crd_len;
  12195. + drvOpData->verifyResult = CPA_FALSE;
  12196. + drvOpData->lacOpData.ivLenInBytes = DES3_BLOCK_LEN;
  12197. + break;
  12198. + case CRYPTO_ARC4:
  12199. + drvOpData->lacOpData.
  12200. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  12201. + drvOpData->lacOpData.
  12202. + messageLenToCipherInBytes = crp_desc->crd_len;
  12203. + drvOpData->verifyResult = CPA_FALSE;
  12204. + drvOpData->lacOpData.ivLenInBytes = ARC4_COUNTER_LEN;
  12205. + break;
  12206. + case CRYPTO_AES_CBC:
  12207. + drvOpData->lacOpData.
  12208. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  12209. + drvOpData->lacOpData.
  12210. + messageLenToCipherInBytes = crp_desc->crd_len;
  12211. + drvOpData->verifyResult = CPA_FALSE;
  12212. + drvOpData->lacOpData.ivLenInBytes = RIJNDAEL128_BLOCK_LEN;
  12213. + break;
  12214. + case CRYPTO_SHA1:
  12215. + case CRYPTO_SHA1_HMAC:
  12216. + case CRYPTO_SHA2_256:
  12217. + case CRYPTO_SHA2_256_HMAC:
  12218. + case CRYPTO_SHA2_384:
  12219. + case CRYPTO_SHA2_384_HMAC:
  12220. + case CRYPTO_SHA2_512:
  12221. + case CRYPTO_SHA2_512_HMAC:
  12222. + case CRYPTO_MD5:
  12223. + case CRYPTO_MD5_HMAC:
  12224. + drvOpData->lacOpData.
  12225. + hashStartSrcOffsetInBytes = crp_desc->crd_skip;
  12226. + drvOpData->lacOpData.
  12227. + messageLenToHashInBytes = crp_desc->crd_len;
  12228. + drvOpData->lacOpData.
  12229. + pDigestResult =
  12230. + icp_ocfDrvDigestPointerFind(drvOpData, crp_desc);
  12231. +
  12232. + if (NULL == drvOpData->lacOpData.pDigestResult) {
  12233. + DPRINTK("%s(): ERROR - could not calculate "
  12234. + "Digest Result memory address\n", __FUNCTION__);
  12235. + return ICP_OCF_DRV_STATUS_FAIL;
  12236. + }
  12237. +
  12238. + drvOpData->lacOpData.digestVerify = CPA_FALSE;
  12239. + break;
  12240. + default:
  12241. + DPRINTK("%s(): Crypto process error - algorithm not "
  12242. + "found \n", __FUNCTION__);
  12243. + return ICP_OCF_DRV_STATUS_FAIL;
  12244. + }
  12245. +
  12246. + /* Figure out what the IV is supposed to be */
  12247. + if ((crp_desc->crd_alg == CRYPTO_DES_CBC) ||
  12248. + (crp_desc->crd_alg == CRYPTO_3DES_CBC) ||
  12249. + (crp_desc->crd_alg == CRYPTO_AES_CBC)) {
  12250. + /*ARC4 doesn't use an IV */
  12251. + if (crp_desc->crd_flags & CRD_F_IV_EXPLICIT) {
  12252. + /* Explicit IV provided to OCF */
  12253. + drvOpData->lacOpData.pIv = crp_desc->crd_iv;
  12254. + } else {
  12255. + /* IV is not explicitly provided to OCF */
  12256. +
  12257. + /* Point the LAC OP Data IV pointer to our allocated
  12258. + storage location for this session. */
  12259. + drvOpData->lacOpData.pIv = drvOpData->ivData;
  12260. +
  12261. + if ((crp_desc->crd_flags & CRD_F_ENCRYPT) &&
  12262. + ((crp_desc->crd_flags & CRD_F_IV_PRESENT) == 0)) {
  12263. +
  12264. + /* Encrypting - need to create IV */
  12265. + randGenOpData.generateBits = CPA_TRUE;
  12266. + randGenOpData.lenInBytes = MAX_IV_LEN_IN_BYTES;
  12267. +
  12268. + icp_ocfDrvPtrAndLenToFlatBuffer((Cpa8U *)
  12269. + drvOpData->
  12270. + ivData,
  12271. + MAX_IV_LEN_IN_BYTES,
  12272. + &randData);
  12273. +
  12274. + if (CPA_STATUS_SUCCESS !=
  12275. + cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
  12276. + NULL, NULL,
  12277. + &randGenOpData, &randData)) {
  12278. + DPRINTK("%s(): ERROR - Failed to"
  12279. + " generate"
  12280. + " Initialisation Vector\n",
  12281. + __FUNCTION__);
  12282. + return ICP_OCF_DRV_STATUS_FAIL;
  12283. + }
  12284. +
  12285. + crypto_copyback(drvOpData->crp->
  12286. + crp_flags,
  12287. + drvOpData->crp->crp_buf,
  12288. + crp_desc->crd_inject,
  12289. + drvOpData->lacOpData.
  12290. + ivLenInBytes,
  12291. + (caddr_t) (drvOpData->lacOpData.
  12292. + pIv));
  12293. + } else {
  12294. + /* Reading IV from buffer */
  12295. + crypto_copydata(drvOpData->crp->
  12296. + crp_flags,
  12297. + drvOpData->crp->crp_buf,
  12298. + crp_desc->crd_inject,
  12299. + drvOpData->lacOpData.
  12300. + ivLenInBytes,
  12301. + (caddr_t) (drvOpData->lacOpData.
  12302. + pIv));
  12303. + }
  12304. +
  12305. + }
  12306. +
  12307. + }
  12308. +
  12309. + return ICP_OCF_DRV_STATUS_SUCCESS;
  12310. +}
  12311. +
  12312. +/* Name : icp_ocfDrvDigestPointerFind
  12313. + *
  12314. + * Description : This function is used to find the memory address of where the
  12315. + * digest information shall be stored in. Input buffer types are an skbuff, iov
  12316. + * or flat buffer. The address is found using the buffer data start address and
  12317. + * an offset.
  12318. + *
  12319. + * Note: In the case of a linux skbuff, the digest address may exist within
  12320. + * a memory space linked to from the start buffer. These linked memory spaces
  12321. + * must be traversed by the data length offset in order to find the digest start
  12322. + * address. Whether there is enough space for the digest must also be checked.
  12323. + */
  12324. +uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData * drvOpData,
  12325. + struct cryptodesc * crp_desc)
  12326. +{
  12327. +
  12328. + int offsetInBytes = crp_desc->crd_inject;
  12329. + uint32_t digestSizeInBytes = drvOpData->digestSizeInBytes;
  12330. + uint8_t *flat_buffer_base = NULL;
  12331. + int flat_buffer_length = 0;
  12332. +
  12333. + if (drvOpData->crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
  12334. +
  12335. + return icp_ocfDrvPacketBufferDigestPointerFind(drvOpData,
  12336. + offsetInBytes,
  12337. + digestSizeInBytes);
  12338. +
  12339. + } else {
  12340. + /* IOV or flat buffer */
  12341. + if (drvOpData->crp->crp_flags & CRYPTO_F_IOV) {
  12342. + /*single IOV check has already been done */
  12343. + flat_buffer_base = ((struct uio *)
  12344. + (drvOpData->crp->crp_buf))->
  12345. + uio_iov[0].iov_base;
  12346. + flat_buffer_length = ((struct uio *)
  12347. + (drvOpData->crp->crp_buf))->
  12348. + uio_iov[0].iov_len;
  12349. + } else {
  12350. + flat_buffer_base = (uint8_t *) drvOpData->crp->crp_buf;
  12351. + flat_buffer_length = drvOpData->crp->crp_ilen;
  12352. + }
  12353. +
  12354. + if (flat_buffer_length < (offsetInBytes + digestSizeInBytes)) {
  12355. + DPRINTK("%s() Not enough space for Digest "
  12356. + "(IOV/Flat Buffer) \n", __FUNCTION__);
  12357. + return NULL;
  12358. + } else {
  12359. + return (uint8_t *) (flat_buffer_base + offsetInBytes);
  12360. + }
  12361. + }
  12362. + DPRINTK("%s() Should not reach this point\n", __FUNCTION__);
  12363. + return NULL;
  12364. +}
  12365. diff -Nur linux-2.6.35.orig/crypto/ocf/ep80579/Makefile linux-2.6.35/crypto/ocf/ep80579/Makefile
  12366. --- linux-2.6.35.orig/crypto/ocf/ep80579/Makefile 1970-01-01 01:00:00.000000000 +0100
  12367. +++ linux-2.6.35/crypto/ocf/ep80579/Makefile 2010-08-05 22:02:08.954868119 +0200
  12368. @@ -0,0 +1,119 @@
  12369. +#########################################################################
  12370. +#
  12371. +# Targets supported
  12372. +# all - builds everything and installs
  12373. +# install - identical to all
  12374. +# depend - build dependencies
  12375. +# clean - clears derived objects except the .depend files
  12376. +# distclean- clears all derived objects and the .depend file
  12377. +#
  12378. +# @par
  12379. +# This file is provided under a dual BSD/GPLv2 license. When using or
  12380. +# redistributing this file, you may do so under either license.
  12381. +#
  12382. +# GPL LICENSE SUMMARY
  12383. +#
  12384. +# Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  12385. +#
  12386. +# This program is free software; you can redistribute it and/or modify
  12387. +# it under the terms of version 2 of the GNU General Public License as
  12388. +# published by the Free Software Foundation.
  12389. +#
  12390. +# This program is distributed in the hope that it will be useful, but
  12391. +# WITHOUT ANY WARRANTY; without even the implied warranty of
  12392. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12393. +# General Public License for more details.
  12394. +#
  12395. +# You should have received a copy of the GNU General Public License
  12396. +# along with this program; if not, write to the Free Software
  12397. +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  12398. +# The full GNU General Public License is included in this distribution
  12399. +# in the file called LICENSE.GPL.
  12400. +#
  12401. +# Contact Information:
  12402. +# Intel Corporation
  12403. +#
  12404. +# BSD LICENSE
  12405. +#
  12406. +# Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  12407. +# All rights reserved.
  12408. +#
  12409. +# Redistribution and use in source and binary forms, with or without
  12410. +# modification, are permitted provided that the following conditions
  12411. +# are met:
  12412. +#
  12413. +# * Redistributions of source code must retain the above copyright
  12414. +# notice, this list of conditions and the following disclaimer.
  12415. +# * Redistributions in binary form must reproduce the above copyright
  12416. +# notice, this list of conditions and the following disclaimer in
  12417. +# the documentation and/or other materials provided with the
  12418. +# distribution.
  12419. +# * Neither the name of Intel Corporation nor the names of its
  12420. +# contributors may be used to endorse or promote products derived
  12421. +# from this software without specific prior written permission.
  12422. +#
  12423. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  12424. +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  12425. +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  12426. +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  12427. +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  12428. +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  12429. +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12430. +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  12431. +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12432. +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  12433. +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  12434. +#
  12435. +#
  12436. +# version: Security.L.1.0.2-229
  12437. +############################################################################
  12438. +
  12439. +
  12440. +####################Common variables and definitions########################
  12441. +
  12442. +ifndef ICP_ROOT
  12443. +$(warning ICP_ROOT is undefined. Please set the path to EP80579 release package directory \
  12444. + "-> setenv ICP_ROOT <path>")
  12445. +all fastdep:
  12446. + :
  12447. +else
  12448. +
  12449. +ifndef KERNEL_SOURCE_ROOT
  12450. +$(error KERNEL_SOURCE_ROOT is undefined. Please set the path to the kernel source directory \
  12451. + "-> setenv KERNEL_SOURCE_ROOT <path>")
  12452. +endif
  12453. +
  12454. +# Ensure The ENV_DIR environmental var is defined.
  12455. +ifndef ICP_ENV_DIR
  12456. +$(error ICP_ENV_DIR is undefined. Please set the path to EP80579 driver environment.mk file \
  12457. + "-> setenv ICP_ENV_DIR <path>")
  12458. +endif
  12459. +
  12460. +#Add your project environment Makefile
  12461. +include ${ICP_ENV_DIR}/environment.mk
  12462. +
  12463. +#include the makefile with all the default and common Make variable definitions
  12464. +include ${ICP_BUILDSYSTEM_PATH}/build_files/common.mk
  12465. +
  12466. +#Add the name for the executable, Library or Module output definitions
  12467. +OUTPUT_NAME= icp_ocf
  12468. +
  12469. +# List of Source Files to be compiled
  12470. +SOURCES= icp_common.c icp_sym.c icp_asym.c icp_ocf_linux.c
  12471. +
  12472. +#common includes between all supported OSes
  12473. +INCLUDES= -I ${ICP_API_DIR} -I${ICP_LAC_API} \
  12474. +-I${ICP_OCF_SRC_DIR}
  12475. +
  12476. +# The location of the os level makefile needs to be changed.
  12477. +include ${ICP_ENV_DIR}/${ICP_OS}_${ICP_OS_LEVEL}.mk
  12478. +
  12479. +# On the line directly below list the outputs you wish to build for,
  12480. +# e.g "lib_static lib_shared exe module" as shown below
  12481. +install: module
  12482. +
  12483. +###################Include rules makefiles########################
  12484. +include ${ICP_BUILDSYSTEM_PATH}/build_files/rules.mk
  12485. +###################End of Rules inclusion#########################
  12486. +
  12487. +endif
  12488. diff -Nur linux-2.6.35.orig/crypto/ocf/hifn/hifn7751.c linux-2.6.35/crypto/ocf/hifn/hifn7751.c
  12489. --- linux-2.6.35.orig/crypto/ocf/hifn/hifn7751.c 1970-01-01 01:00:00.000000000 +0100
  12490. +++ linux-2.6.35/crypto/ocf/hifn/hifn7751.c 2010-08-05 22:02:09.073864347 +0200
  12491. @@ -0,0 +1,2976 @@
  12492. +/* $OpenBSD: hifn7751.c,v 1.120 2002/05/17 00:33:34 deraadt Exp $ */
  12493. +
  12494. +/*-
  12495. + * Invertex AEON / Hifn 7751 driver
  12496. + * Copyright (c) 1999 Invertex Inc. All rights reserved.
  12497. + * Copyright (c) 1999 Theo de Raadt
  12498. + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  12499. + * http://www.netsec.net
  12500. + * Copyright (c) 2003 Hifn Inc.
  12501. + *
  12502. + * This driver is based on a previous driver by Invertex, for which they
  12503. + * requested: Please send any comments, feedback, bug-fixes, or feature
  12504. + * requests to software@invertex.com.
  12505. + *
  12506. + * Redistribution and use in source and binary forms, with or without
  12507. + * modification, are permitted provided that the following conditions
  12508. + * are met:
  12509. + *
  12510. + * 1. Redistributions of source code must retain the above copyright
  12511. + * notice, this list of conditions and the following disclaimer.
  12512. + * 2. Redistributions in binary form must reproduce the above copyright
  12513. + * notice, this list of conditions and the following disclaimer in the
  12514. + * documentation and/or other materials provided with the distribution.
  12515. + * 3. The name of the author may not be used to endorse or promote products
  12516. + * derived from this software without specific prior written permission.
  12517. + *
  12518. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  12519. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  12520. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  12521. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  12522. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  12523. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12524. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  12525. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12526. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  12527. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  12528. + *
  12529. + * Effort sponsored in part by the Defense Advanced Research Projects
  12530. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  12531. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  12532. + *
  12533. + *
  12534. +__FBSDID("$FreeBSD: src/sys/dev/hifn/hifn7751.c,v 1.40 2007/03/21 03:42:49 sam Exp $");
  12535. + */
  12536. +
  12537. +/*
  12538. + * Driver for various Hifn encryption processors.
  12539. + */
  12540. +#ifndef AUTOCONF_INCLUDED
  12541. +#include <linux/config.h>
  12542. +#endif
  12543. +#include <linux/module.h>
  12544. +#include <linux/init.h>
  12545. +#include <linux/list.h>
  12546. +#include <linux/slab.h>
  12547. +#include <linux/wait.h>
  12548. +#include <linux/sched.h>
  12549. +#include <linux/pci.h>
  12550. +#include <linux/delay.h>
  12551. +#include <linux/interrupt.h>
  12552. +#include <linux/spinlock.h>
  12553. +#include <linux/random.h>
  12554. +#include <linux/version.h>
  12555. +#include <linux/skbuff.h>
  12556. +#include <asm/io.h>
  12557. +
  12558. +#include <cryptodev.h>
  12559. +#include <uio.h>
  12560. +#include <hifn/hifn7751reg.h>
  12561. +#include <hifn/hifn7751var.h>
  12562. +
  12563. +#if 1
  12564. +#define DPRINTF(a...) if (hifn_debug) { \
  12565. + printk("%s: ", sc ? \
  12566. + device_get_nameunit(sc->sc_dev) : "hifn"); \
  12567. + printk(a); \
  12568. + } else
  12569. +#else
  12570. +#define DPRINTF(a...)
  12571. +#endif
  12572. +
  12573. +static inline int
  12574. +pci_get_revid(struct pci_dev *dev)
  12575. +{
  12576. + u8 rid = 0;
  12577. + pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
  12578. + return rid;
  12579. +}
  12580. +
  12581. +static struct hifn_stats hifnstats;
  12582. +
  12583. +#define debug hifn_debug
  12584. +int hifn_debug = 0;
  12585. +module_param(hifn_debug, int, 0644);
  12586. +MODULE_PARM_DESC(hifn_debug, "Enable debug");
  12587. +
  12588. +int hifn_maxbatch = 1;
  12589. +module_param(hifn_maxbatch, int, 0644);
  12590. +MODULE_PARM_DESC(hifn_maxbatch, "max ops to batch w/o interrupt");
  12591. +
  12592. +int hifn_cache_linesize = 0x10;
  12593. +module_param(hifn_cache_linesize, int, 0444);
  12594. +MODULE_PARM_DESC(hifn_cache_linesize, "PCI config cache line size");
  12595. +
  12596. +#ifdef MODULE_PARM
  12597. +char *hifn_pllconfig = NULL;
  12598. +MODULE_PARM(hifn_pllconfig, "s");
  12599. +#else
  12600. +char hifn_pllconfig[32]; /* This setting is RO after loading */
  12601. +module_param_string(hifn_pllconfig, hifn_pllconfig, 32, 0444);
  12602. +#endif
  12603. +MODULE_PARM_DESC(hifn_pllconfig, "PLL config, ie., pci66, ext33, ...");
  12604. +
  12605. +#ifdef HIFN_VULCANDEV
  12606. +#include <sys/conf.h>
  12607. +#include <sys/uio.h>
  12608. +
  12609. +static struct cdevsw vulcanpk_cdevsw; /* forward declaration */
  12610. +#endif
  12611. +
  12612. +/*
  12613. + * Prototypes and count for the pci_device structure
  12614. + */
  12615. +static int hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent);
  12616. +static void hifn_remove(struct pci_dev *dev);
  12617. +
  12618. +static int hifn_newsession(device_t, u_int32_t *, struct cryptoini *);
  12619. +static int hifn_freesession(device_t, u_int64_t);
  12620. +static int hifn_process(device_t, struct cryptop *, int);
  12621. +
  12622. +static device_method_t hifn_methods = {
  12623. + /* crypto device methods */
  12624. + DEVMETHOD(cryptodev_newsession, hifn_newsession),
  12625. + DEVMETHOD(cryptodev_freesession,hifn_freesession),
  12626. + DEVMETHOD(cryptodev_process, hifn_process),
  12627. +};
  12628. +
  12629. +static void hifn_reset_board(struct hifn_softc *, int);
  12630. +static void hifn_reset_puc(struct hifn_softc *);
  12631. +static void hifn_puc_wait(struct hifn_softc *);
  12632. +static int hifn_enable_crypto(struct hifn_softc *);
  12633. +static void hifn_set_retry(struct hifn_softc *sc);
  12634. +static void hifn_init_dma(struct hifn_softc *);
  12635. +static void hifn_init_pci_registers(struct hifn_softc *);
  12636. +static int hifn_sramsize(struct hifn_softc *);
  12637. +static int hifn_dramsize(struct hifn_softc *);
  12638. +static int hifn_ramtype(struct hifn_softc *);
  12639. +static void hifn_sessions(struct hifn_softc *);
  12640. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  12641. +static irqreturn_t hifn_intr(int irq, void *arg);
  12642. +#else
  12643. +static irqreturn_t hifn_intr(int irq, void *arg, struct pt_regs *regs);
  12644. +#endif
  12645. +static u_int hifn_write_command(struct hifn_command *, u_int8_t *);
  12646. +static u_int32_t hifn_next_signature(u_int32_t a, u_int cnt);
  12647. +static void hifn_callback(struct hifn_softc *, struct hifn_command *, u_int8_t *);
  12648. +static int hifn_crypto(struct hifn_softc *, struct hifn_command *, struct cryptop *, int);
  12649. +static int hifn_readramaddr(struct hifn_softc *, int, u_int8_t *);
  12650. +static int hifn_writeramaddr(struct hifn_softc *, int, u_int8_t *);
  12651. +static int hifn_dmamap_load_src(struct hifn_softc *, struct hifn_command *);
  12652. +static int hifn_dmamap_load_dst(struct hifn_softc *, struct hifn_command *);
  12653. +static int hifn_init_pubrng(struct hifn_softc *);
  12654. +static void hifn_tick(unsigned long arg);
  12655. +static void hifn_abort(struct hifn_softc *);
  12656. +static void hifn_alloc_slot(struct hifn_softc *, int *, int *, int *, int *);
  12657. +
  12658. +static void hifn_write_reg_0(struct hifn_softc *, bus_size_t, u_int32_t);
  12659. +static void hifn_write_reg_1(struct hifn_softc *, bus_size_t, u_int32_t);
  12660. +
  12661. +#ifdef CONFIG_OCF_RANDOMHARVEST
  12662. +static int hifn_read_random(void *arg, u_int32_t *buf, int len);
  12663. +#endif
  12664. +
  12665. +#define HIFN_MAX_CHIPS 8
  12666. +static struct hifn_softc *hifn_chip_idx[HIFN_MAX_CHIPS];
  12667. +
  12668. +static __inline u_int32_t
  12669. +READ_REG_0(struct hifn_softc *sc, bus_size_t reg)
  12670. +{
  12671. + u_int32_t v = readl(sc->sc_bar0 + reg);
  12672. + sc->sc_bar0_lastreg = (bus_size_t) -1;
  12673. + return (v);
  12674. +}
  12675. +#define WRITE_REG_0(sc, reg, val) hifn_write_reg_0(sc, reg, val)
  12676. +
  12677. +static __inline u_int32_t
  12678. +READ_REG_1(struct hifn_softc *sc, bus_size_t reg)
  12679. +{
  12680. + u_int32_t v = readl(sc->sc_bar1 + reg);
  12681. + sc->sc_bar1_lastreg = (bus_size_t) -1;
  12682. + return (v);
  12683. +}
  12684. +#define WRITE_REG_1(sc, reg, val) hifn_write_reg_1(sc, reg, val)
  12685. +
  12686. +/*
  12687. + * map in a given buffer (great on some arches :-)
  12688. + */
  12689. +
  12690. +static int
  12691. +pci_map_uio(struct hifn_softc *sc, struct hifn_operand *buf, struct uio *uio)
  12692. +{
  12693. + struct iovec *iov = uio->uio_iov;
  12694. +
  12695. + DPRINTF("%s()\n", __FUNCTION__);
  12696. +
  12697. + buf->mapsize = 0;
  12698. + for (buf->nsegs = 0; buf->nsegs < uio->uio_iovcnt; ) {
  12699. + buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
  12700. + iov->iov_base, iov->iov_len,
  12701. + PCI_DMA_BIDIRECTIONAL);
  12702. + buf->segs[buf->nsegs].ds_len = iov->iov_len;
  12703. + buf->mapsize += iov->iov_len;
  12704. + iov++;
  12705. + buf->nsegs++;
  12706. + }
  12707. + /* identify this buffer by the first segment */
  12708. + buf->map = (void *) buf->segs[0].ds_addr;
  12709. + return(0);
  12710. +}
  12711. +
  12712. +/*
  12713. + * map in a given sk_buff
  12714. + */
  12715. +
  12716. +static int
  12717. +pci_map_skb(struct hifn_softc *sc,struct hifn_operand *buf,struct sk_buff *skb)
  12718. +{
  12719. + int i;
  12720. +
  12721. + DPRINTF("%s()\n", __FUNCTION__);
  12722. +
  12723. + buf->mapsize = 0;
  12724. +
  12725. + buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
  12726. + skb->data, skb_headlen(skb), PCI_DMA_BIDIRECTIONAL);
  12727. + buf->segs[0].ds_len = skb_headlen(skb);
  12728. + buf->mapsize += buf->segs[0].ds_len;
  12729. +
  12730. + buf->nsegs = 1;
  12731. +
  12732. + for (i = 0; i < skb_shinfo(skb)->nr_frags; ) {
  12733. + buf->segs[buf->nsegs].ds_len = skb_shinfo(skb)->frags[i].size;
  12734. + buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
  12735. + page_address(skb_shinfo(skb)->frags[i].page) +
  12736. + skb_shinfo(skb)->frags[i].page_offset,
  12737. + buf->segs[buf->nsegs].ds_len, PCI_DMA_BIDIRECTIONAL);
  12738. + buf->mapsize += buf->segs[buf->nsegs].ds_len;
  12739. + buf->nsegs++;
  12740. + }
  12741. +
  12742. + /* identify this buffer by the first segment */
  12743. + buf->map = (void *) buf->segs[0].ds_addr;
  12744. + return(0);
  12745. +}
  12746. +
  12747. +/*
  12748. + * map in a given contiguous buffer
  12749. + */
  12750. +
  12751. +static int
  12752. +pci_map_buf(struct hifn_softc *sc,struct hifn_operand *buf, void *b, int len)
  12753. +{
  12754. + DPRINTF("%s()\n", __FUNCTION__);
  12755. +
  12756. + buf->mapsize = 0;
  12757. + buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
  12758. + b, len, PCI_DMA_BIDIRECTIONAL);
  12759. + buf->segs[0].ds_len = len;
  12760. + buf->mapsize += buf->segs[0].ds_len;
  12761. + buf->nsegs = 1;
  12762. +
  12763. + /* identify this buffer by the first segment */
  12764. + buf->map = (void *) buf->segs[0].ds_addr;
  12765. + return(0);
  12766. +}
  12767. +
  12768. +#if 0 /* not needed at this time */
  12769. +static void
  12770. +pci_sync_iov(struct hifn_softc *sc, struct hifn_operand *buf)
  12771. +{
  12772. + int i;
  12773. +
  12774. + DPRINTF("%s()\n", __FUNCTION__);
  12775. + for (i = 0; i < buf->nsegs; i++)
  12776. + pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
  12777. + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
  12778. +}
  12779. +#endif
  12780. +
  12781. +static void
  12782. +pci_unmap_buf(struct hifn_softc *sc, struct hifn_operand *buf)
  12783. +{
  12784. + int i;
  12785. + DPRINTF("%s()\n", __FUNCTION__);
  12786. + for (i = 0; i < buf->nsegs; i++) {
  12787. + pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
  12788. + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
  12789. + buf->segs[i].ds_addr = 0;
  12790. + buf->segs[i].ds_len = 0;
  12791. + }
  12792. + buf->nsegs = 0;
  12793. + buf->mapsize = 0;
  12794. + buf->map = 0;
  12795. +}
  12796. +
  12797. +static const char*
  12798. +hifn_partname(struct hifn_softc *sc)
  12799. +{
  12800. + /* XXX sprintf numbers when not decoded */
  12801. + switch (pci_get_vendor(sc->sc_pcidev)) {
  12802. + case PCI_VENDOR_HIFN:
  12803. + switch (pci_get_device(sc->sc_pcidev)) {
  12804. + case PCI_PRODUCT_HIFN_6500: return "Hifn 6500";
  12805. + case PCI_PRODUCT_HIFN_7751: return "Hifn 7751";
  12806. + case PCI_PRODUCT_HIFN_7811: return "Hifn 7811";
  12807. + case PCI_PRODUCT_HIFN_7951: return "Hifn 7951";
  12808. + case PCI_PRODUCT_HIFN_7955: return "Hifn 7955";
  12809. + case PCI_PRODUCT_HIFN_7956: return "Hifn 7956";
  12810. + }
  12811. + return "Hifn unknown-part";
  12812. + case PCI_VENDOR_INVERTEX:
  12813. + switch (pci_get_device(sc->sc_pcidev)) {
  12814. + case PCI_PRODUCT_INVERTEX_AEON: return "Invertex AEON";
  12815. + }
  12816. + return "Invertex unknown-part";
  12817. + case PCI_VENDOR_NETSEC:
  12818. + switch (pci_get_device(sc->sc_pcidev)) {
  12819. + case PCI_PRODUCT_NETSEC_7751: return "NetSec 7751";
  12820. + }
  12821. + return "NetSec unknown-part";
  12822. + }
  12823. + return "Unknown-vendor unknown-part";
  12824. +}
  12825. +
  12826. +static u_int
  12827. +checkmaxmin(struct pci_dev *dev, const char *what, u_int v, u_int min, u_int max)
  12828. +{
  12829. + struct hifn_softc *sc = pci_get_drvdata(dev);
  12830. + if (v > max) {
  12831. + device_printf(sc->sc_dev, "Warning, %s %u out of range, "
  12832. + "using max %u\n", what, v, max);
  12833. + v = max;
  12834. + } else if (v < min) {
  12835. + device_printf(sc->sc_dev, "Warning, %s %u out of range, "
  12836. + "using min %u\n", what, v, min);
  12837. + v = min;
  12838. + }
  12839. + return v;
  12840. +}
  12841. +
  12842. +/*
  12843. + * Select PLL configuration for 795x parts. This is complicated in
  12844. + * that we cannot determine the optimal parameters without user input.
  12845. + * The reference clock is derived from an external clock through a
  12846. + * multiplier. The external clock is either the host bus (i.e. PCI)
  12847. + * or an external clock generator. When using the PCI bus we assume
  12848. + * the clock is either 33 or 66 MHz; for an external source we cannot
  12849. + * tell the speed.
  12850. + *
  12851. + * PLL configuration is done with a string: "pci" for PCI bus, or "ext"
  12852. + * for an external source, followed by the frequency. We calculate
  12853. + * the appropriate multiplier and PLL register contents accordingly.
  12854. + * When no configuration is given we default to "pci66" since that
  12855. + * always will allow the card to work. If a card is using the PCI
  12856. + * bus clock and in a 33MHz slot then it will be operating at half
  12857. + * speed until the correct information is provided.
  12858. + *
  12859. + * We use a default setting of "ext66" because according to Mike Ham
  12860. + * of HiFn, almost every board in existence has an external crystal
  12861. + * populated at 66Mhz. Using PCI can be a problem on modern motherboards,
  12862. + * because PCI33 can have clocks from 0 to 33Mhz, and some have
  12863. + * non-PCI-compliant spread-spectrum clocks, which can confuse the pll.
  12864. + */
  12865. +static void
  12866. +hifn_getpllconfig(struct pci_dev *dev, u_int *pll)
  12867. +{
  12868. + const char *pllspec = hifn_pllconfig;
  12869. + u_int freq, mul, fl, fh;
  12870. + u_int32_t pllconfig;
  12871. + char *nxt;
  12872. +
  12873. + if (pllspec == NULL)
  12874. + pllspec = "ext66";
  12875. + fl = 33, fh = 66;
  12876. + pllconfig = 0;
  12877. + if (strncmp(pllspec, "ext", 3) == 0) {
  12878. + pllspec += 3;
  12879. + pllconfig |= HIFN_PLL_REF_SEL;
  12880. + switch (pci_get_device(dev)) {
  12881. + case PCI_PRODUCT_HIFN_7955:
  12882. + case PCI_PRODUCT_HIFN_7956:
  12883. + fl = 20, fh = 100;
  12884. + break;
  12885. +#ifdef notyet
  12886. + case PCI_PRODUCT_HIFN_7954:
  12887. + fl = 20, fh = 66;
  12888. + break;
  12889. +#endif
  12890. + }
  12891. + } else if (strncmp(pllspec, "pci", 3) == 0)
  12892. + pllspec += 3;
  12893. + freq = strtoul(pllspec, &nxt, 10);
  12894. + if (nxt == pllspec)
  12895. + freq = 66;
  12896. + else
  12897. + freq = checkmaxmin(dev, "frequency", freq, fl, fh);
  12898. + /*
  12899. + * Calculate multiplier. We target a Fck of 266 MHz,
  12900. + * allowing only even values, possibly rounded down.
  12901. + * Multipliers > 8 must set the charge pump current.
  12902. + */
  12903. + mul = checkmaxmin(dev, "PLL divisor", (266 / freq) &~ 1, 2, 12);
  12904. + pllconfig |= (mul / 2 - 1) << HIFN_PLL_ND_SHIFT;
  12905. + if (mul > 8)
  12906. + pllconfig |= HIFN_PLL_IS;
  12907. + *pll = pllconfig;
  12908. +}
  12909. +
  12910. +/*
  12911. + * Attach an interface that successfully probed.
  12912. + */
  12913. +static int
  12914. +hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  12915. +{
  12916. + struct hifn_softc *sc = NULL;
  12917. + char rbase;
  12918. + u_int16_t ena, rev;
  12919. + int rseg, rc;
  12920. + unsigned long mem_start, mem_len;
  12921. + static int num_chips = 0;
  12922. +
  12923. + DPRINTF("%s()\n", __FUNCTION__);
  12924. +
  12925. + if (pci_enable_device(dev) < 0)
  12926. + return(-ENODEV);
  12927. +
  12928. + if (pci_set_mwi(dev))
  12929. + return(-ENODEV);
  12930. +
  12931. + if (!dev->irq) {
  12932. + printk("hifn: found device with no IRQ assigned. check BIOS settings!");
  12933. + pci_disable_device(dev);
  12934. + return(-ENODEV);
  12935. + }
  12936. +
  12937. + sc = (struct hifn_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  12938. + if (!sc)
  12939. + return(-ENOMEM);
  12940. + memset(sc, 0, sizeof(*sc));
  12941. +
  12942. + softc_device_init(sc, "hifn", num_chips, hifn_methods);
  12943. +
  12944. + sc->sc_pcidev = dev;
  12945. + sc->sc_irq = -1;
  12946. + sc->sc_cid = -1;
  12947. + sc->sc_num = num_chips++;
  12948. + if (sc->sc_num < HIFN_MAX_CHIPS)
  12949. + hifn_chip_idx[sc->sc_num] = sc;
  12950. +
  12951. + pci_set_drvdata(sc->sc_pcidev, sc);
  12952. +
  12953. + spin_lock_init(&sc->sc_mtx);
  12954. +
  12955. + /* XXX handle power management */
  12956. +
  12957. + /*
  12958. + * The 7951 and 795x have a random number generator and
  12959. + * public key support; note this.
  12960. + */
  12961. + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
  12962. + (pci_get_device(dev) == PCI_PRODUCT_HIFN_7951 ||
  12963. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
  12964. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7956))
  12965. + sc->sc_flags = HIFN_HAS_RNG | HIFN_HAS_PUBLIC;
  12966. + /*
  12967. + * The 7811 has a random number generator and
  12968. + * we also note it's identity 'cuz of some quirks.
  12969. + */
  12970. + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
  12971. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7811)
  12972. + sc->sc_flags |= HIFN_IS_7811 | HIFN_HAS_RNG;
  12973. +
  12974. + /*
  12975. + * The 795x parts support AES.
  12976. + */
  12977. + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
  12978. + (pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
  12979. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7956)) {
  12980. + sc->sc_flags |= HIFN_IS_7956 | HIFN_HAS_AES;
  12981. + /*
  12982. + * Select PLL configuration. This depends on the
  12983. + * bus and board design and must be manually configured
  12984. + * if the default setting is unacceptable.
  12985. + */
  12986. + hifn_getpllconfig(dev, &sc->sc_pllconfig);
  12987. + }
  12988. +
  12989. + /*
  12990. + * Setup PCI resources. Note that we record the bus
  12991. + * tag and handle for each register mapping, this is
  12992. + * used by the READ_REG_0, WRITE_REG_0, READ_REG_1,
  12993. + * and WRITE_REG_1 macros throughout the driver.
  12994. + */
  12995. + mem_start = pci_resource_start(sc->sc_pcidev, 0);
  12996. + mem_len = pci_resource_len(sc->sc_pcidev, 0);
  12997. + sc->sc_bar0 = (ocf_iomem_t) ioremap(mem_start, mem_len);
  12998. + if (!sc->sc_bar0) {
  12999. + device_printf(sc->sc_dev, "cannot map bar%d register space\n", 0);
  13000. + goto fail;
  13001. + }
  13002. + sc->sc_bar0_lastreg = (bus_size_t) -1;
  13003. +
  13004. + mem_start = pci_resource_start(sc->sc_pcidev, 1);
  13005. + mem_len = pci_resource_len(sc->sc_pcidev, 1);
  13006. + sc->sc_bar1 = (ocf_iomem_t) ioremap(mem_start, mem_len);
  13007. + if (!sc->sc_bar1) {
  13008. + device_printf(sc->sc_dev, "cannot map bar%d register space\n", 1);
  13009. + goto fail;
  13010. + }
  13011. + sc->sc_bar1_lastreg = (bus_size_t) -1;
  13012. +
  13013. + /* fix up the bus size */
  13014. + if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
  13015. + device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
  13016. + goto fail;
  13017. + }
  13018. + if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) {
  13019. + device_printf(sc->sc_dev,
  13020. + "No usable consistent DMA configuration, aborting.\n");
  13021. + goto fail;
  13022. + }
  13023. +
  13024. + hifn_set_retry(sc);
  13025. +
  13026. + /*
  13027. + * Setup the area where the Hifn DMA's descriptors
  13028. + * and associated data structures.
  13029. + */
  13030. + sc->sc_dma = (struct hifn_dma *) pci_alloc_consistent(dev,
  13031. + sizeof(*sc->sc_dma),
  13032. + &sc->sc_dma_physaddr);
  13033. + if (!sc->sc_dma) {
  13034. + device_printf(sc->sc_dev, "cannot alloc sc_dma\n");
  13035. + goto fail;
  13036. + }
  13037. + bzero(sc->sc_dma, sizeof(*sc->sc_dma));
  13038. +
  13039. + /*
  13040. + * Reset the board and do the ``secret handshake''
  13041. + * to enable the crypto support. Then complete the
  13042. + * initialization procedure by setting up the interrupt
  13043. + * and hooking in to the system crypto support so we'll
  13044. + * get used for system services like the crypto device,
  13045. + * IPsec, RNG device, etc.
  13046. + */
  13047. + hifn_reset_board(sc, 0);
  13048. +
  13049. + if (hifn_enable_crypto(sc) != 0) {
  13050. + device_printf(sc->sc_dev, "crypto enabling failed\n");
  13051. + goto fail;
  13052. + }
  13053. + hifn_reset_puc(sc);
  13054. +
  13055. + hifn_init_dma(sc);
  13056. + hifn_init_pci_registers(sc);
  13057. +
  13058. + pci_set_master(sc->sc_pcidev);
  13059. +
  13060. + /* XXX can't dynamically determine ram type for 795x; force dram */
  13061. + if (sc->sc_flags & HIFN_IS_7956)
  13062. + sc->sc_drammodel = 1;
  13063. + else if (hifn_ramtype(sc))
  13064. + goto fail;
  13065. +
  13066. + if (sc->sc_drammodel == 0)
  13067. + hifn_sramsize(sc);
  13068. + else
  13069. + hifn_dramsize(sc);
  13070. +
  13071. + /*
  13072. + * Workaround for NetSec 7751 rev A: half ram size because two
  13073. + * of the address lines were left floating
  13074. + */
  13075. + if (pci_get_vendor(dev) == PCI_VENDOR_NETSEC &&
  13076. + pci_get_device(dev) == PCI_PRODUCT_NETSEC_7751 &&
  13077. + pci_get_revid(dev) == 0x61) /*XXX???*/
  13078. + sc->sc_ramsize >>= 1;
  13079. +
  13080. + /*
  13081. + * Arrange the interrupt line.
  13082. + */
  13083. + rc = request_irq(dev->irq, hifn_intr, IRQF_SHARED, "hifn", sc);
  13084. + if (rc) {
  13085. + device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
  13086. + goto fail;
  13087. + }
  13088. + sc->sc_irq = dev->irq;
  13089. +
  13090. + hifn_sessions(sc);
  13091. +
  13092. + /*
  13093. + * NB: Keep only the low 16 bits; this masks the chip id
  13094. + * from the 7951.
  13095. + */
  13096. + rev = READ_REG_1(sc, HIFN_1_REVID) & 0xffff;
  13097. +
  13098. + rseg = sc->sc_ramsize / 1024;
  13099. + rbase = 'K';
  13100. + if (sc->sc_ramsize >= (1024 * 1024)) {
  13101. + rbase = 'M';
  13102. + rseg /= 1024;
  13103. + }
  13104. + device_printf(sc->sc_dev, "%s, rev %u, %d%cB %cram",
  13105. + hifn_partname(sc), rev,
  13106. + rseg, rbase, sc->sc_drammodel ? 'd' : 's');
  13107. + if (sc->sc_flags & HIFN_IS_7956)
  13108. + printf(", pll=0x%x<%s clk, %ux mult>",
  13109. + sc->sc_pllconfig,
  13110. + sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
  13111. + 2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
  13112. + printf("\n");
  13113. +
  13114. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
  13115. + if (sc->sc_cid < 0) {
  13116. + device_printf(sc->sc_dev, "could not get crypto driver id\n");
  13117. + goto fail;
  13118. + }
  13119. +
  13120. + WRITE_REG_0(sc, HIFN_0_PUCNFG,
  13121. + READ_REG_0(sc, HIFN_0_PUCNFG) | HIFN_PUCNFG_CHIPID);
  13122. + ena = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
  13123. +
  13124. + switch (ena) {
  13125. + case HIFN_PUSTAT_ENA_2:
  13126. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  13127. + crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
  13128. + if (sc->sc_flags & HIFN_HAS_AES)
  13129. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  13130. + /*FALLTHROUGH*/
  13131. + case HIFN_PUSTAT_ENA_1:
  13132. + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
  13133. + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
  13134. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  13135. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  13136. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  13137. + break;
  13138. + }
  13139. +
  13140. + if (sc->sc_flags & (HIFN_HAS_PUBLIC | HIFN_HAS_RNG))
  13141. + hifn_init_pubrng(sc);
  13142. +
  13143. + init_timer(&sc->sc_tickto);
  13144. + sc->sc_tickto.function = hifn_tick;
  13145. + sc->sc_tickto.data = (unsigned long) sc->sc_num;
  13146. + mod_timer(&sc->sc_tickto, jiffies + HZ);
  13147. +
  13148. + return (0);
  13149. +
  13150. +fail:
  13151. + if (sc->sc_cid >= 0)
  13152. + crypto_unregister_all(sc->sc_cid);
  13153. + if (sc->sc_irq != -1)
  13154. + free_irq(sc->sc_irq, sc);
  13155. + if (sc->sc_dma) {
  13156. + /* Turn off DMA polling */
  13157. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  13158. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  13159. +
  13160. + pci_free_consistent(sc->sc_pcidev,
  13161. + sizeof(*sc->sc_dma),
  13162. + sc->sc_dma, sc->sc_dma_physaddr);
  13163. + }
  13164. + kfree(sc);
  13165. + return (-ENXIO);
  13166. +}
  13167. +
  13168. +/*
  13169. + * Detach an interface that successfully probed.
  13170. + */
  13171. +static void
  13172. +hifn_remove(struct pci_dev *dev)
  13173. +{
  13174. + struct hifn_softc *sc = pci_get_drvdata(dev);
  13175. + unsigned long l_flags;
  13176. +
  13177. + DPRINTF("%s()\n", __FUNCTION__);
  13178. +
  13179. + KASSERT(sc != NULL, ("hifn_detach: null software carrier!"));
  13180. +
  13181. + /* disable interrupts */
  13182. + HIFN_LOCK(sc);
  13183. + WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
  13184. + HIFN_UNLOCK(sc);
  13185. +
  13186. + /*XXX other resources */
  13187. + del_timer_sync(&sc->sc_tickto);
  13188. +
  13189. + /* Turn off DMA polling */
  13190. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  13191. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  13192. +
  13193. + crypto_unregister_all(sc->sc_cid);
  13194. +
  13195. + free_irq(sc->sc_irq, sc);
  13196. +
  13197. + pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
  13198. + sc->sc_dma, sc->sc_dma_physaddr);
  13199. +}
  13200. +
  13201. +
  13202. +static int
  13203. +hifn_init_pubrng(struct hifn_softc *sc)
  13204. +{
  13205. + int i;
  13206. +
  13207. + DPRINTF("%s()\n", __FUNCTION__);
  13208. +
  13209. + if ((sc->sc_flags & HIFN_IS_7811) == 0) {
  13210. + /* Reset 7951 public key/rng engine */
  13211. + WRITE_REG_1(sc, HIFN_1_PUB_RESET,
  13212. + READ_REG_1(sc, HIFN_1_PUB_RESET) | HIFN_PUBRST_RESET);
  13213. +
  13214. + for (i = 0; i < 100; i++) {
  13215. + DELAY(1000);
  13216. + if ((READ_REG_1(sc, HIFN_1_PUB_RESET) &
  13217. + HIFN_PUBRST_RESET) == 0)
  13218. + break;
  13219. + }
  13220. +
  13221. + if (i == 100) {
  13222. + device_printf(sc->sc_dev, "public key init failed\n");
  13223. + return (1);
  13224. + }
  13225. + }
  13226. +
  13227. + /* Enable the rng, if available */
  13228. +#ifdef CONFIG_OCF_RANDOMHARVEST
  13229. + if (sc->sc_flags & HIFN_HAS_RNG) {
  13230. + if (sc->sc_flags & HIFN_IS_7811) {
  13231. + u_int32_t r;
  13232. + r = READ_REG_1(sc, HIFN_1_7811_RNGENA);
  13233. + if (r & HIFN_7811_RNGENA_ENA) {
  13234. + r &= ~HIFN_7811_RNGENA_ENA;
  13235. + WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
  13236. + }
  13237. + WRITE_REG_1(sc, HIFN_1_7811_RNGCFG,
  13238. + HIFN_7811_RNGCFG_DEFL);
  13239. + r |= HIFN_7811_RNGENA_ENA;
  13240. + WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
  13241. + } else
  13242. + WRITE_REG_1(sc, HIFN_1_RNG_CONFIG,
  13243. + READ_REG_1(sc, HIFN_1_RNG_CONFIG) |
  13244. + HIFN_RNGCFG_ENA);
  13245. +
  13246. + sc->sc_rngfirst = 1;
  13247. + crypto_rregister(sc->sc_cid, hifn_read_random, sc);
  13248. + }
  13249. +#endif
  13250. +
  13251. + /* Enable public key engine, if available */
  13252. + if (sc->sc_flags & HIFN_HAS_PUBLIC) {
  13253. + WRITE_REG_1(sc, HIFN_1_PUB_IEN, HIFN_PUBIEN_DONE);
  13254. + sc->sc_dmaier |= HIFN_DMAIER_PUBDONE;
  13255. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  13256. +#ifdef HIFN_VULCANDEV
  13257. + sc->sc_pkdev = make_dev(&vulcanpk_cdevsw, 0,
  13258. + UID_ROOT, GID_WHEEL, 0666,
  13259. + "vulcanpk");
  13260. + sc->sc_pkdev->si_drv1 = sc;
  13261. +#endif
  13262. + }
  13263. +
  13264. + return (0);
  13265. +}
  13266. +
  13267. +#ifdef CONFIG_OCF_RANDOMHARVEST
  13268. +static int
  13269. +hifn_read_random(void *arg, u_int32_t *buf, int len)
  13270. +{
  13271. + struct hifn_softc *sc = (struct hifn_softc *) arg;
  13272. + u_int32_t sts;
  13273. + int i, rc = 0;
  13274. +
  13275. + if (len <= 0)
  13276. + return rc;
  13277. +
  13278. + if (sc->sc_flags & HIFN_IS_7811) {
  13279. + /* ONLY VALID ON 7811!!!! */
  13280. + for (i = 0; i < 5; i++) {
  13281. + sts = READ_REG_1(sc, HIFN_1_7811_RNGSTS);
  13282. + if (sts & HIFN_7811_RNGSTS_UFL) {
  13283. + device_printf(sc->sc_dev,
  13284. + "RNG underflow: disabling\n");
  13285. + /* DAVIDM perhaps return -1 */
  13286. + break;
  13287. + }
  13288. + if ((sts & HIFN_7811_RNGSTS_RDY) == 0)
  13289. + break;
  13290. +
  13291. + /*
  13292. + * There are at least two words in the RNG FIFO
  13293. + * at this point.
  13294. + */
  13295. + if (rc < len)
  13296. + buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
  13297. + if (rc < len)
  13298. + buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
  13299. + }
  13300. + } else
  13301. + buf[rc++] = READ_REG_1(sc, HIFN_1_RNG_DATA);
  13302. +
  13303. + /* NB: discard first data read */
  13304. + if (sc->sc_rngfirst) {
  13305. + sc->sc_rngfirst = 0;
  13306. + rc = 0;
  13307. + }
  13308. +
  13309. + return(rc);
  13310. +}
  13311. +#endif /* CONFIG_OCF_RANDOMHARVEST */
  13312. +
  13313. +static void
  13314. +hifn_puc_wait(struct hifn_softc *sc)
  13315. +{
  13316. + int i;
  13317. + int reg = HIFN_0_PUCTRL;
  13318. +
  13319. + if (sc->sc_flags & HIFN_IS_7956) {
  13320. + reg = HIFN_0_PUCTRL2;
  13321. + }
  13322. +
  13323. + for (i = 5000; i > 0; i--) {
  13324. + DELAY(1);
  13325. + if (!(READ_REG_0(sc, reg) & HIFN_PUCTRL_RESET))
  13326. + break;
  13327. + }
  13328. + if (!i)
  13329. + device_printf(sc->sc_dev, "proc unit did not reset(0x%x)\n",
  13330. + READ_REG_0(sc, HIFN_0_PUCTRL));
  13331. +}
  13332. +
  13333. +/*
  13334. + * Reset the processing unit.
  13335. + */
  13336. +static void
  13337. +hifn_reset_puc(struct hifn_softc *sc)
  13338. +{
  13339. + /* Reset processing unit */
  13340. + int reg = HIFN_0_PUCTRL;
  13341. +
  13342. + if (sc->sc_flags & HIFN_IS_7956) {
  13343. + reg = HIFN_0_PUCTRL2;
  13344. + }
  13345. + WRITE_REG_0(sc, reg, HIFN_PUCTRL_DMAENA);
  13346. +
  13347. + hifn_puc_wait(sc);
  13348. +}
  13349. +
  13350. +/*
  13351. + * Set the Retry and TRDY registers; note that we set them to
  13352. + * zero because the 7811 locks up when forced to retry (section
  13353. + * 3.6 of "Specification Update SU-0014-04". Not clear if we
  13354. + * should do this for all Hifn parts, but it doesn't seem to hurt.
  13355. + */
  13356. +static void
  13357. +hifn_set_retry(struct hifn_softc *sc)
  13358. +{
  13359. + DPRINTF("%s()\n", __FUNCTION__);
  13360. + /* NB: RETRY only responds to 8-bit reads/writes */
  13361. + pci_write_config_byte(sc->sc_pcidev, HIFN_RETRY_TIMEOUT, 0);
  13362. + pci_write_config_dword(sc->sc_pcidev, HIFN_TRDY_TIMEOUT, 0);
  13363. + /* piggy back the cache line setting here */
  13364. + pci_write_config_byte(sc->sc_pcidev, PCI_CACHE_LINE_SIZE, hifn_cache_linesize);
  13365. +}
  13366. +
  13367. +/*
  13368. + * Resets the board. Values in the regesters are left as is
  13369. + * from the reset (i.e. initial values are assigned elsewhere).
  13370. + */
  13371. +static void
  13372. +hifn_reset_board(struct hifn_softc *sc, int full)
  13373. +{
  13374. + u_int32_t reg;
  13375. +
  13376. + DPRINTF("%s()\n", __FUNCTION__);
  13377. + /*
  13378. + * Set polling in the DMA configuration register to zero. 0x7 avoids
  13379. + * resetting the board and zeros out the other fields.
  13380. + */
  13381. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  13382. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  13383. +
  13384. + /*
  13385. + * Now that polling has been disabled, we have to wait 1 ms
  13386. + * before resetting the board.
  13387. + */
  13388. + DELAY(1000);
  13389. +
  13390. + /* Reset the DMA unit */
  13391. + if (full) {
  13392. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MODE);
  13393. + DELAY(1000);
  13394. + } else {
  13395. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG,
  13396. + HIFN_DMACNFG_MODE | HIFN_DMACNFG_MSTRESET);
  13397. + hifn_reset_puc(sc);
  13398. + }
  13399. +
  13400. + KASSERT(sc->sc_dma != NULL, ("hifn_reset_board: null DMA tag!"));
  13401. + bzero(sc->sc_dma, sizeof(*sc->sc_dma));
  13402. +
  13403. + /* Bring dma unit out of reset */
  13404. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  13405. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  13406. +
  13407. + hifn_puc_wait(sc);
  13408. + hifn_set_retry(sc);
  13409. +
  13410. + if (sc->sc_flags & HIFN_IS_7811) {
  13411. + for (reg = 0; reg < 1000; reg++) {
  13412. + if (READ_REG_1(sc, HIFN_1_7811_MIPSRST) &
  13413. + HIFN_MIPSRST_CRAMINIT)
  13414. + break;
  13415. + DELAY(1000);
  13416. + }
  13417. + if (reg == 1000)
  13418. + device_printf(sc->sc_dev, ": cram init timeout\n");
  13419. + } else {
  13420. + /* set up DMA configuration register #2 */
  13421. + /* turn off all PK and BAR0 swaps */
  13422. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG2,
  13423. + (3 << HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT)|
  13424. + (3 << HIFN_DMACNFG2_INIT_READ_BURST_SHIFT)|
  13425. + (2 << HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT)|
  13426. + (2 << HIFN_DMACNFG2_TGT_READ_BURST_SHIFT));
  13427. + }
  13428. +}
  13429. +
  13430. +static u_int32_t
  13431. +hifn_next_signature(u_int32_t a, u_int cnt)
  13432. +{
  13433. + int i;
  13434. + u_int32_t v;
  13435. +
  13436. + for (i = 0; i < cnt; i++) {
  13437. +
  13438. + /* get the parity */
  13439. + v = a & 0x80080125;
  13440. + v ^= v >> 16;
  13441. + v ^= v >> 8;
  13442. + v ^= v >> 4;
  13443. + v ^= v >> 2;
  13444. + v ^= v >> 1;
  13445. +
  13446. + a = (v & 1) ^ (a << 1);
  13447. + }
  13448. +
  13449. + return a;
  13450. +}
  13451. +
  13452. +
  13453. +/*
  13454. + * Checks to see if crypto is already enabled. If crypto isn't enable,
  13455. + * "hifn_enable_crypto" is called to enable it. The check is important,
  13456. + * as enabling crypto twice will lock the board.
  13457. + */
  13458. +static int
  13459. +hifn_enable_crypto(struct hifn_softc *sc)
  13460. +{
  13461. + u_int32_t dmacfg, ramcfg, encl, addr, i;
  13462. + char offtbl[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  13463. + 0x00, 0x00, 0x00, 0x00 };
  13464. +
  13465. + DPRINTF("%s()\n", __FUNCTION__);
  13466. +
  13467. + ramcfg = READ_REG_0(sc, HIFN_0_PUCNFG);
  13468. + dmacfg = READ_REG_1(sc, HIFN_1_DMA_CNFG);
  13469. +
  13470. + /*
  13471. + * The RAM config register's encrypt level bit needs to be set before
  13472. + * every read performed on the encryption level register.
  13473. + */
  13474. + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
  13475. +
  13476. + encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
  13477. +
  13478. + /*
  13479. + * Make sure we don't re-unlock. Two unlocks kills chip until the
  13480. + * next reboot.
  13481. + */
  13482. + if (encl == HIFN_PUSTAT_ENA_1 || encl == HIFN_PUSTAT_ENA_2) {
  13483. +#ifdef HIFN_DEBUG
  13484. + if (hifn_debug)
  13485. + device_printf(sc->sc_dev,
  13486. + "Strong crypto already enabled!\n");
  13487. +#endif
  13488. + goto report;
  13489. + }
  13490. +
  13491. + if (encl != 0 && encl != HIFN_PUSTAT_ENA_0) {
  13492. +#ifdef HIFN_DEBUG
  13493. + if (hifn_debug)
  13494. + device_printf(sc->sc_dev,
  13495. + "Unknown encryption level 0x%x\n", encl);
  13496. +#endif
  13497. + return 1;
  13498. + }
  13499. +
  13500. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_UNLOCK |
  13501. + HIFN_DMACNFG_MSTRESET | HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  13502. + DELAY(1000);
  13503. + addr = READ_REG_1(sc, HIFN_UNLOCK_SECRET1);
  13504. + DELAY(1000);
  13505. + WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, 0);
  13506. + DELAY(1000);
  13507. +
  13508. + for (i = 0; i <= 12; i++) {
  13509. + addr = hifn_next_signature(addr, offtbl[i] + 0x101);
  13510. + WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, addr);
  13511. +
  13512. + DELAY(1000);
  13513. + }
  13514. +
  13515. + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
  13516. + encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
  13517. +
  13518. +#ifdef HIFN_DEBUG
  13519. + if (hifn_debug) {
  13520. + if (encl != HIFN_PUSTAT_ENA_1 && encl != HIFN_PUSTAT_ENA_2)
  13521. + device_printf(sc->sc_dev, "Engine is permanently "
  13522. + "locked until next system reset!\n");
  13523. + else
  13524. + device_printf(sc->sc_dev, "Engine enabled "
  13525. + "successfully!\n");
  13526. + }
  13527. +#endif
  13528. +
  13529. +report:
  13530. + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg);
  13531. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, dmacfg);
  13532. +
  13533. + switch (encl) {
  13534. + case HIFN_PUSTAT_ENA_1:
  13535. + case HIFN_PUSTAT_ENA_2:
  13536. + break;
  13537. + case HIFN_PUSTAT_ENA_0:
  13538. + default:
  13539. + device_printf(sc->sc_dev, "disabled\n");
  13540. + break;
  13541. + }
  13542. +
  13543. + return 0;
  13544. +}
  13545. +
  13546. +/*
  13547. + * Give initial values to the registers listed in the "Register Space"
  13548. + * section of the HIFN Software Development reference manual.
  13549. + */
  13550. +static void
  13551. +hifn_init_pci_registers(struct hifn_softc *sc)
  13552. +{
  13553. + DPRINTF("%s()\n", __FUNCTION__);
  13554. +
  13555. + /* write fixed values needed by the Initialization registers */
  13556. + WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA);
  13557. + WRITE_REG_0(sc, HIFN_0_FIFOCNFG, HIFN_FIFOCNFG_THRESHOLD);
  13558. + WRITE_REG_0(sc, HIFN_0_PUIER, HIFN_PUIER_DSTOVER);
  13559. +
  13560. + /* write all 4 ring address registers */
  13561. + WRITE_REG_1(sc, HIFN_1_DMA_CRAR, sc->sc_dma_physaddr +
  13562. + offsetof(struct hifn_dma, cmdr[0]));
  13563. + WRITE_REG_1(sc, HIFN_1_DMA_SRAR, sc->sc_dma_physaddr +
  13564. + offsetof(struct hifn_dma, srcr[0]));
  13565. + WRITE_REG_1(sc, HIFN_1_DMA_DRAR, sc->sc_dma_physaddr +
  13566. + offsetof(struct hifn_dma, dstr[0]));
  13567. + WRITE_REG_1(sc, HIFN_1_DMA_RRAR, sc->sc_dma_physaddr +
  13568. + offsetof(struct hifn_dma, resr[0]));
  13569. +
  13570. + DELAY(2000);
  13571. +
  13572. + /* write status register */
  13573. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  13574. + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS |
  13575. + HIFN_DMACSR_S_CTRL_DIS | HIFN_DMACSR_C_CTRL_DIS |
  13576. + HIFN_DMACSR_D_ABORT | HIFN_DMACSR_D_DONE | HIFN_DMACSR_D_LAST |
  13577. + HIFN_DMACSR_D_WAIT | HIFN_DMACSR_D_OVER |
  13578. + HIFN_DMACSR_R_ABORT | HIFN_DMACSR_R_DONE | HIFN_DMACSR_R_LAST |
  13579. + HIFN_DMACSR_R_WAIT | HIFN_DMACSR_R_OVER |
  13580. + HIFN_DMACSR_S_ABORT | HIFN_DMACSR_S_DONE | HIFN_DMACSR_S_LAST |
  13581. + HIFN_DMACSR_S_WAIT |
  13582. + HIFN_DMACSR_C_ABORT | HIFN_DMACSR_C_DONE | HIFN_DMACSR_C_LAST |
  13583. + HIFN_DMACSR_C_WAIT |
  13584. + HIFN_DMACSR_ENGINE |
  13585. + ((sc->sc_flags & HIFN_HAS_PUBLIC) ?
  13586. + HIFN_DMACSR_PUBDONE : 0) |
  13587. + ((sc->sc_flags & HIFN_IS_7811) ?
  13588. + HIFN_DMACSR_ILLW | HIFN_DMACSR_ILLR : 0));
  13589. +
  13590. + sc->sc_d_busy = sc->sc_r_busy = sc->sc_s_busy = sc->sc_c_busy = 0;
  13591. + sc->sc_dmaier |= HIFN_DMAIER_R_DONE | HIFN_DMAIER_C_ABORT |
  13592. + HIFN_DMAIER_D_OVER | HIFN_DMAIER_R_OVER |
  13593. + HIFN_DMAIER_S_ABORT | HIFN_DMAIER_D_ABORT | HIFN_DMAIER_R_ABORT |
  13594. + ((sc->sc_flags & HIFN_IS_7811) ?
  13595. + HIFN_DMAIER_ILLW | HIFN_DMAIER_ILLR : 0);
  13596. + sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
  13597. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  13598. +
  13599. +
  13600. + if (sc->sc_flags & HIFN_IS_7956) {
  13601. + u_int32_t pll;
  13602. +
  13603. + WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
  13604. + HIFN_PUCNFG_TCALLPHASES |
  13605. + HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32);
  13606. +
  13607. + /* turn off the clocks and insure bypass is set */
  13608. + pll = READ_REG_1(sc, HIFN_1_PLL);
  13609. + pll = (pll &~ (HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL))
  13610. + | HIFN_PLL_BP | HIFN_PLL_MBSET;
  13611. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  13612. + DELAY(10*1000); /* 10ms */
  13613. +
  13614. + /* change configuration */
  13615. + pll = (pll &~ HIFN_PLL_CONFIG) | sc->sc_pllconfig;
  13616. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  13617. + DELAY(10*1000); /* 10ms */
  13618. +
  13619. + /* disable bypass */
  13620. + pll &= ~HIFN_PLL_BP;
  13621. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  13622. + /* enable clocks with new configuration */
  13623. + pll |= HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL;
  13624. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  13625. + } else {
  13626. + WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
  13627. + HIFN_PUCNFG_DRFR_128 | HIFN_PUCNFG_TCALLPHASES |
  13628. + HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32 |
  13629. + (sc->sc_drammodel ? HIFN_PUCNFG_DRAM : HIFN_PUCNFG_SRAM));
  13630. + }
  13631. +
  13632. + WRITE_REG_0(sc, HIFN_0_PUISR, HIFN_PUISR_DSTOVER);
  13633. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  13634. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE | HIFN_DMACNFG_LAST |
  13635. + ((HIFN_POLL_FREQUENCY << 16 ) & HIFN_DMACNFG_POLLFREQ) |
  13636. + ((HIFN_POLL_SCALAR << 8) & HIFN_DMACNFG_POLLINVAL));
  13637. +}
  13638. +
  13639. +/*
  13640. + * The maximum number of sessions supported by the card
  13641. + * is dependent on the amount of context ram, which
  13642. + * encryption algorithms are enabled, and how compression
  13643. + * is configured. This should be configured before this
  13644. + * routine is called.
  13645. + */
  13646. +static void
  13647. +hifn_sessions(struct hifn_softc *sc)
  13648. +{
  13649. + u_int32_t pucnfg;
  13650. + int ctxsize;
  13651. +
  13652. + DPRINTF("%s()\n", __FUNCTION__);
  13653. +
  13654. + pucnfg = READ_REG_0(sc, HIFN_0_PUCNFG);
  13655. +
  13656. + if (pucnfg & HIFN_PUCNFG_COMPSING) {
  13657. + if (pucnfg & HIFN_PUCNFG_ENCCNFG)
  13658. + ctxsize = 128;
  13659. + else
  13660. + ctxsize = 512;
  13661. + /*
  13662. + * 7955/7956 has internal context memory of 32K
  13663. + */
  13664. + if (sc->sc_flags & HIFN_IS_7956)
  13665. + sc->sc_maxses = 32768 / ctxsize;
  13666. + else
  13667. + sc->sc_maxses = 1 +
  13668. + ((sc->sc_ramsize - 32768) / ctxsize);
  13669. + } else
  13670. + sc->sc_maxses = sc->sc_ramsize / 16384;
  13671. +
  13672. + if (sc->sc_maxses > 2048)
  13673. + sc->sc_maxses = 2048;
  13674. +}
  13675. +
  13676. +/*
  13677. + * Determine ram type (sram or dram). Board should be just out of a reset
  13678. + * state when this is called.
  13679. + */
  13680. +static int
  13681. +hifn_ramtype(struct hifn_softc *sc)
  13682. +{
  13683. + u_int8_t data[8], dataexpect[8];
  13684. + int i;
  13685. +
  13686. + for (i = 0; i < sizeof(data); i++)
  13687. + data[i] = dataexpect[i] = 0x55;
  13688. + if (hifn_writeramaddr(sc, 0, data))
  13689. + return (-1);
  13690. + if (hifn_readramaddr(sc, 0, data))
  13691. + return (-1);
  13692. + if (bcmp(data, dataexpect, sizeof(data)) != 0) {
  13693. + sc->sc_drammodel = 1;
  13694. + return (0);
  13695. + }
  13696. +
  13697. + for (i = 0; i < sizeof(data); i++)
  13698. + data[i] = dataexpect[i] = 0xaa;
  13699. + if (hifn_writeramaddr(sc, 0, data))
  13700. + return (-1);
  13701. + if (hifn_readramaddr(sc, 0, data))
  13702. + return (-1);
  13703. + if (bcmp(data, dataexpect, sizeof(data)) != 0) {
  13704. + sc->sc_drammodel = 1;
  13705. + return (0);
  13706. + }
  13707. +
  13708. + return (0);
  13709. +}
  13710. +
  13711. +#define HIFN_SRAM_MAX (32 << 20)
  13712. +#define HIFN_SRAM_STEP_SIZE 16384
  13713. +#define HIFN_SRAM_GRANULARITY (HIFN_SRAM_MAX / HIFN_SRAM_STEP_SIZE)
  13714. +
  13715. +static int
  13716. +hifn_sramsize(struct hifn_softc *sc)
  13717. +{
  13718. + u_int32_t a;
  13719. + u_int8_t data[8];
  13720. + u_int8_t dataexpect[sizeof(data)];
  13721. + int32_t i;
  13722. +
  13723. + for (i = 0; i < sizeof(data); i++)
  13724. + data[i] = dataexpect[i] = i ^ 0x5a;
  13725. +
  13726. + for (i = HIFN_SRAM_GRANULARITY - 1; i >= 0; i--) {
  13727. + a = i * HIFN_SRAM_STEP_SIZE;
  13728. + bcopy(&i, data, sizeof(i));
  13729. + hifn_writeramaddr(sc, a, data);
  13730. + }
  13731. +
  13732. + for (i = 0; i < HIFN_SRAM_GRANULARITY; i++) {
  13733. + a = i * HIFN_SRAM_STEP_SIZE;
  13734. + bcopy(&i, dataexpect, sizeof(i));
  13735. + if (hifn_readramaddr(sc, a, data) < 0)
  13736. + return (0);
  13737. + if (bcmp(data, dataexpect, sizeof(data)) != 0)
  13738. + return (0);
  13739. + sc->sc_ramsize = a + HIFN_SRAM_STEP_SIZE;
  13740. + }
  13741. +
  13742. + return (0);
  13743. +}
  13744. +
  13745. +/*
  13746. + * XXX For dram boards, one should really try all of the
  13747. + * HIFN_PUCNFG_DSZ_*'s. This just assumes that PUCNFG
  13748. + * is already set up correctly.
  13749. + */
  13750. +static int
  13751. +hifn_dramsize(struct hifn_softc *sc)
  13752. +{
  13753. + u_int32_t cnfg;
  13754. +
  13755. + if (sc->sc_flags & HIFN_IS_7956) {
  13756. + /*
  13757. + * 7955/7956 have a fixed internal ram of only 32K.
  13758. + */
  13759. + sc->sc_ramsize = 32768;
  13760. + } else {
  13761. + cnfg = READ_REG_0(sc, HIFN_0_PUCNFG) &
  13762. + HIFN_PUCNFG_DRAMMASK;
  13763. + sc->sc_ramsize = 1 << ((cnfg >> 13) + 18);
  13764. + }
  13765. + return (0);
  13766. +}
  13767. +
  13768. +static void
  13769. +hifn_alloc_slot(struct hifn_softc *sc, int *cmdp, int *srcp, int *dstp, int *resp)
  13770. +{
  13771. + struct hifn_dma *dma = sc->sc_dma;
  13772. +
  13773. + DPRINTF("%s()\n", __FUNCTION__);
  13774. +
  13775. + if (dma->cmdi == HIFN_D_CMD_RSIZE) {
  13776. + dma->cmdi = 0;
  13777. + dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  13778. + wmb();
  13779. + dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
  13780. + HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
  13781. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  13782. + }
  13783. + *cmdp = dma->cmdi++;
  13784. + dma->cmdk = dma->cmdi;
  13785. +
  13786. + if (dma->srci == HIFN_D_SRC_RSIZE) {
  13787. + dma->srci = 0;
  13788. + dma->srcr[HIFN_D_SRC_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  13789. + wmb();
  13790. + dma->srcr[HIFN_D_SRC_RSIZE].l |= htole32(HIFN_D_VALID);
  13791. + HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
  13792. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  13793. + }
  13794. + *srcp = dma->srci++;
  13795. + dma->srck = dma->srci;
  13796. +
  13797. + if (dma->dsti == HIFN_D_DST_RSIZE) {
  13798. + dma->dsti = 0;
  13799. + dma->dstr[HIFN_D_DST_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  13800. + wmb();
  13801. + dma->dstr[HIFN_D_DST_RSIZE].l |= htole32(HIFN_D_VALID);
  13802. + HIFN_DSTR_SYNC(sc, HIFN_D_DST_RSIZE,
  13803. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  13804. + }
  13805. + *dstp = dma->dsti++;
  13806. + dma->dstk = dma->dsti;
  13807. +
  13808. + if (dma->resi == HIFN_D_RES_RSIZE) {
  13809. + dma->resi = 0;
  13810. + dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  13811. + wmb();
  13812. + dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
  13813. + HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
  13814. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  13815. + }
  13816. + *resp = dma->resi++;
  13817. + dma->resk = dma->resi;
  13818. +}
  13819. +
  13820. +static int
  13821. +hifn_writeramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
  13822. +{
  13823. + struct hifn_dma *dma = sc->sc_dma;
  13824. + hifn_base_command_t wc;
  13825. + const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
  13826. + int r, cmdi, resi, srci, dsti;
  13827. +
  13828. + DPRINTF("%s()\n", __FUNCTION__);
  13829. +
  13830. + wc.masks = htole16(3 << 13);
  13831. + wc.session_num = htole16(addr >> 14);
  13832. + wc.total_source_count = htole16(8);
  13833. + wc.total_dest_count = htole16(addr & 0x3fff);
  13834. +
  13835. + hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
  13836. +
  13837. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  13838. + HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
  13839. + HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
  13840. +
  13841. + /* build write command */
  13842. + bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
  13843. + *(hifn_base_command_t *)dma->command_bufs[cmdi] = wc;
  13844. + bcopy(data, &dma->test_src, sizeof(dma->test_src));
  13845. +
  13846. + dma->srcr[srci].p = htole32(sc->sc_dma_physaddr
  13847. + + offsetof(struct hifn_dma, test_src));
  13848. + dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr
  13849. + + offsetof(struct hifn_dma, test_dst));
  13850. +
  13851. + dma->cmdr[cmdi].l = htole32(16 | masks);
  13852. + dma->srcr[srci].l = htole32(8 | masks);
  13853. + dma->dstr[dsti].l = htole32(4 | masks);
  13854. + dma->resr[resi].l = htole32(4 | masks);
  13855. +
  13856. + for (r = 10000; r >= 0; r--) {
  13857. + DELAY(10);
  13858. + if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
  13859. + break;
  13860. + }
  13861. + if (r == 0) {
  13862. + device_printf(sc->sc_dev, "writeramaddr -- "
  13863. + "result[%d](addr %d) still valid\n", resi, addr);
  13864. + r = -1;
  13865. + return (-1);
  13866. + } else
  13867. + r = 0;
  13868. +
  13869. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  13870. + HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
  13871. + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
  13872. +
  13873. + return (r);
  13874. +}
  13875. +
  13876. +static int
  13877. +hifn_readramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
  13878. +{
  13879. + struct hifn_dma *dma = sc->sc_dma;
  13880. + hifn_base_command_t rc;
  13881. + const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
  13882. + int r, cmdi, srci, dsti, resi;
  13883. +
  13884. + DPRINTF("%s()\n", __FUNCTION__);
  13885. +
  13886. + rc.masks = htole16(2 << 13);
  13887. + rc.session_num = htole16(addr >> 14);
  13888. + rc.total_source_count = htole16(addr & 0x3fff);
  13889. + rc.total_dest_count = htole16(8);
  13890. +
  13891. + hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
  13892. +
  13893. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  13894. + HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
  13895. + HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
  13896. +
  13897. + bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
  13898. + *(hifn_base_command_t *)dma->command_bufs[cmdi] = rc;
  13899. +
  13900. + dma->srcr[srci].p = htole32(sc->sc_dma_physaddr +
  13901. + offsetof(struct hifn_dma, test_src));
  13902. + dma->test_src = 0;
  13903. + dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr +
  13904. + offsetof(struct hifn_dma, test_dst));
  13905. + dma->test_dst = 0;
  13906. + dma->cmdr[cmdi].l = htole32(8 | masks);
  13907. + dma->srcr[srci].l = htole32(8 | masks);
  13908. + dma->dstr[dsti].l = htole32(8 | masks);
  13909. + dma->resr[resi].l = htole32(HIFN_MAX_RESULT | masks);
  13910. +
  13911. + for (r = 10000; r >= 0; r--) {
  13912. + DELAY(10);
  13913. + if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
  13914. + break;
  13915. + }
  13916. + if (r == 0) {
  13917. + device_printf(sc->sc_dev, "readramaddr -- "
  13918. + "result[%d](addr %d) still valid\n", resi, addr);
  13919. + r = -1;
  13920. + } else {
  13921. + r = 0;
  13922. + bcopy(&dma->test_dst, data, sizeof(dma->test_dst));
  13923. + }
  13924. +
  13925. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  13926. + HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
  13927. + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
  13928. +
  13929. + return (r);
  13930. +}
  13931. +
  13932. +/*
  13933. + * Initialize the descriptor rings.
  13934. + */
  13935. +static void
  13936. +hifn_init_dma(struct hifn_softc *sc)
  13937. +{
  13938. + struct hifn_dma *dma = sc->sc_dma;
  13939. + int i;
  13940. +
  13941. + DPRINTF("%s()\n", __FUNCTION__);
  13942. +
  13943. + hifn_set_retry(sc);
  13944. +
  13945. + /* initialize static pointer values */
  13946. + for (i = 0; i < HIFN_D_CMD_RSIZE; i++)
  13947. + dma->cmdr[i].p = htole32(sc->sc_dma_physaddr +
  13948. + offsetof(struct hifn_dma, command_bufs[i][0]));
  13949. + for (i = 0; i < HIFN_D_RES_RSIZE; i++)
  13950. + dma->resr[i].p = htole32(sc->sc_dma_physaddr +
  13951. + offsetof(struct hifn_dma, result_bufs[i][0]));
  13952. +
  13953. + dma->cmdr[HIFN_D_CMD_RSIZE].p =
  13954. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, cmdr[0]));
  13955. + dma->srcr[HIFN_D_SRC_RSIZE].p =
  13956. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, srcr[0]));
  13957. + dma->dstr[HIFN_D_DST_RSIZE].p =
  13958. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, dstr[0]));
  13959. + dma->resr[HIFN_D_RES_RSIZE].p =
  13960. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, resr[0]));
  13961. +
  13962. + dma->cmdu = dma->srcu = dma->dstu = dma->resu = 0;
  13963. + dma->cmdi = dma->srci = dma->dsti = dma->resi = 0;
  13964. + dma->cmdk = dma->srck = dma->dstk = dma->resk = 0;
  13965. +}
  13966. +
  13967. +/*
  13968. + * Writes out the raw command buffer space. Returns the
  13969. + * command buffer size.
  13970. + */
  13971. +static u_int
  13972. +hifn_write_command(struct hifn_command *cmd, u_int8_t *buf)
  13973. +{
  13974. + struct hifn_softc *sc = NULL;
  13975. + u_int8_t *buf_pos;
  13976. + hifn_base_command_t *base_cmd;
  13977. + hifn_mac_command_t *mac_cmd;
  13978. + hifn_crypt_command_t *cry_cmd;
  13979. + int using_mac, using_crypt, len, ivlen;
  13980. + u_int32_t dlen, slen;
  13981. +
  13982. + DPRINTF("%s()\n", __FUNCTION__);
  13983. +
  13984. + buf_pos = buf;
  13985. + using_mac = cmd->base_masks & HIFN_BASE_CMD_MAC;
  13986. + using_crypt = cmd->base_masks & HIFN_BASE_CMD_CRYPT;
  13987. +
  13988. + base_cmd = (hifn_base_command_t *)buf_pos;
  13989. + base_cmd->masks = htole16(cmd->base_masks);
  13990. + slen = cmd->src_mapsize;
  13991. + if (cmd->sloplen)
  13992. + dlen = cmd->dst_mapsize - cmd->sloplen + sizeof(u_int32_t);
  13993. + else
  13994. + dlen = cmd->dst_mapsize;
  13995. + base_cmd->total_source_count = htole16(slen & HIFN_BASE_CMD_LENMASK_LO);
  13996. + base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO);
  13997. + dlen >>= 16;
  13998. + slen >>= 16;
  13999. + base_cmd->session_num = htole16(
  14000. + ((slen << HIFN_BASE_CMD_SRCLEN_S) & HIFN_BASE_CMD_SRCLEN_M) |
  14001. + ((dlen << HIFN_BASE_CMD_DSTLEN_S) & HIFN_BASE_CMD_DSTLEN_M));
  14002. + buf_pos += sizeof(hifn_base_command_t);
  14003. +
  14004. + if (using_mac) {
  14005. + mac_cmd = (hifn_mac_command_t *)buf_pos;
  14006. + dlen = cmd->maccrd->crd_len;
  14007. + mac_cmd->source_count = htole16(dlen & 0xffff);
  14008. + dlen >>= 16;
  14009. + mac_cmd->masks = htole16(cmd->mac_masks |
  14010. + ((dlen << HIFN_MAC_CMD_SRCLEN_S) & HIFN_MAC_CMD_SRCLEN_M));
  14011. + mac_cmd->header_skip = htole16(cmd->maccrd->crd_skip);
  14012. + mac_cmd->reserved = 0;
  14013. + buf_pos += sizeof(hifn_mac_command_t);
  14014. + }
  14015. +
  14016. + if (using_crypt) {
  14017. + cry_cmd = (hifn_crypt_command_t *)buf_pos;
  14018. + dlen = cmd->enccrd->crd_len;
  14019. + cry_cmd->source_count = htole16(dlen & 0xffff);
  14020. + dlen >>= 16;
  14021. + cry_cmd->masks = htole16(cmd->cry_masks |
  14022. + ((dlen << HIFN_CRYPT_CMD_SRCLEN_S) & HIFN_CRYPT_CMD_SRCLEN_M));
  14023. + cry_cmd->header_skip = htole16(cmd->enccrd->crd_skip);
  14024. + cry_cmd->reserved = 0;
  14025. + buf_pos += sizeof(hifn_crypt_command_t);
  14026. + }
  14027. +
  14028. + if (using_mac && cmd->mac_masks & HIFN_MAC_CMD_NEW_KEY) {
  14029. + bcopy(cmd->mac, buf_pos, HIFN_MAC_KEY_LENGTH);
  14030. + buf_pos += HIFN_MAC_KEY_LENGTH;
  14031. + }
  14032. +
  14033. + if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_KEY) {
  14034. + switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
  14035. + case HIFN_CRYPT_CMD_ALG_3DES:
  14036. + bcopy(cmd->ck, buf_pos, HIFN_3DES_KEY_LENGTH);
  14037. + buf_pos += HIFN_3DES_KEY_LENGTH;
  14038. + break;
  14039. + case HIFN_CRYPT_CMD_ALG_DES:
  14040. + bcopy(cmd->ck, buf_pos, HIFN_DES_KEY_LENGTH);
  14041. + buf_pos += HIFN_DES_KEY_LENGTH;
  14042. + break;
  14043. + case HIFN_CRYPT_CMD_ALG_RC4:
  14044. + len = 256;
  14045. + do {
  14046. + int clen;
  14047. +
  14048. + clen = MIN(cmd->cklen, len);
  14049. + bcopy(cmd->ck, buf_pos, clen);
  14050. + len -= clen;
  14051. + buf_pos += clen;
  14052. + } while (len > 0);
  14053. + bzero(buf_pos, 4);
  14054. + buf_pos += 4;
  14055. + break;
  14056. + case HIFN_CRYPT_CMD_ALG_AES:
  14057. + /*
  14058. + * AES keys are variable 128, 192 and
  14059. + * 256 bits (16, 24 and 32 bytes).
  14060. + */
  14061. + bcopy(cmd->ck, buf_pos, cmd->cklen);
  14062. + buf_pos += cmd->cklen;
  14063. + break;
  14064. + }
  14065. + }
  14066. +
  14067. + if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_IV) {
  14068. + switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
  14069. + case HIFN_CRYPT_CMD_ALG_AES:
  14070. + ivlen = HIFN_AES_IV_LENGTH;
  14071. + break;
  14072. + default:
  14073. + ivlen = HIFN_IV_LENGTH;
  14074. + break;
  14075. + }
  14076. + bcopy(cmd->iv, buf_pos, ivlen);
  14077. + buf_pos += ivlen;
  14078. + }
  14079. +
  14080. + if ((cmd->base_masks & (HIFN_BASE_CMD_MAC|HIFN_BASE_CMD_CRYPT)) == 0) {
  14081. + bzero(buf_pos, 8);
  14082. + buf_pos += 8;
  14083. + }
  14084. +
  14085. + return (buf_pos - buf);
  14086. +}
  14087. +
  14088. +static int
  14089. +hifn_dmamap_aligned(struct hifn_operand *op)
  14090. +{
  14091. + struct hifn_softc *sc = NULL;
  14092. + int i;
  14093. +
  14094. + DPRINTF("%s()\n", __FUNCTION__);
  14095. +
  14096. + for (i = 0; i < op->nsegs; i++) {
  14097. + if (op->segs[i].ds_addr & 3)
  14098. + return (0);
  14099. + if ((i != (op->nsegs - 1)) && (op->segs[i].ds_len & 3))
  14100. + return (0);
  14101. + }
  14102. + return (1);
  14103. +}
  14104. +
  14105. +static __inline int
  14106. +hifn_dmamap_dstwrap(struct hifn_softc *sc, int idx)
  14107. +{
  14108. + struct hifn_dma *dma = sc->sc_dma;
  14109. +
  14110. + if (++idx == HIFN_D_DST_RSIZE) {
  14111. + dma->dstr[idx].l = htole32(HIFN_D_VALID | HIFN_D_JUMP |
  14112. + HIFN_D_MASKDONEIRQ);
  14113. + HIFN_DSTR_SYNC(sc, idx,
  14114. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  14115. + idx = 0;
  14116. + }
  14117. + return (idx);
  14118. +}
  14119. +
  14120. +static int
  14121. +hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd)
  14122. +{
  14123. + struct hifn_dma *dma = sc->sc_dma;
  14124. + struct hifn_operand *dst = &cmd->dst;
  14125. + u_int32_t p, l;
  14126. + int idx, used = 0, i;
  14127. +
  14128. + DPRINTF("%s()\n", __FUNCTION__);
  14129. +
  14130. + idx = dma->dsti;
  14131. + for (i = 0; i < dst->nsegs - 1; i++) {
  14132. + dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
  14133. + dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ | dst->segs[i].ds_len);
  14134. + wmb();
  14135. + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
  14136. + HIFN_DSTR_SYNC(sc, idx,
  14137. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  14138. + used++;
  14139. +
  14140. + idx = hifn_dmamap_dstwrap(sc, idx);
  14141. + }
  14142. +
  14143. + if (cmd->sloplen == 0) {
  14144. + p = dst->segs[i].ds_addr;
  14145. + l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
  14146. + dst->segs[i].ds_len;
  14147. + } else {
  14148. + p = sc->sc_dma_physaddr +
  14149. + offsetof(struct hifn_dma, slop[cmd->slopidx]);
  14150. + l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
  14151. + sizeof(u_int32_t);
  14152. +
  14153. + if ((dst->segs[i].ds_len - cmd->sloplen) != 0) {
  14154. + dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
  14155. + dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ |
  14156. + (dst->segs[i].ds_len - cmd->sloplen));
  14157. + wmb();
  14158. + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
  14159. + HIFN_DSTR_SYNC(sc, idx,
  14160. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  14161. + used++;
  14162. +
  14163. + idx = hifn_dmamap_dstwrap(sc, idx);
  14164. + }
  14165. + }
  14166. + dma->dstr[idx].p = htole32(p);
  14167. + dma->dstr[idx].l = htole32(l);
  14168. + wmb();
  14169. + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
  14170. + HIFN_DSTR_SYNC(sc, idx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  14171. + used++;
  14172. +
  14173. + idx = hifn_dmamap_dstwrap(sc, idx);
  14174. +
  14175. + dma->dsti = idx;
  14176. + dma->dstu += used;
  14177. + return (idx);
  14178. +}
  14179. +
  14180. +static __inline int
  14181. +hifn_dmamap_srcwrap(struct hifn_softc *sc, int idx)
  14182. +{
  14183. + struct hifn_dma *dma = sc->sc_dma;
  14184. +
  14185. + if (++idx == HIFN_D_SRC_RSIZE) {
  14186. + dma->srcr[idx].l = htole32(HIFN_D_VALID |
  14187. + HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
  14188. + HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
  14189. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  14190. + idx = 0;
  14191. + }
  14192. + return (idx);
  14193. +}
  14194. +
  14195. +static int
  14196. +hifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd)
  14197. +{
  14198. + struct hifn_dma *dma = sc->sc_dma;
  14199. + struct hifn_operand *src = &cmd->src;
  14200. + int idx, i;
  14201. + u_int32_t last = 0;
  14202. +
  14203. + DPRINTF("%s()\n", __FUNCTION__);
  14204. +
  14205. + idx = dma->srci;
  14206. + for (i = 0; i < src->nsegs; i++) {
  14207. + if (i == src->nsegs - 1)
  14208. + last = HIFN_D_LAST;
  14209. +
  14210. + dma->srcr[idx].p = htole32(src->segs[i].ds_addr);
  14211. + dma->srcr[idx].l = htole32(src->segs[i].ds_len |
  14212. + HIFN_D_MASKDONEIRQ | last);
  14213. + wmb();
  14214. + dma->srcr[idx].l |= htole32(HIFN_D_VALID);
  14215. + HIFN_SRCR_SYNC(sc, idx,
  14216. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  14217. +
  14218. + idx = hifn_dmamap_srcwrap(sc, idx);
  14219. + }
  14220. + dma->srci = idx;
  14221. + dma->srcu += src->nsegs;
  14222. + return (idx);
  14223. +}
  14224. +
  14225. +
  14226. +static int
  14227. +hifn_crypto(
  14228. + struct hifn_softc *sc,
  14229. + struct hifn_command *cmd,
  14230. + struct cryptop *crp,
  14231. + int hint)
  14232. +{
  14233. + struct hifn_dma *dma = sc->sc_dma;
  14234. + u_int32_t cmdlen, csr;
  14235. + int cmdi, resi, err = 0;
  14236. + unsigned long l_flags;
  14237. +
  14238. + DPRINTF("%s()\n", __FUNCTION__);
  14239. +
  14240. + /*
  14241. + * need 1 cmd, and 1 res
  14242. + *
  14243. + * NB: check this first since it's easy.
  14244. + */
  14245. + HIFN_LOCK(sc);
  14246. + if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE ||
  14247. + (dma->resu + 1) > HIFN_D_RES_RSIZE) {
  14248. +#ifdef HIFN_DEBUG
  14249. + if (hifn_debug) {
  14250. + device_printf(sc->sc_dev,
  14251. + "cmd/result exhaustion, cmdu %u resu %u\n",
  14252. + dma->cmdu, dma->resu);
  14253. + }
  14254. +#endif
  14255. + hifnstats.hst_nomem_cr++;
  14256. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  14257. + HIFN_UNLOCK(sc);
  14258. + return (ERESTART);
  14259. + }
  14260. +
  14261. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  14262. + if (pci_map_skb(sc, &cmd->src, cmd->src_skb)) {
  14263. + hifnstats.hst_nomem_load++;
  14264. + err = ENOMEM;
  14265. + goto err_srcmap1;
  14266. + }
  14267. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  14268. + if (pci_map_uio(sc, &cmd->src, cmd->src_io)) {
  14269. + hifnstats.hst_nomem_load++;
  14270. + err = ENOMEM;
  14271. + goto err_srcmap1;
  14272. + }
  14273. + } else {
  14274. + if (pci_map_buf(sc, &cmd->src, cmd->src_buf, crp->crp_ilen)) {
  14275. + hifnstats.hst_nomem_load++;
  14276. + err = ENOMEM;
  14277. + goto err_srcmap1;
  14278. + }
  14279. + }
  14280. +
  14281. + if (hifn_dmamap_aligned(&cmd->src)) {
  14282. + cmd->sloplen = cmd->src_mapsize & 3;
  14283. + cmd->dst = cmd->src;
  14284. + } else {
  14285. + if (crp->crp_flags & CRYPTO_F_IOV) {
  14286. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14287. + err = EINVAL;
  14288. + goto err_srcmap;
  14289. + } else if (crp->crp_flags & CRYPTO_F_SKBUF) {
  14290. +#ifdef NOTYET
  14291. + int totlen, len;
  14292. + struct mbuf *m, *m0, *mlast;
  14293. +
  14294. + KASSERT(cmd->dst_m == cmd->src_m,
  14295. + ("hifn_crypto: dst_m initialized improperly"));
  14296. + hifnstats.hst_unaligned++;
  14297. + /*
  14298. + * Source is not aligned on a longword boundary.
  14299. + * Copy the data to insure alignment. If we fail
  14300. + * to allocate mbufs or clusters while doing this
  14301. + * we return ERESTART so the operation is requeued
  14302. + * at the crypto later, but only if there are
  14303. + * ops already posted to the hardware; otherwise we
  14304. + * have no guarantee that we'll be re-entered.
  14305. + */
  14306. + totlen = cmd->src_mapsize;
  14307. + if (cmd->src_m->m_flags & M_PKTHDR) {
  14308. + len = MHLEN;
  14309. + MGETHDR(m0, M_DONTWAIT, MT_DATA);
  14310. + if (m0 && !m_dup_pkthdr(m0, cmd->src_m, M_DONTWAIT)) {
  14311. + m_free(m0);
  14312. + m0 = NULL;
  14313. + }
  14314. + } else {
  14315. + len = MLEN;
  14316. + MGET(m0, M_DONTWAIT, MT_DATA);
  14317. + }
  14318. + if (m0 == NULL) {
  14319. + hifnstats.hst_nomem_mbuf++;
  14320. + err = dma->cmdu ? ERESTART : ENOMEM;
  14321. + goto err_srcmap;
  14322. + }
  14323. + if (totlen >= MINCLSIZE) {
  14324. + MCLGET(m0, M_DONTWAIT);
  14325. + if ((m0->m_flags & M_EXT) == 0) {
  14326. + hifnstats.hst_nomem_mcl++;
  14327. + err = dma->cmdu ? ERESTART : ENOMEM;
  14328. + m_freem(m0);
  14329. + goto err_srcmap;
  14330. + }
  14331. + len = MCLBYTES;
  14332. + }
  14333. + totlen -= len;
  14334. + m0->m_pkthdr.len = m0->m_len = len;
  14335. + mlast = m0;
  14336. +
  14337. + while (totlen > 0) {
  14338. + MGET(m, M_DONTWAIT, MT_DATA);
  14339. + if (m == NULL) {
  14340. + hifnstats.hst_nomem_mbuf++;
  14341. + err = dma->cmdu ? ERESTART : ENOMEM;
  14342. + m_freem(m0);
  14343. + goto err_srcmap;
  14344. + }
  14345. + len = MLEN;
  14346. + if (totlen >= MINCLSIZE) {
  14347. + MCLGET(m, M_DONTWAIT);
  14348. + if ((m->m_flags & M_EXT) == 0) {
  14349. + hifnstats.hst_nomem_mcl++;
  14350. + err = dma->cmdu ? ERESTART : ENOMEM;
  14351. + mlast->m_next = m;
  14352. + m_freem(m0);
  14353. + goto err_srcmap;
  14354. + }
  14355. + len = MCLBYTES;
  14356. + }
  14357. +
  14358. + m->m_len = len;
  14359. + m0->m_pkthdr.len += len;
  14360. + totlen -= len;
  14361. +
  14362. + mlast->m_next = m;
  14363. + mlast = m;
  14364. + }
  14365. + cmd->dst_m = m0;
  14366. +#else
  14367. + device_printf(sc->sc_dev,
  14368. + "%s,%d: CRYPTO_F_SKBUF unaligned not implemented\n",
  14369. + __FILE__, __LINE__);
  14370. + err = EINVAL;
  14371. + goto err_srcmap;
  14372. +#endif
  14373. + } else {
  14374. + device_printf(sc->sc_dev,
  14375. + "%s,%d: unaligned contig buffers not implemented\n",
  14376. + __FILE__, __LINE__);
  14377. + err = EINVAL;
  14378. + goto err_srcmap;
  14379. + }
  14380. + }
  14381. +
  14382. + if (cmd->dst_map == NULL) {
  14383. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  14384. + if (pci_map_skb(sc, &cmd->dst, cmd->dst_skb)) {
  14385. + hifnstats.hst_nomem_map++;
  14386. + err = ENOMEM;
  14387. + goto err_dstmap1;
  14388. + }
  14389. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  14390. + if (pci_map_uio(sc, &cmd->dst, cmd->dst_io)) {
  14391. + hifnstats.hst_nomem_load++;
  14392. + err = ENOMEM;
  14393. + goto err_dstmap1;
  14394. + }
  14395. + } else {
  14396. + if (pci_map_buf(sc, &cmd->dst, cmd->dst_buf, crp->crp_ilen)) {
  14397. + hifnstats.hst_nomem_load++;
  14398. + err = ENOMEM;
  14399. + goto err_dstmap1;
  14400. + }
  14401. + }
  14402. + }
  14403. +
  14404. +#ifdef HIFN_DEBUG
  14405. + if (hifn_debug) {
  14406. + device_printf(sc->sc_dev,
  14407. + "Entering cmd: stat %8x ien %8x u %d/%d/%d/%d n %d/%d\n",
  14408. + READ_REG_1(sc, HIFN_1_DMA_CSR),
  14409. + READ_REG_1(sc, HIFN_1_DMA_IER),
  14410. + dma->cmdu, dma->srcu, dma->dstu, dma->resu,
  14411. + cmd->src_nsegs, cmd->dst_nsegs);
  14412. + }
  14413. +#endif
  14414. +
  14415. +#if 0
  14416. + if (cmd->src_map == cmd->dst_map) {
  14417. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  14418. + BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
  14419. + } else {
  14420. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  14421. + BUS_DMASYNC_PREWRITE);
  14422. + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
  14423. + BUS_DMASYNC_PREREAD);
  14424. + }
  14425. +#endif
  14426. +
  14427. + /*
  14428. + * need N src, and N dst
  14429. + */
  14430. + if ((dma->srcu + cmd->src_nsegs) > HIFN_D_SRC_RSIZE ||
  14431. + (dma->dstu + cmd->dst_nsegs + 1) > HIFN_D_DST_RSIZE) {
  14432. +#ifdef HIFN_DEBUG
  14433. + if (hifn_debug) {
  14434. + device_printf(sc->sc_dev,
  14435. + "src/dst exhaustion, srcu %u+%u dstu %u+%u\n",
  14436. + dma->srcu, cmd->src_nsegs,
  14437. + dma->dstu, cmd->dst_nsegs);
  14438. + }
  14439. +#endif
  14440. + hifnstats.hst_nomem_sd++;
  14441. + err = ERESTART;
  14442. + goto err_dstmap;
  14443. + }
  14444. +
  14445. + if (dma->cmdi == HIFN_D_CMD_RSIZE) {
  14446. + dma->cmdi = 0;
  14447. + dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  14448. + wmb();
  14449. + dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
  14450. + HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
  14451. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  14452. + }
  14453. + cmdi = dma->cmdi++;
  14454. + cmdlen = hifn_write_command(cmd, dma->command_bufs[cmdi]);
  14455. + HIFN_CMD_SYNC(sc, cmdi, BUS_DMASYNC_PREWRITE);
  14456. +
  14457. + /* .p for command/result already set */
  14458. + dma->cmdr[cmdi].l = htole32(cmdlen | HIFN_D_LAST |
  14459. + HIFN_D_MASKDONEIRQ);
  14460. + wmb();
  14461. + dma->cmdr[cmdi].l |= htole32(HIFN_D_VALID);
  14462. + HIFN_CMDR_SYNC(sc, cmdi,
  14463. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  14464. + dma->cmdu++;
  14465. +
  14466. + /*
  14467. + * We don't worry about missing an interrupt (which a "command wait"
  14468. + * interrupt salvages us from), unless there is more than one command
  14469. + * in the queue.
  14470. + */
  14471. + if (dma->cmdu > 1) {
  14472. + sc->sc_dmaier |= HIFN_DMAIER_C_WAIT;
  14473. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  14474. + }
  14475. +
  14476. + hifnstats.hst_ipackets++;
  14477. + hifnstats.hst_ibytes += cmd->src_mapsize;
  14478. +
  14479. + hifn_dmamap_load_src(sc, cmd);
  14480. +
  14481. + /*
  14482. + * Unlike other descriptors, we don't mask done interrupt from
  14483. + * result descriptor.
  14484. + */
  14485. +#ifdef HIFN_DEBUG
  14486. + if (hifn_debug)
  14487. + device_printf(sc->sc_dev, "load res\n");
  14488. +#endif
  14489. + if (dma->resi == HIFN_D_RES_RSIZE) {
  14490. + dma->resi = 0;
  14491. + dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  14492. + wmb();
  14493. + dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
  14494. + HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
  14495. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  14496. + }
  14497. + resi = dma->resi++;
  14498. + KASSERT(dma->hifn_commands[resi] == NULL,
  14499. + ("hifn_crypto: command slot %u busy", resi));
  14500. + dma->hifn_commands[resi] = cmd;
  14501. + HIFN_RES_SYNC(sc, resi, BUS_DMASYNC_PREREAD);
  14502. + if ((hint & CRYPTO_HINT_MORE) && sc->sc_curbatch < hifn_maxbatch) {
  14503. + dma->resr[resi].l = htole32(HIFN_MAX_RESULT |
  14504. + HIFN_D_LAST | HIFN_D_MASKDONEIRQ);
  14505. + wmb();
  14506. + dma->resr[resi].l |= htole32(HIFN_D_VALID);
  14507. + sc->sc_curbatch++;
  14508. + if (sc->sc_curbatch > hifnstats.hst_maxbatch)
  14509. + hifnstats.hst_maxbatch = sc->sc_curbatch;
  14510. + hifnstats.hst_totbatch++;
  14511. + } else {
  14512. + dma->resr[resi].l = htole32(HIFN_MAX_RESULT | HIFN_D_LAST);
  14513. + wmb();
  14514. + dma->resr[resi].l |= htole32(HIFN_D_VALID);
  14515. + sc->sc_curbatch = 0;
  14516. + }
  14517. + HIFN_RESR_SYNC(sc, resi,
  14518. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  14519. + dma->resu++;
  14520. +
  14521. + if (cmd->sloplen)
  14522. + cmd->slopidx = resi;
  14523. +
  14524. + hifn_dmamap_load_dst(sc, cmd);
  14525. +
  14526. + csr = 0;
  14527. + if (sc->sc_c_busy == 0) {
  14528. + csr |= HIFN_DMACSR_C_CTRL_ENA;
  14529. + sc->sc_c_busy = 1;
  14530. + }
  14531. + if (sc->sc_s_busy == 0) {
  14532. + csr |= HIFN_DMACSR_S_CTRL_ENA;
  14533. + sc->sc_s_busy = 1;
  14534. + }
  14535. + if (sc->sc_r_busy == 0) {
  14536. + csr |= HIFN_DMACSR_R_CTRL_ENA;
  14537. + sc->sc_r_busy = 1;
  14538. + }
  14539. + if (sc->sc_d_busy == 0) {
  14540. + csr |= HIFN_DMACSR_D_CTRL_ENA;
  14541. + sc->sc_d_busy = 1;
  14542. + }
  14543. + if (csr)
  14544. + WRITE_REG_1(sc, HIFN_1_DMA_CSR, csr);
  14545. +
  14546. +#ifdef HIFN_DEBUG
  14547. + if (hifn_debug) {
  14548. + device_printf(sc->sc_dev, "command: stat %8x ier %8x\n",
  14549. + READ_REG_1(sc, HIFN_1_DMA_CSR),
  14550. + READ_REG_1(sc, HIFN_1_DMA_IER));
  14551. + }
  14552. +#endif
  14553. +
  14554. + sc->sc_active = 5;
  14555. + HIFN_UNLOCK(sc);
  14556. + KASSERT(err == 0, ("hifn_crypto: success with error %u", err));
  14557. + return (err); /* success */
  14558. +
  14559. +err_dstmap:
  14560. + if (cmd->src_map != cmd->dst_map)
  14561. + pci_unmap_buf(sc, &cmd->dst);
  14562. +err_dstmap1:
  14563. +err_srcmap:
  14564. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  14565. + if (cmd->src_skb != cmd->dst_skb)
  14566. +#ifdef NOTYET
  14567. + m_freem(cmd->dst_m);
  14568. +#else
  14569. + device_printf(sc->sc_dev,
  14570. + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
  14571. + __FILE__, __LINE__);
  14572. +#endif
  14573. + }
  14574. + pci_unmap_buf(sc, &cmd->src);
  14575. +err_srcmap1:
  14576. + HIFN_UNLOCK(sc);
  14577. + return (err);
  14578. +}
  14579. +
  14580. +static void
  14581. +hifn_tick(unsigned long arg)
  14582. +{
  14583. + struct hifn_softc *sc;
  14584. + unsigned long l_flags;
  14585. +
  14586. + if (arg >= HIFN_MAX_CHIPS)
  14587. + return;
  14588. + sc = hifn_chip_idx[arg];
  14589. + if (!sc)
  14590. + return;
  14591. +
  14592. + HIFN_LOCK(sc);
  14593. + if (sc->sc_active == 0) {
  14594. + struct hifn_dma *dma = sc->sc_dma;
  14595. + u_int32_t r = 0;
  14596. +
  14597. + if (dma->cmdu == 0 && sc->sc_c_busy) {
  14598. + sc->sc_c_busy = 0;
  14599. + r |= HIFN_DMACSR_C_CTRL_DIS;
  14600. + }
  14601. + if (dma->srcu == 0 && sc->sc_s_busy) {
  14602. + sc->sc_s_busy = 0;
  14603. + r |= HIFN_DMACSR_S_CTRL_DIS;
  14604. + }
  14605. + if (dma->dstu == 0 && sc->sc_d_busy) {
  14606. + sc->sc_d_busy = 0;
  14607. + r |= HIFN_DMACSR_D_CTRL_DIS;
  14608. + }
  14609. + if (dma->resu == 0 && sc->sc_r_busy) {
  14610. + sc->sc_r_busy = 0;
  14611. + r |= HIFN_DMACSR_R_CTRL_DIS;
  14612. + }
  14613. + if (r)
  14614. + WRITE_REG_1(sc, HIFN_1_DMA_CSR, r);
  14615. + } else
  14616. + sc->sc_active--;
  14617. + HIFN_UNLOCK(sc);
  14618. + mod_timer(&sc->sc_tickto, jiffies + HZ);
  14619. +}
  14620. +
  14621. +static irqreturn_t
  14622. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  14623. +hifn_intr(int irq, void *arg)
  14624. +#else
  14625. +hifn_intr(int irq, void *arg, struct pt_regs *regs)
  14626. +#endif
  14627. +{
  14628. + struct hifn_softc *sc = arg;
  14629. + struct hifn_dma *dma;
  14630. + u_int32_t dmacsr, restart;
  14631. + int i, u;
  14632. + unsigned long l_flags;
  14633. +
  14634. + dmacsr = READ_REG_1(sc, HIFN_1_DMA_CSR);
  14635. +
  14636. + /* Nothing in the DMA unit interrupted */
  14637. + if ((dmacsr & sc->sc_dmaier) == 0)
  14638. + return IRQ_NONE;
  14639. +
  14640. + HIFN_LOCK(sc);
  14641. +
  14642. + dma = sc->sc_dma;
  14643. +
  14644. +#ifdef HIFN_DEBUG
  14645. + if (hifn_debug) {
  14646. + device_printf(sc->sc_dev,
  14647. + "irq: stat %08x ien %08x damier %08x i %d/%d/%d/%d k %d/%d/%d/%d u %d/%d/%d/%d\n",
  14648. + dmacsr, READ_REG_1(sc, HIFN_1_DMA_IER), sc->sc_dmaier,
  14649. + dma->cmdi, dma->srci, dma->dsti, dma->resi,
  14650. + dma->cmdk, dma->srck, dma->dstk, dma->resk,
  14651. + dma->cmdu, dma->srcu, dma->dstu, dma->resu);
  14652. + }
  14653. +#endif
  14654. +
  14655. + WRITE_REG_1(sc, HIFN_1_DMA_CSR, dmacsr & sc->sc_dmaier);
  14656. +
  14657. + if ((sc->sc_flags & HIFN_HAS_PUBLIC) &&
  14658. + (dmacsr & HIFN_DMACSR_PUBDONE))
  14659. + WRITE_REG_1(sc, HIFN_1_PUB_STATUS,
  14660. + READ_REG_1(sc, HIFN_1_PUB_STATUS) | HIFN_PUBSTS_DONE);
  14661. +
  14662. + restart = dmacsr & (HIFN_DMACSR_D_OVER | HIFN_DMACSR_R_OVER);
  14663. + if (restart)
  14664. + device_printf(sc->sc_dev, "overrun %x\n", dmacsr);
  14665. +
  14666. + if (sc->sc_flags & HIFN_IS_7811) {
  14667. + if (dmacsr & HIFN_DMACSR_ILLR)
  14668. + device_printf(sc->sc_dev, "illegal read\n");
  14669. + if (dmacsr & HIFN_DMACSR_ILLW)
  14670. + device_printf(sc->sc_dev, "illegal write\n");
  14671. + }
  14672. +
  14673. + restart = dmacsr & (HIFN_DMACSR_C_ABORT | HIFN_DMACSR_S_ABORT |
  14674. + HIFN_DMACSR_D_ABORT | HIFN_DMACSR_R_ABORT);
  14675. + if (restart) {
  14676. + device_printf(sc->sc_dev, "abort, resetting.\n");
  14677. + hifnstats.hst_abort++;
  14678. + hifn_abort(sc);
  14679. + HIFN_UNLOCK(sc);
  14680. + return IRQ_HANDLED;
  14681. + }
  14682. +
  14683. + if ((dmacsr & HIFN_DMACSR_C_WAIT) && (dma->cmdu == 0)) {
  14684. + /*
  14685. + * If no slots to process and we receive a "waiting on
  14686. + * command" interrupt, we disable the "waiting on command"
  14687. + * (by clearing it).
  14688. + */
  14689. + sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
  14690. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  14691. + }
  14692. +
  14693. + /* clear the rings */
  14694. + i = dma->resk; u = dma->resu;
  14695. + while (u != 0) {
  14696. + HIFN_RESR_SYNC(sc, i,
  14697. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  14698. + if (dma->resr[i].l & htole32(HIFN_D_VALID)) {
  14699. + HIFN_RESR_SYNC(sc, i,
  14700. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  14701. + break;
  14702. + }
  14703. +
  14704. + if (i != HIFN_D_RES_RSIZE) {
  14705. + struct hifn_command *cmd;
  14706. + u_int8_t *macbuf = NULL;
  14707. +
  14708. + HIFN_RES_SYNC(sc, i, BUS_DMASYNC_POSTREAD);
  14709. + cmd = dma->hifn_commands[i];
  14710. + KASSERT(cmd != NULL,
  14711. + ("hifn_intr: null command slot %u", i));
  14712. + dma->hifn_commands[i] = NULL;
  14713. +
  14714. + if (cmd->base_masks & HIFN_BASE_CMD_MAC) {
  14715. + macbuf = dma->result_bufs[i];
  14716. + macbuf += 12;
  14717. + }
  14718. +
  14719. + hifn_callback(sc, cmd, macbuf);
  14720. + hifnstats.hst_opackets++;
  14721. + u--;
  14722. + }
  14723. +
  14724. + if (++i == (HIFN_D_RES_RSIZE + 1))
  14725. + i = 0;
  14726. + }
  14727. + dma->resk = i; dma->resu = u;
  14728. +
  14729. + i = dma->srck; u = dma->srcu;
  14730. + while (u != 0) {
  14731. + if (i == HIFN_D_SRC_RSIZE)
  14732. + i = 0;
  14733. + HIFN_SRCR_SYNC(sc, i,
  14734. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  14735. + if (dma->srcr[i].l & htole32(HIFN_D_VALID)) {
  14736. + HIFN_SRCR_SYNC(sc, i,
  14737. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  14738. + break;
  14739. + }
  14740. + i++, u--;
  14741. + }
  14742. + dma->srck = i; dma->srcu = u;
  14743. +
  14744. + i = dma->cmdk; u = dma->cmdu;
  14745. + while (u != 0) {
  14746. + HIFN_CMDR_SYNC(sc, i,
  14747. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  14748. + if (dma->cmdr[i].l & htole32(HIFN_D_VALID)) {
  14749. + HIFN_CMDR_SYNC(sc, i,
  14750. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  14751. + break;
  14752. + }
  14753. + if (i != HIFN_D_CMD_RSIZE) {
  14754. + u--;
  14755. + HIFN_CMD_SYNC(sc, i, BUS_DMASYNC_POSTWRITE);
  14756. + }
  14757. + if (++i == (HIFN_D_CMD_RSIZE + 1))
  14758. + i = 0;
  14759. + }
  14760. + dma->cmdk = i; dma->cmdu = u;
  14761. +
  14762. + HIFN_UNLOCK(sc);
  14763. +
  14764. + if (sc->sc_needwakeup) { /* XXX check high watermark */
  14765. + int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
  14766. +#ifdef HIFN_DEBUG
  14767. + if (hifn_debug)
  14768. + device_printf(sc->sc_dev,
  14769. + "wakeup crypto (%x) u %d/%d/%d/%d\n",
  14770. + sc->sc_needwakeup,
  14771. + dma->cmdu, dma->srcu, dma->dstu, dma->resu);
  14772. +#endif
  14773. + sc->sc_needwakeup &= ~wakeup;
  14774. + crypto_unblock(sc->sc_cid, wakeup);
  14775. + }
  14776. +
  14777. + return IRQ_HANDLED;
  14778. +}
  14779. +
  14780. +/*
  14781. + * Allocate a new 'session' and return an encoded session id. 'sidp'
  14782. + * contains our registration id, and should contain an encoded session
  14783. + * id on successful allocation.
  14784. + */
  14785. +static int
  14786. +hifn_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  14787. +{
  14788. + struct hifn_softc *sc = device_get_softc(dev);
  14789. + struct cryptoini *c;
  14790. + int mac = 0, cry = 0, sesn;
  14791. + struct hifn_session *ses = NULL;
  14792. + unsigned long l_flags;
  14793. +
  14794. + DPRINTF("%s()\n", __FUNCTION__);
  14795. +
  14796. + KASSERT(sc != NULL, ("hifn_newsession: null softc"));
  14797. + if (sidp == NULL || cri == NULL || sc == NULL) {
  14798. + DPRINTF("%s,%d: %s - EINVAL\n", __FILE__, __LINE__, __FUNCTION__);
  14799. + return (EINVAL);
  14800. + }
  14801. +
  14802. + HIFN_LOCK(sc);
  14803. + if (sc->sc_sessions == NULL) {
  14804. + ses = sc->sc_sessions = (struct hifn_session *)kmalloc(sizeof(*ses),
  14805. + SLAB_ATOMIC);
  14806. + if (ses == NULL) {
  14807. + HIFN_UNLOCK(sc);
  14808. + return (ENOMEM);
  14809. + }
  14810. + sesn = 0;
  14811. + sc->sc_nsessions = 1;
  14812. + } else {
  14813. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  14814. + if (!sc->sc_sessions[sesn].hs_used) {
  14815. + ses = &sc->sc_sessions[sesn];
  14816. + break;
  14817. + }
  14818. + }
  14819. +
  14820. + if (ses == NULL) {
  14821. + sesn = sc->sc_nsessions;
  14822. + ses = (struct hifn_session *)kmalloc((sesn + 1) * sizeof(*ses),
  14823. + SLAB_ATOMIC);
  14824. + if (ses == NULL) {
  14825. + HIFN_UNLOCK(sc);
  14826. + return (ENOMEM);
  14827. + }
  14828. + bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));
  14829. + bzero(sc->sc_sessions, sesn * sizeof(*ses));
  14830. + kfree(sc->sc_sessions);
  14831. + sc->sc_sessions = ses;
  14832. + ses = &sc->sc_sessions[sesn];
  14833. + sc->sc_nsessions++;
  14834. + }
  14835. + }
  14836. + HIFN_UNLOCK(sc);
  14837. +
  14838. + bzero(ses, sizeof(*ses));
  14839. + ses->hs_used = 1;
  14840. +
  14841. + for (c = cri; c != NULL; c = c->cri_next) {
  14842. + switch (c->cri_alg) {
  14843. + case CRYPTO_MD5:
  14844. + case CRYPTO_SHA1:
  14845. + case CRYPTO_MD5_HMAC:
  14846. + case CRYPTO_SHA1_HMAC:
  14847. + if (mac) {
  14848. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14849. + return (EINVAL);
  14850. + }
  14851. + mac = 1;
  14852. + ses->hs_mlen = c->cri_mlen;
  14853. + if (ses->hs_mlen == 0) {
  14854. + switch (c->cri_alg) {
  14855. + case CRYPTO_MD5:
  14856. + case CRYPTO_MD5_HMAC:
  14857. + ses->hs_mlen = 16;
  14858. + break;
  14859. + case CRYPTO_SHA1:
  14860. + case CRYPTO_SHA1_HMAC:
  14861. + ses->hs_mlen = 20;
  14862. + break;
  14863. + }
  14864. + }
  14865. + break;
  14866. + case CRYPTO_DES_CBC:
  14867. + case CRYPTO_3DES_CBC:
  14868. + case CRYPTO_AES_CBC:
  14869. + /* XXX this may read fewer, does it matter? */
  14870. + read_random(ses->hs_iv,
  14871. + c->cri_alg == CRYPTO_AES_CBC ?
  14872. + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
  14873. + /*FALLTHROUGH*/
  14874. + case CRYPTO_ARC4:
  14875. + if (cry) {
  14876. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14877. + return (EINVAL);
  14878. + }
  14879. + cry = 1;
  14880. + break;
  14881. + default:
  14882. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14883. + return (EINVAL);
  14884. + }
  14885. + }
  14886. + if (mac == 0 && cry == 0) {
  14887. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14888. + return (EINVAL);
  14889. + }
  14890. +
  14891. + *sidp = HIFN_SID(device_get_unit(sc->sc_dev), sesn);
  14892. +
  14893. + return (0);
  14894. +}
  14895. +
  14896. +/*
  14897. + * Deallocate a session.
  14898. + * XXX this routine should run a zero'd mac/encrypt key into context ram.
  14899. + * XXX to blow away any keys already stored there.
  14900. + */
  14901. +static int
  14902. +hifn_freesession(device_t dev, u_int64_t tid)
  14903. +{
  14904. + struct hifn_softc *sc = device_get_softc(dev);
  14905. + int session, error;
  14906. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  14907. + unsigned long l_flags;
  14908. +
  14909. + DPRINTF("%s()\n", __FUNCTION__);
  14910. +
  14911. + KASSERT(sc != NULL, ("hifn_freesession: null softc"));
  14912. + if (sc == NULL) {
  14913. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14914. + return (EINVAL);
  14915. + }
  14916. +
  14917. + HIFN_LOCK(sc);
  14918. + session = HIFN_SESSION(sid);
  14919. + if (session < sc->sc_nsessions) {
  14920. + bzero(&sc->sc_sessions[session], sizeof(struct hifn_session));
  14921. + error = 0;
  14922. + } else {
  14923. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14924. + error = EINVAL;
  14925. + }
  14926. + HIFN_UNLOCK(sc);
  14927. +
  14928. + return (error);
  14929. +}
  14930. +
  14931. +static int
  14932. +hifn_process(device_t dev, struct cryptop *crp, int hint)
  14933. +{
  14934. + struct hifn_softc *sc = device_get_softc(dev);
  14935. + struct hifn_command *cmd = NULL;
  14936. + int session, err, ivlen;
  14937. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  14938. +
  14939. + DPRINTF("%s()\n", __FUNCTION__);
  14940. +
  14941. + if (crp == NULL || crp->crp_callback == NULL) {
  14942. + hifnstats.hst_invalid++;
  14943. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14944. + return (EINVAL);
  14945. + }
  14946. + session = HIFN_SESSION(crp->crp_sid);
  14947. +
  14948. + if (sc == NULL || session >= sc->sc_nsessions) {
  14949. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14950. + err = EINVAL;
  14951. + goto errout;
  14952. + }
  14953. +
  14954. + cmd = kmalloc(sizeof(struct hifn_command), SLAB_ATOMIC);
  14955. + if (cmd == NULL) {
  14956. + hifnstats.hst_nomem++;
  14957. + err = ENOMEM;
  14958. + goto errout;
  14959. + }
  14960. + memset(cmd, 0, sizeof(*cmd));
  14961. +
  14962. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  14963. + cmd->src_skb = (struct sk_buff *)crp->crp_buf;
  14964. + cmd->dst_skb = (struct sk_buff *)crp->crp_buf;
  14965. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  14966. + cmd->src_io = (struct uio *)crp->crp_buf;
  14967. + cmd->dst_io = (struct uio *)crp->crp_buf;
  14968. + } else {
  14969. + cmd->src_buf = crp->crp_buf;
  14970. + cmd->dst_buf = crp->crp_buf;
  14971. + }
  14972. +
  14973. + crd1 = crp->crp_desc;
  14974. + if (crd1 == NULL) {
  14975. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14976. + err = EINVAL;
  14977. + goto errout;
  14978. + }
  14979. + crd2 = crd1->crd_next;
  14980. +
  14981. + if (crd2 == NULL) {
  14982. + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
  14983. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  14984. + crd1->crd_alg == CRYPTO_SHA1 ||
  14985. + crd1->crd_alg == CRYPTO_MD5) {
  14986. + maccrd = crd1;
  14987. + enccrd = NULL;
  14988. + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
  14989. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  14990. + crd1->crd_alg == CRYPTO_AES_CBC ||
  14991. + crd1->crd_alg == CRYPTO_ARC4) {
  14992. + if ((crd1->crd_flags & CRD_F_ENCRYPT) == 0)
  14993. + cmd->base_masks |= HIFN_BASE_CMD_DECODE;
  14994. + maccrd = NULL;
  14995. + enccrd = crd1;
  14996. + } else {
  14997. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  14998. + err = EINVAL;
  14999. + goto errout;
  15000. + }
  15001. + } else {
  15002. + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
  15003. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  15004. + crd1->crd_alg == CRYPTO_MD5 ||
  15005. + crd1->crd_alg == CRYPTO_SHA1) &&
  15006. + (crd2->crd_alg == CRYPTO_DES_CBC ||
  15007. + crd2->crd_alg == CRYPTO_3DES_CBC ||
  15008. + crd2->crd_alg == CRYPTO_AES_CBC ||
  15009. + crd2->crd_alg == CRYPTO_ARC4) &&
  15010. + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
  15011. + cmd->base_masks = HIFN_BASE_CMD_DECODE;
  15012. + maccrd = crd1;
  15013. + enccrd = crd2;
  15014. + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
  15015. + crd1->crd_alg == CRYPTO_ARC4 ||
  15016. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  15017. + crd1->crd_alg == CRYPTO_AES_CBC) &&
  15018. + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
  15019. + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
  15020. + crd2->crd_alg == CRYPTO_MD5 ||
  15021. + crd2->crd_alg == CRYPTO_SHA1) &&
  15022. + (crd1->crd_flags & CRD_F_ENCRYPT)) {
  15023. + enccrd = crd1;
  15024. + maccrd = crd2;
  15025. + } else {
  15026. + /*
  15027. + * We cannot order the 7751 as requested
  15028. + */
  15029. + DPRINTF("%s,%d: %s %d,%d,%d - EINVAL\n",__FILE__,__LINE__,__FUNCTION__, crd1->crd_alg, crd2->crd_alg, crd1->crd_flags & CRD_F_ENCRYPT);
  15030. + err = EINVAL;
  15031. + goto errout;
  15032. + }
  15033. + }
  15034. +
  15035. + if (enccrd) {
  15036. + cmd->enccrd = enccrd;
  15037. + cmd->base_masks |= HIFN_BASE_CMD_CRYPT;
  15038. + switch (enccrd->crd_alg) {
  15039. + case CRYPTO_ARC4:
  15040. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_RC4;
  15041. + break;
  15042. + case CRYPTO_DES_CBC:
  15043. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_DES |
  15044. + HIFN_CRYPT_CMD_MODE_CBC |
  15045. + HIFN_CRYPT_CMD_NEW_IV;
  15046. + break;
  15047. + case CRYPTO_3DES_CBC:
  15048. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_3DES |
  15049. + HIFN_CRYPT_CMD_MODE_CBC |
  15050. + HIFN_CRYPT_CMD_NEW_IV;
  15051. + break;
  15052. + case CRYPTO_AES_CBC:
  15053. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_AES |
  15054. + HIFN_CRYPT_CMD_MODE_CBC |
  15055. + HIFN_CRYPT_CMD_NEW_IV;
  15056. + break;
  15057. + default:
  15058. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  15059. + err = EINVAL;
  15060. + goto errout;
  15061. + }
  15062. + if (enccrd->crd_alg != CRYPTO_ARC4) {
  15063. + ivlen = ((enccrd->crd_alg == CRYPTO_AES_CBC) ?
  15064. + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
  15065. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  15066. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  15067. + bcopy(enccrd->crd_iv, cmd->iv, ivlen);
  15068. + else
  15069. + bcopy(sc->sc_sessions[session].hs_iv,
  15070. + cmd->iv, ivlen);
  15071. +
  15072. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT)
  15073. + == 0) {
  15074. + crypto_copyback(crp->crp_flags,
  15075. + crp->crp_buf, enccrd->crd_inject,
  15076. + ivlen, cmd->iv);
  15077. + }
  15078. + } else {
  15079. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  15080. + bcopy(enccrd->crd_iv, cmd->iv, ivlen);
  15081. + else {
  15082. + crypto_copydata(crp->crp_flags,
  15083. + crp->crp_buf, enccrd->crd_inject,
  15084. + ivlen, cmd->iv);
  15085. + }
  15086. + }
  15087. + }
  15088. +
  15089. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
  15090. + cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
  15091. + cmd->ck = enccrd->crd_key;
  15092. + cmd->cklen = enccrd->crd_klen >> 3;
  15093. + cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
  15094. +
  15095. + /*
  15096. + * Need to specify the size for the AES key in the masks.
  15097. + */
  15098. + if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) ==
  15099. + HIFN_CRYPT_CMD_ALG_AES) {
  15100. + switch (cmd->cklen) {
  15101. + case 16:
  15102. + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_128;
  15103. + break;
  15104. + case 24:
  15105. + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_192;
  15106. + break;
  15107. + case 32:
  15108. + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_256;
  15109. + break;
  15110. + default:
  15111. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  15112. + err = EINVAL;
  15113. + goto errout;
  15114. + }
  15115. + }
  15116. + }
  15117. +
  15118. + if (maccrd) {
  15119. + cmd->maccrd = maccrd;
  15120. + cmd->base_masks |= HIFN_BASE_CMD_MAC;
  15121. +
  15122. + switch (maccrd->crd_alg) {
  15123. + case CRYPTO_MD5:
  15124. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |
  15125. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |
  15126. + HIFN_MAC_CMD_POS_IPSEC;
  15127. + break;
  15128. + case CRYPTO_MD5_HMAC:
  15129. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |
  15130. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |
  15131. + HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;
  15132. + break;
  15133. + case CRYPTO_SHA1:
  15134. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |
  15135. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |
  15136. + HIFN_MAC_CMD_POS_IPSEC;
  15137. + break;
  15138. + case CRYPTO_SHA1_HMAC:
  15139. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |
  15140. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |
  15141. + HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;
  15142. + break;
  15143. + }
  15144. +
  15145. + if (maccrd->crd_alg == CRYPTO_SHA1_HMAC ||
  15146. + maccrd->crd_alg == CRYPTO_MD5_HMAC) {
  15147. + cmd->mac_masks |= HIFN_MAC_CMD_NEW_KEY;
  15148. + bcopy(maccrd->crd_key, cmd->mac, maccrd->crd_klen >> 3);
  15149. + bzero(cmd->mac + (maccrd->crd_klen >> 3),
  15150. + HIFN_MAC_KEY_LENGTH - (maccrd->crd_klen >> 3));
  15151. + }
  15152. + }
  15153. +
  15154. + cmd->crp = crp;
  15155. + cmd->session_num = session;
  15156. + cmd->softc = sc;
  15157. +
  15158. + err = hifn_crypto(sc, cmd, crp, hint);
  15159. + if (!err) {
  15160. + return 0;
  15161. + } else if (err == ERESTART) {
  15162. + /*
  15163. + * There weren't enough resources to dispatch the request
  15164. + * to the part. Notify the caller so they'll requeue this
  15165. + * request and resubmit it again soon.
  15166. + */
  15167. +#ifdef HIFN_DEBUG
  15168. + if (hifn_debug)
  15169. + device_printf(sc->sc_dev, "requeue request\n");
  15170. +#endif
  15171. + kfree(cmd);
  15172. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  15173. + return (err);
  15174. + }
  15175. +
  15176. +errout:
  15177. + if (cmd != NULL)
  15178. + kfree(cmd);
  15179. + if (err == EINVAL)
  15180. + hifnstats.hst_invalid++;
  15181. + else
  15182. + hifnstats.hst_nomem++;
  15183. + crp->crp_etype = err;
  15184. + crypto_done(crp);
  15185. + return (err);
  15186. +}
  15187. +
  15188. +static void
  15189. +hifn_abort(struct hifn_softc *sc)
  15190. +{
  15191. + struct hifn_dma *dma = sc->sc_dma;
  15192. + struct hifn_command *cmd;
  15193. + struct cryptop *crp;
  15194. + int i, u;
  15195. +
  15196. + DPRINTF("%s()\n", __FUNCTION__);
  15197. +
  15198. + i = dma->resk; u = dma->resu;
  15199. + while (u != 0) {
  15200. + cmd = dma->hifn_commands[i];
  15201. + KASSERT(cmd != NULL, ("hifn_abort: null command slot %u", i));
  15202. + dma->hifn_commands[i] = NULL;
  15203. + crp = cmd->crp;
  15204. +
  15205. + if ((dma->resr[i].l & htole32(HIFN_D_VALID)) == 0) {
  15206. + /* Salvage what we can. */
  15207. + u_int8_t *macbuf;
  15208. +
  15209. + if (cmd->base_masks & HIFN_BASE_CMD_MAC) {
  15210. + macbuf = dma->result_bufs[i];
  15211. + macbuf += 12;
  15212. + } else
  15213. + macbuf = NULL;
  15214. + hifnstats.hst_opackets++;
  15215. + hifn_callback(sc, cmd, macbuf);
  15216. + } else {
  15217. +#if 0
  15218. + if (cmd->src_map == cmd->dst_map) {
  15219. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  15220. + BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  15221. + } else {
  15222. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  15223. + BUS_DMASYNC_POSTWRITE);
  15224. + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
  15225. + BUS_DMASYNC_POSTREAD);
  15226. + }
  15227. +#endif
  15228. +
  15229. + if (cmd->src_skb != cmd->dst_skb) {
  15230. +#ifdef NOTYET
  15231. + m_freem(cmd->src_m);
  15232. + crp->crp_buf = (caddr_t)cmd->dst_m;
  15233. +#else
  15234. + device_printf(sc->sc_dev,
  15235. + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
  15236. + __FILE__, __LINE__);
  15237. +#endif
  15238. + }
  15239. +
  15240. + /* non-shared buffers cannot be restarted */
  15241. + if (cmd->src_map != cmd->dst_map) {
  15242. + /*
  15243. + * XXX should be EAGAIN, delayed until
  15244. + * after the reset.
  15245. + */
  15246. + crp->crp_etype = ENOMEM;
  15247. + pci_unmap_buf(sc, &cmd->dst);
  15248. + } else
  15249. + crp->crp_etype = ENOMEM;
  15250. +
  15251. + pci_unmap_buf(sc, &cmd->src);
  15252. +
  15253. + kfree(cmd);
  15254. + if (crp->crp_etype != EAGAIN)
  15255. + crypto_done(crp);
  15256. + }
  15257. +
  15258. + if (++i == HIFN_D_RES_RSIZE)
  15259. + i = 0;
  15260. + u--;
  15261. + }
  15262. + dma->resk = i; dma->resu = u;
  15263. +
  15264. + hifn_reset_board(sc, 1);
  15265. + hifn_init_dma(sc);
  15266. + hifn_init_pci_registers(sc);
  15267. +}
  15268. +
  15269. +static void
  15270. +hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, u_int8_t *macbuf)
  15271. +{
  15272. + struct hifn_dma *dma = sc->sc_dma;
  15273. + struct cryptop *crp = cmd->crp;
  15274. + struct cryptodesc *crd;
  15275. + int i, u, ivlen;
  15276. +
  15277. + DPRINTF("%s()\n", __FUNCTION__);
  15278. +
  15279. +#if 0
  15280. + if (cmd->src_map == cmd->dst_map) {
  15281. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  15282. + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
  15283. + } else {
  15284. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  15285. + BUS_DMASYNC_POSTWRITE);
  15286. + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
  15287. + BUS_DMASYNC_POSTREAD);
  15288. + }
  15289. +#endif
  15290. +
  15291. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  15292. + if (cmd->src_skb != cmd->dst_skb) {
  15293. +#ifdef NOTYET
  15294. + crp->crp_buf = (caddr_t)cmd->dst_m;
  15295. + totlen = cmd->src_mapsize;
  15296. + for (m = cmd->dst_m; m != NULL; m = m->m_next) {
  15297. + if (totlen < m->m_len) {
  15298. + m->m_len = totlen;
  15299. + totlen = 0;
  15300. + } else
  15301. + totlen -= m->m_len;
  15302. + }
  15303. + cmd->dst_m->m_pkthdr.len = cmd->src_m->m_pkthdr.len;
  15304. + m_freem(cmd->src_m);
  15305. +#else
  15306. + device_printf(sc->sc_dev,
  15307. + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
  15308. + __FILE__, __LINE__);
  15309. +#endif
  15310. + }
  15311. + }
  15312. +
  15313. + if (cmd->sloplen != 0) {
  15314. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  15315. + cmd->src_mapsize - cmd->sloplen, cmd->sloplen,
  15316. + (caddr_t)&dma->slop[cmd->slopidx]);
  15317. + }
  15318. +
  15319. + i = dma->dstk; u = dma->dstu;
  15320. + while (u != 0) {
  15321. + if (i == HIFN_D_DST_RSIZE)
  15322. + i = 0;
  15323. +#if 0
  15324. + bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
  15325. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  15326. +#endif
  15327. + if (dma->dstr[i].l & htole32(HIFN_D_VALID)) {
  15328. +#if 0
  15329. + bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
  15330. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  15331. +#endif
  15332. + break;
  15333. + }
  15334. + i++, u--;
  15335. + }
  15336. + dma->dstk = i; dma->dstu = u;
  15337. +
  15338. + hifnstats.hst_obytes += cmd->dst_mapsize;
  15339. +
  15340. + if ((cmd->base_masks & (HIFN_BASE_CMD_CRYPT | HIFN_BASE_CMD_DECODE)) ==
  15341. + HIFN_BASE_CMD_CRYPT) {
  15342. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  15343. + if (crd->crd_alg != CRYPTO_DES_CBC &&
  15344. + crd->crd_alg != CRYPTO_3DES_CBC &&
  15345. + crd->crd_alg != CRYPTO_AES_CBC)
  15346. + continue;
  15347. + ivlen = ((crd->crd_alg == CRYPTO_AES_CBC) ?
  15348. + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
  15349. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  15350. + crd->crd_skip + crd->crd_len - ivlen, ivlen,
  15351. + cmd->softc->sc_sessions[cmd->session_num].hs_iv);
  15352. + break;
  15353. + }
  15354. + }
  15355. +
  15356. + if (macbuf != NULL) {
  15357. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  15358. + int len;
  15359. +
  15360. + if (crd->crd_alg != CRYPTO_MD5 &&
  15361. + crd->crd_alg != CRYPTO_SHA1 &&
  15362. + crd->crd_alg != CRYPTO_MD5_HMAC &&
  15363. + crd->crd_alg != CRYPTO_SHA1_HMAC) {
  15364. + continue;
  15365. + }
  15366. + len = cmd->softc->sc_sessions[cmd->session_num].hs_mlen;
  15367. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  15368. + crd->crd_inject, len, macbuf);
  15369. + break;
  15370. + }
  15371. + }
  15372. +
  15373. + if (cmd->src_map != cmd->dst_map)
  15374. + pci_unmap_buf(sc, &cmd->dst);
  15375. + pci_unmap_buf(sc, &cmd->src);
  15376. + kfree(cmd);
  15377. + crypto_done(crp);
  15378. +}
  15379. +
  15380. +/*
  15381. + * 7811 PB3 rev/2 parts lock-up on burst writes to Group 0
  15382. + * and Group 1 registers; avoid conditions that could create
  15383. + * burst writes by doing a read in between the writes.
  15384. + *
  15385. + * NB: The read we interpose is always to the same register;
  15386. + * we do this because reading from an arbitrary (e.g. last)
  15387. + * register may not always work.
  15388. + */
  15389. +static void
  15390. +hifn_write_reg_0(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
  15391. +{
  15392. + if (sc->sc_flags & HIFN_IS_7811) {
  15393. + if (sc->sc_bar0_lastreg == reg - 4)
  15394. + readl(sc->sc_bar0 + HIFN_0_PUCNFG);
  15395. + sc->sc_bar0_lastreg = reg;
  15396. + }
  15397. + writel(val, sc->sc_bar0 + reg);
  15398. +}
  15399. +
  15400. +static void
  15401. +hifn_write_reg_1(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
  15402. +{
  15403. + if (sc->sc_flags & HIFN_IS_7811) {
  15404. + if (sc->sc_bar1_lastreg == reg - 4)
  15405. + readl(sc->sc_bar1 + HIFN_1_REVID);
  15406. + sc->sc_bar1_lastreg = reg;
  15407. + }
  15408. + writel(val, sc->sc_bar1 + reg);
  15409. +}
  15410. +
  15411. +
  15412. +static struct pci_device_id hifn_pci_tbl[] = {
  15413. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7951,
  15414. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  15415. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7955,
  15416. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  15417. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7956,
  15418. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  15419. + { PCI_VENDOR_NETSEC, PCI_PRODUCT_NETSEC_7751,
  15420. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  15421. + { PCI_VENDOR_INVERTEX, PCI_PRODUCT_INVERTEX_AEON,
  15422. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  15423. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7811,
  15424. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  15425. + /*
  15426. + * Other vendors share this PCI ID as well, such as
  15427. + * http://www.powercrypt.com, and obviously they also
  15428. + * use the same key.
  15429. + */
  15430. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7751,
  15431. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  15432. + { 0, 0, 0, 0, 0, 0, }
  15433. +};
  15434. +MODULE_DEVICE_TABLE(pci, hifn_pci_tbl);
  15435. +
  15436. +static struct pci_driver hifn_driver = {
  15437. + .name = "hifn",
  15438. + .id_table = hifn_pci_tbl,
  15439. + .probe = hifn_probe,
  15440. + .remove = hifn_remove,
  15441. + /* add PM stuff here one day */
  15442. +};
  15443. +
  15444. +static int __init hifn_init (void)
  15445. +{
  15446. + struct hifn_softc *sc = NULL;
  15447. + int rc;
  15448. +
  15449. + DPRINTF("%s(%p)\n", __FUNCTION__, hifn_init);
  15450. +
  15451. + rc = pci_register_driver(&hifn_driver);
  15452. + pci_register_driver_compat(&hifn_driver, rc);
  15453. +
  15454. + return rc;
  15455. +}
  15456. +
  15457. +static void __exit hifn_exit (void)
  15458. +{
  15459. + pci_unregister_driver(&hifn_driver);
  15460. +}
  15461. +
  15462. +module_init(hifn_init);
  15463. +module_exit(hifn_exit);
  15464. +
  15465. +MODULE_LICENSE("BSD");
  15466. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  15467. +MODULE_DESCRIPTION("OCF driver for hifn PCI crypto devices");
  15468. diff -Nur linux-2.6.35.orig/crypto/ocf/hifn/hifn7751reg.h linux-2.6.35/crypto/ocf/hifn/hifn7751reg.h
  15469. --- linux-2.6.35.orig/crypto/ocf/hifn/hifn7751reg.h 1970-01-01 01:00:00.000000000 +0100
  15470. +++ linux-2.6.35/crypto/ocf/hifn/hifn7751reg.h 2010-08-05 22:02:09.203658159 +0200
  15471. @@ -0,0 +1,540 @@
  15472. +/* $FreeBSD: src/sys/dev/hifn/hifn7751reg.h,v 1.7 2007/03/21 03:42:49 sam Exp $ */
  15473. +/* $OpenBSD: hifn7751reg.h,v 1.35 2002/04/08 17:49:42 jason Exp $ */
  15474. +
  15475. +/*-
  15476. + * Invertex AEON / Hifn 7751 driver
  15477. + * Copyright (c) 1999 Invertex Inc. All rights reserved.
  15478. + * Copyright (c) 1999 Theo de Raadt
  15479. + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  15480. + * http://www.netsec.net
  15481. + *
  15482. + * Please send any comments, feedback, bug-fixes, or feature requests to
  15483. + * software@invertex.com.
  15484. + *
  15485. + * Redistribution and use in source and binary forms, with or without
  15486. + * modification, are permitted provided that the following conditions
  15487. + * are met:
  15488. + *
  15489. + * 1. Redistributions of source code must retain the above copyright
  15490. + * notice, this list of conditions and the following disclaimer.
  15491. + * 2. Redistributions in binary form must reproduce the above copyright
  15492. + * notice, this list of conditions and the following disclaimer in the
  15493. + * documentation and/or other materials provided with the distribution.
  15494. + * 3. The name of the author may not be used to endorse or promote products
  15495. + * derived from this software without specific prior written permission.
  15496. + *
  15497. + *
  15498. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  15499. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  15500. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  15501. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  15502. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  15503. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  15504. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  15505. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  15506. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  15507. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  15508. + *
  15509. + * Effort sponsored in part by the Defense Advanced Research Projects
  15510. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  15511. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  15512. + *
  15513. + */
  15514. +#ifndef __HIFN_H__
  15515. +#define __HIFN_H__
  15516. +
  15517. +/*
  15518. + * Some PCI configuration space offset defines. The names were made
  15519. + * identical to the names used by the Linux kernel.
  15520. + */
  15521. +#define HIFN_BAR0 PCIR_BAR(0) /* PUC register map */
  15522. +#define HIFN_BAR1 PCIR_BAR(1) /* DMA register map */
  15523. +#define HIFN_TRDY_TIMEOUT 0x40
  15524. +#define HIFN_RETRY_TIMEOUT 0x41
  15525. +
  15526. +/*
  15527. + * PCI vendor and device identifiers
  15528. + * (the names are preserved from their OpenBSD source).
  15529. + */
  15530. +#define PCI_VENDOR_HIFN 0x13a3 /* Hifn */
  15531. +#define PCI_PRODUCT_HIFN_7751 0x0005 /* 7751 */
  15532. +#define PCI_PRODUCT_HIFN_6500 0x0006 /* 6500 */
  15533. +#define PCI_PRODUCT_HIFN_7811 0x0007 /* 7811 */
  15534. +#define PCI_PRODUCT_HIFN_7855 0x001f /* 7855 */
  15535. +#define PCI_PRODUCT_HIFN_7951 0x0012 /* 7951 */
  15536. +#define PCI_PRODUCT_HIFN_7955 0x0020 /* 7954/7955 */
  15537. +#define PCI_PRODUCT_HIFN_7956 0x001d /* 7956 */
  15538. +
  15539. +#define PCI_VENDOR_INVERTEX 0x14e1 /* Invertex */
  15540. +#define PCI_PRODUCT_INVERTEX_AEON 0x0005 /* AEON */
  15541. +
  15542. +#define PCI_VENDOR_NETSEC 0x1660 /* NetSec */
  15543. +#define PCI_PRODUCT_NETSEC_7751 0x7751 /* 7751 */
  15544. +
  15545. +/*
  15546. + * The values below should multiple of 4 -- and be large enough to handle
  15547. + * any command the driver implements.
  15548. + *
  15549. + * MAX_COMMAND = base command + mac command + encrypt command +
  15550. + * mac-key + rc4-key
  15551. + * MAX_RESULT = base result + mac result + mac + encrypt result
  15552. + *
  15553. + *
  15554. + */
  15555. +#define HIFN_MAX_COMMAND (8 + 8 + 8 + 64 + 260)
  15556. +#define HIFN_MAX_RESULT (8 + 4 + 20 + 4)
  15557. +
  15558. +/*
  15559. + * hifn_desc_t
  15560. + *
  15561. + * Holds an individual descriptor for any of the rings.
  15562. + */
  15563. +typedef struct hifn_desc {
  15564. + volatile u_int32_t l; /* length and status bits */
  15565. + volatile u_int32_t p;
  15566. +} hifn_desc_t;
  15567. +
  15568. +/*
  15569. + * Masks for the "length" field of struct hifn_desc.
  15570. + */
  15571. +#define HIFN_D_LENGTH 0x0000ffff /* length bit mask */
  15572. +#define HIFN_D_MASKDONEIRQ 0x02000000 /* mask the done interrupt */
  15573. +#define HIFN_D_DESTOVER 0x04000000 /* destination overflow */
  15574. +#define HIFN_D_OVER 0x08000000 /* overflow */
  15575. +#define HIFN_D_LAST 0x20000000 /* last descriptor in chain */
  15576. +#define HIFN_D_JUMP 0x40000000 /* jump descriptor */
  15577. +#define HIFN_D_VALID 0x80000000 /* valid bit */
  15578. +
  15579. +
  15580. +/*
  15581. + * Processing Unit Registers (offset from BASEREG0)
  15582. + */
  15583. +#define HIFN_0_PUDATA 0x00 /* Processing Unit Data */
  15584. +#define HIFN_0_PUCTRL 0x04 /* Processing Unit Control */
  15585. +#define HIFN_0_PUISR 0x08 /* Processing Unit Interrupt Status */
  15586. +#define HIFN_0_PUCNFG 0x0c /* Processing Unit Configuration */
  15587. +#define HIFN_0_PUIER 0x10 /* Processing Unit Interrupt Enable */
  15588. +#define HIFN_0_PUSTAT 0x14 /* Processing Unit Status/Chip ID */
  15589. +#define HIFN_0_FIFOSTAT 0x18 /* FIFO Status */
  15590. +#define HIFN_0_FIFOCNFG 0x1c /* FIFO Configuration */
  15591. +#define HIFN_0_PUCTRL2 0x28 /* Processing Unit Control (2nd map) */
  15592. +#define HIFN_0_MUTE1 0x80
  15593. +#define HIFN_0_MUTE2 0x90
  15594. +#define HIFN_0_SPACESIZE 0x100 /* Register space size */
  15595. +
  15596. +/* Processing Unit Control Register (HIFN_0_PUCTRL) */
  15597. +#define HIFN_PUCTRL_CLRSRCFIFO 0x0010 /* clear source fifo */
  15598. +#define HIFN_PUCTRL_STOP 0x0008 /* stop pu */
  15599. +#define HIFN_PUCTRL_LOCKRAM 0x0004 /* lock ram */
  15600. +#define HIFN_PUCTRL_DMAENA 0x0002 /* enable dma */
  15601. +#define HIFN_PUCTRL_RESET 0x0001 /* Reset processing unit */
  15602. +
  15603. +/* Processing Unit Interrupt Status Register (HIFN_0_PUISR) */
  15604. +#define HIFN_PUISR_CMDINVAL 0x8000 /* Invalid command interrupt */
  15605. +#define HIFN_PUISR_DATAERR 0x4000 /* Data error interrupt */
  15606. +#define HIFN_PUISR_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
  15607. +#define HIFN_PUISR_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
  15608. +#define HIFN_PUISR_DSTOVER 0x0200 /* Destination overrun interrupt */
  15609. +#define HIFN_PUISR_SRCCMD 0x0080 /* Source command interrupt */
  15610. +#define HIFN_PUISR_SRCCTX 0x0040 /* Source context interrupt */
  15611. +#define HIFN_PUISR_SRCDATA 0x0020 /* Source data interrupt */
  15612. +#define HIFN_PUISR_DSTDATA 0x0010 /* Destination data interrupt */
  15613. +#define HIFN_PUISR_DSTRESULT 0x0004 /* Destination result interrupt */
  15614. +
  15615. +/* Processing Unit Configuration Register (HIFN_0_PUCNFG) */
  15616. +#define HIFN_PUCNFG_DRAMMASK 0xe000 /* DRAM size mask */
  15617. +#define HIFN_PUCNFG_DSZ_256K 0x0000 /* 256k dram */
  15618. +#define HIFN_PUCNFG_DSZ_512K 0x2000 /* 512k dram */
  15619. +#define HIFN_PUCNFG_DSZ_1M 0x4000 /* 1m dram */
  15620. +#define HIFN_PUCNFG_DSZ_2M 0x6000 /* 2m dram */
  15621. +#define HIFN_PUCNFG_DSZ_4M 0x8000 /* 4m dram */
  15622. +#define HIFN_PUCNFG_DSZ_8M 0xa000 /* 8m dram */
  15623. +#define HIFN_PUNCFG_DSZ_16M 0xc000 /* 16m dram */
  15624. +#define HIFN_PUCNFG_DSZ_32M 0xe000 /* 32m dram */
  15625. +#define HIFN_PUCNFG_DRAMREFRESH 0x1800 /* DRAM refresh rate mask */
  15626. +#define HIFN_PUCNFG_DRFR_512 0x0000 /* 512 divisor of ECLK */
  15627. +#define HIFN_PUCNFG_DRFR_256 0x0800 /* 256 divisor of ECLK */
  15628. +#define HIFN_PUCNFG_DRFR_128 0x1000 /* 128 divisor of ECLK */
  15629. +#define HIFN_PUCNFG_TCALLPHASES 0x0200 /* your guess is as good as mine... */
  15630. +#define HIFN_PUCNFG_TCDRVTOTEM 0x0100 /* your guess is as good as mine... */
  15631. +#define HIFN_PUCNFG_BIGENDIAN 0x0080 /* DMA big endian mode */
  15632. +#define HIFN_PUCNFG_BUS32 0x0040 /* Bus width 32bits */
  15633. +#define HIFN_PUCNFG_BUS16 0x0000 /* Bus width 16 bits */
  15634. +#define HIFN_PUCNFG_CHIPID 0x0020 /* Allow chipid from PUSTAT */
  15635. +#define HIFN_PUCNFG_DRAM 0x0010 /* Context RAM is DRAM */
  15636. +#define HIFN_PUCNFG_SRAM 0x0000 /* Context RAM is SRAM */
  15637. +#define HIFN_PUCNFG_COMPSING 0x0004 /* Enable single compression context */
  15638. +#define HIFN_PUCNFG_ENCCNFG 0x0002 /* Encryption configuration */
  15639. +
  15640. +/* Processing Unit Interrupt Enable Register (HIFN_0_PUIER) */
  15641. +#define HIFN_PUIER_CMDINVAL 0x8000 /* Invalid command interrupt */
  15642. +#define HIFN_PUIER_DATAERR 0x4000 /* Data error interrupt */
  15643. +#define HIFN_PUIER_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
  15644. +#define HIFN_PUIER_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
  15645. +#define HIFN_PUIER_DSTOVER 0x0200 /* Destination overrun interrupt */
  15646. +#define HIFN_PUIER_SRCCMD 0x0080 /* Source command interrupt */
  15647. +#define HIFN_PUIER_SRCCTX 0x0040 /* Source context interrupt */
  15648. +#define HIFN_PUIER_SRCDATA 0x0020 /* Source data interrupt */
  15649. +#define HIFN_PUIER_DSTDATA 0x0010 /* Destination data interrupt */
  15650. +#define HIFN_PUIER_DSTRESULT 0x0004 /* Destination result interrupt */
  15651. +
  15652. +/* Processing Unit Status Register/Chip ID (HIFN_0_PUSTAT) */
  15653. +#define HIFN_PUSTAT_CMDINVAL 0x8000 /* Invalid command interrupt */
  15654. +#define HIFN_PUSTAT_DATAERR 0x4000 /* Data error interrupt */
  15655. +#define HIFN_PUSTAT_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
  15656. +#define HIFN_PUSTAT_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
  15657. +#define HIFN_PUSTAT_DSTOVER 0x0200 /* Destination overrun interrupt */
  15658. +#define HIFN_PUSTAT_SRCCMD 0x0080 /* Source command interrupt */
  15659. +#define HIFN_PUSTAT_SRCCTX 0x0040 /* Source context interrupt */
  15660. +#define HIFN_PUSTAT_SRCDATA 0x0020 /* Source data interrupt */
  15661. +#define HIFN_PUSTAT_DSTDATA 0x0010 /* Destination data interrupt */
  15662. +#define HIFN_PUSTAT_DSTRESULT 0x0004 /* Destination result interrupt */
  15663. +#define HIFN_PUSTAT_CHIPREV 0x00ff /* Chip revision mask */
  15664. +#define HIFN_PUSTAT_CHIPENA 0xff00 /* Chip enabled mask */
  15665. +#define HIFN_PUSTAT_ENA_2 0x1100 /* Level 2 enabled */
  15666. +#define HIFN_PUSTAT_ENA_1 0x1000 /* Level 1 enabled */
  15667. +#define HIFN_PUSTAT_ENA_0 0x3000 /* Level 0 enabled */
  15668. +#define HIFN_PUSTAT_REV_2 0x0020 /* 7751 PT6/2 */
  15669. +#define HIFN_PUSTAT_REV_3 0x0030 /* 7751 PT6/3 */
  15670. +
  15671. +/* FIFO Status Register (HIFN_0_FIFOSTAT) */
  15672. +#define HIFN_FIFOSTAT_SRC 0x7f00 /* Source FIFO available */
  15673. +#define HIFN_FIFOSTAT_DST 0x007f /* Destination FIFO available */
  15674. +
  15675. +/* FIFO Configuration Register (HIFN_0_FIFOCNFG) */
  15676. +#define HIFN_FIFOCNFG_THRESHOLD 0x0400 /* must be written as this value */
  15677. +
  15678. +/*
  15679. + * DMA Interface Registers (offset from BASEREG1)
  15680. + */
  15681. +#define HIFN_1_DMA_CRAR 0x0c /* DMA Command Ring Address */
  15682. +#define HIFN_1_DMA_SRAR 0x1c /* DMA Source Ring Address */
  15683. +#define HIFN_1_DMA_RRAR 0x2c /* DMA Result Ring Address */
  15684. +#define HIFN_1_DMA_DRAR 0x3c /* DMA Destination Ring Address */
  15685. +#define HIFN_1_DMA_CSR 0x40 /* DMA Status and Control */
  15686. +#define HIFN_1_DMA_IER 0x44 /* DMA Interrupt Enable */
  15687. +#define HIFN_1_DMA_CNFG 0x48 /* DMA Configuration */
  15688. +#define HIFN_1_PLL 0x4c /* 7955/7956: PLL config */
  15689. +#define HIFN_1_7811_RNGENA 0x60 /* 7811: rng enable */
  15690. +#define HIFN_1_7811_RNGCFG 0x64 /* 7811: rng config */
  15691. +#define HIFN_1_7811_RNGDAT 0x68 /* 7811: rng data */
  15692. +#define HIFN_1_7811_RNGSTS 0x6c /* 7811: rng status */
  15693. +#define HIFN_1_DMA_CNFG2 0x6c /* 7955/7956: dma config #2 */
  15694. +#define HIFN_1_7811_MIPSRST 0x94 /* 7811: MIPS reset */
  15695. +#define HIFN_1_REVID 0x98 /* Revision ID */
  15696. +
  15697. +#define HIFN_1_PUB_RESET 0x204 /* Public/RNG Reset */
  15698. +#define HIFN_1_PUB_BASE 0x300 /* Public Base Address */
  15699. +#define HIFN_1_PUB_OPLEN 0x304 /* 7951-compat Public Operand Length */
  15700. +#define HIFN_1_PUB_OP 0x308 /* 7951-compat Public Operand */
  15701. +#define HIFN_1_PUB_STATUS 0x30c /* 7951-compat Public Status */
  15702. +#define HIFN_1_PUB_IEN 0x310 /* Public Interrupt enable */
  15703. +#define HIFN_1_RNG_CONFIG 0x314 /* RNG config */
  15704. +#define HIFN_1_RNG_DATA 0x318 /* RNG data */
  15705. +#define HIFN_1_PUB_MODE 0x320 /* PK mode */
  15706. +#define HIFN_1_PUB_FIFO_OPLEN 0x380 /* first element of oplen fifo */
  15707. +#define HIFN_1_PUB_FIFO_OP 0x384 /* first element of op fifo */
  15708. +#define HIFN_1_PUB_MEM 0x400 /* start of Public key memory */
  15709. +#define HIFN_1_PUB_MEMEND 0xbff /* end of Public key memory */
  15710. +
  15711. +/* DMA Status and Control Register (HIFN_1_DMA_CSR) */
  15712. +#define HIFN_DMACSR_D_CTRLMASK 0xc0000000 /* Destinition Ring Control */
  15713. +#define HIFN_DMACSR_D_CTRL_NOP 0x00000000 /* Dest. Control: no-op */
  15714. +#define HIFN_DMACSR_D_CTRL_DIS 0x40000000 /* Dest. Control: disable */
  15715. +#define HIFN_DMACSR_D_CTRL_ENA 0x80000000 /* Dest. Control: enable */
  15716. +#define HIFN_DMACSR_D_ABORT 0x20000000 /* Destinition Ring PCIAbort */
  15717. +#define HIFN_DMACSR_D_DONE 0x10000000 /* Destinition Ring Done */
  15718. +#define HIFN_DMACSR_D_LAST 0x08000000 /* Destinition Ring Last */
  15719. +#define HIFN_DMACSR_D_WAIT 0x04000000 /* Destinition Ring Waiting */
  15720. +#define HIFN_DMACSR_D_OVER 0x02000000 /* Destinition Ring Overflow */
  15721. +#define HIFN_DMACSR_R_CTRL 0x00c00000 /* Result Ring Control */
  15722. +#define HIFN_DMACSR_R_CTRL_NOP 0x00000000 /* Result Control: no-op */
  15723. +#define HIFN_DMACSR_R_CTRL_DIS 0x00400000 /* Result Control: disable */
  15724. +#define HIFN_DMACSR_R_CTRL_ENA 0x00800000 /* Result Control: enable */
  15725. +#define HIFN_DMACSR_R_ABORT 0x00200000 /* Result Ring PCI Abort */
  15726. +#define HIFN_DMACSR_R_DONE 0x00100000 /* Result Ring Done */
  15727. +#define HIFN_DMACSR_R_LAST 0x00080000 /* Result Ring Last */
  15728. +#define HIFN_DMACSR_R_WAIT 0x00040000 /* Result Ring Waiting */
  15729. +#define HIFN_DMACSR_R_OVER 0x00020000 /* Result Ring Overflow */
  15730. +#define HIFN_DMACSR_S_CTRL 0x0000c000 /* Source Ring Control */
  15731. +#define HIFN_DMACSR_S_CTRL_NOP 0x00000000 /* Source Control: no-op */
  15732. +#define HIFN_DMACSR_S_CTRL_DIS 0x00004000 /* Source Control: disable */
  15733. +#define HIFN_DMACSR_S_CTRL_ENA 0x00008000 /* Source Control: enable */
  15734. +#define HIFN_DMACSR_S_ABORT 0x00002000 /* Source Ring PCI Abort */
  15735. +#define HIFN_DMACSR_S_DONE 0x00001000 /* Source Ring Done */
  15736. +#define HIFN_DMACSR_S_LAST 0x00000800 /* Source Ring Last */
  15737. +#define HIFN_DMACSR_S_WAIT 0x00000400 /* Source Ring Waiting */
  15738. +#define HIFN_DMACSR_ILLW 0x00000200 /* Illegal write (7811 only) */
  15739. +#define HIFN_DMACSR_ILLR 0x00000100 /* Illegal read (7811 only) */
  15740. +#define HIFN_DMACSR_C_CTRL 0x000000c0 /* Command Ring Control */
  15741. +#define HIFN_DMACSR_C_CTRL_NOP 0x00000000 /* Command Control: no-op */
  15742. +#define HIFN_DMACSR_C_CTRL_DIS 0x00000040 /* Command Control: disable */
  15743. +#define HIFN_DMACSR_C_CTRL_ENA 0x00000080 /* Command Control: enable */
  15744. +#define HIFN_DMACSR_C_ABORT 0x00000020 /* Command Ring PCI Abort */
  15745. +#define HIFN_DMACSR_C_DONE 0x00000010 /* Command Ring Done */
  15746. +#define HIFN_DMACSR_C_LAST 0x00000008 /* Command Ring Last */
  15747. +#define HIFN_DMACSR_C_WAIT 0x00000004 /* Command Ring Waiting */
  15748. +#define HIFN_DMACSR_PUBDONE 0x00000002 /* Public op done (7951 only) */
  15749. +#define HIFN_DMACSR_ENGINE 0x00000001 /* Command Ring Engine IRQ */
  15750. +
  15751. +/* DMA Interrupt Enable Register (HIFN_1_DMA_IER) */
  15752. +#define HIFN_DMAIER_D_ABORT 0x20000000 /* Destination Ring PCIAbort */
  15753. +#define HIFN_DMAIER_D_DONE 0x10000000 /* Destination Ring Done */
  15754. +#define HIFN_DMAIER_D_LAST 0x08000000 /* Destination Ring Last */
  15755. +#define HIFN_DMAIER_D_WAIT 0x04000000 /* Destination Ring Waiting */
  15756. +#define HIFN_DMAIER_D_OVER 0x02000000 /* Destination Ring Overflow */
  15757. +#define HIFN_DMAIER_R_ABORT 0x00200000 /* Result Ring PCI Abort */
  15758. +#define HIFN_DMAIER_R_DONE 0x00100000 /* Result Ring Done */
  15759. +#define HIFN_DMAIER_R_LAST 0x00080000 /* Result Ring Last */
  15760. +#define HIFN_DMAIER_R_WAIT 0x00040000 /* Result Ring Waiting */
  15761. +#define HIFN_DMAIER_R_OVER 0x00020000 /* Result Ring Overflow */
  15762. +#define HIFN_DMAIER_S_ABORT 0x00002000 /* Source Ring PCI Abort */
  15763. +#define HIFN_DMAIER_S_DONE 0x00001000 /* Source Ring Done */
  15764. +#define HIFN_DMAIER_S_LAST 0x00000800 /* Source Ring Last */
  15765. +#define HIFN_DMAIER_S_WAIT 0x00000400 /* Source Ring Waiting */
  15766. +#define HIFN_DMAIER_ILLW 0x00000200 /* Illegal write (7811 only) */
  15767. +#define HIFN_DMAIER_ILLR 0x00000100 /* Illegal read (7811 only) */
  15768. +#define HIFN_DMAIER_C_ABORT 0x00000020 /* Command Ring PCI Abort */
  15769. +#define HIFN_DMAIER_C_DONE 0x00000010 /* Command Ring Done */
  15770. +#define HIFN_DMAIER_C_LAST 0x00000008 /* Command Ring Last */
  15771. +#define HIFN_DMAIER_C_WAIT 0x00000004 /* Command Ring Waiting */
  15772. +#define HIFN_DMAIER_PUBDONE 0x00000002 /* public op done (7951 only) */
  15773. +#define HIFN_DMAIER_ENGINE 0x00000001 /* Engine IRQ */
  15774. +
  15775. +/* DMA Configuration Register (HIFN_1_DMA_CNFG) */
  15776. +#define HIFN_DMACNFG_BIGENDIAN 0x10000000 /* big endian mode */
  15777. +#define HIFN_DMACNFG_POLLFREQ 0x00ff0000 /* Poll frequency mask */
  15778. +#define HIFN_DMACNFG_UNLOCK 0x00000800
  15779. +#define HIFN_DMACNFG_POLLINVAL 0x00000700 /* Invalid Poll Scalar */
  15780. +#define HIFN_DMACNFG_LAST 0x00000010 /* Host control LAST bit */
  15781. +#define HIFN_DMACNFG_MODE 0x00000004 /* DMA mode */
  15782. +#define HIFN_DMACNFG_DMARESET 0x00000002 /* DMA Reset # */
  15783. +#define HIFN_DMACNFG_MSTRESET 0x00000001 /* Master Reset # */
  15784. +
  15785. +/* DMA Configuration Register (HIFN_1_DMA_CNFG2) */
  15786. +#define HIFN_DMACNFG2_PKSWAP32 (1 << 19) /* swap the OPLEN/OP reg */
  15787. +#define HIFN_DMACNFG2_PKSWAP8 (1 << 18) /* swap the bits of OPLEN/OP */
  15788. +#define HIFN_DMACNFG2_BAR0_SWAP32 (1<<17) /* swap the bytes of BAR0 */
  15789. +#define HIFN_DMACNFG2_BAR1_SWAP8 (1<<16) /* swap the bits of BAR0 */
  15790. +#define HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT 12
  15791. +#define HIFN_DMACNFG2_INIT_READ_BURST_SHIFT 8
  15792. +#define HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT 4
  15793. +#define HIFN_DMACNFG2_TGT_READ_BURST_SHIFT 0
  15794. +
  15795. +/* 7811 RNG Enable Register (HIFN_1_7811_RNGENA) */
  15796. +#define HIFN_7811_RNGENA_ENA 0x00000001 /* enable RNG */
  15797. +
  15798. +/* 7811 RNG Config Register (HIFN_1_7811_RNGCFG) */
  15799. +#define HIFN_7811_RNGCFG_PRE1 0x00000f00 /* first prescalar */
  15800. +#define HIFN_7811_RNGCFG_OPRE 0x00000080 /* output prescalar */
  15801. +#define HIFN_7811_RNGCFG_DEFL 0x00000f80 /* 2 words/ 1/100 sec */
  15802. +
  15803. +/* 7811 RNG Status Register (HIFN_1_7811_RNGSTS) */
  15804. +#define HIFN_7811_RNGSTS_RDY 0x00004000 /* two numbers in FIFO */
  15805. +#define HIFN_7811_RNGSTS_UFL 0x00001000 /* rng underflow */
  15806. +
  15807. +/* 7811 MIPS Reset Register (HIFN_1_7811_MIPSRST) */
  15808. +#define HIFN_MIPSRST_BAR2SIZE 0xffff0000 /* sdram size */
  15809. +#define HIFN_MIPSRST_GPRAMINIT 0x00008000 /* gpram can be accessed */
  15810. +#define HIFN_MIPSRST_CRAMINIT 0x00004000 /* ctxram can be accessed */
  15811. +#define HIFN_MIPSRST_LED2 0x00000400 /* external LED2 */
  15812. +#define HIFN_MIPSRST_LED1 0x00000200 /* external LED1 */
  15813. +#define HIFN_MIPSRST_LED0 0x00000100 /* external LED0 */
  15814. +#define HIFN_MIPSRST_MIPSDIS 0x00000004 /* disable MIPS */
  15815. +#define HIFN_MIPSRST_MIPSRST 0x00000002 /* warm reset MIPS */
  15816. +#define HIFN_MIPSRST_MIPSCOLD 0x00000001 /* cold reset MIPS */
  15817. +
  15818. +/* Public key reset register (HIFN_1_PUB_RESET) */
  15819. +#define HIFN_PUBRST_RESET 0x00000001 /* reset public/rng unit */
  15820. +
  15821. +/* Public operation register (HIFN_1_PUB_OP) */
  15822. +#define HIFN_PUBOP_AOFFSET 0x0000003e /* A offset */
  15823. +#define HIFN_PUBOP_BOFFSET 0x00000fc0 /* B offset */
  15824. +#define HIFN_PUBOP_MOFFSET 0x0003f000 /* M offset */
  15825. +#define HIFN_PUBOP_OP_MASK 0x003c0000 /* Opcode: */
  15826. +#define HIFN_PUBOP_OP_NOP 0x00000000 /* NOP */
  15827. +#define HIFN_PUBOP_OP_ADD 0x00040000 /* ADD */
  15828. +#define HIFN_PUBOP_OP_ADDC 0x00080000 /* ADD w/carry */
  15829. +#define HIFN_PUBOP_OP_SUB 0x000c0000 /* SUB */
  15830. +#define HIFN_PUBOP_OP_SUBC 0x00100000 /* SUB w/carry */
  15831. +#define HIFN_PUBOP_OP_MODADD 0x00140000 /* Modular ADD */
  15832. +#define HIFN_PUBOP_OP_MODSUB 0x00180000 /* Modular SUB */
  15833. +#define HIFN_PUBOP_OP_INCA 0x001c0000 /* INC A */
  15834. +#define HIFN_PUBOP_OP_DECA 0x00200000 /* DEC A */
  15835. +#define HIFN_PUBOP_OP_MULT 0x00240000 /* MULT */
  15836. +#define HIFN_PUBOP_OP_MODMULT 0x00280000 /* Modular MULT */
  15837. +#define HIFN_PUBOP_OP_MODRED 0x002c0000 /* Modular Red */
  15838. +#define HIFN_PUBOP_OP_MODEXP 0x00300000 /* Modular Exp */
  15839. +
  15840. +/* Public operand length register (HIFN_1_PUB_OPLEN) */
  15841. +#define HIFN_PUBOPLEN_MODLEN 0x0000007f
  15842. +#define HIFN_PUBOPLEN_EXPLEN 0x0003ff80
  15843. +#define HIFN_PUBOPLEN_REDLEN 0x003c0000
  15844. +
  15845. +/* Public status register (HIFN_1_PUB_STATUS) */
  15846. +#define HIFN_PUBSTS_DONE 0x00000001 /* operation done */
  15847. +#define HIFN_PUBSTS_CARRY 0x00000002 /* carry */
  15848. +#define HIFN_PUBSTS_FIFO_EMPTY 0x00000100 /* fifo empty */
  15849. +#define HIFN_PUBSTS_FIFO_FULL 0x00000200 /* fifo full */
  15850. +#define HIFN_PUBSTS_FIFO_OVFL 0x00000400 /* fifo overflow */
  15851. +#define HIFN_PUBSTS_FIFO_WRITE 0x000f0000 /* fifo write */
  15852. +#define HIFN_PUBSTS_FIFO_READ 0x0f000000 /* fifo read */
  15853. +
  15854. +/* Public interrupt enable register (HIFN_1_PUB_IEN) */
  15855. +#define HIFN_PUBIEN_DONE 0x00000001 /* operation done interrupt */
  15856. +
  15857. +/* Random number generator config register (HIFN_1_RNG_CONFIG) */
  15858. +#define HIFN_RNGCFG_ENA 0x00000001 /* enable rng */
  15859. +
  15860. +/*
  15861. + * Register offsets in register set 1
  15862. + */
  15863. +
  15864. +#define HIFN_UNLOCK_SECRET1 0xf4
  15865. +#define HIFN_UNLOCK_SECRET2 0xfc
  15866. +
  15867. +/*
  15868. + * PLL config register
  15869. + *
  15870. + * This register is present only on 7954/7955/7956 parts. It must be
  15871. + * programmed according to the bus interface method used by the h/w.
  15872. + * Note that the parts require a stable clock. Since the PCI clock
  15873. + * may vary the reference clock must usually be used. To avoid
  15874. + * overclocking the core logic, setup must be done carefully, refer
  15875. + * to the driver for details. The exact multiplier required varies
  15876. + * by part and system configuration; refer to the Hifn documentation.
  15877. + */
  15878. +#define HIFN_PLL_REF_SEL 0x00000001 /* REF/HBI clk selection */
  15879. +#define HIFN_PLL_BP 0x00000002 /* bypass (used during setup) */
  15880. +/* bit 2 reserved */
  15881. +#define HIFN_PLL_PK_CLK_SEL 0x00000008 /* public key clk select */
  15882. +#define HIFN_PLL_PE_CLK_SEL 0x00000010 /* packet engine clk select */
  15883. +/* bits 5-9 reserved */
  15884. +#define HIFN_PLL_MBSET 0x00000400 /* must be set to 1 */
  15885. +#define HIFN_PLL_ND 0x00003800 /* Fpll_ref multiplier select */
  15886. +#define HIFN_PLL_ND_SHIFT 11
  15887. +#define HIFN_PLL_ND_2 0x00000000 /* 2x */
  15888. +#define HIFN_PLL_ND_4 0x00000800 /* 4x */
  15889. +#define HIFN_PLL_ND_6 0x00001000 /* 6x */
  15890. +#define HIFN_PLL_ND_8 0x00001800 /* 8x */
  15891. +#define HIFN_PLL_ND_10 0x00002000 /* 10x */
  15892. +#define HIFN_PLL_ND_12 0x00002800 /* 12x */
  15893. +/* bits 14-15 reserved */
  15894. +#define HIFN_PLL_IS 0x00010000 /* charge pump current select */
  15895. +/* bits 17-31 reserved */
  15896. +
  15897. +/*
  15898. + * Board configuration specifies only these bits.
  15899. + */
  15900. +#define HIFN_PLL_CONFIG (HIFN_PLL_IS|HIFN_PLL_ND|HIFN_PLL_REF_SEL)
  15901. +
  15902. +/*
  15903. + * Public Key Engine Mode Register
  15904. + */
  15905. +#define HIFN_PKMODE_HOSTINVERT (1 << 0) /* HOST INVERT */
  15906. +#define HIFN_PKMODE_ENHANCED (1 << 1) /* Enable enhanced mode */
  15907. +
  15908. +
  15909. +/*********************************************************************
  15910. + * Structs for board commands
  15911. + *
  15912. + *********************************************************************/
  15913. +
  15914. +/*
  15915. + * Structure to help build up the command data structure.
  15916. + */
  15917. +typedef struct hifn_base_command {
  15918. + volatile u_int16_t masks;
  15919. + volatile u_int16_t session_num;
  15920. + volatile u_int16_t total_source_count;
  15921. + volatile u_int16_t total_dest_count;
  15922. +} hifn_base_command_t;
  15923. +
  15924. +#define HIFN_BASE_CMD_MAC 0x0400
  15925. +#define HIFN_BASE_CMD_CRYPT 0x0800
  15926. +#define HIFN_BASE_CMD_DECODE 0x2000
  15927. +#define HIFN_BASE_CMD_SRCLEN_M 0xc000
  15928. +#define HIFN_BASE_CMD_SRCLEN_S 14
  15929. +#define HIFN_BASE_CMD_DSTLEN_M 0x3000
  15930. +#define HIFN_BASE_CMD_DSTLEN_S 12
  15931. +#define HIFN_BASE_CMD_LENMASK_HI 0x30000
  15932. +#define HIFN_BASE_CMD_LENMASK_LO 0x0ffff
  15933. +
  15934. +/*
  15935. + * Structure to help build up the command data structure.
  15936. + */
  15937. +typedef struct hifn_crypt_command {
  15938. + volatile u_int16_t masks;
  15939. + volatile u_int16_t header_skip;
  15940. + volatile u_int16_t source_count;
  15941. + volatile u_int16_t reserved;
  15942. +} hifn_crypt_command_t;
  15943. +
  15944. +#define HIFN_CRYPT_CMD_ALG_MASK 0x0003 /* algorithm: */
  15945. +#define HIFN_CRYPT_CMD_ALG_DES 0x0000 /* DES */
  15946. +#define HIFN_CRYPT_CMD_ALG_3DES 0x0001 /* 3DES */
  15947. +#define HIFN_CRYPT_CMD_ALG_RC4 0x0002 /* RC4 */
  15948. +#define HIFN_CRYPT_CMD_ALG_AES 0x0003 /* AES */
  15949. +#define HIFN_CRYPT_CMD_MODE_MASK 0x0018 /* Encrypt mode: */
  15950. +#define HIFN_CRYPT_CMD_MODE_ECB 0x0000 /* ECB */
  15951. +#define HIFN_CRYPT_CMD_MODE_CBC 0x0008 /* CBC */
  15952. +#define HIFN_CRYPT_CMD_MODE_CFB 0x0010 /* CFB */
  15953. +#define HIFN_CRYPT_CMD_MODE_OFB 0x0018 /* OFB */
  15954. +#define HIFN_CRYPT_CMD_CLR_CTX 0x0040 /* clear context */
  15955. +#define HIFN_CRYPT_CMD_NEW_KEY 0x0800 /* expect new key */
  15956. +#define HIFN_CRYPT_CMD_NEW_IV 0x1000 /* expect new iv */
  15957. +
  15958. +#define HIFN_CRYPT_CMD_SRCLEN_M 0xc000
  15959. +#define HIFN_CRYPT_CMD_SRCLEN_S 14
  15960. +
  15961. +#define HIFN_CRYPT_CMD_KSZ_MASK 0x0600 /* AES key size: */
  15962. +#define HIFN_CRYPT_CMD_KSZ_128 0x0000 /* 128 bit */
  15963. +#define HIFN_CRYPT_CMD_KSZ_192 0x0200 /* 192 bit */
  15964. +#define HIFN_CRYPT_CMD_KSZ_256 0x0400 /* 256 bit */
  15965. +
  15966. +/*
  15967. + * Structure to help build up the command data structure.
  15968. + */
  15969. +typedef struct hifn_mac_command {
  15970. + volatile u_int16_t masks;
  15971. + volatile u_int16_t header_skip;
  15972. + volatile u_int16_t source_count;
  15973. + volatile u_int16_t reserved;
  15974. +} hifn_mac_command_t;
  15975. +
  15976. +#define HIFN_MAC_CMD_ALG_MASK 0x0001
  15977. +#define HIFN_MAC_CMD_ALG_SHA1 0x0000
  15978. +#define HIFN_MAC_CMD_ALG_MD5 0x0001
  15979. +#define HIFN_MAC_CMD_MODE_MASK 0x000c
  15980. +#define HIFN_MAC_CMD_MODE_HMAC 0x0000
  15981. +#define HIFN_MAC_CMD_MODE_SSL_MAC 0x0004
  15982. +#define HIFN_MAC_CMD_MODE_HASH 0x0008
  15983. +#define HIFN_MAC_CMD_MODE_FULL 0x0004
  15984. +#define HIFN_MAC_CMD_TRUNC 0x0010
  15985. +#define HIFN_MAC_CMD_RESULT 0x0020
  15986. +#define HIFN_MAC_CMD_APPEND 0x0040
  15987. +#define HIFN_MAC_CMD_SRCLEN_M 0xc000
  15988. +#define HIFN_MAC_CMD_SRCLEN_S 14
  15989. +
  15990. +/*
  15991. + * MAC POS IPsec initiates authentication after encryption on encodes
  15992. + * and before decryption on decodes.
  15993. + */
  15994. +#define HIFN_MAC_CMD_POS_IPSEC 0x0200
  15995. +#define HIFN_MAC_CMD_NEW_KEY 0x0800
  15996. +
  15997. +/*
  15998. + * The poll frequency and poll scalar defines are unshifted values used
  15999. + * to set fields in the DMA Configuration Register.
  16000. + */
  16001. +#ifndef HIFN_POLL_FREQUENCY
  16002. +#define HIFN_POLL_FREQUENCY 0x1
  16003. +#endif
  16004. +
  16005. +#ifndef HIFN_POLL_SCALAR
  16006. +#define HIFN_POLL_SCALAR 0x0
  16007. +#endif
  16008. +
  16009. +#define HIFN_MAX_SEGLEN 0xffff /* maximum dma segment len */
  16010. +#define HIFN_MAX_DMALEN 0x3ffff /* maximum dma length */
  16011. +#endif /* __HIFN_H__ */
  16012. diff -Nur linux-2.6.35.orig/crypto/ocf/hifn/hifn7751var.h linux-2.6.35/crypto/ocf/hifn/hifn7751var.h
  16013. --- linux-2.6.35.orig/crypto/ocf/hifn/hifn7751var.h 1970-01-01 01:00:00.000000000 +0100
  16014. +++ linux-2.6.35/crypto/ocf/hifn/hifn7751var.h 2010-08-05 22:02:09.453821353 +0200
  16015. @@ -0,0 +1,369 @@
  16016. +/* $FreeBSD: src/sys/dev/hifn/hifn7751var.h,v 1.9 2007/03/21 03:42:49 sam Exp $ */
  16017. +/* $OpenBSD: hifn7751var.h,v 1.42 2002/04/08 17:49:42 jason Exp $ */
  16018. +
  16019. +/*-
  16020. + * Invertex AEON / Hifn 7751 driver
  16021. + * Copyright (c) 1999 Invertex Inc. All rights reserved.
  16022. + * Copyright (c) 1999 Theo de Raadt
  16023. + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  16024. + * http://www.netsec.net
  16025. + *
  16026. + * Please send any comments, feedback, bug-fixes, or feature requests to
  16027. + * software@invertex.com.
  16028. + *
  16029. + * Redistribution and use in source and binary forms, with or without
  16030. + * modification, are permitted provided that the following conditions
  16031. + * are met:
  16032. + *
  16033. + * 1. Redistributions of source code must retain the above copyright
  16034. + * notice, this list of conditions and the following disclaimer.
  16035. + * 2. Redistributions in binary form must reproduce the above copyright
  16036. + * notice, this list of conditions and the following disclaimer in the
  16037. + * documentation and/or other materials provided with the distribution.
  16038. + * 3. The name of the author may not be used to endorse or promote products
  16039. + * derived from this software without specific prior written permission.
  16040. + *
  16041. + *
  16042. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16043. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16044. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  16045. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  16046. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  16047. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  16048. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  16049. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  16050. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  16051. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16052. + *
  16053. + * Effort sponsored in part by the Defense Advanced Research Projects
  16054. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  16055. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  16056. + *
  16057. + */
  16058. +
  16059. +#ifndef __HIFN7751VAR_H__
  16060. +#define __HIFN7751VAR_H__
  16061. +
  16062. +#ifdef __KERNEL__
  16063. +
  16064. +/*
  16065. + * Some configurable values for the driver. By default command+result
  16066. + * descriptor rings are the same size. The src+dst descriptor rings
  16067. + * are sized at 3.5x the number of potential commands. Slower parts
  16068. + * (e.g. 7951) tend to run out of src descriptors; faster parts (7811)
  16069. + * src+cmd/result descriptors. It's not clear that increasing the size
  16070. + * of the descriptor rings helps performance significantly as other
  16071. + * factors tend to come into play (e.g. copying misaligned packets).
  16072. + */
  16073. +#define HIFN_D_CMD_RSIZE 24 /* command descriptors */
  16074. +#define HIFN_D_SRC_RSIZE ((HIFN_D_CMD_RSIZE * 7) / 2) /* source descriptors */
  16075. +#define HIFN_D_RES_RSIZE HIFN_D_CMD_RSIZE /* result descriptors */
  16076. +#define HIFN_D_DST_RSIZE HIFN_D_SRC_RSIZE /* destination descriptors */
  16077. +
  16078. +/*
  16079. + * Length values for cryptography
  16080. + */
  16081. +#define HIFN_DES_KEY_LENGTH 8
  16082. +#define HIFN_3DES_KEY_LENGTH 24
  16083. +#define HIFN_MAX_CRYPT_KEY_LENGTH HIFN_3DES_KEY_LENGTH
  16084. +#define HIFN_IV_LENGTH 8
  16085. +#define HIFN_AES_IV_LENGTH 16
  16086. +#define HIFN_MAX_IV_LENGTH HIFN_AES_IV_LENGTH
  16087. +
  16088. +/*
  16089. + * Length values for authentication
  16090. + */
  16091. +#define HIFN_MAC_KEY_LENGTH 64
  16092. +#define HIFN_MD5_LENGTH 16
  16093. +#define HIFN_SHA1_LENGTH 20
  16094. +#define HIFN_MAC_TRUNC_LENGTH 12
  16095. +
  16096. +#define MAX_SCATTER 64
  16097. +
  16098. +/*
  16099. + * Data structure to hold all 4 rings and any other ring related data.
  16100. + */
  16101. +struct hifn_dma {
  16102. + /*
  16103. + * Descriptor rings. We add +1 to the size to accomidate the
  16104. + * jump descriptor.
  16105. + */
  16106. + struct hifn_desc cmdr[HIFN_D_CMD_RSIZE+1];
  16107. + struct hifn_desc srcr[HIFN_D_SRC_RSIZE+1];
  16108. + struct hifn_desc dstr[HIFN_D_DST_RSIZE+1];
  16109. + struct hifn_desc resr[HIFN_D_RES_RSIZE+1];
  16110. +
  16111. + struct hifn_command *hifn_commands[HIFN_D_RES_RSIZE];
  16112. +
  16113. + u_char command_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_COMMAND];
  16114. + u_char result_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_RESULT];
  16115. + u_int32_t slop[HIFN_D_CMD_RSIZE];
  16116. +
  16117. + u_int64_t test_src, test_dst;
  16118. +
  16119. + /*
  16120. + * Our current positions for insertion and removal from the desriptor
  16121. + * rings.
  16122. + */
  16123. + int cmdi, srci, dsti, resi;
  16124. + volatile int cmdu, srcu, dstu, resu;
  16125. + int cmdk, srck, dstk, resk;
  16126. +};
  16127. +
  16128. +struct hifn_session {
  16129. + int hs_used;
  16130. + int hs_mlen;
  16131. + u_int8_t hs_iv[HIFN_MAX_IV_LENGTH];
  16132. +};
  16133. +
  16134. +#define HIFN_RING_SYNC(sc, r, i, f) \
  16135. + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
  16136. +
  16137. +#define HIFN_CMDR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), cmdr, (i), (f))
  16138. +#define HIFN_RESR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), resr, (i), (f))
  16139. +#define HIFN_SRCR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), srcr, (i), (f))
  16140. +#define HIFN_DSTR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), dstr, (i), (f))
  16141. +
  16142. +#define HIFN_CMD_SYNC(sc, i, f) \
  16143. + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
  16144. +
  16145. +#define HIFN_RES_SYNC(sc, i, f) \
  16146. + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
  16147. +
  16148. +typedef int bus_size_t;
  16149. +
  16150. +/*
  16151. + * Holds data specific to a single HIFN board.
  16152. + */
  16153. +struct hifn_softc {
  16154. + softc_device_decl sc_dev;
  16155. +
  16156. + struct pci_dev *sc_pcidev; /* PCI device pointer */
  16157. + spinlock_t sc_mtx; /* per-instance lock */
  16158. +
  16159. + int sc_num; /* for multiple devs */
  16160. +
  16161. + ocf_iomem_t sc_bar0;
  16162. + bus_size_t sc_bar0_lastreg;/* bar0 last reg written */
  16163. + ocf_iomem_t sc_bar1;
  16164. + bus_size_t sc_bar1_lastreg;/* bar1 last reg written */
  16165. +
  16166. + int sc_irq;
  16167. +
  16168. + u_int32_t sc_dmaier;
  16169. + u_int32_t sc_drammodel; /* 1=dram, 0=sram */
  16170. + u_int32_t sc_pllconfig; /* 7954/7955/7956 PLL config */
  16171. +
  16172. + struct hifn_dma *sc_dma;
  16173. + dma_addr_t sc_dma_physaddr;/* physical address of sc_dma */
  16174. +
  16175. + int sc_dmansegs;
  16176. + int32_t sc_cid;
  16177. + int sc_maxses;
  16178. + int sc_nsessions;
  16179. + struct hifn_session *sc_sessions;
  16180. + int sc_ramsize;
  16181. + int sc_flags;
  16182. +#define HIFN_HAS_RNG 0x1 /* includes random number generator */
  16183. +#define HIFN_HAS_PUBLIC 0x2 /* includes public key support */
  16184. +#define HIFN_HAS_AES 0x4 /* includes AES support */
  16185. +#define HIFN_IS_7811 0x8 /* Hifn 7811 part */
  16186. +#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
  16187. +
  16188. + struct timer_list sc_tickto; /* for managing DMA */
  16189. +
  16190. + int sc_rngfirst;
  16191. + int sc_rnghz; /* RNG polling frequency */
  16192. +
  16193. + int sc_c_busy; /* command ring busy */
  16194. + int sc_s_busy; /* source data ring busy */
  16195. + int sc_d_busy; /* destination data ring busy */
  16196. + int sc_r_busy; /* result ring busy */
  16197. + int sc_active; /* for initial countdown */
  16198. + int sc_needwakeup; /* ops q'd wating on resources */
  16199. + int sc_curbatch; /* # ops submitted w/o int */
  16200. + int sc_suspended;
  16201. +#ifdef HIFN_VULCANDEV
  16202. + struct cdev *sc_pkdev;
  16203. +#endif
  16204. +};
  16205. +
  16206. +#define HIFN_LOCK(_sc) spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
  16207. +#define HIFN_UNLOCK(_sc) spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
  16208. +
  16209. +/*
  16210. + * hifn_command_t
  16211. + *
  16212. + * This is the control structure used to pass commands to hifn_encrypt().
  16213. + *
  16214. + * flags
  16215. + * -----
  16216. + * Flags is the bitwise "or" values for command configuration. A single
  16217. + * encrypt direction needs to be set:
  16218. + *
  16219. + * HIFN_ENCODE or HIFN_DECODE
  16220. + *
  16221. + * To use cryptography, a single crypto algorithm must be included:
  16222. + *
  16223. + * HIFN_CRYPT_3DES or HIFN_CRYPT_DES
  16224. + *
  16225. + * To use authentication is used, a single MAC algorithm must be included:
  16226. + *
  16227. + * HIFN_MAC_MD5 or HIFN_MAC_SHA1
  16228. + *
  16229. + * By default MD5 uses a 16 byte hash and SHA-1 uses a 20 byte hash.
  16230. + * If the value below is set, hash values are truncated or assumed
  16231. + * truncated to 12 bytes:
  16232. + *
  16233. + * HIFN_MAC_TRUNC
  16234. + *
  16235. + * Keys for encryption and authentication can be sent as part of a command,
  16236. + * or the last key value used with a particular session can be retrieved
  16237. + * and used again if either of these flags are not specified.
  16238. + *
  16239. + * HIFN_CRYPT_NEW_KEY, HIFN_MAC_NEW_KEY
  16240. + *
  16241. + * session_num
  16242. + * -----------
  16243. + * A number between 0 and 2048 (for DRAM models) or a number between
  16244. + * 0 and 768 (for SRAM models). Those who don't want to use session
  16245. + * numbers should leave value at zero and send a new crypt key and/or
  16246. + * new MAC key on every command. If you use session numbers and
  16247. + * don't send a key with a command, the last key sent for that same
  16248. + * session number will be used.
  16249. + *
  16250. + * Warning: Using session numbers and multiboard at the same time
  16251. + * is currently broken.
  16252. + *
  16253. + * mbuf
  16254. + * ----
  16255. + * Either fill in the mbuf pointer and npa=0 or
  16256. + * fill packp[] and packl[] and set npa to > 0
  16257. + *
  16258. + * mac_header_skip
  16259. + * ---------------
  16260. + * The number of bytes of the source_buf that are skipped over before
  16261. + * authentication begins. This must be a number between 0 and 2^16-1
  16262. + * and can be used by IPsec implementers to skip over IP headers.
  16263. + * *** Value ignored if authentication not used ***
  16264. + *
  16265. + * crypt_header_skip
  16266. + * -----------------
  16267. + * The number of bytes of the source_buf that are skipped over before
  16268. + * the cryptographic operation begins. This must be a number between 0
  16269. + * and 2^16-1. For IPsec, this number will always be 8 bytes larger
  16270. + * than the auth_header_skip (to skip over the ESP header).
  16271. + * *** Value ignored if cryptography not used ***
  16272. + *
  16273. + */
  16274. +struct hifn_operand {
  16275. + union {
  16276. + struct sk_buff *skb;
  16277. + struct uio *io;
  16278. + unsigned char *buf;
  16279. + } u;
  16280. + void *map;
  16281. + bus_size_t mapsize;
  16282. + int nsegs;
  16283. + struct {
  16284. + dma_addr_t ds_addr;
  16285. + int ds_len;
  16286. + } segs[MAX_SCATTER];
  16287. +};
  16288. +
  16289. +struct hifn_command {
  16290. + u_int16_t session_num;
  16291. + u_int16_t base_masks, cry_masks, mac_masks;
  16292. + u_int8_t iv[HIFN_MAX_IV_LENGTH], *ck, mac[HIFN_MAC_KEY_LENGTH];
  16293. + int cklen;
  16294. + int sloplen, slopidx;
  16295. +
  16296. + struct hifn_operand src;
  16297. + struct hifn_operand dst;
  16298. +
  16299. + struct hifn_softc *softc;
  16300. + struct cryptop *crp;
  16301. + struct cryptodesc *enccrd, *maccrd;
  16302. +};
  16303. +
  16304. +#define src_skb src.u.skb
  16305. +#define src_io src.u.io
  16306. +#define src_map src.map
  16307. +#define src_mapsize src.mapsize
  16308. +#define src_segs src.segs
  16309. +#define src_nsegs src.nsegs
  16310. +#define src_buf src.u.buf
  16311. +
  16312. +#define dst_skb dst.u.skb
  16313. +#define dst_io dst.u.io
  16314. +#define dst_map dst.map
  16315. +#define dst_mapsize dst.mapsize
  16316. +#define dst_segs dst.segs
  16317. +#define dst_nsegs dst.nsegs
  16318. +#define dst_buf dst.u.buf
  16319. +
  16320. +/*
  16321. + * Return values for hifn_crypto()
  16322. + */
  16323. +#define HIFN_CRYPTO_SUCCESS 0
  16324. +#define HIFN_CRYPTO_BAD_INPUT (-1)
  16325. +#define HIFN_CRYPTO_RINGS_FULL (-2)
  16326. +
  16327. +/**************************************************************************
  16328. + *
  16329. + * Function: hifn_crypto
  16330. + *
  16331. + * Purpose: Called by external drivers to begin an encryption on the
  16332. + * HIFN board.
  16333. + *
  16334. + * Blocking/Non-blocking Issues
  16335. + * ============================
  16336. + * The driver cannot block in hifn_crypto (no calls to tsleep) currently.
  16337. + * hifn_crypto() returns HIFN_CRYPTO_RINGS_FULL if there is not enough
  16338. + * room in any of the rings for the request to proceed.
  16339. + *
  16340. + * Return Values
  16341. + * =============
  16342. + * 0 for success, negative values on error
  16343. + *
  16344. + * Defines for negative error codes are:
  16345. + *
  16346. + * HIFN_CRYPTO_BAD_INPUT : The passed in command had invalid settings.
  16347. + * HIFN_CRYPTO_RINGS_FULL : All DMA rings were full and non-blocking
  16348. + * behaviour was requested.
  16349. + *
  16350. + *************************************************************************/
  16351. +
  16352. +/*
  16353. + * Convert back and forth from 'sid' to 'card' and 'session'
  16354. + */
  16355. +#define HIFN_CARD(sid) (((sid) & 0xf0000000) >> 28)
  16356. +#define HIFN_SESSION(sid) ((sid) & 0x000007ff)
  16357. +#define HIFN_SID(crd,ses) (((crd) << 28) | ((ses) & 0x7ff))
  16358. +
  16359. +#endif /* _KERNEL */
  16360. +
  16361. +struct hifn_stats {
  16362. + u_int64_t hst_ibytes;
  16363. + u_int64_t hst_obytes;
  16364. + u_int32_t hst_ipackets;
  16365. + u_int32_t hst_opackets;
  16366. + u_int32_t hst_invalid;
  16367. + u_int32_t hst_nomem; /* malloc or one of hst_nomem_* */
  16368. + u_int32_t hst_abort;
  16369. + u_int32_t hst_noirq; /* IRQ for no reason */
  16370. + u_int32_t hst_totbatch; /* ops submitted w/o interrupt */
  16371. + u_int32_t hst_maxbatch; /* max ops submitted together */
  16372. + u_int32_t hst_unaligned; /* unaligned src caused copy */
  16373. + /*
  16374. + * The following divides hst_nomem into more specific buckets.
  16375. + */
  16376. + u_int32_t hst_nomem_map; /* bus_dmamap_create failed */
  16377. + u_int32_t hst_nomem_load; /* bus_dmamap_load_* failed */
  16378. + u_int32_t hst_nomem_mbuf; /* MGET* failed */
  16379. + u_int32_t hst_nomem_mcl; /* MCLGET* failed */
  16380. + u_int32_t hst_nomem_cr; /* out of command/result descriptor */
  16381. + u_int32_t hst_nomem_sd; /* out of src/dst descriptors */
  16382. +};
  16383. +
  16384. +#endif /* __HIFN7751VAR_H__ */
  16385. diff -Nur linux-2.6.35.orig/crypto/ocf/hifn/hifnHIPP.c linux-2.6.35/crypto/ocf/hifn/hifnHIPP.c
  16386. --- linux-2.6.35.orig/crypto/ocf/hifn/hifnHIPP.c 1970-01-01 01:00:00.000000000 +0100
  16387. +++ linux-2.6.35/crypto/ocf/hifn/hifnHIPP.c 2010-08-05 22:02:09.593796945 +0200
  16388. @@ -0,0 +1,420 @@
  16389. +/*-
  16390. + * Driver for Hifn HIPP-I/II chipset
  16391. + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
  16392. + *
  16393. + * Redistribution and use in source and binary forms, with or without
  16394. + * modification, are permitted provided that the following conditions
  16395. + * are met:
  16396. + *
  16397. + * 1. Redistributions of source code must retain the above copyright
  16398. + * notice, this list of conditions and the following disclaimer.
  16399. + * 2. Redistributions in binary form must reproduce the above copyright
  16400. + * notice, this list of conditions and the following disclaimer in the
  16401. + * documentation and/or other materials provided with the distribution.
  16402. + * 3. The name of the author may not be used to endorse or promote products
  16403. + * derived from this software without specific prior written permission.
  16404. + *
  16405. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16406. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16407. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  16408. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  16409. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  16410. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  16411. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  16412. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  16413. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  16414. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16415. + *
  16416. + * Effort sponsored by Hifn Inc.
  16417. + *
  16418. + */
  16419. +
  16420. +/*
  16421. + * Driver for various Hifn encryption processors.
  16422. + */
  16423. +#ifndef AUTOCONF_INCLUDED
  16424. +#include <linux/config.h>
  16425. +#endif
  16426. +#include <linux/module.h>
  16427. +#include <linux/init.h>
  16428. +#include <linux/list.h>
  16429. +#include <linux/slab.h>
  16430. +#include <linux/wait.h>
  16431. +#include <linux/sched.h>
  16432. +#include <linux/pci.h>
  16433. +#include <linux/delay.h>
  16434. +#include <linux/interrupt.h>
  16435. +#include <linux/spinlock.h>
  16436. +#include <linux/random.h>
  16437. +#include <linux/version.h>
  16438. +#include <linux/skbuff.h>
  16439. +#include <linux/uio.h>
  16440. +#include <linux/sysfs.h>
  16441. +#include <linux/miscdevice.h>
  16442. +#include <asm/io.h>
  16443. +
  16444. +#include <cryptodev.h>
  16445. +
  16446. +#include "hifnHIPPreg.h"
  16447. +#include "hifnHIPPvar.h"
  16448. +
  16449. +#if 1
  16450. +#define DPRINTF(a...) if (hipp_debug) { \
  16451. + printk("%s: ", sc ? \
  16452. + device_get_nameunit(sc->sc_dev) : "hifn"); \
  16453. + printk(a); \
  16454. + } else
  16455. +#else
  16456. +#define DPRINTF(a...)
  16457. +#endif
  16458. +
  16459. +typedef int bus_size_t;
  16460. +
  16461. +static inline int
  16462. +pci_get_revid(struct pci_dev *dev)
  16463. +{
  16464. + u8 rid = 0;
  16465. + pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
  16466. + return rid;
  16467. +}
  16468. +
  16469. +#define debug hipp_debug
  16470. +int hipp_debug = 0;
  16471. +module_param(hipp_debug, int, 0644);
  16472. +MODULE_PARM_DESC(hipp_debug, "Enable debug");
  16473. +
  16474. +int hipp_maxbatch = 1;
  16475. +module_param(hipp_maxbatch, int, 0644);
  16476. +MODULE_PARM_DESC(hipp_maxbatch, "max ops to batch w/o interrupt");
  16477. +
  16478. +static int hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent);
  16479. +static void hipp_remove(struct pci_dev *dev);
  16480. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  16481. +static irqreturn_t hipp_intr(int irq, void *arg);
  16482. +#else
  16483. +static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs);
  16484. +#endif
  16485. +
  16486. +static int hipp_num_chips = 0;
  16487. +static struct hipp_softc *hipp_chip_idx[HIPP_MAX_CHIPS];
  16488. +
  16489. +static int hipp_newsession(device_t, u_int32_t *, struct cryptoini *);
  16490. +static int hipp_freesession(device_t, u_int64_t);
  16491. +static int hipp_process(device_t, struct cryptop *, int);
  16492. +
  16493. +static device_method_t hipp_methods = {
  16494. + /* crypto device methods */
  16495. + DEVMETHOD(cryptodev_newsession, hipp_newsession),
  16496. + DEVMETHOD(cryptodev_freesession,hipp_freesession),
  16497. + DEVMETHOD(cryptodev_process, hipp_process),
  16498. +};
  16499. +
  16500. +static __inline u_int32_t
  16501. +READ_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg)
  16502. +{
  16503. + u_int32_t v = readl(sc->sc_bar[barno] + reg);
  16504. + //sc->sc_bar0_lastreg = (bus_size_t) -1;
  16505. + return (v);
  16506. +}
  16507. +static __inline void
  16508. +WRITE_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg, u_int32_t val)
  16509. +{
  16510. + writel(val, sc->sc_bar[barno] + reg);
  16511. +}
  16512. +
  16513. +#define READ_REG_0(sc, reg) READ_REG(sc, 0, reg)
  16514. +#define WRITE_REG_0(sc, reg, val) WRITE_REG(sc,0, reg, val)
  16515. +#define READ_REG_1(sc, reg) READ_REG(sc, 1, reg)
  16516. +#define WRITE_REG_1(sc, reg, val) WRITE_REG(sc,1, reg, val)
  16517. +
  16518. +static int
  16519. +hipp_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  16520. +{
  16521. + return EINVAL;
  16522. +}
  16523. +
  16524. +static int
  16525. +hipp_freesession(device_t dev, u_int64_t tid)
  16526. +{
  16527. + return EINVAL;
  16528. +}
  16529. +
  16530. +static int
  16531. +hipp_process(device_t dev, struct cryptop *crp, int hint)
  16532. +{
  16533. + return EINVAL;
  16534. +}
  16535. +
  16536. +static const char*
  16537. +hipp_partname(struct hipp_softc *sc, char buf[128], size_t blen)
  16538. +{
  16539. + char *n = NULL;
  16540. +
  16541. + switch (pci_get_vendor(sc->sc_pcidev)) {
  16542. + case PCI_VENDOR_HIFN:
  16543. + switch (pci_get_device(sc->sc_pcidev)) {
  16544. + case PCI_PRODUCT_HIFN_7855: n = "Hifn 7855";
  16545. + case PCI_PRODUCT_HIFN_8155: n = "Hifn 8155";
  16546. + case PCI_PRODUCT_HIFN_6500: n = "Hifn 6500";
  16547. + }
  16548. + }
  16549. +
  16550. + if(n==NULL) {
  16551. + snprintf(buf, blen, "VID=%02x,PID=%02x",
  16552. + pci_get_vendor(sc->sc_pcidev),
  16553. + pci_get_device(sc->sc_pcidev));
  16554. + } else {
  16555. + buf[0]='\0';
  16556. + strncat(buf, n, blen);
  16557. + }
  16558. + return buf;
  16559. +}
  16560. +
  16561. +struct hipp_fs_entry {
  16562. + struct attribute attr;
  16563. + /* other stuff */
  16564. +};
  16565. +
  16566. +
  16567. +static ssize_t
  16568. +cryptoid_show(struct device *dev,
  16569. + struct device_attribute *attr,
  16570. + char *buf)
  16571. +{
  16572. + struct hipp_softc *sc;
  16573. +
  16574. + sc = pci_get_drvdata(to_pci_dev (dev));
  16575. + return sprintf (buf, "%d\n", sc->sc_cid);
  16576. +}
  16577. +
  16578. +struct device_attribute hipp_dev_cryptoid = __ATTR_RO(cryptoid);
  16579. +
  16580. +/*
  16581. + * Attach an interface that successfully probed.
  16582. + */
  16583. +static int
  16584. +hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  16585. +{
  16586. + struct hipp_softc *sc = NULL;
  16587. + int i;
  16588. + //char rbase;
  16589. + //u_int16_t ena;
  16590. + int rev;
  16591. + //int rseg;
  16592. + int rc;
  16593. +
  16594. + DPRINTF("%s()\n", __FUNCTION__);
  16595. +
  16596. + if (pci_enable_device(dev) < 0)
  16597. + return(-ENODEV);
  16598. +
  16599. + if (pci_set_mwi(dev))
  16600. + return(-ENODEV);
  16601. +
  16602. + if (!dev->irq) {
  16603. + printk("hifn: found device with no IRQ assigned. check BIOS settings!");
  16604. + pci_disable_device(dev);
  16605. + return(-ENODEV);
  16606. + }
  16607. +
  16608. + sc = (struct hipp_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  16609. + if (!sc)
  16610. + return(-ENOMEM);
  16611. + memset(sc, 0, sizeof(*sc));
  16612. +
  16613. + softc_device_init(sc, "hifn-hipp", hipp_num_chips, hipp_methods);
  16614. +
  16615. + sc->sc_pcidev = dev;
  16616. + sc->sc_irq = -1;
  16617. + sc->sc_cid = -1;
  16618. + sc->sc_num = hipp_num_chips++;
  16619. +
  16620. + if (sc->sc_num < HIPP_MAX_CHIPS)
  16621. + hipp_chip_idx[sc->sc_num] = sc;
  16622. +
  16623. + pci_set_drvdata(sc->sc_pcidev, sc);
  16624. +
  16625. + spin_lock_init(&sc->sc_mtx);
  16626. +
  16627. + /*
  16628. + * Setup PCI resources.
  16629. + * The READ_REG_0, WRITE_REG_0, READ_REG_1,
  16630. + * and WRITE_REG_1 macros throughout the driver are used
  16631. + * to permit better debugging.
  16632. + */
  16633. + for(i=0; i<4; i++) {
  16634. + unsigned long mem_start, mem_len;
  16635. + mem_start = pci_resource_start(sc->sc_pcidev, i);
  16636. + mem_len = pci_resource_len(sc->sc_pcidev, i);
  16637. + sc->sc_barphy[i] = (caddr_t)mem_start;
  16638. + sc->sc_bar[i] = (ocf_iomem_t) ioremap(mem_start, mem_len);
  16639. + if (!sc->sc_bar[i]) {
  16640. + device_printf(sc->sc_dev, "cannot map bar%d register space\n", i);
  16641. + goto fail;
  16642. + }
  16643. + }
  16644. +
  16645. + //hipp_reset_board(sc, 0);
  16646. + pci_set_master(sc->sc_pcidev);
  16647. +
  16648. + /*
  16649. + * Arrange the interrupt line.
  16650. + */
  16651. + rc = request_irq(dev->irq, hipp_intr, IRQF_SHARED, "hifn", sc);
  16652. + if (rc) {
  16653. + device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
  16654. + goto fail;
  16655. + }
  16656. + sc->sc_irq = dev->irq;
  16657. +
  16658. + rev = READ_REG_1(sc, HIPP_1_REVID) & 0xffff;
  16659. +
  16660. + {
  16661. + char b[32];
  16662. + device_printf(sc->sc_dev, "%s, rev %u",
  16663. + hipp_partname(sc, b, sizeof(b)), rev);
  16664. + }
  16665. +
  16666. +#if 0
  16667. + if (sc->sc_flags & HIFN_IS_7956)
  16668. + printf(", pll=0x%x<%s clk, %ux mult>",
  16669. + sc->sc_pllconfig,
  16670. + sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
  16671. + 2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
  16672. +#endif
  16673. + printf("\n");
  16674. +
  16675. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
  16676. + if (sc->sc_cid < 0) {
  16677. + device_printf(sc->sc_dev, "could not get crypto driver id\n");
  16678. + goto fail;
  16679. + }
  16680. +
  16681. +#if 0 /* cannot work with a non-GPL module */
  16682. + /* make a sysfs entry to let the world know what entry we got */
  16683. + sysfs_create_file(&sc->sc_pcidev->dev.kobj, &hipp_dev_cryptoid.attr);
  16684. +#endif
  16685. +
  16686. +#if 0
  16687. + init_timer(&sc->sc_tickto);
  16688. + sc->sc_tickto.function = hifn_tick;
  16689. + sc->sc_tickto.data = (unsigned long) sc->sc_num;
  16690. + mod_timer(&sc->sc_tickto, jiffies + HZ);
  16691. +#endif
  16692. +
  16693. +#if 0 /* no code here yet ?? */
  16694. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  16695. +#endif
  16696. +
  16697. + return (0);
  16698. +
  16699. +fail:
  16700. + if (sc->sc_cid >= 0)
  16701. + crypto_unregister_all(sc->sc_cid);
  16702. + if (sc->sc_irq != -1)
  16703. + free_irq(sc->sc_irq, sc);
  16704. +
  16705. +#if 0
  16706. + if (sc->sc_dma) {
  16707. + /* Turn off DMA polling */
  16708. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  16709. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  16710. +
  16711. + pci_free_consistent(sc->sc_pcidev,
  16712. + sizeof(*sc->sc_dma),
  16713. + sc->sc_dma, sc->sc_dma_physaddr);
  16714. + }
  16715. +#endif
  16716. + kfree(sc);
  16717. + return (-ENXIO);
  16718. +}
  16719. +
  16720. +/*
  16721. + * Detach an interface that successfully probed.
  16722. + */
  16723. +static void
  16724. +hipp_remove(struct pci_dev *dev)
  16725. +{
  16726. + struct hipp_softc *sc = pci_get_drvdata(dev);
  16727. + unsigned long l_flags;
  16728. +
  16729. + DPRINTF("%s()\n", __FUNCTION__);
  16730. +
  16731. + /* disable interrupts */
  16732. + HIPP_LOCK(sc);
  16733. +
  16734. +#if 0
  16735. + WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
  16736. + HIFN_UNLOCK(sc);
  16737. +
  16738. + /*XXX other resources */
  16739. + del_timer_sync(&sc->sc_tickto);
  16740. +
  16741. + /* Turn off DMA polling */
  16742. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  16743. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  16744. +#endif
  16745. +
  16746. + crypto_unregister_all(sc->sc_cid);
  16747. +
  16748. + free_irq(sc->sc_irq, sc);
  16749. +
  16750. +#if 0
  16751. + pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
  16752. + sc->sc_dma, sc->sc_dma_physaddr);
  16753. +#endif
  16754. +}
  16755. +
  16756. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  16757. +static irqreturn_t hipp_intr(int irq, void *arg)
  16758. +#else
  16759. +static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs)
  16760. +#endif
  16761. +{
  16762. + struct hipp_softc *sc = arg;
  16763. +
  16764. + sc = sc; /* shut up compiler */
  16765. +
  16766. + return IRQ_HANDLED;
  16767. +}
  16768. +
  16769. +static struct pci_device_id hipp_pci_tbl[] = {
  16770. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7855,
  16771. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  16772. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_8155,
  16773. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  16774. +};
  16775. +MODULE_DEVICE_TABLE(pci, hipp_pci_tbl);
  16776. +
  16777. +static struct pci_driver hipp_driver = {
  16778. + .name = "hipp",
  16779. + .id_table = hipp_pci_tbl,
  16780. + .probe = hipp_probe,
  16781. + .remove = hipp_remove,
  16782. + /* add PM stuff here one day */
  16783. +};
  16784. +
  16785. +static int __init hipp_init (void)
  16786. +{
  16787. + struct hipp_softc *sc = NULL;
  16788. + int rc;
  16789. +
  16790. + DPRINTF("%s(%p)\n", __FUNCTION__, hipp_init);
  16791. +
  16792. + rc = pci_register_driver(&hipp_driver);
  16793. + pci_register_driver_compat(&hipp_driver, rc);
  16794. +
  16795. + return rc;
  16796. +}
  16797. +
  16798. +static void __exit hipp_exit (void)
  16799. +{
  16800. + pci_unregister_driver(&hipp_driver);
  16801. +}
  16802. +
  16803. +module_init(hipp_init);
  16804. +module_exit(hipp_exit);
  16805. +
  16806. +MODULE_LICENSE("BSD");
  16807. +MODULE_AUTHOR("Michael Richardson <mcr@xelerance.com>");
  16808. +MODULE_DESCRIPTION("OCF driver for hifn HIPP-I/II PCI crypto devices");
  16809. diff -Nur linux-2.6.35.orig/crypto/ocf/hifn/hifnHIPPreg.h linux-2.6.35/crypto/ocf/hifn/hifnHIPPreg.h
  16810. --- linux-2.6.35.orig/crypto/ocf/hifn/hifnHIPPreg.h 1970-01-01 01:00:00.000000000 +0100
  16811. +++ linux-2.6.35/crypto/ocf/hifn/hifnHIPPreg.h 2010-08-05 22:02:09.813634159 +0200
  16812. @@ -0,0 +1,46 @@
  16813. +/*-
  16814. + * Hifn HIPP-I/HIPP-II (7855/8155) driver.
  16815. + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
  16816. + *
  16817. + * Redistribution and use in source and binary forms, with or without
  16818. + * modification, are permitted provided that the following conditions
  16819. + * are met:
  16820. + *
  16821. + * 1. Redistributions of source code must retain the above copyright
  16822. + * notice, this list of conditions and the following disclaimer.
  16823. + * 2. Redistributions in binary form must reproduce the above copyright
  16824. + * notice, this list of conditions and the following disclaimer in the
  16825. + * documentation and/or other materials provided with the distribution.
  16826. + * 3. The name of the author may not be used to endorse or promote products
  16827. + * derived from this software without specific prior written permission.
  16828. + *
  16829. + *
  16830. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16831. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16832. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  16833. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  16834. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  16835. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  16836. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  16837. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  16838. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  16839. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16840. + *
  16841. + * Effort sponsored by Hifn inc.
  16842. + *
  16843. + */
  16844. +
  16845. +#ifndef __HIFNHIPP_H__
  16846. +#define __HIFNHIPP_H__
  16847. +
  16848. +/*
  16849. + * PCI vendor and device identifiers
  16850. + */
  16851. +#define PCI_VENDOR_HIFN 0x13a3 /* Hifn */
  16852. +#define PCI_PRODUCT_HIFN_6500 0x0006 /* 6500 */
  16853. +#define PCI_PRODUCT_HIFN_7855 0x001f /* 7855 */
  16854. +#define PCI_PRODUCT_HIFN_8155 0x999 /* XXX 8155 */
  16855. +
  16856. +#define HIPP_1_REVID 0x01 /* BOGUS */
  16857. +
  16858. +#endif /* __HIPP_H__ */
  16859. diff -Nur linux-2.6.35.orig/crypto/ocf/hifn/hifnHIPPvar.h linux-2.6.35/crypto/ocf/hifn/hifnHIPPvar.h
  16860. --- linux-2.6.35.orig/crypto/ocf/hifn/hifnHIPPvar.h 1970-01-01 01:00:00.000000000 +0100
  16861. +++ linux-2.6.35/crypto/ocf/hifn/hifnHIPPvar.h 2010-08-05 22:02:09.983630855 +0200
  16862. @@ -0,0 +1,93 @@
  16863. +/*
  16864. + * Hifn HIPP-I/HIPP-II (7855/8155) driver.
  16865. + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com> *
  16866. + *
  16867. + * Redistribution and use in source and binary forms, with or without
  16868. + * modification, are permitted provided that the following conditions
  16869. + * are met:
  16870. + *
  16871. + * 1. Redistributions of source code must retain the above copyright
  16872. + * notice, this list of conditions and the following disclaimer.
  16873. + * 2. Redistributions in binary form must reproduce the above copyright
  16874. + * notice, this list of conditions and the following disclaimer in the
  16875. + * documentation and/or other materials provided with the distribution.
  16876. + * 3. The name of the author may not be used to endorse or promote products
  16877. + * derived from this software without specific prior written permission.
  16878. + *
  16879. + *
  16880. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16881. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16882. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  16883. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  16884. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  16885. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  16886. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  16887. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  16888. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  16889. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16890. + *
  16891. + * Effort sponsored by Hifn inc.
  16892. + *
  16893. + */
  16894. +
  16895. +#ifndef __HIFNHIPPVAR_H__
  16896. +#define __HIFNHIPPVAR_H__
  16897. +
  16898. +#define HIPP_MAX_CHIPS 8
  16899. +
  16900. +/*
  16901. + * Holds data specific to a single Hifn HIPP-I board.
  16902. + */
  16903. +struct hipp_softc {
  16904. + softc_device_decl sc_dev;
  16905. +
  16906. + struct pci_dev *sc_pcidev; /* device backpointer */
  16907. + ocf_iomem_t sc_bar[5];
  16908. + caddr_t sc_barphy[5]; /* physical address */
  16909. + int sc_num; /* for multiple devs */
  16910. + spinlock_t sc_mtx; /* per-instance lock */
  16911. + int32_t sc_cid;
  16912. + int sc_irq;
  16913. +
  16914. +#if 0
  16915. +
  16916. + u_int32_t sc_dmaier;
  16917. + u_int32_t sc_drammodel; /* 1=dram, 0=sram */
  16918. + u_int32_t sc_pllconfig; /* 7954/7955/7956 PLL config */
  16919. +
  16920. + struct hifn_dma *sc_dma;
  16921. + dma_addr_t sc_dma_physaddr;/* physical address of sc_dma */
  16922. +
  16923. + int sc_dmansegs;
  16924. + int sc_maxses;
  16925. + int sc_nsessions;
  16926. + struct hifn_session *sc_sessions;
  16927. + int sc_ramsize;
  16928. + int sc_flags;
  16929. +#define HIFN_HAS_RNG 0x1 /* includes random number generator */
  16930. +#define HIFN_HAS_PUBLIC 0x2 /* includes public key support */
  16931. +#define HIFN_HAS_AES 0x4 /* includes AES support */
  16932. +#define HIFN_IS_7811 0x8 /* Hifn 7811 part */
  16933. +#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
  16934. +
  16935. + struct timer_list sc_tickto; /* for managing DMA */
  16936. +
  16937. + int sc_rngfirst;
  16938. + int sc_rnghz; /* RNG polling frequency */
  16939. +
  16940. + int sc_c_busy; /* command ring busy */
  16941. + int sc_s_busy; /* source data ring busy */
  16942. + int sc_d_busy; /* destination data ring busy */
  16943. + int sc_r_busy; /* result ring busy */
  16944. + int sc_active; /* for initial countdown */
  16945. + int sc_needwakeup; /* ops q'd wating on resources */
  16946. + int sc_curbatch; /* # ops submitted w/o int */
  16947. + int sc_suspended;
  16948. + struct miscdevice sc_miscdev;
  16949. +#endif
  16950. +};
  16951. +
  16952. +#define HIPP_LOCK(_sc) spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
  16953. +#define HIPP_UNLOCK(_sc) spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
  16954. +
  16955. +#endif /* __HIFNHIPPVAR_H__ */
  16956. diff -Nur linux-2.6.35.orig/crypto/ocf/hifn/Makefile linux-2.6.35/crypto/ocf/hifn/Makefile
  16957. --- linux-2.6.35.orig/crypto/ocf/hifn/Makefile 1970-01-01 01:00:00.000000000 +0100
  16958. +++ linux-2.6.35/crypto/ocf/hifn/Makefile 2010-08-05 22:02:10.024868029 +0200
  16959. @@ -0,0 +1,13 @@
  16960. +# for SGlinux builds
  16961. +-include $(ROOTDIR)/modules/.config
  16962. +
  16963. +obj-$(CONFIG_OCF_HIFN) += hifn7751.o
  16964. +obj-$(CONFIG_OCF_HIFNHIPP) += hifnHIPP.o
  16965. +
  16966. +obj ?= .
  16967. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  16968. +
  16969. +ifdef TOPDIR
  16970. +-include $(TOPDIR)/Rules.make
  16971. +endif
  16972. +
  16973. diff -Nur linux-2.6.35.orig/crypto/ocf/ixp4xx/ixp4xx.c linux-2.6.35/crypto/ocf/ixp4xx/ixp4xx.c
  16974. --- linux-2.6.35.orig/crypto/ocf/ixp4xx/ixp4xx.c 1970-01-01 01:00:00.000000000 +0100
  16975. +++ linux-2.6.35/crypto/ocf/ixp4xx/ixp4xx.c 2010-08-05 22:02:10.103664861 +0200
  16976. @@ -0,0 +1,1324 @@
  16977. +/*
  16978. + * An OCF module that uses Intels IXP CryptACC API to do the crypto.
  16979. + * This driver requires the IXP400 Access Library that is available
  16980. + * from Intel in order to operate (or compile).
  16981. + *
  16982. + * Written by David McCullough <david_mccullough@mcafee.com>
  16983. + * Copyright (C) 2006-2010 David McCullough
  16984. + * Copyright (C) 2004-2005 Intel Corporation.
  16985. + *
  16986. + * LICENSE TERMS
  16987. + *
  16988. + * The free distribution and use of this software in both source and binary
  16989. + * form is allowed (with or without changes) provided that:
  16990. + *
  16991. + * 1. distributions of this source code include the above copyright
  16992. + * notice, this list of conditions and the following disclaimer;
  16993. + *
  16994. + * 2. distributions in binary form include the above copyright
  16995. + * notice, this list of conditions and the following disclaimer
  16996. + * in the documentation and/or other associated materials;
  16997. + *
  16998. + * 3. the copyright holder's name is not used to endorse products
  16999. + * built using this software without specific written permission.
  17000. + *
  17001. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  17002. + * may be distributed under the terms of the GNU General Public License (GPL),
  17003. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  17004. + *
  17005. + * DISCLAIMER
  17006. + *
  17007. + * This software is provided 'as is' with no explicit or implied warranties
  17008. + * in respect of its properties, including, but not limited to, correctness
  17009. + * and/or fitness for purpose.
  17010. + */
  17011. +
  17012. +#ifndef AUTOCONF_INCLUDED
  17013. +#include <linux/config.h>
  17014. +#endif
  17015. +#include <linux/module.h>
  17016. +#include <linux/init.h>
  17017. +#include <linux/list.h>
  17018. +#include <linux/slab.h>
  17019. +#include <linux/sched.h>
  17020. +#include <linux/wait.h>
  17021. +#include <linux/crypto.h>
  17022. +#include <linux/interrupt.h>
  17023. +#include <asm/scatterlist.h>
  17024. +
  17025. +#include <IxTypes.h>
  17026. +#include <IxOsBuffMgt.h>
  17027. +#include <IxNpeDl.h>
  17028. +#include <IxCryptoAcc.h>
  17029. +#include <IxQMgr.h>
  17030. +#include <IxOsServices.h>
  17031. +#include <IxOsCacheMMU.h>
  17032. +
  17033. +#include <cryptodev.h>
  17034. +#include <uio.h>
  17035. +
  17036. +#ifndef IX_MBUF_PRIV
  17037. +#define IX_MBUF_PRIV(x) ((x)->priv)
  17038. +#endif
  17039. +
  17040. +struct ixp_data;
  17041. +
  17042. +struct ixp_q {
  17043. + struct list_head ixp_q_list;
  17044. + struct ixp_data *ixp_q_data;
  17045. + struct cryptop *ixp_q_crp;
  17046. + struct cryptodesc *ixp_q_ccrd;
  17047. + struct cryptodesc *ixp_q_acrd;
  17048. + IX_MBUF ixp_q_mbuf;
  17049. + UINT8 *ixp_hash_dest; /* Location for hash in client buffer */
  17050. + UINT8 *ixp_hash_src; /* Location of hash in internal buffer */
  17051. + unsigned char ixp_q_iv_data[IX_CRYPTO_ACC_MAX_CIPHER_IV_LENGTH];
  17052. + unsigned char *ixp_q_iv;
  17053. +};
  17054. +
  17055. +struct ixp_data {
  17056. + int ixp_registered; /* is the context registered */
  17057. + int ixp_crd_flags; /* detect direction changes */
  17058. +
  17059. + int ixp_cipher_alg;
  17060. + int ixp_auth_alg;
  17061. +
  17062. + UINT32 ixp_ctx_id;
  17063. + UINT32 ixp_hash_key_id; /* used when hashing */
  17064. + IxCryptoAccCtx ixp_ctx;
  17065. + IX_MBUF ixp_pri_mbuf;
  17066. + IX_MBUF ixp_sec_mbuf;
  17067. +
  17068. + struct work_struct ixp_pending_work;
  17069. + struct work_struct ixp_registration_work;
  17070. + struct list_head ixp_q; /* unprocessed requests */
  17071. +};
  17072. +
  17073. +#ifdef __ixp46X
  17074. +
  17075. +#define MAX_IOP_SIZE 64 /* words */
  17076. +#define MAX_OOP_SIZE 128
  17077. +
  17078. +#define MAX_PARAMS 3
  17079. +
  17080. +struct ixp_pkq {
  17081. + struct list_head pkq_list;
  17082. + struct cryptkop *pkq_krp;
  17083. +
  17084. + IxCryptoAccPkeEauInOperands pkq_op;
  17085. + IxCryptoAccPkeEauOpResult pkq_result;
  17086. +
  17087. + UINT32 pkq_ibuf0[MAX_IOP_SIZE];
  17088. + UINT32 pkq_ibuf1[MAX_IOP_SIZE];
  17089. + UINT32 pkq_ibuf2[MAX_IOP_SIZE];
  17090. + UINT32 pkq_obuf[MAX_OOP_SIZE];
  17091. +};
  17092. +
  17093. +static LIST_HEAD(ixp_pkq); /* current PK wait list */
  17094. +static struct ixp_pkq *ixp_pk_cur;
  17095. +static spinlock_t ixp_pkq_lock;
  17096. +
  17097. +#endif /* __ixp46X */
  17098. +
  17099. +static int ixp_blocked = 0;
  17100. +
  17101. +static int32_t ixp_id = -1;
  17102. +static struct ixp_data **ixp_sessions = NULL;
  17103. +static u_int32_t ixp_sesnum = 0;
  17104. +
  17105. +static int ixp_process(device_t, struct cryptop *, int);
  17106. +static int ixp_newsession(device_t, u_int32_t *, struct cryptoini *);
  17107. +static int ixp_freesession(device_t, u_int64_t);
  17108. +#ifdef __ixp46X
  17109. +static int ixp_kprocess(device_t, struct cryptkop *krp, int hint);
  17110. +#endif
  17111. +
  17112. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  17113. +static kmem_cache_t *qcache;
  17114. +#else
  17115. +static struct kmem_cache *qcache;
  17116. +#endif
  17117. +
  17118. +#define debug ixp_debug
  17119. +static int ixp_debug = 0;
  17120. +module_param(ixp_debug, int, 0644);
  17121. +MODULE_PARM_DESC(ixp_debug, "Enable debug");
  17122. +
  17123. +static int ixp_init_crypto = 1;
  17124. +module_param(ixp_init_crypto, int, 0444); /* RO after load/boot */
  17125. +MODULE_PARM_DESC(ixp_init_crypto, "Call ixCryptoAccInit (default is 1)");
  17126. +
  17127. +static void ixp_process_pending(void *arg);
  17128. +static void ixp_registration(void *arg);
  17129. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  17130. +static void ixp_process_pending_wq(struct work_struct *work);
  17131. +static void ixp_registration_wq(struct work_struct *work);
  17132. +#endif
  17133. +
  17134. +/*
  17135. + * dummy device structure
  17136. + */
  17137. +
  17138. +static struct {
  17139. + softc_device_decl sc_dev;
  17140. +} ixpdev;
  17141. +
  17142. +static device_method_t ixp_methods = {
  17143. + /* crypto device methods */
  17144. + DEVMETHOD(cryptodev_newsession, ixp_newsession),
  17145. + DEVMETHOD(cryptodev_freesession,ixp_freesession),
  17146. + DEVMETHOD(cryptodev_process, ixp_process),
  17147. +#ifdef __ixp46X
  17148. + DEVMETHOD(cryptodev_kprocess, ixp_kprocess),
  17149. +#endif
  17150. +};
  17151. +
  17152. +/*
  17153. + * Generate a new software session.
  17154. + */
  17155. +static int
  17156. +ixp_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  17157. +{
  17158. + struct ixp_data *ixp;
  17159. + u_int32_t i;
  17160. +#define AUTH_LEN(cri, def) \
  17161. + (cri->cri_mlen ? cri->cri_mlen : (def))
  17162. +
  17163. + dprintk("%s():alg %d\n", __FUNCTION__,cri->cri_alg);
  17164. + if (sid == NULL || cri == NULL) {
  17165. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  17166. + return EINVAL;
  17167. + }
  17168. +
  17169. + if (ixp_sessions) {
  17170. + for (i = 1; i < ixp_sesnum; i++)
  17171. + if (ixp_sessions[i] == NULL)
  17172. + break;
  17173. + } else
  17174. + i = 1; /* NB: to silence compiler warning */
  17175. +
  17176. + if (ixp_sessions == NULL || i == ixp_sesnum) {
  17177. + struct ixp_data **ixpd;
  17178. +
  17179. + if (ixp_sessions == NULL) {
  17180. + i = 1; /* We leave ixp_sessions[0] empty */
  17181. + ixp_sesnum = CRYPTO_SW_SESSIONS;
  17182. + } else
  17183. + ixp_sesnum *= 2;
  17184. +
  17185. + ixpd = kmalloc(ixp_sesnum * sizeof(struct ixp_data *), SLAB_ATOMIC);
  17186. + if (ixpd == NULL) {
  17187. + /* Reset session number */
  17188. + if (ixp_sesnum == CRYPTO_SW_SESSIONS)
  17189. + ixp_sesnum = 0;
  17190. + else
  17191. + ixp_sesnum /= 2;
  17192. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  17193. + return ENOBUFS;
  17194. + }
  17195. + memset(ixpd, 0, ixp_sesnum * sizeof(struct ixp_data *));
  17196. +
  17197. + /* Copy existing sessions */
  17198. + if (ixp_sessions) {
  17199. + memcpy(ixpd, ixp_sessions,
  17200. + (ixp_sesnum / 2) * sizeof(struct ixp_data *));
  17201. + kfree(ixp_sessions);
  17202. + }
  17203. +
  17204. + ixp_sessions = ixpd;
  17205. + }
  17206. +
  17207. + ixp_sessions[i] = (struct ixp_data *) kmalloc(sizeof(struct ixp_data),
  17208. + SLAB_ATOMIC);
  17209. + if (ixp_sessions[i] == NULL) {
  17210. + ixp_freesession(NULL, i);
  17211. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  17212. + return ENOBUFS;
  17213. + }
  17214. +
  17215. + *sid = i;
  17216. +
  17217. + ixp = ixp_sessions[i];
  17218. + memset(ixp, 0, sizeof(*ixp));
  17219. +
  17220. + ixp->ixp_cipher_alg = -1;
  17221. + ixp->ixp_auth_alg = -1;
  17222. + ixp->ixp_ctx_id = -1;
  17223. + INIT_LIST_HEAD(&ixp->ixp_q);
  17224. +
  17225. + ixp->ixp_ctx.useDifferentSrcAndDestMbufs = 0;
  17226. +
  17227. + while (cri) {
  17228. + switch (cri->cri_alg) {
  17229. + case CRYPTO_DES_CBC:
  17230. + ixp->ixp_cipher_alg = cri->cri_alg;
  17231. + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_DES;
  17232. + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  17233. + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
  17234. + ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
  17235. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =
  17236. + IX_CRYPTO_ACC_DES_IV_64;
  17237. + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
  17238. + cri->cri_key, (cri->cri_klen + 7) / 8);
  17239. + break;
  17240. +
  17241. + case CRYPTO_3DES_CBC:
  17242. + ixp->ixp_cipher_alg = cri->cri_alg;
  17243. + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
  17244. + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  17245. + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
  17246. + ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
  17247. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =
  17248. + IX_CRYPTO_ACC_DES_IV_64;
  17249. + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
  17250. + cri->cri_key, (cri->cri_klen + 7) / 8);
  17251. + break;
  17252. +
  17253. + case CRYPTO_RIJNDAEL128_CBC:
  17254. + ixp->ixp_cipher_alg = cri->cri_alg;
  17255. + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_AES;
  17256. + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  17257. + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
  17258. + ixp->ixp_ctx.cipherCtx.cipherBlockLen = 16;
  17259. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen = 16;
  17260. + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
  17261. + cri->cri_key, (cri->cri_klen + 7) / 8);
  17262. + break;
  17263. +
  17264. + case CRYPTO_MD5:
  17265. + case CRYPTO_MD5_HMAC:
  17266. + ixp->ixp_auth_alg = cri->cri_alg;
  17267. + ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_MD5;
  17268. + ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, MD5_HASH_LEN);
  17269. + ixp->ixp_ctx.authCtx.aadLen = 0;
  17270. + /* Only MD5_HMAC needs a key */
  17271. + if (cri->cri_alg == CRYPTO_MD5_HMAC) {
  17272. + ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;
  17273. + if (ixp->ixp_ctx.authCtx.authKeyLen >
  17274. + sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {
  17275. + printk(
  17276. + "ixp4xx: Invalid key length for MD5_HMAC - %d bits\n",
  17277. + cri->cri_klen);
  17278. + ixp_freesession(NULL, i);
  17279. + return EINVAL;
  17280. + }
  17281. + memcpy(ixp->ixp_ctx.authCtx.key.authKey,
  17282. + cri->cri_key, (cri->cri_klen + 7) / 8);
  17283. + }
  17284. + break;
  17285. +
  17286. + case CRYPTO_SHA1:
  17287. + case CRYPTO_SHA1_HMAC:
  17288. + ixp->ixp_auth_alg = cri->cri_alg;
  17289. + ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
  17290. + ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, SHA1_HASH_LEN);
  17291. + ixp->ixp_ctx.authCtx.aadLen = 0;
  17292. + /* Only SHA1_HMAC needs a key */
  17293. + if (cri->cri_alg == CRYPTO_SHA1_HMAC) {
  17294. + ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;
  17295. + if (ixp->ixp_ctx.authCtx.authKeyLen >
  17296. + sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {
  17297. + printk(
  17298. + "ixp4xx: Invalid key length for SHA1_HMAC - %d bits\n",
  17299. + cri->cri_klen);
  17300. + ixp_freesession(NULL, i);
  17301. + return EINVAL;
  17302. + }
  17303. + memcpy(ixp->ixp_ctx.authCtx.key.authKey,
  17304. + cri->cri_key, (cri->cri_klen + 7) / 8);
  17305. + }
  17306. + break;
  17307. +
  17308. + default:
  17309. + printk("ixp: unknown algo 0x%x\n", cri->cri_alg);
  17310. + ixp_freesession(NULL, i);
  17311. + return EINVAL;
  17312. + }
  17313. + cri = cri->cri_next;
  17314. + }
  17315. +
  17316. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  17317. + INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending_wq);
  17318. + INIT_WORK(&ixp->ixp_registration_work, ixp_registration_wq);
  17319. +#else
  17320. + INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending, ixp);
  17321. + INIT_WORK(&ixp->ixp_registration_work, ixp_registration, ixp);
  17322. +#endif
  17323. +
  17324. + return 0;
  17325. +}
  17326. +
  17327. +
  17328. +/*
  17329. + * Free a session.
  17330. + */
  17331. +static int
  17332. +ixp_freesession(device_t dev, u_int64_t tid)
  17333. +{
  17334. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  17335. +
  17336. + dprintk("%s()\n", __FUNCTION__);
  17337. + if (sid > ixp_sesnum || ixp_sessions == NULL ||
  17338. + ixp_sessions[sid] == NULL) {
  17339. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  17340. + return EINVAL;
  17341. + }
  17342. +
  17343. + /* Silently accept and return */
  17344. + if (sid == 0)
  17345. + return 0;
  17346. +
  17347. + if (ixp_sessions[sid]) {
  17348. + if (ixp_sessions[sid]->ixp_ctx_id != -1) {
  17349. + ixCryptoAccCtxUnregister(ixp_sessions[sid]->ixp_ctx_id);
  17350. + ixp_sessions[sid]->ixp_ctx_id = -1;
  17351. + }
  17352. + kfree(ixp_sessions[sid]);
  17353. + }
  17354. + ixp_sessions[sid] = NULL;
  17355. + if (ixp_blocked) {
  17356. + ixp_blocked = 0;
  17357. + crypto_unblock(ixp_id, CRYPTO_SYMQ);
  17358. + }
  17359. + return 0;
  17360. +}
  17361. +
  17362. +
  17363. +/*
  17364. + * callback for when hash processing is complete
  17365. + */
  17366. +
  17367. +static void
  17368. +ixp_hash_perform_cb(
  17369. + UINT32 hash_key_id,
  17370. + IX_MBUF *bufp,
  17371. + IxCryptoAccStatus status)
  17372. +{
  17373. + struct ixp_q *q;
  17374. +
  17375. + dprintk("%s(%u, %p, 0x%x)\n", __FUNCTION__, hash_key_id, bufp, status);
  17376. +
  17377. + if (bufp == NULL) {
  17378. + printk("ixp: NULL buf in %s\n", __FUNCTION__);
  17379. + return;
  17380. + }
  17381. +
  17382. + q = IX_MBUF_PRIV(bufp);
  17383. + if (q == NULL) {
  17384. + printk("ixp: NULL priv in %s\n", __FUNCTION__);
  17385. + return;
  17386. + }
  17387. +
  17388. + if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
  17389. + /* On success, need to copy hash back into original client buffer */
  17390. + memcpy(q->ixp_hash_dest, q->ixp_hash_src,
  17391. + (q->ixp_q_data->ixp_auth_alg == CRYPTO_SHA1) ?
  17392. + SHA1_HASH_LEN : MD5_HASH_LEN);
  17393. + }
  17394. + else {
  17395. + printk("ixp: hash perform failed status=%d\n", status);
  17396. + q->ixp_q_crp->crp_etype = EINVAL;
  17397. + }
  17398. +
  17399. + /* Free internal buffer used for hashing */
  17400. + kfree(IX_MBUF_MDATA(&q->ixp_q_mbuf));
  17401. +
  17402. + crypto_done(q->ixp_q_crp);
  17403. + kmem_cache_free(qcache, q);
  17404. +}
  17405. +
  17406. +/*
  17407. + * setup a request and perform it
  17408. + */
  17409. +static void
  17410. +ixp_q_process(struct ixp_q *q)
  17411. +{
  17412. + IxCryptoAccStatus status;
  17413. + struct ixp_data *ixp = q->ixp_q_data;
  17414. + int auth_off = 0;
  17415. + int auth_len = 0;
  17416. + int crypt_off = 0;
  17417. + int crypt_len = 0;
  17418. + int icv_off = 0;
  17419. + char *crypt_func;
  17420. +
  17421. + dprintk("%s(%p)\n", __FUNCTION__, q);
  17422. +
  17423. + if (q->ixp_q_ccrd) {
  17424. + if (q->ixp_q_ccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  17425. + q->ixp_q_iv = q->ixp_q_ccrd->crd_iv;
  17426. + } else {
  17427. + q->ixp_q_iv = q->ixp_q_iv_data;
  17428. + crypto_copydata(q->ixp_q_crp->crp_flags, q->ixp_q_crp->crp_buf,
  17429. + q->ixp_q_ccrd->crd_inject,
  17430. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen,
  17431. + (caddr_t) q->ixp_q_iv);
  17432. + }
  17433. +
  17434. + if (q->ixp_q_acrd) {
  17435. + auth_off = q->ixp_q_acrd->crd_skip;
  17436. + auth_len = q->ixp_q_acrd->crd_len;
  17437. + icv_off = q->ixp_q_acrd->crd_inject;
  17438. + }
  17439. +
  17440. + crypt_off = q->ixp_q_ccrd->crd_skip;
  17441. + crypt_len = q->ixp_q_ccrd->crd_len;
  17442. + } else { /* if (q->ixp_q_acrd) */
  17443. + auth_off = q->ixp_q_acrd->crd_skip;
  17444. + auth_len = q->ixp_q_acrd->crd_len;
  17445. + icv_off = q->ixp_q_acrd->crd_inject;
  17446. + }
  17447. +
  17448. + if (q->ixp_q_crp->crp_flags & CRYPTO_F_SKBUF) {
  17449. + struct sk_buff *skb = (struct sk_buff *) q->ixp_q_crp->crp_buf;
  17450. + if (skb_shinfo(skb)->nr_frags) {
  17451. + /*
  17452. + * DAVIDM fix this limitation one day by using
  17453. + * a buffer pool and chaining, it is not currently
  17454. + * needed for current user/kernel space acceleration
  17455. + */
  17456. + printk("ixp: Cannot handle fragmented skb's yet !\n");
  17457. + q->ixp_q_crp->crp_etype = ENOENT;
  17458. + goto done;
  17459. + }
  17460. + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
  17461. + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = skb->len;
  17462. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = skb->data;
  17463. + } else if (q->ixp_q_crp->crp_flags & CRYPTO_F_IOV) {
  17464. + struct uio *uiop = (struct uio *) q->ixp_q_crp->crp_buf;
  17465. + if (uiop->uio_iovcnt != 1) {
  17466. + /*
  17467. + * DAVIDM fix this limitation one day by using
  17468. + * a buffer pool and chaining, it is not currently
  17469. + * needed for current user/kernel space acceleration
  17470. + */
  17471. + printk("ixp: Cannot handle more than 1 iovec yet !\n");
  17472. + q->ixp_q_crp->crp_etype = ENOENT;
  17473. + goto done;
  17474. + }
  17475. + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
  17476. + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_len;
  17477. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_base;
  17478. + } else /* contig buffer */ {
  17479. + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
  17480. + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_ilen;
  17481. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_buf;
  17482. + }
  17483. +
  17484. + IX_MBUF_PRIV(&q->ixp_q_mbuf) = q;
  17485. +
  17486. + if (ixp->ixp_auth_alg == CRYPTO_SHA1 || ixp->ixp_auth_alg == CRYPTO_MD5) {
  17487. + /*
  17488. + * For SHA1 and MD5 hash, need to create an internal buffer that is big
  17489. + * enough to hold the original data + the appropriate padding for the
  17490. + * hash algorithm.
  17491. + */
  17492. + UINT8 *tbuf = NULL;
  17493. +
  17494. + IX_MBUF_MLEN(&q->ixp_q_mbuf) = IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) =
  17495. + ((IX_MBUF_MLEN(&q->ixp_q_mbuf) * 8) + 72 + 511) / 8;
  17496. + tbuf = kmalloc(IX_MBUF_MLEN(&q->ixp_q_mbuf), SLAB_ATOMIC);
  17497. +
  17498. + if (IX_MBUF_MDATA(&q->ixp_q_mbuf) == NULL) {
  17499. + printk("ixp: kmalloc(%u, SLAB_ATOMIC) failed\n",
  17500. + IX_MBUF_MLEN(&q->ixp_q_mbuf));
  17501. + q->ixp_q_crp->crp_etype = ENOMEM;
  17502. + goto done;
  17503. + }
  17504. + memcpy(tbuf, &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off], auth_len);
  17505. +
  17506. + /* Set location in client buffer to copy hash into */
  17507. + q->ixp_hash_dest =
  17508. + &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off + auth_len];
  17509. +
  17510. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = tbuf;
  17511. +
  17512. + /* Set location in internal buffer for where hash starts */
  17513. + q->ixp_hash_src = &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_len];
  17514. +
  17515. + crypt_func = "ixCryptoAccHashPerform";
  17516. + status = ixCryptoAccHashPerform(ixp->ixp_ctx.authCtx.authAlgo,
  17517. + &q->ixp_q_mbuf, ixp_hash_perform_cb, 0, auth_len, auth_len,
  17518. + &ixp->ixp_hash_key_id);
  17519. + }
  17520. + else {
  17521. + crypt_func = "ixCryptoAccAuthCryptPerform";
  17522. + status = ixCryptoAccAuthCryptPerform(ixp->ixp_ctx_id, &q->ixp_q_mbuf,
  17523. + NULL, auth_off, auth_len, crypt_off, crypt_len, icv_off,
  17524. + q->ixp_q_iv);
  17525. + }
  17526. +
  17527. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  17528. + return;
  17529. +
  17530. + if (IX_CRYPTO_ACC_STATUS_QUEUE_FULL == status) {
  17531. + q->ixp_q_crp->crp_etype = ENOMEM;
  17532. + goto done;
  17533. + }
  17534. +
  17535. + printk("ixp: %s failed %u\n", crypt_func, status);
  17536. + q->ixp_q_crp->crp_etype = EINVAL;
  17537. +
  17538. +done:
  17539. + crypto_done(q->ixp_q_crp);
  17540. + kmem_cache_free(qcache, q);
  17541. +}
  17542. +
  17543. +
  17544. +/*
  17545. + * because we cannot process the Q from the Register callback
  17546. + * we do it here on a task Q.
  17547. + */
  17548. +
  17549. +static void
  17550. +ixp_process_pending(void *arg)
  17551. +{
  17552. + struct ixp_data *ixp = arg;
  17553. + struct ixp_q *q = NULL;
  17554. +
  17555. + dprintk("%s(%p)\n", __FUNCTION__, arg);
  17556. +
  17557. + if (!ixp)
  17558. + return;
  17559. +
  17560. + while (!list_empty(&ixp->ixp_q)) {
  17561. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  17562. + list_del(&q->ixp_q_list);
  17563. + ixp_q_process(q);
  17564. + }
  17565. +}
  17566. +
  17567. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  17568. +static void
  17569. +ixp_process_pending_wq(struct work_struct *work)
  17570. +{
  17571. + struct ixp_data *ixp = container_of(work, struct ixp_data, ixp_pending_work);
  17572. + ixp_process_pending(ixp);
  17573. +}
  17574. +#endif
  17575. +
  17576. +/*
  17577. + * callback for when context registration is complete
  17578. + */
  17579. +
  17580. +static void
  17581. +ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
  17582. +{
  17583. + int i;
  17584. + struct ixp_data *ixp;
  17585. + struct ixp_q *q;
  17586. +
  17587. + dprintk("%s(%d, %p, %d)\n", __FUNCTION__, ctx_id, bufp, status);
  17588. +
  17589. + /*
  17590. + * free any buffer passed in to this routine
  17591. + */
  17592. + if (bufp) {
  17593. + IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
  17594. + kfree(IX_MBUF_MDATA(bufp));
  17595. + IX_MBUF_MDATA(bufp) = NULL;
  17596. + }
  17597. +
  17598. + for (i = 0; i < ixp_sesnum; i++) {
  17599. + ixp = ixp_sessions[i];
  17600. + if (ixp && ixp->ixp_ctx_id == ctx_id)
  17601. + break;
  17602. + }
  17603. + if (i >= ixp_sesnum) {
  17604. + printk("ixp: invalid context id %d\n", ctx_id);
  17605. + return;
  17606. + }
  17607. +
  17608. + if (IX_CRYPTO_ACC_STATUS_WAIT == status) {
  17609. + /* this is normal to free the first of two buffers */
  17610. + dprintk("ixp: register not finished yet.\n");
  17611. + return;
  17612. + }
  17613. +
  17614. + if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
  17615. + printk("ixp: register failed 0x%x\n", status);
  17616. + while (!list_empty(&ixp->ixp_q)) {
  17617. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  17618. + list_del(&q->ixp_q_list);
  17619. + q->ixp_q_crp->crp_etype = EINVAL;
  17620. + crypto_done(q->ixp_q_crp);
  17621. + kmem_cache_free(qcache, q);
  17622. + }
  17623. + return;
  17624. + }
  17625. +
  17626. + /*
  17627. + * we are now registered, we cannot start processing the Q here
  17628. + * or we get strange errors with AES (DES/3DES seem to be ok).
  17629. + */
  17630. + ixp->ixp_registered = 1;
  17631. + schedule_work(&ixp->ixp_pending_work);
  17632. +}
  17633. +
  17634. +
  17635. +/*
  17636. + * callback for when data processing is complete
  17637. + */
  17638. +
  17639. +static void
  17640. +ixp_perform_cb(
  17641. + UINT32 ctx_id,
  17642. + IX_MBUF *sbufp,
  17643. + IX_MBUF *dbufp,
  17644. + IxCryptoAccStatus status)
  17645. +{
  17646. + struct ixp_q *q;
  17647. +
  17648. + dprintk("%s(%d, %p, %p, 0x%x)\n", __FUNCTION__, ctx_id, sbufp,
  17649. + dbufp, status);
  17650. +
  17651. + if (sbufp == NULL) {
  17652. + printk("ixp: NULL sbuf in ixp_perform_cb\n");
  17653. + return;
  17654. + }
  17655. +
  17656. + q = IX_MBUF_PRIV(sbufp);
  17657. + if (q == NULL) {
  17658. + printk("ixp: NULL priv in ixp_perform_cb\n");
  17659. + return;
  17660. + }
  17661. +
  17662. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  17663. + printk("ixp: perform failed status=%d\n", status);
  17664. + q->ixp_q_crp->crp_etype = EINVAL;
  17665. + }
  17666. +
  17667. + crypto_done(q->ixp_q_crp);
  17668. + kmem_cache_free(qcache, q);
  17669. +}
  17670. +
  17671. +
  17672. +/*
  17673. + * registration is not callable at IRQ time, so we defer
  17674. + * to a task queue, this routines completes the registration for us
  17675. + * when the task queue runs
  17676. + *
  17677. + * Unfortunately this means we cannot tell OCF that the driver is blocked,
  17678. + * we do that on the next request.
  17679. + */
  17680. +
  17681. +static void
  17682. +ixp_registration(void *arg)
  17683. +{
  17684. + struct ixp_data *ixp = arg;
  17685. + struct ixp_q *q = NULL;
  17686. + IX_MBUF *pri = NULL, *sec = NULL;
  17687. + int status = IX_CRYPTO_ACC_STATUS_SUCCESS;
  17688. +
  17689. + if (!ixp) {
  17690. + printk("ixp: ixp_registration with no arg\n");
  17691. + return;
  17692. + }
  17693. +
  17694. + if (ixp->ixp_ctx_id != -1) {
  17695. + ixCryptoAccCtxUnregister(ixp->ixp_ctx_id);
  17696. + ixp->ixp_ctx_id = -1;
  17697. + }
  17698. +
  17699. + if (list_empty(&ixp->ixp_q)) {
  17700. + printk("ixp: ixp_registration with no Q\n");
  17701. + return;
  17702. + }
  17703. +
  17704. + /*
  17705. + * setup the primary and secondary buffers
  17706. + */
  17707. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  17708. + if (q->ixp_q_acrd) {
  17709. + pri = &ixp->ixp_pri_mbuf;
  17710. + sec = &ixp->ixp_sec_mbuf;
  17711. + IX_MBUF_MLEN(pri) = IX_MBUF_PKT_LEN(pri) = 128;
  17712. + IX_MBUF_MDATA(pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  17713. + IX_MBUF_MLEN(sec) = IX_MBUF_PKT_LEN(sec) = 128;
  17714. + IX_MBUF_MDATA(sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  17715. + }
  17716. +
  17717. + /* Only need to register if a crypt op or HMAC op */
  17718. + if (!(ixp->ixp_auth_alg == CRYPTO_SHA1 ||
  17719. + ixp->ixp_auth_alg == CRYPTO_MD5)) {
  17720. + status = ixCryptoAccCtxRegister(
  17721. + &ixp->ixp_ctx,
  17722. + pri, sec,
  17723. + ixp_register_cb,
  17724. + ixp_perform_cb,
  17725. + &ixp->ixp_ctx_id);
  17726. + }
  17727. + else {
  17728. + /* Otherwise we start processing pending q */
  17729. + schedule_work(&ixp->ixp_pending_work);
  17730. + }
  17731. +
  17732. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  17733. + return;
  17734. +
  17735. + if (IX_CRYPTO_ACC_STATUS_EXCEED_MAX_TUNNELS == status) {
  17736. + printk("ixp: ixCryptoAccCtxRegister failed (out of tunnels)\n");
  17737. + ixp_blocked = 1;
  17738. + /* perhaps we should return EGAIN on queued ops ? */
  17739. + return;
  17740. + }
  17741. +
  17742. + printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
  17743. + ixp->ixp_ctx_id = -1;
  17744. +
  17745. + /*
  17746. + * everything waiting is toasted
  17747. + */
  17748. + while (!list_empty(&ixp->ixp_q)) {
  17749. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  17750. + list_del(&q->ixp_q_list);
  17751. + q->ixp_q_crp->crp_etype = ENOENT;
  17752. + crypto_done(q->ixp_q_crp);
  17753. + kmem_cache_free(qcache, q);
  17754. + }
  17755. +}
  17756. +
  17757. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  17758. +static void
  17759. +ixp_registration_wq(struct work_struct *work)
  17760. +{
  17761. + struct ixp_data *ixp = container_of(work, struct ixp_data,
  17762. + ixp_registration_work);
  17763. + ixp_registration(ixp);
  17764. +}
  17765. +#endif
  17766. +
  17767. +/*
  17768. + * Process a request.
  17769. + */
  17770. +static int
  17771. +ixp_process(device_t dev, struct cryptop *crp, int hint)
  17772. +{
  17773. + struct ixp_data *ixp;
  17774. + unsigned int lid;
  17775. + struct ixp_q *q = NULL;
  17776. + int status;
  17777. +
  17778. + dprintk("%s()\n", __FUNCTION__);
  17779. +
  17780. + /* Sanity check */
  17781. + if (crp == NULL) {
  17782. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  17783. + return EINVAL;
  17784. + }
  17785. +
  17786. + crp->crp_etype = 0;
  17787. +
  17788. + if (ixp_blocked)
  17789. + return ERESTART;
  17790. +
  17791. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  17792. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  17793. + crp->crp_etype = EINVAL;
  17794. + goto done;
  17795. + }
  17796. +
  17797. + /*
  17798. + * find the session we are using
  17799. + */
  17800. +
  17801. + lid = crp->crp_sid & 0xffffffff;
  17802. + if (lid >= ixp_sesnum || lid == 0 || ixp_sessions == NULL ||
  17803. + ixp_sessions[lid] == NULL) {
  17804. + crp->crp_etype = ENOENT;
  17805. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  17806. + goto done;
  17807. + }
  17808. + ixp = ixp_sessions[lid];
  17809. +
  17810. + /*
  17811. + * setup a new request ready for queuing
  17812. + */
  17813. + q = kmem_cache_alloc(qcache, SLAB_ATOMIC);
  17814. + if (q == NULL) {
  17815. + dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);
  17816. + crp->crp_etype = ENOMEM;
  17817. + goto done;
  17818. + }
  17819. + /*
  17820. + * save some cycles by only zeroing the important bits
  17821. + */
  17822. + memset(&q->ixp_q_mbuf, 0, sizeof(q->ixp_q_mbuf));
  17823. + q->ixp_q_ccrd = NULL;
  17824. + q->ixp_q_acrd = NULL;
  17825. + q->ixp_q_crp = crp;
  17826. + q->ixp_q_data = ixp;
  17827. +
  17828. + /*
  17829. + * point the cipher and auth descriptors appropriately
  17830. + * check that we have something to do
  17831. + */
  17832. + if (crp->crp_desc->crd_alg == ixp->ixp_cipher_alg)
  17833. + q->ixp_q_ccrd = crp->crp_desc;
  17834. + else if (crp->crp_desc->crd_alg == ixp->ixp_auth_alg)
  17835. + q->ixp_q_acrd = crp->crp_desc;
  17836. + else {
  17837. + crp->crp_etype = ENOENT;
  17838. + dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);
  17839. + goto done;
  17840. + }
  17841. + if (crp->crp_desc->crd_next) {
  17842. + if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_cipher_alg)
  17843. + q->ixp_q_ccrd = crp->crp_desc->crd_next;
  17844. + else if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_auth_alg)
  17845. + q->ixp_q_acrd = crp->crp_desc->crd_next;
  17846. + else {
  17847. + crp->crp_etype = ENOENT;
  17848. + dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);
  17849. + goto done;
  17850. + }
  17851. + }
  17852. +
  17853. + /*
  17854. + * If there is a direction change for this context then we mark it as
  17855. + * unregistered and re-register is for the new direction. This is not
  17856. + * a very expensive operation and currently only tends to happen when
  17857. + * user-space application are doing benchmarks
  17858. + *
  17859. + * DM - we should be checking for pending requests before unregistering.
  17860. + */
  17861. + if (q->ixp_q_ccrd && ixp->ixp_registered &&
  17862. + ixp->ixp_crd_flags != (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT)) {
  17863. + dprintk("%s - detected direction change on session\n", __FUNCTION__);
  17864. + ixp->ixp_registered = 0;
  17865. + }
  17866. +
  17867. + /*
  17868. + * if we are registered, call straight into the perform code
  17869. + */
  17870. + if (ixp->ixp_registered) {
  17871. + ixp_q_process(q);
  17872. + return 0;
  17873. + }
  17874. +
  17875. + /*
  17876. + * the only part of the context not set in newsession is the direction
  17877. + * dependent parts
  17878. + */
  17879. + if (q->ixp_q_ccrd) {
  17880. + ixp->ixp_crd_flags = (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT);
  17881. + if (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT) {
  17882. + ixp->ixp_ctx.operation = q->ixp_q_acrd ?
  17883. + IX_CRYPTO_ACC_OP_ENCRYPT_AUTH : IX_CRYPTO_ACC_OP_ENCRYPT;
  17884. + } else {
  17885. + ixp->ixp_ctx.operation = q->ixp_q_acrd ?
  17886. + IX_CRYPTO_ACC_OP_AUTH_DECRYPT : IX_CRYPTO_ACC_OP_DECRYPT;
  17887. + }
  17888. + } else {
  17889. + /* q->ixp_q_acrd must be set if we are here */
  17890. + ixp->ixp_ctx.operation = IX_CRYPTO_ACC_OP_AUTH_CALC;
  17891. + }
  17892. +
  17893. + status = list_empty(&ixp->ixp_q);
  17894. + list_add_tail(&q->ixp_q_list, &ixp->ixp_q);
  17895. + if (status)
  17896. + schedule_work(&ixp->ixp_registration_work);
  17897. + return 0;
  17898. +
  17899. +done:
  17900. + if (q)
  17901. + kmem_cache_free(qcache, q);
  17902. + crypto_done(crp);
  17903. + return 0;
  17904. +}
  17905. +
  17906. +
  17907. +#ifdef __ixp46X
  17908. +/*
  17909. + * key processing support for the ixp465
  17910. + */
  17911. +
  17912. +
  17913. +/*
  17914. + * copy a BN (LE) into a buffer (BE) an fill out the op appropriately
  17915. + * assume zeroed and only copy bits that are significant
  17916. + */
  17917. +
  17918. +static int
  17919. +ixp_copy_ibuf(struct crparam *p, IxCryptoAccPkeEauOperand *op, UINT32 *buf)
  17920. +{
  17921. + unsigned char *src = (unsigned char *) p->crp_p;
  17922. + unsigned char *dst;
  17923. + int len, bits = p->crp_nbits;
  17924. +
  17925. + dprintk("%s()\n", __FUNCTION__);
  17926. +
  17927. + if (bits > MAX_IOP_SIZE * sizeof(UINT32) * 8) {
  17928. + dprintk("%s - ibuf too big (%d > %d)\n", __FUNCTION__,
  17929. + bits, MAX_IOP_SIZE * sizeof(UINT32) * 8);
  17930. + return -1;
  17931. + }
  17932. +
  17933. + len = (bits + 31) / 32; /* the number UINT32's needed */
  17934. +
  17935. + dst = (unsigned char *) &buf[len];
  17936. + dst--;
  17937. +
  17938. + while (bits > 0) {
  17939. + *dst-- = *src++;
  17940. + bits -= 8;
  17941. + }
  17942. +
  17943. +#if 0 /* no need to zero remaining bits as it is done during request alloc */
  17944. + while (dst > (unsigned char *) buf)
  17945. + *dst-- = '\0';
  17946. +#endif
  17947. +
  17948. + op->pData = buf;
  17949. + op->dataLen = len;
  17950. + return 0;
  17951. +}
  17952. +
  17953. +/*
  17954. + * copy out the result, be as forgiving as we can about small output buffers
  17955. + */
  17956. +
  17957. +static int
  17958. +ixp_copy_obuf(struct crparam *p, IxCryptoAccPkeEauOpResult *op, UINT32 *buf)
  17959. +{
  17960. + unsigned char *dst = (unsigned char *) p->crp_p;
  17961. + unsigned char *src = (unsigned char *) buf;
  17962. + int len, z, bits = p->crp_nbits;
  17963. +
  17964. + dprintk("%s()\n", __FUNCTION__);
  17965. +
  17966. + len = op->dataLen * sizeof(UINT32);
  17967. +
  17968. + /* skip leading zeroes to be small buffer friendly */
  17969. + z = 0;
  17970. + while (z < len && src[z] == '\0')
  17971. + z++;
  17972. +
  17973. + src += len;
  17974. + src--;
  17975. + len -= z;
  17976. +
  17977. + while (len > 0 && bits > 0) {
  17978. + *dst++ = *src--;
  17979. + len--;
  17980. + bits -= 8;
  17981. + }
  17982. +
  17983. + while (bits > 0) {
  17984. + *dst++ = '\0';
  17985. + bits -= 8;
  17986. + }
  17987. +
  17988. + if (len > 0) {
  17989. + dprintk("%s - obuf is %d (z=%d, ob=%d) bytes too small\n",
  17990. + __FUNCTION__, len, z, p->crp_nbits / 8);
  17991. + return -1;
  17992. + }
  17993. +
  17994. + return 0;
  17995. +}
  17996. +
  17997. +
  17998. +/*
  17999. + * the parameter offsets for exp_mod
  18000. + */
  18001. +
  18002. +#define IXP_PARAM_BASE 0
  18003. +#define IXP_PARAM_EXP 1
  18004. +#define IXP_PARAM_MOD 2
  18005. +#define IXP_PARAM_RES 3
  18006. +
  18007. +/*
  18008. + * key processing complete callback, is also used to start processing
  18009. + * by passing a NULL for pResult
  18010. + */
  18011. +
  18012. +static void
  18013. +ixp_kperform_cb(
  18014. + IxCryptoAccPkeEauOperation operation,
  18015. + IxCryptoAccPkeEauOpResult *pResult,
  18016. + BOOL carryOrBorrow,
  18017. + IxCryptoAccStatus status)
  18018. +{
  18019. + struct ixp_pkq *q, *tmp;
  18020. + unsigned long flags;
  18021. +
  18022. + dprintk("%s(0x%x, %p, %d, 0x%x)\n", __FUNCTION__, operation, pResult,
  18023. + carryOrBorrow, status);
  18024. +
  18025. + /* handle a completed request */
  18026. + if (pResult) {
  18027. + if (ixp_pk_cur && &ixp_pk_cur->pkq_result == pResult) {
  18028. + q = ixp_pk_cur;
  18029. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  18030. + dprintk("%s() - op failed 0x%x\n", __FUNCTION__, status);
  18031. + q->pkq_krp->krp_status = ERANGE; /* could do better */
  18032. + } else {
  18033. + /* copy out the result */
  18034. + if (ixp_copy_obuf(&q->pkq_krp->krp_param[IXP_PARAM_RES],
  18035. + &q->pkq_result, q->pkq_obuf))
  18036. + q->pkq_krp->krp_status = ERANGE;
  18037. + }
  18038. + crypto_kdone(q->pkq_krp);
  18039. + kfree(q);
  18040. + ixp_pk_cur = NULL;
  18041. + } else
  18042. + printk("%s - callback with invalid result pointer\n", __FUNCTION__);
  18043. + }
  18044. +
  18045. + spin_lock_irqsave(&ixp_pkq_lock, flags);
  18046. + if (ixp_pk_cur || list_empty(&ixp_pkq)) {
  18047. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  18048. + return;
  18049. + }
  18050. +
  18051. + list_for_each_entry_safe(q, tmp, &ixp_pkq, pkq_list) {
  18052. +
  18053. + list_del(&q->pkq_list);
  18054. + ixp_pk_cur = q;
  18055. +
  18056. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  18057. +
  18058. + status = ixCryptoAccPkeEauPerform(
  18059. + IX_CRYPTO_ACC_OP_EAU_MOD_EXP,
  18060. + &q->pkq_op,
  18061. + ixp_kperform_cb,
  18062. + &q->pkq_result);
  18063. +
  18064. + if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
  18065. + dprintk("%s() - ixCryptoAccPkeEauPerform SUCCESS\n", __FUNCTION__);
  18066. + return; /* callback will return here for callback */
  18067. + } else if (status == IX_CRYPTO_ACC_STATUS_RETRY) {
  18068. + printk("%s() - ixCryptoAccPkeEauPerform RETRY\n", __FUNCTION__);
  18069. + } else {
  18070. + printk("%s() - ixCryptoAccPkeEauPerform failed %d\n",
  18071. + __FUNCTION__, status);
  18072. + }
  18073. + q->pkq_krp->krp_status = ERANGE; /* could do better */
  18074. + crypto_kdone(q->pkq_krp);
  18075. + kfree(q);
  18076. + spin_lock_irqsave(&ixp_pkq_lock, flags);
  18077. + }
  18078. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  18079. +}
  18080. +
  18081. +
  18082. +static int
  18083. +ixp_kprocess(device_t dev, struct cryptkop *krp, int hint)
  18084. +{
  18085. + struct ixp_pkq *q;
  18086. + int rc = 0;
  18087. + unsigned long flags;
  18088. +
  18089. + dprintk("%s l1=%d l2=%d l3=%d l4=%d\n", __FUNCTION__,
  18090. + krp->krp_param[IXP_PARAM_BASE].crp_nbits,
  18091. + krp->krp_param[IXP_PARAM_EXP].crp_nbits,
  18092. + krp->krp_param[IXP_PARAM_MOD].crp_nbits,
  18093. + krp->krp_param[IXP_PARAM_RES].crp_nbits);
  18094. +
  18095. +
  18096. + if (krp->krp_op != CRK_MOD_EXP) {
  18097. + krp->krp_status = EOPNOTSUPP;
  18098. + goto err;
  18099. + }
  18100. +
  18101. + q = (struct ixp_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);
  18102. + if (q == NULL) {
  18103. + krp->krp_status = ENOMEM;
  18104. + goto err;
  18105. + }
  18106. +
  18107. + /*
  18108. + * The PKE engine does not appear to zero the output buffer
  18109. + * appropriately, so we need to do it all here.
  18110. + */
  18111. + memset(q, 0, sizeof(*q));
  18112. +
  18113. + q->pkq_krp = krp;
  18114. + INIT_LIST_HEAD(&q->pkq_list);
  18115. +
  18116. + if (ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_BASE], &q->pkq_op.modExpOpr.M,
  18117. + q->pkq_ibuf0))
  18118. + rc = 1;
  18119. + if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_EXP],
  18120. + &q->pkq_op.modExpOpr.e, q->pkq_ibuf1))
  18121. + rc = 2;
  18122. + if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_MOD],
  18123. + &q->pkq_op.modExpOpr.N, q->pkq_ibuf2))
  18124. + rc = 3;
  18125. +
  18126. + if (rc) {
  18127. + kfree(q);
  18128. + krp->krp_status = ERANGE;
  18129. + goto err;
  18130. + }
  18131. +
  18132. + q->pkq_result.pData = q->pkq_obuf;
  18133. + q->pkq_result.dataLen =
  18134. + (krp->krp_param[IXP_PARAM_RES].crp_nbits + 31) / 32;
  18135. +
  18136. + spin_lock_irqsave(&ixp_pkq_lock, flags);
  18137. + list_add_tail(&q->pkq_list, &ixp_pkq);
  18138. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  18139. +
  18140. + if (!ixp_pk_cur)
  18141. + ixp_kperform_cb(0, NULL, 0, 0);
  18142. + return (0);
  18143. +
  18144. +err:
  18145. + crypto_kdone(krp);
  18146. + return (0);
  18147. +}
  18148. +
  18149. +
  18150. +
  18151. +#ifdef CONFIG_OCF_RANDOMHARVEST
  18152. +/*
  18153. + * We run the random number generator output through SHA so that it
  18154. + * is FIPS compliant.
  18155. + */
  18156. +
  18157. +static volatile int sha_done = 0;
  18158. +static unsigned char sha_digest[20];
  18159. +
  18160. +static void
  18161. +ixp_hash_cb(UINT8 *digest, IxCryptoAccStatus status)
  18162. +{
  18163. + dprintk("%s(%p, %d)\n", __FUNCTION__, digest, status);
  18164. + if (sha_digest != digest)
  18165. + printk("digest error\n");
  18166. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  18167. + sha_done = 1;
  18168. + else
  18169. + sha_done = -status;
  18170. +}
  18171. +
  18172. +static int
  18173. +ixp_read_random(void *arg, u_int32_t *buf, int maxwords)
  18174. +{
  18175. + IxCryptoAccStatus status;
  18176. + int i, n, rc;
  18177. +
  18178. + dprintk("%s(%p, %d)\n", __FUNCTION__, buf, maxwords);
  18179. + memset(buf, 0, maxwords * sizeof(*buf));
  18180. + status = ixCryptoAccPkePseudoRandomNumberGet(maxwords, buf);
  18181. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  18182. + dprintk("%s: ixCryptoAccPkePseudoRandomNumberGet failed %d\n",
  18183. + __FUNCTION__, status);
  18184. + return 0;
  18185. + }
  18186. +
  18187. + /*
  18188. + * run the random data through SHA to make it look more random
  18189. + */
  18190. +
  18191. + n = sizeof(sha_digest); /* process digest bytes at a time */
  18192. +
  18193. + rc = 0;
  18194. + for (i = 0; i < maxwords; i += n / sizeof(*buf)) {
  18195. + if ((maxwords - i) * sizeof(*buf) < n)
  18196. + n = (maxwords - i) * sizeof(*buf);
  18197. + sha_done = 0;
  18198. + status = ixCryptoAccPkeHashPerform(IX_CRYPTO_ACC_AUTH_SHA1,
  18199. + (UINT8 *) &buf[i], n, ixp_hash_cb, sha_digest);
  18200. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  18201. + dprintk("ixCryptoAccPkeHashPerform failed %d\n", status);
  18202. + return -EIO;
  18203. + }
  18204. + while (!sha_done)
  18205. + schedule();
  18206. + if (sha_done < 0) {
  18207. + dprintk("ixCryptoAccPkeHashPerform failed CB %d\n", -sha_done);
  18208. + return 0;
  18209. + }
  18210. + memcpy(&buf[i], sha_digest, n);
  18211. + rc += n / sizeof(*buf);;
  18212. + }
  18213. +
  18214. + return rc;
  18215. +}
  18216. +#endif /* CONFIG_OCF_RANDOMHARVEST */
  18217. +
  18218. +#endif /* __ixp46X */
  18219. +
  18220. +
  18221. +
  18222. +/*
  18223. + * our driver startup and shutdown routines
  18224. + */
  18225. +
  18226. +static int
  18227. +ixp_init(void)
  18228. +{
  18229. + dprintk("%s(%p)\n", __FUNCTION__, ixp_init);
  18230. +
  18231. + if (ixp_init_crypto && ixCryptoAccInit() != IX_CRYPTO_ACC_STATUS_SUCCESS)
  18232. + printk("ixCryptoAccInit failed, assuming already initialised!\n");
  18233. +
  18234. + qcache = kmem_cache_create("ixp4xx_q", sizeof(struct ixp_q), 0,
  18235. + SLAB_HWCACHE_ALIGN, NULL
  18236. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  18237. + , NULL
  18238. +#endif
  18239. + );
  18240. + if (!qcache) {
  18241. + printk("failed to create Qcache\n");
  18242. + return -ENOENT;
  18243. + }
  18244. +
  18245. + memset(&ixpdev, 0, sizeof(ixpdev));
  18246. + softc_device_init(&ixpdev, "ixp4xx", 0, ixp_methods);
  18247. +
  18248. + ixp_id = crypto_get_driverid(softc_get_device(&ixpdev),
  18249. + CRYPTOCAP_F_HARDWARE);
  18250. + if (ixp_id < 0)
  18251. + panic("IXP/OCF crypto device cannot initialize!");
  18252. +
  18253. +#define REGISTER(alg) \
  18254. + crypto_register(ixp_id,alg,0,0)
  18255. +
  18256. + REGISTER(CRYPTO_DES_CBC);
  18257. + REGISTER(CRYPTO_3DES_CBC);
  18258. + REGISTER(CRYPTO_RIJNDAEL128_CBC);
  18259. +#ifdef CONFIG_OCF_IXP4XX_SHA1_MD5
  18260. + REGISTER(CRYPTO_MD5);
  18261. + REGISTER(CRYPTO_SHA1);
  18262. +#endif
  18263. + REGISTER(CRYPTO_MD5_HMAC);
  18264. + REGISTER(CRYPTO_SHA1_HMAC);
  18265. +#undef REGISTER
  18266. +
  18267. +#ifdef __ixp46X
  18268. + spin_lock_init(&ixp_pkq_lock);
  18269. + /*
  18270. + * we do not enable the go fast options here as they can potentially
  18271. + * allow timing based attacks
  18272. + *
  18273. + * http://www.openssl.org/news/secadv_20030219.txt
  18274. + */
  18275. + ixCryptoAccPkeEauExpConfig(0, 0);
  18276. + crypto_kregister(ixp_id, CRK_MOD_EXP, 0);
  18277. +#ifdef CONFIG_OCF_RANDOMHARVEST
  18278. + crypto_rregister(ixp_id, ixp_read_random, NULL);
  18279. +#endif
  18280. +#endif
  18281. +
  18282. + return 0;
  18283. +}
  18284. +
  18285. +static void
  18286. +ixp_exit(void)
  18287. +{
  18288. + dprintk("%s()\n", __FUNCTION__);
  18289. + crypto_unregister_all(ixp_id);
  18290. + ixp_id = -1;
  18291. + kmem_cache_destroy(qcache);
  18292. + qcache = NULL;
  18293. +}
  18294. +
  18295. +module_init(ixp_init);
  18296. +module_exit(ixp_exit);
  18297. +
  18298. +MODULE_LICENSE("Dual BSD/GPL");
  18299. +MODULE_AUTHOR("David McCullough <dmccullough@cyberguard.com>");
  18300. +MODULE_DESCRIPTION("ixp (OCF module for IXP4xx crypto)");
  18301. diff -Nur linux-2.6.35.orig/crypto/ocf/ixp4xx/Makefile linux-2.6.35/crypto/ocf/ixp4xx/Makefile
  18302. --- linux-2.6.35.orig/crypto/ocf/ixp4xx/Makefile 1970-01-01 01:00:00.000000000 +0100
  18303. +++ linux-2.6.35/crypto/ocf/ixp4xx/Makefile 2010-08-05 22:02:10.174081406 +0200
  18304. @@ -0,0 +1,104 @@
  18305. +# for SGlinux builds
  18306. +-include $(ROOTDIR)/modules/.config
  18307. +
  18308. +#
  18309. +# You will need to point this at your Intel ixp425 includes, this portion
  18310. +# of the Makefile only really works under SGLinux with the appropriate libs
  18311. +# installed. They can be downloaded from http://www.snapgear.org/
  18312. +#
  18313. +ifeq ($(CONFIG_CPU_IXP46X),y)
  18314. +IXPLATFORM = ixp46X
  18315. +else
  18316. +ifeq ($(CONFIG_CPU_IXP43X),y)
  18317. +IXPLATFORM = ixp43X
  18318. +else
  18319. +IXPLATFORM = ixp42X
  18320. +endif
  18321. +endif
  18322. +
  18323. +ifdef CONFIG_IXP400_LIB_2_4
  18324. +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp400_xscale_sw
  18325. +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp_osal
  18326. +endif
  18327. +ifdef CONFIG_IXP400_LIB_2_1
  18328. +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp400_xscale_sw
  18329. +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp_osal
  18330. +endif
  18331. +ifdef CONFIG_IXP400_LIB_2_0
  18332. +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp400_xscale_sw
  18333. +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp_osal
  18334. +endif
  18335. +ifdef IX_XSCALE_SW
  18336. +ifdef CONFIG_IXP400_LIB_2_4
  18337. +IXP_CFLAGS = \
  18338. + -I$(ROOTDIR)/. \
  18339. + -I$(IX_XSCALE_SW)/src/include \
  18340. + -I$(OSAL_DIR)/common/include/ \
  18341. + -I$(OSAL_DIR)/common/include/modules/ \
  18342. + -I$(OSAL_DIR)/common/include/modules/ddk/ \
  18343. + -I$(OSAL_DIR)/common/include/modules/bufferMgt/ \
  18344. + -I$(OSAL_DIR)/common/include/modules/ioMem/ \
  18345. + -I$(OSAL_DIR)/common/os/linux/include/ \
  18346. + -I$(OSAL_DIR)/common/os/linux/include/core/ \
  18347. + -I$(OSAL_DIR)/common/os/linux/include/modules/ \
  18348. + -I$(OSAL_DIR)/common/os/linux/include/modules/ddk/ \
  18349. + -I$(OSAL_DIR)/common/os/linux/include/modules/bufferMgt/ \
  18350. + -I$(OSAL_DIR)/common/os/linux/include/modules/ioMem/ \
  18351. + -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/include/ \
  18352. + -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/os/linux/include/ \
  18353. + -DENABLE_IOMEM -DENABLE_BUFFERMGT -DENABLE_DDK \
  18354. + -DUSE_IXP4XX_CRYPTO
  18355. +else
  18356. +IXP_CFLAGS = \
  18357. + -I$(ROOTDIR)/. \
  18358. + -I$(IX_XSCALE_SW)/src/include \
  18359. + -I$(OSAL_DIR)/ \
  18360. + -I$(OSAL_DIR)/os/linux/include/ \
  18361. + -I$(OSAL_DIR)/os/linux/include/modules/ \
  18362. + -I$(OSAL_DIR)/os/linux/include/modules/ioMem/ \
  18363. + -I$(OSAL_DIR)/os/linux/include/modules/bufferMgt/ \
  18364. + -I$(OSAL_DIR)/os/linux/include/core/ \
  18365. + -I$(OSAL_DIR)/os/linux/include/platforms/ \
  18366. + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ \
  18367. + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp425 \
  18368. + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp465 \
  18369. + -I$(OSAL_DIR)/os/linux/include/core/ \
  18370. + -I$(OSAL_DIR)/include/ \
  18371. + -I$(OSAL_DIR)/include/modules/ \
  18372. + -I$(OSAL_DIR)/include/modules/bufferMgt/ \
  18373. + -I$(OSAL_DIR)/include/modules/ioMem/ \
  18374. + -I$(OSAL_DIR)/include/platforms/ \
  18375. + -I$(OSAL_DIR)/include/platforms/ixp400/ \
  18376. + -DUSE_IXP4XX_CRYPTO
  18377. +endif
  18378. +endif
  18379. +ifdef CONFIG_IXP400_LIB_1_4
  18380. +IXP_CFLAGS = \
  18381. + -I$(ROOTDIR)/. \
  18382. + -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/include \
  18383. + -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/linux \
  18384. + -DUSE_IXP4XX_CRYPTO
  18385. +endif
  18386. +ifndef IXPDIR
  18387. +IXPDIR = ixp-version-is-not-supported
  18388. +endif
  18389. +
  18390. +ifeq ($(CONFIG_CPU_IXP46X),y)
  18391. +IXP_CFLAGS += -D__ixp46X
  18392. +else
  18393. +ifeq ($(CONFIG_CPU_IXP43X),y)
  18394. +IXP_CFLAGS += -D__ixp43X
  18395. +else
  18396. +IXP_CFLAGS += -D__ixp42X
  18397. +endif
  18398. +endif
  18399. +
  18400. +obj-$(CONFIG_OCF_IXP4XX) += ixp4xx.o
  18401. +
  18402. +obj ?= .
  18403. +EXTRA_CFLAGS += $(IXP_CFLAGS) -I$(obj)/.. -I$(obj)/.
  18404. +
  18405. +ifdef TOPDIR
  18406. +-include $(TOPDIR)/Rules.make
  18407. +endif
  18408. +
  18409. diff -Nur linux-2.6.35.orig/crypto/ocf/Kconfig linux-2.6.35/crypto/ocf/Kconfig
  18410. --- linux-2.6.35.orig/crypto/ocf/Kconfig 1970-01-01 01:00:00.000000000 +0100
  18411. +++ linux-2.6.35/crypto/ocf/Kconfig 2010-08-05 22:02:10.224092004 +0200
  18412. @@ -0,0 +1,119 @@
  18413. +menu "OCF Configuration"
  18414. +
  18415. +config OCF_OCF
  18416. + tristate "OCF (Open Cryptograhic Framework)"
  18417. + help
  18418. + A linux port of the OpenBSD/FreeBSD crypto framework.
  18419. +
  18420. +config OCF_RANDOMHARVEST
  18421. + bool "crypto random --- harvest entropy for /dev/random"
  18422. + depends on OCF_OCF
  18423. + help
  18424. + Includes code to harvest random numbers from devices that support it.
  18425. +
  18426. +config OCF_FIPS
  18427. + bool "enable fips RNG checks"
  18428. + depends on OCF_OCF && OCF_RANDOMHARVEST
  18429. + help
  18430. + Run all RNG provided data through a fips check before
  18431. + adding it /dev/random's entropy pool.
  18432. +
  18433. +config OCF_CRYPTODEV
  18434. + tristate "cryptodev (user space support)"
  18435. + depends on OCF_OCF
  18436. + help
  18437. + The user space API to access crypto hardware.
  18438. +
  18439. +config OCF_CRYPTOSOFT
  18440. + tristate "cryptosoft (software crypto engine)"
  18441. + depends on OCF_OCF
  18442. + help
  18443. + A software driver for the OCF framework that uses
  18444. + the kernel CryptoAPI.
  18445. +
  18446. +config OCF_SAFE
  18447. + tristate "safenet (HW crypto engine)"
  18448. + depends on OCF_OCF
  18449. + help
  18450. + A driver for a number of the safenet Excel crypto accelerators.
  18451. + Currently tested and working on the 1141 and 1741.
  18452. +
  18453. +config OCF_IXP4XX
  18454. + tristate "IXP4xx (HW crypto engine)"
  18455. + depends on OCF_OCF
  18456. + help
  18457. + XScale IXP4xx crypto accelerator driver. Requires the
  18458. + Intel Access library.
  18459. +
  18460. +config OCF_IXP4XX_SHA1_MD5
  18461. + bool "IXP4xx SHA1 and MD5 Hashing"
  18462. + depends on OCF_IXP4XX
  18463. + help
  18464. + Allows the IXP4xx crypto accelerator to perform SHA1 and MD5 hashing.
  18465. + Note: this is MUCH slower than using cryptosoft (software crypto engine).
  18466. +
  18467. +config OCF_HIFN
  18468. + tristate "hifn (HW crypto engine)"
  18469. + depends on OCF_OCF
  18470. + help
  18471. + OCF driver for various HIFN based crypto accelerators.
  18472. + (7951, 7955, 7956, 7751, 7811)
  18473. +
  18474. +config OCF_HIFNHIPP
  18475. + tristate "Hifn HIPP (HW packet crypto engine)"
  18476. + depends on OCF_OCF
  18477. + help
  18478. + OCF driver for various HIFN (HIPP) based crypto accelerators
  18479. + (7855)
  18480. +
  18481. +config OCF_TALITOS
  18482. + tristate "talitos (HW crypto engine)"
  18483. + depends on OCF_OCF
  18484. + help
  18485. + OCF driver for Freescale's security engine (SEC/talitos).
  18486. +
  18487. +config OCF_PASEMI
  18488. + tristate "pasemi (HW crypto engine)"
  18489. + depends on OCF_OCF && PPC_PASEMI
  18490. + help
  18491. + OCF driver for the PA Semi PWRficient DMA Engine
  18492. +
  18493. +config OCF_EP80579
  18494. + tristate "ep80579 (HW crypto engine)"
  18495. + depends on OCF_OCF
  18496. + help
  18497. + OCF driver for the Intel EP80579 Integrated Processor Product Line.
  18498. +
  18499. +config OCF_CRYPTOCTEON
  18500. + tristate "cryptocteon (HW crypto engine)"
  18501. + depends on OCF_OCF
  18502. + help
  18503. + OCF driver for the Cavium OCTEON Processors.
  18504. +
  18505. +config OCF_KIRKWOOD
  18506. + tristate "kirkwood (HW crypto engine)"
  18507. + depends on OCF_OCF
  18508. + help
  18509. + OCF driver for the Marvell Kirkwood (88F6xxx) Processors.
  18510. +
  18511. +config OCF_C7108
  18512. + tristate "Micronas 7108 (HW crypto engine)"
  18513. + depends on OCF_OCF
  18514. + help
  18515. + OCF driver for the Microna 7108 Cipher processors.
  18516. +
  18517. +config OCF_OCFNULL
  18518. + tristate "ocfnull (fake crypto engine)"
  18519. + depends on OCF_OCF
  18520. + help
  18521. + OCF driver for measuring ipsec overheads (does no crypto)
  18522. +
  18523. +config OCF_BENCH
  18524. + tristate "ocf-bench (HW crypto in-kernel benchmark)"
  18525. + depends on OCF_OCF
  18526. + help
  18527. + A very simple encryption test for the in-kernel interface
  18528. + of OCF. Also includes code to benchmark the IXP Access library
  18529. + for comparison.
  18530. +
  18531. +endmenu
  18532. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c linux-2.6.35/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c
  18533. --- linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c 1970-01-01 01:00:00.000000000 +0100
  18534. +++ linux-2.6.35/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c 2010-08-05 22:02:10.274867934 +0200
  18535. @@ -0,0 +1,317 @@
  18536. +/* rijndael-alg-ref.c v2.0 August '99
  18537. + * Reference ANSI C code
  18538. + * authors: Paulo Barreto
  18539. + * Vincent Rijmen, K.U.Leuven
  18540. + *
  18541. + * This code is placed in the public domain.
  18542. + */
  18543. +
  18544. +#include "mvOs.h"
  18545. +
  18546. +#include "mvAesAlg.h"
  18547. +
  18548. +#include "mvAesBoxes.dat"
  18549. +
  18550. +
  18551. +MV_U8 mul1(MV_U8 aa, MV_U8 bb);
  18552. +void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC);
  18553. +void ShiftRow128Enc(MV_U8 a[4][MAXBC]);
  18554. +void ShiftRow128Dec(MV_U8 a[4][MAXBC]);
  18555. +void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]);
  18556. +void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]);
  18557. +void InvMixColumn(MV_U8 a[4][MAXBC]);
  18558. +
  18559. +
  18560. +#define mul(aa, bb) (mask[bb] & Alogtable[aa + Logtable[bb]])
  18561. +
  18562. +MV_U8 mul1(MV_U8 aa, MV_U8 bb)
  18563. +{
  18564. + return mask[bb] & Alogtable[aa + Logtable[bb]];
  18565. +}
  18566. +
  18567. +
  18568. +void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC)
  18569. +{
  18570. + /* Exor corresponding text input and round key input bytes
  18571. + */
  18572. + ((MV_U32*)(&(a[0][0])))[0] ^= ((MV_U32*)(&(rk[0][0])))[0];
  18573. + ((MV_U32*)(&(a[1][0])))[0] ^= ((MV_U32*)(&(rk[1][0])))[0];
  18574. + ((MV_U32*)(&(a[2][0])))[0] ^= ((MV_U32*)(&(rk[2][0])))[0];
  18575. + ((MV_U32*)(&(a[3][0])))[0] ^= ((MV_U32*)(&(rk[3][0])))[0];
  18576. +
  18577. +}
  18578. +
  18579. +void ShiftRow128Enc(MV_U8 a[4][MAXBC]) {
  18580. + /* Row 0 remains unchanged
  18581. + * The other three rows are shifted a variable amount
  18582. + */
  18583. + MV_U8 tmp[MAXBC];
  18584. +
  18585. + tmp[0] = a[1][1];
  18586. + tmp[1] = a[1][2];
  18587. + tmp[2] = a[1][3];
  18588. + tmp[3] = a[1][0];
  18589. +
  18590. + ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  18591. + /*
  18592. + a[1][0] = tmp[0];
  18593. + a[1][1] = tmp[1];
  18594. + a[1][2] = tmp[2];
  18595. + a[1][3] = tmp[3];
  18596. + */
  18597. + tmp[0] = a[2][2];
  18598. + tmp[1] = a[2][3];
  18599. + tmp[2] = a[2][0];
  18600. + tmp[3] = a[2][1];
  18601. +
  18602. + ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  18603. + /*
  18604. + a[2][0] = tmp[0];
  18605. + a[2][1] = tmp[1];
  18606. + a[2][2] = tmp[2];
  18607. + a[2][3] = tmp[3];
  18608. + */
  18609. + tmp[0] = a[3][3];
  18610. + tmp[1] = a[3][0];
  18611. + tmp[2] = a[3][1];
  18612. + tmp[3] = a[3][2];
  18613. +
  18614. + ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  18615. + /*
  18616. + a[3][0] = tmp[0];
  18617. + a[3][1] = tmp[1];
  18618. + a[3][2] = tmp[2];
  18619. + a[3][3] = tmp[3];
  18620. + */
  18621. +}
  18622. +
  18623. +void ShiftRow128Dec(MV_U8 a[4][MAXBC]) {
  18624. + /* Row 0 remains unchanged
  18625. + * The other three rows are shifted a variable amount
  18626. + */
  18627. + MV_U8 tmp[MAXBC];
  18628. +
  18629. + tmp[0] = a[1][3];
  18630. + tmp[1] = a[1][0];
  18631. + tmp[2] = a[1][1];
  18632. + tmp[3] = a[1][2];
  18633. +
  18634. + ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  18635. + /*
  18636. + a[1][0] = tmp[0];
  18637. + a[1][1] = tmp[1];
  18638. + a[1][2] = tmp[2];
  18639. + a[1][3] = tmp[3];
  18640. + */
  18641. +
  18642. + tmp[0] = a[2][2];
  18643. + tmp[1] = a[2][3];
  18644. + tmp[2] = a[2][0];
  18645. + tmp[3] = a[2][1];
  18646. +
  18647. + ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  18648. + /*
  18649. + a[2][0] = tmp[0];
  18650. + a[2][1] = tmp[1];
  18651. + a[2][2] = tmp[2];
  18652. + a[2][3] = tmp[3];
  18653. + */
  18654. +
  18655. + tmp[0] = a[3][1];
  18656. + tmp[1] = a[3][2];
  18657. + tmp[2] = a[3][3];
  18658. + tmp[3] = a[3][0];
  18659. +
  18660. + ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  18661. + /*
  18662. + a[3][0] = tmp[0];
  18663. + a[3][1] = tmp[1];
  18664. + a[3][2] = tmp[2];
  18665. + a[3][3] = tmp[3];
  18666. + */
  18667. +}
  18668. +
  18669. +void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]) {
  18670. + /* Replace every byte of the input by the byte at that place
  18671. + * in the nonlinear S-box
  18672. + */
  18673. + int i, j;
  18674. +
  18675. + for(i = 0; i < 4; i++)
  18676. + for(j = 0; j < 4; j++) a[i][j] = box[a[i][j]] ;
  18677. +}
  18678. +
  18679. +void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]) {
  18680. + /* Mix the four bytes of every column in a linear way
  18681. + */
  18682. + MV_U8 b[4][MAXBC];
  18683. + int i, j;
  18684. +
  18685. + for(j = 0; j < 4; j++){
  18686. + b[0][j] = mul(25,a[0][j]) ^ mul(1,a[1][j]) ^ a[2][j] ^ a[3][j];
  18687. + b[1][j] = mul(25,a[1][j]) ^ mul(1,a[2][j]) ^ a[3][j] ^ a[0][j];
  18688. + b[2][j] = mul(25,a[2][j]) ^ mul(1,a[3][j]) ^ a[0][j] ^ a[1][j];
  18689. + b[3][j] = mul(25,a[3][j]) ^ mul(1,a[0][j]) ^ a[1][j] ^ a[2][j];
  18690. + }
  18691. + for(i = 0; i < 4; i++)
  18692. + /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/
  18693. + ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0] ^ ((MV_U32*)(&(rk[i][0])))[0];;
  18694. +}
  18695. +
  18696. +void InvMixColumn(MV_U8 a[4][MAXBC]) {
  18697. + /* Mix the four bytes of every column in a linear way
  18698. + * This is the opposite operation of Mixcolumn
  18699. + */
  18700. + MV_U8 b[4][MAXBC];
  18701. + int i, j;
  18702. +
  18703. + for(j = 0; j < 4; j++){
  18704. + b[0][j] = mul(223,a[0][j]) ^ mul(104,a[1][j]) ^ mul(238,a[2][j]) ^ mul(199,a[3][j]);
  18705. + b[1][j] = mul(223,a[1][j]) ^ mul(104,a[2][j]) ^ mul(238,a[3][j]) ^ mul(199,a[0][j]);
  18706. + b[2][j] = mul(223,a[2][j]) ^ mul(104,a[3][j]) ^ mul(238,a[0][j]) ^ mul(199,a[1][j]);
  18707. + b[3][j] = mul(223,a[3][j]) ^ mul(104,a[0][j]) ^ mul(238,a[1][j]) ^ mul(199,a[2][j]);
  18708. + }
  18709. + for(i = 0; i < 4; i++)
  18710. + /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/
  18711. + ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0];
  18712. +}
  18713. +
  18714. +int rijndaelKeySched (MV_U8 k[4][MAXKC], int keyBits, int blockBits, MV_U8 W[MAXROUNDS+1][4][MAXBC])
  18715. +{
  18716. + /* Calculate the necessary round keys
  18717. + * The number of calculations depends on keyBits and blockBits
  18718. + */
  18719. + int KC, BC, ROUNDS;
  18720. + int i, j, t, rconpointer = 0;
  18721. + MV_U8 tk[4][MAXKC];
  18722. +
  18723. + switch (keyBits) {
  18724. + case 128: KC = 4; break;
  18725. + case 192: KC = 6; break;
  18726. + case 256: KC = 8; break;
  18727. + default : return (-1);
  18728. + }
  18729. +
  18730. + switch (blockBits) {
  18731. + case 128: BC = 4; break;
  18732. + case 192: BC = 6; break;
  18733. + case 256: BC = 8; break;
  18734. + default : return (-2);
  18735. + }
  18736. +
  18737. + switch (keyBits >= blockBits ? keyBits : blockBits) {
  18738. + case 128: ROUNDS = 10; break;
  18739. + case 192: ROUNDS = 12; break;
  18740. + case 256: ROUNDS = 14; break;
  18741. + default : return (-3); /* this cannot happen */
  18742. + }
  18743. +
  18744. +
  18745. + for(j = 0; j < KC; j++)
  18746. + for(i = 0; i < 4; i++)
  18747. + tk[i][j] = k[i][j];
  18748. + t = 0;
  18749. + /* copy values into round key array */
  18750. + for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
  18751. + for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
  18752. +
  18753. + while (t < (ROUNDS+1)*BC) { /* while not enough round key material calculated */
  18754. + /* calculate new values */
  18755. + for(i = 0; i < 4; i++)
  18756. + tk[i][0] ^= S[tk[(i+1)%4][KC-1]];
  18757. + tk[0][0] ^= rcon[rconpointer++];
  18758. +
  18759. + if (KC != 8)
  18760. + for(j = 1; j < KC; j++)
  18761. + for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
  18762. + else {
  18763. + for(j = 1; j < KC/2; j++)
  18764. + for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
  18765. + for(i = 0; i < 4; i++) tk[i][KC/2] ^= S[tk[i][KC/2 - 1]];
  18766. + for(j = KC/2 + 1; j < KC; j++)
  18767. + for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
  18768. + }
  18769. + /* copy values into round key array */
  18770. + for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
  18771. + for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
  18772. + }
  18773. +
  18774. + return 0;
  18775. +}
  18776. +
  18777. +
  18778. +
  18779. +int rijndaelEncrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
  18780. +{
  18781. + /* Encryption of one block.
  18782. + */
  18783. + int r, BC, ROUNDS;
  18784. +
  18785. + BC = 4;
  18786. + ROUNDS = rounds;
  18787. +
  18788. + /* begin with a key addition
  18789. + */
  18790. +
  18791. + KeyAddition(a,rk[0],BC);
  18792. +
  18793. + /* ROUNDS-1 ordinary rounds
  18794. + */
  18795. + for(r = 1; r < ROUNDS; r++) {
  18796. + Substitution(a,S);
  18797. + ShiftRow128Enc(a);
  18798. + MixColumn(a, rk[r]);
  18799. + /*KeyAddition(a,rk[r],BC);*/
  18800. + }
  18801. +
  18802. + /* Last round is special: there is no MixColumn
  18803. + */
  18804. + Substitution(a,S);
  18805. + ShiftRow128Enc(a);
  18806. + KeyAddition(a,rk[ROUNDS],BC);
  18807. +
  18808. + return 0;
  18809. +}
  18810. +
  18811. +
  18812. +int rijndaelDecrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
  18813. +{
  18814. + int r, BC, ROUNDS;
  18815. +
  18816. + BC = 4;
  18817. + ROUNDS = rounds;
  18818. +
  18819. + /* To decrypt: apply the inverse operations of the encrypt routine,
  18820. + * in opposite order
  18821. + *
  18822. + * (KeyAddition is an involution: it 's equal to its inverse)
  18823. + * (the inverse of Substitution with table S is Substitution with the inverse table of S)
  18824. + * (the inverse of Shiftrow is Shiftrow over a suitable distance)
  18825. + */
  18826. +
  18827. + /* First the special round:
  18828. + * without InvMixColumn
  18829. + * with extra KeyAddition
  18830. + */
  18831. + KeyAddition(a,rk[ROUNDS],BC);
  18832. + ShiftRow128Dec(a);
  18833. + Substitution(a,Si);
  18834. +
  18835. + /* ROUNDS-1 ordinary rounds
  18836. + */
  18837. + for(r = ROUNDS-1; r > 0; r--) {
  18838. + KeyAddition(a,rk[r],BC);
  18839. + InvMixColumn(a);
  18840. + ShiftRow128Dec(a);
  18841. + Substitution(a,Si);
  18842. +
  18843. + }
  18844. +
  18845. + /* End with the extra key addition
  18846. + */
  18847. +
  18848. + KeyAddition(a,rk[0],BC);
  18849. +
  18850. + return 0;
  18851. +}
  18852. +
  18853. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h linux-2.6.35/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h
  18854. --- linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h 1970-01-01 01:00:00.000000000 +0100
  18855. +++ linux-2.6.35/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h 2010-08-05 22:02:10.333632718 +0200
  18856. @@ -0,0 +1,19 @@
  18857. +/* rijndael-alg-ref.h v2.0 August '99
  18858. + * Reference ANSI C code
  18859. + * authors: Paulo Barreto
  18860. + * Vincent Rijmen, K.U.Leuven
  18861. + */
  18862. +#ifndef __RIJNDAEL_ALG_H
  18863. +#define __RIJNDAEL_ALG_H
  18864. +
  18865. +#define MAXBC (128/32)
  18866. +#define MAXKC (256/32)
  18867. +#define MAXROUNDS 14
  18868. +
  18869. +
  18870. +int rijndaelKeySched (MV_U8 k[4][MAXKC], int keyBits, int blockBits, MV_U8 rk[MAXROUNDS+1][4][MAXBC]);
  18871. +
  18872. +int rijndaelEncrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds);
  18873. +int rijndaelDecrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds);
  18874. +
  18875. +#endif /* __RIJNDAEL_ALG_H */
  18876. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c linux-2.6.35/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c
  18877. --- linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c 1970-01-01 01:00:00.000000000 +0100
  18878. +++ linux-2.6.35/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c 2010-08-05 22:02:10.383874308 +0200
  18879. @@ -0,0 +1,312 @@
  18880. +/* rijndael-api-ref.c v2.1 April 2000
  18881. + * Reference ANSI C code
  18882. + * authors: v2.0 Paulo Barreto
  18883. + * Vincent Rijmen, K.U.Leuven
  18884. + * v2.1 Vincent Rijmen, K.U.Leuven
  18885. + *
  18886. + * This code is placed in the public domain.
  18887. + */
  18888. +#include "mvOs.h"
  18889. +
  18890. +#include "mvAes.h"
  18891. +#include "mvAesAlg.h"
  18892. +
  18893. +
  18894. +/* Defines:
  18895. + Add any additional defines you need
  18896. +*/
  18897. +
  18898. +#define MODE_ECB 1 /* Are we ciphering in ECB mode? */
  18899. +#define MODE_CBC 2 /* Are we ciphering in CBC mode? */
  18900. +#define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */
  18901. +
  18902. +
  18903. +int aesMakeKey(MV_U8 *expandedKey, MV_U8 *keyMaterial, int keyLen, int blockLen)
  18904. +{
  18905. + MV_U8 W[MAXROUNDS+1][4][MAXBC];
  18906. + MV_U8 k[4][MAXKC];
  18907. + MV_U8 j;
  18908. + int i, rounds, KC;
  18909. +
  18910. + if (expandedKey == NULL)
  18911. + {
  18912. + return AES_BAD_KEY_INSTANCE;
  18913. + }
  18914. +
  18915. + if (!((keyLen == 128) || (keyLen == 192) || (keyLen == 256)))
  18916. + {
  18917. + return AES_BAD_KEY_MAT;
  18918. + }
  18919. +
  18920. + if (keyMaterial == NULL)
  18921. + {
  18922. + return AES_BAD_KEY_MAT;
  18923. + }
  18924. +
  18925. + /* initialize key schedule: */
  18926. + for(i=0; i<keyLen/8; i++)
  18927. + {
  18928. + j = keyMaterial[i];
  18929. + k[i % 4][i / 4] = j;
  18930. + }
  18931. +
  18932. + rijndaelKeySched (k, keyLen, blockLen, W);
  18933. +#ifdef MV_AES_DEBUG
  18934. + {
  18935. + MV_U8* pW = &W[0][0][0];
  18936. + int x;
  18937. +
  18938. + mvOsPrintf("Expended Key: size = %d\n", sizeof(W));
  18939. + for(i=0; i<sizeof(W); i++)
  18940. + {
  18941. + mvOsPrintf("%02x ", pW[i]);
  18942. + }
  18943. + for(i=0; i<MAXROUNDS+1; i++)
  18944. + {
  18945. + mvOsPrintf("\n Round #%02d: ", i);
  18946. + for(x=0; x<MAXBC; x++)
  18947. + {
  18948. + mvOsPrintf("%02x%02x%02x%02x ",
  18949. + W[i][0][x], W[i][1][x], W[i][2][x], W[i][3][x]);
  18950. + }
  18951. + mvOsPrintf("\n");
  18952. + }
  18953. + }
  18954. +#endif /* MV_AES_DEBUG */
  18955. + switch (keyLen)
  18956. + {
  18957. + case 128:
  18958. + rounds = 10;
  18959. + KC = 4;
  18960. + break;
  18961. + case 192:
  18962. + rounds = 12;
  18963. + KC = 6;
  18964. + break;
  18965. + case 256:
  18966. + rounds = 14;
  18967. + KC = 8;
  18968. + break;
  18969. + default :
  18970. + return (-1);
  18971. + }
  18972. +
  18973. + for(i=0; i<MAXBC; i++)
  18974. + {
  18975. + for(j=0; j<4; j++)
  18976. + {
  18977. + expandedKey[i*4+j] = W[rounds][j][i];
  18978. + }
  18979. + }
  18980. + for(; i<KC; i++)
  18981. + {
  18982. + for(j=0; j<4; j++)
  18983. + {
  18984. + expandedKey[i*4+j] = W[rounds-1][j][i+MAXBC-KC];
  18985. + }
  18986. + }
  18987. +
  18988. +
  18989. + return 0;
  18990. +}
  18991. +
  18992. +int aesBlockEncrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
  18993. + MV_U32 *plain, int numBlocks, MV_U32 *cipher)
  18994. +{
  18995. + int i, j, t;
  18996. + MV_U8 block[4][MAXBC];
  18997. + int rounds;
  18998. + char *input, *outBuffer;
  18999. +
  19000. + input = (char*)plain;
  19001. + outBuffer = (char*)cipher;
  19002. +
  19003. + /* check parameter consistency: */
  19004. + if( (expandedKey == NULL) || ((keyLen != 128) && (keyLen != 192) && (keyLen != 256)))
  19005. + {
  19006. + return AES_BAD_KEY_MAT;
  19007. + }
  19008. + if ((mode != MODE_ECB && mode != MODE_CBC))
  19009. + {
  19010. + return AES_BAD_CIPHER_STATE;
  19011. + }
  19012. +
  19013. + switch (keyLen)
  19014. + {
  19015. + case 128: rounds = 10; break;
  19016. + case 192: rounds = 12; break;
  19017. + case 256: rounds = 14; break;
  19018. + default : return (-3); /* this cannot happen */
  19019. + }
  19020. +
  19021. +
  19022. + switch (mode)
  19023. + {
  19024. + case MODE_ECB:
  19025. + for (i = 0; i < numBlocks; i++)
  19026. + {
  19027. + for (j = 0; j < 4; j++)
  19028. + {
  19029. + for(t = 0; t < 4; t++)
  19030. + /* parse input stream into rectangular array */
  19031. + block[t][j] = input[16*i+4*j+t] & 0xFF;
  19032. + }
  19033. + rijndaelEncrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  19034. + for (j = 0; j < 4; j++)
  19035. + {
  19036. + /* parse rectangular array into output ciphertext bytes */
  19037. + for(t = 0; t < 4; t++)
  19038. + outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];
  19039. +
  19040. + }
  19041. + }
  19042. + break;
  19043. +
  19044. + case MODE_CBC:
  19045. + for (j = 0; j < 4; j++)
  19046. + {
  19047. + for(t = 0; t < 4; t++)
  19048. + /* parse initial value into rectangular array */
  19049. + block[t][j] = IV[t+4*j] & 0xFF;
  19050. + }
  19051. + for (i = 0; i < numBlocks; i++)
  19052. + {
  19053. + for (j = 0; j < 4; j++)
  19054. + {
  19055. + for(t = 0; t < 4; t++)
  19056. + /* parse input stream into rectangular array and exor with
  19057. + IV or the previous ciphertext */
  19058. + block[t][j] ^= input[16*i+4*j+t] & 0xFF;
  19059. + }
  19060. + rijndaelEncrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  19061. + for (j = 0; j < 4; j++)
  19062. + {
  19063. + /* parse rectangular array into output ciphertext bytes */
  19064. + for(t = 0; t < 4; t++)
  19065. + outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];
  19066. + }
  19067. + }
  19068. + break;
  19069. +
  19070. + default: return AES_BAD_CIPHER_STATE;
  19071. + }
  19072. +
  19073. + return 0;
  19074. +}
  19075. +
  19076. +int aesBlockDecrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
  19077. + MV_U32 *srcData, int numBlocks, MV_U32 *dstData)
  19078. +{
  19079. + int i, j, t;
  19080. + MV_U8 block[4][MAXBC];
  19081. + MV_U8 iv[4][MAXBC];
  19082. + int rounds;
  19083. + char *input, *outBuffer;
  19084. +
  19085. + input = (char*)srcData;
  19086. + outBuffer = (char*)dstData;
  19087. +
  19088. + if (expandedKey == NULL)
  19089. + {
  19090. + return AES_BAD_KEY_MAT;
  19091. + }
  19092. +
  19093. + /* check parameter consistency: */
  19094. + if (keyLen != 128 && keyLen != 192 && keyLen != 256)
  19095. + {
  19096. + return AES_BAD_KEY_MAT;
  19097. + }
  19098. + if ((mode != MODE_ECB && mode != MODE_CBC))
  19099. + {
  19100. + return AES_BAD_CIPHER_STATE;
  19101. + }
  19102. +
  19103. + switch (keyLen)
  19104. + {
  19105. + case 128: rounds = 10; break;
  19106. + case 192: rounds = 12; break;
  19107. + case 256: rounds = 14; break;
  19108. + default : return (-3); /* this cannot happen */
  19109. + }
  19110. +
  19111. +
  19112. + switch (mode)
  19113. + {
  19114. + case MODE_ECB:
  19115. + for (i = 0; i < numBlocks; i++)
  19116. + {
  19117. + for (j = 0; j < 4; j++)
  19118. + {
  19119. + for(t = 0; t < 4; t++)
  19120. + {
  19121. + /* parse input stream into rectangular array */
  19122. + block[t][j] = input[16*i+4*j+t] & 0xFF;
  19123. + }
  19124. + }
  19125. + rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  19126. + for (j = 0; j < 4; j++)
  19127. + {
  19128. + /* parse rectangular array into output ciphertext bytes */
  19129. + for(t = 0; t < 4; t++)
  19130. + outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];
  19131. + }
  19132. + }
  19133. + break;
  19134. +
  19135. + case MODE_CBC:
  19136. + /* first block */
  19137. + for (j = 0; j < 4; j++)
  19138. + {
  19139. + for(t = 0; t < 4; t++)
  19140. + {
  19141. + /* parse input stream into rectangular array */
  19142. + block[t][j] = input[4*j+t] & 0xFF;
  19143. + iv[t][j] = block[t][j];
  19144. + }
  19145. + }
  19146. + rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  19147. +
  19148. + for (j = 0; j < 4; j++)
  19149. + {
  19150. + /* exor the IV and parse rectangular array into output ciphertext bytes */
  19151. + for(t = 0; t < 4; t++)
  19152. + {
  19153. + outBuffer[4*j+t] = (MV_U8) (block[t][j] ^ IV[t+4*j]);
  19154. + IV[t+4*j] = iv[t][j];
  19155. + }
  19156. + }
  19157. +
  19158. + /* next blocks */
  19159. + for (i = 1; i < numBlocks; i++)
  19160. + {
  19161. + for (j = 0; j < 4; j++)
  19162. + {
  19163. + for(t = 0; t < 4; t++)
  19164. + {
  19165. + /* parse input stream into rectangular array */
  19166. + iv[t][j] = input[16*i+4*j+t] & 0xFF;
  19167. + block[t][j] = iv[t][j];
  19168. + }
  19169. + }
  19170. + rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  19171. +
  19172. + for (j = 0; j < 4; j++)
  19173. + {
  19174. + /* exor previous ciphertext block and parse rectangular array
  19175. + into output ciphertext bytes */
  19176. + for(t = 0; t < 4; t++)
  19177. + {
  19178. + outBuffer[16*i+4*j+t] = (MV_U8) (block[t][j] ^ IV[t+4*j]);
  19179. + IV[t+4*j] = iv[t][j];
  19180. + }
  19181. + }
  19182. + }
  19183. + break;
  19184. +
  19185. + default: return AES_BAD_CIPHER_STATE;
  19186. + }
  19187. +
  19188. + return 0;
  19189. +}
  19190. +
  19191. +
  19192. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/AES/mvAes.h linux-2.6.35/crypto/ocf/kirkwood/cesa/AES/mvAes.h
  19193. --- linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/AES/mvAes.h 1970-01-01 01:00:00.000000000 +0100
  19194. +++ linux-2.6.35/crypto/ocf/kirkwood/cesa/AES/mvAes.h 2010-08-05 22:02:10.433877267 +0200
  19195. @@ -0,0 +1,62 @@
  19196. +/* mvAes.h v2.0 August '99
  19197. + * Reference ANSI C code
  19198. + */
  19199. +
  19200. +/* AES Cipher header file for ANSI C Submissions
  19201. + Lawrence E. Bassham III
  19202. + Computer Security Division
  19203. + National Institute of Standards and Technology
  19204. +
  19205. + April 15, 1998
  19206. +
  19207. + This sample is to assist implementers developing to the Cryptographic
  19208. +API Profile for AES Candidate Algorithm Submissions. Please consult this
  19209. +document as a cross-reference.
  19210. +
  19211. + ANY CHANGES, WHERE APPROPRIATE, TO INFORMATION PROVIDED IN THIS FILE
  19212. +MUST BE DOCUMENTED. CHANGES ARE ONLY APPROPRIATE WHERE SPECIFIED WITH
  19213. +THE STRING "CHANGE POSSIBLE". FUNCTION CALLS AND THEIR PARAMETERS CANNOT
  19214. +BE CHANGED. STRUCTURES CAN BE ALTERED TO ALLOW IMPLEMENTERS TO INCLUDE
  19215. +IMPLEMENTATION SPECIFIC INFORMATION.
  19216. +*/
  19217. +
  19218. +/* Includes:
  19219. + Standard include files
  19220. +*/
  19221. +
  19222. +#include "mvOs.h"
  19223. +
  19224. +
  19225. +/* Error Codes - CHANGE POSSIBLE: inclusion of additional error codes */
  19226. +
  19227. +/* Key direction is invalid, e.g., unknown value */
  19228. +#define AES_BAD_KEY_DIR -1
  19229. +
  19230. +/* Key material not of correct length */
  19231. +#define AES_BAD_KEY_MAT -2
  19232. +
  19233. +/* Key passed is not valid */
  19234. +#define AES_BAD_KEY_INSTANCE -3
  19235. +
  19236. +/* Params struct passed to cipherInit invalid */
  19237. +#define AES_BAD_CIPHER_MODE -4
  19238. +
  19239. +/* Cipher in wrong state (e.g., not initialized) */
  19240. +#define AES_BAD_CIPHER_STATE -5
  19241. +
  19242. +#define AES_BAD_CIPHER_INSTANCE -7
  19243. +
  19244. +
  19245. +/* Function protoypes */
  19246. +/* CHANGED: makeKey(): parameter blockLen added
  19247. + this parameter is absolutely necessary if you want to
  19248. + setup the round keys in a variable block length setting
  19249. + cipherInit(): parameter blockLen added (for obvious reasons)
  19250. + */
  19251. +int aesMakeKey(MV_U8 *expandedKey, MV_U8 *keyMaterial, int keyLen, int blockLen);
  19252. +int aesBlockEncrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
  19253. + MV_U32 *plain, int numBlocks, MV_U32 *cipher);
  19254. +int aesBlockDecrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
  19255. + MV_U32 *plain, int numBlocks, MV_U32 *cipher);
  19256. +
  19257. +
  19258. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvCesa.c linux-2.6.35/crypto/ocf/kirkwood/cesa/mvCesa.c
  19259. --- linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvCesa.c 1970-01-01 01:00:00.000000000 +0100
  19260. +++ linux-2.6.35/crypto/ocf/kirkwood/cesa/mvCesa.c 2010-08-05 22:02:10.483645871 +0200
  19261. @@ -0,0 +1,3126 @@
  19262. +/*******************************************************************************
  19263. +Copyright (C) Marvell International Ltd. and its affiliates
  19264. +
  19265. +This software file (the "File") is owned and distributed by Marvell
  19266. +International Ltd. and/or its affiliates ("Marvell") under the following
  19267. +alternative licensing terms. Once you have made an election to distribute the
  19268. +File under one of the following license alternatives, please (i) delete this
  19269. +introductory statement regarding license alternatives, (ii) delete the two
  19270. +license alternatives that you have not elected to use and (iii) preserve the
  19271. +Marvell copyright notice above.
  19272. +
  19273. +********************************************************************************
  19274. +Marvell Commercial License Option
  19275. +
  19276. +If you received this File from Marvell and you have entered into a commercial
  19277. +license agreement (a "Commercial License") with Marvell, the File is licensed
  19278. +to you under the terms of the applicable Commercial License.
  19279. +
  19280. +********************************************************************************
  19281. +Marvell GPL License Option
  19282. +
  19283. +If you received this File from Marvell, you may opt to use, redistribute and/or
  19284. +modify this File in accordance with the terms and conditions of the General
  19285. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  19286. +available along with the File in the license.txt file or by writing to the Free
  19287. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  19288. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  19289. +
  19290. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  19291. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  19292. +DISCLAIMED. The GPL License provides additional details about this warranty
  19293. +disclaimer.
  19294. +********************************************************************************
  19295. +Marvell BSD License Option
  19296. +
  19297. +If you received this File from Marvell, you may opt to use, redistribute and/or
  19298. +modify this File under the following licensing terms.
  19299. +Redistribution and use in source and binary forms, with or without modification,
  19300. +are permitted provided that the following conditions are met:
  19301. +
  19302. + * Redistributions of source code must retain the above copyright notice,
  19303. + this list of conditions and the following disclaimer.
  19304. +
  19305. + * Redistributions in binary form must reproduce the above copyright
  19306. + notice, this list of conditions and the following disclaimer in the
  19307. + documentation and/or other materials provided with the distribution.
  19308. +
  19309. + * Neither the name of Marvell nor the names of its contributors may be
  19310. + used to endorse or promote products derived from this software without
  19311. + specific prior written permission.
  19312. +
  19313. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  19314. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19315. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19316. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  19317. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  19318. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  19319. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  19320. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  19321. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  19322. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  19323. +
  19324. +*******************************************************************************/
  19325. +
  19326. +#include "cesa/mvCesa.h"
  19327. +
  19328. +#include "ctrlEnv/mvCtrlEnvLib.h"
  19329. +#undef CESA_DEBUG
  19330. +
  19331. +
  19332. +/********** Global variables **********/
  19333. +
  19334. +/* If request size is more than MV_CESA_MAX_BUF_SIZE the
  19335. + * request is processed as fragmented request.
  19336. + */
  19337. +
  19338. +MV_CESA_STATS cesaStats;
  19339. +
  19340. +MV_BUF_INFO cesaSramSaBuf;
  19341. +short cesaLastSid = -1;
  19342. +MV_CESA_SA* pCesaSAD = NULL;
  19343. +MV_U16 cesaMaxSA = 0;
  19344. +
  19345. +MV_CESA_REQ* pCesaReqFirst = NULL;
  19346. +MV_CESA_REQ* pCesaReqLast = NULL;
  19347. +MV_CESA_REQ* pCesaReqEmpty = NULL;
  19348. +MV_CESA_REQ* pCesaReqProcess = NULL;
  19349. +int cesaQueueDepth = 0;
  19350. +int cesaReqResources = 0;
  19351. +
  19352. +MV_CESA_SRAM_MAP* cesaSramVirtPtr = NULL;
  19353. +MV_U32 cesaCryptEngBase = 0;
  19354. +void *cesaOsHandle = NULL;
  19355. +#if (MV_CESA_VERSION >= 3)
  19356. +MV_U32 cesaChainLength = 0;
  19357. +int chainReqNum = 0;
  19358. +MV_U32 chainIndex = 0;
  19359. +MV_CESA_REQ* pNextActiveChain = 0;
  19360. +MV_CESA_REQ* pEndCurrChain = 0;
  19361. +MV_BOOL isFirstReq = MV_TRUE;
  19362. +#endif
  19363. +
  19364. +static INLINE MV_U8* mvCesaSramAddrGet(void)
  19365. +{
  19366. +#ifdef MV_CESA_NO_SRAM
  19367. + return (MV_U8*)cesaSramVirtPtr;
  19368. +#else
  19369. + return (MV_U8*)cesaCryptEngBase;
  19370. +#endif /* MV_CESA_NO_SRAM */
  19371. +}
  19372. +
  19373. +static INLINE MV_ULONG mvCesaSramVirtToPhys(void* pDev, MV_U8* pSramVirt)
  19374. +{
  19375. +#ifdef MV_CESA_NO_SRAM
  19376. + return (MV_ULONG)mvOsIoVirtToPhy(NULL, pSramVirt);
  19377. +#else
  19378. + return (MV_ULONG)pSramVirt;
  19379. +#endif /* MV_CESA_NO_SRAM */
  19380. +}
  19381. +
  19382. +/* Internal Function prototypes */
  19383. +
  19384. +static INLINE void mvCesaSramDescrBuild(MV_U32 config, int frag,
  19385. + int cryptoOffset, int ivOffset, int cryptoLength,
  19386. + int macOffset, int digestOffset, int macLength, int macTotalLen,
  19387. + MV_CESA_REQ *pCesaReq, MV_DMA_DESC* pDmaDesc);
  19388. +
  19389. +static INLINE void mvCesaSramSaUpdate(short sid, MV_DMA_DESC *pDmaDesc);
  19390. +
  19391. +static INLINE int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,
  19392. + MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,
  19393. + int offset, int copySize, MV_BOOL skipFlush);
  19394. +
  19395. +static void mvCesaHmacIvGet(MV_CESA_MAC_MODE macMode, unsigned char key[], int keyLength,
  19396. + unsigned char innerIV[], unsigned char outerIV[]);
  19397. +
  19398. +static MV_STATUS mvCesaFragAuthComplete(MV_CESA_REQ* pReq, MV_CESA_SA* pSA,
  19399. + int macDataSize);
  19400. +
  19401. +static MV_CESA_COMMAND* mvCesaCtrModeInit(void);
  19402. +
  19403. +static MV_STATUS mvCesaCtrModePrepare(MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd);
  19404. +static MV_STATUS mvCesaCtrModeComplete(MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd);
  19405. +static void mvCesaCtrModeFinish(MV_CESA_COMMAND *pCmd);
  19406. +
  19407. +static INLINE MV_STATUS mvCesaReqProcess(MV_CESA_REQ* pReq);
  19408. +static MV_STATUS mvCesaFragReqProcess(MV_CESA_REQ* pReq, MV_U8 frag);
  19409. +
  19410. +static INLINE MV_STATUS mvCesaParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, MV_U8* pFixOffset);
  19411. +static INLINE MV_STATUS mvCesaFragParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd);
  19412. +
  19413. +static INLINE void mvCesaFragSizeFind(MV_CESA_SA* pSA, MV_CESA_REQ* pReq,
  19414. + int cryptoOffset, int macOffset,
  19415. + int* pCopySize, int* pCryptoDataSize, int* pMacDataSize);
  19416. +static MV_STATUS mvCesaMbufCacheUnmap(MV_CESA_MBUF* pMbuf, int offset, int size);
  19417. +
  19418. +
  19419. +/* Go to the next request in the request queue */
  19420. +static INLINE MV_CESA_REQ* MV_CESA_REQ_NEXT_PTR(MV_CESA_REQ* pReq)
  19421. +{
  19422. + if(pReq == pCesaReqLast)
  19423. + return pCesaReqFirst;
  19424. +
  19425. + return pReq+1;
  19426. +}
  19427. +
  19428. +#if (MV_CESA_VERSION >= 3)
  19429. +/* Go to the previous request in the request queue */
  19430. +static INLINE MV_CESA_REQ* MV_CESA_REQ_PREV_PTR(MV_CESA_REQ* pReq)
  19431. +{
  19432. + if(pReq == pCesaReqFirst)
  19433. + return pCesaReqLast;
  19434. +
  19435. + return pReq-1;
  19436. +}
  19437. +
  19438. +#endif
  19439. +
  19440. +
  19441. +static INLINE void mvCesaReqProcessStart(MV_CESA_REQ* pReq)
  19442. +{
  19443. + int frag;
  19444. +
  19445. +#if (MV_CESA_VERSION >= 3)
  19446. + pReq->state = MV_CESA_CHAIN;
  19447. +#else
  19448. + pReq->state = MV_CESA_PROCESS;
  19449. +#endif
  19450. + cesaStats.startCount++;
  19451. +
  19452. + if(pReq->fragMode == MV_CESA_FRAG_NONE)
  19453. + {
  19454. + frag = 0;
  19455. + }
  19456. + else
  19457. + {
  19458. + frag = pReq->frags.nextFrag;
  19459. + pReq->frags.nextFrag++;
  19460. + }
  19461. +#if (MV_CESA_VERSION >= 2)
  19462. + /* Enable TDMA engine */
  19463. + MV_REG_WRITE(MV_CESA_TDMA_CURR_DESC_PTR_REG, 0);
  19464. + MV_REG_WRITE(MV_CESA_TDMA_NEXT_DESC_PTR_REG,
  19465. + (MV_U32)mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));
  19466. +#else
  19467. + /* Enable IDMA engine */
  19468. + MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(0), 0);
  19469. + MV_REG_WRITE(IDMA_NEXT_DESC_PTR_REG(0),
  19470. + (MV_U32)mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));
  19471. +#endif /* MV_CESA_VERSION >= 2 */
  19472. +
  19473. +#if defined(MV_BRIDGE_SYNC_REORDER)
  19474. + mvOsBridgeReorderWA();
  19475. +#endif
  19476. +
  19477. + /* Start Accelerator */
  19478. + MV_REG_WRITE(MV_CESA_CMD_REG, MV_CESA_CMD_CHAN_ENABLE_MASK);
  19479. +}
  19480. +
  19481. +
  19482. +/*******************************************************************************
  19483. +* mvCesaHalInit - Initialize the CESA driver
  19484. +*
  19485. +* DESCRIPTION:
  19486. +* This function initialize the CESA driver.
  19487. +* 1) Session database
  19488. +* 2) Request queue
  19489. +* 4) DMA descriptor lists - one list per request. Each list
  19490. +* has MV_CESA_MAX_DMA_DESC descriptors.
  19491. +*
  19492. +* INPUT:
  19493. +* numOfSession - maximum number of supported sessions
  19494. +* queueDepth - number of elements in the request queue.
  19495. +* pSramBase - virtual address of Sram
  19496. +* osHandle - A handle used by the OS to allocate memory for the
  19497. +* module (Passed to the OS Services layer)
  19498. +*
  19499. +* RETURN:
  19500. +* MV_OK - Success
  19501. +* MV_NO_RESOURCE - Fail, can't allocate resources:
  19502. +* Session database, request queue,
  19503. +* DMA descriptors list, LRU cache database.
  19504. +* MV_NOT_ALIGNED - Sram base address is not 8 byte aligned.
  19505. +*
  19506. +*******************************************************************************/
  19507. +MV_STATUS mvCesaHalInit (int numOfSession, int queueDepth, char* pSramBase, MV_U32 cryptEngBase,
  19508. + void *osHandle)
  19509. +{
  19510. + int i, req;
  19511. + MV_U32 descOffsetReg, configReg;
  19512. + MV_CESA_SRAM_SA *pSramSA;
  19513. +
  19514. +
  19515. + mvOsPrintf("mvCesaInit: sessions=%d, queue=%d, pSram=%p\n",
  19516. + numOfSession, queueDepth, pSramBase);
  19517. +
  19518. + cesaOsHandle = osHandle;
  19519. + /* Create Session database */
  19520. + pCesaSAD = mvOsMalloc(sizeof(MV_CESA_SA)*numOfSession);
  19521. + if(pCesaSAD == NULL)
  19522. + {
  19523. + mvOsPrintf("mvCesaInit: Can't allocate %u bytes for %d SAs\n",
  19524. + sizeof(MV_CESA_SA)*numOfSession, numOfSession);
  19525. + mvCesaFinish();
  19526. + return MV_NO_RESOURCE;
  19527. + }
  19528. + memset(pCesaSAD, 0, sizeof(MV_CESA_SA)*numOfSession);
  19529. + cesaMaxSA = numOfSession;
  19530. +
  19531. + /* Allocate imag of sramSA in the DRAM */
  19532. + cesaSramSaBuf.bufSize = sizeof(MV_CESA_SRAM_SA)*numOfSession +
  19533. + CPU_D_CACHE_LINE_SIZE;
  19534. +
  19535. + cesaSramSaBuf.bufVirtPtr = mvOsIoCachedMalloc(osHandle,cesaSramSaBuf.bufSize,
  19536. + &cesaSramSaBuf.bufPhysAddr,
  19537. + &cesaSramSaBuf.memHandle);
  19538. +
  19539. + if(cesaSramSaBuf.bufVirtPtr == NULL)
  19540. + {
  19541. + mvOsPrintf("mvCesaInit: Can't allocate %d bytes for sramSA structures\n",
  19542. + cesaSramSaBuf.bufSize);
  19543. + mvCesaFinish();
  19544. + return MV_NO_RESOURCE;
  19545. + }
  19546. + memset(cesaSramSaBuf.bufVirtPtr, 0, cesaSramSaBuf.bufSize);
  19547. + pSramSA = (MV_CESA_SRAM_SA*)MV_ALIGN_UP((MV_ULONG)cesaSramSaBuf.bufVirtPtr,
  19548. + CPU_D_CACHE_LINE_SIZE);
  19549. + for(i=0; i<numOfSession; i++)
  19550. + {
  19551. + pCesaSAD[i].pSramSA = &pSramSA[i];
  19552. + }
  19553. +
  19554. + /* Create request queue */
  19555. + pCesaReqFirst = mvOsMalloc(sizeof(MV_CESA_REQ)*queueDepth);
  19556. + if(pCesaReqFirst == NULL)
  19557. + {
  19558. + mvOsPrintf("mvCesaInit: Can't allocate %u bytes for %d requests\n",
  19559. + sizeof(MV_CESA_REQ)*queueDepth, queueDepth);
  19560. + mvCesaFinish();
  19561. + return MV_NO_RESOURCE;
  19562. + }
  19563. + memset(pCesaReqFirst, 0, sizeof(MV_CESA_REQ)*queueDepth);
  19564. + pCesaReqEmpty = pCesaReqFirst;
  19565. + pCesaReqLast = pCesaReqFirst + (queueDepth-1);
  19566. + pCesaReqProcess = pCesaReqEmpty;
  19567. + cesaQueueDepth = queueDepth;
  19568. + cesaReqResources = queueDepth;
  19569. +#if (MV_CESA_VERSION >= 3)
  19570. + cesaChainLength = MAX_CESA_CHAIN_LENGTH;
  19571. +#endif
  19572. + /* pSramBase must be 8 byte aligned */
  19573. + if( MV_IS_NOT_ALIGN((MV_ULONG)pSramBase, 8) )
  19574. + {
  19575. + mvOsPrintf("mvCesaInit: pSramBase (%p) must be 8 byte aligned\n",
  19576. + pSramBase);
  19577. + mvCesaFinish();
  19578. + return MV_NOT_ALIGNED;
  19579. + }
  19580. + cesaSramVirtPtr = (MV_CESA_SRAM_MAP*)pSramBase;
  19581. +
  19582. + cesaCryptEngBase = cryptEngBase;
  19583. +
  19584. + /*memset(cesaSramVirtPtr, 0, sizeof(MV_CESA_SRAM_MAP));*/
  19585. +
  19586. + /* Clear registers */
  19587. + MV_REG_WRITE( MV_CESA_CFG_REG, 0);
  19588. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  19589. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
  19590. +
  19591. + /* Initialize DMA descriptor lists for all requests in Request queue */
  19592. + descOffsetReg = configReg = 0;
  19593. + for(req=0; req<queueDepth; req++)
  19594. + {
  19595. + int frag;
  19596. + MV_CESA_REQ* pReq;
  19597. + MV_DMA_DESC* pDmaDesc;
  19598. +
  19599. + pReq = &pCesaReqFirst[req];
  19600. +
  19601. + pReq->cesaDescBuf.bufSize = sizeof(MV_CESA_DESC)*MV_CESA_MAX_REQ_FRAGS +
  19602. + CPU_D_CACHE_LINE_SIZE;
  19603. +
  19604. + pReq->cesaDescBuf.bufVirtPtr =
  19605. + mvOsIoCachedMalloc(osHandle,pReq->cesaDescBuf.bufSize,
  19606. + &pReq->cesaDescBuf.bufPhysAddr,
  19607. + &pReq->cesaDescBuf.memHandle);
  19608. +
  19609. + if(pReq->cesaDescBuf.bufVirtPtr == NULL)
  19610. + {
  19611. + mvOsPrintf("mvCesaInit: req=%d, Can't allocate %d bytes for CESA descriptors\n",
  19612. + req, pReq->cesaDescBuf.bufSize);
  19613. + mvCesaFinish();
  19614. + return MV_NO_RESOURCE;
  19615. + }
  19616. + memset(pReq->cesaDescBuf.bufVirtPtr, 0, pReq->cesaDescBuf.bufSize);
  19617. + pReq->pCesaDesc = (MV_CESA_DESC*)MV_ALIGN_UP((MV_ULONG)pReq->cesaDescBuf.bufVirtPtr,
  19618. + CPU_D_CACHE_LINE_SIZE);
  19619. +
  19620. + pReq->dmaDescBuf.bufSize = sizeof(MV_DMA_DESC)*MV_CESA_MAX_DMA_DESC*MV_CESA_MAX_REQ_FRAGS +
  19621. + CPU_D_CACHE_LINE_SIZE;
  19622. +
  19623. + pReq->dmaDescBuf.bufVirtPtr =
  19624. + mvOsIoCachedMalloc(osHandle,pReq->dmaDescBuf.bufSize,
  19625. + &pReq->dmaDescBuf.bufPhysAddr,
  19626. + &pReq->dmaDescBuf.memHandle);
  19627. +
  19628. + if(pReq->dmaDescBuf.bufVirtPtr == NULL)
  19629. + {
  19630. + mvOsPrintf("mvCesaInit: req=%d, Can't allocate %d bytes for DMA descriptor list\n",
  19631. + req, pReq->dmaDescBuf.bufSize);
  19632. + mvCesaFinish();
  19633. + return MV_NO_RESOURCE;
  19634. + }
  19635. + memset(pReq->dmaDescBuf.bufVirtPtr, 0, pReq->dmaDescBuf.bufSize);
  19636. + pDmaDesc = (MV_DMA_DESC*)MV_ALIGN_UP((MV_ULONG)pReq->dmaDescBuf.bufVirtPtr,
  19637. + CPU_D_CACHE_LINE_SIZE);
  19638. +
  19639. + for(frag=0; frag<MV_CESA_MAX_REQ_FRAGS; frag++)
  19640. + {
  19641. + MV_CESA_DMA* pDma = &pReq->dma[frag];
  19642. +
  19643. + pDma->pDmaFirst = pDmaDesc;
  19644. + pDma->pDmaLast = NULL;
  19645. +
  19646. + for(i=0; i<MV_CESA_MAX_DMA_DESC-1; i++)
  19647. + {
  19648. + /* link all DMA descriptors together */
  19649. + pDma->pDmaFirst[i].phyNextDescPtr =
  19650. + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pDmaDesc[i+1]));
  19651. + }
  19652. + pDma->pDmaFirst[i].phyNextDescPtr = 0;
  19653. + mvOsCacheFlush(NULL, &pDma->pDmaFirst[0], MV_CESA_MAX_DMA_DESC*sizeof(MV_DMA_DESC));
  19654. +
  19655. + pDmaDesc += MV_CESA_MAX_DMA_DESC;
  19656. + }
  19657. + }
  19658. + /*mvCesaCryptoIvSet(NULL, MV_CESA_MAX_IV_LENGTH);*/
  19659. + descOffsetReg = (MV_U16)((MV_U8*)&cesaSramVirtPtr->desc - mvCesaSramAddrGet());
  19660. + MV_REG_WRITE(MV_CESA_CHAN_DESC_OFFSET_REG, descOffsetReg);
  19661. +
  19662. + configReg |= (MV_CESA_CFG_WAIT_DMA_MASK | MV_CESA_CFG_ACT_DMA_MASK);
  19663. +#if (MV_CESA_VERSION >= 3)
  19664. + configReg |= MV_CESA_CFG_CHAIN_MODE_MASK;
  19665. +#endif
  19666. +
  19667. +#if (MV_CESA_VERSION >= 2)
  19668. + /* Initialize TDMA engine */
  19669. + MV_REG_WRITE(MV_CESA_TDMA_CTRL_REG, MV_CESA_TDMA_CTRL_VALUE);
  19670. + MV_REG_WRITE(MV_CESA_TDMA_BYTE_COUNT_REG, 0);
  19671. + MV_REG_WRITE(MV_CESA_TDMA_CURR_DESC_PTR_REG, 0);
  19672. +#else
  19673. + /* Initialize IDMA #0 engine */
  19674. + MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), 0);
  19675. + MV_REG_WRITE(IDMA_BYTE_COUNT_REG(0), 0);
  19676. + MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(0), 0);
  19677. + MV_REG_WRITE(IDMA_CTRL_HIGH_REG(0), ICCHR_ENDIAN_LITTLE
  19678. +#ifdef MV_CPU_LE
  19679. + | ICCHR_DESC_BYTE_SWAP_EN
  19680. +#endif
  19681. + );
  19682. + /* Clear Cause Byte of IDMA channel to be used */
  19683. + MV_REG_WRITE( IDMA_CAUSE_REG, ~ICICR_CAUSE_MASK_ALL(0));
  19684. + MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), MV_CESA_IDMA_CTRL_LOW_VALUE);
  19685. +#endif /* (MV_CESA_VERSION >= 2) */
  19686. +
  19687. + /* Set CESA configuration registers */
  19688. + MV_REG_WRITE( MV_CESA_CFG_REG, configReg);
  19689. + mvCesaDebugStatsClear();
  19690. +
  19691. + return MV_OK;
  19692. +}
  19693. +
  19694. +/*******************************************************************************
  19695. +* mvCesaFinish - Shutdown the CESA driver
  19696. +*
  19697. +* DESCRIPTION:
  19698. +* This function shutdown the CESA driver and free all allocted resources.
  19699. +*
  19700. +* INPUT: None
  19701. +*
  19702. +* RETURN:
  19703. +* MV_OK - Success
  19704. +* Other - Fail
  19705. +*
  19706. +*******************************************************************************/
  19707. +MV_STATUS mvCesaFinish (void)
  19708. +{
  19709. + int req;
  19710. + MV_CESA_REQ* pReq;
  19711. +
  19712. + mvOsPrintf("mvCesaFinish: \n");
  19713. +
  19714. + cesaSramVirtPtr = NULL;
  19715. +
  19716. + /* Free all resources: DMA list, etc. */
  19717. + for(req=0; req<cesaQueueDepth; req++)
  19718. + {
  19719. + pReq = &pCesaReqFirst[req];
  19720. + if(pReq->dmaDescBuf.bufVirtPtr != NULL)
  19721. + {
  19722. + mvOsIoCachedFree(cesaOsHandle,pReq->dmaDescBuf.bufSize,
  19723. + pReq->dmaDescBuf.bufPhysAddr,
  19724. + pReq->dmaDescBuf.bufVirtPtr,
  19725. + pReq->dmaDescBuf.memHandle);
  19726. + }
  19727. + if(pReq->cesaDescBuf.bufVirtPtr != NULL)
  19728. + {
  19729. + mvOsIoCachedFree(cesaOsHandle,pReq->cesaDescBuf.bufSize,
  19730. + pReq->cesaDescBuf.bufPhysAddr,
  19731. + pReq->cesaDescBuf.bufVirtPtr,
  19732. + pReq->cesaDescBuf.memHandle);
  19733. + }
  19734. + }
  19735. +#if (MV_CESA_VERSION < 2)
  19736. + MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), 0);
  19737. +#endif /* (MV_CESA_VERSION < 2) */
  19738. +
  19739. + /* Free request queue */
  19740. + if(pCesaReqFirst != NULL)
  19741. + {
  19742. + mvOsFree(pCesaReqFirst);
  19743. + pCesaReqFirst = pCesaReqLast = NULL;
  19744. + pCesaReqEmpty = pCesaReqProcess = NULL;
  19745. + cesaQueueDepth = cesaReqResources = 0;
  19746. + }
  19747. + /* Free SA database */
  19748. + if(pCesaSAD != NULL)
  19749. + {
  19750. + mvOsFree(pCesaSAD);
  19751. + pCesaSAD = NULL;
  19752. + cesaMaxSA = 0;
  19753. + }
  19754. + MV_REG_WRITE( MV_CESA_CFG_REG, 0);
  19755. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  19756. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
  19757. +
  19758. + return MV_OK;
  19759. +}
  19760. +
  19761. +/*******************************************************************************
  19762. +* mvCesaCryptoIvSet - Set IV value for Crypto algorithm working in CBC mode
  19763. +*
  19764. +* DESCRIPTION:
  19765. +* This function set IV value using by Crypto algorithms in CBC mode.
  19766. +* Each channel has its own IV value.
  19767. +* This function gets IV value from the caller. If no IV value passed from
  19768. +* the caller or only part of IV passed, the function will init the rest part
  19769. +* of IV value (or the whole IV) by random value.
  19770. +*
  19771. +* INPUT:
  19772. +* MV_U8* pIV - Pointer to IV value supplied by user. If pIV==NULL
  19773. +* the function will generate random IV value.
  19774. +* int ivSize - size (in bytes) of IV provided by user. If ivSize is
  19775. +* smaller than maximum IV size, the function will complete
  19776. +* IV by random value.
  19777. +*
  19778. +* RETURN:
  19779. +* MV_OK - Success
  19780. +* Other - Fail
  19781. +*
  19782. +*******************************************************************************/
  19783. +MV_STATUS mvCesaCryptoIvSet(MV_U8* pIV, int ivSize)
  19784. +{
  19785. + MV_U8* pSramIV;
  19786. +#if defined(MV646xx)
  19787. + mvOsPrintf("mvCesaCryptoIvSet: ERR. shouldn't use this call on MV64660\n");
  19788. +#endif
  19789. + pSramIV = cesaSramVirtPtr->cryptoIV;
  19790. + if(ivSize > MV_CESA_MAX_IV_LENGTH)
  19791. + {
  19792. + mvOsPrintf("mvCesaCryptoIvSet: ivSize (%d) is too large\n", ivSize);
  19793. + ivSize = MV_CESA_MAX_IV_LENGTH;
  19794. + }
  19795. + if(pIV != NULL)
  19796. + {
  19797. + memcpy(pSramIV, pIV, ivSize);
  19798. + ivSize = MV_CESA_MAX_IV_LENGTH - ivSize;
  19799. + pSramIV += ivSize;
  19800. + }
  19801. +
  19802. + while(ivSize > 0)
  19803. + {
  19804. + int size, mv_random = mvOsRand();
  19805. +
  19806. + size = MV_MIN(ivSize, sizeof(mv_random));
  19807. + memcpy(pSramIV, (void*)&mv_random, size);
  19808. +
  19809. + pSramIV += size;
  19810. + ivSize -= size;
  19811. + }
  19812. +/*
  19813. + mvOsCacheFlush(NULL, cesaSramVirtPtr->cryptoIV,
  19814. + MV_CESA_MAX_IV_LENGTH);
  19815. + mvOsCacheInvalidate(NULL, cesaSramVirtPtr->cryptoIV,
  19816. + MV_CESA_MAX_IV_LENGTH);
  19817. +*/
  19818. + return MV_OK;
  19819. +}
  19820. +
  19821. +/*******************************************************************************
  19822. +* mvCesaSessionOpen - Open new uni-directional crypto session
  19823. +*
  19824. +* DESCRIPTION:
  19825. +* This function open new session.
  19826. +*
  19827. +* INPUT:
  19828. +* MV_CESA_OPEN_SESSION *pSession - pointer to new session input parameters
  19829. +*
  19830. +* OUTPUT:
  19831. +* short *pSid - session ID, should be used for all future
  19832. +* requests over this session.
  19833. +*
  19834. +* RETURN:
  19835. +* MV_OK - Session opend successfully.
  19836. +* MV_FULL - All sessions are in use, no free place in
  19837. +* SA database.
  19838. +* MV_BAD_PARAM - One of session input parameters is invalid.
  19839. +*
  19840. +*******************************************************************************/
  19841. +MV_STATUS mvCesaSessionOpen(MV_CESA_OPEN_SESSION *pSession, short* pSid)
  19842. +{
  19843. + short sid;
  19844. + MV_U32 config = 0;
  19845. + int digestSize;
  19846. +
  19847. + cesaStats.openedCount++;
  19848. +
  19849. + /* Find free entry in SAD */
  19850. + for(sid=0; sid<cesaMaxSA; sid++)
  19851. + {
  19852. + if(pCesaSAD[sid].valid == 0)
  19853. + {
  19854. + break;
  19855. + }
  19856. + }
  19857. + if(sid == cesaMaxSA)
  19858. + {
  19859. + mvOsPrintf("mvCesaSessionOpen: SA Database is FULL\n");
  19860. + return MV_FULL;
  19861. + }
  19862. +
  19863. + /* Check Input parameters for Open session */
  19864. + if (pSession->operation >= MV_CESA_MAX_OPERATION)
  19865. + {
  19866. + mvOsPrintf("mvCesaSessionOpen: Unexpected operation %d\n",
  19867. + pSession->operation);
  19868. + return MV_BAD_PARAM;
  19869. + }
  19870. + config |= (pSession->operation << MV_CESA_OPERATION_OFFSET);
  19871. +
  19872. + if( (pSession->direction != MV_CESA_DIR_ENCODE) &&
  19873. + (pSession->direction != MV_CESA_DIR_DECODE) )
  19874. + {
  19875. + mvOsPrintf("mvCesaSessionOpen: Unexpected direction %d\n",
  19876. + pSession->direction);
  19877. + return MV_BAD_PARAM;
  19878. + }
  19879. + config |= (pSession->direction << MV_CESA_DIRECTION_BIT);
  19880. + /* Clear SA entry */
  19881. + /* memset(&pCesaSAD[sid], 0, sizeof(pCesaSAD[sid])); */
  19882. +
  19883. + /* Check AUTH parameters and update SA entry */
  19884. + if(pSession->operation != MV_CESA_CRYPTO_ONLY)
  19885. + {
  19886. + /* For HMAC (MD5 and SHA1) - Maximum Key size is 64 bytes */
  19887. + if( (pSession->macMode == MV_CESA_MAC_HMAC_MD5) ||
  19888. + (pSession->macMode == MV_CESA_MAC_HMAC_SHA1) )
  19889. + {
  19890. + if(pSession->macKeyLength > MV_CESA_MAX_MAC_KEY_LENGTH)
  19891. + {
  19892. + mvOsPrintf("mvCesaSessionOpen: macKeyLength %d is too large\n",
  19893. + pSession->macKeyLength);
  19894. + return MV_BAD_PARAM;
  19895. + }
  19896. + mvCesaHmacIvGet(pSession->macMode, pSession->macKey, pSession->macKeyLength,
  19897. + pCesaSAD[sid].pSramSA->macInnerIV,
  19898. + pCesaSAD[sid].pSramSA->macOuterIV);
  19899. + pCesaSAD[sid].macKeyLength = pSession->macKeyLength;
  19900. + }
  19901. + switch(pSession->macMode)
  19902. + {
  19903. + case MV_CESA_MAC_MD5:
  19904. + case MV_CESA_MAC_HMAC_MD5:
  19905. + digestSize = MV_CESA_MD5_DIGEST_SIZE;
  19906. + break;
  19907. +
  19908. + case MV_CESA_MAC_SHA1:
  19909. + case MV_CESA_MAC_HMAC_SHA1:
  19910. + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
  19911. + break;
  19912. +
  19913. + default:
  19914. + mvOsPrintf("mvCesaSessionOpen: Unexpected macMode %d\n",
  19915. + pSession->macMode);
  19916. + return MV_BAD_PARAM;
  19917. + }
  19918. + config |= (pSession->macMode << MV_CESA_MAC_MODE_OFFSET);
  19919. +
  19920. + /* Supported digest sizes: MD5 - 16 bytes (128 bits), */
  19921. + /* SHA1 - 20 bytes (160 bits) or 12 bytes (96 bits) for both */
  19922. + if( (pSession->digestSize != digestSize) && (pSession->digestSize != 12))
  19923. + {
  19924. + mvOsPrintf("mvCesaSessionOpen: Unexpected digest size %d\n",
  19925. + pSession->digestSize);
  19926. + mvOsPrintf("\t Valid values [bytes]: MD5-16, SHA1-20, Both-12\n");
  19927. + return MV_BAD_PARAM;
  19928. + }
  19929. + pCesaSAD[sid].digestSize = pSession->digestSize;
  19930. +
  19931. + if(pCesaSAD[sid].digestSize == 12)
  19932. + {
  19933. + /* Set MV_CESA_MAC_DIGEST_SIZE_BIT if digest size is 96 bits */
  19934. + config |= (MV_CESA_MAC_DIGEST_96B << MV_CESA_MAC_DIGEST_SIZE_BIT);
  19935. + }
  19936. + }
  19937. +
  19938. + /* Check CRYPTO parameters and update SA entry */
  19939. + if(pSession->operation != MV_CESA_MAC_ONLY)
  19940. + {
  19941. + switch(pSession->cryptoAlgorithm)
  19942. + {
  19943. + case MV_CESA_CRYPTO_DES:
  19944. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_DES_KEY_LENGTH;
  19945. + pCesaSAD[sid].cryptoBlockSize = MV_CESA_DES_BLOCK_SIZE;
  19946. + break;
  19947. +
  19948. + case MV_CESA_CRYPTO_3DES:
  19949. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_3DES_KEY_LENGTH;
  19950. + pCesaSAD[sid].cryptoBlockSize = MV_CESA_DES_BLOCK_SIZE;
  19951. + /* Only EDE mode is supported */
  19952. + config |= (MV_CESA_CRYPTO_3DES_EDE <<
  19953. + MV_CESA_CRYPTO_3DES_MODE_BIT);
  19954. + break;
  19955. +
  19956. + case MV_CESA_CRYPTO_AES:
  19957. + switch(pSession->cryptoKeyLength)
  19958. + {
  19959. + case 16:
  19960. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_128_KEY_LENGTH;
  19961. + config |= (MV_CESA_CRYPTO_AES_KEY_128 <<
  19962. + MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);
  19963. + break;
  19964. +
  19965. + case 24:
  19966. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_192_KEY_LENGTH;
  19967. + config |= (MV_CESA_CRYPTO_AES_KEY_192 <<
  19968. + MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);
  19969. + break;
  19970. +
  19971. + case 32:
  19972. + default:
  19973. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_256_KEY_LENGTH;
  19974. + config |= (MV_CESA_CRYPTO_AES_KEY_256 <<
  19975. + MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);
  19976. + break;
  19977. + }
  19978. + pCesaSAD[sid].cryptoBlockSize = MV_CESA_AES_BLOCK_SIZE;
  19979. + break;
  19980. +
  19981. + default:
  19982. + mvOsPrintf("mvCesaSessionOpen: Unexpected cryptoAlgorithm %d\n",
  19983. + pSession->cryptoAlgorithm);
  19984. + return MV_BAD_PARAM;
  19985. + }
  19986. + config |= (pSession->cryptoAlgorithm << MV_CESA_CRYPTO_ALG_OFFSET);
  19987. +
  19988. + if(pSession->cryptoKeyLength != pCesaSAD[sid].cryptoKeyLength)
  19989. + {
  19990. + mvOsPrintf("cesaSessionOpen: Wrong CryptoKeySize %d != %d\n",
  19991. + pSession->cryptoKeyLength, pCesaSAD[sid].cryptoKeyLength);
  19992. + return MV_BAD_PARAM;
  19993. + }
  19994. +
  19995. + /* Copy Crypto key */
  19996. + if( (pSession->cryptoAlgorithm == MV_CESA_CRYPTO_AES) &&
  19997. + (pSession->direction == MV_CESA_DIR_DECODE))
  19998. + {
  19999. + /* Crypto Key for AES decode is computed from original key material */
  20000. + /* and depend on cryptoKeyLength (128/192/256 bits) */
  20001. + aesMakeKey(pCesaSAD[sid].pSramSA->cryptoKey, pSession->cryptoKey,
  20002. + pSession->cryptoKeyLength*8, MV_CESA_AES_BLOCK_SIZE*8);
  20003. + }
  20004. + else
  20005. + {
  20006. + /*panic("mvCesaSessionOpen2");*/
  20007. + memcpy(pCesaSAD[sid].pSramSA->cryptoKey, pSession->cryptoKey,
  20008. + pCesaSAD[sid].cryptoKeyLength);
  20009. +
  20010. + }
  20011. +
  20012. + switch(pSession->cryptoMode)
  20013. + {
  20014. + case MV_CESA_CRYPTO_ECB:
  20015. + pCesaSAD[sid].cryptoIvSize = 0;
  20016. + break;
  20017. +
  20018. + case MV_CESA_CRYPTO_CBC:
  20019. + pCesaSAD[sid].cryptoIvSize = pCesaSAD[sid].cryptoBlockSize;
  20020. + break;
  20021. +
  20022. + case MV_CESA_CRYPTO_CTR:
  20023. + /* Supported only for AES algorithm */
  20024. + if(pSession->cryptoAlgorithm != MV_CESA_CRYPTO_AES)
  20025. + {
  20026. + mvOsPrintf("mvCesaSessionOpen: CRYPTO CTR mode supported for AES only\n");
  20027. + return MV_BAD_PARAM;
  20028. + }
  20029. + pCesaSAD[sid].cryptoIvSize = 0;
  20030. + pCesaSAD[sid].ctrMode = 1;
  20031. + /* Replace to ECB mode for HW */
  20032. + pSession->cryptoMode = MV_CESA_CRYPTO_ECB;
  20033. + break;
  20034. +
  20035. + default:
  20036. + mvOsPrintf("mvCesaSessionOpen: Unexpected cryptoMode %d\n",
  20037. + pSession->cryptoMode);
  20038. + return MV_BAD_PARAM;
  20039. + }
  20040. +
  20041. + config |= (pSession->cryptoMode << MV_CESA_CRYPTO_MODE_BIT);
  20042. + }
  20043. + pCesaSAD[sid].config = config;
  20044. +
  20045. + mvOsCacheFlush(NULL, pCesaSAD[sid].pSramSA, sizeof(MV_CESA_SRAM_SA));
  20046. + if(pSid != NULL)
  20047. + *pSid = sid;
  20048. +
  20049. + pCesaSAD[sid].valid = 1;
  20050. + return MV_OK;
  20051. +}
  20052. +
  20053. +/*******************************************************************************
  20054. +* mvCesaSessionClose - Close active crypto session
  20055. +*
  20056. +* DESCRIPTION:
  20057. +* This function closes existing session
  20058. +*
  20059. +* INPUT:
  20060. +* short sid - Unique identifier of the session to be closed
  20061. +*
  20062. +* RETURN:
  20063. +* MV_OK - Session closed successfully.
  20064. +* MV_BAD_PARAM - Session identifier is out of valid range.
  20065. +* MV_NOT_FOUND - There is no active session with such ID.
  20066. +*
  20067. +*******************************************************************************/
  20068. +MV_STATUS mvCesaSessionClose(short sid)
  20069. +{
  20070. + cesaStats.closedCount++;
  20071. +
  20072. + if(sid >= cesaMaxSA)
  20073. + {
  20074. + mvOsPrintf("CESA Error: sid (%d) is too big\n", sid);
  20075. + return MV_BAD_PARAM;
  20076. + }
  20077. + if(pCesaSAD[sid].valid == 0)
  20078. + {
  20079. + mvOsPrintf("CESA Warning: Session (sid=%d) is invalid\n", sid);
  20080. + return MV_NOT_FOUND;
  20081. + }
  20082. + if(cesaLastSid == sid)
  20083. + cesaLastSid = -1;
  20084. +
  20085. + pCesaSAD[sid].valid = 0;
  20086. + return MV_OK;
  20087. +}
  20088. +
  20089. +/*******************************************************************************
  20090. +* mvCesaAction - Perform crypto operation
  20091. +*
  20092. +* DESCRIPTION:
  20093. +* This function set new CESA request FIFO queue for further HW processing.
  20094. +* The function checks request parameters before set new request to the queue.
  20095. +* If one of the CESA channels is ready for processing the request will be
  20096. +* passed to HW. When request processing is finished the CESA interrupt will
  20097. +* be generated by HW. The caller should call mvCesaReadyGet() function to
  20098. +* complete request processing and get result.
  20099. +*
  20100. +* INPUT:
  20101. +* MV_CESA_COMMAND *pCmd - pointer to new CESA request.
  20102. +* It includes pointers to Source and Destination
  20103. +* buffers, session identifier get from
  20104. +* mvCesaSessionOpen() function, pointer to caller
  20105. +* private data and all needed crypto parameters.
  20106. +*
  20107. +* RETURN:
  20108. +* MV_OK - request successfully added to request queue
  20109. +* and will be processed.
  20110. +* MV_NO_MORE - request successfully added to request queue and will
  20111. +* be processed, but request queue became Full and next
  20112. +* request will not be accepted.
  20113. +* MV_NO_RESOURCE - request queue is FULL and the request can not
  20114. +* be processed.
  20115. +* MV_OUT_OF_CPU_MEM - memory allocation needed for request processing is
  20116. +* failed. Request can not be processed.
  20117. +* MV_NOT_ALLOWED - This mixed request (CRYPTO+MAC) can not be processed
  20118. +* as one request and should be splitted for two requests:
  20119. +* CRYPTO_ONLY and MAC_ONLY.
  20120. +* MV_BAD_PARAM - One of the request parameters is out of valid range.
  20121. +* The request can not be processed.
  20122. +*
  20123. +*******************************************************************************/
  20124. +MV_STATUS mvCesaAction (MV_CESA_COMMAND *pCmd)
  20125. +{
  20126. + MV_STATUS status;
  20127. + MV_CESA_REQ* pReq = pCesaReqEmpty;
  20128. + int sid = pCmd->sessionId;
  20129. + MV_CESA_SA* pSA = &pCesaSAD[sid];
  20130. +#if (MV_CESA_VERSION >= 3)
  20131. + MV_CESA_REQ* pFromReq;
  20132. + MV_CESA_REQ* pToReq;
  20133. +#endif
  20134. + cesaStats.reqCount++;
  20135. +
  20136. + /* Check that the request queue is not FULL */
  20137. + if(cesaReqResources == 0)
  20138. + return MV_NO_RESOURCE;
  20139. +
  20140. + if( (sid >= cesaMaxSA) || (!pSA->valid) )
  20141. + {
  20142. + mvOsPrintf("CESA Action Error: Session sid=%d is INVALID\n", sid);
  20143. + return MV_BAD_PARAM;
  20144. + }
  20145. + pSA->count++;
  20146. +
  20147. + if(pSA->ctrMode)
  20148. + {
  20149. + /* AES in CTR mode can't be mixed with Authentication */
  20150. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  20151. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  20152. + {
  20153. + mvOsPrintf("mvCesaAction : CRYPTO CTR mode can't be mixed with AUTH\n");
  20154. + return MV_NOT_ALLOWED;
  20155. + }
  20156. + /* All other request parameters should not be checked because key stream */
  20157. + /* (not user data) processed by AES HW engine */
  20158. + pReq->pOrgCmd = pCmd;
  20159. + /* Allocate temporary pCmd structure for Key stream */
  20160. + pCmd = mvCesaCtrModeInit();
  20161. + if(pCmd == NULL)
  20162. + return MV_OUT_OF_CPU_MEM;
  20163. +
  20164. + /* Prepare Key stream */
  20165. + mvCesaCtrModePrepare(pCmd, pReq->pOrgCmd);
  20166. + pReq->fixOffset = 0;
  20167. + }
  20168. + else
  20169. + {
  20170. + /* Check request parameters and calculae fixOffset */
  20171. + status = mvCesaParamCheck(pSA, pCmd, &pReq->fixOffset);
  20172. + if(status != MV_OK)
  20173. + {
  20174. + return status;
  20175. + }
  20176. + }
  20177. + pReq->pCmd = pCmd;
  20178. +
  20179. + /* Check if the packet need fragmentation */
  20180. + if(pCmd->pSrc->mbufSize <= sizeof(cesaSramVirtPtr->buf) )
  20181. + {
  20182. + /* request size is smaller than single buffer size */
  20183. + pReq->fragMode = MV_CESA_FRAG_NONE;
  20184. +
  20185. + /* Prepare NOT fragmented packets */
  20186. + status = mvCesaReqProcess(pReq);
  20187. + if(status != MV_OK)
  20188. + {
  20189. + mvOsPrintf("CesaReady: ReqProcess error: pReq=%p, status=0x%x\n",
  20190. + pReq, status);
  20191. + }
  20192. +#if (MV_CESA_VERSION >= 3)
  20193. + pReq->frags.numFrag = 1;
  20194. +#endif
  20195. + }
  20196. + else
  20197. + {
  20198. + MV_U8 frag = 0;
  20199. +
  20200. + /* request size is larger than buffer size - needs fragmentation */
  20201. +
  20202. + /* Check restrictions for processing fragmented packets */
  20203. + status = mvCesaFragParamCheck(pSA, pCmd);
  20204. + if(status != MV_OK)
  20205. + return status;
  20206. +
  20207. + pReq->fragMode = MV_CESA_FRAG_FIRST;
  20208. + pReq->frags.nextFrag = 0;
  20209. +
  20210. + /* Prepare Process Fragmented packets */
  20211. + while(pReq->fragMode != MV_CESA_FRAG_LAST)
  20212. + {
  20213. + if(frag >= MV_CESA_MAX_REQ_FRAGS)
  20214. + {
  20215. + mvOsPrintf("mvCesaAction Error: Too large request frag=%d\n", frag);
  20216. + return MV_OUT_OF_CPU_MEM;
  20217. + }
  20218. + status = mvCesaFragReqProcess(pReq, frag);
  20219. + if(status == MV_OK) {
  20220. +#if (MV_CESA_VERSION >= 3)
  20221. + if(frag) {
  20222. + pReq->dma[frag-1].pDmaLast->phyNextDescPtr =
  20223. + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));
  20224. + mvOsCacheFlush(NULL, pReq->dma[frag-1].pDmaLast, sizeof(MV_DMA_DESC));
  20225. + }
  20226. +#endif
  20227. + frag++;
  20228. + }
  20229. + }
  20230. + pReq->frags.numFrag = frag;
  20231. +#if (MV_CESA_VERSION >= 3)
  20232. + if(chainReqNum) {
  20233. + chainReqNum += pReq->frags.numFrag;
  20234. + if(chainReqNum >= MAX_CESA_CHAIN_LENGTH)
  20235. + chainReqNum = MAX_CESA_CHAIN_LENGTH;
  20236. + }
  20237. +#endif
  20238. + }
  20239. +
  20240. + pReq->state = MV_CESA_PENDING;
  20241. +
  20242. + pCesaReqEmpty = MV_CESA_REQ_NEXT_PTR(pReq);
  20243. + cesaReqResources -= 1;
  20244. +
  20245. +/* #ifdef CESA_DEBUG */
  20246. + if( (cesaQueueDepth - cesaReqResources) > cesaStats.maxReqCount)
  20247. + cesaStats.maxReqCount = (cesaQueueDepth - cesaReqResources);
  20248. +/* #endif CESA_DEBUG */
  20249. +
  20250. + cesaLastSid = sid;
  20251. +
  20252. +#if (MV_CESA_VERSION >= 3)
  20253. + /* Are we within chain bounderies and follows the first request ? */
  20254. + if((chainReqNum > 0) && (chainReqNum < MAX_CESA_CHAIN_LENGTH)) {
  20255. + if(chainIndex) {
  20256. + pFromReq = MV_CESA_REQ_PREV_PTR(pReq);
  20257. + pToReq = pReq;
  20258. + pReq->state = MV_CESA_CHAIN;
  20259. + /* assume concatenating is possible */
  20260. + pFromReq->dma[pFromReq->frags.numFrag-1].pDmaLast->phyNextDescPtr =
  20261. + MV_32BIT_LE(mvCesaVirtToPhys(&pToReq->dmaDescBuf, pToReq->dma[0].pDmaFirst));
  20262. + mvOsCacheFlush(NULL, pFromReq->dma[pFromReq->frags.numFrag-1].pDmaLast, sizeof(MV_DMA_DESC));
  20263. +
  20264. + /* align active & next pointers */
  20265. + if(pNextActiveChain->state != MV_CESA_PENDING)
  20266. + pEndCurrChain = pNextActiveChain = MV_CESA_REQ_NEXT_PTR(pReq);
  20267. + }
  20268. + else { /* we have only one chain, start new one */
  20269. + chainReqNum = 0;
  20270. + chainIndex++;
  20271. + /* align active & next pointers */
  20272. + if(pNextActiveChain->state != MV_CESA_PENDING)
  20273. + pEndCurrChain = pNextActiveChain = pReq;
  20274. + }
  20275. + }
  20276. + else {
  20277. + /* In case we concatenate full chain */
  20278. + if(chainReqNum == MAX_CESA_CHAIN_LENGTH) {
  20279. + chainIndex++;
  20280. + if(pNextActiveChain->state != MV_CESA_PENDING)
  20281. + pEndCurrChain = pNextActiveChain = pReq;
  20282. + chainReqNum = 0;
  20283. + }
  20284. +
  20285. + pReq = pCesaReqProcess;
  20286. + if(pReq->state == MV_CESA_PENDING) {
  20287. + pNextActiveChain = pReq;
  20288. + pEndCurrChain = MV_CESA_REQ_NEXT_PTR(pReq);
  20289. + /* Start Process new request */
  20290. + mvCesaReqProcessStart(pReq);
  20291. + }
  20292. + }
  20293. +
  20294. + chainReqNum++;
  20295. +
  20296. + if((chainIndex < MAX_CESA_CHAIN_LENGTH) && (chainReqNum > cesaStats.maxChainUsage))
  20297. + cesaStats.maxChainUsage = chainReqNum;
  20298. +
  20299. +#else
  20300. +
  20301. + /* Check status of CESA channels and process requests if possible */
  20302. + pReq = pCesaReqProcess;
  20303. + if(pReq->state == MV_CESA_PENDING)
  20304. + {
  20305. + /* Start Process new request */
  20306. + mvCesaReqProcessStart(pReq);
  20307. + }
  20308. +#endif
  20309. + /* If request queue became FULL - return MV_NO_MORE */
  20310. + if(cesaReqResources == 0)
  20311. + return MV_NO_MORE;
  20312. +
  20313. + return MV_OK;
  20314. +
  20315. +}
  20316. +
  20317. +/*******************************************************************************
  20318. +* mvCesaReadyGet - Get crypto request that processing is finished
  20319. +*
  20320. +* DESCRIPTION:
  20321. +* This function complete request processing and return ready request to
  20322. +* caller. To don't miss interrupts the caller must call this function
  20323. +* while MV_OK or MV_TERMINATE values returned.
  20324. +*
  20325. +* INPUT:
  20326. +* MV_U32 chanMap - map of CESA channels finished thier job
  20327. +* accordingly with CESA Cause register.
  20328. +* MV_CESA_RESULT* pResult - pointer to structure contains information
  20329. +* about ready request. It includes pointer to
  20330. +* user private structure "pReqPrv", session identifier
  20331. +* for this request "sessionId" and return code.
  20332. +* Return code set to MV_FAIL if calculated digest value
  20333. +* on decode direction is different than digest value
  20334. +* in the packet.
  20335. +*
  20336. +* RETURN:
  20337. +* MV_OK - Success, ready request is returned.
  20338. +* MV_NOT_READY - Next request is not ready yet. New interrupt will
  20339. +* be generated for futher request processing.
  20340. +* MV_EMPTY - There is no more request for processing.
  20341. +* MV_BUSY - Fragmented request is not ready yet.
  20342. +* MV_TERMINATE - Call this function once more to complete processing
  20343. +* of fragmented request.
  20344. +*
  20345. +*******************************************************************************/
  20346. +MV_STATUS mvCesaReadyGet(MV_CESA_RESULT* pResult)
  20347. +{
  20348. + MV_STATUS status, readyStatus = MV_NOT_READY;
  20349. + MV_U32 statusReg;
  20350. + MV_CESA_REQ* pReq;
  20351. + MV_CESA_SA* pSA;
  20352. +
  20353. +#if (MV_CESA_VERSION >= 3)
  20354. + if(isFirstReq == MV_TRUE) {
  20355. + if(chainIndex == 0)
  20356. + chainReqNum = 0;
  20357. +
  20358. + isFirstReq = MV_FALSE;
  20359. +
  20360. + if(pNextActiveChain->state == MV_CESA_PENDING) {
  20361. + /* Start request Process */
  20362. + mvCesaReqProcessStart(pNextActiveChain);
  20363. + pEndCurrChain = pNextActiveChain;
  20364. + if(chainIndex > 0)
  20365. + chainIndex--;
  20366. + /* Update pNextActiveChain to next chain head */
  20367. + while(pNextActiveChain->state == MV_CESA_CHAIN)
  20368. + pNextActiveChain = MV_CESA_REQ_NEXT_PTR(pNextActiveChain);
  20369. + }
  20370. + }
  20371. +
  20372. + /* Check if there are more processed requests - can we remove pEndCurrChain ??? */
  20373. + if(pCesaReqProcess == pEndCurrChain) {
  20374. + isFirstReq = MV_TRUE;
  20375. + pEndCurrChain = pNextActiveChain;
  20376. +#else
  20377. + if(pCesaReqProcess->state != MV_CESA_PROCESS) {
  20378. +#endif
  20379. + return MV_EMPTY;
  20380. + }
  20381. +
  20382. +#ifdef CESA_DEBUG
  20383. + statusReg = MV_REG_READ(MV_CESA_STATUS_REG);
  20384. + if( statusReg & MV_CESA_STATUS_ACTIVE_MASK )
  20385. + {
  20386. + mvOsPrintf("mvCesaReadyGet: Not Ready, Status = 0x%x\n", statusReg);
  20387. + cesaStats.notReadyCount++;
  20388. + return MV_NOT_READY;
  20389. + }
  20390. +#endif /* CESA_DEBUG */
  20391. +
  20392. + cesaStats.readyCount++;
  20393. +
  20394. + pReq = pCesaReqProcess;
  20395. + pSA = &pCesaSAD[pReq->pCmd->sessionId];
  20396. +
  20397. + pResult->retCode = MV_OK;
  20398. + if(pReq->fragMode != MV_CESA_FRAG_NONE)
  20399. + {
  20400. + MV_U8* pNewDigest;
  20401. + int frag;
  20402. +#if (MV_CESA_VERSION >= 3)
  20403. + pReq->frags.nextFrag = 1;
  20404. + while(pReq->frags.nextFrag <= pReq->frags.numFrag) {
  20405. +#endif
  20406. + frag = (pReq->frags.nextFrag - 1);
  20407. +
  20408. + /* Restore DMA descriptor list */
  20409. + pReq->dma[frag].pDmaLast->phyNextDescPtr =
  20410. + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pReq->dma[frag].pDmaLast[1]));
  20411. + pReq->dma[frag].pDmaLast = NULL;
  20412. +
  20413. + /* Special processing for finished fragmented request */
  20414. + if(pReq->frags.nextFrag >= pReq->frags.numFrag)
  20415. + {
  20416. + mvCesaMbufCacheUnmap(pReq->pCmd->pDst, 0, pReq->pCmd->pDst->mbufSize);
  20417. +
  20418. + /* Fragmented packet is ready */
  20419. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  20420. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  20421. + {
  20422. + int macDataSize = pReq->pCmd->macLength - pReq->frags.macSize;
  20423. +
  20424. + if(macDataSize != 0)
  20425. + {
  20426. + /* Calculate all other blocks by SW */
  20427. + mvCesaFragAuthComplete(pReq, pSA, macDataSize);
  20428. + }
  20429. +
  20430. + /* Copy new digest from SRAM to the Destination buffer */
  20431. + pNewDigest = cesaSramVirtPtr->buf + pReq->frags.newDigestOffset;
  20432. + status = mvCesaCopyToMbuf(pNewDigest, pReq->pCmd->pDst,
  20433. + pReq->pCmd->digestOffset, pSA->digestSize);
  20434. +
  20435. + /* For decryption: Compare new digest value with original one */
  20436. + if((pSA->config & MV_CESA_DIRECTION_MASK) ==
  20437. + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))
  20438. + {
  20439. + if( memcmp(pNewDigest, pReq->frags.orgDigest, pSA->digestSize) != 0)
  20440. + {
  20441. +/*
  20442. + mvOsPrintf("Digest error: chan=%d, newDigest=%p, orgDigest=%p, status = 0x%x\n",
  20443. + chan, pNewDigest, pReq->frags.orgDigest, MV_REG_READ(MV_CESA_STATUS_REG));
  20444. +*/
  20445. + /* Signiture verification is failed */
  20446. + pResult->retCode = MV_FAIL;
  20447. + }
  20448. + }
  20449. + }
  20450. + readyStatus = MV_OK;
  20451. + }
  20452. +#if (MV_CESA_VERSION >= 3)
  20453. + pReq->frags.nextFrag++;
  20454. + }
  20455. +#endif
  20456. + }
  20457. + else
  20458. + {
  20459. + mvCesaMbufCacheUnmap(pReq->pCmd->pDst, 0, pReq->pCmd->pDst->mbufSize);
  20460. +
  20461. + /* Restore DMA descriptor list */
  20462. + pReq->dma[0].pDmaLast->phyNextDescPtr =
  20463. + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pReq->dma[0].pDmaLast[1]));
  20464. + pReq->dma[0].pDmaLast = NULL;
  20465. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  20466. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) ) &&
  20467. + ((pSA->config & MV_CESA_DIRECTION_MASK) ==
  20468. + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT)) )
  20469. + {
  20470. + /* For AUTH on decode : Check Digest result in Status register */
  20471. + statusReg = MV_REG_READ(MV_CESA_STATUS_REG);
  20472. + if(statusReg & MV_CESA_STATUS_DIGEST_ERR_MASK)
  20473. + {
  20474. +/*
  20475. + mvOsPrintf("Digest error: chan=%d, status = 0x%x\n",
  20476. + chan, statusReg);
  20477. +*/
  20478. + /* Signiture verification is failed */
  20479. + pResult->retCode = MV_FAIL;
  20480. + }
  20481. + }
  20482. + readyStatus = MV_OK;
  20483. + }
  20484. +
  20485. + if(readyStatus == MV_OK)
  20486. + {
  20487. + /* If Request is ready - Prepare pResult structure */
  20488. + pResult->pReqPrv = pReq->pCmd->pReqPrv;
  20489. + pResult->sessionId = pReq->pCmd->sessionId;
  20490. +
  20491. + pReq->state = MV_CESA_IDLE;
  20492. + pCesaReqProcess = MV_CESA_REQ_NEXT_PTR(pReq);
  20493. + cesaReqResources++;
  20494. +
  20495. + if(pSA->ctrMode)
  20496. + {
  20497. + /* For AES CTR mode - complete processing and free allocated resources */
  20498. + mvCesaCtrModeComplete(pReq->pOrgCmd, pReq->pCmd);
  20499. + mvCesaCtrModeFinish(pReq->pCmd);
  20500. + pReq->pOrgCmd = NULL;
  20501. + }
  20502. + }
  20503. +
  20504. +#if (MV_CESA_VERSION < 3)
  20505. + if(pCesaReqProcess->state == MV_CESA_PROCESS)
  20506. + {
  20507. + /* Start request Process */
  20508. + mvCesaReqProcessStart(pCesaReqProcess);
  20509. + if(readyStatus == MV_NOT_READY)
  20510. + readyStatus = MV_BUSY;
  20511. + }
  20512. + else if(pCesaReqProcess != pCesaReqEmpty)
  20513. + {
  20514. + /* Start process new request from the queue */
  20515. + mvCesaReqProcessStart(pCesaReqProcess);
  20516. + }
  20517. +#endif
  20518. + return readyStatus;
  20519. +}
  20520. +
  20521. +/***************** Functions to work with CESA_MBUF structure ******************/
  20522. +
  20523. +/*******************************************************************************
  20524. +* mvCesaMbufOffset - Locate offset in the Mbuf structure
  20525. +*
  20526. +* DESCRIPTION:
  20527. +* This function locates offset inside Multi-Bufeer structure.
  20528. +* It get fragment number and place in the fragment where the offset
  20529. +* is located.
  20530. +*
  20531. +*
  20532. +* INPUT:
  20533. +* MV_CESA_MBUF* pMbuf - Pointer to multi-buffer structure
  20534. +* int offset - Offset from the beginning of the data presented by
  20535. +* the Mbuf structure.
  20536. +*
  20537. +* OUTPUT:
  20538. +* int* pBufOffset - Offset from the beginning of the fragment where
  20539. +* the offset is located.
  20540. +*
  20541. +* RETURN:
  20542. +* int - Number of fragment, where the offset is located\
  20543. +*
  20544. +*******************************************************************************/
  20545. +int mvCesaMbufOffset(MV_CESA_MBUF* pMbuf, int offset, int* pBufOffset)
  20546. +{
  20547. + int frag = 0;
  20548. +
  20549. + while(offset > 0)
  20550. + {
  20551. + if(frag >= pMbuf->numFrags)
  20552. + {
  20553. + mvOsPrintf("mvCesaMbufOffset: Error: frag (%d) > numFrags (%d)\n",
  20554. + frag, pMbuf->numFrags);
  20555. + return MV_INVALID;
  20556. + }
  20557. + if(offset < pMbuf->pFrags[frag].bufSize)
  20558. + {
  20559. + break;
  20560. + }
  20561. + offset -= pMbuf->pFrags[frag].bufSize;
  20562. + frag++;
  20563. + }
  20564. + if(pBufOffset != NULL)
  20565. + *pBufOffset = offset;
  20566. +
  20567. + return frag;
  20568. +}
  20569. +
  20570. +/*******************************************************************************
  20571. +* mvCesaCopyFromMbuf - Copy data from the Mbuf structure to continuous buffer
  20572. +*
  20573. +* DESCRIPTION:
  20574. +*
  20575. +*
  20576. +* INPUT:
  20577. +* MV_U8* pDstBuf - Pointer to continuous buffer, where data is
  20578. +* copied to.
  20579. +* MV_CESA_MBUF* pSrcMbuf - Pointer to multi-buffer structure where data is
  20580. +* copied from.
  20581. +* int offset - Offset in the Mbuf structure where located first
  20582. +* byte of data should be copied.
  20583. +* int size - Size of data should be copied
  20584. +*
  20585. +* RETURN:
  20586. +* MV_OK - Success, all data is copied successfully.
  20587. +* MV_OUT_OF_RANGE - Failed, offset is out of Multi-buffer data range.
  20588. +* No data is copied.
  20589. +* MV_EMPTY - Multi-buffer structure has not enough data to copy
  20590. +* Data from the offset to end of Mbuf data is copied.
  20591. +*
  20592. +*******************************************************************************/
  20593. +MV_STATUS mvCesaCopyFromMbuf(MV_U8* pDstBuf, MV_CESA_MBUF* pSrcMbuf,
  20594. + int offset, int size)
  20595. +{
  20596. + int frag, fragOffset, bufSize;
  20597. + MV_U8* pBuf;
  20598. +
  20599. + if(size == 0)
  20600. + return MV_OK;
  20601. +
  20602. + frag = mvCesaMbufOffset(pSrcMbuf, offset, &fragOffset);
  20603. + if(frag == MV_INVALID)
  20604. + {
  20605. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  20606. + return MV_OUT_OF_RANGE;
  20607. + }
  20608. +
  20609. + bufSize = pSrcMbuf->pFrags[frag].bufSize - fragOffset;
  20610. + pBuf = pSrcMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  20611. + while(MV_TRUE)
  20612. + {
  20613. + if(size <= bufSize)
  20614. + {
  20615. + memcpy(pDstBuf, pBuf, size);
  20616. + return MV_OK;
  20617. + }
  20618. + memcpy(pDstBuf, pBuf, bufSize);
  20619. + size -= bufSize;
  20620. + frag++;
  20621. + pDstBuf += bufSize;
  20622. + if(frag >= pSrcMbuf->numFrags)
  20623. + break;
  20624. +
  20625. + bufSize = pSrcMbuf->pFrags[frag].bufSize;
  20626. + pBuf = pSrcMbuf->pFrags[frag].bufVirtPtr;
  20627. + }
  20628. + mvOsPrintf("mvCesaCopyFromMbuf: Mbuf is EMPTY - %d bytes isn't copied\n",
  20629. + size);
  20630. + return MV_EMPTY;
  20631. +}
  20632. +
  20633. +/*******************************************************************************
  20634. +* mvCesaCopyToMbuf - Copy data from continuous buffer to the Mbuf structure
  20635. +*
  20636. +* DESCRIPTION:
  20637. +*
  20638. +*
  20639. +* INPUT:
  20640. +* MV_U8* pSrcBuf - Pointer to continuous buffer, where data is
  20641. +* copied from.
  20642. +* MV_CESA_MBUF* pDstMbuf - Pointer to multi-buffer structure where data is
  20643. +* copied to.
  20644. +* int offset - Offset in the Mbuf structure where located first
  20645. +* byte of data should be copied.
  20646. +* int size - Size of data should be copied
  20647. +*
  20648. +* RETURN:
  20649. +* MV_OK - Success, all data is copied successfully.
  20650. +* MV_OUT_OF_RANGE - Failed, offset is out of Multi-buffer data range.
  20651. +* No data is copied.
  20652. +* MV_FULL - Multi-buffer structure has not enough place to copy
  20653. +* all data. Data from the offset to end of Mbuf data
  20654. +* is copied.
  20655. +*
  20656. +*******************************************************************************/
  20657. +MV_STATUS mvCesaCopyToMbuf(MV_U8* pSrcBuf, MV_CESA_MBUF* pDstMbuf,
  20658. + int offset, int size)
  20659. +{
  20660. + int frag, fragOffset, bufSize;
  20661. + MV_U8* pBuf;
  20662. +
  20663. + if(size == 0)
  20664. + return MV_OK;
  20665. +
  20666. + frag = mvCesaMbufOffset(pDstMbuf, offset, &fragOffset);
  20667. + if(frag == MV_INVALID)
  20668. + {
  20669. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  20670. + return MV_OUT_OF_RANGE;
  20671. + }
  20672. +
  20673. + bufSize = pDstMbuf->pFrags[frag].bufSize - fragOffset;
  20674. + pBuf = pDstMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  20675. + while(MV_TRUE)
  20676. + {
  20677. + if(size <= bufSize)
  20678. + {
  20679. + memcpy(pBuf, pSrcBuf, size);
  20680. + return MV_OK;
  20681. + }
  20682. + memcpy(pBuf, pSrcBuf, bufSize);
  20683. + size -= bufSize;
  20684. + frag++;
  20685. + pSrcBuf += bufSize;
  20686. + if(frag >= pDstMbuf->numFrags)
  20687. + break;
  20688. +
  20689. + bufSize = pDstMbuf->pFrags[frag].bufSize;
  20690. + pBuf = pDstMbuf->pFrags[frag].bufVirtPtr;
  20691. + }
  20692. + mvOsPrintf("mvCesaCopyToMbuf: Mbuf is FULL - %d bytes isn't copied\n",
  20693. + size);
  20694. + return MV_FULL;
  20695. +}
  20696. +
  20697. +/*******************************************************************************
  20698. +* mvCesaMbufCopy - Copy data from one Mbuf structure to the other Mbuf structure
  20699. +*
  20700. +* DESCRIPTION:
  20701. +*
  20702. +*
  20703. +* INPUT:
  20704. +*
  20705. +* MV_CESA_MBUF* pDstMbuf - Pointer to multi-buffer structure where data is
  20706. +* copied to.
  20707. +* int dstMbufOffset - Offset in the dstMbuf structure where first byte
  20708. +* of data should be copied to.
  20709. +* MV_CESA_MBUF* pSrcMbuf - Pointer to multi-buffer structure where data is
  20710. +* copied from.
  20711. +* int srcMbufOffset - Offset in the srcMbuf structure where first byte
  20712. +* of data should be copied from.
  20713. +* int size - Size of data should be copied
  20714. +*
  20715. +* RETURN:
  20716. +* MV_OK - Success, all data is copied successfully.
  20717. +* MV_OUT_OF_RANGE - Failed, srcMbufOffset or dstMbufOffset is out of
  20718. +* srcMbuf or dstMbuf structure correspondently.
  20719. +* No data is copied.
  20720. +* MV_BAD_SIZE - srcMbuf or dstMbuf structure is too small to copy
  20721. +* all data. Partial data is copied
  20722. +*
  20723. +*******************************************************************************/
  20724. +MV_STATUS mvCesaMbufCopy(MV_CESA_MBUF* pMbufDst, int dstMbufOffset,
  20725. + MV_CESA_MBUF* pMbufSrc, int srcMbufOffset, int size)
  20726. +{
  20727. + int srcFrag, dstFrag, srcSize, dstSize, srcOffset, dstOffset;
  20728. + int copySize;
  20729. + MV_U8 *pSrc, *pDst;
  20730. +
  20731. + if(size == 0)
  20732. + return MV_OK;
  20733. +
  20734. + srcFrag = mvCesaMbufOffset(pMbufSrc, srcMbufOffset, &srcOffset);
  20735. + if(srcFrag == MV_INVALID)
  20736. + {
  20737. + mvOsPrintf("CESA srcMbuf Error: offset (%d) out of range\n", srcMbufOffset);
  20738. + return MV_OUT_OF_RANGE;
  20739. + }
  20740. + pSrc = pMbufSrc->pFrags[srcFrag].bufVirtPtr + srcOffset;
  20741. + srcSize = pMbufSrc->pFrags[srcFrag].bufSize - srcOffset;
  20742. +
  20743. + dstFrag = mvCesaMbufOffset(pMbufDst, dstMbufOffset, &dstOffset);
  20744. + if(dstFrag == MV_INVALID)
  20745. + {
  20746. + mvOsPrintf("CESA dstMbuf Error: offset (%d) out of range\n", dstMbufOffset);
  20747. + return MV_OUT_OF_RANGE;
  20748. + }
  20749. + pDst = pMbufDst->pFrags[dstFrag].bufVirtPtr + dstOffset;
  20750. + dstSize = pMbufDst->pFrags[dstFrag].bufSize - dstOffset;
  20751. +
  20752. + while(size > 0)
  20753. + {
  20754. + copySize = MV_MIN(srcSize, dstSize);
  20755. + if(size <= copySize)
  20756. + {
  20757. + memcpy(pDst, pSrc, size);
  20758. + return MV_OK;
  20759. + }
  20760. + memcpy(pDst, pSrc, copySize);
  20761. + size -= copySize;
  20762. + srcSize -= copySize;
  20763. + dstSize -= copySize;
  20764. +
  20765. + if(srcSize == 0)
  20766. + {
  20767. + srcFrag++;
  20768. + if(srcFrag >= pMbufSrc->numFrags)
  20769. + break;
  20770. +
  20771. + pSrc = pMbufSrc->pFrags[srcFrag].bufVirtPtr;
  20772. + srcSize = pMbufSrc->pFrags[srcFrag].bufSize;
  20773. + }
  20774. +
  20775. + if(dstSize == 0)
  20776. + {
  20777. + dstFrag++;
  20778. + if(dstFrag >= pMbufDst->numFrags)
  20779. + break;
  20780. +
  20781. + pDst = pMbufDst->pFrags[dstFrag].bufVirtPtr;
  20782. + dstSize = pMbufDst->pFrags[dstFrag].bufSize;
  20783. + }
  20784. + }
  20785. + mvOsPrintf("mvCesaMbufCopy: BAD size - %d bytes isn't copied\n",
  20786. + size);
  20787. +
  20788. + return MV_BAD_SIZE;
  20789. +}
  20790. +
  20791. +static MV_STATUS mvCesaMbufCacheUnmap(MV_CESA_MBUF* pMbuf, int offset, int size)
  20792. +{
  20793. + int frag, fragOffset, bufSize;
  20794. + MV_U8* pBuf;
  20795. +
  20796. + if(size == 0)
  20797. + return MV_OK;
  20798. +
  20799. + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
  20800. + if(frag == MV_INVALID)
  20801. + {
  20802. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  20803. + return MV_OUT_OF_RANGE;
  20804. + }
  20805. +
  20806. + bufSize = pMbuf->pFrags[frag].bufSize - fragOffset;
  20807. + pBuf = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  20808. + while(MV_TRUE)
  20809. + {
  20810. + if(size <= bufSize)
  20811. + {
  20812. + mvOsCacheUnmap(NULL, mvOsIoVirtToPhy(NULL, pBuf), size);
  20813. + return MV_OK;
  20814. + }
  20815. +
  20816. + mvOsCacheUnmap(NULL, mvOsIoVirtToPhy(NULL, pBuf), bufSize);
  20817. + size -= bufSize;
  20818. + frag++;
  20819. + if(frag >= pMbuf->numFrags)
  20820. + break;
  20821. +
  20822. + bufSize = pMbuf->pFrags[frag].bufSize;
  20823. + pBuf = pMbuf->pFrags[frag].bufVirtPtr;
  20824. + }
  20825. + mvOsPrintf("%s: Mbuf is FULL - %d bytes isn't Unmapped\n",
  20826. + __FUNCTION__, size);
  20827. + return MV_FULL;
  20828. +}
  20829. +
  20830. +
  20831. +/*************************************** Local Functions ******************************/
  20832. +
  20833. +/*******************************************************************************
  20834. +* mvCesaFragReqProcess - Process fragmented request
  20835. +*
  20836. +* DESCRIPTION:
  20837. +* This function processes a fragment of fragmented request (First, Middle or Last)
  20838. +*
  20839. +*
  20840. +* INPUT:
  20841. +* MV_CESA_REQ* pReq - Pointer to the request in the request queue.
  20842. +*
  20843. +* RETURN:
  20844. +* MV_OK - The fragment is successfully passed to HW for processing.
  20845. +* MV_TERMINATE - Means, that HW finished its work on this packet and no more
  20846. +* interrupts will be generated for this request.
  20847. +* Function mvCesaReadyGet() must be called to complete request
  20848. +* processing and get request result.
  20849. +*
  20850. +*******************************************************************************/
  20851. +static MV_STATUS mvCesaFragReqProcess(MV_CESA_REQ* pReq, MV_U8 frag)
  20852. +{
  20853. + int i, copySize, cryptoDataSize, macDataSize, sid;
  20854. + int cryptoIvOffset, digestOffset;
  20855. + MV_U32 config;
  20856. + MV_CESA_COMMAND* pCmd = pReq->pCmd;
  20857. + MV_CESA_SA* pSA;
  20858. + MV_CESA_MBUF* pMbuf;
  20859. + MV_DMA_DESC* pDmaDesc = pReq->dma[frag].pDmaFirst;
  20860. + MV_U8* pSramBuf = cesaSramVirtPtr->buf;
  20861. + int macTotalLen = 0;
  20862. + int fixOffset, cryptoOffset, macOffset;
  20863. +
  20864. + cesaStats.fragCount++;
  20865. +
  20866. + sid = pReq->pCmd->sessionId;
  20867. +
  20868. + pSA = &pCesaSAD[sid];
  20869. +
  20870. + cryptoIvOffset = digestOffset = 0;
  20871. + i = macDataSize = 0;
  20872. + cryptoDataSize = 0;
  20873. +
  20874. + /* First fragment processing */
  20875. + if(pReq->fragMode == MV_CESA_FRAG_FIRST)
  20876. + {
  20877. + /* pReq->frags monitors processing of fragmented request between fragments */
  20878. + pReq->frags.bufOffset = 0;
  20879. + pReq->frags.cryptoSize = 0;
  20880. + pReq->frags.macSize = 0;
  20881. +
  20882. + config = pSA->config | (MV_CESA_FRAG_FIRST << MV_CESA_FRAG_MODE_OFFSET);
  20883. +
  20884. + /* fixOffset can be not equal to zero only for FIRST fragment */
  20885. + fixOffset = pReq->fixOffset;
  20886. + /* For FIRST fragment crypto and mac offsets are taken from pCmd */
  20887. + cryptoOffset = pCmd->cryptoOffset;
  20888. + macOffset = pCmd->macOffset;
  20889. +
  20890. + copySize = sizeof(cesaSramVirtPtr->buf) - pReq->fixOffset;
  20891. +
  20892. + /* Find fragment size: Must meet all requirements for CRYPTO and MAC
  20893. + * cryptoDataSize - size of data will be encrypted/decrypted in this fragment
  20894. + * macDataSize - size of data will be signed/verified in this fragment
  20895. + * copySize - size of data will be copied from srcMbuf to SRAM and
  20896. + * back to dstMbuf for this fragment
  20897. + */
  20898. + mvCesaFragSizeFind(pSA, pReq, cryptoOffset, macOffset,
  20899. + &copySize, &cryptoDataSize, &macDataSize);
  20900. +
  20901. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  20902. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET))
  20903. + {
  20904. + /* CryptoIV special processing */
  20905. + if( (pSA->config & MV_CESA_CRYPTO_MODE_MASK) ==
  20906. + (MV_CESA_CRYPTO_CBC << MV_CESA_CRYPTO_MODE_BIT) )
  20907. + {
  20908. + /* In CBC mode for encode direction when IV from user */
  20909. + if( (pCmd->ivFromUser) &&
  20910. + ((pSA->config & MV_CESA_DIRECTION_MASK) ==
  20911. + (MV_CESA_DIR_ENCODE << MV_CESA_DIRECTION_BIT)) )
  20912. + {
  20913. +
  20914. + /* For Crypto Encode in CBC mode HW always takes IV from SRAM IVPointer,
  20915. + * (not from IVBufPointer). So when ivFromUser==1, we should copy IV from user place
  20916. + * in the buffer to SRAM IVPointer
  20917. + */
  20918. + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],
  20919. + MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
  20920. + }
  20921. +
  20922. + /* Special processing when IV is not located in the first fragment */
  20923. + if(pCmd->ivOffset > (copySize - pSA->cryptoIvSize))
  20924. + {
  20925. + /* Prepare dummy place for cryptoIV in SRAM */
  20926. + cryptoIvOffset = cesaSramVirtPtr->tempCryptoIV - mvCesaSramAddrGet();
  20927. +
  20928. + /* For Decryption: Copy IV value from pCmd->ivOffset to Special SRAM place */
  20929. + if((pSA->config & MV_CESA_DIRECTION_MASK) ==
  20930. + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))
  20931. + {
  20932. + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->tempCryptoIV, &pDmaDesc[i],
  20933. + MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
  20934. + }
  20935. + else
  20936. + {
  20937. + /* For Encryption when IV is NOT from User: */
  20938. + /* Copy IV from SRAM to buffer (pCmd->ivOffset) */
  20939. + if(pCmd->ivFromUser == 0)
  20940. + {
  20941. + /* copy IV value from cryptoIV to Buffer (pCmd->ivOffset) */
  20942. + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],
  20943. + MV_TRUE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
  20944. + }
  20945. + }
  20946. + }
  20947. + else
  20948. + {
  20949. + cryptoIvOffset = pCmd->ivOffset;
  20950. + }
  20951. + }
  20952. + }
  20953. +
  20954. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  20955. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  20956. + {
  20957. + /* MAC digest special processing on Decode direction */
  20958. + if((pSA->config & MV_CESA_DIRECTION_MASK) ==
  20959. + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))
  20960. + {
  20961. + /* Save digest from pCmd->digestOffset */
  20962. + mvCesaCopyFromMbuf(pReq->frags.orgDigest,
  20963. + pCmd->pSrc, pCmd->digestOffset, pSA->digestSize);
  20964. +
  20965. + /* If pCmd->digestOffset is not located on the first */
  20966. + if(pCmd->digestOffset > (copySize - pSA->digestSize))
  20967. + {
  20968. + MV_U8 digestZero[MV_CESA_MAX_DIGEST_SIZE];
  20969. +
  20970. + /* Set zeros to pCmd->digestOffset (DRAM) */
  20971. + memset(digestZero, 0, MV_CESA_MAX_DIGEST_SIZE);
  20972. + mvCesaCopyToMbuf(digestZero, pCmd->pSrc, pCmd->digestOffset, pSA->digestSize);
  20973. +
  20974. + /* Prepare dummy place for digest in SRAM */
  20975. + digestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();
  20976. + }
  20977. + else
  20978. + {
  20979. + digestOffset = pCmd->digestOffset;
  20980. + }
  20981. + }
  20982. + }
  20983. + /* Update SA in SRAM */
  20984. + if(cesaLastSid != sid)
  20985. + {
  20986. + mvCesaSramSaUpdate(sid, &pDmaDesc[i]);
  20987. + i++;
  20988. + }
  20989. +
  20990. + pReq->fragMode = MV_CESA_FRAG_MIDDLE;
  20991. + }
  20992. + else
  20993. + {
  20994. + /* Continue fragment */
  20995. + fixOffset = 0;
  20996. + cryptoOffset = 0;
  20997. + macOffset = 0;
  20998. + if( (pCmd->pSrc->mbufSize - pReq->frags.bufOffset) <= sizeof(cesaSramVirtPtr->buf))
  20999. + {
  21000. + /* Last fragment */
  21001. + config = pSA->config | (MV_CESA_FRAG_LAST << MV_CESA_FRAG_MODE_OFFSET);
  21002. + pReq->fragMode = MV_CESA_FRAG_LAST;
  21003. + copySize = pCmd->pSrc->mbufSize - pReq->frags.bufOffset;
  21004. +
  21005. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  21006. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  21007. + {
  21008. + macDataSize = pCmd->macLength - pReq->frags.macSize;
  21009. +
  21010. + /* If pCmd->digestOffset is not located on last fragment */
  21011. + if(pCmd->digestOffset < pReq->frags.bufOffset)
  21012. + {
  21013. + /* Prepare dummy place for digest in SRAM */
  21014. + digestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();
  21015. + }
  21016. + else
  21017. + {
  21018. + digestOffset = pCmd->digestOffset - pReq->frags.bufOffset;
  21019. + }
  21020. + pReq->frags.newDigestOffset = digestOffset;
  21021. + macTotalLen = pCmd->macLength;
  21022. +
  21023. + /* HW can't calculate the Digest correctly for fragmented packets
  21024. + * in the following cases:
  21025. + * - MV88F5182 ||
  21026. + * - MV88F5181L when total macLength more that 16 Kbytes ||
  21027. + * - total macLength more that 64 Kbytes
  21028. + */
  21029. + if( (mvCtrlModelGet() == MV_5182_DEV_ID) ||
  21030. + ( (mvCtrlModelGet() == MV_5181_DEV_ID) &&
  21031. + (mvCtrlRevGet() >= MV_5181L_A0_REV) &&
  21032. + (pCmd->macLength >= (1 << 14)) ) )
  21033. + {
  21034. + return MV_TERMINATE;
  21035. + }
  21036. + }
  21037. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  21038. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )
  21039. + {
  21040. + cryptoDataSize = pCmd->cryptoLength - pReq->frags.cryptoSize;
  21041. + }
  21042. +
  21043. + /* cryptoIvOffset - don't care */
  21044. + }
  21045. + else
  21046. + {
  21047. + /* WA for MV88F5182 SHA1 and MD5 fragmentation mode */
  21048. + if( (mvCtrlModelGet() == MV_5182_DEV_ID) &&
  21049. + (((pSA->config & MV_CESA_MAC_MODE_MASK) ==
  21050. + (MV_CESA_MAC_MD5 << MV_CESA_MAC_MODE_OFFSET)) ||
  21051. + ((pSA->config & MV_CESA_MAC_MODE_MASK) ==
  21052. + (MV_CESA_MAC_SHA1 << MV_CESA_MAC_MODE_OFFSET))) )
  21053. + {
  21054. + pReq->frags.newDigestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();
  21055. + pReq->fragMode = MV_CESA_FRAG_LAST;
  21056. +
  21057. + return MV_TERMINATE;
  21058. + }
  21059. + /* Middle fragment */
  21060. + config = pSA->config | (MV_CESA_FRAG_MIDDLE << MV_CESA_FRAG_MODE_OFFSET);
  21061. + copySize = sizeof(cesaSramVirtPtr->buf);
  21062. + /* digestOffset and cryptoIvOffset - don't care */
  21063. +
  21064. + /* Find fragment size */
  21065. + mvCesaFragSizeFind(pSA, pReq, cryptoOffset, macOffset,
  21066. + &copySize, &cryptoDataSize, &macDataSize);
  21067. + }
  21068. + }
  21069. + /********* Prepare DMA descriptors to copy from pSrc to SRAM *********/
  21070. + pMbuf = pCmd->pSrc;
  21071. + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
  21072. + MV_FALSE, pReq->frags.bufOffset, copySize, pCmd->skipFlush);
  21073. +
  21074. + /* Prepare CESA descriptor to copy from DRAM to SRAM by DMA */
  21075. + mvCesaSramDescrBuild(config, frag,
  21076. + cryptoOffset + fixOffset, cryptoIvOffset + fixOffset,
  21077. + cryptoDataSize, macOffset + fixOffset,
  21078. + digestOffset + fixOffset, macDataSize, macTotalLen,
  21079. + pReq, &pDmaDesc[i]);
  21080. + i++;
  21081. +
  21082. + /* Add special descriptor Ownership for CPU */
  21083. + pDmaDesc[i].byteCnt = 0;
  21084. + pDmaDesc[i].phySrcAdd = 0;
  21085. + pDmaDesc[i].phyDestAdd = 0;
  21086. + i++;
  21087. +
  21088. + /********* Prepare DMA descriptors to copy from SRAM to pDst *********/
  21089. + pMbuf = pCmd->pDst;
  21090. + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
  21091. + MV_TRUE, pReq->frags.bufOffset, copySize, pCmd->skipFlush);
  21092. +
  21093. + /* Next field of Last DMA descriptor must be NULL */
  21094. + pDmaDesc[i-1].phyNextDescPtr = 0;
  21095. + pReq->dma[frag].pDmaLast = &pDmaDesc[i-1];
  21096. + mvOsCacheFlush(NULL, pReq->dma[frag].pDmaFirst,
  21097. + i*sizeof(MV_DMA_DESC));
  21098. +
  21099. + /*mvCesaDebugDescriptor(&cesaSramVirtPtr->desc[frag]);*/
  21100. +
  21101. + pReq->frags.bufOffset += copySize;
  21102. + pReq->frags.cryptoSize += cryptoDataSize;
  21103. + pReq->frags.macSize += macDataSize;
  21104. +
  21105. + return MV_OK;
  21106. +}
  21107. +
  21108. +
  21109. +/*******************************************************************************
  21110. +* mvCesaReqProcess - Process regular (Non-fragmented) request
  21111. +*
  21112. +* DESCRIPTION:
  21113. +* This function processes the whole (not fragmented) request
  21114. +*
  21115. +* INPUT:
  21116. +* MV_CESA_REQ* pReq - Pointer to the request in the request queue.
  21117. +*
  21118. +* RETURN:
  21119. +* MV_OK - The request is successfully passed to HW for processing.
  21120. +* Other - Failure. The request will not be processed
  21121. +*
  21122. +*******************************************************************************/
  21123. +static MV_STATUS mvCesaReqProcess(MV_CESA_REQ* pReq)
  21124. +{
  21125. + MV_CESA_MBUF *pMbuf;
  21126. + MV_DMA_DESC *pDmaDesc;
  21127. + MV_U8 *pSramBuf;
  21128. + int sid, i, fixOffset;
  21129. + MV_CESA_SA *pSA;
  21130. + MV_CESA_COMMAND *pCmd = pReq->pCmd;
  21131. +
  21132. + cesaStats.procCount++;
  21133. +
  21134. + sid = pCmd->sessionId;
  21135. + pSA = &pCesaSAD[sid];
  21136. + pDmaDesc = pReq->dma[0].pDmaFirst;
  21137. + pSramBuf = cesaSramVirtPtr->buf;
  21138. + fixOffset = pReq->fixOffset;
  21139. +
  21140. +/*
  21141. + mvOsPrintf("mvCesaReqProcess: sid=%d, pSA=%p, pDmaDesc=%p, pSramBuf=%p\n",
  21142. + sid, pSA, pDmaDesc, pSramBuf);
  21143. +*/
  21144. + i = 0;
  21145. +
  21146. + /* Crypto IV Special processing in CBC mode for Encryption direction */
  21147. + if( ((pSA->config & MV_CESA_OPERATION_MASK) != (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) &&
  21148. + ((pSA->config & MV_CESA_CRYPTO_MODE_MASK) == (MV_CESA_CRYPTO_CBC << MV_CESA_CRYPTO_MODE_BIT)) &&
  21149. + ((pSA->config & MV_CESA_DIRECTION_MASK) == (MV_CESA_DIR_ENCODE << MV_CESA_DIRECTION_BIT)) &&
  21150. + (pCmd->ivFromUser) )
  21151. + {
  21152. + /* For Crypto Encode in CBC mode HW always takes IV from SRAM IVPointer,
  21153. + * (not from IVBufPointer). So when ivFromUser==1, we should copy IV from user place
  21154. + * in the buffer to SRAM IVPointer
  21155. + */
  21156. + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],
  21157. + MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
  21158. + }
  21159. +
  21160. + /* Update SA in SRAM */
  21161. + if(cesaLastSid != sid)
  21162. + {
  21163. + mvCesaSramSaUpdate(sid, &pDmaDesc[i]);
  21164. + i++;
  21165. + }
  21166. +
  21167. + /********* Prepare DMA descriptors to copy from pSrc to SRAM *********/
  21168. + pMbuf = pCmd->pSrc;
  21169. + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
  21170. + MV_FALSE, 0, pMbuf->mbufSize, pCmd->skipFlush);
  21171. +
  21172. + /* Prepare Security Accelerator descriptor to SRAM words 0 - 7 */
  21173. + mvCesaSramDescrBuild(pSA->config, 0, pCmd->cryptoOffset + fixOffset,
  21174. + pCmd->ivOffset + fixOffset, pCmd->cryptoLength,
  21175. + pCmd->macOffset + fixOffset, pCmd->digestOffset + fixOffset,
  21176. + pCmd->macLength, pCmd->macLength, pReq, &pDmaDesc[i]);
  21177. + i++;
  21178. +
  21179. + /* Add special descriptor Ownership for CPU */
  21180. + pDmaDesc[i].byteCnt = 0;
  21181. + pDmaDesc[i].phySrcAdd = 0;
  21182. + pDmaDesc[i].phyDestAdd = 0;
  21183. + i++;
  21184. +
  21185. + /********* Prepare DMA descriptors to copy from SRAM to pDst *********/
  21186. + pMbuf = pCmd->pDst;
  21187. + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
  21188. + MV_TRUE, 0, pMbuf->mbufSize, pCmd->skipFlush);
  21189. +
  21190. + /* Next field of Last DMA descriptor must be NULL */
  21191. + pDmaDesc[i-1].phyNextDescPtr = 0;
  21192. + pReq->dma[0].pDmaLast = &pDmaDesc[i-1];
  21193. + mvOsCacheFlush(NULL, pReq->dma[0].pDmaFirst, i*sizeof(MV_DMA_DESC));
  21194. +
  21195. + return MV_OK;
  21196. +}
  21197. +
  21198. +
  21199. +/*******************************************************************************
  21200. +* mvCesaSramDescrBuild - Set CESA descriptor in SRAM
  21201. +*
  21202. +* DESCRIPTION:
  21203. +* This function builds CESA descriptor in SRAM from all Command parameters
  21204. +*
  21205. +*
  21206. +* INPUT:
  21207. +* int chan - CESA channel uses the descriptor
  21208. +* MV_U32 config - 32 bits of WORD_0 in CESA descriptor structure
  21209. +* int cryptoOffset - Offset from the beginning of SRAM buffer where
  21210. +* data for encryption/decription is started.
  21211. +* int ivOffset - Offset of crypto IV from the SRAM base. Valid only
  21212. +* for first fragment.
  21213. +* int cryptoLength - Size (in bytes) of data for encryption/descryption
  21214. +* operation on this fragment.
  21215. +* int macOffset - Offset from the beginning of SRAM buffer where
  21216. +* data for Authentication is started
  21217. +* int digestOffset - Offset from the beginning of SRAM buffer where
  21218. +* digest is located. Valid for first and last fragments.
  21219. +* int macLength - Size (in bytes) of data for Authentication
  21220. +* operation on this fragment.
  21221. +* int macTotalLen - Toatl size (in bytes) of data for Authentication
  21222. +* operation on the whole request (packet). Valid for
  21223. +* last fragment only.
  21224. +*
  21225. +* RETURN: None
  21226. +*
  21227. +*******************************************************************************/
  21228. +static void mvCesaSramDescrBuild(MV_U32 config, int frag,
  21229. + int cryptoOffset, int ivOffset, int cryptoLength,
  21230. + int macOffset, int digestOffset, int macLength,
  21231. + int macTotalLen, MV_CESA_REQ* pReq, MV_DMA_DESC* pDmaDesc)
  21232. +{
  21233. + MV_CESA_DESC* pCesaDesc = &pReq->pCesaDesc[frag];
  21234. + MV_CESA_DESC* pSramDesc = pSramDesc = &cesaSramVirtPtr->desc;
  21235. + MV_U16 sramBufOffset = (MV_U16)((MV_U8*)cesaSramVirtPtr->buf - mvCesaSramAddrGet());
  21236. +
  21237. + pCesaDesc->config = MV_32BIT_LE(config);
  21238. +
  21239. + if( (config & MV_CESA_OPERATION_MASK) !=
  21240. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )
  21241. + {
  21242. + /* word 1 */
  21243. + pCesaDesc->cryptoSrcOffset = MV_16BIT_LE(sramBufOffset + cryptoOffset);
  21244. + pCesaDesc->cryptoDstOffset = MV_16BIT_LE(sramBufOffset + cryptoOffset);
  21245. + /* word 2 */
  21246. + pCesaDesc->cryptoDataLen = MV_16BIT_LE(cryptoLength);
  21247. + /* word 3 */
  21248. + pCesaDesc->cryptoKeyOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.cryptoKey -
  21249. + mvCesaSramAddrGet()));
  21250. + /* word 4 */
  21251. + pCesaDesc->cryptoIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->cryptoIV -
  21252. + mvCesaSramAddrGet()));
  21253. + pCesaDesc->cryptoIvBufOffset = MV_16BIT_LE(sramBufOffset + ivOffset);
  21254. + }
  21255. +
  21256. + if( (config & MV_CESA_OPERATION_MASK) !=
  21257. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  21258. + {
  21259. + /* word 5 */
  21260. + pCesaDesc->macSrcOffset = MV_16BIT_LE(sramBufOffset + macOffset);
  21261. + pCesaDesc->macTotalLen = MV_16BIT_LE(macTotalLen);
  21262. +
  21263. + /* word 6 */
  21264. + pCesaDesc->macDigestOffset = MV_16BIT_LE(sramBufOffset + digestOffset);
  21265. + pCesaDesc->macDataLen = MV_16BIT_LE(macLength);
  21266. +
  21267. + /* word 7 */
  21268. + pCesaDesc->macInnerIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.macInnerIV -
  21269. + mvCesaSramAddrGet()));
  21270. + pCesaDesc->macOuterIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.macOuterIV -
  21271. + mvCesaSramAddrGet()));
  21272. + }
  21273. + /* Prepare DMA descriptor to CESA descriptor from DRAM to SRAM */
  21274. + pDmaDesc->phySrcAdd = MV_32BIT_LE(mvCesaVirtToPhys(&pReq->cesaDescBuf, pCesaDesc));
  21275. + pDmaDesc->phyDestAdd = MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (MV_U8*)pSramDesc));
  21276. + pDmaDesc->byteCnt = MV_32BIT_LE(sizeof(MV_CESA_DESC) | BIT31);
  21277. +
  21278. + /* flush Source buffer */
  21279. + mvOsCacheFlush(NULL, pCesaDesc, sizeof(MV_CESA_DESC));
  21280. +}
  21281. +
  21282. +/*******************************************************************************
  21283. +* mvCesaSramSaUpdate - Move required SA information to SRAM if needed.
  21284. +*
  21285. +* DESCRIPTION:
  21286. +* Copy to SRAM values of the required SA.
  21287. +*
  21288. +*
  21289. +* INPUT:
  21290. +* short sid - Session ID needs SRAM Cache update
  21291. +* MV_DMA_DESC *pDmaDesc - Pointer to DMA descriptor used to
  21292. +* copy SA values from DRAM to SRAM.
  21293. +*
  21294. +* RETURN:
  21295. +* MV_OK - Cache entry for this SA copied to SRAM.
  21296. +* MV_NO_CHANGE - Cache entry for this SA already exist in SRAM
  21297. +*
  21298. +*******************************************************************************/
  21299. +static INLINE void mvCesaSramSaUpdate(short sid, MV_DMA_DESC *pDmaDesc)
  21300. +{
  21301. + MV_CESA_SA *pSA = &pCesaSAD[sid];
  21302. +
  21303. + /* Prepare DMA descriptor to Copy CACHE_SA from SA database in DRAM to SRAM */
  21304. + pDmaDesc->byteCnt = MV_32BIT_LE(sizeof(MV_CESA_SRAM_SA) | BIT31);
  21305. + pDmaDesc->phySrcAdd = MV_32BIT_LE(mvCesaVirtToPhys(&cesaSramSaBuf, pSA->pSramSA));
  21306. + pDmaDesc->phyDestAdd =
  21307. + MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (MV_U8*)&cesaSramVirtPtr->sramSA));
  21308. +
  21309. + /* Source buffer is already flushed during OpenSession*/
  21310. + /*mvOsCacheFlush(NULL, &pSA->sramSA, sizeof(MV_CESA_SRAM_SA));*/
  21311. +}
  21312. +
  21313. +/*******************************************************************************
  21314. +* mvCesaDmaCopyPrepare - prepare DMA descriptor list to copy data presented by
  21315. +* Mbuf structure from DRAM to SRAM
  21316. +*
  21317. +* DESCRIPTION:
  21318. +*
  21319. +*
  21320. +* INPUT:
  21321. +* MV_CESA_MBUF* pMbuf - pointer to Mbuf structure contains request
  21322. +* data in DRAM
  21323. +* MV_U8* pSramBuf - pointer to buffer in SRAM where data should
  21324. +* be copied to.
  21325. +* MV_DMA_DESC* pDmaDesc - pointer to first DMA descriptor for this copy.
  21326. +* The function set number of DMA descriptors needed
  21327. +* to copy the copySize bytes from Mbuf.
  21328. +* MV_BOOL isToMbuf - Copy direction.
  21329. +* MV_TRUE means copy from SRAM buffer to Mbuf in DRAM.
  21330. +* MV_FALSE means copy from Mbuf in DRAM to SRAM buffer.
  21331. +* int offset - Offset in the Mbuf structure that copy should be
  21332. +* started from.
  21333. +* int copySize - Size of data should be copied.
  21334. +*
  21335. +* RETURN:
  21336. +* int - number of DMA descriptors used for the copy.
  21337. +*
  21338. +*******************************************************************************/
  21339. +#ifndef MV_NETBSD
  21340. +static INLINE int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,
  21341. + MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,
  21342. + int offset, int copySize, MV_BOOL skipFlush)
  21343. +{
  21344. + int bufOffset, bufSize, size, frag, i;
  21345. + MV_U8* pBuf;
  21346. +
  21347. + i = 0;
  21348. +
  21349. + /* Calculate start place for copy: fragment number and offset in the fragment */
  21350. + frag = mvCesaMbufOffset(pMbuf, offset, &bufOffset);
  21351. + bufSize = pMbuf->pFrags[frag].bufSize - bufOffset;
  21352. + pBuf = pMbuf->pFrags[frag].bufVirtPtr + bufOffset;
  21353. +
  21354. + /* Size accumulate total copy size */
  21355. + size = 0;
  21356. +
  21357. + /* Create DMA lists to copy mBuf from pSrc to SRAM */
  21358. + while(size < copySize)
  21359. + {
  21360. + /* Find copy size for each DMA descriptor */
  21361. + bufSize = MV_MIN(bufSize, (copySize - size));
  21362. + pDmaDesc[i].byteCnt = MV_32BIT_LE(bufSize | BIT31);
  21363. + if(isToMbuf)
  21364. + {
  21365. + pDmaDesc[i].phyDestAdd = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));
  21366. + pDmaDesc[i].phySrcAdd =
  21367. + MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (pSramBuf + size)));
  21368. + /* invalidate the buffer */
  21369. + if(skipFlush == MV_FALSE)
  21370. + mvOsCacheInvalidate(NULL, pBuf, bufSize);
  21371. + }
  21372. + else
  21373. + {
  21374. + pDmaDesc[i].phySrcAdd = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));
  21375. + pDmaDesc[i].phyDestAdd =
  21376. + MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (pSramBuf + size)));
  21377. + /* flush the buffer */
  21378. + if(skipFlush == MV_FALSE)
  21379. + mvOsCacheFlush(NULL, pBuf, bufSize);
  21380. + }
  21381. +
  21382. + /* Count number of used DMA descriptors */
  21383. + i++;
  21384. + size += bufSize;
  21385. +
  21386. + /* go to next fragment in the Mbuf */
  21387. + frag++;
  21388. + pBuf = pMbuf->pFrags[frag].bufVirtPtr;
  21389. + bufSize = pMbuf->pFrags[frag].bufSize;
  21390. + }
  21391. + return i;
  21392. +}
  21393. +#else /* MV_NETBSD */
  21394. +static int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,
  21395. + MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,
  21396. + int offset, int copySize, MV_BOOL skipFlush)
  21397. +{
  21398. + int bufOffset, bufSize, thisSize, size, frag, i;
  21399. + MV_ULONG bufPhys, sramPhys;
  21400. + MV_U8* pBuf;
  21401. +
  21402. + /*
  21403. + * Calculate start place for copy: fragment number and offset in
  21404. + * the fragment
  21405. + */
  21406. + frag = mvCesaMbufOffset(pMbuf, offset, &bufOffset);
  21407. +
  21408. + /*
  21409. + * Get SRAM physical address only once. We can update it in-place
  21410. + * as we build the descriptor chain.
  21411. + */
  21412. + sramPhys = mvCesaSramVirtToPhys(NULL, pSramBuf);
  21413. +
  21414. + /*
  21415. + * 'size' accumulates total copy size, 'i' counts desccriptors.
  21416. + */
  21417. + size = i = 0;
  21418. +
  21419. + /* Create DMA lists to copy mBuf from pSrc to SRAM */
  21420. + while (size < copySize) {
  21421. + /*
  21422. + * Calculate # of bytes to copy from the current fragment,
  21423. + * and the pointer to the start of data
  21424. + */
  21425. + bufSize = pMbuf->pFrags[frag].bufSize - bufOffset;
  21426. + pBuf = pMbuf->pFrags[frag].bufVirtPtr + bufOffset;
  21427. + bufOffset = 0; /* First frag may be non-zero */
  21428. + frag++;
  21429. +
  21430. + /*
  21431. + * As long as there is data in the current fragment...
  21432. + */
  21433. + while (bufSize > 0) {
  21434. + /*
  21435. + * Ensure we don't cross an MMU page boundary.
  21436. + * XXX: This is NetBSD-specific, but it is a
  21437. + * quick and dirty way to fix the problem.
  21438. + * A true HAL would rely on the OS-specific
  21439. + * driver to do this...
  21440. + */
  21441. + thisSize = PAGE_SIZE -
  21442. + (((MV_ULONG)pBuf) & (PAGE_SIZE - 1));
  21443. + thisSize = MV_MIN(bufSize, thisSize);
  21444. + /*
  21445. + * Make sure we don't copy more than requested
  21446. + */
  21447. + if (thisSize > (copySize - size)) {
  21448. + thisSize = copySize - size;
  21449. + bufSize = 0;
  21450. + }
  21451. +
  21452. + /*
  21453. + * Physicall address of this fragment
  21454. + */
  21455. + bufPhys = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));
  21456. +
  21457. + /*
  21458. + * Set up the descriptor
  21459. + */
  21460. + pDmaDesc[i].byteCnt = MV_32BIT_LE(thisSize | BIT31);
  21461. + if(isToMbuf) {
  21462. + pDmaDesc[i].phyDestAdd = bufPhys;
  21463. + pDmaDesc[i].phySrcAdd = MV_32BIT_LE(sramPhys);
  21464. + /* invalidate the buffer */
  21465. + if(skipFlush == MV_FALSE)
  21466. + mvOsCacheInvalidate(NULL, pBuf, thisSize);
  21467. + } else {
  21468. + pDmaDesc[i].phySrcAdd = bufPhys;
  21469. + pDmaDesc[i].phyDestAdd = MV_32BIT_LE(sramPhys);
  21470. + /* flush the buffer */
  21471. + if(skipFlush == MV_FALSE)
  21472. + mvOsCacheFlush(NULL, pBuf, thisSize);
  21473. + }
  21474. +
  21475. + pDmaDesc[i].phyNextDescPtr =
  21476. + MV_32BIT_LE(mvOsIoVirtToPhy(NULL,(&pDmaDesc[i+1])));
  21477. +
  21478. + /* flush the DMA desc */
  21479. + mvOsCacheFlush(NULL, &pDmaDesc[i], sizeof(MV_DMA_DESC));
  21480. +
  21481. + /* Update state */
  21482. + bufSize -= thisSize;
  21483. + sramPhys += thisSize;
  21484. + pBuf += thisSize;
  21485. + size += thisSize;
  21486. + i++;
  21487. + }
  21488. + }
  21489. +
  21490. + return i;
  21491. +}
  21492. +#endif /* MV_NETBSD */
  21493. +/*******************************************************************************
  21494. +* mvCesaHmacIvGet - Calculate Inner and Outter values from HMAC key
  21495. +*
  21496. +* DESCRIPTION:
  21497. +* This function calculate Inner and Outer values used for HMAC algorithm.
  21498. +* This operation allows improve performance fro the whole HMAC processing.
  21499. +*
  21500. +* INPUT:
  21501. +* MV_CESA_MAC_MODE macMode - Authentication mode: HMAC_MD5 or HMAC_SHA1.
  21502. +* unsigned char key[] - Pointer to HMAC key.
  21503. +* int keyLength - Size of HMAC key (maximum 64 bytes)
  21504. +*
  21505. +* OUTPUT:
  21506. +* unsigned char innerIV[] - HASH(key^inner)
  21507. +* unsigned char outerIV[] - HASH(key^outter)
  21508. +*
  21509. +* RETURN: None
  21510. +*
  21511. +*******************************************************************************/
  21512. +static void mvCesaHmacIvGet(MV_CESA_MAC_MODE macMode, unsigned char key[], int keyLength,
  21513. + unsigned char innerIV[], unsigned char outerIV[])
  21514. +{
  21515. + unsigned char inner[MV_CESA_MAX_MAC_KEY_LENGTH];
  21516. + unsigned char outer[MV_CESA_MAX_MAC_KEY_LENGTH];
  21517. + int i, digestSize = 0;
  21518. +#if defined(MV_CPU_LE) || defined(MV_PPC)
  21519. + MV_U32 swapped32, val32, *pVal32;
  21520. +#endif
  21521. + for(i=0; i<keyLength; i++)
  21522. + {
  21523. + inner[i] = 0x36 ^ key[i];
  21524. + outer[i] = 0x5c ^ key[i];
  21525. + }
  21526. +
  21527. + for(i=keyLength; i<MV_CESA_MAX_MAC_KEY_LENGTH; i++)
  21528. + {
  21529. + inner[i] = 0x36;
  21530. + outer[i] = 0x5c;
  21531. + }
  21532. + if(macMode == MV_CESA_MAC_HMAC_MD5)
  21533. + {
  21534. + MV_MD5_CONTEXT ctx;
  21535. +
  21536. + mvMD5Init(&ctx);
  21537. + mvMD5Update(&ctx, inner, MV_CESA_MAX_MAC_KEY_LENGTH);
  21538. +
  21539. + memcpy(innerIV, ctx.buf, MV_CESA_MD5_DIGEST_SIZE);
  21540. + memset(&ctx, 0, sizeof(ctx));
  21541. +
  21542. + mvMD5Init(&ctx);
  21543. + mvMD5Update(&ctx, outer, MV_CESA_MAX_MAC_KEY_LENGTH);
  21544. + memcpy(outerIV, ctx.buf, MV_CESA_MD5_DIGEST_SIZE);
  21545. + memset(&ctx, 0, sizeof(ctx));
  21546. + digestSize = MV_CESA_MD5_DIGEST_SIZE;
  21547. + }
  21548. + else if(macMode == MV_CESA_MAC_HMAC_SHA1)
  21549. + {
  21550. + MV_SHA1_CTX ctx;
  21551. +
  21552. + mvSHA1Init(&ctx);
  21553. + mvSHA1Update(&ctx, inner, MV_CESA_MAX_MAC_KEY_LENGTH);
  21554. + memcpy(innerIV, ctx.state, MV_CESA_SHA1_DIGEST_SIZE);
  21555. + memset(&ctx, 0, sizeof(ctx));
  21556. +
  21557. + mvSHA1Init(&ctx);
  21558. + mvSHA1Update(&ctx, outer, MV_CESA_MAX_MAC_KEY_LENGTH);
  21559. + memcpy(outerIV, ctx.state, MV_CESA_SHA1_DIGEST_SIZE);
  21560. + memset(&ctx, 0, sizeof(ctx));
  21561. + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
  21562. + }
  21563. + else
  21564. + {
  21565. + mvOsPrintf("hmacGetIV: Unexpected macMode %d\n", macMode);
  21566. + }
  21567. +#if defined(MV_CPU_LE) || defined(MV_PPC)
  21568. + /* 32 bits Swap of Inner and Outer values */
  21569. + pVal32 = (MV_U32*)innerIV;
  21570. + for(i=0; i<digestSize/4; i++)
  21571. + {
  21572. + val32 = *pVal32;
  21573. + swapped32 = MV_BYTE_SWAP_32BIT(val32);
  21574. + *pVal32 = swapped32;
  21575. + pVal32++;
  21576. + }
  21577. + pVal32 = (MV_U32*)outerIV;
  21578. + for(i=0; i<digestSize/4; i++)
  21579. + {
  21580. + val32 = *pVal32;
  21581. + swapped32 = MV_BYTE_SWAP_32BIT(val32);
  21582. + *pVal32 = swapped32;
  21583. + pVal32++;
  21584. + }
  21585. +#endif /* defined(MV_CPU_LE) || defined(MV_PPC) */
  21586. +}
  21587. +
  21588. +
  21589. +/*******************************************************************************
  21590. +* mvCesaFragSha1Complete - Complete SHA1 authentication started by HW using SW
  21591. +*
  21592. +* DESCRIPTION:
  21593. +*
  21594. +*
  21595. +* INPUT:
  21596. +* MV_CESA_MBUF* pMbuf - Pointer to Mbuf structure where data
  21597. +* for SHA1 is placed.
  21598. +* int offset - Offset in the Mbuf structure where
  21599. +* unprocessed data for SHA1 is started.
  21600. +* MV_U8* pOuterIV - Pointer to OUTER for this session.
  21601. +* If pOuterIV==NULL - MAC mode is HASH_SHA1
  21602. +* If pOuterIV!=NULL - MAC mode is HMAC_SHA1
  21603. +* int macLeftSize - Size of unprocessed data for SHA1.
  21604. +* int macTotalSize - Total size of data for SHA1 in the
  21605. +* request (processed + unprocessed)
  21606. +*
  21607. +* OUTPUT:
  21608. +* MV_U8* pDigest - Pointer to place where calculated Digest will
  21609. +* be stored.
  21610. +*
  21611. +* RETURN: None
  21612. +*
  21613. +*******************************************************************************/
  21614. +static void mvCesaFragSha1Complete(MV_CESA_MBUF* pMbuf, int offset,
  21615. + MV_U8* pOuterIV, int macLeftSize,
  21616. + int macTotalSize, MV_U8* pDigest)
  21617. +{
  21618. + MV_SHA1_CTX ctx;
  21619. + MV_U8 *pData;
  21620. + int i, frag, fragOffset, size;
  21621. +
  21622. + /* Read temporary Digest from HW */
  21623. + for(i=0; i<MV_CESA_SHA1_DIGEST_SIZE/4; i++)
  21624. + {
  21625. + ctx.state[i] = MV_REG_READ(MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i));
  21626. + }
  21627. + /* Initialize MV_SHA1_CTX structure */
  21628. + memset(ctx.buffer, 0, 64);
  21629. + /* Set count[0] in bits. 32 bits is enough for 512 MBytes */
  21630. + /* so count[1] is always 0 */
  21631. + ctx.count[0] = ((macTotalSize - macLeftSize) * 8);
  21632. + ctx.count[1] = 0;
  21633. +
  21634. + /* If HMAC - add size of Inner block (64 bytes) ro count[0] */
  21635. + if(pOuterIV != NULL)
  21636. + ctx.count[0] += (64 * 8);
  21637. +
  21638. + /* Get place of unprocessed data in the Mbuf structure */
  21639. + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
  21640. + if(frag == MV_INVALID)
  21641. + {
  21642. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  21643. + return;
  21644. + }
  21645. +
  21646. + pData = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  21647. + size = pMbuf->pFrags[frag].bufSize - fragOffset;
  21648. +
  21649. + /* Complete Inner part */
  21650. + while(macLeftSize > 0)
  21651. + {
  21652. + if(macLeftSize <= size)
  21653. + {
  21654. + mvSHA1Update(&ctx, pData, macLeftSize);
  21655. + break;
  21656. + }
  21657. + mvSHA1Update(&ctx, pData, size);
  21658. + macLeftSize -= size;
  21659. + frag++;
  21660. + pData = pMbuf->pFrags[frag].bufVirtPtr;
  21661. + size = pMbuf->pFrags[frag].bufSize;
  21662. + }
  21663. + mvSHA1Final(pDigest, &ctx);
  21664. +/*
  21665. + mvOsPrintf("mvCesaFragSha1Complete: pOuterIV=%p, macLeftSize=%d, macTotalSize=%d\n",
  21666. + pOuterIV, macLeftSize, macTotalSize);
  21667. + mvDebugMemDump(pDigest, MV_CESA_SHA1_DIGEST_SIZE, 1);
  21668. +*/
  21669. +
  21670. + if(pOuterIV != NULL)
  21671. + {
  21672. + /* If HMAC - Complete Outer part */
  21673. + for(i=0; i<MV_CESA_SHA1_DIGEST_SIZE/4; i++)
  21674. + {
  21675. +#if defined(MV_CPU_LE) || defined(MV_ARM)
  21676. + ctx.state[i] = MV_BYTE_SWAP_32BIT(((MV_U32*)pOuterIV)[i]);
  21677. +#else
  21678. + ctx.state[i] = ((MV_U32*)pOuterIV)[i];
  21679. +#endif
  21680. + }
  21681. + memset(ctx.buffer, 0, 64);
  21682. +
  21683. + ctx.count[0] = 64*8;
  21684. + ctx.count[1] = 0;
  21685. + mvSHA1Update(&ctx, pDigest, MV_CESA_SHA1_DIGEST_SIZE);
  21686. + mvSHA1Final(pDigest, &ctx);
  21687. + }
  21688. +}
  21689. +
  21690. +/*******************************************************************************
  21691. +* mvCesaFragMd5Complete - Complete MD5 authentication started by HW using SW
  21692. +*
  21693. +* DESCRIPTION:
  21694. +*
  21695. +*
  21696. +* INPUT:
  21697. +* MV_CESA_MBUF* pMbuf - Pointer to Mbuf structure where data
  21698. +* for SHA1 is placed.
  21699. +* int offset - Offset in the Mbuf structure where
  21700. +* unprocessed data for MD5 is started.
  21701. +* MV_U8* pOuterIV - Pointer to OUTER for this session.
  21702. +* If pOuterIV==NULL - MAC mode is HASH_MD5
  21703. +* If pOuterIV!=NULL - MAC mode is HMAC_MD5
  21704. +* int macLeftSize - Size of unprocessed data for MD5.
  21705. +* int macTotalSize - Total size of data for MD5 in the
  21706. +* request (processed + unprocessed)
  21707. +*
  21708. +* OUTPUT:
  21709. +* MV_U8* pDigest - Pointer to place where calculated Digest will
  21710. +* be stored.
  21711. +*
  21712. +* RETURN: None
  21713. +*
  21714. +*******************************************************************************/
  21715. +static void mvCesaFragMd5Complete(MV_CESA_MBUF* pMbuf, int offset,
  21716. + MV_U8* pOuterIV, int macLeftSize,
  21717. + int macTotalSize, MV_U8* pDigest)
  21718. +{
  21719. + MV_MD5_CONTEXT ctx;
  21720. + MV_U8 *pData;
  21721. + int i, frag, fragOffset, size;
  21722. +
  21723. + /* Read temporary Digest from HW */
  21724. + for(i=0; i<MV_CESA_MD5_DIGEST_SIZE/4; i++)
  21725. + {
  21726. + ctx.buf[i] = MV_REG_READ(MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i));
  21727. + }
  21728. + memset(ctx.in, 0, 64);
  21729. +
  21730. + /* Set count[0] in bits. 32 bits is enough for 512 MBytes */
  21731. + /* so count[1] is always 0 */
  21732. + ctx.bits[0] = ((macTotalSize - macLeftSize) * 8);
  21733. + ctx.bits[1] = 0;
  21734. +
  21735. + /* If HMAC - add size of Inner block (64 bytes) ro count[0] */
  21736. + if(pOuterIV != NULL)
  21737. + ctx.bits[0] += (64 * 8);
  21738. +
  21739. + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
  21740. + if(frag == MV_INVALID)
  21741. + {
  21742. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  21743. + return;
  21744. + }
  21745. +
  21746. + pData = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  21747. + size = pMbuf->pFrags[frag].bufSize - fragOffset;
  21748. +
  21749. + /* Complete Inner part */
  21750. + while(macLeftSize > 0)
  21751. + {
  21752. + if(macLeftSize <= size)
  21753. + {
  21754. + mvMD5Update(&ctx, pData, macLeftSize);
  21755. + break;
  21756. + }
  21757. + mvMD5Update(&ctx, pData, size);
  21758. + macLeftSize -= size;
  21759. + frag++;
  21760. + pData = pMbuf->pFrags[frag].bufVirtPtr;
  21761. + size = pMbuf->pFrags[frag].bufSize;
  21762. + }
  21763. + mvMD5Final(pDigest, &ctx);
  21764. +
  21765. +/*
  21766. + mvOsPrintf("mvCesaFragMd5Complete: pOuterIV=%p, macLeftSize=%d, macTotalSize=%d\n",
  21767. + pOuterIV, macLeftSize, macTotalSize);
  21768. + mvDebugMemDump(pDigest, MV_CESA_MD5_DIGEST_SIZE, 1);
  21769. +*/
  21770. + if(pOuterIV != NULL)
  21771. + {
  21772. + /* Complete Outer part */
  21773. + for(i=0; i<MV_CESA_MD5_DIGEST_SIZE/4; i++)
  21774. + {
  21775. +#if defined(MV_CPU_LE) || defined(MV_ARM)
  21776. + ctx.buf[i] = MV_BYTE_SWAP_32BIT(((MV_U32*)pOuterIV)[i]);
  21777. +#else
  21778. + ctx.buf[i] = ((MV_U32*)pOuterIV)[i];
  21779. +#endif
  21780. + }
  21781. + memset(ctx.in, 0, 64);
  21782. +
  21783. + ctx.bits[0] = 64*8;
  21784. + ctx.bits[1] = 0;
  21785. + mvMD5Update(&ctx, pDigest, MV_CESA_MD5_DIGEST_SIZE);
  21786. + mvMD5Final(pDigest, &ctx);
  21787. + }
  21788. +}
  21789. +
  21790. +/*******************************************************************************
  21791. +* mvCesaFragAuthComplete -
  21792. +*
  21793. +* DESCRIPTION:
  21794. +*
  21795. +*
  21796. +* INPUT:
  21797. +* MV_CESA_REQ* pReq,
  21798. +* MV_CESA_SA* pSA,
  21799. +* int macDataSize
  21800. +*
  21801. +* RETURN:
  21802. +* MV_STATUS
  21803. +*
  21804. +*******************************************************************************/
  21805. +static MV_STATUS mvCesaFragAuthComplete(MV_CESA_REQ* pReq, MV_CESA_SA* pSA,
  21806. + int macDataSize)
  21807. +{
  21808. + MV_CESA_COMMAND* pCmd = pReq->pCmd;
  21809. + MV_U8* pDigest;
  21810. + MV_CESA_MAC_MODE macMode;
  21811. + MV_U8* pOuterIV = NULL;
  21812. +
  21813. + /* Copy data from Source fragment to Destination */
  21814. + if(pCmd->pSrc != pCmd->pDst)
  21815. + {
  21816. + mvCesaMbufCopy(pCmd->pDst, pReq->frags.bufOffset,
  21817. + pCmd->pSrc, pReq->frags.bufOffset, macDataSize);
  21818. + }
  21819. +
  21820. +/*
  21821. + mvCesaCopyFromMbuf(cesaSramVirtPtr->buf[0], pCmd->pSrc, pReq->frags.bufOffset, macDataSize);
  21822. + mvCesaCopyToMbuf(cesaSramVirtPtr->buf[0], pCmd->pDst, pReq->frags.bufOffset, macDataSize);
  21823. +*/
  21824. + pDigest = (mvCesaSramAddrGet() + pReq->frags.newDigestOffset);
  21825. +
  21826. + macMode = (pSA->config & MV_CESA_MAC_MODE_MASK) >> MV_CESA_MAC_MODE_OFFSET;
  21827. +/*
  21828. + mvOsPrintf("macDataSize=%d, macLength=%d, digestOffset=%d, macMode=%d\n",
  21829. + macDataSize, pCmd->macLength, pCmd->digestOffset, macMode);
  21830. +*/
  21831. + switch(macMode)
  21832. + {
  21833. + case MV_CESA_MAC_HMAC_MD5:
  21834. + pOuterIV = pSA->pSramSA->macOuterIV;
  21835. +
  21836. + case MV_CESA_MAC_MD5:
  21837. + mvCesaFragMd5Complete(pCmd->pDst, pReq->frags.bufOffset, pOuterIV,
  21838. + macDataSize, pCmd->macLength, pDigest);
  21839. + break;
  21840. +
  21841. + case MV_CESA_MAC_HMAC_SHA1:
  21842. + pOuterIV = pSA->pSramSA->macOuterIV;
  21843. +
  21844. + case MV_CESA_MAC_SHA1:
  21845. + mvCesaFragSha1Complete(pCmd->pDst, pReq->frags.bufOffset, pOuterIV,
  21846. + macDataSize, pCmd->macLength, pDigest);
  21847. + break;
  21848. +
  21849. + default:
  21850. + mvOsPrintf("mvCesaFragAuthComplete: Unexpected macMode %d\n", macMode);
  21851. + return MV_BAD_PARAM;
  21852. + }
  21853. + return MV_OK;
  21854. +}
  21855. +
  21856. +/*******************************************************************************
  21857. +* mvCesaCtrModeInit -
  21858. +*
  21859. +* DESCRIPTION:
  21860. +*
  21861. +*
  21862. +* INPUT: NONE
  21863. +*
  21864. +*
  21865. +* RETURN:
  21866. +* MV_CESA_COMMAND*
  21867. +*
  21868. +*******************************************************************************/
  21869. +static MV_CESA_COMMAND* mvCesaCtrModeInit(void)
  21870. +{
  21871. + MV_CESA_MBUF *pMbuf;
  21872. + MV_U8 *pBuf;
  21873. + MV_CESA_COMMAND *pCmd;
  21874. +
  21875. + pBuf = mvOsMalloc(sizeof(MV_CESA_COMMAND) +
  21876. + sizeof(MV_CESA_MBUF) + sizeof(MV_BUF_INFO) + 100);
  21877. + if(pBuf == NULL)
  21878. + {
  21879. + mvOsPrintf("mvCesaSessionOpen: Can't allocate %u bytes for CTR Mode\n",
  21880. + sizeof(MV_CESA_COMMAND) + sizeof(MV_CESA_MBUF) + sizeof(MV_BUF_INFO) );
  21881. + return NULL;
  21882. + }
  21883. + pCmd = (MV_CESA_COMMAND*)pBuf;
  21884. + pBuf += sizeof(MV_CESA_COMMAND);
  21885. +
  21886. + pMbuf = (MV_CESA_MBUF*)pBuf;
  21887. + pBuf += sizeof(MV_CESA_MBUF);
  21888. +
  21889. + pMbuf->pFrags = (MV_BUF_INFO*)pBuf;
  21890. +
  21891. + pMbuf->numFrags = 1;
  21892. + pCmd->pSrc = pMbuf;
  21893. + pCmd->pDst = pMbuf;
  21894. +/*
  21895. + mvOsPrintf("CtrModeInit: pCmd=%p, pSrc=%p, pDst=%p, pFrags=%p\n",
  21896. + pCmd, pCmd->pSrc, pCmd->pDst,
  21897. + pMbuf->pFrags);
  21898. +*/
  21899. + return pCmd;
  21900. +}
  21901. +
  21902. +/*******************************************************************************
  21903. +* mvCesaCtrModePrepare -
  21904. +*
  21905. +* DESCRIPTION:
  21906. +*
  21907. +*
  21908. +* INPUT:
  21909. +* MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd
  21910. +*
  21911. +* RETURN:
  21912. +* MV_STATUS
  21913. +*
  21914. +*******************************************************************************/
  21915. +static MV_STATUS mvCesaCtrModePrepare(MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd)
  21916. +{
  21917. + MV_CESA_MBUF *pMbuf;
  21918. + MV_U8 *pBuf, *pIV;
  21919. + MV_U32 counter, *pCounter;
  21920. + int cryptoSize = MV_ALIGN_UP(pCmd->cryptoLength, MV_CESA_AES_BLOCK_SIZE);
  21921. +/*
  21922. + mvOsPrintf("CtrModePrepare: pCmd=%p, pCtrSrc=%p, pCtrDst=%p, pOrgCmd=%p, pOrgSrc=%p, pOrgDst=%p\n",
  21923. + pCmd, pCmd->pSrc, pCmd->pDst,
  21924. + pCtrModeCmd, pCtrModeCmd->pSrc, pCtrModeCmd->pDst);
  21925. +*/
  21926. + pMbuf = pCtrModeCmd->pSrc;
  21927. +
  21928. + /* Allocate buffer for Key stream */
  21929. + pBuf = mvOsIoCachedMalloc(cesaOsHandle,cryptoSize,
  21930. + &pMbuf->pFrags[0].bufPhysAddr,
  21931. + &pMbuf->pFrags[0].memHandle);
  21932. + if(pBuf == NULL)
  21933. + {
  21934. + mvOsPrintf("mvCesaCtrModePrepare: Can't allocate %d bytes\n", cryptoSize);
  21935. + return MV_OUT_OF_CPU_MEM;
  21936. + }
  21937. + memset(pBuf, 0, cryptoSize);
  21938. + mvOsCacheFlush(NULL, pBuf, cryptoSize);
  21939. +
  21940. + pMbuf->pFrags[0].bufVirtPtr = pBuf;
  21941. + pMbuf->mbufSize = cryptoSize;
  21942. + pMbuf->pFrags[0].bufSize = cryptoSize;
  21943. +
  21944. + pCtrModeCmd->pReqPrv = pCmd->pReqPrv;
  21945. + pCtrModeCmd->sessionId = pCmd->sessionId;
  21946. +
  21947. + /* ivFromUser and ivOffset are don't care */
  21948. + pCtrModeCmd->cryptoOffset = 0;
  21949. + pCtrModeCmd->cryptoLength = cryptoSize;
  21950. +
  21951. + /* digestOffset, macOffset and macLength are don't care */
  21952. +
  21953. + mvCesaCopyFromMbuf(pBuf, pCmd->pSrc, pCmd->ivOffset, MV_CESA_AES_BLOCK_SIZE);
  21954. + pCounter = (MV_U32*)(pBuf + (MV_CESA_AES_BLOCK_SIZE - sizeof(counter)));
  21955. + counter = *pCounter;
  21956. + counter = MV_32BIT_BE(counter);
  21957. + pIV = pBuf;
  21958. + cryptoSize -= MV_CESA_AES_BLOCK_SIZE;
  21959. +
  21960. + /* fill key stream */
  21961. + while(cryptoSize > 0)
  21962. + {
  21963. + pBuf += MV_CESA_AES_BLOCK_SIZE;
  21964. + memcpy(pBuf, pIV, MV_CESA_AES_BLOCK_SIZE - sizeof(counter));
  21965. + pCounter = (MV_U32*)(pBuf + (MV_CESA_AES_BLOCK_SIZE - sizeof(counter)));
  21966. + counter++;
  21967. + *pCounter = MV_32BIT_BE(counter);
  21968. + cryptoSize -= MV_CESA_AES_BLOCK_SIZE;
  21969. + }
  21970. +
  21971. + return MV_OK;
  21972. +}
  21973. +
  21974. +/*******************************************************************************
  21975. +* mvCesaCtrModeComplete -
  21976. +*
  21977. +* DESCRIPTION:
  21978. +*
  21979. +*
  21980. +* INPUT:
  21981. +* MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd
  21982. +*
  21983. +* RETURN:
  21984. +* MV_STATUS
  21985. +*
  21986. +*******************************************************************************/
  21987. +static MV_STATUS mvCesaCtrModeComplete(MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd)
  21988. +{
  21989. + int srcFrag, dstFrag, srcOffset, dstOffset, keyOffset, srcSize, dstSize;
  21990. + int cryptoSize = pCmd->cryptoLength;
  21991. + MV_U8 *pSrc, *pDst, *pKey;
  21992. + MV_STATUS status = MV_OK;
  21993. +/*
  21994. + mvOsPrintf("CtrModeComplete: pCmd=%p, pCtrSrc=%p, pCtrDst=%p, pOrgCmd=%p, pOrgSrc=%p, pOrgDst=%p\n",
  21995. + pCmd, pCmd->pSrc, pCmd->pDst,
  21996. + pOrgCmd, pOrgCmd->pSrc, pOrgCmd->pDst);
  21997. +*/
  21998. + /* XOR source data with key stream to destination data */
  21999. + pKey = pCmd->pDst->pFrags[0].bufVirtPtr;
  22000. + keyOffset = 0;
  22001. +
  22002. + if( (pOrgCmd->pSrc != pOrgCmd->pDst) &&
  22003. + (pOrgCmd->cryptoOffset > 0) )
  22004. + {
  22005. + /* Copy Prefix from source buffer to destination buffer */
  22006. +
  22007. + status = mvCesaMbufCopy(pOrgCmd->pDst, 0,
  22008. + pOrgCmd->pSrc, 0, pOrgCmd->cryptoOffset);
  22009. +/*
  22010. + status = mvCesaCopyFromMbuf(tempBuf, pOrgCmd->pSrc,
  22011. + 0, pOrgCmd->cryptoOffset);
  22012. + status = mvCesaCopyToMbuf(tempBuf, pOrgCmd->pDst,
  22013. + 0, pOrgCmd->cryptoOffset);
  22014. +*/
  22015. + }
  22016. +
  22017. + srcFrag = mvCesaMbufOffset(pOrgCmd->pSrc, pOrgCmd->cryptoOffset, &srcOffset);
  22018. + pSrc = pOrgCmd->pSrc->pFrags[srcFrag].bufVirtPtr;
  22019. + srcSize = pOrgCmd->pSrc->pFrags[srcFrag].bufSize;
  22020. +
  22021. + dstFrag = mvCesaMbufOffset(pOrgCmd->pDst, pOrgCmd->cryptoOffset, &dstOffset);
  22022. + pDst = pOrgCmd->pDst->pFrags[dstFrag].bufVirtPtr;
  22023. + dstSize = pOrgCmd->pDst->pFrags[dstFrag].bufSize;
  22024. +
  22025. + while(cryptoSize > 0)
  22026. + {
  22027. + pDst[dstOffset] = (pSrc[srcOffset] ^ pKey[keyOffset]);
  22028. +
  22029. + cryptoSize--;
  22030. + dstOffset++;
  22031. + srcOffset++;
  22032. + keyOffset++;
  22033. +
  22034. + if(srcOffset >= srcSize)
  22035. + {
  22036. + srcFrag++;
  22037. + srcOffset = 0;
  22038. + pSrc = pOrgCmd->pSrc->pFrags[srcFrag].bufVirtPtr;
  22039. + srcSize = pOrgCmd->pSrc->pFrags[srcFrag].bufSize;
  22040. + }
  22041. +
  22042. + if(dstOffset >= dstSize)
  22043. + {
  22044. + dstFrag++;
  22045. + dstOffset = 0;
  22046. + pDst = pOrgCmd->pDst->pFrags[dstFrag].bufVirtPtr;
  22047. + dstSize = pOrgCmd->pDst->pFrags[dstFrag].bufSize;
  22048. + }
  22049. + }
  22050. +
  22051. + if(pOrgCmd->pSrc != pOrgCmd->pDst)
  22052. + {
  22053. + /* Copy Suffix from source buffer to destination buffer */
  22054. + srcOffset = pOrgCmd->cryptoOffset + pOrgCmd->cryptoLength;
  22055. +
  22056. + if( (pOrgCmd->pDst->mbufSize - srcOffset) > 0)
  22057. + {
  22058. + status = mvCesaMbufCopy(pOrgCmd->pDst, srcOffset,
  22059. + pOrgCmd->pSrc, srcOffset,
  22060. + pOrgCmd->pDst->mbufSize - srcOffset);
  22061. + }
  22062. +
  22063. +/*
  22064. + status = mvCesaCopyFromMbuf(tempBuf, pOrgCmd->pSrc,
  22065. + srcOffset, pOrgCmd->pSrc->mbufSize - srcOffset);
  22066. + status = mvCesaCopyToMbuf(tempBuf, pOrgCmd->pDst,
  22067. + srcOffset, pOrgCmd->pDst->mbufSize - srcOffset);
  22068. +*/
  22069. + }
  22070. +
  22071. + /* Free buffer used for Key stream */
  22072. + mvOsIoCachedFree(cesaOsHandle,pCmd->pDst->pFrags[0].bufSize,
  22073. + pCmd->pDst->pFrags[0].bufPhysAddr,
  22074. + pCmd->pDst->pFrags[0].bufVirtPtr,
  22075. + pCmd->pDst->pFrags[0].memHandle);
  22076. +
  22077. + return MV_OK;
  22078. +}
  22079. +
  22080. +/*******************************************************************************
  22081. +* mvCesaCtrModeFinish -
  22082. +*
  22083. +* DESCRIPTION:
  22084. +*
  22085. +*
  22086. +* INPUT:
  22087. +* MV_CESA_COMMAND* pCmd
  22088. +*
  22089. +* RETURN:
  22090. +* MV_STATUS
  22091. +*
  22092. +*******************************************************************************/
  22093. +static void mvCesaCtrModeFinish(MV_CESA_COMMAND* pCmd)
  22094. +{
  22095. + mvOsFree(pCmd);
  22096. +}
  22097. +
  22098. +/*******************************************************************************
  22099. +* mvCesaParamCheck -
  22100. +*
  22101. +* DESCRIPTION:
  22102. +*
  22103. +*
  22104. +* INPUT:
  22105. +* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, MV_U8* pFixOffset
  22106. +*
  22107. +* RETURN:
  22108. +* MV_STATUS
  22109. +*
  22110. +*******************************************************************************/
  22111. +static MV_STATUS mvCesaParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd,
  22112. + MV_U8* pFixOffset)
  22113. +{
  22114. + MV_U8 fixOffset = 0xFF;
  22115. +
  22116. + /* Check AUTH operation parameters */
  22117. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  22118. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET)) )
  22119. + {
  22120. + /* MAC offset should be at least 4 byte aligned */
  22121. + if( MV_IS_NOT_ALIGN(pCmd->macOffset, 4) )
  22122. + {
  22123. + mvOsPrintf("mvCesaAction: macOffset %d must be 4 byte aligned\n",
  22124. + pCmd->macOffset);
  22125. + return MV_BAD_PARAM;
  22126. + }
  22127. + /* Digest offset must be 4 byte aligned */
  22128. + if( MV_IS_NOT_ALIGN(pCmd->digestOffset, 4) )
  22129. + {
  22130. + mvOsPrintf("mvCesaAction: digestOffset %d must be 4 byte aligned\n",
  22131. + pCmd->digestOffset);
  22132. + return MV_BAD_PARAM;
  22133. + }
  22134. + /* In addition all offsets should be the same alignment: 8 or 4 */
  22135. + if(fixOffset == 0xFF)
  22136. + {
  22137. + fixOffset = (pCmd->macOffset % 8);
  22138. + }
  22139. + else
  22140. + {
  22141. + if( (pCmd->macOffset % 8) != fixOffset)
  22142. + {
  22143. + mvOsPrintf("mvCesaAction: macOffset %d mod 8 must be equal %d\n",
  22144. + pCmd->macOffset, fixOffset);
  22145. + return MV_BAD_PARAM;
  22146. + }
  22147. + }
  22148. + if( (pCmd->digestOffset % 8) != fixOffset)
  22149. + {
  22150. + mvOsPrintf("mvCesaAction: digestOffset %d mod 8 must be equal %d\n",
  22151. + pCmd->digestOffset, fixOffset);
  22152. + return MV_BAD_PARAM;
  22153. + }
  22154. + }
  22155. + /* Check CRYPTO operation parameters */
  22156. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  22157. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) )
  22158. + {
  22159. + /* CryptoOffset should be at least 4 byte aligned */
  22160. + if( MV_IS_NOT_ALIGN(pCmd->cryptoOffset, 4) )
  22161. + {
  22162. + mvOsPrintf("CesaAction: cryptoOffset=%d must be 4 byte aligned\n",
  22163. + pCmd->cryptoOffset);
  22164. + return MV_BAD_PARAM;
  22165. + }
  22166. + /* cryptoLength should be the whole number of blocks */
  22167. + if( MV_IS_NOT_ALIGN(pCmd->cryptoLength, pSA->cryptoBlockSize) )
  22168. + {
  22169. + mvOsPrintf("mvCesaAction: cryptoLength=%d must be %d byte aligned\n",
  22170. + pCmd->cryptoLength, pSA->cryptoBlockSize);
  22171. + return MV_BAD_PARAM;
  22172. + }
  22173. + if(fixOffset == 0xFF)
  22174. + {
  22175. + fixOffset = (pCmd->cryptoOffset % 8);
  22176. + }
  22177. + else
  22178. + {
  22179. + /* In addition all offsets should be the same alignment: 8 or 4 */
  22180. + if( (pCmd->cryptoOffset % 8) != fixOffset)
  22181. + {
  22182. + mvOsPrintf("mvCesaAction: cryptoOffset %d mod 8 must be equal %d \n",
  22183. + pCmd->cryptoOffset, fixOffset);
  22184. + return MV_BAD_PARAM;
  22185. + }
  22186. + }
  22187. +
  22188. + /* check for CBC mode */
  22189. + if(pSA->cryptoIvSize > 0)
  22190. + {
  22191. + /* cryptoIV must not be part of CryptoLength */
  22192. + if( ((pCmd->ivOffset + pSA->cryptoIvSize) > pCmd->cryptoOffset) &&
  22193. + (pCmd->ivOffset < (pCmd->cryptoOffset + pCmd->cryptoLength)) )
  22194. + {
  22195. + mvOsPrintf("mvCesaFragParamCheck: cryptoIvOffset (%d) is part of cryptoLength (%d+%d)\n",
  22196. + pCmd->ivOffset, pCmd->macOffset, pCmd->macLength);
  22197. + return MV_BAD_PARAM;
  22198. + }
  22199. +
  22200. + /* ivOffset must be 4 byte aligned */
  22201. + if( MV_IS_NOT_ALIGN(pCmd->ivOffset, 4) )
  22202. + {
  22203. + mvOsPrintf("CesaAction: ivOffset=%d must be 4 byte aligned\n",
  22204. + pCmd->ivOffset);
  22205. + return MV_BAD_PARAM;
  22206. + }
  22207. + /* In addition all offsets should be the same alignment: 8 or 4 */
  22208. + if( (pCmd->ivOffset % 8) != fixOffset)
  22209. + {
  22210. + mvOsPrintf("mvCesaAction: ivOffset %d mod 8 must be %d\n",
  22211. + pCmd->ivOffset, fixOffset);
  22212. + return MV_BAD_PARAM;
  22213. + }
  22214. + }
  22215. + }
  22216. + return MV_OK;
  22217. +}
  22218. +
  22219. +/*******************************************************************************
  22220. +* mvCesaFragParamCheck -
  22221. +*
  22222. +* DESCRIPTION:
  22223. +*
  22224. +*
  22225. +* INPUT:
  22226. +* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd
  22227. +*
  22228. +* RETURN:
  22229. +* MV_STATUS
  22230. +*
  22231. +*******************************************************************************/
  22232. +static MV_STATUS mvCesaFragParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd)
  22233. +{
  22234. + int offset;
  22235. +
  22236. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  22237. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET)) )
  22238. + {
  22239. + /* macOffset must be less that SRAM buffer size */
  22240. + if(pCmd->macOffset > (sizeof(cesaSramVirtPtr->buf) - MV_CESA_AUTH_BLOCK_SIZE))
  22241. + {
  22242. + mvOsPrintf("mvCesaFragParamCheck: macOffset is too large (%d)\n",
  22243. + pCmd->macOffset);
  22244. + return MV_BAD_PARAM;
  22245. + }
  22246. + /* macOffset+macSize must be more than mbufSize - SRAM buffer size */
  22247. + if( ((pCmd->macOffset + pCmd->macLength) > pCmd->pSrc->mbufSize) ||
  22248. + ((pCmd->pSrc->mbufSize - (pCmd->macOffset + pCmd->macLength)) >=
  22249. + sizeof(cesaSramVirtPtr->buf)) )
  22250. + {
  22251. + mvOsPrintf("mvCesaFragParamCheck: macLength is too large (%d), mbufSize=%d\n",
  22252. + pCmd->macLength, pCmd->pSrc->mbufSize);
  22253. + return MV_BAD_PARAM;
  22254. + }
  22255. + }
  22256. +
  22257. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  22258. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) )
  22259. + {
  22260. + /* cryptoOffset must be less that SRAM buffer size */
  22261. + /* 4 for possible fixOffset */
  22262. + if( (pCmd->cryptoOffset + 4) > (sizeof(cesaSramVirtPtr->buf) - pSA->cryptoBlockSize))
  22263. + {
  22264. + mvOsPrintf("mvCesaFragParamCheck: cryptoOffset is too large (%d)\n",
  22265. + pCmd->cryptoOffset);
  22266. + return MV_BAD_PARAM;
  22267. + }
  22268. +
  22269. + /* cryptoOffset+cryptoSize must be more than mbufSize - SRAM buffer size */
  22270. + if( ((pCmd->cryptoOffset + pCmd->cryptoLength) > pCmd->pSrc->mbufSize) ||
  22271. + ((pCmd->pSrc->mbufSize - (pCmd->cryptoOffset + pCmd->cryptoLength)) >=
  22272. + (sizeof(cesaSramVirtPtr->buf) - pSA->cryptoBlockSize)) )
  22273. + {
  22274. + mvOsPrintf("mvCesaFragParamCheck: cryptoLength is too large (%d), mbufSize=%d\n",
  22275. + pCmd->cryptoLength, pCmd->pSrc->mbufSize);
  22276. + return MV_BAD_PARAM;
  22277. + }
  22278. + }
  22279. +
  22280. + /* When MAC_THEN_CRYPTO or CRYPTO_THEN_MAC */
  22281. + if( ((pSA->config & MV_CESA_OPERATION_MASK) ==
  22282. + (MV_CESA_MAC_THEN_CRYPTO << MV_CESA_OPERATION_OFFSET)) ||
  22283. + ((pSA->config & MV_CESA_OPERATION_MASK) ==
  22284. + (MV_CESA_CRYPTO_THEN_MAC << MV_CESA_OPERATION_OFFSET)) )
  22285. + {
  22286. + if( (mvCtrlModelGet() == MV_5182_DEV_ID) ||
  22287. + ( (mvCtrlModelGet() == MV_5181_DEV_ID) &&
  22288. + (mvCtrlRevGet() >= MV_5181L_A0_REV) &&
  22289. + (pCmd->macLength >= (1 << 14)) ) )
  22290. + {
  22291. + return MV_NOT_ALLOWED;
  22292. + }
  22293. +
  22294. + /* abs(cryptoOffset-macOffset) must be aligned cryptoBlockSize */
  22295. + if(pCmd->cryptoOffset > pCmd->macOffset)
  22296. + {
  22297. + offset = pCmd->cryptoOffset - pCmd->macOffset;
  22298. + }
  22299. + else
  22300. + {
  22301. + offset = pCmd->macOffset - pCmd->cryptoOffset;
  22302. + }
  22303. +
  22304. + if( MV_IS_NOT_ALIGN(offset, pSA->cryptoBlockSize) )
  22305. + {
  22306. +/*
  22307. + mvOsPrintf("mvCesaFragParamCheck: (cryptoOffset - macOffset) must be %d byte aligned\n",
  22308. + pSA->cryptoBlockSize);
  22309. +*/
  22310. + return MV_NOT_ALLOWED;
  22311. + }
  22312. + /* Digest must not be part of CryptoLength */
  22313. + if( ((pCmd->digestOffset + pSA->digestSize) > pCmd->cryptoOffset) &&
  22314. + (pCmd->digestOffset < (pCmd->cryptoOffset + pCmd->cryptoLength)) )
  22315. + {
  22316. +/*
  22317. + mvOsPrintf("mvCesaFragParamCheck: digestOffset (%d) is part of cryptoLength (%d+%d)\n",
  22318. + pCmd->digestOffset, pCmd->cryptoOffset, pCmd->cryptoLength);
  22319. +*/
  22320. + return MV_NOT_ALLOWED;
  22321. + }
  22322. + }
  22323. + return MV_OK;
  22324. +}
  22325. +
  22326. +/*******************************************************************************
  22327. +* mvCesaFragSizeFind -
  22328. +*
  22329. +* DESCRIPTION:
  22330. +*
  22331. +*
  22332. +* INPUT:
  22333. +* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd,
  22334. +* int cryptoOffset, int macOffset,
  22335. +*
  22336. +* OUTPUT:
  22337. +* int* pCopySize, int* pCryptoDataSize, int* pMacDataSize
  22338. +*
  22339. +* RETURN:
  22340. +* MV_STATUS
  22341. +*
  22342. +*******************************************************************************/
  22343. +static void mvCesaFragSizeFind(MV_CESA_SA* pSA, MV_CESA_REQ* pReq,
  22344. + int cryptoOffset, int macOffset,
  22345. + int* pCopySize, int* pCryptoDataSize, int* pMacDataSize)
  22346. +{
  22347. + MV_CESA_COMMAND *pCmd = pReq->pCmd;
  22348. + int cryptoDataSize, macDataSize, copySize;
  22349. +
  22350. + cryptoDataSize = macDataSize = 0;
  22351. + copySize = *pCopySize;
  22352. +
  22353. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  22354. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )
  22355. + {
  22356. + cryptoDataSize = MV_MIN( (copySize - cryptoOffset),
  22357. + (pCmd->cryptoLength - (pReq->frags.cryptoSize + 1)) );
  22358. +
  22359. + /* cryptoSize for each fragment must be the whole number of blocksSize */
  22360. + if( MV_IS_NOT_ALIGN(cryptoDataSize, pSA->cryptoBlockSize) )
  22361. + {
  22362. + cryptoDataSize = MV_ALIGN_DOWN(cryptoDataSize, pSA->cryptoBlockSize);
  22363. + copySize = cryptoOffset + cryptoDataSize;
  22364. + }
  22365. + }
  22366. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  22367. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  22368. + {
  22369. + macDataSize = MV_MIN( (copySize - macOffset),
  22370. + (pCmd->macLength - (pReq->frags.macSize + 1)));
  22371. +
  22372. + /* macSize for each fragment (except last) must be the whole number of blocksSize */
  22373. + if( MV_IS_NOT_ALIGN(macDataSize, MV_CESA_AUTH_BLOCK_SIZE) )
  22374. + {
  22375. + macDataSize = MV_ALIGN_DOWN(macDataSize, MV_CESA_AUTH_BLOCK_SIZE);
  22376. + copySize = macOffset + macDataSize;
  22377. + }
  22378. + cryptoDataSize = copySize - cryptoOffset;
  22379. + }
  22380. + *pCopySize = copySize;
  22381. +
  22382. + if(pCryptoDataSize != NULL)
  22383. + *pCryptoDataSize = cryptoDataSize;
  22384. +
  22385. + if(pMacDataSize != NULL)
  22386. + *pMacDataSize = macDataSize;
  22387. +}
  22388. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvCesaDebug.c linux-2.6.35/crypto/ocf/kirkwood/cesa/mvCesaDebug.c
  22389. --- linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvCesaDebug.c 1970-01-01 01:00:00.000000000 +0100
  22390. +++ linux-2.6.35/crypto/ocf/kirkwood/cesa/mvCesaDebug.c 2010-08-05 22:02:10.524868337 +0200
  22391. @@ -0,0 +1,484 @@
  22392. +/*******************************************************************************
  22393. +Copyright (C) Marvell International Ltd. and its affiliates
  22394. +
  22395. +This software file (the "File") is owned and distributed by Marvell
  22396. +International Ltd. and/or its affiliates ("Marvell") under the following
  22397. +alternative licensing terms. Once you have made an election to distribute the
  22398. +File under one of the following license alternatives, please (i) delete this
  22399. +introductory statement regarding license alternatives, (ii) delete the two
  22400. +license alternatives that you have not elected to use and (iii) preserve the
  22401. +Marvell copyright notice above.
  22402. +
  22403. +********************************************************************************
  22404. +Marvell Commercial License Option
  22405. +
  22406. +If you received this File from Marvell and you have entered into a commercial
  22407. +license agreement (a "Commercial License") with Marvell, the File is licensed
  22408. +to you under the terms of the applicable Commercial License.
  22409. +
  22410. +********************************************************************************
  22411. +Marvell GPL License Option
  22412. +
  22413. +If you received this File from Marvell, you may opt to use, redistribute and/or
  22414. +modify this File in accordance with the terms and conditions of the General
  22415. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  22416. +available along with the File in the license.txt file or by writing to the Free
  22417. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  22418. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  22419. +
  22420. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  22421. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  22422. +DISCLAIMED. The GPL License provides additional details about this warranty
  22423. +disclaimer.
  22424. +********************************************************************************
  22425. +Marvell BSD License Option
  22426. +
  22427. +If you received this File from Marvell, you may opt to use, redistribute and/or
  22428. +modify this File under the following licensing terms.
  22429. +Redistribution and use in source and binary forms, with or without modification,
  22430. +are permitted provided that the following conditions are met:
  22431. +
  22432. + * Redistributions of source code must retain the above copyright notice,
  22433. + this list of conditions and the following disclaimer.
  22434. +
  22435. + * Redistributions in binary form must reproduce the above copyright
  22436. + notice, this list of conditions and the following disclaimer in the
  22437. + documentation and/or other materials provided with the distribution.
  22438. +
  22439. + * Neither the name of Marvell nor the names of its contributors may be
  22440. + used to endorse or promote products derived from this software without
  22441. + specific prior written permission.
  22442. +
  22443. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  22444. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  22445. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22446. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  22447. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22448. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22449. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  22450. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22451. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  22452. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  22453. +
  22454. +*******************************************************************************/
  22455. +
  22456. +#include "mvOs.h"
  22457. +#include "mvDebug.h"
  22458. +
  22459. +#include "cesa/mvMD5.h"
  22460. +#include "cesa/mvSHA1.h"
  22461. +
  22462. +#include "cesa/mvCesa.h"
  22463. +#include "cesa/mvCesaRegs.h"
  22464. +#include "cesa/AES/mvAes.h"
  22465. +
  22466. +static const char* mvCesaDebugStateStr(MV_CESA_STATE state)
  22467. +{
  22468. + switch(state)
  22469. + {
  22470. + case MV_CESA_IDLE:
  22471. + return "Idle";
  22472. +
  22473. + case MV_CESA_PENDING:
  22474. + return "Pend";
  22475. +
  22476. + case MV_CESA_PROCESS:
  22477. + return "Proc";
  22478. +
  22479. + case MV_CESA_READY:
  22480. + return "Ready";
  22481. +
  22482. + default:
  22483. + break;
  22484. + }
  22485. + return "Unknown";
  22486. +}
  22487. +
  22488. +static const char* mvCesaDebugOperStr(MV_CESA_OPERATION oper)
  22489. +{
  22490. + switch(oper)
  22491. + {
  22492. + case MV_CESA_MAC_ONLY:
  22493. + return "MacOnly";
  22494. +
  22495. + case MV_CESA_CRYPTO_ONLY:
  22496. + return "CryptoOnly";
  22497. +
  22498. + case MV_CESA_MAC_THEN_CRYPTO:
  22499. + return "MacCrypto";
  22500. +
  22501. + case MV_CESA_CRYPTO_THEN_MAC:
  22502. + return "CryptoMac";
  22503. +
  22504. + default:
  22505. + break;
  22506. + }
  22507. + return "Null";
  22508. +}
  22509. +
  22510. +static const char* mvCesaDebugCryptoAlgStr(MV_CESA_CRYPTO_ALG cryptoAlg)
  22511. +{
  22512. + switch(cryptoAlg)
  22513. + {
  22514. + case MV_CESA_CRYPTO_DES:
  22515. + return "DES";
  22516. +
  22517. + case MV_CESA_CRYPTO_3DES:
  22518. + return "3DES";
  22519. +
  22520. + case MV_CESA_CRYPTO_AES:
  22521. + return "AES";
  22522. +
  22523. + default:
  22524. + break;
  22525. + }
  22526. + return "Null";
  22527. +}
  22528. +
  22529. +static const char* mvCesaDebugMacModeStr(MV_CESA_MAC_MODE macMode)
  22530. +{
  22531. + switch(macMode)
  22532. + {
  22533. + case MV_CESA_MAC_MD5:
  22534. + return "MD5";
  22535. +
  22536. + case MV_CESA_MAC_SHA1:
  22537. + return "SHA1";
  22538. +
  22539. + case MV_CESA_MAC_HMAC_MD5:
  22540. + return "HMAC-MD5";
  22541. +
  22542. + case MV_CESA_MAC_HMAC_SHA1:
  22543. + return "HMAC_SHA1";
  22544. +
  22545. + default:
  22546. + break;
  22547. + }
  22548. + return "Null";
  22549. +}
  22550. +
  22551. +void mvCesaDebugCmd(MV_CESA_COMMAND* pCmd, int mode)
  22552. +{
  22553. + mvOsPrintf("pCmd=%p, pReqPrv=%p, pSrc=%p, pDst=%p, pCB=%p, sid=%d\n",
  22554. + pCmd, pCmd->pReqPrv, pCmd->pSrc, pCmd->pDst,
  22555. + pCmd->pFuncCB, pCmd->sessionId);
  22556. + mvOsPrintf("isUser=%d, ivOffs=%d, crOffs=%d, crLen=%d, digest=%d, macOffs=%d, macLen=%d\n",
  22557. + pCmd->ivFromUser, pCmd->ivOffset, pCmd->cryptoOffset, pCmd->cryptoLength,
  22558. + pCmd->digestOffset, pCmd->macOffset, pCmd->macLength);
  22559. +}
  22560. +
  22561. +/* no need to use in tool */
  22562. +void mvCesaDebugMbuf(const char* str, MV_CESA_MBUF *pMbuf, int offset, int size)
  22563. +{
  22564. + int frag, len, fragOffset;
  22565. +
  22566. + if(str != NULL)
  22567. + mvOsPrintf("%s: pMbuf=%p, numFrags=%d, mbufSize=%d\n",
  22568. + str, pMbuf, pMbuf->numFrags, pMbuf->mbufSize);
  22569. +
  22570. + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
  22571. + if(frag == MV_INVALID)
  22572. + {
  22573. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  22574. + return;
  22575. + }
  22576. +
  22577. + for(; frag<pMbuf->numFrags; frag++)
  22578. + {
  22579. + mvOsPrintf("#%2d. bufVirt=%p, bufSize=%d\n",
  22580. + frag, pMbuf->pFrags[frag].bufVirtPtr,
  22581. + pMbuf->pFrags[frag].bufSize);
  22582. + if(size > 0)
  22583. + {
  22584. + len = MV_MIN(pMbuf->pFrags[frag].bufSize, size);
  22585. + mvDebugMemDump(pMbuf->pFrags[frag].bufVirtPtr+fragOffset, len, 1);
  22586. + size -= len;
  22587. + fragOffset = 0;
  22588. + }
  22589. + }
  22590. +}
  22591. +
  22592. +void mvCesaDebugRegs(void)
  22593. +{
  22594. + mvOsPrintf("\t CESA Registers:\n");
  22595. +
  22596. + mvOsPrintf("MV_CESA_CMD_REG : 0x%X = 0x%08x\n",
  22597. + MV_CESA_CMD_REG,
  22598. + MV_REG_READ( MV_CESA_CMD_REG ) );
  22599. +
  22600. + mvOsPrintf("MV_CESA_CHAN_DESC_OFFSET_REG : 0x%X = 0x%08x\n",
  22601. + MV_CESA_CHAN_DESC_OFFSET_REG,
  22602. + MV_REG_READ(MV_CESA_CHAN_DESC_OFFSET_REG) );
  22603. +
  22604. + mvOsPrintf("MV_CESA_CFG_REG : 0x%X = 0x%08x\n",
  22605. + MV_CESA_CFG_REG,
  22606. + MV_REG_READ( MV_CESA_CFG_REG ) );
  22607. +
  22608. + mvOsPrintf("MV_CESA_STATUS_REG : 0x%X = 0x%08x\n",
  22609. + MV_CESA_STATUS_REG,
  22610. + MV_REG_READ( MV_CESA_STATUS_REG ) );
  22611. +
  22612. + mvOsPrintf("MV_CESA_ISR_CAUSE_REG : 0x%X = 0x%08x\n",
  22613. + MV_CESA_ISR_CAUSE_REG,
  22614. + MV_REG_READ( MV_CESA_ISR_CAUSE_REG ) );
  22615. +
  22616. + mvOsPrintf("MV_CESA_ISR_MASK_REG : 0x%X = 0x%08x\n",
  22617. + MV_CESA_ISR_MASK_REG,
  22618. + MV_REG_READ( MV_CESA_ISR_MASK_REG ) );
  22619. +#if (MV_CESA_VERSION >= 2)
  22620. + mvOsPrintf("MV_CESA_TDMA_CTRL_REG : 0x%X = 0x%08x\n",
  22621. + MV_CESA_TDMA_CTRL_REG,
  22622. + MV_REG_READ( MV_CESA_TDMA_CTRL_REG ) );
  22623. +
  22624. + mvOsPrintf("MV_CESA_TDMA_BYTE_COUNT_REG : 0x%X = 0x%08x\n",
  22625. + MV_CESA_TDMA_BYTE_COUNT_REG,
  22626. + MV_REG_READ( MV_CESA_TDMA_BYTE_COUNT_REG ) );
  22627. +
  22628. + mvOsPrintf("MV_CESA_TDMA_SRC_ADDR_REG : 0x%X = 0x%08x\n",
  22629. + MV_CESA_TDMA_SRC_ADDR_REG,
  22630. + MV_REG_READ( MV_CESA_TDMA_SRC_ADDR_REG ) );
  22631. +
  22632. + mvOsPrintf("MV_CESA_TDMA_DST_ADDR_REG : 0x%X = 0x%08x\n",
  22633. + MV_CESA_TDMA_DST_ADDR_REG,
  22634. + MV_REG_READ( MV_CESA_TDMA_DST_ADDR_REG ) );
  22635. +
  22636. + mvOsPrintf("MV_CESA_TDMA_NEXT_DESC_PTR_REG : 0x%X = 0x%08x\n",
  22637. + MV_CESA_TDMA_NEXT_DESC_PTR_REG,
  22638. + MV_REG_READ( MV_CESA_TDMA_NEXT_DESC_PTR_REG ) );
  22639. +
  22640. + mvOsPrintf("MV_CESA_TDMA_CURR_DESC_PTR_REG : 0x%X = 0x%08x\n",
  22641. + MV_CESA_TDMA_CURR_DESC_PTR_REG,
  22642. + MV_REG_READ( MV_CESA_TDMA_CURR_DESC_PTR_REG ) );
  22643. +
  22644. + mvOsPrintf("MV_CESA_TDMA_ERROR_CAUSE_REG : 0x%X = 0x%08x\n",
  22645. + MV_CESA_TDMA_ERROR_CAUSE_REG,
  22646. + MV_REG_READ( MV_CESA_TDMA_ERROR_CAUSE_REG ) );
  22647. +
  22648. + mvOsPrintf("MV_CESA_TDMA_ERROR_MASK_REG : 0x%X = 0x%08x\n",
  22649. + MV_CESA_TDMA_ERROR_MASK_REG,
  22650. + MV_REG_READ( MV_CESA_TDMA_ERROR_CAUSE_REG ) );
  22651. +
  22652. +#endif
  22653. +}
  22654. +
  22655. +void mvCesaDebugStatus(void)
  22656. +{
  22657. + mvOsPrintf("\n\t CESA Status\n\n");
  22658. +
  22659. + mvOsPrintf("pReqQ=%p, qDepth=%d, reqSize=%ld bytes, qRes=%d, ",
  22660. + pCesaReqFirst, cesaQueueDepth, sizeof(MV_CESA_REQ),
  22661. + cesaReqResources);
  22662. +#if (MV_CESA_VERSION >= 3)
  22663. + mvOsPrintf("chainLength=%u\n",cesaChainLength);
  22664. +#else
  22665. + mvOsPrintf("\n");
  22666. +#endif
  22667. +
  22668. + mvOsPrintf("pSAD=%p, maxSA=%d, sizeSA=%ld bytes\n",
  22669. + pCesaSAD, cesaMaxSA, sizeof(MV_CESA_SA));
  22670. +
  22671. + mvOsPrintf("\n");
  22672. +
  22673. + mvCesaDebugRegs();
  22674. + mvCesaDebugStats();
  22675. + mvCesaDebugStatsClear();
  22676. +}
  22677. +
  22678. +void mvCesaDebugDescriptor(MV_CESA_DESC* pDesc)
  22679. +{
  22680. + mvOsPrintf("config=0x%08x, crSrcOffs=0x%04x, crDstOffs=0x%04x\n",
  22681. + pDesc->config, pDesc->cryptoSrcOffset, pDesc->cryptoDstOffset);
  22682. +
  22683. + mvOsPrintf("crLen=0x%04x, crKeyOffs=0x%04x, ivOffs=0x%04x, ivBufOffs=0x%04x\n",
  22684. + pDesc->cryptoDataLen, pDesc->cryptoKeyOffset,
  22685. + pDesc->cryptoIvOffset, pDesc->cryptoIvBufOffset);
  22686. +
  22687. + mvOsPrintf("macSrc=0x%04x, digest=0x%04x, macLen=0x%04x, inIv=0x%04x, outIv=0x%04x\n",
  22688. + pDesc->macSrcOffset, pDesc->macDigestOffset, pDesc->macDataLen,
  22689. + pDesc->macInnerIvOffset, pDesc->macOuterIvOffset);
  22690. +}
  22691. +
  22692. +void mvCesaDebugQueue(int mode)
  22693. +{
  22694. + mvOsPrintf("\n\t CESA Request Queue:\n\n");
  22695. +
  22696. + mvOsPrintf("pFirstReq=%p, pLastReq=%p, qDepth=%d, reqSize=%ld bytes\n",
  22697. + pCesaReqFirst, pCesaReqLast, cesaQueueDepth, sizeof(MV_CESA_REQ));
  22698. +
  22699. + mvOsPrintf("pEmpty=%p, pProcess=%p, qResources=%d\n",
  22700. + pCesaReqEmpty, pCesaReqProcess,
  22701. + cesaReqResources);
  22702. +
  22703. + if(mode != 0)
  22704. + {
  22705. + int count = 0;
  22706. + MV_CESA_REQ* pReq = pCesaReqFirst;
  22707. +
  22708. + for(count=0; count<cesaQueueDepth; count++)
  22709. + {
  22710. + /* Print out requsts */
  22711. + mvOsPrintf("%02d. pReq=%p, state=%s, frag=0x%x, pCmd=%p, pDma=%p, pDesc=%p\n",
  22712. + count, pReq, mvCesaDebugStateStr(pReq->state),
  22713. + pReq->fragMode, pReq->pCmd, pReq->dma[0].pDmaFirst, &pReq->pCesaDesc[0]);
  22714. + if(pReq->fragMode != MV_CESA_FRAG_NONE)
  22715. + {
  22716. + int frag;
  22717. +
  22718. + mvOsPrintf("pFrags=%p, num=%d, next=%d, bufOffset=%d, cryptoSize=%d, macSize=%d\n",
  22719. + &pReq->frags, pReq->frags.numFrag, pReq->frags.nextFrag,
  22720. + pReq->frags.bufOffset, pReq->frags.cryptoSize, pReq->frags.macSize);
  22721. + for(frag=0; frag<pReq->frags.numFrag; frag++)
  22722. + {
  22723. + mvOsPrintf("#%d: pDmaFirst=%p, pDesc=%p\n", frag,
  22724. + pReq->dma[frag].pDmaFirst, &pReq->pCesaDesc[frag]);
  22725. + }
  22726. + }
  22727. + if(mode > 1)
  22728. + {
  22729. + /* Print out Command */
  22730. + mvCesaDebugCmd(pReq->pCmd, mode);
  22731. +
  22732. + /* Print out Descriptor */
  22733. + mvCesaDebugDescriptor(&pReq->pCesaDesc[0]);
  22734. + }
  22735. + pReq++;
  22736. + }
  22737. + }
  22738. +}
  22739. +
  22740. +
  22741. +void mvCesaDebugSramSA(MV_CESA_SRAM_SA* pSramSA, int mode)
  22742. +{
  22743. + if(pSramSA == NULL)
  22744. + {
  22745. + mvOsPrintf("cesaSramSA: Unexpected pSramSA=%p\n", pSramSA);
  22746. + return;
  22747. + }
  22748. + mvOsPrintf("pSramSA=%p, sizeSramSA=%ld bytes\n",
  22749. + pSramSA, sizeof(MV_CESA_SRAM_SA));
  22750. +
  22751. + if(mode != 0)
  22752. + {
  22753. + mvOsPrintf("cryptoKey=%p, maxCryptoKey=%d bytes\n",
  22754. + pSramSA->cryptoKey, MV_CESA_MAX_CRYPTO_KEY_LENGTH);
  22755. + mvDebugMemDump(pSramSA->cryptoKey, MV_CESA_MAX_CRYPTO_KEY_LENGTH, 1);
  22756. +
  22757. + mvOsPrintf("macInnerIV=%p, maxInnerIV=%d bytes\n",
  22758. + pSramSA->macInnerIV, MV_CESA_MAX_DIGEST_SIZE);
  22759. + mvDebugMemDump(pSramSA->macInnerIV, MV_CESA_MAX_DIGEST_SIZE, 1);
  22760. +
  22761. + mvOsPrintf("macOuterIV=%p, maxOuterIV=%d bytes\n",
  22762. + pSramSA->macOuterIV, MV_CESA_MAX_DIGEST_SIZE);
  22763. + mvDebugMemDump(pSramSA->macOuterIV, MV_CESA_MAX_DIGEST_SIZE, 1);
  22764. + }
  22765. +}
  22766. +
  22767. +void mvCesaDebugSA(short sid, int mode)
  22768. +{
  22769. + MV_CESA_OPERATION oper;
  22770. + MV_CESA_DIRECTION dir;
  22771. + MV_CESA_CRYPTO_ALG cryptoAlg;
  22772. + MV_CESA_CRYPTO_MODE cryptoMode;
  22773. + MV_CESA_MAC_MODE macMode;
  22774. + MV_CESA_SA* pSA = &pCesaSAD[sid];
  22775. +
  22776. + if( (pSA->valid) || ((pSA->count != 0) && (mode > 0)) || (mode >= 2) )
  22777. + {
  22778. + mvOsPrintf("\n\nCESA SA Entry #%d (%p) - %s (count=%d)\n",
  22779. + sid, pSA,
  22780. + pSA->valid ? "Valid" : "Invalid", pSA->count);
  22781. +
  22782. + oper = (pSA->config & MV_CESA_OPERATION_MASK) >> MV_CESA_OPERATION_OFFSET;
  22783. + dir = (pSA->config & MV_CESA_DIRECTION_MASK) >> MV_CESA_DIRECTION_BIT;
  22784. + mvOsPrintf("%s - %s ", mvCesaDebugOperStr(oper),
  22785. + (dir == MV_CESA_DIR_ENCODE) ? "Encode" : "Decode");
  22786. + if(oper != MV_CESA_MAC_ONLY)
  22787. + {
  22788. + cryptoAlg = (pSA->config & MV_CESA_CRYPTO_ALG_MASK) >> MV_CESA_CRYPTO_ALG_OFFSET;
  22789. + cryptoMode = (pSA->config & MV_CESA_CRYPTO_MODE_MASK) >> MV_CESA_CRYPTO_MODE_BIT;
  22790. + mvOsPrintf("- %s - %s ", mvCesaDebugCryptoAlgStr(cryptoAlg),
  22791. + (cryptoMode == MV_CESA_CRYPTO_ECB) ? "ECB" : "CBC");
  22792. + }
  22793. + if(oper != MV_CESA_CRYPTO_ONLY)
  22794. + {
  22795. + macMode = (pSA->config & MV_CESA_MAC_MODE_MASK) >> MV_CESA_MAC_MODE_OFFSET;
  22796. + mvOsPrintf("- %s ", mvCesaDebugMacModeStr(macMode));
  22797. + }
  22798. + mvOsPrintf("\n");
  22799. +
  22800. + if(mode > 0)
  22801. + {
  22802. + mvOsPrintf("config=0x%08x, cryptoKeySize=%d, digestSize=%d\n",
  22803. + pCesaSAD[sid].config, pCesaSAD[sid].cryptoKeyLength,
  22804. + pCesaSAD[sid].digestSize);
  22805. +
  22806. + mvCesaDebugSramSA(pCesaSAD[sid].pSramSA, mode);
  22807. + }
  22808. + }
  22809. +}
  22810. +
  22811. +
  22812. +/**/
  22813. +void mvCesaDebugSram(int mode)
  22814. +{
  22815. + mvOsPrintf("\n\t SRAM contents: size=%ld, pVirt=%p\n\n",
  22816. + sizeof(MV_CESA_SRAM_MAP), cesaSramVirtPtr);
  22817. +
  22818. + mvOsPrintf("\n\t Sram buffer: size=%d, pVirt=%p\n",
  22819. + MV_CESA_MAX_BUF_SIZE, cesaSramVirtPtr->buf);
  22820. + if(mode != 0)
  22821. + mvDebugMemDump(cesaSramVirtPtr->buf, 64, 1);
  22822. +
  22823. + mvOsPrintf("\n");
  22824. + mvOsPrintf("\n\t Sram descriptor: size=%ld, pVirt=%p\n",
  22825. + sizeof(MV_CESA_DESC), &cesaSramVirtPtr->desc);
  22826. + if(mode != 0)
  22827. + {
  22828. + mvOsPrintf("\n");
  22829. + mvCesaDebugDescriptor(&cesaSramVirtPtr->desc);
  22830. + }
  22831. + mvOsPrintf("\n\t Sram IV: size=%d, pVirt=%p\n",
  22832. + MV_CESA_MAX_IV_LENGTH, &cesaSramVirtPtr->cryptoIV);
  22833. + if(mode != 0)
  22834. + {
  22835. + mvOsPrintf("\n");
  22836. + mvDebugMemDump(cesaSramVirtPtr->cryptoIV, MV_CESA_MAX_IV_LENGTH, 1);
  22837. + }
  22838. + mvOsPrintf("\n");
  22839. + mvCesaDebugSramSA(&cesaSramVirtPtr->sramSA, 0);
  22840. +}
  22841. +
  22842. +void mvCesaDebugSAD(int mode)
  22843. +{
  22844. + int sid;
  22845. +
  22846. + mvOsPrintf("\n\t Cesa SAD status: pSAD=%p, maxSA=%d\n",
  22847. + pCesaSAD, cesaMaxSA);
  22848. +
  22849. + for(sid=0; sid<cesaMaxSA; sid++)
  22850. + {
  22851. + mvCesaDebugSA(sid, mode);
  22852. + }
  22853. +}
  22854. +
  22855. +void mvCesaDebugStats(void)
  22856. +{
  22857. + mvOsPrintf("\n\t Cesa Statistics\n");
  22858. +
  22859. + mvOsPrintf("Opened=%u, Closed=%u\n",
  22860. + cesaStats.openedCount, cesaStats.closedCount);
  22861. + mvOsPrintf("Req=%u, maxReq=%u, frags=%u, start=%u\n",
  22862. + cesaStats.reqCount, cesaStats.maxReqCount,
  22863. + cesaStats.fragCount, cesaStats.startCount);
  22864. +#if (MV_CESA_VERSION >= 3)
  22865. + mvOsPrintf("maxChainUsage=%u\n",cesaStats.maxChainUsage);
  22866. +#endif
  22867. + mvOsPrintf("\n");
  22868. + mvOsPrintf("proc=%u, ready=%u, notReady=%u\n",
  22869. + cesaStats.procCount, cesaStats.readyCount, cesaStats.notReadyCount);
  22870. +}
  22871. +
  22872. +void mvCesaDebugStatsClear(void)
  22873. +{
  22874. + memset(&cesaStats, 0, sizeof(cesaStats));
  22875. +}
  22876. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvCesa.h linux-2.6.35/crypto/ocf/kirkwood/cesa/mvCesa.h
  22877. --- linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvCesa.h 1970-01-01 01:00:00.000000000 +0100
  22878. +++ linux-2.6.35/crypto/ocf/kirkwood/cesa/mvCesa.h 2010-08-05 22:02:10.564867912 +0200
  22879. @@ -0,0 +1,412 @@
  22880. +/*******************************************************************************
  22881. +Copyright (C) Marvell International Ltd. and its affiliates
  22882. +
  22883. +This software file (the "File") is owned and distributed by Marvell
  22884. +International Ltd. and/or its affiliates ("Marvell") under the following
  22885. +alternative licensing terms. Once you have made an election to distribute the
  22886. +File under one of the following license alternatives, please (i) delete this
  22887. +introductory statement regarding license alternatives, (ii) delete the two
  22888. +license alternatives that you have not elected to use and (iii) preserve the
  22889. +Marvell copyright notice above.
  22890. +
  22891. +********************************************************************************
  22892. +Marvell Commercial License Option
  22893. +
  22894. +If you received this File from Marvell and you have entered into a commercial
  22895. +license agreement (a "Commercial License") with Marvell, the File is licensed
  22896. +to you under the terms of the applicable Commercial License.
  22897. +
  22898. +********************************************************************************
  22899. +Marvell GPL License Option
  22900. +
  22901. +If you received this File from Marvell, you may opt to use, redistribute and/or
  22902. +modify this File in accordance with the terms and conditions of the General
  22903. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  22904. +available along with the File in the license.txt file or by writing to the Free
  22905. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  22906. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  22907. +
  22908. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  22909. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  22910. +DISCLAIMED. The GPL License provides additional details about this warranty
  22911. +disclaimer.
  22912. +********************************************************************************
  22913. +Marvell BSD License Option
  22914. +
  22915. +If you received this File from Marvell, you may opt to use, redistribute and/or
  22916. +modify this File under the following licensing terms.
  22917. +Redistribution and use in source and binary forms, with or without modification,
  22918. +are permitted provided that the following conditions are met:
  22919. +
  22920. + * Redistributions of source code must retain the above copyright notice,
  22921. + this list of conditions and the following disclaimer.
  22922. +
  22923. + * Redistributions in binary form must reproduce the above copyright
  22924. + notice, this list of conditions and the following disclaimer in the
  22925. + documentation and/or other materials provided with the distribution.
  22926. +
  22927. + * Neither the name of Marvell nor the names of its contributors may be
  22928. + used to endorse or promote products derived from this software without
  22929. + specific prior written permission.
  22930. +
  22931. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  22932. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  22933. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22934. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  22935. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22936. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22937. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  22938. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22939. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  22940. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  22941. +
  22942. +*******************************************************************************/
  22943. +
  22944. +/*******************************************************************************
  22945. +* mvCesa.h - Header File for Cryptographic Engines and Security Accelerator
  22946. +*
  22947. +* DESCRIPTION:
  22948. +* This header file contains macros typedefs and function declaration for
  22949. +* the Marvell Cryptographic Engines and Security Accelerator.
  22950. +*
  22951. +*******************************************************************************/
  22952. +
  22953. +#ifndef __mvCesa_h__
  22954. +#define __mvCesa_h__
  22955. +
  22956. +#include "mvOs.h"
  22957. +#include "mvCommon.h"
  22958. +#include "mvDebug.h"
  22959. +
  22960. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  22961. +
  22962. +#include "cesa/mvMD5.h"
  22963. +#include "cesa/mvSHA1.h"
  22964. +
  22965. +#include "cesa/mvCesa.h"
  22966. +#include "cesa/AES/mvAes.h"
  22967. +#include "mvSysHwConfig.h"
  22968. +
  22969. +#ifdef MV_INCLUDE_IDMA
  22970. +#include "idma/mvIdma.h"
  22971. +#include "idma/mvIdmaRegs.h"
  22972. +#else
  22973. +/* Redefine MV_DMA_DESC structure */
  22974. +typedef struct _mvDmaDesc
  22975. +{
  22976. + MV_U32 byteCnt; /* The total number of bytes to transfer */
  22977. + MV_U32 phySrcAdd; /* The physical source address */
  22978. + MV_U32 phyDestAdd; /* The physical destination address */
  22979. + MV_U32 phyNextDescPtr; /* If we are using chain mode DMA transfer, */
  22980. + /* then this pointer should point to the */
  22981. + /* physical address of the next descriptor, */
  22982. + /* otherwise it should be NULL. */
  22983. +}MV_DMA_DESC;
  22984. +#endif /* MV_INCLUDE_IDMA */
  22985. +
  22986. +#include "cesa/mvCesaRegs.h"
  22987. +
  22988. +#define MV_CESA_AUTH_BLOCK_SIZE 64 /* bytes */
  22989. +
  22990. +#define MV_CESA_MD5_DIGEST_SIZE 16 /* bytes */
  22991. +#define MV_CESA_SHA1_DIGEST_SIZE 20 /* bytes */
  22992. +
  22993. +#define MV_CESA_MAX_DIGEST_SIZE MV_CESA_SHA1_DIGEST_SIZE
  22994. +
  22995. +#define MV_CESA_DES_KEY_LENGTH 8 /* bytes = 64 bits */
  22996. +#define MV_CESA_3DES_KEY_LENGTH 24 /* bytes = 192 bits */
  22997. +#define MV_CESA_AES_128_KEY_LENGTH 16 /* bytes = 128 bits */
  22998. +#define MV_CESA_AES_192_KEY_LENGTH 24 /* bytes = 192 bits */
  22999. +#define MV_CESA_AES_256_KEY_LENGTH 32 /* bytes = 256 bits */
  23000. +
  23001. +#define MV_CESA_MAX_CRYPTO_KEY_LENGTH MV_CESA_AES_256_KEY_LENGTH
  23002. +
  23003. +#define MV_CESA_DES_BLOCK_SIZE 8 /* bytes = 64 bits */
  23004. +#define MV_CESA_3DES_BLOCK_SIZE 8 /* bytes = 64 bits */
  23005. +
  23006. +#define MV_CESA_AES_BLOCK_SIZE 16 /* bytes = 128 bits */
  23007. +
  23008. +#define MV_CESA_MAX_IV_LENGTH MV_CESA_AES_BLOCK_SIZE
  23009. +
  23010. +#define MV_CESA_MAX_MAC_KEY_LENGTH 64 /* bytes */
  23011. +
  23012. +typedef struct
  23013. +{
  23014. + MV_U8 cryptoKey[MV_CESA_MAX_CRYPTO_KEY_LENGTH];
  23015. + MV_U8 macKey[MV_CESA_MAX_MAC_KEY_LENGTH];
  23016. + MV_CESA_OPERATION operation;
  23017. + MV_CESA_DIRECTION direction;
  23018. + MV_CESA_CRYPTO_ALG cryptoAlgorithm;
  23019. + MV_CESA_CRYPTO_MODE cryptoMode;
  23020. + MV_U8 cryptoKeyLength;
  23021. + MV_CESA_MAC_MODE macMode;
  23022. + MV_U8 macKeyLength;
  23023. + MV_U8 digestSize;
  23024. +
  23025. +} MV_CESA_OPEN_SESSION;
  23026. +
  23027. +typedef struct
  23028. +{
  23029. + MV_BUF_INFO *pFrags;
  23030. + MV_U16 numFrags;
  23031. + MV_U16 mbufSize;
  23032. +
  23033. +} MV_CESA_MBUF;
  23034. +
  23035. +typedef struct
  23036. +{
  23037. + void* pReqPrv; /* instead of reqId */
  23038. + MV_U32 retCode;
  23039. + MV_16 sessionId;
  23040. +
  23041. +} MV_CESA_RESULT;
  23042. +
  23043. +typedef void (*MV_CESA_CALLBACK) (MV_CESA_RESULT* pResult);
  23044. +
  23045. +
  23046. +typedef struct
  23047. +{
  23048. + void* pReqPrv; /* instead of reqId */
  23049. + MV_CESA_MBUF* pSrc;
  23050. + MV_CESA_MBUF* pDst;
  23051. + MV_CESA_CALLBACK* pFuncCB;
  23052. + MV_16 sessionId;
  23053. + MV_U16 ivFromUser;
  23054. + MV_U16 ivOffset;
  23055. + MV_U16 cryptoOffset;
  23056. + MV_U16 cryptoLength;
  23057. + MV_U16 digestOffset;
  23058. + MV_U16 macOffset;
  23059. + MV_U16 macLength;
  23060. + MV_BOOL skipFlush;
  23061. +} MV_CESA_COMMAND;
  23062. +
  23063. +
  23064. +
  23065. +MV_STATUS mvCesaHalInit (int numOfSession, int queueDepth, char* pSramBase, MV_U32 cryptEngBase, void *osHandle);
  23066. +MV_STATUS mvCesaFinish (void);
  23067. +MV_STATUS mvCesaSessionOpen(MV_CESA_OPEN_SESSION *pSession, short* pSid);
  23068. +MV_STATUS mvCesaSessionClose(short sid);
  23069. +MV_STATUS mvCesaCryptoIvSet(MV_U8* pIV, int ivSize);
  23070. +
  23071. +MV_STATUS mvCesaAction (MV_CESA_COMMAND* pCmd);
  23072. +
  23073. +MV_U32 mvCesaInProcessGet(void);
  23074. +MV_STATUS mvCesaReadyDispatch(void);
  23075. +MV_STATUS mvCesaReadyGet(MV_CESA_RESULT* pResult);
  23076. +MV_BOOL mvCesaIsReady(void);
  23077. +
  23078. +int mvCesaMbufOffset(MV_CESA_MBUF* pMbuf, int offset, int* pBufOffset);
  23079. +MV_STATUS mvCesaCopyFromMbuf(MV_U8* pDst, MV_CESA_MBUF* pSrcMbuf,
  23080. + int offset, int size);
  23081. +MV_STATUS mvCesaCopyToMbuf(MV_U8* pSrc, MV_CESA_MBUF* pDstMbuf,
  23082. + int offset, int size);
  23083. +MV_STATUS mvCesaMbufCopy(MV_CESA_MBUF* pMbufDst, int dstMbufOffset,
  23084. + MV_CESA_MBUF* pMbufSrc, int srcMbufOffset, int size);
  23085. +
  23086. +/********** Debug functions ********/
  23087. +
  23088. +void mvCesaDebugMbuf(const char* str, MV_CESA_MBUF *pMbuf, int offset, int size);
  23089. +void mvCesaDebugSA(short sid, int mode);
  23090. +void mvCesaDebugStats(void);
  23091. +void mvCesaDebugStatsClear(void);
  23092. +void mvCesaDebugRegs(void);
  23093. +void mvCesaDebugStatus(void);
  23094. +void mvCesaDebugQueue(int mode);
  23095. +void mvCesaDebugSram(int mode);
  23096. +void mvCesaDebugSAD(int mode);
  23097. +
  23098. +
  23099. +/******** CESA Private definitions ********/
  23100. +#if (MV_CESA_VERSION >= 2)
  23101. +#if (MV_CACHE_COHERENCY == MV_CACHE_COHER_SW)
  23102. +#define MV_CESA_TDMA_CTRL_VALUE MV_CESA_TDMA_DST_BURST_MASK(MV_CESA_TDMA_BURST_128B) \
  23103. + | MV_CESA_TDMA_SRC_BURST_MASK(MV_CESA_TDMA_BURST_128B) \
  23104. + | MV_CESA_TDMA_OUTSTAND_READ_EN_MASK \
  23105. + | MV_CESA_TDMA_NO_BYTE_SWAP_MASK \
  23106. + | MV_CESA_TDMA_ENABLE_MASK
  23107. +#else
  23108. +#define MV_CESA_TDMA_CTRL_VALUE MV_CESA_TDMA_DST_BURST_MASK(MV_CESA_TDMA_BURST_32B) \
  23109. + | MV_CESA_TDMA_SRC_BURST_MASK(MV_CESA_TDMA_BURST_128B) \
  23110. + /*| MV_CESA_TDMA_OUTSTAND_READ_EN_MASK */\
  23111. + | MV_CESA_TDMA_ENABLE_MASK
  23112. +
  23113. +#endif
  23114. +#else
  23115. +#define MV_CESA_IDMA_CTRL_LOW_VALUE ICCLR_DST_BURST_LIM_128BYTE \
  23116. + | ICCLR_SRC_BURST_LIM_128BYTE \
  23117. + | ICCLR_INT_MODE_MASK \
  23118. + | ICCLR_BLOCK_MODE \
  23119. + | ICCLR_CHAN_ENABLE \
  23120. + | ICCLR_DESC_MODE_16M
  23121. +#endif /* MV_CESA_VERSION >= 2 */
  23122. +
  23123. +#define MV_CESA_MAX_PKT_SIZE (64 * 1024)
  23124. +#define MV_CESA_MAX_MBUF_FRAGS 20
  23125. +
  23126. +#define MV_CESA_MAX_REQ_FRAGS ( (MV_CESA_MAX_PKT_SIZE / MV_CESA_MAX_BUF_SIZE) + 1)
  23127. +
  23128. +#define MV_CESA_MAX_DMA_DESC (MV_CESA_MAX_MBUF_FRAGS*2 + 5)
  23129. +
  23130. +#define MAX_CESA_CHAIN_LENGTH 20
  23131. +
  23132. +typedef enum
  23133. +{
  23134. + MV_CESA_IDLE = 0,
  23135. + MV_CESA_PENDING,
  23136. + MV_CESA_PROCESS,
  23137. + MV_CESA_READY,
  23138. +#if (MV_CESA_VERSION >= 3)
  23139. + MV_CESA_CHAIN,
  23140. +#endif
  23141. +} MV_CESA_STATE;
  23142. +
  23143. +
  23144. +/* Session database */
  23145. +
  23146. +/* Map of Key materials of the session in SRAM.
  23147. + * Each field must be 8 byte aligned
  23148. + * Total size: 32 + 24 + 24 = 80 bytes
  23149. + */
  23150. +typedef struct
  23151. +{
  23152. + MV_U8 cryptoKey[MV_CESA_MAX_CRYPTO_KEY_LENGTH];
  23153. + MV_U8 macInnerIV[MV_CESA_MAX_DIGEST_SIZE];
  23154. + MV_U8 reservedInner[4];
  23155. + MV_U8 macOuterIV[MV_CESA_MAX_DIGEST_SIZE];
  23156. + MV_U8 reservedOuter[4];
  23157. +
  23158. +} MV_CESA_SRAM_SA;
  23159. +
  23160. +typedef struct
  23161. +{
  23162. + MV_CESA_SRAM_SA* pSramSA;
  23163. + MV_U32 config;
  23164. + MV_U8 cryptoKeyLength;
  23165. + MV_U8 cryptoIvSize;
  23166. + MV_U8 cryptoBlockSize;
  23167. + MV_U8 digestSize;
  23168. + MV_U8 macKeyLength;
  23169. + MV_U8 valid;
  23170. + MV_U8 ctrMode;
  23171. + MV_U32 count;
  23172. +
  23173. +} MV_CESA_SA;
  23174. +
  23175. +/* DMA list management */
  23176. +typedef struct
  23177. +{
  23178. + MV_DMA_DESC* pDmaFirst;
  23179. + MV_DMA_DESC* pDmaLast;
  23180. +
  23181. +} MV_CESA_DMA;
  23182. +
  23183. +
  23184. +typedef struct
  23185. +{
  23186. + MV_U8 numFrag;
  23187. + MV_U8 nextFrag;
  23188. + int bufOffset;
  23189. + int cryptoSize;
  23190. + int macSize;
  23191. + int newDigestOffset;
  23192. + MV_U8 orgDigest[MV_CESA_MAX_DIGEST_SIZE];
  23193. +
  23194. +} MV_CESA_FRAGS;
  23195. +
  23196. +/* Request queue */
  23197. +typedef struct
  23198. +{
  23199. + MV_U8 state;
  23200. + MV_U8 fragMode;
  23201. + MV_U8 fixOffset;
  23202. + MV_CESA_COMMAND* pCmd;
  23203. + MV_CESA_COMMAND* pOrgCmd;
  23204. + MV_BUF_INFO dmaDescBuf;
  23205. + MV_CESA_DMA dma[MV_CESA_MAX_REQ_FRAGS];
  23206. + MV_BUF_INFO cesaDescBuf;
  23207. + MV_CESA_DESC* pCesaDesc;
  23208. + MV_CESA_FRAGS frags;
  23209. +
  23210. +
  23211. +} MV_CESA_REQ;
  23212. +
  23213. +
  23214. +/* SRAM map */
  23215. +/* Total SRAM size calculation */
  23216. +/* SRAM size =
  23217. + * MV_CESA_MAX_BUF_SIZE +
  23218. + * sizeof(MV_CESA_DESC) +
  23219. + * MV_CESA_MAX_IV_LENGTH +
  23220. + * MV_CESA_MAX_IV_LENGTH +
  23221. + * MV_CESA_MAX_DIGEST_SIZE +
  23222. + * sizeof(MV_CESA_SRAM_SA)
  23223. + * = 1600 + 32 + 16 + 16 + 24 + 80 + 280 (reserved) = 2048 bytes
  23224. + * = 3200 + 32 + 16 + 16 + 24 + 80 + 728 (reserved) = 4096 bytes
  23225. + */
  23226. +typedef struct
  23227. +{
  23228. + MV_U8 buf[MV_CESA_MAX_BUF_SIZE];
  23229. + MV_CESA_DESC desc;
  23230. + MV_U8 cryptoIV[MV_CESA_MAX_IV_LENGTH];
  23231. + MV_U8 tempCryptoIV[MV_CESA_MAX_IV_LENGTH];
  23232. + MV_U8 tempDigest[MV_CESA_MAX_DIGEST_SIZE+4];
  23233. + MV_CESA_SRAM_SA sramSA;
  23234. +
  23235. +} MV_CESA_SRAM_MAP;
  23236. +
  23237. +
  23238. +typedef struct
  23239. +{
  23240. + MV_U32 openedCount;
  23241. + MV_U32 closedCount;
  23242. + MV_U32 fragCount;
  23243. + MV_U32 reqCount;
  23244. + MV_U32 maxReqCount;
  23245. + MV_U32 procCount;
  23246. + MV_U32 readyCount;
  23247. + MV_U32 notReadyCount;
  23248. + MV_U32 startCount;
  23249. +#if (MV_CESA_VERSION >= 3)
  23250. + MV_U32 maxChainUsage;
  23251. +#endif
  23252. +
  23253. +} MV_CESA_STATS;
  23254. +
  23255. +
  23256. +/* External variables */
  23257. +
  23258. +extern MV_CESA_STATS cesaStats;
  23259. +extern MV_CESA_FRAGS cesaFrags;
  23260. +
  23261. +extern MV_BUF_INFO cesaSramSaBuf;
  23262. +
  23263. +extern MV_CESA_SA* pCesaSAD;
  23264. +extern MV_U16 cesaMaxSA;
  23265. +
  23266. +extern MV_CESA_REQ* pCesaReqFirst;
  23267. +extern MV_CESA_REQ* pCesaReqLast;
  23268. +extern MV_CESA_REQ* pCesaReqEmpty;
  23269. +extern MV_CESA_REQ* pCesaReqProcess;
  23270. +extern int cesaQueueDepth;
  23271. +extern int cesaReqResources;
  23272. +#if (MV_CESA_VERSION>= 3)
  23273. +extern MV_U32 cesaChainLength;
  23274. +#endif
  23275. +
  23276. +extern MV_CESA_SRAM_MAP* cesaSramVirtPtr;
  23277. +extern MV_U32 cesaSramPhysAddr;
  23278. +
  23279. +static INLINE MV_ULONG mvCesaVirtToPhys(MV_BUF_INFO* pBufInfo, void* pVirt)
  23280. +{
  23281. + return (pBufInfo->bufPhysAddr + ((MV_U8*)pVirt - pBufInfo->bufVirtPtr));
  23282. +}
  23283. +
  23284. +/* Additional DEBUG functions */
  23285. +void mvCesaDebugSramSA(MV_CESA_SRAM_SA* pSramSA, int mode);
  23286. +void mvCesaDebugCmd(MV_CESA_COMMAND* pCmd, int mode);
  23287. +void mvCesaDebugDescriptor(MV_CESA_DESC* pDesc);
  23288. +
  23289. +
  23290. +
  23291. +#endif /* __mvCesa_h__ */
  23292. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvCesaRegs.h linux-2.6.35/crypto/ocf/kirkwood/cesa/mvCesaRegs.h
  23293. --- linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvCesaRegs.h 1970-01-01 01:00:00.000000000 +0100
  23294. +++ linux-2.6.35/crypto/ocf/kirkwood/cesa/mvCesaRegs.h 2010-08-05 22:02:10.624867891 +0200
  23295. @@ -0,0 +1,357 @@
  23296. +/*******************************************************************************
  23297. +Copyright (C) Marvell International Ltd. and its affiliates
  23298. +
  23299. +This software file (the "File") is owned and distributed by Marvell
  23300. +International Ltd. and/or its affiliates ("Marvell") under the following
  23301. +alternative licensing terms. Once you have made an election to distribute the
  23302. +File under one of the following license alternatives, please (i) delete this
  23303. +introductory statement regarding license alternatives, (ii) delete the two
  23304. +license alternatives that you have not elected to use and (iii) preserve the
  23305. +Marvell copyright notice above.
  23306. +
  23307. +********************************************************************************
  23308. +Marvell Commercial License Option
  23309. +
  23310. +If you received this File from Marvell and you have entered into a commercial
  23311. +license agreement (a "Commercial License") with Marvell, the File is licensed
  23312. +to you under the terms of the applicable Commercial License.
  23313. +
  23314. +********************************************************************************
  23315. +Marvell GPL License Option
  23316. +
  23317. +If you received this File from Marvell, you may opt to use, redistribute and/or
  23318. +modify this File in accordance with the terms and conditions of the General
  23319. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  23320. +available along with the File in the license.txt file or by writing to the Free
  23321. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  23322. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  23323. +
  23324. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  23325. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  23326. +DISCLAIMED. The GPL License provides additional details about this warranty
  23327. +disclaimer.
  23328. +********************************************************************************
  23329. +Marvell BSD License Option
  23330. +
  23331. +If you received this File from Marvell, you may opt to use, redistribute and/or
  23332. +modify this File under the following licensing terms.
  23333. +Redistribution and use in source and binary forms, with or without modification,
  23334. +are permitted provided that the following conditions are met:
  23335. +
  23336. + * Redistributions of source code must retain the above copyright notice,
  23337. + this list of conditions and the following disclaimer.
  23338. +
  23339. + * Redistributions in binary form must reproduce the above copyright
  23340. + notice, this list of conditions and the following disclaimer in the
  23341. + documentation and/or other materials provided with the distribution.
  23342. +
  23343. + * Neither the name of Marvell nor the names of its contributors may be
  23344. + used to endorse or promote products derived from this software without
  23345. + specific prior written permission.
  23346. +
  23347. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  23348. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  23349. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  23350. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  23351. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23352. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23353. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  23354. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23355. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23356. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23357. +
  23358. +*******************************************************************************/
  23359. +
  23360. +#ifndef __mvCesaRegs_h__
  23361. +#define __mvCesaRegs_h__
  23362. +
  23363. +#include "mvTypes.h"
  23364. +
  23365. +typedef struct
  23366. +{
  23367. + /* word 0 */
  23368. + MV_U32 config;
  23369. + /* word 1 */
  23370. + MV_U16 cryptoSrcOffset;
  23371. + MV_U16 cryptoDstOffset;
  23372. + /* word 2 */
  23373. + MV_U16 cryptoDataLen;
  23374. + MV_U16 reserved1;
  23375. + /* word 3 */
  23376. + MV_U16 cryptoKeyOffset;
  23377. + MV_U16 reserved2;
  23378. + /* word 4 */
  23379. + MV_U16 cryptoIvOffset;
  23380. + MV_U16 cryptoIvBufOffset;
  23381. + /* word 5 */
  23382. + MV_U16 macSrcOffset;
  23383. + MV_U16 macTotalLen;
  23384. + /* word 6 */
  23385. + MV_U16 macDigestOffset;
  23386. + MV_U16 macDataLen;
  23387. + /* word 7 */
  23388. + MV_U16 macInnerIvOffset;
  23389. + MV_U16 macOuterIvOffset;
  23390. +
  23391. +} MV_CESA_DESC;
  23392. +
  23393. +/* operation */
  23394. +typedef enum
  23395. +{
  23396. + MV_CESA_MAC_ONLY = 0,
  23397. + MV_CESA_CRYPTO_ONLY = 1,
  23398. + MV_CESA_MAC_THEN_CRYPTO = 2,
  23399. + MV_CESA_CRYPTO_THEN_MAC = 3,
  23400. +
  23401. + MV_CESA_MAX_OPERATION
  23402. +
  23403. +} MV_CESA_OPERATION;
  23404. +
  23405. +#define MV_CESA_OPERATION_OFFSET 0
  23406. +#define MV_CESA_OPERATION_MASK (0x3 << MV_CESA_OPERATION_OFFSET)
  23407. +
  23408. +/* mac algorithm */
  23409. +typedef enum
  23410. +{
  23411. + MV_CESA_MAC_NULL = 0,
  23412. + MV_CESA_MAC_MD5 = 4,
  23413. + MV_CESA_MAC_SHA1 = 5,
  23414. + MV_CESA_MAC_HMAC_MD5 = 6,
  23415. + MV_CESA_MAC_HMAC_SHA1 = 7,
  23416. +
  23417. +} MV_CESA_MAC_MODE;
  23418. +
  23419. +#define MV_CESA_MAC_MODE_OFFSET 4
  23420. +#define MV_CESA_MAC_MODE_MASK (0x7 << MV_CESA_MAC_MODE_OFFSET)
  23421. +
  23422. +typedef enum
  23423. +{
  23424. + MV_CESA_MAC_DIGEST_FULL = 0,
  23425. + MV_CESA_MAC_DIGEST_96B = 1,
  23426. +
  23427. +} MV_CESA_MAC_DIGEST_SIZE;
  23428. +
  23429. +#define MV_CESA_MAC_DIGEST_SIZE_BIT 7
  23430. +#define MV_CESA_MAC_DIGEST_SIZE_MASK (1 << MV_CESA_MAC_DIGEST_SIZE_BIT)
  23431. +
  23432. +
  23433. +typedef enum
  23434. +{
  23435. + MV_CESA_CRYPTO_NULL = 0,
  23436. + MV_CESA_CRYPTO_DES = 1,
  23437. + MV_CESA_CRYPTO_3DES = 2,
  23438. + MV_CESA_CRYPTO_AES = 3,
  23439. +
  23440. +} MV_CESA_CRYPTO_ALG;
  23441. +
  23442. +#define MV_CESA_CRYPTO_ALG_OFFSET 8
  23443. +#define MV_CESA_CRYPTO_ALG_MASK (0x3 << MV_CESA_CRYPTO_ALG_OFFSET)
  23444. +
  23445. +
  23446. +/* direction */
  23447. +typedef enum
  23448. +{
  23449. + MV_CESA_DIR_ENCODE = 0,
  23450. + MV_CESA_DIR_DECODE = 1,
  23451. +
  23452. +} MV_CESA_DIRECTION;
  23453. +
  23454. +#define MV_CESA_DIRECTION_BIT 12
  23455. +#define MV_CESA_DIRECTION_MASK (1 << MV_CESA_DIRECTION_BIT)
  23456. +
  23457. +/* crypto IV mode */
  23458. +typedef enum
  23459. +{
  23460. + MV_CESA_CRYPTO_ECB = 0,
  23461. + MV_CESA_CRYPTO_CBC = 1,
  23462. +
  23463. + /* NO HW Support */
  23464. + MV_CESA_CRYPTO_CTR = 10,
  23465. +
  23466. +} MV_CESA_CRYPTO_MODE;
  23467. +
  23468. +#define MV_CESA_CRYPTO_MODE_BIT 16
  23469. +#define MV_CESA_CRYPTO_MODE_MASK (1 << MV_CESA_CRYPTO_MODE_BIT)
  23470. +
  23471. +/* 3DES mode */
  23472. +typedef enum
  23473. +{
  23474. + MV_CESA_CRYPTO_3DES_EEE = 0,
  23475. + MV_CESA_CRYPTO_3DES_EDE = 1,
  23476. +
  23477. +} MV_CESA_CRYPTO_3DES_MODE;
  23478. +
  23479. +#define MV_CESA_CRYPTO_3DES_MODE_BIT 20
  23480. +#define MV_CESA_CRYPTO_3DES_MODE_MASK (1 << MV_CESA_CRYPTO_3DES_MODE_BIT)
  23481. +
  23482. +
  23483. +/* AES Key Length */
  23484. +typedef enum
  23485. +{
  23486. + MV_CESA_CRYPTO_AES_KEY_128 = 0,
  23487. + MV_CESA_CRYPTO_AES_KEY_192 = 1,
  23488. + MV_CESA_CRYPTO_AES_KEY_256 = 2,
  23489. +
  23490. +} MV_CESA_CRYPTO_AES_KEY_LEN;
  23491. +
  23492. +#define MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET 24
  23493. +#define MV_CESA_CRYPTO_AES_KEY_LEN_MASK (0x3 << MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET)
  23494. +
  23495. +/* Fragmentation mode */
  23496. +typedef enum
  23497. +{
  23498. + MV_CESA_FRAG_NONE = 0,
  23499. + MV_CESA_FRAG_FIRST = 1,
  23500. + MV_CESA_FRAG_LAST = 2,
  23501. + MV_CESA_FRAG_MIDDLE = 3,
  23502. +
  23503. +} MV_CESA_FRAG_MODE;
  23504. +
  23505. +#define MV_CESA_FRAG_MODE_OFFSET 30
  23506. +#define MV_CESA_FRAG_MODE_MASK (0x3 << MV_CESA_FRAG_MODE_OFFSET)
  23507. +/*---------------------------------------------------------------------------*/
  23508. +
  23509. +/********** Security Accelerator Command Register **************/
  23510. +#define MV_CESA_CMD_REG (MV_CESA_REG_BASE + 0xE00)
  23511. +
  23512. +#define MV_CESA_CMD_CHAN_ENABLE_BIT 0
  23513. +#define MV_CESA_CMD_CHAN_ENABLE_MASK (1 << MV_CESA_CMD_CHAN_ENABLE_BIT)
  23514. +
  23515. +#define MV_CESA_CMD_CHAN_DISABLE_BIT 2
  23516. +#define MV_CESA_CMD_CHAN_DISABLE_MASK (1 << MV_CESA_CMD_CHAN_DISABLE_BIT)
  23517. +
  23518. +/********** Security Accelerator Descriptor Pointers Register **********/
  23519. +#define MV_CESA_CHAN_DESC_OFFSET_REG (MV_CESA_REG_BASE + 0xE04)
  23520. +
  23521. +/********** Security Accelerator Configuration Register **********/
  23522. +#define MV_CESA_CFG_REG (MV_CESA_REG_BASE + 0xE08)
  23523. +
  23524. +#define MV_CESA_CFG_STOP_DIGEST_ERR_BIT 0
  23525. +#define MV_CESA_CFG_STOP_DIGEST_ERR_MASK (1 << MV_CESA_CFG_STOP_DIGEST_ERR_BIT)
  23526. +
  23527. +#define MV_CESA_CFG_WAIT_DMA_BIT 7
  23528. +#define MV_CESA_CFG_WAIT_DMA_MASK (1 << MV_CESA_CFG_WAIT_DMA_BIT)
  23529. +
  23530. +#define MV_CESA_CFG_ACT_DMA_BIT 9
  23531. +#define MV_CESA_CFG_ACT_DMA_MASK (1 << MV_CESA_CFG_ACT_DMA_BIT)
  23532. +
  23533. +#define MV_CESA_CFG_CHAIN_MODE_BIT 11
  23534. +#define MV_CESA_CFG_CHAIN_MODE_MASK (1 << MV_CESA_CFG_CHAIN_MODE_BIT)
  23535. +
  23536. +/********** Security Accelerator Status Register ***********/
  23537. +#define MV_CESA_STATUS_REG (MV_CESA_REG_BASE + 0xE0C)
  23538. +
  23539. +#define MV_CESA_STATUS_ACTIVE_BIT 0
  23540. +#define MV_CESA_STATUS_ACTIVE_MASK (1 << MV_CESA_STATUS_ACTIVE_BIT)
  23541. +
  23542. +#define MV_CESA_STATUS_DIGEST_ERR_BIT 8
  23543. +#define MV_CESA_STATUS_DIGEST_ERR_MASK (1 << MV_CESA_STATUS_DIGEST_ERR_BIT)
  23544. +
  23545. +
  23546. +/* Cryptographic Engines and Security Accelerator Interrupt Cause Register */
  23547. +#define MV_CESA_ISR_CAUSE_REG (MV_CESA_REG_BASE + 0xE20)
  23548. +
  23549. +/* Cryptographic Engines and Security Accelerator Interrupt Mask Register */
  23550. +#define MV_CESA_ISR_MASK_REG (MV_CESA_REG_BASE + 0xE24)
  23551. +
  23552. +#define MV_CESA_CAUSE_AUTH_MASK (1 << 0)
  23553. +#define MV_CESA_CAUSE_DES_MASK (1 << 1)
  23554. +#define MV_CESA_CAUSE_AES_ENCR_MASK (1 << 2)
  23555. +#define MV_CESA_CAUSE_AES_DECR_MASK (1 << 3)
  23556. +#define MV_CESA_CAUSE_DES_ALL_MASK (1 << 4)
  23557. +
  23558. +#define MV_CESA_CAUSE_ACC_BIT 5
  23559. +#define MV_CESA_CAUSE_ACC_MASK (1 << MV_CESA_CAUSE_ACC_BIT)
  23560. +
  23561. +#define MV_CESA_CAUSE_ACC_DMA_BIT 7
  23562. +#define MV_CESA_CAUSE_ACC_DMA_MASK (1 << MV_CESA_CAUSE_ACC_DMA_BIT)
  23563. +#define MV_CESA_CAUSE_ACC_DMA_ALL_MASK (3 << MV_CESA_CAUSE_ACC_DMA_BIT)
  23564. +
  23565. +#define MV_CESA_CAUSE_DMA_COMPL_BIT 9
  23566. +#define MV_CESA_CAUSE_DMA_COMPL_MASK (1 << MV_CESA_CAUSE_DMA_COMPL_BIT)
  23567. +
  23568. +#define MV_CESA_CAUSE_DMA_OWN_ERR_BIT 10
  23569. +#define MV_CESA_CAUSE_DMA_OWN_ERR_MASK (1 < MV_CESA_CAUSE_DMA_OWN_ERR_BIT)
  23570. +
  23571. +#define MV_CESA_CAUSE_DMA_CHAIN_PKT_BIT 11
  23572. +#define MV_CESA_CAUSE_DMA_CHAIN_PKT_MASK (1 < MV_CESA_CAUSE_DMA_CHAIN_PKT_BIT)
  23573. +
  23574. +
  23575. +#define MV_CESA_AUTH_DATA_IN_REG (MV_CESA_REG_BASE + 0xd38)
  23576. +#define MV_CESA_AUTH_BIT_COUNT_LOW_REG (MV_CESA_REG_BASE + 0xd20)
  23577. +#define MV_CESA_AUTH_BIT_COUNT_HIGH_REG (MV_CESA_REG_BASE + 0xd24)
  23578. +
  23579. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i) (MV_CESA_REG_BASE + 0xd00 + (i<<2))
  23580. +
  23581. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_A_REG (MV_CESA_REG_BASE + 0xd00)
  23582. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_B_REG (MV_CESA_REG_BASE + 0xd04)
  23583. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_C_REG (MV_CESA_REG_BASE + 0xd08)
  23584. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_D_REG (MV_CESA_REG_BASE + 0xd0c)
  23585. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_E_REG (MV_CESA_REG_BASE + 0xd10)
  23586. +#define MV_CESA_AUTH_COMMAND_REG (MV_CESA_REG_BASE + 0xd18)
  23587. +
  23588. +#define MV_CESA_AUTH_ALGORITHM_BIT 0
  23589. +#define MV_CESA_AUTH_ALGORITHM_MD5 (0<<AUTH_ALGORITHM_BIT)
  23590. +#define MV_CESA_AUTH_ALGORITHM_SHA1 (1<<AUTH_ALGORITHM_BIT)
  23591. +
  23592. +#define MV_CESA_AUTH_IV_MODE_BIT 1
  23593. +#define MV_CESA_AUTH_IV_MODE_INIT (0<<AUTH_IV_MODE_BIT)
  23594. +#define MV_CESA_AUTH_IV_MODE_CONTINUE (1<<AUTH_IV_MODE_BIT)
  23595. +
  23596. +#define MV_CESA_AUTH_DATA_BYTE_SWAP_BIT 2
  23597. +#define MV_CESA_AUTH_DATA_BYTE_SWAP_MASK (1<<AUTH_DATA_BYTE_SWAP_BIT)
  23598. +
  23599. +
  23600. +#define MV_CESA_AUTH_IV_BYTE_SWAP_BIT 4
  23601. +#define MV_CESA_AUTH_IV_BYTE_SWAP_MASK (1<<AUTH_IV_BYTE_SWAP_BIT)
  23602. +
  23603. +#define MV_CESA_AUTH_TERMINATION_BIT 31
  23604. +#define MV_CESA_AUTH_TERMINATION_MASK (1<<AUTH_TERMINATION_BIT)
  23605. +
  23606. +
  23607. +/*************** TDMA Control Register ************************************************/
  23608. +#define MV_CESA_TDMA_CTRL_REG (MV_CESA_TDMA_REG_BASE + 0x840)
  23609. +
  23610. +#define MV_CESA_TDMA_BURST_32B 3
  23611. +#define MV_CESA_TDMA_BURST_128B 4
  23612. +
  23613. +#define MV_CESA_TDMA_DST_BURST_OFFSET 0
  23614. +#define MV_CESA_TDMA_DST_BURST_ALL_MASK (0x7<<MV_CESA_TDMA_DST_BURST_OFFSET)
  23615. +#define MV_CESA_TDMA_DST_BURST_MASK(burst) ((burst)<<MV_CESA_TDMA_DST_BURST_OFFSET)
  23616. +
  23617. +#define MV_CESA_TDMA_OUTSTAND_READ_EN_BIT 4
  23618. +#define MV_CESA_TDMA_OUTSTAND_READ_EN_MASK (1<<MV_CESA_TDMA_OUTSTAND_READ_EN_BIT)
  23619. +
  23620. +#define MV_CESA_TDMA_SRC_BURST_OFFSET 6
  23621. +#define MV_CESA_TDMA_SRC_BURST_ALL_MASK (0x7<<MV_CESA_TDMA_SRC_BURST_OFFSET)
  23622. +#define MV_CESA_TDMA_SRC_BURST_MASK(burst) ((burst)<<MV_CESA_TDMA_SRC_BURST_OFFSET)
  23623. +
  23624. +#define MV_CESA_TDMA_CHAIN_MODE_BIT 9
  23625. +#define MV_CESA_TDMA_NON_CHAIN_MODE_MASK (1<<MV_CESA_TDMA_CHAIN_MODE_BIT)
  23626. +
  23627. +#define MV_CESA_TDMA_BYTE_SWAP_BIT 11
  23628. +#define MV_CESA_TDMA_BYTE_SWAP_MASK (0 << MV_CESA_TDMA_BYTE_SWAP_BIT)
  23629. +#define MV_CESA_TDMA_NO_BYTE_SWAP_MASK (1 << MV_CESA_TDMA_BYTE_SWAP_BIT)
  23630. +
  23631. +#define MV_CESA_TDMA_ENABLE_BIT 12
  23632. +#define MV_CESA_TDMA_ENABLE_MASK (1<<MV_CESA_TDMA_ENABLE_BIT)
  23633. +
  23634. +#define MV_CESA_TDMA_FETCH_NEXT_DESC_BIT 13
  23635. +#define MV_CESA_TDMA_FETCH_NEXT_DESC_MASK (1<<MV_CESA_TDMA_FETCH_NEXT_DESC_BIT)
  23636. +
  23637. +#define MV_CESA_TDMA_CHAN_ACTIVE_BIT 14
  23638. +#define MV_CESA_TDMA_CHAN_ACTIVE_MASK (1<<MV_CESA_TDMA_CHAN_ACTIVE_BIT)
  23639. +/*------------------------------------------------------------------------------------*/
  23640. +
  23641. +#define MV_CESA_TDMA_BYTE_COUNT_REG (MV_CESA_TDMA_REG_BASE + 0x800)
  23642. +#define MV_CESA_TDMA_SRC_ADDR_REG (MV_CESA_TDMA_REG_BASE + 0x810)
  23643. +#define MV_CESA_TDMA_DST_ADDR_REG (MV_CESA_TDMA_REG_BASE + 0x820)
  23644. +#define MV_CESA_TDMA_NEXT_DESC_PTR_REG (MV_CESA_TDMA_REG_BASE + 0x830)
  23645. +#define MV_CESA_TDMA_CURR_DESC_PTR_REG (MV_CESA_TDMA_REG_BASE + 0x870)
  23646. +
  23647. +#define MV_CESA_TDMA_ERROR_CAUSE_REG (MV_CESA_TDMA_REG_BASE + 0x8C0)
  23648. +#define MV_CESA_TDMA_ERROR_MASK_REG (MV_CESA_TDMA_REG_BASE + 0x8C4)
  23649. +
  23650. +
  23651. +#endif /* __mvCesaRegs_h__ */
  23652. +
  23653. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvCesaTest.c linux-2.6.35/crypto/ocf/kirkwood/cesa/mvCesaTest.c
  23654. --- linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvCesaTest.c 1970-01-01 01:00:00.000000000 +0100
  23655. +++ linux-2.6.35/crypto/ocf/kirkwood/cesa/mvCesaTest.c 2010-08-05 22:02:10.873768273 +0200
  23656. @@ -0,0 +1,3096 @@
  23657. +/*******************************************************************************
  23658. +Copyright (C) Marvell International Ltd. and its affiliates
  23659. +
  23660. +This software file (the "File") is owned and distributed by Marvell
  23661. +International Ltd. and/or its affiliates ("Marvell") under the following
  23662. +alternative licensing terms. Once you have made an election to distribute the
  23663. +File under one of the following license alternatives, please (i) delete this
  23664. +introductory statement regarding license alternatives, (ii) delete the two
  23665. +license alternatives that you have not elected to use and (iii) preserve the
  23666. +Marvell copyright notice above.
  23667. +
  23668. +********************************************************************************
  23669. +Marvell Commercial License Option
  23670. +
  23671. +If you received this File from Marvell and you have entered into a commercial
  23672. +license agreement (a "Commercial License") with Marvell, the File is licensed
  23673. +to you under the terms of the applicable Commercial License.
  23674. +
  23675. +********************************************************************************
  23676. +Marvell GPL License Option
  23677. +
  23678. +If you received this File from Marvell, you may opt to use, redistribute and/or
  23679. +modify this File in accordance with the terms and conditions of the General
  23680. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  23681. +available along with the File in the license.txt file or by writing to the Free
  23682. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  23683. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  23684. +
  23685. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  23686. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  23687. +DISCLAIMED. The GPL License provides additional details about this warranty
  23688. +disclaimer.
  23689. +********************************************************************************
  23690. +Marvell BSD License Option
  23691. +
  23692. +If you received this File from Marvell, you may opt to use, redistribute and/or
  23693. +modify this File under the following licensing terms.
  23694. +Redistribution and use in source and binary forms, with or without modification,
  23695. +are permitted provided that the following conditions are met:
  23696. +
  23697. + * Redistributions of source code must retain the above copyright notice,
  23698. + this list of conditions and the following disclaimer.
  23699. +
  23700. + * Redistributions in binary form must reproduce the above copyright
  23701. + notice, this list of conditions and the following disclaimer in the
  23702. + documentation and/or other materials provided with the distribution.
  23703. +
  23704. + * Neither the name of Marvell nor the names of its contributors may be
  23705. + used to endorse or promote products derived from this software without
  23706. + specific prior written permission.
  23707. +
  23708. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  23709. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  23710. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  23711. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  23712. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23713. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23714. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  23715. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23716. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23717. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23718. +
  23719. +*******************************************************************************/
  23720. +
  23721. +#include "mvOs.h"
  23722. +
  23723. +#if defined(MV_VXWORKS)
  23724. +
  23725. +#include "sysLib.h"
  23726. +#include "logLib.h"
  23727. +#include "tickLib.h"
  23728. +#include "intLib.h"
  23729. +#include "config.h"
  23730. +
  23731. +
  23732. +SEM_ID cesaSemId = NULL;
  23733. +SEM_ID cesaWaitSemId = NULL;
  23734. +
  23735. +#define CESA_TEST_LOCK(flags) flags = intLock()
  23736. +#define CESA_TEST_UNLOCK(flags) intUnlock(flags)
  23737. +
  23738. +#define CESA_TEST_WAIT_INIT() cesaWaitSemId = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY)
  23739. +#define CESA_TEST_WAKE_UP() semGive(cesaWaitSemId)
  23740. +#define CESA_TEST_WAIT(cond, ms) semTake(cesaWaitSemId, (sysClkRateGet()*ms)/1000)
  23741. +
  23742. +#define CESA_TEST_TICK_GET() tickGet()
  23743. +#define CESA_TEST_TICK_TO_MS(tick) (((tick)*1000)/sysClkRateGet())
  23744. +
  23745. +#elif defined(MV_LINUX)
  23746. +
  23747. +#include <linux/wait.h>
  23748. +wait_queue_head_t cesaTest_waitq;
  23749. +spinlock_t cesaLock;
  23750. +
  23751. +#define CESA_TEST_LOCK(flags) spin_lock_irqsave( &cesaLock, flags)
  23752. +#define CESA_TEST_UNLOCK(flags) spin_unlock_irqrestore( &cesaLock, flags);
  23753. +
  23754. +#define CESA_TEST_WAIT_INIT() init_waitqueue_head(&cesaTest_waitq)
  23755. +#define CESA_TEST_WAKE_UP() wake_up(&cesaTest_waitq)
  23756. +#define CESA_TEST_WAIT(cond, ms) wait_event_timeout(cesaTest_waitq, (cond), msecs_to_jiffies(ms))
  23757. +
  23758. +#define CESA_TEST_TICK_GET() jiffies
  23759. +#define CESA_TEST_TICK_TO_MS(tick) jiffies_to_msecs(tick)
  23760. +
  23761. +#elif defined(MV_NETBSD)
  23762. +
  23763. +#include <sys/param.h>
  23764. +#include <sys/kernel.h>
  23765. +static int cesaLock;
  23766. +
  23767. +#define CESA_TEST_LOCK(flags) flags = splnet()
  23768. +#define CESA_TEST_UNLOCK(flags) splx(flags)
  23769. +
  23770. +#define CESA_TEST_WAIT_INIT() /* nothing */
  23771. +#define CESA_TEST_WAKE_UP() wakeup(&cesaLock)
  23772. +#define CESA_TEST_WAIT(cond, ms) \
  23773. +do { \
  23774. + while (!(cond)) \
  23775. + tsleep(&cesaLock, PWAIT, "cesatest",mstohz(ms)); \
  23776. +} while (/*CONSTCOND*/0)
  23777. +
  23778. +#define CESA_TEST_TICK_GET() hardclock_ticks
  23779. +#define CESA_TEST_TICK_TO_MS(tick) ((1000/hz)*(tick))
  23780. +
  23781. +#define request_irq(i,h,t,n,a) \
  23782. + !mv_intr_establish((i),IPL_NET,(int(*)(void *))(h),(a))
  23783. +
  23784. +#else
  23785. +#error "Only Linux, VxWorks, or NetBSD OS are supported"
  23786. +#endif
  23787. +
  23788. +#include "mvDebug.h"
  23789. +
  23790. +#include "mvSysHwConfig.h"
  23791. +#include "boardEnv/mvBoardEnvLib.h"
  23792. +#include "ctrlEnv/sys/mvCpuIf.h"
  23793. +#include "cntmr/mvCntmr.h"
  23794. +#include "cesa/mvCesa.h"
  23795. +#include "cesa/mvCesaRegs.h"
  23796. +#include "cesa/mvMD5.h"
  23797. +#include "cesa/mvSHA1.h"
  23798. +
  23799. +#if defined(CONFIG_MV646xx)
  23800. +#include "marvell_pic.h"
  23801. +#endif
  23802. +
  23803. +#define MV_CESA_USE_TIMER_ID 0
  23804. +#define CESA_DEF_BUF_SIZE 1500
  23805. +#define CESA_DEF_BUF_NUM 1
  23806. +#define CESA_DEF_SESSION_NUM 32
  23807. +
  23808. +#define CESA_DEF_ITER_NUM 100
  23809. +
  23810. +#define CESA_DEF_REQ_SIZE 256
  23811. +
  23812. +
  23813. +/* CESA Tests Debug */
  23814. +#undef CESA_TEST_DEBUG
  23815. +
  23816. +#ifdef CESA_TEST_DEBUG
  23817. +
  23818. +# define CESA_TEST_DEBUG_PRINT(msg) mvOsPrintf msg
  23819. +# define CESA_TEST_DEBUG_CODE(code) code
  23820. +
  23821. +typedef struct
  23822. +{
  23823. + int type; /* 0 - isrEmpty, 1 - cesaReadyGet, 2 - cesaAction */
  23824. + MV_U32 timeStamp;
  23825. + MV_U32 cause;
  23826. + MV_U32 realCause;
  23827. + MV_U32 dmaCause;
  23828. + int resources;
  23829. + MV_CESA_REQ* pReqReady;
  23830. + MV_CESA_REQ* pReqEmpty;
  23831. + MV_CESA_REQ* pReqProcess;
  23832. +} MV_CESA_TEST_TRACE;
  23833. +
  23834. +#define MV_CESA_TEST_TRACE_SIZE 25
  23835. +
  23836. +static int cesaTestTraceIdx = 0;
  23837. +static MV_CESA_TEST_TRACE cesaTestTrace[MV_CESA_TEST_TRACE_SIZE];
  23838. +
  23839. +static void cesaTestTraceAdd(int type, MV_U32 cause)
  23840. +{
  23841. + cesaTestTrace[cesaTestTraceIdx].type = type;
  23842. + cesaTestTrace[cesaTestTraceIdx].cause = cause;
  23843. + cesaTestTrace[cesaTestTraceIdx].realCause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  23844. + cesaTestTrace[cesaTestTraceIdx].dmaCause = MV_REG_READ(IDMA_CAUSE_REG);
  23845. + cesaTestTrace[cesaTestTraceIdx].resources = cesaReqResources;
  23846. + cesaTestTrace[cesaTestTraceIdx].pReqReady = pCesaReqReady;
  23847. + cesaTestTrace[cesaTestTraceIdx].pReqEmpty = pCesaReqEmpty;
  23848. + cesaTestTrace[cesaTestTraceIdx].pReqProcess = pCesaReqProcess;
  23849. + cesaTestTrace[cesaTestTraceIdx].timeStamp = mvCntmrRead(MV_CESA_USE_TIMER_ID);
  23850. + cesaTestTraceIdx++;
  23851. + if(cesaTestTraceIdx == MV_CESA_TEST_TRACE_SIZE)
  23852. + cesaTestTraceIdx = 0;
  23853. +}
  23854. +
  23855. +#else
  23856. +
  23857. +# define CESA_TEST_DEBUG_PRINT(msg)
  23858. +# define CESA_TEST_DEBUG_CODE(code)
  23859. +
  23860. +#endif /* CESA_TEST_DEBUG */
  23861. +
  23862. +int cesaExpReqId=0;
  23863. +int cesaCbIter=0;
  23864. +
  23865. +int cesaIdx;
  23866. +int cesaIteration;
  23867. +int cesaRateSize;
  23868. +int cesaReqSize;
  23869. +unsigned long cesaTaskId;
  23870. +int cesaBufNum;
  23871. +int cesaBufSize;
  23872. +int cesaCheckOffset;
  23873. +int cesaCheckSize;
  23874. +int cesaCheckMode;
  23875. +int cesaTestIdx;
  23876. +int cesaCaseIdx;
  23877. +
  23878. +
  23879. +MV_U32 cesaTestIsrCount = 0;
  23880. +MV_U32 cesaTestIsrMissCount = 0;
  23881. +
  23882. +MV_U32 cesaCryptoError = 0;
  23883. +MV_U32 cesaReqIdError = 0;
  23884. +MV_U32 cesaError = 0;
  23885. +
  23886. +char* cesaHexBuffer = NULL;
  23887. +
  23888. +char* cesaBinBuffer = NULL;
  23889. +char* cesaExpBinBuffer = NULL;
  23890. +
  23891. +char* cesaInputHexStr = NULL;
  23892. +char* cesaOutputHexStr = NULL;
  23893. +
  23894. +MV_BUF_INFO cesaReqBufs[CESA_DEF_REQ_SIZE];
  23895. +
  23896. +MV_CESA_COMMAND* cesaCmdRing;
  23897. +MV_CESA_RESULT cesaResult;
  23898. +
  23899. +int cesaTestFull = 0;
  23900. +
  23901. +MV_BOOL cesaIsReady = MV_FALSE;
  23902. +MV_U32 cesaCycles = 0;
  23903. +MV_U32 cesaBeginTicks = 0;
  23904. +MV_U32 cesaEndTicks = 0;
  23905. +MV_U32 cesaRate = 0;
  23906. +MV_U32 cesaRateAfterDot = 0;
  23907. +
  23908. +void *cesaTestOSHandle = NULL;
  23909. +
  23910. +enum
  23911. +{
  23912. + CESA_FAST_CHECK_MODE = 0,
  23913. + CESA_FULL_CHECK_MODE,
  23914. + CESA_NULL_CHECK_MODE,
  23915. + CESA_SHOW_CHECK_MODE,
  23916. + CESA_SW_SHOW_CHECK_MODE,
  23917. + CESA_SW_NULL_CHECK_MODE,
  23918. +
  23919. + CESA_MAX_CHECK_MODE
  23920. +};
  23921. +
  23922. +enum
  23923. +{
  23924. + DES_TEST_TYPE = 0,
  23925. + TRIPLE_DES_TEST_TYPE = 1,
  23926. + AES_TEST_TYPE = 2,
  23927. + MD5_TEST_TYPE = 3,
  23928. + SHA_TEST_TYPE = 4,
  23929. + COMBINED_TEST_TYPE = 5,
  23930. +
  23931. + MAX_TEST_TYPE
  23932. +};
  23933. +
  23934. +/* Tests data base */
  23935. +typedef struct
  23936. +{
  23937. + short sid;
  23938. + char cryptoAlgorithm; /* DES/3DES/AES */
  23939. + char cryptoMode; /* ECB or CBC */
  23940. + char macAlgorithm; /* MD5 / SHA1 */
  23941. + char operation; /* CRYPTO/HMAC/CRYPTO+HMAC/HMAC+CRYPTO */
  23942. + char direction; /* ENCODE(SIGN)/DECODE(VERIFY) */
  23943. + unsigned char* pCryptoKey;
  23944. + int cryptoKeySize;
  23945. + unsigned char* pMacKey;
  23946. + int macKeySize;
  23947. + const char* name;
  23948. +
  23949. +} MV_CESA_TEST_SESSION;
  23950. +
  23951. +typedef struct
  23952. +{
  23953. + MV_CESA_TEST_SESSION* pSessions;
  23954. + int numSessions;
  23955. +
  23956. +} MV_CESA_TEST_DB_ENTRY;
  23957. +
  23958. +typedef struct
  23959. +{
  23960. + char* plainHexStr;
  23961. + char* cipherHexStr;
  23962. + unsigned char* pCryptoIV;
  23963. + int cryptoLength;
  23964. + int macLength;
  23965. + int digestOffset;
  23966. +
  23967. +} MV_CESA_TEST_CASE;
  23968. +
  23969. +typedef struct
  23970. +{
  23971. + int size;
  23972. + const char* outputHexStr;
  23973. +
  23974. +} MV_CESA_SIZE_TEST;
  23975. +
  23976. +static unsigned char cryptoKey1[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
  23977. + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
  23978. + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
  23979. +
  23980. +static unsigned char cryptoKey7[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
  23981. +static unsigned char iv1[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef};
  23982. +
  23983. +
  23984. +static unsigned char cryptoKey2[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  23985. + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
  23986. +
  23987. +static unsigned char cryptoKey3[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  23988. + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
  23989. + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
  23990. +
  23991. +static unsigned char cryptoKey4[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  23992. + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
  23993. + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  23994. + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
  23995. +
  23996. +static unsigned char cryptoKey5[] = {0x56, 0xe4, 0x7a, 0x38, 0xc5, 0x59, 0x89, 0x74,
  23997. + 0xbc, 0x46, 0x90, 0x3d, 0xba, 0x29, 0x03, 0x49};
  23998. +
  23999. +
  24000. +static unsigned char key3des1[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
  24001. + 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
  24002. + 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23};
  24003. +
  24004. +/* Input ASCII string: The quick brown fox jump */
  24005. +static char plain3des1[] = "54686520717566636B2062726F776E20666F78206A756D70";
  24006. +static char cipher3des1[] = "A826FD8CE53B855FCCE21C8112256FE668D5C05DD9B6B900";
  24007. +
  24008. +static unsigned char key3des2[] = {0x62, 0x7f, 0x46, 0x0e, 0x08, 0x10, 0x4a, 0x10,
  24009. + 0x43, 0xcd, 0x26, 0x5d, 0x58, 0x40, 0xea, 0xf1,
  24010. + 0x31, 0x3e, 0xdf, 0x97, 0xdf, 0x2a, 0x8a, 0x8c};
  24011. +
  24012. +static unsigned char iv3des2[] = {0x8e, 0x29, 0xf7, 0x5e, 0xa7, 0x7e, 0x54, 0x75};
  24013. +
  24014. +static char plain3des2[] = "326a494cd33fe756";
  24015. +
  24016. +static char cipher3desCbc2[] = "8e29f75ea77e5475"
  24017. + "b22b8d66de970692";
  24018. +
  24019. +static unsigned char key3des3[] = {0x37, 0xae, 0x5e, 0xbf, 0x46, 0xdf, 0xf2, 0xdc,
  24020. + 0x07, 0x54, 0xb9, 0x4f, 0x31, 0xcb, 0xb3, 0x85,
  24021. + 0x5e, 0x7f, 0xd3, 0x6d, 0xc8, 0x70, 0xbf, 0xae};
  24022. +
  24023. +static unsigned char iv3des3[] = {0x3d, 0x1d, 0xe3, 0xcc, 0x13, 0x2e, 0x3b, 0x65};
  24024. +
  24025. +static char plain3des3[] = "84401f78fe6c10876d8ea23094ea5309";
  24026. +
  24027. +static char cipher3desCbc3[] = "3d1de3cc132e3b65"
  24028. + "7b1f7c7e3b1c948ebd04a75ffba7d2f5";
  24029. +
  24030. +static unsigned char iv5[] = {0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c,
  24031. + 0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9};
  24032. +
  24033. +static unsigned char aesCtrKey[] = {0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
  24034. + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC};
  24035. +
  24036. +static unsigned char mdKey1[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  24037. + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
  24038. +
  24039. +static unsigned char mdKey2[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  24040. + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
  24041. +
  24042. +static unsigned char shaKey1[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  24043. + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  24044. + 0x0b, 0x0b, 0x0b, 0x0b};
  24045. +
  24046. +static unsigned char shaKey2[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  24047. + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  24048. + 0xaa, 0xaa, 0xaa, 0xaa};
  24049. +
  24050. +static unsigned char mdKey4[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24051. + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
  24052. +
  24053. +static unsigned char shaKey4[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24054. + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
  24055. + 0x11, 0x12, 0x13, 0x14};
  24056. +
  24057. +
  24058. +static MV_CESA_TEST_SESSION desTestSessions[] =
  24059. +{
  24060. +/*000*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
  24061. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24062. + MV_CESA_DIR_ENCODE,
  24063. + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
  24064. + NULL, 0,
  24065. + "DES ECB encode",
  24066. + },
  24067. +/*001*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
  24068. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24069. + MV_CESA_DIR_DECODE,
  24070. + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
  24071. + NULL, 0,
  24072. + "DES ECB decode",
  24073. + },
  24074. +/*002*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_CBC,
  24075. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24076. + MV_CESA_DIR_ENCODE,
  24077. + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
  24078. + NULL, 0,
  24079. + "DES CBC encode"
  24080. + },
  24081. +/*003*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_CBC,
  24082. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24083. + MV_CESA_DIR_DECODE,
  24084. + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
  24085. + NULL, 0,
  24086. + "DES CBC decode"
  24087. + },
  24088. +/*004*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24089. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24090. + MV_CESA_DIR_ENCODE,
  24091. + NULL, 0, NULL, 0,
  24092. + "NULL Crypto Algorithm encode"
  24093. + },
  24094. +};
  24095. +
  24096. +
  24097. +static MV_CESA_TEST_SESSION tripleDesTestSessions[] =
  24098. +{
  24099. +/*100*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  24100. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24101. + MV_CESA_DIR_ENCODE,
  24102. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  24103. + NULL, 0,
  24104. + "3DES ECB encode",
  24105. + },
  24106. +/*101*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  24107. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24108. + MV_CESA_DIR_DECODE,
  24109. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  24110. + NULL, 0,
  24111. + "3DES ECB decode",
  24112. + },
  24113. +/*102*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  24114. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24115. + MV_CESA_DIR_ENCODE,
  24116. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  24117. + NULL, 0,
  24118. + "3DES CBC encode"
  24119. + },
  24120. +/*103*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  24121. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24122. + MV_CESA_DIR_DECODE,
  24123. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  24124. + NULL, 0,
  24125. + "3DES CBC decode"
  24126. + },
  24127. +/*104*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  24128. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24129. + MV_CESA_DIR_ENCODE,
  24130. + key3des1, sizeof(key3des1),
  24131. + NULL, 0,
  24132. + "3DES ECB encode"
  24133. + },
  24134. +/*105*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  24135. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24136. + MV_CESA_DIR_ENCODE,
  24137. + key3des2, sizeof(key3des2),
  24138. + NULL, 0,
  24139. + "3DES ECB encode"
  24140. + },
  24141. +/*106*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  24142. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24143. + MV_CESA_DIR_ENCODE,
  24144. + key3des3, sizeof(key3des3),
  24145. + NULL, 0,
  24146. + "3DES ECB encode"
  24147. + },
  24148. +};
  24149. +
  24150. +
  24151. +static MV_CESA_TEST_SESSION aesTestSessions[] =
  24152. +{
  24153. +/*200*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  24154. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24155. + MV_CESA_DIR_ENCODE,
  24156. + cryptoKey2, sizeof(cryptoKey2)/sizeof(cryptoKey2[0]),
  24157. + NULL, 0,
  24158. + "AES-128 ECB encode"
  24159. + },
  24160. +/*201*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  24161. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24162. + MV_CESA_DIR_DECODE,
  24163. + cryptoKey2, sizeof(cryptoKey2)/sizeof(cryptoKey2[0]),
  24164. + NULL, 0,
  24165. + "AES-128 ECB decode"
  24166. + },
  24167. +/*202*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
  24168. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24169. + MV_CESA_DIR_ENCODE,
  24170. + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
  24171. + NULL, 0,
  24172. + "AES-128 CBC encode"
  24173. + },
  24174. +/*203*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
  24175. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24176. + MV_CESA_DIR_DECODE,
  24177. + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
  24178. + NULL, 0,
  24179. + "AES-128 CBC decode"
  24180. + },
  24181. +/*204*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  24182. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24183. + MV_CESA_DIR_ENCODE,
  24184. + cryptoKey3, sizeof(cryptoKey3)/sizeof(cryptoKey3[0]),
  24185. + NULL, 0,
  24186. + "AES-192 ECB encode"
  24187. + },
  24188. +/*205*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  24189. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24190. + MV_CESA_DIR_DECODE,
  24191. + cryptoKey3, sizeof(cryptoKey3)/sizeof(cryptoKey3[0]),
  24192. + NULL, 0,
  24193. + "AES-192 ECB decode"
  24194. + },
  24195. +/*206*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  24196. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24197. + MV_CESA_DIR_ENCODE,
  24198. + cryptoKey4, sizeof(cryptoKey4)/sizeof(cryptoKey4[0]),
  24199. + NULL, 0,
  24200. + "AES-256 ECB encode"
  24201. + },
  24202. +/*207*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  24203. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24204. + MV_CESA_DIR_DECODE,
  24205. + cryptoKey4, sizeof(cryptoKey4)/sizeof(cryptoKey4[0]),
  24206. + NULL, 0,
  24207. + "AES-256 ECB decode"
  24208. + },
  24209. +/*208*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CTR,
  24210. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  24211. + MV_CESA_DIR_ENCODE,
  24212. + aesCtrKey, sizeof(aesCtrKey)/sizeof(aesCtrKey[0]),
  24213. + NULL, 0,
  24214. + "AES-128 CTR encode"
  24215. + },
  24216. +};
  24217. +
  24218. +
  24219. +static MV_CESA_TEST_SESSION md5TestSessions[] =
  24220. +{
  24221. +/*300*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24222. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  24223. + MV_CESA_DIR_ENCODE,
  24224. + NULL, 0,
  24225. + mdKey1, sizeof(mdKey1),
  24226. + "HMAC-MD5 Generate Signature"
  24227. + },
  24228. +/*301*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24229. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  24230. + MV_CESA_DIR_DECODE,
  24231. + NULL, 0,
  24232. + mdKey1, sizeof(mdKey1),
  24233. + "HMAC-MD5 Verify Signature"
  24234. + },
  24235. +/*302*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24236. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  24237. + MV_CESA_DIR_ENCODE,
  24238. + NULL, 0,
  24239. + mdKey2, sizeof(mdKey2),
  24240. + "HMAC-MD5 Generate Signature"
  24241. + },
  24242. +/*303*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24243. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  24244. + MV_CESA_DIR_DECODE,
  24245. + NULL, 0,
  24246. + mdKey2, sizeof(mdKey2),
  24247. + "HMAC-MD5 Verify Signature"
  24248. + },
  24249. +/*304*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24250. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  24251. + MV_CESA_DIR_ENCODE,
  24252. + NULL, 0,
  24253. + mdKey4, sizeof(mdKey4),
  24254. + "HMAC-MD5 Generate Signature"
  24255. + },
  24256. +/*305*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24257. + MV_CESA_MAC_MD5, MV_CESA_MAC_ONLY,
  24258. + MV_CESA_DIR_ENCODE,
  24259. + NULL, 0,
  24260. + NULL, 0,
  24261. + "HASH-MD5 Generate Signature"
  24262. + },
  24263. +};
  24264. +
  24265. +
  24266. +static MV_CESA_TEST_SESSION shaTestSessions[] =
  24267. +{
  24268. +/*400*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24269. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  24270. + MV_CESA_DIR_ENCODE,
  24271. + NULL, 0,
  24272. + shaKey1, sizeof(shaKey1),
  24273. + "HMAC-SHA1 Generate Signature"
  24274. + },
  24275. +/*401*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24276. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  24277. + MV_CESA_DIR_DECODE,
  24278. + NULL, 0,
  24279. + shaKey1, sizeof(shaKey1),
  24280. + "HMAC-SHA1 Verify Signature"
  24281. + },
  24282. +/*402*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24283. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  24284. + MV_CESA_DIR_ENCODE,
  24285. + NULL, 0,
  24286. + shaKey2, sizeof(shaKey2),
  24287. + "HMAC-SHA1 Generate Signature"
  24288. + },
  24289. +/*403*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24290. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  24291. + MV_CESA_DIR_DECODE,
  24292. + NULL, 0,
  24293. + shaKey2, sizeof(shaKey2),
  24294. + "HMAC-SHA1 Verify Signature"
  24295. + },
  24296. +/*404*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24297. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  24298. + MV_CESA_DIR_ENCODE,
  24299. + NULL, 0,
  24300. + shaKey4, sizeof(shaKey4),
  24301. + "HMAC-SHA1 Generate Signature"
  24302. + },
  24303. +/*405*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  24304. + MV_CESA_MAC_SHA1, MV_CESA_MAC_ONLY,
  24305. + MV_CESA_DIR_ENCODE,
  24306. + NULL, 0,
  24307. + NULL, 0,
  24308. + "HASH-SHA1 Generate Signature"
  24309. + },
  24310. +};
  24311. +
  24312. +static MV_CESA_TEST_SESSION combinedTestSessions[] =
  24313. +{
  24314. +/*500*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
  24315. + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
  24316. + MV_CESA_DIR_ENCODE,
  24317. + cryptoKey1, MV_CESA_DES_KEY_LENGTH,
  24318. + mdKey4, sizeof(mdKey4),
  24319. + "DES + MD5 encode"
  24320. + },
  24321. +/*501*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
  24322. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
  24323. + MV_CESA_DIR_ENCODE,
  24324. + cryptoKey1, MV_CESA_DES_KEY_LENGTH,
  24325. + shaKey4, sizeof(shaKey4),
  24326. + "DES + SHA1 encode"
  24327. + },
  24328. +/*502*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  24329. + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
  24330. + MV_CESA_DIR_ENCODE,
  24331. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  24332. + mdKey4, sizeof(mdKey4),
  24333. + "3DES + MD5 encode"
  24334. + },
  24335. +/*503*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  24336. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
  24337. + MV_CESA_DIR_ENCODE,
  24338. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  24339. + shaKey4, sizeof(shaKey4),
  24340. + "3DES + SHA1 encode"
  24341. + },
  24342. +/*504*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  24343. + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
  24344. + MV_CESA_DIR_ENCODE,
  24345. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  24346. + mdKey4, sizeof(mdKey4),
  24347. + "3DES CBC + MD5 encode"
  24348. + },
  24349. +/*505*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  24350. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
  24351. + MV_CESA_DIR_ENCODE,
  24352. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  24353. + shaKey4, sizeof(shaKey4),
  24354. + "3DES CBC + SHA1 encode"
  24355. + },
  24356. +/*506*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
  24357. + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
  24358. + MV_CESA_DIR_ENCODE,
  24359. + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
  24360. + mdKey4, sizeof(mdKey4),
  24361. + "AES-128 CBC + MD5 encode"
  24362. + },
  24363. +/*507*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
  24364. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
  24365. + MV_CESA_DIR_ENCODE,
  24366. + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
  24367. + shaKey4, sizeof(shaKey4),
  24368. + "AES-128 CBC + SHA1 encode"
  24369. + },
  24370. +/*508*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  24371. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_THEN_CRYPTO,
  24372. + MV_CESA_DIR_DECODE,
  24373. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  24374. + mdKey4, sizeof(mdKey4),
  24375. + "HMAC-MD5 + 3DES decode"
  24376. + },
  24377. +};
  24378. +
  24379. +
  24380. +static MV_CESA_TEST_DB_ENTRY cesaTestsDB[MAX_TEST_TYPE+1] =
  24381. +{
  24382. + { desTestSessions, sizeof(desTestSessions)/sizeof(desTestSessions[0]) },
  24383. + { tripleDesTestSessions, sizeof(tripleDesTestSessions)/sizeof(tripleDesTestSessions[0]) },
  24384. + { aesTestSessions, sizeof(aesTestSessions)/sizeof(aesTestSessions[0]) },
  24385. + { md5TestSessions, sizeof(md5TestSessions)/sizeof(md5TestSessions[0]) },
  24386. + { shaTestSessions, sizeof(shaTestSessions)/sizeof(shaTestSessions[0]) },
  24387. + { combinedTestSessions, sizeof(combinedTestSessions)/sizeof(combinedTestSessions[0]) },
  24388. + { NULL, 0 }
  24389. +};
  24390. +
  24391. +
  24392. +char cesaNullPlainHexText[] = "000000000000000000000000000000000000000000000000";
  24393. +
  24394. +char cesaPlainAsciiText[] = "Now is the time for all ";
  24395. +char cesaPlainHexEbc[] = "4e6f77206973207468652074696d6520666f7220616c6c20";
  24396. +char cesaCipherHexEcb[] = "3fa40e8a984d48156a271787ab8883f9893d51ec4b563b53";
  24397. +char cesaPlainHexCbc[] = "1234567890abcdef4e6f77206973207468652074696d6520666f7220616c6c20";
  24398. +char cesaCipherHexCbc[] = "1234567890abcdefe5c7cdde872bf27c43e934008c389c0f683788499a7c05f6";
  24399. +
  24400. +char cesaAesPlainHexEcb[] = "000102030405060708090a0b0c0d0e0f";
  24401. +char cesaAes128cipherHexEcb[] = "0a940bb5416ef045f1c39458c653ea5a";
  24402. +char cesaAes192cipherHexEcb[] = "0060bffe46834bb8da5cf9a61ff220ae";
  24403. +char cesaAes256cipherHexEcb[] = "5a6e045708fb7196f02e553d02c3a692";
  24404. +
  24405. +char cesaAsciiStr1[] = "Hi There";
  24406. +char cesaDataHexStr1[] = "4869205468657265";
  24407. +char cesaHmacMd5digestHex1[] = "9294727a3638bb1c13f48ef8158bfc9d";
  24408. +char cesaHmacSha1digestHex1[] = "b617318655057264e28bc0b6fb378c8ef146be00";
  24409. +char cesaDataAndMd5digest1[] = "48692054686572659294727a3638bb1c13f48ef8158bfc9d";
  24410. +char cesaDataAndSha1digest1[] = "4869205468657265b617318655057264e28bc0b6fb378c8ef146be00";
  24411. +
  24412. +char cesaAesPlainText[] = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
  24413. + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
  24414. + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
  24415. + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
  24416. +
  24417. +char cesaAes128CipherCbc[] = "c30e32ffedc0774e6aff6af0869f71aa"
  24418. + "0f3af07a9a31a9c684db207eb0ef8e4e"
  24419. + "35907aa632c3ffdf868bb7b29d3d46ad"
  24420. + "83ce9f9a102ee99d49a53e87f4c3da55";
  24421. +
  24422. +char cesaAesIvPlainText[] = "8ce82eefbea0da3c44699ed7db51b7d9"
  24423. + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
  24424. + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
  24425. + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
  24426. + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
  24427. +
  24428. +char cesaAes128IvCipherCbc[] = "8ce82eefbea0da3c44699ed7db51b7d9"
  24429. + "c30e32ffedc0774e6aff6af0869f71aa"
  24430. + "0f3af07a9a31a9c684db207eb0ef8e4e"
  24431. + "35907aa632c3ffdf868bb7b29d3d46ad"
  24432. + "83ce9f9a102ee99d49a53e87f4c3da55";
  24433. +
  24434. +char cesaAesCtrPlain[] = "00E0017B27777F3F4A1786F000000001"
  24435. + "000102030405060708090A0B0C0D0E0F"
  24436. + "101112131415161718191A1B1C1D1E1F"
  24437. + "20212223";
  24438. +
  24439. +char cesaAesCtrCipher[] = "00E0017B27777F3F4A1786F000000001"
  24440. + "C1CF48A89F2FFDD9CF4652E9EFDB72D7"
  24441. + "4540A42BDE6D7836D59A5CEAAEF31053"
  24442. + "25B2072F";
  24443. +
  24444. +
  24445. +
  24446. +/* Input cesaHmacHex3 is '0xdd' repeated 50 times */
  24447. +char cesaHmacMd5digestHex3[] = "56be34521d144c88dbb8c733f0e8b3f6";
  24448. +char cesaHmacSha1digestHex3[] = "125d7342b9ac11cd91a39af48aa17b4f63f175d3";
  24449. +char cesaDataHexStr3[50*2+1] = "";
  24450. +char cesaDataAndMd5digest3[sizeof(cesaDataHexStr3)+sizeof(cesaHmacMd5digestHex3)+8*2+1] = "";
  24451. +char cesaDataAndSha1digest3[sizeof(cesaDataHexStr3)+sizeof(cesaHmacSha1digestHex3)+8*2+1] = "";
  24452. +
  24453. +/* Ascii string is "abc" */
  24454. +char hashHexStr3[] = "616263";
  24455. +char hashMd5digest3[] = "900150983cd24fb0d6963f7d28e17f72";
  24456. +char hashSha1digest3[] = "a9993e364706816aba3e25717850c26c9cd0d89d";
  24457. +
  24458. +char hashHexStr80[] = "31323334353637383930"
  24459. + "31323334353637383930"
  24460. + "31323334353637383930"
  24461. + "31323334353637383930"
  24462. + "31323334353637383930"
  24463. + "31323334353637383930"
  24464. + "31323334353637383930"
  24465. + "31323334353637383930";
  24466. +
  24467. +char hashMd5digest80[] = "57edf4a22be3c955ac49da2e2107b67a";
  24468. +
  24469. +char tripleDesThenMd5digest80[] = "b7726a03aad490bd6c5a452a89a1b271";
  24470. +char tripleDesThenSha1digest80[] = "b2ddeaca91030eab5b95a234ef2c0f6e738ff883";
  24471. +
  24472. +char cbc3desThenMd5digest80[] = "6f463057e1a90e0e91ae505b527bcec0";
  24473. +char cbc3desThenSha1digest80[] = "1b002ed050be743aa98860cf35659646bb8efcc0";
  24474. +
  24475. +char cbcAes128ThenMd5digest80[] = "6b6e863ac5a71d15e3e9b1c86c9ba05f";
  24476. +char cbcAes128ThenSha1digest80[] = "13558472d1fc1c90dffec6e5136c7203452d509b";
  24477. +
  24478. +
  24479. +static MV_CESA_TEST_CASE cesaTestCases[] =
  24480. +{
  24481. + /* plainHexStr cipherHexStr IV crypto mac digest */
  24482. + /* Length Length Offset */
  24483. + /*0*/ { NULL, NULL, NULL, 0, 0, -1 },
  24484. + /*1*/ { cesaPlainHexEbc, cesaCipherHexEcb, NULL, 24, 0, -1 },
  24485. + /*2*/ { cesaPlainHexCbc, cesaCipherHexCbc, NULL, 24, 0, -1 },
  24486. + /*3*/ { cesaAesPlainHexEcb, cesaAes128cipherHexEcb, NULL, 16, 0, -1 },
  24487. + /*4*/ { cesaAesPlainHexEcb, cesaAes192cipherHexEcb, NULL, 16, 0, -1 },
  24488. + /*5*/ { cesaAesPlainHexEcb, cesaAes256cipherHexEcb, NULL, 16, 0, -1 },
  24489. + /*6*/ { cesaDataHexStr1, cesaHmacMd5digestHex1, NULL, 0, 8, -1 },
  24490. + /*7*/ { NULL, cesaDataAndMd5digest1, NULL, 0, 8, -1 },
  24491. + /*8*/ { cesaDataHexStr3, cesaHmacMd5digestHex3, NULL, 0, 50, -1 },
  24492. + /*9*/ { NULL, cesaDataAndMd5digest3, NULL, 0, 50, -1 },
  24493. +/*10*/ { cesaAesPlainText, cesaAes128IvCipherCbc, iv5, 64, 0, -1 },
  24494. +/*11*/ { cesaDataHexStr1, cesaHmacSha1digestHex1, NULL, 0, 8, -1 },
  24495. +/*12*/ { NULL, cesaDataAndSha1digest1, NULL, 0, 8, -1 },
  24496. +/*13*/ { cesaDataHexStr3, cesaHmacSha1digestHex3, NULL, 0, 50, -1 },
  24497. +/*14*/ { NULL, cesaDataAndSha1digest3, NULL, 0, 50, -1 },
  24498. +/*15*/ { hashHexStr3, hashMd5digest3, NULL, 0, 3, -1 },
  24499. +/*16*/ { hashHexStr3, hashSha1digest3, NULL, 0, 3, -1 },
  24500. +/*17*/ { hashHexStr80, tripleDesThenMd5digest80, NULL, 80, 80, -1 },
  24501. +/*18*/ { hashHexStr80, tripleDesThenSha1digest80, NULL, 80, 80, -1 },
  24502. +/*19*/ { hashHexStr80, cbc3desThenMd5digest80, iv1, 80, 80, -1 },
  24503. +/*20*/ { hashHexStr80, cbc3desThenSha1digest80, iv1, 80, 80, -1 },
  24504. +/*21*/ { hashHexStr80, cbcAes128ThenMd5digest80, iv5, 80, 80, -1 },
  24505. +/*22*/ { hashHexStr80, cbcAes128ThenSha1digest80, iv5, 80, 80, -1 },
  24506. +/*23*/ { cesaAesCtrPlain, cesaAesCtrCipher, NULL, 36, 0, -1 },
  24507. +/*24*/ { cesaAesIvPlainText, cesaAes128IvCipherCbc, NULL, 64, 0, -1 },
  24508. +/*25*/ { plain3des1, cipher3des1, NULL, 0, 0, -1 },
  24509. +/*26*/ { plain3des2, cipher3desCbc2, iv3des2,0, 0, -1 },
  24510. +/*27*/ { plain3des3, cipher3desCbc3, iv3des3,0, 0, -1 },
  24511. +};
  24512. +
  24513. +
  24514. +/* Key = 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  24515. + * 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
  24516. + * Input 0xdd repeated "size" times
  24517. + */
  24518. +static MV_CESA_SIZE_TEST mdMultiSizeTest302[] =
  24519. +{
  24520. + { 80, "7a031a640c14a4872814930b1ef3a5b2" },
  24521. + { 512, "5488e6c5a14dc72a79f28312ca5b939b" },
  24522. + { 1000, "d00814f586a8b78a05724239d2531821" },
  24523. + { 1001, "bf07df7b7f49d3f5b5ecacd4e9e63281" },
  24524. + { 1002, "1ed4a1a802e87817a819d4e37bb4d0f7" },
  24525. + { 1003, "5972ab64a4f265ee371dac2f2f137f90" },
  24526. + { 1004, "71f95e7ec3aa7df2548e90898abdb28e" },
  24527. + { 1005, "e082790b4857fcfc266e92e59e608814" },
  24528. + { 1006, "9500f02fd8ac7fde8b10e4fece9a920d" },
  24529. + { 1336, "e42edcce57d0b75b01aa09d71427948b" },
  24530. + { 1344, "bb5454ada0deb49ba0a97ffd60f57071" },
  24531. + { 1399, "0f44d793e744b24d53f44f295082ee8c" },
  24532. + { 1400, "359de8a03a9b707928c6c60e0e8d79f1" },
  24533. + { 1401, "e913858b484cbe2b384099ea88d8855b" },
  24534. + { 1402, "d9848a164af53620e0540c1d7d87629e" },
  24535. + { 1403, "0c9ee1c2c9ef45e9b625c26cbaf3e822" },
  24536. + { 1404, "12edd4f609416e3c936170360561b064" },
  24537. + { 1405, "7fc912718a05446395345009132bf562" },
  24538. + { 1406, "882f17425e579ff0d85a91a59f308aa0" },
  24539. + { 1407, "005cae408630a2fb5db82ad9db7e59da" },
  24540. + { 1408, "64655f8b404b3fea7a3e3e609bc5088f" },
  24541. + { 1409, "4a145284a7f74e01b6bb1a0ec6a0dd80" },
  24542. + { 2048, "67caf64475650732def374ebb8bde3fd" },
  24543. + { 2049, "6c84f11f472825f7e6cd125c2981884b" },
  24544. + { 2050, "8999586754a73a99efbe4dbad2816d41" },
  24545. + { 2051, "ba6946b610e098d286bc81091659dfff" },
  24546. + { 2052, "d0afa01c92d4d13def2b024f36faed83" },
  24547. + { 3072, "61d8beac61806afa2585d74a9a0e6974" },
  24548. + { 3074, "f6501a28dcc24d1e4770505c51a87ed3" },
  24549. + { 3075, "ea4a6929be67e33e61ff475369248b73" },
  24550. + { 4048, "aa8c4d68f282a07e7385acdfa69f4bed" },
  24551. + { 4052, "afb5ed2c0e1d430ea59e59ed5ed6b18a" },
  24552. + { 4058, "9e8553f9bdd43aebe0bd729f0e600c99" },
  24553. + { 6144, "f628f3e5d183fe5cdd3a5abee39cf872" },
  24554. + { 6150, "89a3efcea9a2f25f919168ad4a1fd292" },
  24555. + { 6400, "cdd176b7fb747873efa4da5e32bdf88f" },
  24556. + { 6528, "b1d707b027354aca152c45ee559ccd3f" },
  24557. + { 8192, "c600ea4429ac47f9941f09182166e51a" },
  24558. + {16384, "16e8754bfbeb4c649218422792267a37" },
  24559. + {18432, "0fd0607521b0aa8b52219cfbe215f63e" },
  24560. + { 0, NULL },
  24561. +};
  24562. +
  24563. +/* Key = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24564. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  24565. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24566. + */
  24567. +static MV_CESA_SIZE_TEST mdMultiSizeTest304[] =
  24568. +{
  24569. + { 80, "a456c4723fee6068530af5a2afa71627" },
  24570. + { 512, "f85c2a2344f5de68b432208ad13e5794" },
  24571. + { 1000, "35464d6821fd4a293a41eb84e274c8c5" },
  24572. + { 1001, "c08eedbdce60cceb54bc2d732bb32c8b" },
  24573. + { 1002, "5664f71800c011cc311cb6943339c1b8" },
  24574. + { 1003, "779c723b044c585dc7802b13e8501bdc" },
  24575. + { 1004, "55e500766a2c307bc5c5fdd15e4cacd4" },
  24576. + { 1005, "d5f978954f5c38529d1679d2b714f068" },
  24577. + { 1006, "cd3efc827ce628b7281b72172693abf9" },
  24578. + { 1336, "6f04479910785878ae6335b8d1e87edf" },
  24579. + { 1344, "b6d27b50c2bce1ba2a8e1b5cc4324368" },
  24580. + { 1399, "65f70a1d4c86e5eaeb0704c8a7816795" },
  24581. + { 1400, "3394b5adc4cb3ff98843ca260a44a88a" },
  24582. + { 1401, "3a06f3582033a66a4e57e0603ce94e74" },
  24583. + { 1402, "e4d97f5ed51edc48abfa46eeb5c31752" },
  24584. + { 1403, "3d05e40b080ee3bedf293cb87b7140e7" },
  24585. + { 1404, "8cf294fc3cd153ab18dccb2a52cbf244" },
  24586. + { 1405, "d1487bd42f6edd9b4dab316631159221" },
  24587. + { 1406, "0527123b6bf6936cf5d369dc18c6c70f" },
  24588. + { 1407, "3224a06639db70212a0cd1ae1fcc570a" },
  24589. + { 1408, "a9e13335612c0356f5e2c27086e86c43" },
  24590. + { 1409, "a86d1f37d1ed8a3552e9a4f04dceea98" },
  24591. + { 2048, "396905c9b961cd0f6152abfb69c4449c" },
  24592. + { 2049, "49f39bff85d9dcf059fadb89efc4a70f" },
  24593. + { 2050, "3a2b4823bc4d0415656550226a63e34a" },
  24594. + { 2051, "dec60580d406c782540f398ad0bcc7e0" },
  24595. + { 2052, "32f76610a14310309eb748fe025081bf" },
  24596. + { 3072, "45edc1a42bf9d708a621076b63b774da" },
  24597. + { 3074, "9be1b333fe7c0c9f835fb369dc45f778" },
  24598. + { 3075, "8c06fcac7bd0e7b7a17fd6508c09a549" },
  24599. + { 4048, "0ddaef848184bf0ad98507a10f1e90e4" },
  24600. + { 4052, "81976bcaeb274223983996c137875cb8" },
  24601. + { 4058, "0b0a7a1c82bc7cbc64d8b7cd2dc2bb22" },
  24602. + { 6144, "1c24056f52725ede2dff0d7f9fc9855f" },
  24603. + { 6150, "b7f4b65681c4e43ee68ca466ca9ca4ec" },
  24604. + { 6400, "443bbaab9f7331ddd4bf11b659cd43c8" },
  24605. + { 6528, "216f44f23047cfee03a7a64f88f9a995" },
  24606. + { 8192, "ac7a993b2cad54879dba1bde63e39097" },
  24607. + { 8320, "55ed7be9682d6c0025b3221a62088d08" },
  24608. + {16384, "c6c722087653b62007aea668277175e5" },
  24609. + {18432, "f1faca8e907872c809e14ffbd85792d6" },
  24610. + { 0, NULL },
  24611. +};
  24612. +
  24613. +/* HASH-MD5
  24614. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24615. + * repeated "size" times
  24616. + */
  24617. +static MV_CESA_SIZE_TEST mdMultiSizeTest305[] =
  24618. +{
  24619. + { 80, "57edf4a22be3c955ac49da2e2107b67a" },
  24620. + { 512, "c729ae8f0736cc377a9767a660eaa04e" },
  24621. + { 1000, "f1257a8659eb92d36fe14c6bf3852a6a" },
  24622. + { 1001, "f8a46fe8ea04fdc8c7de0e84042d3878" },
  24623. + { 1002, "da188dd67bff87d58aa3c02af2d0cc0f" },
  24624. + { 1003, "961753017feee04c9b93a8e51658a829" },
  24625. + { 1004, "dd68c4338608dcc87807a711636bf2af" },
  24626. + { 1005, "e338d567d3ce66bf69ada29658a8759b" },
  24627. + { 1006, "443c9811e8b92599b0b149e8d7ec700a" },
  24628. + { 1336, "89a98511706008ba4cbd0b4a24fa5646" },
  24629. + { 1344, "335a919805f370b9e402a62c6fe01739" },
  24630. + { 1399, "5d18d0eddcd84212fe28d812b5e80e3b" },
  24631. + { 1400, "6b695c240d2dffd0dffc99459ca76db6" },
  24632. + { 1401, "49590f61298a76719bc93a57a30136f5" },
  24633. + { 1402, "94c2999fa3ef1910a683d69b2b8476f2" },
  24634. + { 1403, "37073a02ab00ecba2645c57c228860db" },
  24635. + { 1404, "1bcd06994fce28b624f0c5fdc2dcdd2b" },
  24636. + { 1405, "11b93671a64c95079e8cf9e7cddc8b3d" },
  24637. + { 1406, "4b6695772a4c66313fa4871017d05f36" },
  24638. + { 1407, "d1539b97fbfda1c075624e958de19c5b" },
  24639. + { 1408, "b801b9b69920907cd018e8063092ede9" },
  24640. + { 1409, "b765f1406cfe78e238273ed01bbcaf7e" },
  24641. + { 2048, "1d7e2c64ac29e2b3fb4c272844ed31f5" },
  24642. + { 2049, "71d38fac49c6b1f4478d8d88447bcdd0" },
  24643. + { 2050, "141c34a5592b1bebfa731e0b23d0cdba" },
  24644. + { 2051, "c5e1853f21c59f5d6039bd13d4b380d8" },
  24645. + { 2052, "dd44a0d128b63d4b5cccd967906472d7" },
  24646. + { 3072, "37d158e33b21390822739d13db7b87fe" },
  24647. + { 3074, "aef3b209d01d39d0597fe03634bbf441" },
  24648. + { 3075, "335ffb428eabf210bada96d74d5a4012" },
  24649. + { 4048, "2434c2b43d798d2819487a886261fc64" },
  24650. + { 4052, "ac2fa84a8a33065b2e92e36432e861f8" },
  24651. + { 4058, "856781f85616c341c3533d090c1e1e84" },
  24652. + { 6144, "e5d134c652c18bf19833e115f7a82e9b" },
  24653. + { 6150, "a09a353be7795fac2401dac5601872e6" },
  24654. + { 6400, "08b9033ac6a1821398f50af75a2dbc83" },
  24655. + { 6528, "3d47aa193a8540c091e7e02f779e6751" },
  24656. + { 8192, "d3164e710c0626f6f395b38f20141cb7" },
  24657. + { 8320, "b727589d9183ff4e8491dd24466974a3" },
  24658. + {16384, "3f54d970793d2274d5b20d10a69938ac" },
  24659. + {18432, "f558511dcf81985b7a1bb57fad970531" },
  24660. + { 0, NULL },
  24661. +};
  24662. +
  24663. +
  24664. +/* Key = 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  24665. + * 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
  24666. + * 0xaa, 0xaa, 0xaa, 0xaa
  24667. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24668. + */
  24669. +static MV_CESA_SIZE_TEST shaMultiSizeTest402[] =
  24670. +{
  24671. + { 80, "e812f370e659705a1649940d1f78cd7af18affd3" },
  24672. + { 512, "e547f886b2c15d995ed76a8a924cb408c8080f66" },
  24673. + { 1000, "239443194409f1a5342ecde1a092c8f3a3ed790a" },
  24674. + { 1001, "f278ab9a102850a9f48dc4e9e6822afe2d0c52b5" },
  24675. + { 1002, "8bcc667df5ab6ece988b3af361d09747c77f4e72" },
  24676. + { 1003, "0fae6046c7dc1d3e356b25af836f6077a363f338" },
  24677. + { 1004, "0ea48401cc92ae6bc92ae76685269cb0167fbe1a" },
  24678. + { 1005, "ecbcd7c879b295bafcd8766cbeac58cc371e31d1" },
  24679. + { 1006, "eb4a4a3d07d1e9a15e6f1ab8a9c47f243e27324c" },
  24680. + { 1336, "f5950ee1d77c10e9011d2149699c9366fe52529c" },
  24681. + { 1344, "b04263604a63c351b0b3b9cf1785b4bdba6c8838" },
  24682. + { 1399, "8cb1cff61d5b784045974a2fc69386e3b8d24218" },
  24683. + { 1400, "9bb2f3fcbeddb2b90f0be797cd647334a2816d51" },
  24684. + { 1401, "23ae462a7a0cb440f7445791079a5d75a535dd33" },
  24685. + { 1402, "832974b524a4d3f9cc2f45a3cabf5ccef65cd2aa" },
  24686. + { 1403, "d1c683742fe404c3c20d5704a5430e7832a7ec95" },
  24687. + { 1404, "867c79042e64f310628e219d8b85594cd0c7adc3" },
  24688. + { 1405, "c9d81d49d13d94358f56ccfd61af02b36c69f7c3" },
  24689. + { 1406, "0df43daab2786172f9b8d07d61f14a070cf1287a" },
  24690. + { 1407, "0fd8f3ad7f169534b274d4c66bbddd89f759e391" },
  24691. + { 1408, "3987511182b18473a564436003139b808fa46343" },
  24692. + { 1409, "ef667e063c9e9f539a8987a8d0bd3066ee85d901" },
  24693. + { 2048, "921109c99f3fedaca21727156d5f2b4460175327" },
  24694. + { 2049, "47188600dd165eb45f27c27196d3c46f4f042c1b" },
  24695. + { 2050, "8831939904009338de10e7fa670847041387807d" },
  24696. + { 2051, "2f8ebb5db2997d614e767be1050366f3641e7520" },
  24697. + { 2052, "669e51cd730dae158d3bef8adba075bd95a0d011" },
  24698. + { 3072, "cfee66cfd83abc8451af3c96c6b35a41cc6c55f5" },
  24699. + { 3074, "216ea26f02976a261b7d21a4dd3085157bedfabd" },
  24700. + { 3075, "bd612ebba021fd8e012b14c3bd60c8c5161fabc0" },
  24701. + { 4048, "c2564c1fdf2d5e9d7dde7aace2643428e90662e8" },
  24702. + { 4052, "91ce61fe924b445dfe7b5a1dcd10a27caec16df6" },
  24703. + { 4058, "db2a9be5ee8124f091c7ebd699266c5de223c164" },
  24704. + { 6144, "855109903feae2ba3a7a05a326b8a171116eb368" },
  24705. + { 6150, "37520bb3a668294d9c7b073e7e3daf8fee248a78" },
  24706. + { 6400, "60a353c841b6d2b1a05890349dad2fa33c7536b7" },
  24707. + { 6528, "9e53a43a69bb42d7c8522ca8bd632e421d5edb36" },
  24708. + { 8192, "a918cb0da862eaea0a33ee0efea50243e6b4927c" },
  24709. + { 8320, "29a5dcf55d1db29cd113fcf0572ae414f1c71329" },
  24710. + {16384, "6fb27966138e0c8d5a0d65ace817ebd53633cee1" },
  24711. + {18432, "ca09900d891c7c9ae2a559b10f63a217003341c1" },
  24712. + { 0, NULL },
  24713. +};
  24714. +
  24715. +/* Key = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24716. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  24717. + * 0x11, 0x12, 0x13, 0x14
  24718. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24719. + */
  24720. +static MV_CESA_SIZE_TEST shaMultiSizeTest404[] =
  24721. +{
  24722. + { 80, "beaf20a34b06a87558d156c0949bc3957d40222e" },
  24723. + { 512, "3353955358d886bc2940a3c7f337ff7dafb59c7b" },
  24724. + { 1000, "8737a542c5e9b2b6244b757ebb69d5bd602a829f" },
  24725. + { 1001, "fd9e7582d8a5d3c9fe3b923e4e6a41b07a1eb4d4" },
  24726. + { 1002, "a146d14a6fc3c274ff600568f4d75b977989e00d" },
  24727. + { 1003, "be22601bbc027ddef2dec97d30b3dc424fd803c5" },
  24728. + { 1004, "3e71fe99b2fe2b7bfdf4dbf0c7f3da25d7ea35e7" },
  24729. + { 1005, "2c422735d7295408fddd76f5e8a83a2a8da13df3" },
  24730. + { 1006, "6d875319049314b61855101a647b9ba3313428e6" },
  24731. + { 1336, "c1631ea80bad9dc43a180712461b65a0598c711c" },
  24732. + { 1344, "816069bf91d34581005746e2e0283d0f9c7b7605" },
  24733. + { 1399, "4e139866dc61cfcb8b67ca2ebd637b3a538593af" },
  24734. + { 1400, "ff2a0f8dd2b02c5417910f6f55d33a78e081a723" },
  24735. + { 1401, "ab00c12be62336964cbce31ae97fe2a0002984d5" },
  24736. + { 1402, "61349e7f999f3a1acc56c3e9a5060a9c4a7b05b6" },
  24737. + { 1403, "3edbc0f61e435bc1317fa27d840076093fb79353" },
  24738. + { 1404, "d052c6dfdbe63d45dab23ef9893e2aa4636aca1e" },
  24739. + { 1405, "0cc16b7388d67bf0add15a31e6e6c753cfae4987" },
  24740. + { 1406, "c96ba7eaad74253c38c22101b558d2850b1d1b90" },
  24741. + { 1407, "3445428a40d2c6556e7c55797ad8d323b61a48d9" },
  24742. + { 1408, "8d6444f937a09317c89834187b8ea9b8d3a8c56b" },
  24743. + { 1409, "c700acd3ecd19014ea2bdb4d42510c467e088475" },
  24744. + { 2048, "ee27d2a0cb77470c2f496212dfd68b5bb7b04e4b" },
  24745. + { 2049, "683762d7a02983b26a6d046e6451d9cd82c25932" },
  24746. + { 2050, "0fd20f1d55a9ee18363c2a6fd54aa13aee69992f" },
  24747. + { 2051, "86c267d8cc4bc8d59090e4f8b303da960fd228b7" },
  24748. + { 2052, "452395ae05b3ec503eea34f86fc0832485ad97c1" },
  24749. + { 3072, "75198e3cfd0b9bcff2dabdf8e38e6fdaa33ca49a" },
  24750. + { 3074, "4e24785ef080141ce4aab4675986d9acea624d7c" },
  24751. + { 3075, "3a20c5978dd637ec0e809bf84f0d9ccf30bc65bf" },
  24752. + { 4048, "3c32da256be7a7554922bf5fed51b0d2d09e59ad" },
  24753. + { 4052, "fff898426ea16e54325ae391a32c6c9bce4c23c0" },
  24754. + { 4058, "c800b9e562e1c91e1310116341a3c91d37f848ec" },
  24755. + { 6144, "d91d509d0cc4376c2d05bf9a5097717a373530e6" },
  24756. + { 6150, "d957030e0f13c5df07d9eec298542d8f94a07f12" },
  24757. + { 6400, "bb745313c3d7dc17b3f955e5534ad500a1082613" },
  24758. + { 6528, "77905f80d9ca82080bbb3e5654896dabfcfd1bdb" },
  24759. + { 8192, "5237fd9a81830c974396f99f32047586612ff3c0" },
  24760. + { 8320, "57668e28d5f2dba0839518a11db0f6af3d7e08bf" },
  24761. + {16384, "62e093fde467f0748087beea32e9af97d5c61241" },
  24762. + {18432, "845fb33130c7d6ea554fd5aacb9c50cf7ccb5929" },
  24763. + { 0, NULL },
  24764. +};
  24765. +
  24766. +/* HASH-SHA1
  24767. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24768. + * repeated "size" times
  24769. + */
  24770. +static MV_CESA_SIZE_TEST shaMultiSizeTest405[] =
  24771. +{
  24772. + { 80, "50abf5706a150990a08b2c5ea40fa0e585554732" },
  24773. + { 512, "f14516a08948fa27917a974d219741a697ba0087" },
  24774. + { 1000, "0bd18c378d5788817eb4f1e5dc07d867efa5cbf4" },
  24775. + { 1001, "ca29b85c35db1b8aef83c977893a11159d1b7aa2" },
  24776. + { 1002, "d83bc973eaaedb8a31437994dabbb3304b0be086" },
  24777. + { 1003, "2cf7bbef0acd6c00536b5c58ca470df9a3a90b6c" },
  24778. + { 1004, "e4375d09b1223385a8a393066f8209acfd936a80" },
  24779. + { 1005, "1029b38043e027745d019ce1d2d68e3d8b9d8f99" },
  24780. + { 1006, "deea16dcebbd8ac137e2b984deb639b9fb5e9680" },
  24781. + { 1336, "ea031b065fff63dcfb6a41956e4777520cdbc55d" },
  24782. + { 1344, "b52096c6445e6c0a8355995c70dc36ae186c863c" },
  24783. + { 1399, "cde2f6f8379870db4b32cf17471dc828a8dbff2b" },
  24784. + { 1400, "e53ff664064bc09fe5054c650806bd42d8179518" },
  24785. + { 1401, "d1156db5ddafcace64cdb510ff0d4af9b9a8ad64" },
  24786. + { 1402, "34ede0e9a909dd84a2ae291539105c0507b958e1" },
  24787. + { 1403, "a772ca3536da77e6ad3251e4f9e1234a4d7b87c0" },
  24788. + { 1404, "29740fd2b04e7a8bfd32242db6233156ad699948" },
  24789. + { 1405, "65b17397495b70ce4865dad93bf991b74c97cce1" },
  24790. + { 1406, "a7ee89cd0754061fdb91af7ea6abad2c69d542e3" },
  24791. + { 1407, "3eebf82f7420188e23d328b7ce93580b279a5715" },
  24792. + { 1408, "e08d3363a8b9a490dfb3a4c453452b8f114deeec" },
  24793. + { 1409, "95d74df739181a4ff30b8c39e28793a36598e924" },
  24794. + { 2048, "aa40262509c2abf84aab0197f83187fc90056d91" },
  24795. + { 2049, "7dec28ef105bc313bade8d9a7cdeac58b99de5ea" },
  24796. + { 2050, "d2e30f77ec81197de20f56588a156094ecb88450" },
  24797. + { 2051, "6b22ccc874833e96551a39da0c0edcaa0d969d92" },
  24798. + { 2052, "f843141e57875cd669af58744bc60aa9ea59549c" },
  24799. + { 3072, "09c5fedeaa62c132e673cc3c608a00142273d086" },
  24800. + { 3074, "b09e95eea9c7b1b007a58accec488301901a7f3d" },
  24801. + { 3075, "e6226b77b4ada287a8c9bbcf4ed71eec5ce632dc" },
  24802. + { 4048, "e99394894f855821951ddddf5bfc628547435f5c" },
  24803. + { 4052, "32d2f1af38be9cfba6cd03d55a254d0b3e1eb382" },
  24804. + { 4058, "d906552a4f2aca3a22e1fecccbcd183d7289d0ef" },
  24805. + { 6144, "2e7f62d35a860988e1224dc0543204af19316041" },
  24806. + { 6150, "d6b89698ee133df46fec9d552fadc328aa5a1b51" },
  24807. + { 6400, "dff50e90c46853988fa3a4b4ce5dda6945aae976" },
  24808. + { 6528, "9e63ec0430b96db02d38bc78357a2f63de2ab7f8" },
  24809. + { 8192, "971eb71ed60394d5ab5abb12e88420bdd41b5992" },
  24810. + { 8320, "91606a31b46afeaac965cecf87297e791b211013" },
  24811. + {16384, "547f830a5ec1f5f170ce818f156b1002cabc7569" },
  24812. + {18432, "f16f272787f3b8d539652e4dc315af6ab4fda0ef" },
  24813. + { 0, NULL },
  24814. +};
  24815. +
  24816. +/* CryptoKey = 0x01234567, 0x89abcdef,
  24817. + * 0x01234567, 0x89abcdef,
  24818. + * 0x01234567, 0x89abcdef;
  24819. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24820. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  24821. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24822. + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
  24823. + */
  24824. +static MV_CESA_SIZE_TEST tripleDesMdMultiSizeTest502[] =
  24825. +{
  24826. + { 64, "9586962a2aaaef28803dec2e17807a7f" },
  24827. + { 80, "b7726a03aad490bd6c5a452a89a1b271" },
  24828. + { 352, "f1ed9563aecc3c0d2766eb2bed3b4e4c" },
  24829. + { 512, "0f9decb11ab40fe86f4d4d9397bc020e" },
  24830. + { 1000, "3ba69deac12cab8ff9dff7dbd9669927" },
  24831. + { 1336, "6cf47bf1e80e03e2c1d0945bc50d37d2" },
  24832. + { 1344, "4be388dab21ceb3fa1b8d302e9b821f7" },
  24833. + { 1400, "a58b79fb21dd9bfc6ec93e3b99fb0ef1" },
  24834. + { 1408, "8bc97379fc2ac3237effcdd4f7a86528" },
  24835. + { 2048, "1339f03ab3076f25a20bc4cba16eb5bf" },
  24836. + { 3072, "731204d2d90c4b36ae41f5e1fb874288" },
  24837. + { 4048, "c028d998cfda5642547b7e1ed5ea16e4" },
  24838. + { 6144, "b1b19cd910cc51bd22992f1e59f1e068" },
  24839. + { 6400, "44e4613496ba622deb0e7cb768135a2f" },
  24840. + { 6528, "3b06b0a86f8db9cd67f9448dfcf10549" },
  24841. + { 8192, "d581780b7163138a0f412be681457d82" },
  24842. + {16384, "03b8ac05527faaf1bed03df149c65ccf" },
  24843. + {18432, "677c8a86a41dab6c5d81b85b8fb10ff6" },
  24844. + { 0, NULL },
  24845. +};
  24846. +
  24847. +
  24848. +/* CryptoKey = 0x01234567, 0x89abcdef,
  24849. + * 0x01234567, 0x89abcdef,
  24850. + * 0x01234567, 0x89abcdef;
  24851. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24852. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  24853. + * 0x11, 0x12, 0x13, 0x14
  24854. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24855. + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
  24856. + */
  24857. +static MV_CESA_SIZE_TEST tripleDesShaMultiSizeTest503[] =
  24858. +{
  24859. + { 64, "44a1e9bcbfc1429630d9ea68b7a48b0427a684f2" },
  24860. + { 80, "b2ddeaca91030eab5b95a234ef2c0f6e738ff883" },
  24861. + { 352, "4b91864c7ff629bdff75d9726421f76705452aaf" },
  24862. + { 512, "6dd37faceeb2aa98ba74f4242ed6734a4d546af5" },
  24863. + { 1000, "463661c30300be512a9df40904f0757cde5f1141" },
  24864. + { 1336, "b931f831d9034fe59c65176400b039fe9c1f44a5" },
  24865. + { 1344, "af8866b1cd4a4887d6185bfe72470ffdfb3648e1" },
  24866. + { 1400, "49c6caf07296d5e31d2504d088bc5b20c3ee7cdb" },
  24867. + { 1408, "fcae8deedbc6ebf0763575dc7e9de075b448a0f4" },
  24868. + { 2048, "edece5012146c1faa0dd10f50b183ba5d2af58ac" },
  24869. + { 3072, "5b83625adb43a488b8d64fecf39bb766818547b7" },
  24870. + { 4048, "d2c533678d26c970293af60f14c8279dc708bfc9" },
  24871. + { 6144, "b8f67af4f991b08b725f969b049ebf813bfacc5c" },
  24872. + { 6400, "d9a6c7f746ac7a60ef2edbed2841cf851c25cfb0" },
  24873. + { 6528, "376792b8c8d18161d15579fb7829e6e3a27e9946" },
  24874. + { 8192, "d890eabdca195b34ef8724b28360cffa92ae5655" },
  24875. + {16384, "a167ee52639ec7bf19aee9c6e8f76667c14134b9" },
  24876. + {18432, "e4396ab56f67296b220985a12078f4a0e365d2cc" },
  24877. + { 0, NULL },
  24878. +};
  24879. +
  24880. +/* CryptoKey = 0x01234567, 0x89abcdef,
  24881. + * 0x01234567, 0x89abcdef,
  24882. + * 0x01234567, 0x89abcdef
  24883. + * IV = 0x12345678, 0x90abcdef
  24884. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24885. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  24886. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24887. + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
  24888. + */
  24889. +static MV_CESA_SIZE_TEST cbc3desMdMultiSizeTest504[] =
  24890. +{
  24891. + { 64, "8d10e00802460ede0058c139ba48bd2d" },
  24892. + { 80, "6f463057e1a90e0e91ae505b527bcec0" },
  24893. + { 352, "4938d48bdf86aece2c6851e7c6079788" },
  24894. + { 512, "516705d59f3cf810ebf2a13a23a7d42e" },
  24895. + { 1000, "a5a000ee5c830e67ddc6a2d2e5644b31" },
  24896. + { 1336, "44af60087b74ed07950088efbe3b126a" },
  24897. + { 1344, "1f5b39e0577920af731dabbfcf6dfc2a" },
  24898. + { 1400, "6804ea640e29b9cd39e08bc37dbce734" },
  24899. + { 1408, "4fb436624b02516fc9d1535466574bf9" },
  24900. + { 2048, "c909b0985c423d8d86719f701e9e83db" },
  24901. + { 3072, "cfe0bc34ef97213ee3d3f8b10122db21" },
  24902. + { 4048, "03ea10b5ae4ddeb20aed6af373082ed1" },
  24903. + { 6144, "b9a0ff4f87fc14b3c2dc6f0ed0998fdf" },
  24904. + { 6400, "6995f85d9d4985dd99e974ec7dda9dd6" },
  24905. + { 6528, "bbbb548ce2fa3d58467f6a6a5168a0e6" },
  24906. + { 8192, "afe101fbe745bb449ae4f50d10801456" },
  24907. + {16384, "9741706d0b1c923340c4660ff97cacdf" },
  24908. + {18432, "b0217becb73cb8f61fd79c7ce9d023fb" },
  24909. + { 0, NULL },
  24910. +};
  24911. +
  24912. +
  24913. +/* CryptoKey = 0x01234567, 0x89abcdef,
  24914. + * 0x01234567, 0x89abcdef,
  24915. + * 0x01234567, 0x89abcdef;
  24916. + * IV = 0x12345678, 0x90abcdef
  24917. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24918. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  24919. + * 0x11, 0x12, 0x13, 0x14
  24920. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24921. + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
  24922. + */
  24923. +static MV_CESA_SIZE_TEST cbc3desShaMultiSizeTest505[] =
  24924. +{
  24925. + { 64, "409187e5bdb0be4a7754ca3747f7433dc4f01b98" },
  24926. + { 80, "1b002ed050be743aa98860cf35659646bb8efcc0" },
  24927. + { 352, "6cbf7ebe50fa4fa6eecc19eca23f9eae553ccfff" },
  24928. + { 512, "cfb5253fb4bf72b743320c30c7e48c54965853b0" },
  24929. + { 1000, "95e04e1ca2937e7c5a9aba9e42d2bcdb8a7af21f" },
  24930. + { 1336, "3b5c1f5eee5837ebf67b83ae01405542d77a6627" },
  24931. + { 1344, "2b3d42ab25615437f98a1ee310b81d07a02badc2" },
  24932. + { 1400, "7f8687df7c1af44e4baf3c934b6cca5ab6bc993e" },
  24933. + { 1408, "473a581c5f04f7527d50793c845471ac87e86430" },
  24934. + { 2048, "e41d20cae7ebe34e6e828ed62b1e5734019037bb" },
  24935. + { 3072, "275664afd7a561d804e6b0d204e53939cde653ae" },
  24936. + { 4048, "0d220cc5b34aeeb46bbbd637dde6290b5a8285a3" },
  24937. + { 6144, "cb393ddcc8b1c206060625b7d822ef9839e67bc5" },
  24938. + { 6400, "dd3317e2a627fc04800f74a4b05bfda00fab0347" },
  24939. + { 6528, "8a74c3b2441ab3f5a7e08895cc432566219a7c41" },
  24940. + { 8192, "b8e6ef3a549ed0e005bd5b8b1a5fe6689e9711a7" },
  24941. + {16384, "55f59404008276cdac0e2ba0d193af2d40eac5ce" },
  24942. + {18432, "86ae6c4fc72369a54cce39938e2d0296cd9c6ec5" },
  24943. + { 0, NULL },
  24944. +};
  24945. +
  24946. +
  24947. +/* CryptoKey = 0x01234567, 0x89abcdef,
  24948. + * 0x01234567, 0x89abcdef,
  24949. + * 0x01234567, 0x89abcdef
  24950. + * IV = 0x12345678, 0x90abcdef
  24951. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24952. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  24953. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24954. + * Note: only sizes aligned to AES block size (16 bytes) allowed
  24955. + */
  24956. +static MV_CESA_SIZE_TEST cbcAes128md5multiSizeTest506[] =
  24957. +{
  24958. + { 16, "7ca4c2ba866751598720c5c4aa0d6786" },
  24959. + { 64, "7dba7fb988e80da609b1fea7254bced8" },
  24960. + { 80, "6b6e863ac5a71d15e3e9b1c86c9ba05f" },
  24961. + { 352, "a1ceb9c2e3021002400d525187a9f38c" },
  24962. + { 512, "596c055c1c55db748379223164075641" },
  24963. + { 1008, "f920989c02f3b3603f53c99d89492377" },
  24964. + { 1344, "2e496b73759d77ed32ea222dbd2e7b41" },
  24965. + { 1408, "7178c046b3a8d772efdb6a71c4991ea4" },
  24966. + { 2048, "a917f0099c69eb94079a8421714b6aad" },
  24967. + { 3072, "693cd5033d7f5391d3c958519fa9e934" },
  24968. + { 4048, "139dca91bcff65b3c40771749052906b" },
  24969. + { 6144, "428d9cef6df4fb70a6e9b6bbe4819e55" },
  24970. + { 6400, "9c0b909e76daa811e12b1fc17000a0c4" },
  24971. + { 6528, "ad876f6297186a7be1f1b907ed860eda" },
  24972. + { 8192, "479cbbaca37dd3191ea1f3e8134a0ef4" },
  24973. + {16384, "60fda559c74f91df538100c9842f2f15" },
  24974. + {18432, "4a3eb1cba1fa45f3981270953f720c42" },
  24975. + { 0, NULL },
  24976. +};
  24977. +
  24978. +
  24979. +/* CryptoKey = 0x01234567, 0x89abcdef,
  24980. + * 0x01234567, 0x89abcdef,
  24981. + * 0x01234567, 0x89abcdef;
  24982. + * IV = 0x12345678, 0x90abcdef
  24983. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  24984. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  24985. + * 0x11, 0x12, 0x13, 0x14
  24986. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  24987. + * Note: only sizes aligned to AES block size (16 bytes) allowed
  24988. + */
  24989. +static MV_CESA_SIZE_TEST cbcAes128sha1multiSizeTest507[] =
  24990. +{
  24991. + { 16, "9aa8dc1c45f0946daf78057fa978759c625c1fee" },
  24992. + { 64, "9f588fc1ede851e5f8b20256abc9979465ae2189" },
  24993. + { 80, "13558472d1fc1c90dffec6e5136c7203452d509b" },
  24994. + { 352, "6b93518e006cfaa1f7adb24615e7291fb0a27e06" },
  24995. + { 512, "096874951a77fbbf333e49d80c096ee2016e09bd" },
  24996. + { 1008, "696fc203c2e4b5ae0ec5d1db3f623c490bc6dbac" },
  24997. + { 1344, "79bf77509935ccd3528caaac6a5eb6481f74029b" },
  24998. + { 1408, "627f9462b95fc188e8cfa7eec15119bdc5d4fcf1" },
  24999. + { 2048, "3d50d0c005feba92fe41502d609fced9c882b4d1" },
  25000. + { 3072, "758807e5b983e3a91c06fb218fe0f73f77111e94" },
  25001. + { 4048, "ca90e85242e33f005da3504416a52098d0d31fb2" },
  25002. + { 6144, "8044c1d4fd06642dfc46990b4f18b61ef1e972cf" },
  25003. + { 6400, "166f1f4ea57409f04feba9fb1e39af0e00bd6f43" },
  25004. + { 6528, "0389016a39485d6e330f8b4215ddf718b404f7e9" },
  25005. + { 8192, "6df7ee2a8b61d6f7f860ce8dbf778f0c2a5b508b" },
  25006. + {16384, "a70a6d8dfa1f91ded621c3dbaed34162bc48783f" },
  25007. + {18432, "8dfad627922ce15df1eed10bdbed49244efa57db" },
  25008. + { 0, NULL },
  25009. +};
  25010. +
  25011. +
  25012. +void cesaTestPrintStatus(void);
  25013. +
  25014. +
  25015. +/*------------------------- LOCAL FUNCTIONs ---------------------------------*/
  25016. +MV_STATUS testCmd(int sid, int iter, MV_CESA_COMMAND* pCmd,
  25017. + MV_CESA_TEST_SESSION* pTestSession, MV_U8* pIV, int ivSize);
  25018. +MV_STATUS testClose(int idx);
  25019. +MV_STATUS testOpen(int idx);
  25020. +void close_session(int sid);
  25021. +void cesaTestCheckReady(const MV_CESA_RESULT *r);
  25022. +void cesaCheckReady(MV_CESA_RESULT* r);
  25023. +void printTestResults(int idx, MV_STATUS status, int checkMode);
  25024. +void cesaLastResult(void);
  25025. +void cesaTestPrintReq(int req, int offset, int size);
  25026. +
  25027. +void cesaTestPrintStatus(void);
  25028. +void cesaTestPrintSession(int idx);
  25029. +void sizeTest(int testIdx, int iter, int checkMode);
  25030. +void multiTest(int iter, int reqSize, int checkMode);
  25031. +void oneTest(int testIdx, int caseIdx,int iter, int reqSize, int checkMode);
  25032. +void multiSizeTest(int idx, int iter, int checkMode, char* inputData);
  25033. +void cesaTest(int iter, int reqSize, int checkMode);
  25034. +void cesaOneTest(int testIdx, int caseIdx,int iter, int reqSize, int checkMode);
  25035. +void combiTest(int iter, int reqSize, int checkMode);
  25036. +void shaTest(int iter, int reqSize, int checkMode);
  25037. +void mdTest(int iter, int reqSize, int checkMode);
  25038. +void aesTest(int iter, int reqSize, int checkMode);
  25039. +void tripleDesTest(int iter, int reqSize, int checkMode);
  25040. +void desTest(int iter, int reqSize, int checkMode);
  25041. +void cesaTestStop(void);
  25042. +MV_STATUS testRun(int idx, int caseIdx, int iter,int reqSize, int checkMode);
  25043. +void cesaTestStart(int bufNum, int bufSize);
  25044. +
  25045. +
  25046. +static MV_U32 getRate(MV_U32* remainder)
  25047. +{
  25048. + MV_U32 kBits, milliSec, rate;
  25049. +
  25050. + milliSec = 0;
  25051. + if( (cesaEndTicks - cesaBeginTicks) > 0)
  25052. + {
  25053. + milliSec = CESA_TEST_TICK_TO_MS(cesaEndTicks - cesaBeginTicks);
  25054. + }
  25055. + if(milliSec == 0)
  25056. + {
  25057. + if(remainder != NULL)
  25058. + *remainder = 0;
  25059. + return 0;
  25060. + }
  25061. +
  25062. + kBits = (cesaIteration*cesaRateSize*8)/1000;
  25063. + rate = kBits/milliSec;
  25064. + if(remainder != NULL)
  25065. + *remainder = ((kBits % milliSec)*10)/milliSec;
  25066. +
  25067. + return rate;
  25068. +}
  25069. +
  25070. +static char* extractMbuf(MV_CESA_MBUF *pMbuf,
  25071. + int offset, int size, char* hexStr)
  25072. +{
  25073. + mvCesaCopyFromMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset, size);
  25074. + mvBinToHex((const MV_U8*)cesaBinBuffer, hexStr, size);
  25075. +
  25076. + return hexStr;
  25077. +}
  25078. +
  25079. +static MV_BOOL cesaCheckMbuf(MV_CESA_MBUF *pMbuf,
  25080. + const char* hexString, int offset,
  25081. + int checkSize)
  25082. +{
  25083. + MV_BOOL isFailed = MV_FALSE;
  25084. + MV_STATUS status;
  25085. + int size = strlen(hexString)/2;
  25086. + int checkedSize = 0;
  25087. +/*
  25088. + mvOsPrintf("cesaCheckMbuf: pMbuf=%p, offset=%d, checkSize=%d, mBufSize=%d\n",
  25089. + pMbuf, offset, checkSize, pMbuf->mbufSize);
  25090. +*/
  25091. + if(pMbuf->mbufSize < (checkSize + offset))
  25092. + {
  25093. + mvOsPrintf("checkSize (%d) is too large: offset=%d, mbufSize=%d\n",
  25094. + checkSize, offset, pMbuf->mbufSize);
  25095. + return MV_TRUE;
  25096. + }
  25097. + status = mvCesaCopyFromMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset, checkSize);
  25098. + if(status != MV_OK)
  25099. + {
  25100. + mvOsPrintf("CesaTest: Can't copy %d bytes from Mbuf=%p to checkBuf=%p\n",
  25101. + checkSize, pMbuf, cesaBinBuffer);
  25102. + return MV_TRUE;
  25103. + }
  25104. +/*
  25105. + mvDebugMemDump(cesaBinBuffer, size, 1);
  25106. +*/
  25107. + mvHexToBin(hexString, (MV_U8*)cesaExpBinBuffer, size);
  25108. +
  25109. + /* Compare buffers */
  25110. + while(checkSize > checkedSize)
  25111. + {
  25112. + size = MV_MIN(size, (checkSize - checkedSize));
  25113. + if(memcmp(cesaExpBinBuffer, &cesaBinBuffer[checkedSize], size) != 0)
  25114. + {
  25115. + mvOsPrintf("CheckMbuf failed: checkSize=%d, size=%d, checkedSize=%d\n",
  25116. + checkSize, size, checkedSize);
  25117. + mvDebugMemDump(&cesaBinBuffer[checkedSize], size, 1);
  25118. + mvDebugMemDump(cesaExpBinBuffer, size, 1);
  25119. +
  25120. + isFailed = MV_TRUE;
  25121. + break;
  25122. + }
  25123. + checkedSize += size;
  25124. + }
  25125. +
  25126. + return isFailed;
  25127. +}
  25128. +
  25129. +static MV_STATUS cesaSetMbuf(MV_CESA_MBUF *pMbuf,
  25130. + const char* hexString,
  25131. + int offset, int reqSize)
  25132. +{
  25133. + MV_STATUS status = MV_OK;
  25134. + int copySize, size = strlen(hexString)/2;
  25135. +
  25136. + mvHexToBin(hexString, (MV_U8*)cesaBinBuffer, size);
  25137. +
  25138. + copySize = 0;
  25139. + while(reqSize > copySize)
  25140. + {
  25141. + size = MV_MIN(size, (reqSize - copySize));
  25142. +
  25143. + status = mvCesaCopyToMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset+copySize, size);
  25144. + if(status != MV_OK)
  25145. + {
  25146. + mvOsPrintf("cesaSetMbuf Error: Copy %d of %d bytes to MBuf\n",
  25147. + copySize, reqSize);
  25148. + break;
  25149. + }
  25150. + copySize += size;
  25151. + }
  25152. + pMbuf->mbufSize = offset+copySize;
  25153. + return status;
  25154. +}
  25155. +
  25156. +static MV_CESA_TEST_SESSION* getTestSessionDb(int idx, int* pTestIdx)
  25157. +{
  25158. + int testIdx, dbIdx = idx/100;
  25159. +
  25160. + if(dbIdx > MAX_TEST_TYPE)
  25161. + {
  25162. + mvOsPrintf("Wrong index %d - No such test type\n", idx);
  25163. + return NULL;
  25164. + }
  25165. + testIdx = idx % 100;
  25166. +
  25167. + if(testIdx >= cesaTestsDB[dbIdx].numSessions)
  25168. + {
  25169. + mvOsPrintf("Wrong index %d - No such test\n", idx);
  25170. + return NULL;
  25171. + }
  25172. + if(pTestIdx != NULL)
  25173. + *pTestIdx = testIdx;
  25174. +
  25175. + return cesaTestsDB[dbIdx].pSessions;
  25176. +}
  25177. +
  25178. +/* Debug */
  25179. +void cesaTestPrintReq(int req, int offset, int size)
  25180. +{
  25181. + MV_CESA_MBUF* pMbuf;
  25182. +
  25183. + mvOsPrintf("cesaTestPrintReq: req=%d, offset=%d, size=%d\n",
  25184. + req, offset, size);
  25185. + mvDebugMemDump(cesaCmdRing, 128, 4);
  25186. +
  25187. + pMbuf = cesaCmdRing[req].pSrc;
  25188. + mvCesaDebugMbuf("src", pMbuf, offset,size);
  25189. + pMbuf = cesaCmdRing[req].pDst;
  25190. + mvCesaDebugMbuf("dst", pMbuf, offset, size);
  25191. +
  25192. + cesaTestPrintStatus();
  25193. +}
  25194. +
  25195. +void cesaLastResult(void)
  25196. +{
  25197. + mvOsPrintf("Last Result: ReqId = %d, SessionId = %d, rc = (%d)\n",
  25198. + (MV_U32)cesaResult.pReqPrv, cesaResult.sessionId,
  25199. + cesaResult.retCode);
  25200. +}
  25201. +
  25202. +void printTestResults(int idx, MV_STATUS status, int checkMode)
  25203. +{
  25204. + int testIdx;
  25205. + MV_CESA_TEST_SESSION* pTestSessions = getTestSessionDb(idx, &testIdx);
  25206. +
  25207. + if(pTestSessions == NULL)
  25208. + return;
  25209. +
  25210. + mvOsPrintf("%-35s %4dx%-4d : ", pTestSessions[testIdx].name,
  25211. + cesaIteration, cesaReqSize);
  25212. + if( (status == MV_OK) &&
  25213. + (cesaCryptoError == 0) &&
  25214. + (cesaError == 0) &&
  25215. + (cesaReqIdError == 0) )
  25216. + {
  25217. + mvOsPrintf("Passed, Rate=%3u.%u Mbps (%5u cpp)\n",
  25218. + cesaRate, cesaRateAfterDot, cesaEndTicks - cesaBeginTicks);
  25219. + }
  25220. + else
  25221. + {
  25222. + mvOsPrintf("Failed, Status = 0x%x\n", status);
  25223. + if(cesaCryptoError > 0)
  25224. + mvOsPrintf("cryptoError : %d\n", cesaCryptoError);
  25225. + if(cesaReqIdError > 0)
  25226. + mvOsPrintf("reqIdError : %d\n", cesaReqIdError);
  25227. + if(cesaError > 0)
  25228. + mvOsPrintf("cesaError : %d\n", cesaError);
  25229. + }
  25230. + if(cesaTestIsrMissCount > 0)
  25231. + mvOsPrintf("cesaIsrMissed : %d\n", cesaTestIsrMissCount);
  25232. +}
  25233. +
  25234. +void cesaCheckReady(MV_CESA_RESULT* r)
  25235. +{
  25236. + int reqId;
  25237. + MV_CESA_MBUF *pMbuf;
  25238. + MV_BOOL isFailed;
  25239. +
  25240. + cesaResult = *r;
  25241. + reqId = (int)cesaResult.pReqPrv;
  25242. + pMbuf = cesaCmdRing[reqId].pDst;
  25243. +
  25244. +/*
  25245. + mvOsPrintf("cesaCheckReady: reqId=%d, checkOffset=%d, checkSize=%d\n",
  25246. + reqId, cesaCheckOffset, cesaCheckSize);
  25247. +*/
  25248. + /* Check expected reqId */
  25249. + if(reqId != cesaExpReqId)
  25250. + {
  25251. + cesaReqIdError++;
  25252. +/*
  25253. + mvOsPrintf("CESA reqId Error: cbIter=%d (%d), reqId=%d, expReqId=%d\n",
  25254. + cesaCbIter, cesaIteration, reqId, cesaExpReqId);
  25255. +*/
  25256. + }
  25257. + else
  25258. + {
  25259. + if( (cesaCheckMode == CESA_FULL_CHECK_MODE) ||
  25260. + (cesaCheckMode == CESA_FAST_CHECK_MODE) )
  25261. + {
  25262. + if(cesaResult.retCode != MV_OK)
  25263. + {
  25264. + cesaError++;
  25265. +
  25266. + mvOsPrintf("CESA Error: cbIter=%d (%d), reqId=%d, rc=%d\n",
  25267. + cesaCbIter, cesaIteration, reqId, cesaResult.retCode);
  25268. + }
  25269. + else
  25270. + {
  25271. + if( (cesaCheckSize > 0) && (cesaOutputHexStr != NULL) )
  25272. + {
  25273. + /* Check expected output */
  25274. +
  25275. + isFailed = cesaCheckMbuf(pMbuf, cesaOutputHexStr, cesaCheckOffset, cesaCheckSize);
  25276. + if(isFailed)
  25277. + {
  25278. + mvOsPrintf("CESA Crypto Error: cbIter=%d (%d), reqId=%d\n",
  25279. + cesaCbIter, cesaIteration, reqId);
  25280. +
  25281. + CESA_TEST_DEBUG_PRINT(("Error: reqId=%d, reqSize=%d, checkOffset=%d, checkSize=%d\n",
  25282. + reqId, cesaReqSize, cesaCheckOffset, cesaCheckSize));
  25283. +
  25284. + CESA_TEST_DEBUG_PRINT(("Output str: %s\n", cesaOutputHexStr));
  25285. +
  25286. + CESA_TEST_DEBUG_CODE( mvCesaDebugMbuf("error", pMbuf, 0, cesaCheckOffset+cesaCheckSize) );
  25287. +
  25288. + cesaCryptoError++;
  25289. + }
  25290. + }
  25291. + }
  25292. + }
  25293. + }
  25294. + if(cesaCheckMode == CESA_SHOW_CHECK_MODE)
  25295. + {
  25296. + extractMbuf(pMbuf, cesaCheckOffset, cesaCheckSize, cesaHexBuffer);
  25297. + mvOsPrintf("%4d, %s\n", cesaCheckOffset, cesaHexBuffer);
  25298. + }
  25299. +
  25300. + cesaCbIter++;
  25301. + if(cesaCbIter >= cesaIteration)
  25302. + {
  25303. + cesaCbIter = 0;
  25304. + cesaExpReqId = 0;
  25305. + cesaIsReady = MV_TRUE;
  25306. +
  25307. + cesaEndTicks = CESA_TEST_TICK_GET();
  25308. + cesaRate = getRate(&cesaRateAfterDot);
  25309. + }
  25310. + else
  25311. + {
  25312. + cesaExpReqId = reqId + 1;
  25313. + if(cesaExpReqId == CESA_DEF_REQ_SIZE)
  25314. + cesaExpReqId = 0;
  25315. + }
  25316. +}
  25317. +
  25318. +
  25319. +#ifdef MV_NETBSD
  25320. +static int cesaTestReadyIsr(void *arg)
  25321. +#else
  25322. +#ifdef __KERNEL__
  25323. +static irqreturn_t cesaTestReadyIsr( int irq , void *dev_id)
  25324. +#endif
  25325. +#ifdef MV_VXWORKS
  25326. +void cesaTestReadyIsr(void)
  25327. +#endif
  25328. +#endif
  25329. +{
  25330. + MV_U32 cause;
  25331. + MV_STATUS status;
  25332. + MV_CESA_RESULT result;
  25333. +
  25334. + cesaTestIsrCount++;
  25335. + /* Clear cause register */
  25336. + cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  25337. + if( (cause & MV_CESA_CAUSE_ACC_DMA_ALL_MASK) == 0)
  25338. + {
  25339. + mvOsPrintf("cesaTestReadyIsr: cause=0x%x\n", cause);
  25340. +#ifdef MV_NETBSD
  25341. + return 0;
  25342. +#else
  25343. +#ifdef __KERNEL__
  25344. + return 1;
  25345. +#else
  25346. + return;
  25347. +#endif
  25348. +#endif
  25349. + }
  25350. +
  25351. + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
  25352. +
  25353. + while(MV_TRUE)
  25354. + {
  25355. + /* Get Ready requests */
  25356. + status = mvCesaReadyGet(&result);
  25357. + if(status == MV_OK)
  25358. + cesaCheckReady(&result);
  25359. +
  25360. + break;
  25361. + }
  25362. + if( (cesaTestFull == 1) && (status != MV_BUSY) )
  25363. + {
  25364. + cesaTestFull = 0;
  25365. + CESA_TEST_WAKE_UP();
  25366. + }
  25367. +
  25368. +#ifdef __KERNEL__
  25369. + return 1;
  25370. +#endif
  25371. +}
  25372. +
  25373. +void
  25374. +cesaTestCheckReady(const MV_CESA_RESULT *r)
  25375. +{
  25376. + MV_CESA_RESULT result = *r;
  25377. +
  25378. + cesaCheckReady(&result);
  25379. +
  25380. + if (cesaTestFull == 1) {
  25381. + cesaTestFull = 0;
  25382. + CESA_TEST_WAKE_UP();
  25383. + }
  25384. +}
  25385. +
  25386. +static INLINE int open_session(MV_CESA_OPEN_SESSION* pOs)
  25387. +{
  25388. + MV_U16 sid;
  25389. + MV_STATUS status;
  25390. +
  25391. + status = mvCesaSessionOpen(pOs, (short*)&sid);
  25392. + if(status != MV_OK)
  25393. + {
  25394. + mvOsPrintf("CesaTest: Can't open new session - status = 0x%x\n",
  25395. + status);
  25396. + return -1;
  25397. + }
  25398. +
  25399. + return (int)sid;
  25400. +}
  25401. +
  25402. +void close_session(int sid)
  25403. +{
  25404. + MV_STATUS status;
  25405. +
  25406. + status = mvCesaSessionClose(sid);
  25407. + if(status != MV_OK)
  25408. + {
  25409. + mvOsPrintf("CesaTest: Can't close session %d - status = 0x%x\n",
  25410. + sid, status);
  25411. + }
  25412. +}
  25413. +
  25414. +MV_STATUS testOpen(int idx)
  25415. +{
  25416. + MV_CESA_OPEN_SESSION os;
  25417. + int sid, i, testIdx;
  25418. + MV_CESA_TEST_SESSION* pTestSession;
  25419. + MV_U16 digestSize = 0;
  25420. +
  25421. + pTestSession = getTestSessionDb(idx, &testIdx);
  25422. + if(pTestSession == NULL)
  25423. + {
  25424. + mvOsPrintf("Test %d is not exist\n", idx);
  25425. + return MV_BAD_PARAM;
  25426. + }
  25427. + pTestSession = &pTestSession[testIdx];
  25428. +
  25429. + if(pTestSession->sid != -1)
  25430. + {
  25431. + mvOsPrintf("Session for test %d already created: sid=%d\n",
  25432. + idx, pTestSession->sid);
  25433. + return MV_OK;
  25434. + }
  25435. +
  25436. + os.cryptoAlgorithm = pTestSession->cryptoAlgorithm;
  25437. + os.macMode = pTestSession->macAlgorithm;
  25438. + switch(os.macMode)
  25439. + {
  25440. + case MV_CESA_MAC_MD5:
  25441. + case MV_CESA_MAC_HMAC_MD5:
  25442. + digestSize = MV_CESA_MD5_DIGEST_SIZE;
  25443. + break;
  25444. +
  25445. + case MV_CESA_MAC_SHA1:
  25446. + case MV_CESA_MAC_HMAC_SHA1:
  25447. + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
  25448. + break;
  25449. +
  25450. + case MV_CESA_MAC_NULL:
  25451. + digestSize = 0;
  25452. + }
  25453. + os.cryptoMode = pTestSession->cryptoMode;
  25454. + os.direction = pTestSession->direction;
  25455. + os.operation = pTestSession->operation;
  25456. +
  25457. + for(i=0; i<pTestSession->cryptoKeySize; i++)
  25458. + os.cryptoKey[i] = pTestSession->pCryptoKey[i];
  25459. +
  25460. + os.cryptoKeyLength = pTestSession->cryptoKeySize;
  25461. +
  25462. + for(i=0; i<pTestSession->macKeySize; i++)
  25463. + os.macKey[i] = pTestSession->pMacKey[i];
  25464. +
  25465. + os.macKeyLength = pTestSession->macKeySize;
  25466. + os.digestSize = digestSize;
  25467. +
  25468. + sid = open_session(&os);
  25469. + if(sid == -1)
  25470. + {
  25471. + mvOsPrintf("Can't open session for test %d: rc=0x%x\n",
  25472. + idx, cesaResult.retCode);
  25473. + return cesaResult.retCode;
  25474. + }
  25475. + CESA_TEST_DEBUG_PRINT(("Opened session: sid = %d\n", sid));
  25476. + pTestSession->sid = sid;
  25477. + return MV_OK;
  25478. +}
  25479. +
  25480. +MV_STATUS testClose(int idx)
  25481. +{
  25482. + int testIdx;
  25483. + MV_CESA_TEST_SESSION* pTestSession;
  25484. +
  25485. + pTestSession = getTestSessionDb(idx, &testIdx);
  25486. + if(pTestSession == NULL)
  25487. + {
  25488. + mvOsPrintf("Test %d is not exist\n", idx);
  25489. + return MV_BAD_PARAM;
  25490. + }
  25491. + pTestSession = &pTestSession[testIdx];
  25492. +
  25493. + if(pTestSession->sid == -1)
  25494. + {
  25495. + mvOsPrintf("Test session %d is not opened\n", idx);
  25496. + return MV_NO_SUCH;
  25497. + }
  25498. +
  25499. + close_session(pTestSession->sid);
  25500. + pTestSession->sid = -1;
  25501. +
  25502. + return MV_OK;
  25503. +}
  25504. +
  25505. +MV_STATUS testCmd(int sid, int iter, MV_CESA_COMMAND* pCmd,
  25506. + MV_CESA_TEST_SESSION* pTestSession, MV_U8* pIV, int ivSize)
  25507. +{
  25508. + int cmdReqId = 0;
  25509. + int i;
  25510. + MV_STATUS rc = MV_OK;
  25511. + char ivZeroHex[] = "0000";
  25512. +
  25513. + if(iter == 0)
  25514. + iter = CESA_DEF_ITER_NUM;
  25515. +
  25516. + if(pCmd == NULL)
  25517. + {
  25518. + mvOsPrintf("testCmd failed: pCmd=NULL\n");
  25519. + return MV_BAD_PARAM;
  25520. + }
  25521. + pCmd->sessionId = sid;
  25522. +
  25523. + cesaCryptoError = 0;
  25524. + cesaReqIdError = 0;
  25525. + cesaError = 0;
  25526. + cesaTestIsrMissCount = 0;
  25527. + cesaIsReady = MV_FALSE;
  25528. + cesaIteration = iter;
  25529. +
  25530. + if(cesaInputHexStr == NULL)
  25531. + cesaInputHexStr = cesaPlainHexEbc;
  25532. +
  25533. + for(i=0; i<CESA_DEF_REQ_SIZE; i++)
  25534. + {
  25535. + pCmd->pSrc = (MV_CESA_MBUF*)(cesaCmdRing[i].pSrc);
  25536. + if(pIV != NULL)
  25537. + {
  25538. + /* If IV from SA - set IV in Source buffer to zeros */
  25539. + cesaSetMbuf(pCmd->pSrc, ivZeroHex, 0, pCmd->cryptoOffset);
  25540. + cesaSetMbuf(pCmd->pSrc, cesaInputHexStr, pCmd->cryptoOffset,
  25541. + (cesaReqSize - pCmd->cryptoOffset));
  25542. + }
  25543. + else
  25544. + {
  25545. + cesaSetMbuf(pCmd->pSrc, cesaInputHexStr, 0, cesaReqSize);
  25546. + }
  25547. + pCmd->pDst = (MV_CESA_MBUF*)(cesaCmdRing[i].pDst);
  25548. + cesaSetMbuf(pCmd->pDst, cesaNullPlainHexText, 0, cesaReqSize);
  25549. +
  25550. + memcpy(&cesaCmdRing[i], pCmd, sizeof(*pCmd));
  25551. + }
  25552. +
  25553. + if(cesaCheckMode == CESA_SW_SHOW_CHECK_MODE)
  25554. + {
  25555. + MV_U8 pDigest[MV_CESA_MAX_DIGEST_SIZE];
  25556. +
  25557. + if(pTestSession->macAlgorithm == MV_CESA_MAC_MD5)
  25558. + {
  25559. + mvMD5(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, pDigest);
  25560. + mvOsPrintf("SW HASH_MD5: reqSize=%d, macLength=%d\n",
  25561. + cesaReqSize, pCmd->macLength);
  25562. + mvDebugMemDump(pDigest, MV_CESA_MD5_DIGEST_SIZE, 1);
  25563. + return MV_OK;
  25564. + }
  25565. + if(pTestSession->macAlgorithm == MV_CESA_MAC_SHA1)
  25566. + {
  25567. + mvSHA1(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, pDigest);
  25568. + mvOsPrintf("SW HASH_SHA1: reqSize=%d, macLength=%d\n",
  25569. + cesaReqSize, pCmd->macLength);
  25570. + mvDebugMemDump(pDigest, MV_CESA_SHA1_DIGEST_SIZE, 1);
  25571. + return MV_OK;
  25572. + }
  25573. + }
  25574. +
  25575. + cesaBeginTicks = CESA_TEST_TICK_GET();
  25576. + CESA_TEST_DEBUG_CODE( memset(cesaTestTrace, 0, sizeof(cesaTestTrace));
  25577. + cesaTestTraceIdx = 0;
  25578. + );
  25579. +
  25580. + if(cesaCheckMode == CESA_SW_NULL_CHECK_MODE)
  25581. + {
  25582. + volatile MV_U8 pDigest[MV_CESA_MAX_DIGEST_SIZE];
  25583. +
  25584. + for(i=0; i<iter; i++)
  25585. + {
  25586. + if(pTestSession->macAlgorithm == MV_CESA_MAC_MD5)
  25587. + {
  25588. + mvMD5(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, (unsigned char*)pDigest);
  25589. + }
  25590. + if(pTestSession->macAlgorithm == MV_CESA_MAC_SHA1)
  25591. + {
  25592. + mvSHA1(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, (MV_U8 *)pDigest);
  25593. + }
  25594. + }
  25595. + cesaEndTicks = CESA_TEST_TICK_GET();
  25596. + cesaRate = getRate(&cesaRateAfterDot);
  25597. + cesaIsReady = MV_TRUE;
  25598. +
  25599. + return MV_OK;
  25600. + }
  25601. +
  25602. + /*cesaTestIsrCount = 0;*/
  25603. + /*mvCesaDebugStatsClear();*/
  25604. +
  25605. +#ifndef MV_NETBSD
  25606. + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
  25607. +#endif
  25608. +
  25609. + for(i=0; i<iter; i++)
  25610. + {
  25611. + unsigned long flags;
  25612. +
  25613. + pCmd = &cesaCmdRing[cmdReqId];
  25614. + pCmd->pReqPrv = (void*)cmdReqId;
  25615. +
  25616. + CESA_TEST_LOCK(flags);
  25617. +
  25618. + rc = mvCesaAction(pCmd);
  25619. + if(rc == MV_NO_RESOURCE)
  25620. + cesaTestFull = 1;
  25621. +
  25622. + CESA_TEST_UNLOCK(flags);
  25623. +
  25624. + if(rc == MV_NO_RESOURCE)
  25625. + {
  25626. + CESA_TEST_LOCK(flags);
  25627. + CESA_TEST_WAIT( (cesaTestFull == 0), 100);
  25628. + CESA_TEST_UNLOCK(flags);
  25629. + if(cesaTestFull == 1)
  25630. + {
  25631. + mvOsPrintf("CESA Test timeout: i=%d, iter=%d, cesaTestFull=%d\n",
  25632. + i, iter, cesaTestFull);
  25633. + cesaTestFull = 0;
  25634. + return MV_TIMEOUT;
  25635. + }
  25636. +
  25637. + CESA_TEST_LOCK(flags);
  25638. +
  25639. + rc = mvCesaAction(pCmd);
  25640. +
  25641. + CESA_TEST_UNLOCK(flags);
  25642. + }
  25643. + if( (rc != MV_OK) && (rc != MV_NO_MORE) )
  25644. + {
  25645. + mvOsPrintf("mvCesaAction failed: rc=%d\n", rc);
  25646. + return rc;
  25647. + }
  25648. +
  25649. + cmdReqId++;
  25650. + if(cmdReqId >= CESA_DEF_REQ_SIZE)
  25651. + cmdReqId = 0;
  25652. +
  25653. +#ifdef MV_LINUX
  25654. + /* Reschedule each 16 requests */
  25655. + if( (i & 0xF) == 0)
  25656. + schedule();
  25657. +#endif
  25658. + }
  25659. + return MV_OK;
  25660. +}
  25661. +
  25662. +void cesaTestStart(int bufNum, int bufSize)
  25663. +{
  25664. + int i, j, idx;
  25665. + MV_CESA_MBUF *pMbufSrc, *pMbufDst;
  25666. + MV_BUF_INFO *pFragsSrc, *pFragsDst;
  25667. + char *pBuf;
  25668. +#ifndef MV_NETBSD
  25669. + int numOfSessions, queueDepth;
  25670. + char *pSram;
  25671. + MV_STATUS status;
  25672. + MV_CPU_DEC_WIN addrDecWin;
  25673. +#endif
  25674. +
  25675. + cesaCmdRing = mvOsMalloc(sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);
  25676. + if(cesaCmdRing == NULL)
  25677. + {
  25678. + mvOsPrintf("testStart: Can't allocate %ld bytes of memory\n",
  25679. + sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);
  25680. + return;
  25681. + }
  25682. + memset(cesaCmdRing, 0, sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);
  25683. +
  25684. + if(bufNum == 0)
  25685. + bufNum = CESA_DEF_BUF_NUM;
  25686. +
  25687. + if(bufSize == 0)
  25688. + bufSize = CESA_DEF_BUF_SIZE;
  25689. +
  25690. + cesaBufNum = bufNum;
  25691. + cesaBufSize = bufSize;
  25692. + mvOsPrintf("CESA test started: bufNum = %d, bufSize = %d\n",
  25693. + bufNum, bufSize);
  25694. +
  25695. + cesaHexBuffer = mvOsMalloc(2*bufNum*bufSize);
  25696. + if(cesaHexBuffer == NULL)
  25697. + {
  25698. + mvOsPrintf("testStart: Can't malloc %d bytes for cesaHexBuffer.\n",
  25699. + 2*bufNum*bufSize);
  25700. + return;
  25701. + }
  25702. + memset(cesaHexBuffer, 0, (2*bufNum*bufSize));
  25703. +
  25704. + cesaBinBuffer = mvOsMalloc(bufNum*bufSize);
  25705. + if(cesaBinBuffer == NULL)
  25706. + {
  25707. + mvOsPrintf("testStart: Can't malloc %d bytes for cesaBinBuffer\n",
  25708. + bufNum*bufSize);
  25709. + return;
  25710. + }
  25711. + memset(cesaBinBuffer, 0, (bufNum*bufSize));
  25712. +
  25713. + cesaExpBinBuffer = mvOsMalloc(bufNum*bufSize);
  25714. + if(cesaExpBinBuffer == NULL)
  25715. + {
  25716. + mvOsPrintf("testStart: Can't malloc %d bytes for cesaExpBinBuffer\n",
  25717. + bufNum*bufSize);
  25718. + return;
  25719. + }
  25720. + memset(cesaExpBinBuffer, 0, (bufNum*bufSize));
  25721. +
  25722. + CESA_TEST_WAIT_INIT();
  25723. +
  25724. + pMbufSrc = mvOsMalloc(sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
  25725. + pFragsSrc = mvOsMalloc(sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
  25726. +
  25727. + pMbufDst = mvOsMalloc(sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
  25728. + pFragsDst = mvOsMalloc(sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
  25729. +
  25730. + if( (pMbufSrc == NULL) || (pFragsSrc == NULL) ||
  25731. + (pMbufDst == NULL) || (pFragsDst == NULL) )
  25732. + {
  25733. + mvOsPrintf("testStart: Can't malloc Src and Dst pMbuf and pFrags structures.\n");
  25734. + /* !!!! Dima cesaTestCleanup();*/
  25735. + return;
  25736. + }
  25737. +
  25738. + memset(pMbufSrc, 0, sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
  25739. + memset(pFragsSrc, 0, sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
  25740. +
  25741. + memset(pMbufDst, 0, sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
  25742. + memset(pFragsDst, 0, sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
  25743. +
  25744. + mvOsPrintf("Cesa Test Start: pMbufSrc=%p, pFragsSrc=%p, pMbufDst=%p, pFragsDst=%p\n",
  25745. + pMbufSrc, pFragsSrc, pMbufDst, pFragsDst);
  25746. +
  25747. + idx = 0;
  25748. + for(i=0; i<CESA_DEF_REQ_SIZE; i++)
  25749. + {
  25750. + pBuf = mvOsIoCachedMalloc(cesaTestOSHandle,bufSize * bufNum * 2,
  25751. + &cesaReqBufs[i].bufPhysAddr,
  25752. + &cesaReqBufs[i].memHandle);
  25753. + if(pBuf == NULL)
  25754. + {
  25755. + mvOsPrintf("testStart: Can't malloc %d bytes for pBuf\n",
  25756. + bufSize * bufNum * 2);
  25757. + return;
  25758. + }
  25759. +
  25760. + memset(pBuf, 0, bufSize * bufNum * 2);
  25761. + mvOsCacheFlush(cesaTestOSHandle,pBuf, bufSize * bufNum * 2);
  25762. + if(pBuf == NULL)
  25763. + {
  25764. + mvOsPrintf("cesaTestStart: Can't allocate %d bytes for req_%d buffers\n",
  25765. + bufSize * bufNum * 2, i);
  25766. + return;
  25767. + }
  25768. +
  25769. + cesaReqBufs[i].bufVirtPtr = (MV_U8*)pBuf;
  25770. + cesaReqBufs[i].bufSize = bufSize * bufNum * 2;
  25771. +
  25772. + cesaCmdRing[i].pSrc = &pMbufSrc[i];
  25773. + cesaCmdRing[i].pSrc->pFrags = &pFragsSrc[idx];
  25774. + cesaCmdRing[i].pSrc->numFrags = bufNum;
  25775. + cesaCmdRing[i].pSrc->mbufSize = 0;
  25776. +
  25777. + cesaCmdRing[i].pDst = &pMbufDst[i];
  25778. + cesaCmdRing[i].pDst->pFrags = &pFragsDst[idx];
  25779. + cesaCmdRing[i].pDst->numFrags = bufNum;
  25780. + cesaCmdRing[i].pDst->mbufSize = 0;
  25781. +
  25782. + for(j=0; j<bufNum; j++)
  25783. + {
  25784. + cesaCmdRing[i].pSrc->pFrags[j].bufVirtPtr = (MV_U8*)pBuf;
  25785. + cesaCmdRing[i].pSrc->pFrags[j].bufSize = bufSize;
  25786. + pBuf += bufSize;
  25787. + cesaCmdRing[i].pDst->pFrags[j].bufVirtPtr = (MV_U8*)pBuf;
  25788. + cesaCmdRing[i].pDst->pFrags[j].bufSize = bufSize;
  25789. + pBuf += bufSize;
  25790. + }
  25791. + idx += bufNum;
  25792. + }
  25793. +
  25794. +#ifndef MV_NETBSD
  25795. + if (mvCpuIfTargetWinGet(CRYPT_ENG, &addrDecWin) == MV_OK)
  25796. + pSram = (char*)addrDecWin.addrWin.baseLow;
  25797. + else
  25798. + {
  25799. + mvOsPrintf("mvCesaInit: ERR. mvCpuIfTargetWinGet failed\n");
  25800. + return;
  25801. + }
  25802. +
  25803. +#ifdef MV_CESA_NO_SRAM
  25804. + pSram = mvOsMalloc(4*1024+8);
  25805. + if(pSram == NULL)
  25806. + {
  25807. + mvOsPrintf("CesaTest: can't allocate %d bytes for SRAM simulation\n",
  25808. + 4*1024+8);
  25809. + /* !!!! Dima cesaTestCleanup();*/
  25810. + return;
  25811. + }
  25812. + pSram = (MV_U8*)MV_ALIGN_UP((MV_U32)pSram, 8);
  25813. +#endif /* MV_CESA_NO_SRAM */
  25814. +
  25815. + numOfSessions = CESA_DEF_SESSION_NUM;
  25816. + queueDepth = CESA_DEF_REQ_SIZE - MV_CESA_MAX_CHAN;
  25817. +
  25818. + status = mvCesaInit(numOfSessions, queueDepth, pSram, NULL);
  25819. + if(status != MV_OK)
  25820. + {
  25821. + mvOsPrintf("mvCesaInit is Failed: status = 0x%x\n", status);
  25822. + /* !!!! Dima cesaTestCleanup();*/
  25823. + return;
  25824. + }
  25825. +#endif /* !MV_NETBSD */
  25826. +
  25827. + /* Prepare data for tests */
  25828. + for(i=0; i<50; i++)
  25829. + strcat((char*)cesaDataHexStr3, "dd");
  25830. +
  25831. + strcpy((char*)cesaDataAndMd5digest3, cesaDataHexStr3);
  25832. + strcpy((char*)cesaDataAndSha1digest3, cesaDataHexStr3);
  25833. +
  25834. + /* Digest must be 8 byte aligned */
  25835. + for(; i<56; i++)
  25836. + {
  25837. + strcat((char*)cesaDataAndMd5digest3, "00");
  25838. + strcat((char*)cesaDataAndSha1digest3, "00");
  25839. + }
  25840. + strcat((char*)cesaDataAndMd5digest3, cesaHmacMd5digestHex3);
  25841. + strcat((char*)cesaDataAndSha1digest3, cesaHmacSha1digestHex3);
  25842. +
  25843. +#ifndef MV_NETBSD
  25844. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  25845. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, MV_CESA_CAUSE_ACC_DMA_MASK);
  25846. +#endif
  25847. +
  25848. +#ifdef MV_VXWORKS
  25849. + {
  25850. + MV_STATUS status;
  25851. +
  25852. + status = intConnect((VOIDFUNCPTR *)INT_LVL_CESA, cesaTestReadyIsr, (int)NULL);
  25853. + if (status != OK)
  25854. + {
  25855. + mvOsPrintf("CESA: Can't connect CESA (%d) interrupt, status=0x%x \n",
  25856. + INT_LVL_CESA, status);
  25857. + /* !!!! Dima cesaTestCleanup();*/
  25858. + return;
  25859. + }
  25860. + cesaSemId = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE);
  25861. + if(cesaSemId == NULL)
  25862. + {
  25863. + mvOsPrintf("cesaTestStart: Can't create semaphore\n");
  25864. + return;
  25865. + }
  25866. + intEnable(INT_LVL_CESA);
  25867. + }
  25868. +#endif /* MV_VXWORKS */
  25869. +
  25870. +#if !defined(MV_NETBSD) && defined(__KERNEL__)
  25871. + if( request_irq(CESA_IRQ, cesaTestReadyIsr, (SA_INTERRUPT) , "cesa_test", NULL ) )
  25872. + {
  25873. + mvOsPrintf( "cannot assign irq\n" );
  25874. + /* !!!! Dima cesaTestCleanup();*/
  25875. + return;
  25876. + }
  25877. + spin_lock_init( &cesaLock );
  25878. +#endif
  25879. +}
  25880. +
  25881. +MV_STATUS testRun(int idx, int caseIdx, int iter,
  25882. + int reqSize, int checkMode)
  25883. +{
  25884. + int testIdx, count, sid, digestSize;
  25885. + int blockSize;
  25886. + MV_CESA_TEST_SESSION* pTestSession;
  25887. + MV_CESA_COMMAND cmd;
  25888. + MV_STATUS status;
  25889. +
  25890. + memset(&cmd, 0, sizeof(cmd));
  25891. +
  25892. + pTestSession = getTestSessionDb(idx, &testIdx);
  25893. + if(pTestSession == NULL)
  25894. + {
  25895. + mvOsPrintf("Test %d is not exist\n", idx);
  25896. + return MV_BAD_PARAM;
  25897. + }
  25898. + pTestSession = &pTestSession[testIdx];
  25899. +
  25900. + sid = pTestSession->sid;
  25901. + if(sid == -1)
  25902. + {
  25903. + mvOsPrintf("Test %d is not opened\n", idx);
  25904. + return MV_BAD_STATE;
  25905. + }
  25906. + switch(pTestSession->cryptoAlgorithm)
  25907. + {
  25908. + case MV_CESA_CRYPTO_DES:
  25909. + case MV_CESA_CRYPTO_3DES:
  25910. + blockSize = MV_CESA_DES_BLOCK_SIZE;
  25911. + break;
  25912. +
  25913. + case MV_CESA_CRYPTO_AES:
  25914. + blockSize = MV_CESA_AES_BLOCK_SIZE;
  25915. + break;
  25916. +
  25917. + case MV_CESA_CRYPTO_NULL:
  25918. + blockSize = 0;
  25919. + break;
  25920. +
  25921. + default:
  25922. + mvOsPrintf("cesaTestRun: Bad CryptoAlgorithm=%d\n",
  25923. + pTestSession->cryptoAlgorithm);
  25924. + return MV_BAD_PARAM;
  25925. + }
  25926. + switch(pTestSession->macAlgorithm)
  25927. + {
  25928. + case MV_CESA_MAC_MD5:
  25929. + case MV_CESA_MAC_HMAC_MD5:
  25930. + digestSize = MV_CESA_MD5_DIGEST_SIZE;
  25931. + break;
  25932. +
  25933. + case MV_CESA_MAC_SHA1:
  25934. + case MV_CESA_MAC_HMAC_SHA1:
  25935. + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
  25936. + break;
  25937. + default:
  25938. + digestSize = 0;
  25939. + }
  25940. +
  25941. + if(iter == 0)
  25942. + iter = CESA_DEF_ITER_NUM;
  25943. +
  25944. + if(pTestSession->direction == MV_CESA_DIR_ENCODE)
  25945. + {
  25946. + cesaOutputHexStr = cesaTestCases[caseIdx].cipherHexStr;
  25947. + cesaInputHexStr = cesaTestCases[caseIdx].plainHexStr;
  25948. + }
  25949. + else
  25950. + {
  25951. + cesaOutputHexStr = cesaTestCases[caseIdx].plainHexStr;
  25952. + cesaInputHexStr = cesaTestCases[caseIdx].cipherHexStr;
  25953. + }
  25954. +
  25955. + cmd.sessionId = sid;
  25956. + if(checkMode == CESA_FAST_CHECK_MODE)
  25957. + {
  25958. + cmd.cryptoLength = cesaTestCases[caseIdx].cryptoLength;
  25959. + cmd.macLength = cesaTestCases[caseIdx].macLength;
  25960. + }
  25961. + else
  25962. + {
  25963. + cmd.cryptoLength = reqSize;
  25964. + cmd.macLength = reqSize;
  25965. + }
  25966. + cesaRateSize = cmd.cryptoLength;
  25967. + cesaReqSize = cmd.cryptoLength;
  25968. + cmd.cryptoOffset = 0;
  25969. + if(pTestSession->operation != MV_CESA_MAC_ONLY)
  25970. + {
  25971. + if( (pTestSession->cryptoMode == MV_CESA_CRYPTO_CBC) ||
  25972. + (pTestSession->cryptoMode == MV_CESA_CRYPTO_CTR) )
  25973. + {
  25974. + cmd.ivOffset = 0;
  25975. + cmd.cryptoOffset = blockSize;
  25976. + if(cesaTestCases[caseIdx].pCryptoIV == NULL)
  25977. + {
  25978. + cmd.ivFromUser = 1;
  25979. + }
  25980. + else
  25981. + {
  25982. + cmd.ivFromUser = 0;
  25983. + mvCesaCryptoIvSet(cesaTestCases[caseIdx].pCryptoIV, blockSize);
  25984. + }
  25985. + cesaReqSize = cmd.cryptoOffset + cmd.cryptoLength;
  25986. + }
  25987. + }
  25988. +
  25989. +/*
  25990. + mvOsPrintf("ivFromUser=%d, cryptoLength=%d, cesaReqSize=%d, cryptoOffset=%d\n",
  25991. + cmd.ivFromUser, cmd.cryptoLength, cesaReqSize, cmd.cryptoOffset);
  25992. +*/
  25993. + if(pTestSession->operation != MV_CESA_CRYPTO_ONLY)
  25994. + {
  25995. + cmd.macOffset = cmd.cryptoOffset;
  25996. +
  25997. + if(cesaTestCases[caseIdx].digestOffset == -1)
  25998. + {
  25999. + cmd.digestOffset = cmd.macOffset + cmd.macLength;
  26000. + cmd.digestOffset = MV_ALIGN_UP(cmd.digestOffset, 8);
  26001. + }
  26002. + else
  26003. + {
  26004. + cmd.digestOffset = cesaTestCases[caseIdx].digestOffset;
  26005. + }
  26006. + if( (cmd.digestOffset + digestSize) > cesaReqSize)
  26007. + cesaReqSize = cmd.digestOffset + digestSize;
  26008. + }
  26009. +
  26010. + cesaCheckMode = checkMode;
  26011. +
  26012. + if(checkMode == CESA_NULL_CHECK_MODE)
  26013. + {
  26014. + cesaCheckSize = 0;
  26015. + cesaCheckOffset = 0;
  26016. + }
  26017. + else
  26018. + {
  26019. + if(pTestSession->operation == MV_CESA_CRYPTO_ONLY)
  26020. + {
  26021. + cesaCheckOffset = 0;
  26022. + cesaCheckSize = cmd.cryptoLength;
  26023. + }
  26024. + else
  26025. + {
  26026. + cesaCheckSize = digestSize;
  26027. + cesaCheckOffset = cmd.digestOffset;
  26028. + }
  26029. + }
  26030. +/*
  26031. + mvOsPrintf("reqSize=%d, checkSize=%d, checkOffset=%d, checkMode=%d\n",
  26032. + cesaReqSize, cesaCheckSize, cesaCheckOffset, cesaCheckMode);
  26033. +
  26034. + mvOsPrintf("blockSize=%d, ivOffset=%d, ivFromUser=%d, crOffset=%d, crLength=%d\n",
  26035. + blockSize, cmd.ivOffset, cmd.ivFromUser,
  26036. + cmd.cryptoOffset, cmd.cryptoLength);
  26037. +
  26038. + mvOsPrintf("macOffset=%d, digestOffset=%d, macLength=%d\n",
  26039. + cmd.macOffset, cmd.digestOffset, cmd.macLength);
  26040. +*/
  26041. + status = testCmd(sid, iter, &cmd, pTestSession,
  26042. + cesaTestCases[caseIdx].pCryptoIV, blockSize);
  26043. +
  26044. + if(status != MV_OK)
  26045. + return status;
  26046. +
  26047. + /* Wait when all callbacks is received */
  26048. + count = 0;
  26049. + while(cesaIsReady == MV_FALSE)
  26050. + {
  26051. + mvOsSleep(10);
  26052. + count++;
  26053. + if(count > 100)
  26054. + {
  26055. + mvOsPrintf("testRun: Timeout occured\n");
  26056. + return MV_TIMEOUT;
  26057. + }
  26058. + }
  26059. +
  26060. + return MV_OK;
  26061. +}
  26062. +
  26063. +
  26064. +void cesaTestStop(void)
  26065. +{
  26066. + MV_CESA_MBUF *pMbufSrc, *pMbufDst;
  26067. + MV_BUF_INFO *pFragsSrc, *pFragsDst;
  26068. + int i;
  26069. +
  26070. + /* Release all allocated memories */
  26071. + pMbufSrc = (MV_CESA_MBUF*)(cesaCmdRing[0].pSrc);
  26072. + pFragsSrc = cesaCmdRing[0].pSrc->pFrags;
  26073. +
  26074. + pMbufDst = (MV_CESA_MBUF*)(cesaCmdRing[0].pDst);
  26075. + pFragsDst = cesaCmdRing[0].pDst->pFrags;
  26076. +
  26077. + mvOsFree(pMbufSrc);
  26078. + mvOsFree(pMbufDst);
  26079. + mvOsFree(pFragsSrc);
  26080. + mvOsFree(pFragsDst);
  26081. +
  26082. + for(i=0; i<CESA_DEF_REQ_SIZE; i++)
  26083. + {
  26084. + mvOsIoCachedFree(cesaTestOSHandle,cesaReqBufs[i].bufSize,
  26085. + cesaReqBufs[i].bufPhysAddr,cesaReqBufs[i].bufVirtPtr,
  26086. + cesaReqBufs[i].memHandle);
  26087. + }
  26088. + cesaDataHexStr3[0] = '\0';
  26089. +}
  26090. +
  26091. +void desTest(int iter, int reqSize, int checkMode)
  26092. +{
  26093. + int mode, i;
  26094. + MV_STATUS status;
  26095. +
  26096. + mode = checkMode;
  26097. + if(checkMode == CESA_FULL_CHECK_MODE)
  26098. + mode = CESA_FAST_CHECK_MODE;
  26099. + i = iter;
  26100. + if(mode != CESA_NULL_CHECK_MODE)
  26101. + i = 1;
  26102. +
  26103. + testOpen(0);
  26104. + testOpen(1);
  26105. + testOpen(2);
  26106. + testOpen(3);
  26107. +
  26108. +/* DES / ECB mode / Encrypt only */
  26109. + status = testRun(0, 1, iter, reqSize, checkMode);
  26110. + printTestResults(0, status, checkMode);
  26111. +
  26112. +/* DES / ECB mode / Decrypt only */
  26113. + status = testRun(1, 1, iter, reqSize, checkMode);
  26114. + printTestResults(1, status, checkMode);
  26115. +
  26116. +/* DES / CBC mode / Encrypt only */
  26117. + status = testRun(2, 2, i, reqSize, mode);
  26118. + printTestResults(2, status, mode);
  26119. +
  26120. +/* DES / CBC mode / Decrypt only */
  26121. + status = testRun(3, 2, iter, reqSize, mode);
  26122. + printTestResults(3, status, mode);
  26123. +
  26124. + testClose(0);
  26125. + testClose(1);
  26126. + testClose(2);
  26127. + testClose(3);
  26128. +}
  26129. +
  26130. +void tripleDesTest(int iter, int reqSize, int checkMode)
  26131. +{
  26132. + int mode, i;
  26133. + MV_STATUS status;
  26134. +
  26135. + mode = checkMode;
  26136. + if(checkMode == CESA_FULL_CHECK_MODE)
  26137. + mode = CESA_FAST_CHECK_MODE;
  26138. + i = iter;
  26139. + if(mode != CESA_NULL_CHECK_MODE)
  26140. + i = 1;
  26141. +
  26142. + testOpen(100);
  26143. + testOpen(101);
  26144. + testOpen(102);
  26145. + testOpen(103);
  26146. +
  26147. +/* 3DES / ECB mode / Encrypt only */
  26148. + status = testRun(100, 1, iter, reqSize, checkMode);
  26149. + printTestResults(100, status, checkMode);
  26150. +
  26151. +/* 3DES / ECB mode / Decrypt only */
  26152. + status = testRun(101, 1, iter, reqSize, checkMode);
  26153. + printTestResults(101, status, checkMode);
  26154. +
  26155. +/* 3DES / CBC mode / Encrypt only */
  26156. + status = testRun(102, 2, i, reqSize, mode);
  26157. + printTestResults(102, status, mode);
  26158. +
  26159. +/* 3DES / CBC mode / Decrypt only */
  26160. + status = testRun(103, 2, iter, reqSize, mode);
  26161. + printTestResults(103, status, mode);
  26162. +
  26163. + testClose(100);
  26164. + testClose(101);
  26165. + testClose(102);
  26166. + testClose(103);
  26167. +}
  26168. +
  26169. +void aesTest(int iter, int reqSize, int checkMode)
  26170. +{
  26171. + MV_STATUS status;
  26172. + int mode, i;
  26173. +
  26174. + mode = checkMode;
  26175. + if(checkMode == CESA_FULL_CHECK_MODE)
  26176. + mode = CESA_FAST_CHECK_MODE;
  26177. +
  26178. + i = iter;
  26179. + if(mode != CESA_NULL_CHECK_MODE)
  26180. + i = 1;
  26181. +
  26182. + testOpen(200);
  26183. + testOpen(201);
  26184. + testOpen(202);
  26185. + testOpen(203);
  26186. + testOpen(204);
  26187. + testOpen(205);
  26188. + testOpen(206);
  26189. + testOpen(207);
  26190. + testOpen(208);
  26191. +
  26192. +/* AES-128 Encode ECB mode */
  26193. + status = testRun(200, 3, iter, reqSize, checkMode);
  26194. + printTestResults(200, status, checkMode);
  26195. +
  26196. +/* AES-128 Decode ECB mode */
  26197. + status = testRun(201, 3, iter, reqSize, checkMode);
  26198. + printTestResults(201, status, checkMode);
  26199. +
  26200. +/* AES-128 Encode CBC mode (IV from SA) */
  26201. + status = testRun(202, 10, i, reqSize, mode);
  26202. + printTestResults(202, status, mode);
  26203. +
  26204. +/* AES-128 Encode CBC mode (IV from User) */
  26205. + status = testRun(202, 24, i, reqSize, mode);
  26206. + printTestResults(202, status, mode);
  26207. +
  26208. +/* AES-128 Decode CBC mode */
  26209. + status = testRun(203, 24, iter, reqSize, mode);
  26210. + printTestResults(203, status, checkMode);
  26211. +
  26212. +/* AES-192 Encode ECB mode */
  26213. + status = testRun(204, 4, iter, reqSize, checkMode);
  26214. + printTestResults(204, status, checkMode);
  26215. +
  26216. +/* AES-192 Decode ECB mode */
  26217. + status = testRun(205, 4, iter, reqSize, checkMode);
  26218. + printTestResults(205, status, checkMode);
  26219. +
  26220. +/* AES-256 Encode ECB mode */
  26221. + status = testRun(206, 5, iter, reqSize, checkMode);
  26222. + printTestResults(206, status, checkMode);
  26223. +
  26224. +/* AES-256 Decode ECB mode */
  26225. + status = testRun(207, 5, iter, reqSize, checkMode);
  26226. + printTestResults(207, status, checkMode);
  26227. +
  26228. +#if defined(MV_LINUX)
  26229. +/* AES-128 Encode CTR mode */
  26230. + status = testRun(208, 23, iter, reqSize, mode);
  26231. + printTestResults(208, status, checkMode);
  26232. +#endif
  26233. + testClose(200);
  26234. + testClose(201);
  26235. + testClose(202);
  26236. + testClose(203);
  26237. + testClose(204);
  26238. + testClose(205);
  26239. + testClose(206);
  26240. + testClose(207);
  26241. + testClose(208);
  26242. +}
  26243. +
  26244. +
  26245. +void mdTest(int iter, int reqSize, int checkMode)
  26246. +{
  26247. + int mode;
  26248. + MV_STATUS status;
  26249. +
  26250. + if(iter == 0)
  26251. + iter = CESA_DEF_ITER_NUM;
  26252. +
  26253. + mode = checkMode;
  26254. + if(checkMode == CESA_FULL_CHECK_MODE)
  26255. + mode = CESA_FAST_CHECK_MODE;
  26256. +
  26257. + testOpen(300);
  26258. + testOpen(301);
  26259. + testOpen(302);
  26260. + testOpen(303);
  26261. + testOpen(305);
  26262. +
  26263. +/* HMAC-MD5 Generate signature test */
  26264. + status = testRun(300, 6, iter, reqSize, mode);
  26265. + printTestResults(300, status, checkMode);
  26266. +
  26267. +/* HMAC-MD5 Verify Signature test */
  26268. + status = testRun(301, 7, iter, reqSize, mode);
  26269. + printTestResults(301, status, checkMode);
  26270. +
  26271. +/* HMAC-MD5 Generate signature test */
  26272. + status = testRun(302, 8, iter, reqSize, mode);
  26273. + printTestResults(302, status, checkMode);
  26274. +
  26275. +/* HMAC-MD5 Verify Signature test */
  26276. + status = testRun(303, 9, iter, reqSize, mode);
  26277. + printTestResults(303, status, checkMode);
  26278. +
  26279. +/* HASH-MD5 Generate signature test */
  26280. + status = testRun(305, 15, iter, reqSize, mode);
  26281. + printTestResults(305, status, checkMode);
  26282. +
  26283. + testClose(300);
  26284. + testClose(301);
  26285. + testClose(302);
  26286. + testClose(303);
  26287. + testClose(305);
  26288. +}
  26289. +
  26290. +void shaTest(int iter, int reqSize, int checkMode)
  26291. +{
  26292. + int mode;
  26293. + MV_STATUS status;
  26294. +
  26295. + if(iter == 0)
  26296. + iter = CESA_DEF_ITER_NUM;
  26297. +
  26298. + mode = checkMode;
  26299. + if(checkMode == CESA_FULL_CHECK_MODE)
  26300. + mode = CESA_FAST_CHECK_MODE;
  26301. +
  26302. + testOpen(400);
  26303. + testOpen(401);
  26304. + testOpen(402);
  26305. + testOpen(403);
  26306. + testOpen(405);
  26307. +
  26308. +/* HMAC-SHA1 Generate signature test */
  26309. + status = testRun(400, 11, iter, reqSize, mode);
  26310. + printTestResults(400, status, checkMode);
  26311. +
  26312. +/* HMAC-SHA1 Verify Signature test */
  26313. + status = testRun(401, 12, iter, reqSize, mode);
  26314. + printTestResults(401, status, checkMode);
  26315. +
  26316. +/* HMAC-SHA1 Generate signature test */
  26317. + status = testRun(402, 13, iter, reqSize, mode);
  26318. + printTestResults(402, status, checkMode);
  26319. +
  26320. +/* HMAC-SHA1 Verify Signature test */
  26321. + status = testRun(403, 14, iter, reqSize, mode);
  26322. + printTestResults(403, status, checkMode);
  26323. +
  26324. +/* HMAC-SHA1 Generate signature test */
  26325. + status = testRun(405, 16, iter, reqSize, mode);
  26326. + printTestResults(405, status, checkMode);
  26327. +
  26328. + testClose(400);
  26329. + testClose(401);
  26330. + testClose(402);
  26331. + testClose(403);
  26332. + testClose(405);
  26333. +}
  26334. +
  26335. +void combiTest(int iter, int reqSize, int checkMode)
  26336. +{
  26337. + MV_STATUS status;
  26338. + int mode, i;
  26339. +
  26340. + mode = checkMode;
  26341. + if(checkMode == CESA_FULL_CHECK_MODE)
  26342. + mode = CESA_FAST_CHECK_MODE;
  26343. +
  26344. + if(iter == 0)
  26345. + iter = CESA_DEF_ITER_NUM;
  26346. +
  26347. + i = iter;
  26348. + if(mode != CESA_NULL_CHECK_MODE)
  26349. + i = 1;
  26350. +
  26351. + testOpen(500);
  26352. + testOpen(501);
  26353. + testOpen(502);
  26354. + testOpen(503);
  26355. + testOpen(504);
  26356. + testOpen(505);
  26357. + testOpen(506);
  26358. + testOpen(507);
  26359. +
  26360. +/* DES ECB + MD5 encode test */
  26361. + status = testRun(500, 17, iter, reqSize, mode);
  26362. + printTestResults(500, status, mode);
  26363. +
  26364. +/* DES ECB + SHA1 encode test */
  26365. + status = testRun(501, 18, iter, reqSize, mode);
  26366. + printTestResults(501, status, mode);
  26367. +
  26368. +/* 3DES ECB + MD5 encode test */
  26369. + status = testRun(502, 17, iter, reqSize, mode);
  26370. + printTestResults(502, status, mode);
  26371. +
  26372. +/* 3DES ECB + SHA1 encode test */
  26373. + status = testRun(503, 18, iter, reqSize, mode);
  26374. + printTestResults(503, status, mode);
  26375. +
  26376. +/* 3DES CBC + MD5 encode test */
  26377. + status = testRun(504, 19, i, reqSize, mode);
  26378. + printTestResults(504, status, mode);
  26379. +
  26380. +/* 3DES CBC + SHA1 encode test */
  26381. + status = testRun(505, 20, i, reqSize, mode);
  26382. + printTestResults(505, status, mode);
  26383. +
  26384. +/* AES-128 CBC + MD5 encode test */
  26385. + status = testRun(506, 21, i, reqSize, mode);
  26386. + printTestResults(506, status, mode);
  26387. +
  26388. +/* AES-128 CBC + SHA1 encode test */
  26389. + status = testRun(507, 22, i, reqSize, mode);
  26390. + printTestResults(507, status, mode);
  26391. +
  26392. + testClose(500);
  26393. + testClose(501);
  26394. + testClose(502);
  26395. + testClose(503);
  26396. + testClose(504);
  26397. + testClose(505);
  26398. + testClose(506);
  26399. + testClose(507);
  26400. +}
  26401. +
  26402. +void cesaOneTest(int testIdx, int caseIdx,
  26403. + int iter, int reqSize, int checkMode)
  26404. +{
  26405. + MV_STATUS status;
  26406. +
  26407. + if(iter == 0)
  26408. + iter = CESA_DEF_ITER_NUM;
  26409. +
  26410. + mvOsPrintf("test=%d, case=%d, size=%d, iter=%d\n",
  26411. + testIdx, caseIdx, reqSize, iter);
  26412. +
  26413. + status = testOpen(testIdx);
  26414. +
  26415. + status = testRun(testIdx, caseIdx, iter, reqSize, checkMode);
  26416. + printTestResults(testIdx, status, checkMode);
  26417. + status = testClose(testIdx);
  26418. +
  26419. +}
  26420. +
  26421. +void cesaTest(int iter, int reqSize, int checkMode)
  26422. +{
  26423. + if(iter == 0)
  26424. + iter = CESA_DEF_ITER_NUM;
  26425. +
  26426. + mvOsPrintf("%d iteration\n", iter);
  26427. + mvOsPrintf("%d size\n\n", reqSize);
  26428. +
  26429. +/* DES tests */
  26430. + desTest(iter, reqSize, checkMode);
  26431. +
  26432. +/* 3DES tests */
  26433. + tripleDesTest(iter, reqSize, checkMode);
  26434. +
  26435. +/* AES tests */
  26436. + aesTest(iter, reqSize, checkMode);
  26437. +
  26438. +/* MD5 tests */
  26439. + mdTest(iter, reqSize, checkMode);
  26440. +
  26441. +/* SHA-1 tests */
  26442. + shaTest(iter, reqSize, checkMode);
  26443. +}
  26444. +
  26445. +void multiSizeTest(int idx, int iter, int checkMode, char* inputData)
  26446. +{
  26447. + MV_STATUS status;
  26448. + int i;
  26449. + MV_CESA_SIZE_TEST* pMultiTest;
  26450. +
  26451. + if( testOpen(idx) != MV_OK)
  26452. + return;
  26453. +
  26454. + if(iter == 0)
  26455. + iter = CESA_DEF_ITER_NUM;
  26456. +
  26457. + if(checkMode == CESA_SHOW_CHECK_MODE)
  26458. + {
  26459. + iter = 1;
  26460. + }
  26461. + else
  26462. + checkMode = CESA_FULL_CHECK_MODE;
  26463. +
  26464. + cesaTestCases[0].plainHexStr = inputData;
  26465. + cesaTestCases[0].pCryptoIV = NULL;
  26466. +
  26467. + switch(idx)
  26468. + {
  26469. + case 302:
  26470. + pMultiTest = mdMultiSizeTest302;
  26471. + if(inputData == NULL)
  26472. + cesaTestCases[0].plainHexStr = cesaDataHexStr3;
  26473. + break;
  26474. +
  26475. + case 304:
  26476. + pMultiTest = mdMultiSizeTest304;
  26477. + if(inputData == NULL)
  26478. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26479. + break;
  26480. +
  26481. + case 305:
  26482. + pMultiTest = mdMultiSizeTest305;
  26483. + if(inputData == NULL)
  26484. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26485. + break;
  26486. +
  26487. + case 402:
  26488. + pMultiTest = shaMultiSizeTest402;
  26489. + if(inputData == NULL)
  26490. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26491. + break;
  26492. +
  26493. + case 404:
  26494. + pMultiTest = shaMultiSizeTest404;
  26495. + if(inputData == NULL)
  26496. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26497. + break;
  26498. +
  26499. + case 405:
  26500. + pMultiTest = shaMultiSizeTest405;
  26501. + if(inputData == NULL)
  26502. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26503. + break;
  26504. +
  26505. + case 502:
  26506. + pMultiTest = tripleDesMdMultiSizeTest502;
  26507. + if(inputData == NULL)
  26508. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26509. + break;
  26510. +
  26511. + case 503:
  26512. + pMultiTest = tripleDesShaMultiSizeTest503;
  26513. + if(inputData == NULL)
  26514. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26515. + break;
  26516. +
  26517. + case 504:
  26518. + iter = 1;
  26519. + pMultiTest = cbc3desMdMultiSizeTest504;
  26520. + cesaTestCases[0].pCryptoIV = iv1;
  26521. + if(inputData == NULL)
  26522. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26523. + break;
  26524. +
  26525. + case 505:
  26526. + iter = 1;
  26527. + pMultiTest = cbc3desShaMultiSizeTest505;
  26528. + cesaTestCases[0].pCryptoIV = iv1;
  26529. + if(inputData == NULL)
  26530. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26531. + break;
  26532. +
  26533. + case 506:
  26534. + iter = 1;
  26535. + pMultiTest = cbcAes128md5multiSizeTest506;
  26536. + cesaTestCases[0].pCryptoIV = iv5;
  26537. + if(inputData == NULL)
  26538. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26539. + break;
  26540. +
  26541. + case 507:
  26542. + iter = 1;
  26543. + pMultiTest = cbcAes128sha1multiSizeTest507;
  26544. + cesaTestCases[0].pCryptoIV = iv5;
  26545. + if(inputData == NULL)
  26546. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26547. + break;
  26548. +
  26549. + default:
  26550. + iter = 1;
  26551. + checkMode = CESA_SHOW_CHECK_MODE;
  26552. + pMultiTest = mdMultiSizeTest302;
  26553. + if(inputData == NULL)
  26554. + cesaTestCases[0].plainHexStr = hashHexStr80;
  26555. + }
  26556. + i = 0;
  26557. + while(pMultiTest[i].outputHexStr != NULL)
  26558. + {
  26559. + cesaTestCases[0].cipherHexStr = (char *)pMultiTest[i].outputHexStr;
  26560. + status = testRun(idx, 0, iter, pMultiTest[i].size,
  26561. + checkMode);
  26562. + if(checkMode != CESA_SHOW_CHECK_MODE)
  26563. + {
  26564. + cesaReqSize = pMultiTest[i].size;
  26565. + printTestResults(idx, status, checkMode);
  26566. + }
  26567. + if(status != MV_OK)
  26568. + break;
  26569. + i++;
  26570. + }
  26571. + testClose(idx);
  26572. +/*
  26573. + mvCesaDebugStatus();
  26574. + cesaTestPrintStatus();
  26575. +*/
  26576. +}
  26577. +
  26578. +void open_session_test(int idx, int caseIdx, int iter)
  26579. +{
  26580. + int reqIdError, cryptoError, openErrors, i;
  26581. + int openErrDisp[100];
  26582. + MV_STATUS status;
  26583. +
  26584. + memset(openErrDisp, 0, sizeof(openErrDisp));
  26585. + openErrors = 0;
  26586. + reqIdError = 0;
  26587. + cryptoError = 0;
  26588. + for(i=0; i<iter; i++)
  26589. + {
  26590. + status = testOpen(idx);
  26591. + if(status != MV_OK)
  26592. + {
  26593. + openErrors++;
  26594. + openErrDisp[status]++;
  26595. + }
  26596. + else
  26597. + {
  26598. + testRun(idx, caseIdx, 1, 0, CESA_FAST_CHECK_MODE);
  26599. + if(cesaCryptoError > 0)
  26600. + cryptoError++;
  26601. + if(cesaReqIdError > 0)
  26602. + reqIdError++;
  26603. +
  26604. + testClose(idx);
  26605. + }
  26606. + }
  26607. + if(cryptoError > 0)
  26608. + mvOsPrintf("cryptoError : %d\n", cryptoError);
  26609. + if(reqIdError > 0)
  26610. + mvOsPrintf("reqIdError : %d\n", reqIdError);
  26611. +
  26612. + if(openErrors > 0)
  26613. + {
  26614. + mvOsPrintf("Open Errors = %d\n", openErrors);
  26615. + for(i=0; i<100; i++)
  26616. + {
  26617. + if(openErrDisp[i] != 0)
  26618. + mvOsPrintf("Error %d - occurs %d times\n", i, openErrDisp[i]);
  26619. + }
  26620. + }
  26621. +}
  26622. +
  26623. +
  26624. +void loopback_test(int idx, int iter, int size, char* pPlainData)
  26625. +{
  26626. +}
  26627. +
  26628. +
  26629. +#if defined(MV_VXWORKS)
  26630. +int testMode = 0;
  26631. +unsigned __TASKCONV cesaTask(void* args)
  26632. +{
  26633. + int reqSize = cesaReqSize;
  26634. +
  26635. + if(testMode == 0)
  26636. + {
  26637. + cesaOneTest(cesaTestIdx, cesaCaseIdx, cesaIteration,
  26638. + reqSize, cesaCheckMode);
  26639. + }
  26640. + else
  26641. + {
  26642. + if(testMode == 1)
  26643. + {
  26644. + cesaTest(cesaIteration, reqSize, cesaCheckMode);
  26645. + combiTest(cesaIteration, reqSize, cesaCheckMode);
  26646. + }
  26647. + else
  26648. + {
  26649. + multiSizeTest(cesaIdx, cesaIteration, cesaCheckMode, NULL);
  26650. + }
  26651. + }
  26652. + return 0;
  26653. +}
  26654. +
  26655. +void oneTest(int testIdx, int caseIdx,
  26656. + int iter, int reqSize, int checkMode)
  26657. +{
  26658. + long rc;
  26659. +
  26660. + cesaIteration = iter;
  26661. + cesaReqSize = cesaRateSize = reqSize;
  26662. + cesaCheckMode = checkMode;
  26663. + testMode = 0;
  26664. + cesaTestIdx = testIdx;
  26665. + cesaCaseIdx = caseIdx;
  26666. + rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);
  26667. + if (rc != MV_OK)
  26668. + {
  26669. + mvOsPrintf("hMW: Can't create CESA multiCmd test task, rc = %ld\n", rc);
  26670. + }
  26671. +}
  26672. +
  26673. +void multiTest(int iter, int reqSize, int checkMode)
  26674. +{
  26675. + long rc;
  26676. +
  26677. + cesaIteration = iter;
  26678. + cesaCheckMode = checkMode;
  26679. + cesaReqSize = reqSize;
  26680. + testMode = 1;
  26681. + rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);
  26682. + if (rc != MV_OK)
  26683. + {
  26684. + mvOsPrintf("hMW: Can't create CESA multiCmd test task, rc = %ld\n", rc);
  26685. + }
  26686. +}
  26687. +
  26688. +void sizeTest(int testIdx, int iter, int checkMode)
  26689. +{
  26690. + long rc;
  26691. +
  26692. + cesaIteration = iter;
  26693. + cesaCheckMode = checkMode;
  26694. + testMode = 2;
  26695. + cesaIdx = testIdx;
  26696. + rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);
  26697. + if (rc != MV_OK)
  26698. + {
  26699. + mvOsPrintf("hMW: Can't create CESA test task, rc = %ld\n", rc);
  26700. + }
  26701. +}
  26702. +
  26703. +#endif /* MV_VXWORKS */
  26704. +
  26705. +extern void mvCesaDebugSA(short sid, int mode);
  26706. +void cesaTestPrintSession(int idx)
  26707. +{
  26708. + int testIdx;
  26709. + MV_CESA_TEST_SESSION* pTestSession;
  26710. +
  26711. + pTestSession = getTestSessionDb(idx, &testIdx);
  26712. + if(pTestSession == NULL)
  26713. + {
  26714. + mvOsPrintf("Test %d is not exist\n", idx);
  26715. + return;
  26716. + }
  26717. + pTestSession = &pTestSession[testIdx];
  26718. +
  26719. + if(pTestSession->sid == -1)
  26720. + {
  26721. + mvOsPrintf("Test session %d is not opened\n", idx);
  26722. + return;
  26723. + }
  26724. +
  26725. + mvCesaDebugSA(pTestSession->sid, 1);
  26726. +}
  26727. +
  26728. +void cesaTestPrintStatus(void)
  26729. +{
  26730. + mvOsPrintf("\n\t Cesa Test Status\n\n");
  26731. +
  26732. + mvOsPrintf("isrCount=%d\n",
  26733. + cesaTestIsrCount);
  26734. +
  26735. +#ifdef CESA_TEST_DEBUG
  26736. + {
  26737. + int i, j;
  26738. + j = cesaTestTraceIdx;
  26739. + mvOsPrintf("No Type Cause rCause iCause Res Time pReady pProc pEmpty\n");
  26740. + for(i=0; i<MV_CESA_TEST_TRACE_SIZE; i++)
  26741. + {
  26742. + mvOsPrintf("%02d. %d 0x%04x 0x%04x 0x%04x 0x%02x 0x%02x %02d 0x%06x %p %p %p\n",
  26743. + j, cesaTestTrace[j].type, cesaTestTrace[j].cause, cesaTestTrace[j].realCause,
  26744. + cesaTestTrace[j].dmaCause, cesaTestTrace[j].resources, cesaTestTrace[j].timeStamp,
  26745. + cesaTestTrace[j].pReqReady, cesaTestTrace[j].pReqProcess, cesaTestTrace[j].pReqEmpty);
  26746. + j++;
  26747. + if(j == MV_CESA_TEST_TRACE_SIZE)
  26748. + j = 0;
  26749. + }
  26750. + }
  26751. +#endif /* CESA_TEST_DEBUG */
  26752. +}
  26753. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvLru.c linux-2.6.35/crypto/ocf/kirkwood/cesa/mvLru.c
  26754. --- linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvLru.c 1970-01-01 01:00:00.000000000 +0100
  26755. +++ linux-2.6.35/crypto/ocf/kirkwood/cesa/mvLru.c 2010-08-05 22:02:11.083970513 +0200
  26756. @@ -0,0 +1,158 @@
  26757. +/*******************************************************************************
  26758. +Copyright (C) Marvell International Ltd. and its affiliates
  26759. +
  26760. +This software file (the "File") is owned and distributed by Marvell
  26761. +International Ltd. and/or its affiliates ("Marvell") under the following
  26762. +alternative licensing terms. Once you have made an election to distribute the
  26763. +File under one of the following license alternatives, please (i) delete this
  26764. +introductory statement regarding license alternatives, (ii) delete the two
  26765. +license alternatives that you have not elected to use and (iii) preserve the
  26766. +Marvell copyright notice above.
  26767. +
  26768. +********************************************************************************
  26769. +Marvell Commercial License Option
  26770. +
  26771. +If you received this File from Marvell and you have entered into a commercial
  26772. +license agreement (a "Commercial License") with Marvell, the File is licensed
  26773. +to you under the terms of the applicable Commercial License.
  26774. +
  26775. +********************************************************************************
  26776. +Marvell GPL License Option
  26777. +
  26778. +If you received this File from Marvell, you may opt to use, redistribute and/or
  26779. +modify this File in accordance with the terms and conditions of the General
  26780. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  26781. +available along with the File in the license.txt file or by writing to the Free
  26782. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  26783. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  26784. +
  26785. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  26786. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  26787. +DISCLAIMED. The GPL License provides additional details about this warranty
  26788. +disclaimer.
  26789. +********************************************************************************
  26790. +Marvell BSD License Option
  26791. +
  26792. +If you received this File from Marvell, you may opt to use, redistribute and/or
  26793. +modify this File under the following licensing terms.
  26794. +Redistribution and use in source and binary forms, with or without modification,
  26795. +are permitted provided that the following conditions are met:
  26796. +
  26797. + * Redistributions of source code must retain the above copyright notice,
  26798. + this list of conditions and the following disclaimer.
  26799. +
  26800. + * Redistributions in binary form must reproduce the above copyright
  26801. + notice, this list of conditions and the following disclaimer in the
  26802. + documentation and/or other materials provided with the distribution.
  26803. +
  26804. + * Neither the name of Marvell nor the names of its contributors may be
  26805. + used to endorse or promote products derived from this software without
  26806. + specific prior written permission.
  26807. +
  26808. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  26809. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  26810. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26811. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  26812. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  26813. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  26814. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26815. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26816. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  26817. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26818. +
  26819. +*******************************************************************************/
  26820. +
  26821. +#include "mvOs.h"
  26822. +#include "mvLru.h"
  26823. +/* LRU Cache support */
  26824. +
  26825. +
  26826. +/* Init LRU cache database */
  26827. +MV_LRU_CACHE* mvLruCacheInit(int numOfEntries)
  26828. +{
  26829. + int i;
  26830. + MV_LRU_CACHE* pLruCache;
  26831. +
  26832. + pLruCache = mvOsMalloc(sizeof(MV_LRU_CACHE));
  26833. + if(pLruCache == NULL)
  26834. + {
  26835. + return NULL;
  26836. + }
  26837. + memset(pLruCache, 0, sizeof(MV_LRU_CACHE));
  26838. +
  26839. + pLruCache->table = mvOsMalloc(numOfEntries*sizeof(MV_LRU_ENTRY));
  26840. + if(pLruCache->table == NULL)
  26841. + {
  26842. + mvOsFree(pLruCache);
  26843. + return NULL;
  26844. + }
  26845. + memset(pLruCache->table, 0, numOfEntries*sizeof(MV_LRU_ENTRY));
  26846. + pLruCache->tableSize = numOfEntries;
  26847. +
  26848. + for(i=0; i<numOfEntries; i++)
  26849. + {
  26850. + pLruCache->table[i].next = i+1;
  26851. + pLruCache->table[i].prev = i-1;
  26852. + }
  26853. + pLruCache->least = 0;
  26854. + pLruCache->most = numOfEntries-1;
  26855. +
  26856. + return pLruCache;
  26857. +}
  26858. +
  26859. +void mvLruCacheFinish(MV_LRU_CACHE* pLruCache)
  26860. +{
  26861. + mvOsFree(pLruCache->table);
  26862. + mvOsFree(pLruCache);
  26863. +}
  26864. +
  26865. +/* Update LRU cache database after using cache Index */
  26866. +void mvLruCacheIdxUpdate(MV_LRU_CACHE* pLruHndl, int cacheIdx)
  26867. +{
  26868. + int prev, next;
  26869. +
  26870. + if(cacheIdx == pLruHndl->most)
  26871. + return;
  26872. +
  26873. + next = pLruHndl->table[cacheIdx].next;
  26874. + if(cacheIdx == pLruHndl->least)
  26875. + {
  26876. + pLruHndl->least = next;
  26877. + }
  26878. + else
  26879. + {
  26880. + prev = pLruHndl->table[cacheIdx].prev;
  26881. +
  26882. + pLruHndl->table[next].prev = prev;
  26883. + pLruHndl->table[prev].next = next;
  26884. + }
  26885. +
  26886. + pLruHndl->table[pLruHndl->most].next = cacheIdx;
  26887. + pLruHndl->table[cacheIdx].prev = pLruHndl->most;
  26888. + pLruHndl->most = cacheIdx;
  26889. +}
  26890. +
  26891. +/* Delete LRU cache entry */
  26892. +void mvLruCacheIdxDelete(MV_LRU_CACHE* pLruHndl, int cacheIdx)
  26893. +{
  26894. + int prev, next;
  26895. +
  26896. + if(cacheIdx == pLruHndl->least)
  26897. + return;
  26898. +
  26899. + prev = pLruHndl->table[cacheIdx].prev;
  26900. + if(cacheIdx == pLruHndl->most)
  26901. + {
  26902. + pLruHndl->most = prev;
  26903. + }
  26904. + else
  26905. + {
  26906. + next = pLruHndl->table[cacheIdx].next;
  26907. +
  26908. + pLruHndl->table[next].prev = prev;
  26909. + pLruHndl->table[prev].next = next;
  26910. + }
  26911. + pLruHndl->table[pLruHndl->least].prev = cacheIdx;
  26912. + pLruHndl->table[cacheIdx].next = pLruHndl->least;
  26913. + pLruHndl->least = cacheIdx;
  26914. +}
  26915. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvLru.h linux-2.6.35/crypto/ocf/kirkwood/cesa/mvLru.h
  26916. --- linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvLru.h 1970-01-01 01:00:00.000000000 +0100
  26917. +++ linux-2.6.35/crypto/ocf/kirkwood/cesa/mvLru.h 2010-08-05 22:02:11.524868087 +0200
  26918. @@ -0,0 +1,112 @@
  26919. +/*******************************************************************************
  26920. +Copyright (C) Marvell International Ltd. and its affiliates
  26921. +
  26922. +This software file (the "File") is owned and distributed by Marvell
  26923. +International Ltd. and/or its affiliates ("Marvell") under the following
  26924. +alternative licensing terms. Once you have made an election to distribute the
  26925. +File under one of the following license alternatives, please (i) delete this
  26926. +introductory statement regarding license alternatives, (ii) delete the two
  26927. +license alternatives that you have not elected to use and (iii) preserve the
  26928. +Marvell copyright notice above.
  26929. +
  26930. +********************************************************************************
  26931. +Marvell Commercial License Option
  26932. +
  26933. +If you received this File from Marvell and you have entered into a commercial
  26934. +license agreement (a "Commercial License") with Marvell, the File is licensed
  26935. +to you under the terms of the applicable Commercial License.
  26936. +
  26937. +********************************************************************************
  26938. +Marvell GPL License Option
  26939. +
  26940. +If you received this File from Marvell, you may opt to use, redistribute and/or
  26941. +modify this File in accordance with the terms and conditions of the General
  26942. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  26943. +available along with the File in the license.txt file or by writing to the Free
  26944. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  26945. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  26946. +
  26947. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  26948. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  26949. +DISCLAIMED. The GPL License provides additional details about this warranty
  26950. +disclaimer.
  26951. +********************************************************************************
  26952. +Marvell BSD License Option
  26953. +
  26954. +If you received this File from Marvell, you may opt to use, redistribute and/or
  26955. +modify this File under the following licensing terms.
  26956. +Redistribution and use in source and binary forms, with or without modification,
  26957. +are permitted provided that the following conditions are met:
  26958. +
  26959. + * Redistributions of source code must retain the above copyright notice,
  26960. + this list of conditions and the following disclaimer.
  26961. +
  26962. + * Redistributions in binary form must reproduce the above copyright
  26963. + notice, this list of conditions and the following disclaimer in the
  26964. + documentation and/or other materials provided with the distribution.
  26965. +
  26966. + * Neither the name of Marvell nor the names of its contributors may be
  26967. + used to endorse or promote products derived from this software without
  26968. + specific prior written permission.
  26969. +
  26970. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  26971. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  26972. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26973. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  26974. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  26975. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  26976. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  26977. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26978. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  26979. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26980. +
  26981. +*******************************************************************************/
  26982. +/*******************************************************************************
  26983. +* mvLru.h - Header File for Least Recently Used Cache algorithm
  26984. +*
  26985. +* DESCRIPTION:
  26986. +* This header file contains macros typedefs and function declaration for
  26987. +* the Least Recently Used Cache algorithm.
  26988. +*
  26989. +*******************************************************************************/
  26990. +
  26991. +#ifndef __mvLru_h__
  26992. +#define __mvLru_h__
  26993. +
  26994. +
  26995. +typedef struct
  26996. +{
  26997. + int next;
  26998. + int prev;
  26999. +} MV_LRU_ENTRY;
  27000. +
  27001. +typedef struct
  27002. +{
  27003. + int least;
  27004. + int most;
  27005. + MV_LRU_ENTRY* table;
  27006. + int tableSize;
  27007. +
  27008. +}MV_LRU_CACHE;
  27009. +
  27010. +
  27011. +/* Find Cache index for replacement LRU */
  27012. +static INLINE int mvLruCacheIdxFind(MV_LRU_CACHE* pLruHndl)
  27013. +{
  27014. + return pLruHndl->least;
  27015. +}
  27016. +
  27017. +/* Init LRU cache module */
  27018. +MV_LRU_CACHE* mvLruCacheInit(int numOfEntries);
  27019. +
  27020. +/* Finish LRU cache module */
  27021. +void mvLruCacheFinish(MV_LRU_CACHE* pLruHndl);
  27022. +
  27023. +/* Update LRU cache database after using cache Index */
  27024. +void mvLruCacheIdxUpdate(MV_LRU_CACHE* pLruHndl, int cacheIdx);
  27025. +
  27026. +/* Delete LRU cache entry */
  27027. +void mvLruCacheIdxDelete(MV_LRU_CACHE* pLruHndl, int cacheIdx);
  27028. +
  27029. +
  27030. +#endif /* __mvLru_h__ */
  27031. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvMD5.c linux-2.6.35/crypto/ocf/kirkwood/cesa/mvMD5.c
  27032. --- linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvMD5.c 1970-01-01 01:00:00.000000000 +0100
  27033. +++ linux-2.6.35/crypto/ocf/kirkwood/cesa/mvMD5.c 2010-08-05 22:02:11.683751212 +0200
  27034. @@ -0,0 +1,349 @@
  27035. +/*******************************************************************************
  27036. +Copyright (C) Marvell International Ltd. and its affiliates
  27037. +
  27038. +This software file (the "File") is owned and distributed by Marvell
  27039. +International Ltd. and/or its affiliates ("Marvell") under the following
  27040. +alternative licensing terms. Once you have made an election to distribute the
  27041. +File under one of the following license alternatives, please (i) delete this
  27042. +introductory statement regarding license alternatives, (ii) delete the two
  27043. +license alternatives that you have not elected to use and (iii) preserve the
  27044. +Marvell copyright notice above.
  27045. +
  27046. +********************************************************************************
  27047. +Marvell Commercial License Option
  27048. +
  27049. +If you received this File from Marvell and you have entered into a commercial
  27050. +license agreement (a "Commercial License") with Marvell, the File is licensed
  27051. +to you under the terms of the applicable Commercial License.
  27052. +
  27053. +********************************************************************************
  27054. +Marvell GPL License Option
  27055. +
  27056. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27057. +modify this File in accordance with the terms and conditions of the General
  27058. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  27059. +available along with the File in the license.txt file or by writing to the Free
  27060. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  27061. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  27062. +
  27063. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  27064. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  27065. +DISCLAIMED. The GPL License provides additional details about this warranty
  27066. +disclaimer.
  27067. +********************************************************************************
  27068. +Marvell BSD License Option
  27069. +
  27070. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27071. +modify this File under the following licensing terms.
  27072. +Redistribution and use in source and binary forms, with or without modification,
  27073. +are permitted provided that the following conditions are met:
  27074. +
  27075. + * Redistributions of source code must retain the above copyright notice,
  27076. + this list of conditions and the following disclaimer.
  27077. +
  27078. + * Redistributions in binary form must reproduce the above copyright
  27079. + notice, this list of conditions and the following disclaimer in the
  27080. + documentation and/or other materials provided with the distribution.
  27081. +
  27082. + * Neither the name of Marvell nor the names of its contributors may be
  27083. + used to endorse or promote products derived from this software without
  27084. + specific prior written permission.
  27085. +
  27086. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  27087. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  27088. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  27089. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  27090. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27091. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27092. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  27093. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27094. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27095. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27096. +
  27097. +*******************************************************************************/
  27098. +
  27099. +#include "mvOs.h"
  27100. +#include "mvMD5.h"
  27101. +
  27102. +static void mvMD5Transform(MV_U32 buf[4], MV_U32 const in[MV_MD5_MAC_LEN]);
  27103. +
  27104. +#ifdef MV_CPU_LE
  27105. +#define mvByteReverse(buf, len) /* Nothing */
  27106. +#else
  27107. +static void mvByteReverse(unsigned char *buf, unsigned longs);
  27108. +
  27109. +/*
  27110. + * Note: this code is harmless on little-endian machines.
  27111. + */
  27112. +static void mvByteReverse(unsigned char *buf, unsigned longs)
  27113. +{
  27114. + MV_U32 t;
  27115. +
  27116. + do
  27117. + {
  27118. + t = (MV_U32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
  27119. + ((unsigned) buf[1] << 8 | buf[0]);
  27120. + *(MV_U32 *) buf = t;
  27121. + buf += 4;
  27122. + } while (--longs);
  27123. +}
  27124. +#endif
  27125. +
  27126. +/*
  27127. + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
  27128. + * initialization constants.
  27129. + */
  27130. +void mvMD5Init(MV_MD5_CONTEXT *ctx)
  27131. +{
  27132. + ctx->buf[0] = 0x67452301;
  27133. + ctx->buf[1] = 0xefcdab89;
  27134. + ctx->buf[2] = 0x98badcfe;
  27135. + ctx->buf[3] = 0x10325476;
  27136. +
  27137. + ctx->bits[0] = 0;
  27138. + ctx->bits[1] = 0;
  27139. +}
  27140. +
  27141. +/*
  27142. + * Update context to reflect the concatenation of another buffer full
  27143. + * of bytes.
  27144. + */
  27145. +void mvMD5Update(MV_MD5_CONTEXT *ctx, unsigned char const *buf, unsigned len)
  27146. +{
  27147. + MV_U32 t;
  27148. +
  27149. + /* Update bitcount */
  27150. +
  27151. + t = ctx->bits[0];
  27152. + if ((ctx->bits[0] = t + ((MV_U32) len << 3)) < t)
  27153. + ctx->bits[1]++; /* Carry from low to high */
  27154. + ctx->bits[1] += len >> 29;
  27155. +
  27156. + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
  27157. +
  27158. + /* Handle any leading odd-sized chunks */
  27159. +
  27160. + if (t)
  27161. + {
  27162. + unsigned char *p = (unsigned char *) ctx->in + t;
  27163. +
  27164. + t = 64 - t;
  27165. + if (len < t)
  27166. + {
  27167. + memcpy(p, buf, len);
  27168. + return;
  27169. + }
  27170. + memcpy(p, buf, t);
  27171. + mvByteReverse(ctx->in, MV_MD5_MAC_LEN);
  27172. + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
  27173. + buf += t;
  27174. + len -= t;
  27175. + }
  27176. + /* Process data in 64-byte chunks */
  27177. +
  27178. + while (len >= 64)
  27179. + {
  27180. + memcpy(ctx->in, buf, 64);
  27181. + mvByteReverse(ctx->in, MV_MD5_MAC_LEN);
  27182. + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
  27183. + buf += 64;
  27184. + len -= 64;
  27185. + }
  27186. +
  27187. + /* Handle any remaining bytes of data. */
  27188. +
  27189. + memcpy(ctx->in, buf, len);
  27190. +}
  27191. +
  27192. +/*
  27193. + * Final wrapup - pad to 64-byte boundary with the bit pattern
  27194. + * 1 0* (64-bit count of bits processed, MSB-first)
  27195. + */
  27196. +void mvMD5Final(unsigned char digest[MV_MD5_MAC_LEN], MV_MD5_CONTEXT *ctx)
  27197. +{
  27198. + unsigned count;
  27199. + unsigned char *p;
  27200. +
  27201. + /* Compute number of bytes mod 64 */
  27202. + count = (ctx->bits[0] >> 3) & 0x3F;
  27203. +
  27204. + /* Set the first char of padding to 0x80. This is safe since there is
  27205. + always at least one byte free */
  27206. + p = ctx->in + count;
  27207. + *p++ = 0x80;
  27208. +
  27209. + /* Bytes of padding needed to make 64 bytes */
  27210. + count = 64 - 1 - count;
  27211. +
  27212. + /* Pad out to 56 mod 64 */
  27213. + if (count < 8)
  27214. + {
  27215. + /* Two lots of padding: Pad the first block to 64 bytes */
  27216. + memset(p, 0, count);
  27217. + mvByteReverse(ctx->in, MV_MD5_MAC_LEN);
  27218. + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
  27219. +
  27220. + /* Now fill the next block with 56 bytes */
  27221. + memset(ctx->in, 0, 56);
  27222. + }
  27223. + else
  27224. + {
  27225. + /* Pad block to 56 bytes */
  27226. + memset(p, 0, count - 8);
  27227. + }
  27228. + mvByteReverse(ctx->in, 14);
  27229. +
  27230. + /* Append length in bits and transform */
  27231. + ((MV_U32 *) ctx->in)[14] = ctx->bits[0];
  27232. + ((MV_U32 *) ctx->in)[15] = ctx->bits[1];
  27233. +
  27234. + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
  27235. + mvByteReverse((unsigned char *) ctx->buf, 4);
  27236. + memcpy(digest, ctx->buf, MV_MD5_MAC_LEN);
  27237. + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
  27238. +}
  27239. +
  27240. +/* The four core functions - F1 is optimized somewhat */
  27241. +
  27242. +/* #define F1(x, y, z) (x & y | ~x & z) */
  27243. +#define F1(x, y, z) (z ^ (x & (y ^ z)))
  27244. +#define F2(x, y, z) F1(z, x, y)
  27245. +#define F3(x, y, z) (x ^ y ^ z)
  27246. +#define F4(x, y, z) (y ^ (x | ~z))
  27247. +
  27248. +/* This is the central step in the MD5 algorithm. */
  27249. +#define MD5STEP(f, w, x, y, z, data, s) \
  27250. + ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
  27251. +
  27252. +/*
  27253. + * The core of the MD5 algorithm, this alters an existing MD5 hash to
  27254. + * reflect the addition of 16 longwords of new data. MD5Update blocks
  27255. + * the data and converts bytes into longwords for this routine.
  27256. + */
  27257. +static void mvMD5Transform(MV_U32 buf[4], MV_U32 const in[MV_MD5_MAC_LEN])
  27258. +{
  27259. + register MV_U32 a, b, c, d;
  27260. +
  27261. + a = buf[0];
  27262. + b = buf[1];
  27263. + c = buf[2];
  27264. + d = buf[3];
  27265. +
  27266. + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
  27267. + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
  27268. + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
  27269. + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
  27270. + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
  27271. + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
  27272. + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
  27273. + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
  27274. + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
  27275. + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
  27276. + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
  27277. + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
  27278. + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
  27279. + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
  27280. + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
  27281. + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
  27282. +
  27283. + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
  27284. + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
  27285. + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
  27286. + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
  27287. + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
  27288. + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
  27289. + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
  27290. + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
  27291. + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
  27292. + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
  27293. + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
  27294. + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
  27295. + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
  27296. + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
  27297. + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
  27298. + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
  27299. +
  27300. + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
  27301. + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
  27302. + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
  27303. + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
  27304. + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
  27305. + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
  27306. + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
  27307. + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
  27308. + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
  27309. + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
  27310. + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
  27311. + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
  27312. + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
  27313. + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
  27314. + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
  27315. + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
  27316. +
  27317. + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
  27318. + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
  27319. + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
  27320. + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
  27321. + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
  27322. + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
  27323. + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
  27324. + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
  27325. + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
  27326. + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
  27327. + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
  27328. + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
  27329. + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
  27330. + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
  27331. + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
  27332. + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
  27333. +
  27334. + buf[0] += a;
  27335. + buf[1] += b;
  27336. + buf[2] += c;
  27337. + buf[3] += d;
  27338. +}
  27339. +
  27340. +void mvMD5(unsigned char const *buf, unsigned len, unsigned char* digest)
  27341. +{
  27342. + MV_MD5_CONTEXT ctx;
  27343. +
  27344. + mvMD5Init(&ctx);
  27345. + mvMD5Update(&ctx, buf, len);
  27346. + mvMD5Final(digest, &ctx);
  27347. +}
  27348. +
  27349. +
  27350. +void mvHmacMd5(unsigned char const* text, int text_len,
  27351. + unsigned char const* key, int key_len,
  27352. + unsigned char* digest)
  27353. +{
  27354. + int i;
  27355. + MV_MD5_CONTEXT ctx;
  27356. + unsigned char k_ipad[64+1]; /* inner padding - key XORd with ipad */
  27357. + unsigned char k_opad[64+1]; /* outer padding - key XORd with opad */
  27358. +
  27359. + /* start out by storing key in pads */
  27360. + memset(k_ipad, 0, 64);
  27361. + memcpy(k_ipad, key, key_len);
  27362. + memset(k_opad, 0, 64);
  27363. + memcpy(k_opad, key, key_len);
  27364. +
  27365. + /* XOR key with ipad and opad values */
  27366. + for (i=0; i<64; i++)
  27367. + {
  27368. + k_ipad[i] ^= 0x36;
  27369. + k_opad[i] ^= 0x5c;
  27370. + }
  27371. +
  27372. + /* perform inner MD5 */
  27373. + mvMD5Init(&ctx); /* init ctx for 1st pass */
  27374. + mvMD5Update(&ctx, k_ipad, 64); /* start with inner pad */
  27375. + mvMD5Update(&ctx, text, text_len); /* then text of datagram */
  27376. + mvMD5Final(digest, &ctx); /* finish up 1st pass */
  27377. +
  27378. + /* perform outer MD5 */
  27379. + mvMD5Init(&ctx); /* init ctx for 2nd pass */
  27380. + mvMD5Update(&ctx, k_opad, 64); /* start with outer pad */
  27381. + mvMD5Update(&ctx, digest, 16); /* then results of 1st hash */
  27382. + mvMD5Final(digest, &ctx); /* finish up 2nd pass */
  27383. +}
  27384. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvMD5.h linux-2.6.35/crypto/ocf/kirkwood/cesa/mvMD5.h
  27385. --- linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvMD5.h 1970-01-01 01:00:00.000000000 +0100
  27386. +++ linux-2.6.35/crypto/ocf/kirkwood/cesa/mvMD5.h 2010-08-05 22:02:11.883814685 +0200
  27387. @@ -0,0 +1,93 @@
  27388. +/*******************************************************************************
  27389. +Copyright (C) Marvell International Ltd. and its affiliates
  27390. +
  27391. +This software file (the "File") is owned and distributed by Marvell
  27392. +International Ltd. and/or its affiliates ("Marvell") under the following
  27393. +alternative licensing terms. Once you have made an election to distribute the
  27394. +File under one of the following license alternatives, please (i) delete this
  27395. +introductory statement regarding license alternatives, (ii) delete the two
  27396. +license alternatives that you have not elected to use and (iii) preserve the
  27397. +Marvell copyright notice above.
  27398. +
  27399. +********************************************************************************
  27400. +Marvell Commercial License Option
  27401. +
  27402. +If you received this File from Marvell and you have entered into a commercial
  27403. +license agreement (a "Commercial License") with Marvell, the File is licensed
  27404. +to you under the terms of the applicable Commercial License.
  27405. +
  27406. +********************************************************************************
  27407. +Marvell GPL License Option
  27408. +
  27409. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27410. +modify this File in accordance with the terms and conditions of the General
  27411. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  27412. +available along with the File in the license.txt file or by writing to the Free
  27413. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  27414. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  27415. +
  27416. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  27417. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  27418. +DISCLAIMED. The GPL License provides additional details about this warranty
  27419. +disclaimer.
  27420. +********************************************************************************
  27421. +Marvell BSD License Option
  27422. +
  27423. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27424. +modify this File under the following licensing terms.
  27425. +Redistribution and use in source and binary forms, with or without modification,
  27426. +are permitted provided that the following conditions are met:
  27427. +
  27428. + * Redistributions of source code must retain the above copyright notice,
  27429. + this list of conditions and the following disclaimer.
  27430. +
  27431. + * Redistributions in binary form must reproduce the above copyright
  27432. + notice, this list of conditions and the following disclaimer in the
  27433. + documentation and/or other materials provided with the distribution.
  27434. +
  27435. + * Neither the name of Marvell nor the names of its contributors may be
  27436. + used to endorse or promote products derived from this software without
  27437. + specific prior written permission.
  27438. +
  27439. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  27440. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  27441. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  27442. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  27443. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27444. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27445. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  27446. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27447. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27448. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27449. +
  27450. +*******************************************************************************/
  27451. +
  27452. +#ifndef __mvMD5_h__
  27453. +#define __mvMD5_h__
  27454. +
  27455. +#include "mvMD5.h"
  27456. +
  27457. +#define MV_MD5_MAC_LEN 16
  27458. +
  27459. +
  27460. +typedef struct
  27461. +{
  27462. + MV_U32 buf[4];
  27463. + MV_U32 bits[2];
  27464. + MV_U8 in[64];
  27465. +
  27466. +} MV_MD5_CONTEXT;
  27467. +
  27468. +void mvMD5Init(MV_MD5_CONTEXT *context);
  27469. +void mvMD5Update(MV_MD5_CONTEXT *context, unsigned char const *buf,
  27470. + unsigned len);
  27471. +void mvMD5Final(unsigned char digest[16], MV_MD5_CONTEXT *context);
  27472. +
  27473. +void mvMD5(unsigned char const *buf, unsigned len, unsigned char* digest);
  27474. +
  27475. +void mvHmacMd5(unsigned char const* text, int text_len,
  27476. + unsigned char const* key, int key_len,
  27477. + unsigned char* digest);
  27478. +
  27479. +
  27480. +#endif /* __mvMD5_h__ */
  27481. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvSHA1.c linux-2.6.35/crypto/ocf/kirkwood/cesa/mvSHA1.c
  27482. --- linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvSHA1.c 1970-01-01 01:00:00.000000000 +0100
  27483. +++ linux-2.6.35/crypto/ocf/kirkwood/cesa/mvSHA1.c 2010-08-05 22:02:12.133696310 +0200
  27484. @@ -0,0 +1,239 @@
  27485. +/*******************************************************************************
  27486. +Copyright (C) Marvell International Ltd. and its affiliates
  27487. +
  27488. +This software file (the "File") is owned and distributed by Marvell
  27489. +International Ltd. and/or its affiliates ("Marvell") under the following
  27490. +alternative licensing terms. Once you have made an election to distribute the
  27491. +File under one of the following license alternatives, please (i) delete this
  27492. +introductory statement regarding license alternatives, (ii) delete the two
  27493. +license alternatives that you have not elected to use and (iii) preserve the
  27494. +Marvell copyright notice above.
  27495. +
  27496. +********************************************************************************
  27497. +Marvell Commercial License Option
  27498. +
  27499. +If you received this File from Marvell and you have entered into a commercial
  27500. +license agreement (a "Commercial License") with Marvell, the File is licensed
  27501. +to you under the terms of the applicable Commercial License.
  27502. +
  27503. +********************************************************************************
  27504. +Marvell GPL License Option
  27505. +
  27506. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27507. +modify this File in accordance with the terms and conditions of the General
  27508. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  27509. +available along with the File in the license.txt file or by writing to the Free
  27510. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  27511. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  27512. +
  27513. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  27514. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  27515. +DISCLAIMED. The GPL License provides additional details about this warranty
  27516. +disclaimer.
  27517. +********************************************************************************
  27518. +Marvell BSD License Option
  27519. +
  27520. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27521. +modify this File under the following licensing terms.
  27522. +Redistribution and use in source and binary forms, with or without modification,
  27523. +are permitted provided that the following conditions are met:
  27524. +
  27525. + * Redistributions of source code must retain the above copyright notice,
  27526. + this list of conditions and the following disclaimer.
  27527. +
  27528. + * Redistributions in binary form must reproduce the above copyright
  27529. + notice, this list of conditions and the following disclaimer in the
  27530. + documentation and/or other materials provided with the distribution.
  27531. +
  27532. + * Neither the name of Marvell nor the names of its contributors may be
  27533. + used to endorse or promote products derived from this software without
  27534. + specific prior written permission.
  27535. +
  27536. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  27537. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  27538. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  27539. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  27540. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27541. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27542. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  27543. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27544. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27545. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27546. +
  27547. +*******************************************************************************/
  27548. +
  27549. +#include "mvOs.h"
  27550. +#include "mvSHA1.h"
  27551. +
  27552. +#define SHA1HANDSOFF
  27553. +
  27554. +typedef union
  27555. +{
  27556. + MV_U8 c[64];
  27557. + MV_U32 l[16];
  27558. +
  27559. +} CHAR64LONG16;
  27560. +
  27561. +static void mvSHA1Transform(MV_U32 state[5], const MV_U8 *buffer);
  27562. +
  27563. +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
  27564. +
  27565. +
  27566. +#ifdef MV_CPU_LE
  27567. +#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
  27568. + (rol(block->l[i], 8) & 0x00FF00FF))
  27569. +#else
  27570. +#define blk0(i) block->l[i]
  27571. +#endif
  27572. +#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
  27573. + block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
  27574. +
  27575. +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
  27576. +#define R0(v,w,x,y,z,i) \
  27577. + z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
  27578. + w = rol(w, 30);
  27579. +#define R1(v,w,x,y,z,i) \
  27580. + z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
  27581. + w = rol(w, 30);
  27582. +#define R2(v,w,x,y,z,i) \
  27583. + z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
  27584. +#define R3(v,w,x,y,z,i) \
  27585. + z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
  27586. + w = rol(w, 30);
  27587. +#define R4(v,w,x,y,z,i) \
  27588. + z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
  27589. + w=rol(w, 30);
  27590. +
  27591. +/* Hash a single 512-bit block. This is the core of the algorithm. */
  27592. +static void mvSHA1Transform(MV_U32 state[5], const MV_U8 *buffer)
  27593. +{
  27594. + MV_U32 a, b, c, d, e;
  27595. + CHAR64LONG16* block;
  27596. +
  27597. +#ifdef SHA1HANDSOFF
  27598. + static MV_U32 workspace[16];
  27599. +
  27600. + block = (CHAR64LONG16 *) workspace;
  27601. + memcpy(block, buffer, 64);
  27602. +#else
  27603. + block = (CHAR64LONG16 *) buffer;
  27604. +#endif
  27605. + /* Copy context->state[] to working vars */
  27606. + a = state[0];
  27607. + b = state[1];
  27608. + c = state[2];
  27609. + d = state[3];
  27610. + e = state[4];
  27611. + /* 4 rounds of 20 operations each. Loop unrolled. */
  27612. + 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);
  27613. + 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);
  27614. + 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);
  27615. + 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);
  27616. + 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);
  27617. + 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);
  27618. + 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);
  27619. + 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);
  27620. + 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);
  27621. + 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);
  27622. + 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);
  27623. + 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);
  27624. + 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);
  27625. + 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);
  27626. + 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);
  27627. + 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);
  27628. + 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);
  27629. + 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);
  27630. + 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);
  27631. + 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);
  27632. + /* Add the working vars back into context.state[] */
  27633. + state[0] += a;
  27634. + state[1] += b;
  27635. + state[2] += c;
  27636. + state[3] += d;
  27637. + state[4] += e;
  27638. + /* Wipe variables */
  27639. + a = b = c = d = e = 0;
  27640. +}
  27641. +
  27642. +void mvSHA1Init(MV_SHA1_CTX* context)
  27643. +{
  27644. + /* SHA1 initialization constants */
  27645. + context->state[0] = 0x67452301;
  27646. + context->state[1] = 0xEFCDAB89;
  27647. + context->state[2] = 0x98BADCFE;
  27648. + context->state[3] = 0x10325476;
  27649. + context->state[4] = 0xC3D2E1F0;
  27650. + context->count[0] = context->count[1] = 0;
  27651. +}
  27652. +
  27653. +
  27654. +/* Run your data through this. */
  27655. +void mvSHA1Update(MV_SHA1_CTX *context, MV_U8 const *data,
  27656. + unsigned int len)
  27657. +{
  27658. + MV_U32 i, j;
  27659. +
  27660. + j = (context->count[0] >> 3) & 63;
  27661. + if ((context->count[0] += len << 3) < (len << 3))
  27662. + context->count[1]++;
  27663. + context->count[1] += (len >> 29);
  27664. + if ((j + len) > 63)
  27665. + {
  27666. + memcpy(&context->buffer[j], data, (i = 64-j));
  27667. + mvSHA1Transform(context->state, context->buffer);
  27668. + for ( ; i + 63 < len; i += 64)
  27669. + {
  27670. + mvSHA1Transform(context->state, &data[i]);
  27671. + }
  27672. + j = 0;
  27673. + }
  27674. + else
  27675. + {
  27676. + i = 0;
  27677. + }
  27678. + memcpy(&context->buffer[j], &data[i], len - i);
  27679. +}
  27680. +
  27681. +void mvSHA1Final(MV_U8* digest, MV_SHA1_CTX* context)
  27682. +{
  27683. + MV_U32 i;
  27684. + MV_U8 finalcount[8];
  27685. +
  27686. + for (i = 0; i < 8; i++)
  27687. + {
  27688. + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >>
  27689. + ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
  27690. + }
  27691. + mvSHA1Update(context, (const unsigned char *) "\200", 1);
  27692. + while ((context->count[0] & 504) != 448)
  27693. + {
  27694. + mvSHA1Update(context, (const unsigned char *) "\0", 1);
  27695. + }
  27696. + mvSHA1Update(context, finalcount, 8); /* Should cause a mvSHA1Transform()
  27697. + */
  27698. + for (i = 0; i < 20; i++)
  27699. + {
  27700. + digest[i] = (unsigned char)
  27701. + ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
  27702. + }
  27703. + /* Wipe variables */
  27704. + i = 0;
  27705. + memset(context->buffer, 0, 64);
  27706. + memset(context->state, 0, 20);
  27707. + memset(context->count, 0, 8);
  27708. + memset(finalcount, 0, 8);
  27709. +
  27710. +#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
  27711. + mvSHA1Transform(context->state, context->buffer);
  27712. +#endif
  27713. +}
  27714. +
  27715. +
  27716. +void mvSHA1(MV_U8 const *buf, unsigned int len, MV_U8* digest)
  27717. +{
  27718. + MV_SHA1_CTX ctx;
  27719. +
  27720. + mvSHA1Init(&ctx);
  27721. + mvSHA1Update(&ctx, buf, len);
  27722. + mvSHA1Final(digest, &ctx);
  27723. +}
  27724. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvSHA1.h linux-2.6.35/crypto/ocf/kirkwood/cesa/mvSHA1.h
  27725. --- linux-2.6.35.orig/crypto/ocf/kirkwood/cesa/mvSHA1.h 1970-01-01 01:00:00.000000000 +0100
  27726. +++ linux-2.6.35/crypto/ocf/kirkwood/cesa/mvSHA1.h 2010-08-05 22:02:12.323820640 +0200
  27727. @@ -0,0 +1,88 @@
  27728. +/*******************************************************************************
  27729. +Copyright (C) Marvell International Ltd. and its affiliates
  27730. +
  27731. +This software file (the "File") is owned and distributed by Marvell
  27732. +International Ltd. and/or its affiliates ("Marvell") under the following
  27733. +alternative licensing terms. Once you have made an election to distribute the
  27734. +File under one of the following license alternatives, please (i) delete this
  27735. +introductory statement regarding license alternatives, (ii) delete the two
  27736. +license alternatives that you have not elected to use and (iii) preserve the
  27737. +Marvell copyright notice above.
  27738. +
  27739. +********************************************************************************
  27740. +Marvell Commercial License Option
  27741. +
  27742. +If you received this File from Marvell and you have entered into a commercial
  27743. +license agreement (a "Commercial License") with Marvell, the File is licensed
  27744. +to you under the terms of the applicable Commercial License.
  27745. +
  27746. +********************************************************************************
  27747. +Marvell GPL License Option
  27748. +
  27749. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27750. +modify this File in accordance with the terms and conditions of the General
  27751. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  27752. +available along with the File in the license.txt file or by writing to the Free
  27753. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  27754. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  27755. +
  27756. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  27757. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  27758. +DISCLAIMED. The GPL License provides additional details about this warranty
  27759. +disclaimer.
  27760. +********************************************************************************
  27761. +Marvell BSD License Option
  27762. +
  27763. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27764. +modify this File under the following licensing terms.
  27765. +Redistribution and use in source and binary forms, with or without modification,
  27766. +are permitted provided that the following conditions are met:
  27767. +
  27768. + * Redistributions of source code must retain the above copyright notice,
  27769. + this list of conditions and the following disclaimer.
  27770. +
  27771. + * Redistributions in binary form must reproduce the above copyright
  27772. + notice, this list of conditions and the following disclaimer in the
  27773. + documentation and/or other materials provided with the distribution.
  27774. +
  27775. + * Neither the name of Marvell nor the names of its contributors may be
  27776. + used to endorse or promote products derived from this software without
  27777. + specific prior written permission.
  27778. +
  27779. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  27780. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  27781. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  27782. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  27783. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  27784. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27785. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  27786. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27787. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  27788. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27789. +
  27790. +*******************************************************************************/
  27791. +
  27792. +#ifndef __mvSHA1_h__
  27793. +#define __mvSHA1_h__
  27794. +
  27795. +#include "mvSHA1.h"
  27796. +
  27797. +#define MV_SHA1_MAC_LEN 20
  27798. +
  27799. +
  27800. +typedef struct
  27801. +{
  27802. + MV_U32 state[5];
  27803. + MV_U32 count[2];
  27804. + MV_U8 buffer[64];
  27805. +
  27806. +} MV_SHA1_CTX;
  27807. +
  27808. +void mvSHA1Init(MV_SHA1_CTX *context);
  27809. +void mvSHA1Update(MV_SHA1_CTX *context, MV_U8 const *buf, unsigned int len);
  27810. +void mvSHA1Final(MV_U8* digest, MV_SHA1_CTX *context);
  27811. +
  27812. +void mvSHA1(MV_U8 const *buf, unsigned int len, MV_U8* digest);
  27813. +
  27814. +
  27815. +#endif /* __mvSHA1_h__ */
  27816. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/cesa_ocf_drv.c linux-2.6.35/crypto/ocf/kirkwood/cesa_ocf_drv.c
  27817. --- linux-2.6.35.orig/crypto/ocf/kirkwood/cesa_ocf_drv.c 1970-01-01 01:00:00.000000000 +0100
  27818. +++ linux-2.6.35/crypto/ocf/kirkwood/cesa_ocf_drv.c 2010-08-05 22:02:12.583622191 +0200
  27819. @@ -0,0 +1,1296 @@
  27820. +/*******************************************************************************
  27821. +Copyright (C) Marvell International Ltd. and its affiliates
  27822. +
  27823. +This software file (the "File") is owned and distributed by Marvell
  27824. +International Ltd. and/or its affiliates ("Marvell") under the following
  27825. +alternative licensing terms. Once you have made an election to distribute the
  27826. +File under one of the following license alternatives, please (i) delete this
  27827. +introductory statement regarding license alternatives, (ii) delete the two
  27828. +license alternatives that you have not elected to use and (iii) preserve the
  27829. +Marvell copyright notice above.
  27830. +
  27831. +
  27832. +********************************************************************************
  27833. +Marvell GPL License Option
  27834. +
  27835. +If you received this File from Marvell, you may opt to use, redistribute and/or
  27836. +modify this File in accordance with the terms and conditions of the General
  27837. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  27838. +available along with the File in the license.txt file or by writing to the Free
  27839. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  27840. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  27841. +
  27842. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  27843. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  27844. +DISCLAIMED. The GPL License provides additional details about this warranty
  27845. +disclaimer.
  27846. +*******************************************************************************/
  27847. +
  27848. +#ifndef AUTOCONF_INCLUDED
  27849. +#include <linux/config.h>
  27850. +#endif
  27851. +#include <linux/module.h>
  27852. +#include <linux/init.h>
  27853. +#include <linux/list.h>
  27854. +#include <linux/slab.h>
  27855. +#include <linux/sched.h>
  27856. +#include <linux/wait.h>
  27857. +#include <linux/crypto.h>
  27858. +#include <linux/mm.h>
  27859. +#include <linux/skbuff.h>
  27860. +#include <linux/random.h>
  27861. +#include <linux/platform_device.h>
  27862. +#include <asm/scatterlist.h>
  27863. +#include <linux/spinlock.h>
  27864. +#include "ctrlEnv/sys/mvSysCesa.h"
  27865. +#include "cesa/mvCesa.h" /* moved here before cryptodev.h due to include dependencies */
  27866. +#include <cryptodev.h>
  27867. +#include <uio.h>
  27868. +#include <plat/mv_cesa.h>
  27869. +#include <linux/mbus.h>
  27870. +#include "mvDebug.h"
  27871. +
  27872. +#include "cesa/mvMD5.h"
  27873. +#include "cesa/mvSHA1.h"
  27874. +
  27875. +#include "cesa/mvCesaRegs.h"
  27876. +#include "cesa/AES/mvAes.h"
  27877. +#include "cesa/mvLru.h"
  27878. +
  27879. +#undef RT_DEBUG
  27880. +#ifdef RT_DEBUG
  27881. +static int debug = 1;
  27882. +module_param(debug, int, 1);
  27883. +MODULE_PARM_DESC(debug, "Enable debug");
  27884. +#undef dprintk
  27885. +#define dprintk(a...) if (debug) { printk(a); } else
  27886. +#else
  27887. +static int debug = 0;
  27888. +#undef dprintk
  27889. +#define dprintk(a...)
  27890. +#endif
  27891. +
  27892. +
  27893. +/* TDMA Regs */
  27894. +#define WINDOW_BASE(i) 0xA00 + (i << 3)
  27895. +#define WINDOW_CTRL(i) 0xA04 + (i << 3)
  27896. +
  27897. +/* interrupt handling */
  27898. +#undef CESA_OCF_POLLING
  27899. +#undef CESA_OCF_TASKLET
  27900. +
  27901. +#if defined(CESA_OCF_POLLING) && defined(CESA_OCF_TASKLET)
  27902. +#error "don't use both tasklet and polling mode"
  27903. +#endif
  27904. +
  27905. +extern int cesaReqResources;
  27906. +/* support for spliting action into 2 actions */
  27907. +#define CESA_OCF_SPLIT
  27908. +
  27909. +/* general defines */
  27910. +#define CESA_OCF_MAX_SES 128
  27911. +#define CESA_Q_SIZE 64
  27912. +
  27913. +
  27914. +/* data structures */
  27915. +struct cesa_ocf_data {
  27916. + int cipher_alg;
  27917. + int auth_alg;
  27918. + int encrypt_tn_auth;
  27919. +#define auth_tn_decrypt encrypt_tn_auth
  27920. + int ivlen;
  27921. + int digestlen;
  27922. + short sid_encrypt;
  27923. + short sid_decrypt;
  27924. + /* fragment workaround sessions */
  27925. + short frag_wa_encrypt;
  27926. + short frag_wa_decrypt;
  27927. + short frag_wa_auth;
  27928. +};
  27929. +
  27930. +/* CESA device data */
  27931. +struct cesa_dev {
  27932. + void __iomem *sram;
  27933. + void __iomem *reg;
  27934. + struct mv_cesa_platform_data *plat_data;
  27935. + int irq;
  27936. +};
  27937. +
  27938. +#define DIGEST_BUF_SIZE 32
  27939. +struct cesa_ocf_process {
  27940. + MV_CESA_COMMAND cesa_cmd;
  27941. + MV_CESA_MBUF cesa_mbuf;
  27942. + MV_BUF_INFO cesa_bufs[MV_CESA_MAX_MBUF_FRAGS];
  27943. + char digest[DIGEST_BUF_SIZE];
  27944. + int digest_len;
  27945. + struct cryptop *crp;
  27946. + int need_cb;
  27947. +};
  27948. +
  27949. +/* global variables */
  27950. +static int32_t cesa_ocf_id = -1;
  27951. +static struct cesa_ocf_data *cesa_ocf_sessions[CESA_OCF_MAX_SES];
  27952. +static spinlock_t cesa_lock;
  27953. +static struct cesa_dev cesa_device;
  27954. +
  27955. +/* static APIs */
  27956. +static int cesa_ocf_process (device_t, struct cryptop *, int);
  27957. +static int cesa_ocf_newsession (device_t, u_int32_t *, struct cryptoini *);
  27958. +static int cesa_ocf_freesession (device_t, u_int64_t);
  27959. +static void cesa_callback (unsigned long);
  27960. +static irqreturn_t cesa_interrupt_handler (int, void *);
  27961. +#ifdef CESA_OCF_POLLING
  27962. +static void cesa_interrupt_polling(void);
  27963. +#endif
  27964. +#ifdef CESA_OCF_TASKLET
  27965. +static struct tasklet_struct cesa_ocf_tasklet;
  27966. +#endif
  27967. +
  27968. +static struct timeval tt_start;
  27969. +static struct timeval tt_end;
  27970. +
  27971. +/*
  27972. + * dummy device structure
  27973. + */
  27974. +
  27975. +static struct {
  27976. + softc_device_decl sc_dev;
  27977. +} mv_cesa_dev;
  27978. +
  27979. +static device_method_t mv_cesa_methods = {
  27980. + /* crypto device methods */
  27981. + DEVMETHOD(cryptodev_newsession, cesa_ocf_newsession),
  27982. + DEVMETHOD(cryptodev_freesession,cesa_ocf_freesession),
  27983. + DEVMETHOD(cryptodev_process, cesa_ocf_process),
  27984. + DEVMETHOD(cryptodev_kprocess, NULL),
  27985. +};
  27986. +
  27987. +
  27988. +
  27989. +/* Add debug Trace */
  27990. +#undef CESA_OCF_TRACE_DEBUG
  27991. +#ifdef CESA_OCF_TRACE_DEBUG
  27992. +
  27993. +#define MV_CESA_USE_TIMER_ID 0
  27994. +
  27995. +typedef struct
  27996. +{
  27997. + int type; /* 0 - isrEmpty, 1 - cesaReadyGet, 2 - cesaAction */
  27998. + MV_U32 timeStamp;
  27999. + MV_U32 cause;
  28000. + MV_U32 realCause;
  28001. + MV_U32 dmaCause;
  28002. + int resources;
  28003. + MV_CESA_REQ* pReqReady;
  28004. + MV_CESA_REQ* pReqEmpty;
  28005. + MV_CESA_REQ* pReqProcess;
  28006. +} MV_CESA_TEST_TRACE;
  28007. +
  28008. +#define MV_CESA_TEST_TRACE_SIZE 50
  28009. +
  28010. +static int cesaTestTraceIdx = 0;
  28011. +static MV_CESA_TEST_TRACE cesaTestTrace[MV_CESA_TEST_TRACE_SIZE];
  28012. +
  28013. +static void cesaTestTraceAdd(int type)
  28014. +{
  28015. + cesaTestTrace[cesaTestTraceIdx].type = type;
  28016. + cesaTestTrace[cesaTestTraceIdx].realCause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  28017. + //cesaTestTrace[cesaTestTraceIdx].idmaCause = MV_REG_READ(IDMA_CAUSE_REG);
  28018. + cesaTestTrace[cesaTestTraceIdx].resources = cesaReqResources;
  28019. + cesaTestTrace[cesaTestTraceIdx].pReqReady = pCesaReqReady;
  28020. + cesaTestTrace[cesaTestTraceIdx].pReqEmpty = pCesaReqEmpty;
  28021. + cesaTestTrace[cesaTestTraceIdx].pReqProcess = pCesaReqProcess;
  28022. + cesaTestTrace[cesaTestTraceIdx].timeStamp = mvCntmrRead(MV_CESA_USE_TIMER_ID);
  28023. + cesaTestTraceIdx++;
  28024. + if(cesaTestTraceIdx == MV_CESA_TEST_TRACE_SIZE)
  28025. + cesaTestTraceIdx = 0;
  28026. +}
  28027. +
  28028. +#else /* CESA_OCF_TRACE_DEBUG */
  28029. +
  28030. +#define cesaTestTraceAdd(x)
  28031. +
  28032. +#endif /* CESA_OCF_TRACE_DEBUG */
  28033. +
  28034. +unsigned int
  28035. +get_usec(unsigned int start)
  28036. +{
  28037. + if(start) {
  28038. + do_gettimeofday (&tt_start);
  28039. + return 0;
  28040. + }
  28041. + else {
  28042. + do_gettimeofday (&tt_end);
  28043. + tt_end.tv_sec -= tt_start.tv_sec;
  28044. + tt_end.tv_usec -= tt_start.tv_usec;
  28045. + if (tt_end.tv_usec < 0) {
  28046. + tt_end.tv_usec += 1000 * 1000;
  28047. + tt_end.tv_sec -= 1;
  28048. + }
  28049. + }
  28050. + printk("time taken is %d\n", (unsigned int)(tt_end.tv_usec + tt_end.tv_sec * 1000000));
  28051. + return (tt_end.tv_usec + tt_end.tv_sec * 1000000);
  28052. +}
  28053. +
  28054. +#ifdef RT_DEBUG
  28055. +/*
  28056. + * check that the crp action match the current session
  28057. + */
  28058. +static int
  28059. +ocf_check_action(struct cryptop *crp, struct cesa_ocf_data *cesa_ocf_cur_ses) {
  28060. + int count = 0;
  28061. + int encrypt = 0, decrypt = 0, auth = 0;
  28062. + struct cryptodesc *crd;
  28063. +
  28064. + /* Go through crypto descriptors, processing as we go */
  28065. + for (crd = crp->crp_desc; crd; crd = crd->crd_next, count++) {
  28066. + if(count > 2) {
  28067. + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
  28068. + return 1;
  28069. + }
  28070. +
  28071. + /* Encryption /Decryption */
  28072. + if(crd->crd_alg == cesa_ocf_cur_ses->cipher_alg) {
  28073. + /* check that the action is compatible with session */
  28074. + if(encrypt || decrypt) {
  28075. + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
  28076. + return 1;
  28077. + }
  28078. +
  28079. + if(crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  28080. + if( (count == 2) && (cesa_ocf_cur_ses->encrypt_tn_auth) ) {
  28081. + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
  28082. + return 1;
  28083. + }
  28084. + encrypt++;
  28085. + }
  28086. + else { /* decrypt */
  28087. + if( (count == 2) && !(cesa_ocf_cur_ses->auth_tn_decrypt) ) {
  28088. + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
  28089. + return 1;
  28090. + }
  28091. + decrypt++;
  28092. + }
  28093. +
  28094. + }
  28095. + /* Authentication */
  28096. + else if(crd->crd_alg == cesa_ocf_cur_ses->auth_alg) {
  28097. + /* check that the action is compatible with session */
  28098. + if(auth) {
  28099. + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
  28100. + return 1;
  28101. + }
  28102. + if( (count == 2) && (decrypt) && (cesa_ocf_cur_ses->auth_tn_decrypt)) {
  28103. + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
  28104. + return 1;
  28105. + }
  28106. + if( (count == 2) && (encrypt) && !(cesa_ocf_cur_ses->encrypt_tn_auth)) {
  28107. + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
  28108. + return 1;
  28109. + }
  28110. + auth++;
  28111. + }
  28112. + else {
  28113. + printk("%s,%d: Alg isn't supported by this session.\n", __FILE__, __LINE__);
  28114. + return 1;
  28115. + }
  28116. + }
  28117. + return 0;
  28118. +
  28119. +}
  28120. +#endif
  28121. +
  28122. +/*
  28123. + * Process a request.
  28124. + */
  28125. +static int
  28126. +cesa_ocf_process(device_t dev, struct cryptop *crp, int hint)
  28127. +{
  28128. + struct cesa_ocf_process *cesa_ocf_cmd = NULL;
  28129. + struct cesa_ocf_process *cesa_ocf_cmd_wa = NULL;
  28130. + MV_CESA_COMMAND *cesa_cmd;
  28131. + struct cryptodesc *crd;
  28132. + struct cesa_ocf_data *cesa_ocf_cur_ses;
  28133. + int sid = 0, temp_len = 0, i;
  28134. + int encrypt = 0, decrypt = 0, auth = 0;
  28135. + int status;
  28136. + struct sk_buff *skb = NULL;
  28137. + struct uio *uiop = NULL;
  28138. + unsigned char *ivp;
  28139. + MV_BUF_INFO *p_buf_info;
  28140. + MV_CESA_MBUF *p_mbuf_info;
  28141. + unsigned long flags;
  28142. +
  28143. + dprintk("%s()\n", __FUNCTION__);
  28144. +
  28145. + if( cesaReqResources <= 1 ) {
  28146. + dprintk("%s,%d: ERESTART\n", __FILE__, __LINE__);
  28147. + return ERESTART;
  28148. + }
  28149. +
  28150. +#ifdef RT_DEBUG
  28151. + /* Sanity check */
  28152. + if (crp == NULL) {
  28153. + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  28154. + return EINVAL;
  28155. + }
  28156. +
  28157. + if (crp->crp_desc == NULL || crp->crp_buf == NULL ) {
  28158. + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  28159. + crp->crp_etype = EINVAL;
  28160. + return EINVAL;
  28161. + }
  28162. +
  28163. + sid = crp->crp_sid & 0xffffffff;
  28164. + if ((sid >= CESA_OCF_MAX_SES) || (cesa_ocf_sessions[sid] == NULL)) {
  28165. + crp->crp_etype = ENOENT;
  28166. + printk("%s,%d: ENOENT session %d \n", __FILE__, __LINE__, sid);
  28167. + return EINVAL;
  28168. + }
  28169. +#endif
  28170. +
  28171. + sid = crp->crp_sid & 0xffffffff;
  28172. + crp->crp_etype = 0;
  28173. + cesa_ocf_cur_ses = cesa_ocf_sessions[sid];
  28174. +
  28175. +#ifdef RT_DEBUG
  28176. + if(ocf_check_action(crp, cesa_ocf_cur_ses)){
  28177. + goto p_error;
  28178. + }
  28179. +#endif
  28180. +
  28181. + /* malloc a new cesa process */
  28182. + cesa_ocf_cmd = kmalloc(sizeof(struct cesa_ocf_process), GFP_ATOMIC);
  28183. +
  28184. + if (cesa_ocf_cmd == NULL) {
  28185. + printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
  28186. + goto p_error;
  28187. + }
  28188. + memset(cesa_ocf_cmd, 0, sizeof(struct cesa_ocf_process));
  28189. +
  28190. + /* init cesa_process */
  28191. + cesa_ocf_cmd->crp = crp;
  28192. + /* always call callback */
  28193. + cesa_ocf_cmd->need_cb = 1;
  28194. +
  28195. + /* init cesa_cmd for usage of the HALs */
  28196. + cesa_cmd = &cesa_ocf_cmd->cesa_cmd;
  28197. + cesa_cmd->pReqPrv = (void *)cesa_ocf_cmd;
  28198. + cesa_cmd->sessionId = cesa_ocf_cur_ses->sid_encrypt; /* defualt use encrypt */
  28199. +
  28200. + /* prepare src buffer */
  28201. + /* we send the entire buffer to the HAL, even if only part of it should be encrypt/auth. */
  28202. + /* if not using seesions for both encrypt and auth, then it will be wiser to to copy only */
  28203. + /* from skip to crd_len. */
  28204. + p_buf_info = cesa_ocf_cmd->cesa_bufs;
  28205. + p_mbuf_info = &cesa_ocf_cmd->cesa_mbuf;
  28206. +
  28207. + p_buf_info += 2; /* save 2 first buffers for IV and digest -
  28208. + we won't append them to the end since, they
  28209. + might be places in an unaligned addresses. */
  28210. +
  28211. + p_mbuf_info->pFrags = p_buf_info;
  28212. + temp_len = 0;
  28213. +
  28214. + /* handle SKB */
  28215. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  28216. +
  28217. + dprintk("%s,%d: handle SKB.\n", __FILE__, __LINE__);
  28218. + skb = (struct sk_buff *) crp->crp_buf;
  28219. +
  28220. + if (skb_shinfo(skb)->nr_frags >= (MV_CESA_MAX_MBUF_FRAGS - 1)) {
  28221. + printk("%s,%d: %d nr_frags > MV_CESA_MAX_MBUF_FRAGS", __FILE__, __LINE__, skb_shinfo(skb)->nr_frags);
  28222. + goto p_error;
  28223. + }
  28224. +
  28225. + p_mbuf_info->mbufSize = skb->len;
  28226. + temp_len = skb->len;
  28227. + /* first skb fragment */
  28228. + p_buf_info->bufSize = skb_headlen(skb);
  28229. + p_buf_info->bufVirtPtr = skb->data;
  28230. + p_buf_info++;
  28231. +
  28232. + /* now handle all other skb fragments */
  28233. + for ( i = 0; i < skb_shinfo(skb)->nr_frags; i++ ) {
  28234. + skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
  28235. + p_buf_info->bufSize = frag->size;
  28236. + p_buf_info->bufVirtPtr = page_address(frag->page) + frag->page_offset;
  28237. + p_buf_info++;
  28238. + }
  28239. + p_mbuf_info->numFrags = skb_shinfo(skb)->nr_frags + 1;
  28240. + }
  28241. + /* handle UIO */
  28242. + else if(crp->crp_flags & CRYPTO_F_IOV) {
  28243. +
  28244. + dprintk("%s,%d: handle UIO.\n", __FILE__, __LINE__);
  28245. + uiop = (struct uio *) crp->crp_buf;
  28246. +
  28247. + if (uiop->uio_iovcnt > (MV_CESA_MAX_MBUF_FRAGS - 1)) {
  28248. + printk("%s,%d: %d uio_iovcnt > MV_CESA_MAX_MBUF_FRAGS \n", __FILE__, __LINE__, uiop->uio_iovcnt);
  28249. + goto p_error;
  28250. + }
  28251. +
  28252. + p_mbuf_info->mbufSize = crp->crp_ilen;
  28253. + p_mbuf_info->numFrags = uiop->uio_iovcnt;
  28254. + for(i = 0; i < uiop->uio_iovcnt; i++) {
  28255. + p_buf_info->bufVirtPtr = uiop->uio_iov[i].iov_base;
  28256. + p_buf_info->bufSize = uiop->uio_iov[i].iov_len;
  28257. + temp_len += p_buf_info->bufSize;
  28258. + dprintk("%s,%d: buf %x-> addr %x, size %x \n"
  28259. + , __FILE__, __LINE__, i, (unsigned int)p_buf_info->bufVirtPtr, p_buf_info->bufSize);
  28260. + p_buf_info++;
  28261. + }
  28262. +
  28263. + }
  28264. + /* handle CONTIG */
  28265. + else {
  28266. + dprintk("%s,%d: handle CONTIG.\n", __FILE__, __LINE__);
  28267. + p_mbuf_info->numFrags = 1;
  28268. + p_mbuf_info->mbufSize = crp->crp_ilen;
  28269. + p_buf_info->bufVirtPtr = crp->crp_buf;
  28270. + p_buf_info->bufSize = crp->crp_ilen;
  28271. + temp_len = crp->crp_ilen;
  28272. + p_buf_info++;
  28273. + }
  28274. +
  28275. + /* Support up to 64K why? cause! */
  28276. + if(crp->crp_ilen > 64*1024) {
  28277. + printk("%s,%d: buf too big %x \n", __FILE__, __LINE__, crp->crp_ilen);
  28278. + goto p_error;
  28279. + }
  28280. +
  28281. + if( temp_len != crp->crp_ilen ) {
  28282. + printk("%s,%d: warning size don't match.(%x %x) \n", __FILE__, __LINE__, temp_len, crp->crp_ilen);
  28283. + }
  28284. +
  28285. + cesa_cmd->pSrc = p_mbuf_info;
  28286. + cesa_cmd->pDst = p_mbuf_info;
  28287. +
  28288. + /* restore p_buf_info to point to first available buf */
  28289. + p_buf_info = cesa_ocf_cmd->cesa_bufs;
  28290. + p_buf_info += 1;
  28291. +
  28292. +
  28293. + /* Go through crypto descriptors, processing as we go */
  28294. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  28295. +
  28296. + /* Encryption /Decryption */
  28297. + if(crd->crd_alg == cesa_ocf_cur_ses->cipher_alg) {
  28298. +
  28299. + dprintk("%s,%d: cipher", __FILE__, __LINE__);
  28300. +
  28301. + cesa_cmd->cryptoOffset = crd->crd_skip;
  28302. + cesa_cmd->cryptoLength = crd->crd_len;
  28303. +
  28304. + if(crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  28305. + dprintk(" encrypt \n");
  28306. + encrypt++;
  28307. +
  28308. + /* handle IV */
  28309. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) { /* IV from USER */
  28310. + dprintk("%s,%d: IV from USER (offset %x) \n", __FILE__, __LINE__, crd->crd_inject);
  28311. + cesa_cmd->ivFromUser = 1;
  28312. + ivp = crd->crd_iv;
  28313. +
  28314. + /*
  28315. + * do we have to copy the IV back to the buffer ?
  28316. + */
  28317. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  28318. + dprintk("%s,%d: copy the IV back to the buffer\n", __FILE__, __LINE__);
  28319. + cesa_cmd->ivOffset = crd->crd_inject;
  28320. + crypto_copy_bits_back(crp->crp_buf, crd->crd_inject, ivp, cesa_ocf_cur_ses->ivlen);
  28321. + }
  28322. + else {
  28323. + dprintk("%s,%d: don't copy the IV back to the buffer \n", __FILE__, __LINE__);
  28324. + p_mbuf_info->numFrags++;
  28325. + p_mbuf_info->mbufSize += cesa_ocf_cur_ses->ivlen;
  28326. + p_mbuf_info->pFrags = p_buf_info;
  28327. +
  28328. + p_buf_info->bufVirtPtr = ivp;
  28329. + p_buf_info->bufSize = cesa_ocf_cur_ses->ivlen;
  28330. + p_buf_info--;
  28331. +
  28332. + /* offsets */
  28333. + cesa_cmd->ivOffset = 0;
  28334. + cesa_cmd->cryptoOffset += cesa_ocf_cur_ses->ivlen;
  28335. + if(auth) {
  28336. + cesa_cmd->macOffset += cesa_ocf_cur_ses->ivlen;
  28337. + cesa_cmd->digestOffset += cesa_ocf_cur_ses->ivlen;
  28338. + }
  28339. + }
  28340. + }
  28341. + else { /* random IV */
  28342. + dprintk("%s,%d: random IV \n", __FILE__, __LINE__);
  28343. + cesa_cmd->ivFromUser = 0;
  28344. +
  28345. + /*
  28346. + * do we have to copy the IV back to the buffer ?
  28347. + */
  28348. + /* in this mode the HAL will always copy the IV */
  28349. + /* given by the session to the ivOffset */
  28350. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  28351. + cesa_cmd->ivOffset = crd->crd_inject;
  28352. + }
  28353. + else {
  28354. + /* if IV isn't copy, then how will the user know which IV did we use??? */
  28355. + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  28356. + goto p_error;
  28357. + }
  28358. + }
  28359. + }
  28360. + else { /* decrypt */
  28361. + dprintk(" decrypt \n");
  28362. + decrypt++;
  28363. + cesa_cmd->sessionId = cesa_ocf_cur_ses->sid_decrypt;
  28364. +
  28365. + /* handle IV */
  28366. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  28367. + dprintk("%s,%d: IV from USER \n", __FILE__, __LINE__);
  28368. + /* append the IV buf to the mbuf */
  28369. + cesa_cmd->ivFromUser = 1;
  28370. + p_mbuf_info->numFrags++;
  28371. + p_mbuf_info->mbufSize += cesa_ocf_cur_ses->ivlen;
  28372. + p_mbuf_info->pFrags = p_buf_info;
  28373. +
  28374. + p_buf_info->bufVirtPtr = crd->crd_iv;
  28375. + p_buf_info->bufSize = cesa_ocf_cur_ses->ivlen;
  28376. + p_buf_info--;
  28377. +
  28378. + /* offsets */
  28379. + cesa_cmd->ivOffset = 0;
  28380. + cesa_cmd->cryptoOffset += cesa_ocf_cur_ses->ivlen;
  28381. + if(auth) {
  28382. + cesa_cmd->macOffset += cesa_ocf_cur_ses->ivlen;
  28383. + cesa_cmd->digestOffset += cesa_ocf_cur_ses->ivlen;
  28384. + }
  28385. + }
  28386. + else {
  28387. + dprintk("%s,%d: IV inside the buffer \n", __FILE__, __LINE__);
  28388. + cesa_cmd->ivFromUser = 0;
  28389. + cesa_cmd->ivOffset = crd->crd_inject;
  28390. + }
  28391. + }
  28392. +
  28393. + }
  28394. + /* Authentication */
  28395. + else if(crd->crd_alg == cesa_ocf_cur_ses->auth_alg) {
  28396. + dprintk("%s,%d: Authentication \n", __FILE__, __LINE__);
  28397. + auth++;
  28398. + cesa_cmd->macOffset = crd->crd_skip;
  28399. + cesa_cmd->macLength = crd->crd_len;
  28400. +
  28401. + /* digest + mac */
  28402. + cesa_cmd->digestOffset = crd->crd_inject;
  28403. + }
  28404. + else {
  28405. + printk("%s,%d: Alg isn't supported by this session.\n", __FILE__, __LINE__);
  28406. + goto p_error;
  28407. + }
  28408. + }
  28409. +
  28410. + dprintk("\n");
  28411. + dprintk("%s,%d: Sending Action: \n", __FILE__, __LINE__);
  28412. + dprintk("%s,%d: IV from user: %d. IV offset %x \n", __FILE__, __LINE__, cesa_cmd->ivFromUser, cesa_cmd->ivOffset);
  28413. + dprintk("%s,%d: crypt offset %x len %x \n", __FILE__, __LINE__, cesa_cmd->cryptoOffset, cesa_cmd->cryptoLength);
  28414. + dprintk("%s,%d: Auth offset %x len %x \n", __FILE__, __LINE__, cesa_cmd->macOffset, cesa_cmd->macLength);
  28415. + dprintk("%s,%d: set digest in offset %x . \n", __FILE__, __LINE__, cesa_cmd->digestOffset);
  28416. + if(debug) {
  28417. + mvCesaDebugMbuf("SRC BUFFER", cesa_cmd->pSrc, 0, cesa_cmd->pSrc->mbufSize);
  28418. + }
  28419. +
  28420. +
  28421. + /* send action to HAL */
  28422. + spin_lock_irqsave(&cesa_lock, flags);
  28423. + status = mvCesaAction(cesa_cmd);
  28424. + spin_unlock_irqrestore(&cesa_lock, flags);
  28425. +
  28426. + /* action not allowed */
  28427. + if(status == MV_NOT_ALLOWED) {
  28428. +#ifdef CESA_OCF_SPLIT
  28429. + /* if both encrypt and auth try to split */
  28430. + if(auth && (encrypt || decrypt)) {
  28431. + MV_CESA_COMMAND *cesa_cmd_wa;
  28432. +
  28433. + /* malloc a new cesa process and init it */
  28434. + cesa_ocf_cmd_wa = kmalloc(sizeof(struct cesa_ocf_process), GFP_ATOMIC);
  28435. +
  28436. + if (cesa_ocf_cmd_wa == NULL) {
  28437. + printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
  28438. + goto p_error;
  28439. + }
  28440. + memcpy(cesa_ocf_cmd_wa, cesa_ocf_cmd, sizeof(struct cesa_ocf_process));
  28441. + cesa_cmd_wa = &cesa_ocf_cmd_wa->cesa_cmd;
  28442. + cesa_cmd_wa->pReqPrv = (void *)cesa_ocf_cmd_wa;
  28443. + cesa_ocf_cmd_wa->need_cb = 0;
  28444. +
  28445. + /* break requests to two operation, first operation completion won't call callback */
  28446. + if((decrypt) && (cesa_ocf_cur_ses->auth_tn_decrypt)) {
  28447. + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
  28448. + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_decrypt;
  28449. + }
  28450. + else if((decrypt) && !(cesa_ocf_cur_ses->auth_tn_decrypt)) {
  28451. + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_decrypt;
  28452. + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
  28453. + }
  28454. + else if((encrypt) && (cesa_ocf_cur_ses->encrypt_tn_auth)) {
  28455. + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_encrypt;
  28456. + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
  28457. + }
  28458. + else if((encrypt) && !(cesa_ocf_cur_ses->encrypt_tn_auth)){
  28459. + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
  28460. + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_encrypt;
  28461. + }
  28462. + else {
  28463. + printk("%s,%d: Unsupporterd fragment wa mode \n", __FILE__, __LINE__);
  28464. + goto p_error;
  28465. + }
  28466. +
  28467. + /* send the 2 actions to the HAL */
  28468. + spin_lock_irqsave(&cesa_lock, flags);
  28469. + status = mvCesaAction(cesa_cmd_wa);
  28470. + spin_unlock_irqrestore(&cesa_lock, flags);
  28471. +
  28472. + if((status != MV_NO_MORE) && (status != MV_OK)) {
  28473. + printk("%s,%d: cesa action failed, status = 0x%x\n", __FILE__, __LINE__, status);
  28474. + goto p_error;
  28475. + }
  28476. + spin_lock_irqsave(&cesa_lock, flags);
  28477. + status = mvCesaAction(cesa_cmd);
  28478. + spin_unlock_irqrestore(&cesa_lock, flags);
  28479. +
  28480. + }
  28481. + /* action not allowed and can't split */
  28482. + else
  28483. +#endif
  28484. + {
  28485. + goto p_error;
  28486. + }
  28487. + }
  28488. +
  28489. + /* Hal Q is full, send again. This should never happen */
  28490. + if(status == MV_NO_RESOURCE) {
  28491. + printk("%s,%d: cesa no more resources \n", __FILE__, __LINE__);
  28492. + if(cesa_ocf_cmd)
  28493. + kfree(cesa_ocf_cmd);
  28494. + if(cesa_ocf_cmd_wa)
  28495. + kfree(cesa_ocf_cmd_wa);
  28496. + return ERESTART;
  28497. + }
  28498. + else if((status != MV_NO_MORE) && (status != MV_OK)) {
  28499. + printk("%s,%d: cesa action failed, status = 0x%x\n", __FILE__, __LINE__, status);
  28500. + goto p_error;
  28501. + }
  28502. +
  28503. +
  28504. +#ifdef CESA_OCF_POLLING
  28505. + cesa_interrupt_polling();
  28506. +#endif
  28507. + cesaTestTraceAdd(5);
  28508. +
  28509. + return 0;
  28510. +p_error:
  28511. + crp->crp_etype = EINVAL;
  28512. + if(cesa_ocf_cmd)
  28513. + kfree(cesa_ocf_cmd);
  28514. + if(cesa_ocf_cmd_wa)
  28515. + kfree(cesa_ocf_cmd_wa);
  28516. + return EINVAL;
  28517. +}
  28518. +
  28519. +/*
  28520. + * cesa callback.
  28521. + */
  28522. +static void
  28523. +cesa_callback(unsigned long dummy)
  28524. +{
  28525. + struct cesa_ocf_process *cesa_ocf_cmd = NULL;
  28526. + struct cryptop *crp = NULL;
  28527. + MV_CESA_RESULT result[MV_CESA_MAX_CHAN];
  28528. + int res_idx = 0,i;
  28529. + MV_STATUS status;
  28530. +
  28531. + dprintk("%s()\n", __FUNCTION__);
  28532. +
  28533. +#ifdef CESA_OCF_TASKLET
  28534. + disable_irq(cesa_device.irq);
  28535. +#endif
  28536. + while(MV_TRUE) {
  28537. +
  28538. + /* Get Ready requests */
  28539. + spin_lock(&cesa_lock);
  28540. + status = mvCesaReadyGet(&result[res_idx]);
  28541. + spin_unlock(&cesa_lock);
  28542. +
  28543. + cesaTestTraceAdd(2);
  28544. +
  28545. + if(status != MV_OK) {
  28546. +#ifdef CESA_OCF_POLLING
  28547. + if(status == MV_BUSY) { /* Fragment */
  28548. + cesa_interrupt_polling();
  28549. + return;
  28550. + }
  28551. +#endif
  28552. + break;
  28553. + }
  28554. + res_idx++;
  28555. + break;
  28556. + }
  28557. +
  28558. + for(i = 0; i < res_idx; i++) {
  28559. +
  28560. + if(!result[i].pReqPrv) {
  28561. + printk("%s,%d: warning private is NULL\n", __FILE__, __LINE__);
  28562. + break;
  28563. + }
  28564. +
  28565. + cesa_ocf_cmd = result[i].pReqPrv;
  28566. + crp = cesa_ocf_cmd->crp;
  28567. +
  28568. + // ignore HMAC error.
  28569. + //if(result->retCode)
  28570. + // crp->crp_etype = EIO;
  28571. +
  28572. +#if defined(CESA_OCF_POLLING)
  28573. + if(!cesa_ocf_cmd->need_cb){
  28574. + cesa_interrupt_polling();
  28575. + }
  28576. +#endif
  28577. + if(cesa_ocf_cmd->need_cb) {
  28578. + if(debug) {
  28579. + mvCesaDebugMbuf("DST BUFFER", cesa_ocf_cmd->cesa_cmd.pDst, 0, cesa_ocf_cmd->cesa_cmd.pDst->mbufSize);
  28580. + }
  28581. + crypto_done(crp);
  28582. + }
  28583. + kfree(cesa_ocf_cmd);
  28584. + }
  28585. +#ifdef CESA_OCF_TASKLET
  28586. + enable_irq(cesa_device.irq);
  28587. +#endif
  28588. +
  28589. + cesaTestTraceAdd(3);
  28590. +
  28591. + return;
  28592. +}
  28593. +
  28594. +#ifdef CESA_OCF_POLLING
  28595. +static void
  28596. +cesa_interrupt_polling(void)
  28597. +{
  28598. + u32 cause;
  28599. +
  28600. + dprintk("%s()\n", __FUNCTION__);
  28601. +
  28602. + /* Read cause register */
  28603. + do {
  28604. + cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  28605. + cause &= MV_CESA_CAUSE_ACC_DMA_ALL_MASK;
  28606. +
  28607. + } while (cause == 0);
  28608. +
  28609. + /* clear interrupts */
  28610. + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
  28611. +
  28612. + cesa_callback(0);
  28613. +
  28614. + return;
  28615. +}
  28616. +
  28617. +#endif
  28618. +
  28619. +/*
  28620. + * cesa Interrupt polling routine.
  28621. + */
  28622. +static irqreturn_t
  28623. +cesa_interrupt_handler(int irq, void *arg)
  28624. +{
  28625. + u32 cause;
  28626. +
  28627. + dprintk("%s()\n", __FUNCTION__);
  28628. +
  28629. + cesaTestTraceAdd(0);
  28630. +
  28631. + /* Read cause register */
  28632. + cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  28633. +
  28634. + if( (cause & MV_CESA_CAUSE_ACC_DMA_ALL_MASK) == 0)
  28635. + {
  28636. + /* Empty interrupt */
  28637. + dprintk("%s,%d: cesaTestReadyIsr: cause=0x%x\n", __FILE__, __LINE__, cause);
  28638. + return IRQ_HANDLED;
  28639. + }
  28640. +
  28641. + /* clear interrupts */
  28642. + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
  28643. +
  28644. + cesaTestTraceAdd(1);
  28645. +#ifdef CESA_OCF_TASKLET
  28646. + tasklet_hi_schedule(&cesa_ocf_tasklet);
  28647. +#else
  28648. + cesa_callback(0);
  28649. +#endif
  28650. + return IRQ_HANDLED;
  28651. +}
  28652. +
  28653. +/*
  28654. + * Open a session.
  28655. + */
  28656. +static int
  28657. +/*cesa_ocf_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)*/
  28658. +cesa_ocf_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  28659. +{
  28660. + u32 status = 0, i;
  28661. + u32 count = 0, auth = 0, encrypt =0;
  28662. + struct cesa_ocf_data *cesa_ocf_cur_ses;
  28663. + MV_CESA_OPEN_SESSION cesa_session;
  28664. + MV_CESA_OPEN_SESSION *cesa_ses = &cesa_session;
  28665. +
  28666. +
  28667. + dprintk("%s()\n", __FUNCTION__);
  28668. + if (sid == NULL || cri == NULL) {
  28669. + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  28670. + return EINVAL;
  28671. + }
  28672. +
  28673. + /* leave first empty like in other implementations */
  28674. + for (i = 1; i < CESA_OCF_MAX_SES; i++) {
  28675. + if (cesa_ocf_sessions[i] == NULL)
  28676. + break;
  28677. + }
  28678. +
  28679. + if(i >= CESA_OCF_MAX_SES) {
  28680. + printk("%s,%d: no more sessions \n", __FILE__, __LINE__);
  28681. + return EINVAL;
  28682. + }
  28683. +
  28684. + cesa_ocf_sessions[i] = (struct cesa_ocf_data *) kmalloc(sizeof(struct cesa_ocf_data), GFP_ATOMIC);
  28685. + if (cesa_ocf_sessions[i] == NULL) {
  28686. + cesa_ocf_freesession(NULL, i);
  28687. + printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
  28688. + return ENOBUFS;
  28689. + }
  28690. + dprintk("%s,%d: new session %d \n", __FILE__, __LINE__, i);
  28691. +
  28692. + *sid = i;
  28693. + cesa_ocf_cur_ses = cesa_ocf_sessions[i];
  28694. + memset(cesa_ocf_cur_ses, 0, sizeof(struct cesa_ocf_data));
  28695. + cesa_ocf_cur_ses->sid_encrypt = -1;
  28696. + cesa_ocf_cur_ses->sid_decrypt = -1;
  28697. + cesa_ocf_cur_ses->frag_wa_encrypt = -1;
  28698. + cesa_ocf_cur_ses->frag_wa_decrypt = -1;
  28699. + cesa_ocf_cur_ses->frag_wa_auth = -1;
  28700. +
  28701. + /* init the session */
  28702. + memset(cesa_ses, 0, sizeof(MV_CESA_OPEN_SESSION));
  28703. + count = 1;
  28704. + while (cri) {
  28705. + if(count > 2) {
  28706. + printk("%s,%d: don't support more then 2 operations\n", __FILE__, __LINE__);
  28707. + goto error;
  28708. + }
  28709. + switch (cri->cri_alg) {
  28710. + case CRYPTO_AES_CBC:
  28711. + dprintk("%s,%d: (%d) AES CBC \n", __FILE__, __LINE__, count);
  28712. + cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
  28713. + cesa_ocf_cur_ses->ivlen = MV_CESA_AES_BLOCK_SIZE;
  28714. + cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_AES;
  28715. + cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
  28716. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  28717. + printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
  28718. + goto error;
  28719. + }
  28720. + memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
  28721. + dprintk("%s,%d: key length %d \n", __FILE__, __LINE__, cri->cri_klen/8);
  28722. + cesa_ses->cryptoKeyLength = cri->cri_klen/8;
  28723. + encrypt += count;
  28724. + break;
  28725. + case CRYPTO_3DES_CBC:
  28726. + dprintk("%s,%d: (%d) 3DES CBC \n", __FILE__, __LINE__, count);
  28727. + cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
  28728. + cesa_ocf_cur_ses->ivlen = MV_CESA_3DES_BLOCK_SIZE;
  28729. + cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_3DES;
  28730. + cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
  28731. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  28732. + printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
  28733. + goto error;
  28734. + }
  28735. + memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
  28736. + cesa_ses->cryptoKeyLength = cri->cri_klen/8;
  28737. + encrypt += count;
  28738. + break;
  28739. + case CRYPTO_DES_CBC:
  28740. + dprintk("%s,%d: (%d) DES CBC \n", __FILE__, __LINE__, count);
  28741. + cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
  28742. + cesa_ocf_cur_ses->ivlen = MV_CESA_DES_BLOCK_SIZE;
  28743. + cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_DES;
  28744. + cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
  28745. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  28746. + printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
  28747. + goto error;
  28748. + }
  28749. + memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
  28750. + cesa_ses->cryptoKeyLength = cri->cri_klen/8;
  28751. + encrypt += count;
  28752. + break;
  28753. + case CRYPTO_MD5:
  28754. + case CRYPTO_MD5_HMAC:
  28755. + dprintk("%s,%d: (%d) %sMD5 CBC \n", __FILE__, __LINE__, count, (cri->cri_alg != CRYPTO_MD5)? "H-":" ");
  28756. + cesa_ocf_cur_ses->auth_alg = cri->cri_alg;
  28757. + cesa_ocf_cur_ses->digestlen = (cri->cri_alg == CRYPTO_MD5)? MV_CESA_MD5_DIGEST_SIZE : 12;
  28758. + cesa_ses->macMode = (cri->cri_alg == CRYPTO_MD5)? MV_CESA_MAC_MD5 : MV_CESA_MAC_HMAC_MD5;
  28759. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  28760. + printk("%s,%d: MAC key too long. \n", __FILE__, __LINE__);
  28761. + goto error;
  28762. + }
  28763. + cesa_ses->macKeyLength = cri->cri_klen/8;
  28764. + memcpy(cesa_ses->macKey, cri->cri_key, cri->cri_klen/8);
  28765. + cesa_ses->digestSize = cesa_ocf_cur_ses->digestlen;
  28766. + auth += count;
  28767. + break;
  28768. + case CRYPTO_SHA1:
  28769. + case CRYPTO_SHA1_HMAC:
  28770. + dprintk("%s,%d: (%d) %sSHA1 CBC \n", __FILE__, __LINE__, count, (cri->cri_alg != CRYPTO_SHA1)? "H-":" ");
  28771. + cesa_ocf_cur_ses->auth_alg = cri->cri_alg;
  28772. + cesa_ocf_cur_ses->digestlen = (cri->cri_alg == CRYPTO_SHA1)? MV_CESA_SHA1_DIGEST_SIZE : 12;
  28773. + cesa_ses->macMode = (cri->cri_alg == CRYPTO_SHA1)? MV_CESA_MAC_SHA1 : MV_CESA_MAC_HMAC_SHA1;
  28774. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  28775. + printk("%s,%d: MAC key too long. \n", __FILE__, __LINE__);
  28776. + goto error;
  28777. + }
  28778. + cesa_ses->macKeyLength = cri->cri_klen/8;
  28779. + memcpy(cesa_ses->macKey, cri->cri_key, cri->cri_klen/8);
  28780. + cesa_ses->digestSize = cesa_ocf_cur_ses->digestlen;
  28781. + auth += count;
  28782. + break;
  28783. + default:
  28784. + printk("%s,%d: unknown algo 0x%x\n", __FILE__, __LINE__, cri->cri_alg);
  28785. + goto error;
  28786. + }
  28787. + cri = cri->cri_next;
  28788. + count++;
  28789. + }
  28790. +
  28791. + if((encrypt > 2) || (auth > 2)) {
  28792. + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
  28793. + goto error;
  28794. + }
  28795. + /* create new sessions in HAL */
  28796. + if(encrypt) {
  28797. + cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
  28798. + /* encrypt session */
  28799. + if(auth == 1) {
  28800. + cesa_ses->operation = MV_CESA_MAC_THEN_CRYPTO;
  28801. + }
  28802. + else if(auth == 2) {
  28803. + cesa_ses->operation = MV_CESA_CRYPTO_THEN_MAC;
  28804. + cesa_ocf_cur_ses->encrypt_tn_auth = 1;
  28805. + }
  28806. + else {
  28807. + cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
  28808. + }
  28809. + cesa_ses->direction = MV_CESA_DIR_ENCODE;
  28810. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_encrypt);
  28811. + if(status != MV_OK) {
  28812. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  28813. + goto error;
  28814. + }
  28815. + /* decrypt session */
  28816. + if( cesa_ses->operation == MV_CESA_MAC_THEN_CRYPTO ) {
  28817. + cesa_ses->operation = MV_CESA_CRYPTO_THEN_MAC;
  28818. + }
  28819. + else if( cesa_ses->operation == MV_CESA_CRYPTO_THEN_MAC ) {
  28820. + cesa_ses->operation = MV_CESA_MAC_THEN_CRYPTO;
  28821. + }
  28822. + cesa_ses->direction = MV_CESA_DIR_DECODE;
  28823. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_decrypt);
  28824. + if(status != MV_OK) {
  28825. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  28826. + goto error;
  28827. + }
  28828. +
  28829. + /* preapre one action sessions for case we will need to split an action */
  28830. +#ifdef CESA_OCF_SPLIT
  28831. + if(( cesa_ses->operation == MV_CESA_MAC_THEN_CRYPTO ) ||
  28832. + ( cesa_ses->operation == MV_CESA_CRYPTO_THEN_MAC )) {
  28833. + /* open one session for encode and one for decode */
  28834. + cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
  28835. + cesa_ses->direction = MV_CESA_DIR_ENCODE;
  28836. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_encrypt);
  28837. + if(status != MV_OK) {
  28838. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  28839. + goto error;
  28840. + }
  28841. +
  28842. + cesa_ses->direction = MV_CESA_DIR_DECODE;
  28843. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_decrypt);
  28844. + if(status != MV_OK) {
  28845. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  28846. + goto error;
  28847. + }
  28848. + /* open one session for auth */
  28849. + cesa_ses->operation = MV_CESA_MAC_ONLY;
  28850. + cesa_ses->direction = MV_CESA_DIR_ENCODE;
  28851. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_auth);
  28852. + if(status != MV_OK) {
  28853. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  28854. + goto error;
  28855. + }
  28856. + }
  28857. +#endif
  28858. + }
  28859. + else { /* only auth */
  28860. + cesa_ses->operation = MV_CESA_MAC_ONLY;
  28861. + cesa_ses->direction = MV_CESA_DIR_ENCODE;
  28862. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_encrypt);
  28863. + if(status != MV_OK) {
  28864. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  28865. + goto error;
  28866. + }
  28867. + }
  28868. +
  28869. + return 0;
  28870. +error:
  28871. + cesa_ocf_freesession(NULL, *sid);
  28872. + return EINVAL;
  28873. +
  28874. +}
  28875. +
  28876. +
  28877. +/*
  28878. + * Free a session.
  28879. + */
  28880. +static int
  28881. +cesa_ocf_freesession(device_t dev, u_int64_t tid)
  28882. +{
  28883. + struct cesa_ocf_data *cesa_ocf_cur_ses;
  28884. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  28885. + //unsigned long flags;
  28886. +
  28887. + dprintk("%s() %d \n", __FUNCTION__, sid);
  28888. + if ( (sid >= CESA_OCF_MAX_SES) || (cesa_ocf_sessions[sid] == NULL) ) {
  28889. + printk("%s,%d: EINVAL can't free session %d \n", __FILE__, __LINE__, sid);
  28890. + return(EINVAL);
  28891. + }
  28892. +
  28893. + /* Silently accept and return */
  28894. + if (sid == 0)
  28895. + return(0);
  28896. +
  28897. + /* release session from HAL */
  28898. + cesa_ocf_cur_ses = cesa_ocf_sessions[sid];
  28899. + if (cesa_ocf_cur_ses->sid_encrypt != -1) {
  28900. + mvCesaSessionClose(cesa_ocf_cur_ses->sid_encrypt);
  28901. + }
  28902. + if (cesa_ocf_cur_ses->sid_decrypt != -1) {
  28903. + mvCesaSessionClose(cesa_ocf_cur_ses->sid_decrypt);
  28904. + }
  28905. + if (cesa_ocf_cur_ses->frag_wa_encrypt != -1) {
  28906. + mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_encrypt);
  28907. + }
  28908. + if (cesa_ocf_cur_ses->frag_wa_decrypt != -1) {
  28909. + mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_decrypt);
  28910. + }
  28911. + if (cesa_ocf_cur_ses->frag_wa_auth != -1) {
  28912. + mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_auth);
  28913. + }
  28914. +
  28915. + kfree(cesa_ocf_cur_ses);
  28916. + cesa_ocf_sessions[sid] = NULL;
  28917. +
  28918. + return 0;
  28919. +}
  28920. +
  28921. +
  28922. +/* TDMA Window setup */
  28923. +
  28924. +static void __init
  28925. +setup_tdma_mbus_windows(struct cesa_dev *dev)
  28926. +{
  28927. + int i;
  28928. +
  28929. + for (i = 0; i < 4; i++) {
  28930. + writel(0, dev->reg + WINDOW_BASE(i));
  28931. + writel(0, dev->reg + WINDOW_CTRL(i));
  28932. + }
  28933. +
  28934. + for (i = 0; i < dev->plat_data->dram->num_cs; i++) {
  28935. + struct mbus_dram_window *cs = dev->plat_data->dram->cs + i;
  28936. + writel(
  28937. + ((cs->size - 1) & 0xffff0000) |
  28938. + (cs->mbus_attr << 8) |
  28939. + (dev->plat_data->dram->mbus_dram_target_id << 4) | 1,
  28940. + dev->reg + WINDOW_CTRL(i)
  28941. + );
  28942. + writel(cs->base, dev->reg + WINDOW_BASE(i));
  28943. + }
  28944. +}
  28945. +
  28946. +/*
  28947. + * our driver startup and shutdown routines
  28948. + */
  28949. +static int
  28950. +mv_cesa_ocf_init(struct platform_device *pdev)
  28951. +{
  28952. +#if defined(CONFIG_MV78200) || defined(CONFIG_MV632X)
  28953. + if (MV_FALSE == mvSocUnitIsMappedToThisCpu(CESA))
  28954. + {
  28955. + dprintk("CESA is not mapped to this CPU\n");
  28956. + return -ENODEV;
  28957. + }
  28958. +#endif
  28959. +
  28960. + dprintk("%s\n", __FUNCTION__);
  28961. + memset(&mv_cesa_dev, 0, sizeof(mv_cesa_dev));
  28962. + softc_device_init(&mv_cesa_dev, "MV CESA", 0, mv_cesa_methods);
  28963. + cesa_ocf_id = crypto_get_driverid(softc_get_device(&mv_cesa_dev),CRYPTOCAP_F_HARDWARE);
  28964. +
  28965. + if (cesa_ocf_id < 0)
  28966. + panic("MV CESA crypto device cannot initialize!");
  28967. +
  28968. + dprintk("%s,%d: cesa ocf device id is %d \n", __FILE__, __LINE__, cesa_ocf_id);
  28969. +
  28970. + /* CESA unit is auto power on off */
  28971. +#if 0
  28972. + if (MV_FALSE == mvCtrlPwrClckGet(CESA_UNIT_ID,0))
  28973. + {
  28974. + printk("\nWarning CESA %d is Powered Off\n",0);
  28975. + return EINVAL;
  28976. + }
  28977. +#endif
  28978. +
  28979. + memset(&cesa_device, 0, sizeof(struct cesa_dev));
  28980. + /* Get the IRQ, and crypto memory regions */
  28981. + {
  28982. + struct resource *res;
  28983. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram");
  28984. +
  28985. + if (!res)
  28986. + return -ENXIO;
  28987. +
  28988. + cesa_device.sram = ioremap(res->start, res->end - res->start + 1);
  28989. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
  28990. +
  28991. + if (!res) {
  28992. + iounmap(cesa_device.sram);
  28993. + return -ENXIO;
  28994. + }
  28995. + cesa_device.reg = ioremap(res->start, res->end - res->start + 1);
  28996. + cesa_device.irq = platform_get_irq(pdev, 0);
  28997. + cesa_device.plat_data = pdev->dev.platform_data;
  28998. + setup_tdma_mbus_windows(&cesa_device);
  28999. +
  29000. + }
  29001. +
  29002. +
  29003. + if( MV_OK != mvCesaInit(CESA_OCF_MAX_SES*5, CESA_Q_SIZE, cesa_device.reg,
  29004. + NULL) ) {
  29005. + printk("%s,%d: mvCesaInit Failed. \n", __FILE__, __LINE__);
  29006. + return EINVAL;
  29007. + }
  29008. +
  29009. + /* clear and unmask Int */
  29010. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  29011. +#ifndef CESA_OCF_POLLING
  29012. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, MV_CESA_CAUSE_ACC_DMA_MASK);
  29013. +#endif
  29014. +#ifdef CESA_OCF_TASKLET
  29015. + tasklet_init(&cesa_ocf_tasklet, cesa_callback, (unsigned int) 0);
  29016. +#endif
  29017. + /* register interrupt */
  29018. + if( request_irq( cesa_device.irq, cesa_interrupt_handler,
  29019. + (IRQF_DISABLED) , "cesa", &cesa_ocf_id) < 0) {
  29020. + printk("%s,%d: cannot assign irq %x\n", __FILE__, __LINE__, cesa_device.reg);
  29021. + return EINVAL;
  29022. + }
  29023. +
  29024. +
  29025. + memset(cesa_ocf_sessions, 0, sizeof(struct cesa_ocf_data *) * CESA_OCF_MAX_SES);
  29026. +
  29027. +#define REGISTER(alg) \
  29028. + crypto_register(cesa_ocf_id, alg, 0,0)
  29029. + REGISTER(CRYPTO_AES_CBC);
  29030. + REGISTER(CRYPTO_DES_CBC);
  29031. + REGISTER(CRYPTO_3DES_CBC);
  29032. + REGISTER(CRYPTO_MD5);
  29033. + REGISTER(CRYPTO_MD5_HMAC);
  29034. + REGISTER(CRYPTO_SHA1);
  29035. + REGISTER(CRYPTO_SHA1_HMAC);
  29036. +#undef REGISTER
  29037. +
  29038. + return 0;
  29039. +}
  29040. +
  29041. +static void
  29042. +mv_cesa_ocf_exit(struct platform_device *pdev)
  29043. +{
  29044. + dprintk("%s()\n", __FUNCTION__);
  29045. +
  29046. + crypto_unregister_all(cesa_ocf_id);
  29047. + cesa_ocf_id = -1;
  29048. + iounmap(cesa_device.reg);
  29049. + iounmap(cesa_device.sram);
  29050. + free_irq(cesa_device.irq, NULL);
  29051. +
  29052. + /* mask and clear Int */
  29053. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
  29054. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  29055. +
  29056. +
  29057. + if( MV_OK != mvCesaFinish() ) {
  29058. + printk("%s,%d: mvCesaFinish Failed. \n", __FILE__, __LINE__);
  29059. + return;
  29060. + }
  29061. +}
  29062. +
  29063. +
  29064. +void cesa_ocf_debug(void)
  29065. +{
  29066. +
  29067. +#ifdef CESA_OCF_TRACE_DEBUG
  29068. + {
  29069. + int i, j;
  29070. + j = cesaTestTraceIdx;
  29071. + mvOsPrintf("No Type rCause iCause Proc Isr Res Time pReady pProc pEmpty\n");
  29072. + for(i=0; i<MV_CESA_TEST_TRACE_SIZE; i++)
  29073. + {
  29074. + mvOsPrintf("%02d. %d 0x%04x 0x%04x 0x%02x 0x%02x %02d 0x%06x %p %p %p\n",
  29075. + j, cesaTestTrace[j].type, cesaTestTrace[j].realCause,
  29076. + cesaTestTrace[j].idmaCause,
  29077. + cesaTestTrace[j].resources, cesaTestTrace[j].timeStamp,
  29078. + cesaTestTrace[j].pReqReady, cesaTestTrace[j].pReqProcess, cesaTestTrace[j].pReqEmpty);
  29079. + j++;
  29080. + if(j == MV_CESA_TEST_TRACE_SIZE)
  29081. + j = 0;
  29082. + }
  29083. + }
  29084. +#endif
  29085. +
  29086. +}
  29087. +
  29088. +static struct platform_driver marvell_cesa = {
  29089. + .probe = mv_cesa_ocf_init,
  29090. + .remove = mv_cesa_ocf_exit,
  29091. + .driver = {
  29092. + .owner = THIS_MODULE,
  29093. + .name = "mv_crypto",
  29094. + },
  29095. +};
  29096. +
  29097. +MODULE_ALIAS("platform:mv_crypto");
  29098. +
  29099. +static int __init mv_cesa_init(void)
  29100. +{
  29101. + return platform_driver_register(&marvell_cesa);
  29102. +}
  29103. +
  29104. +module_init(mv_cesa_init);
  29105. +
  29106. +static void __exit mv_cesa_exit(void)
  29107. +{
  29108. + platform_driver_unregister(&marvell_cesa);
  29109. +}
  29110. +
  29111. +module_exit(mv_cesa_exit);
  29112. +
  29113. +MODULE_LICENSE("GPL");
  29114. +MODULE_AUTHOR("Ronen Shitrit");
  29115. +MODULE_DESCRIPTION("OCF module for Orion CESA crypto");
  29116. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/Makefile linux-2.6.35/crypto/ocf/kirkwood/Makefile
  29117. --- linux-2.6.35.orig/crypto/ocf/kirkwood/Makefile 1970-01-01 01:00:00.000000000 +0100
  29118. +++ linux-2.6.35/crypto/ocf/kirkwood/Makefile 2010-08-05 22:02:12.863672447 +0200
  29119. @@ -0,0 +1,19 @@
  29120. +# for SGlinux builds
  29121. +-include $(ROOTDIR)/modules/.config
  29122. +
  29123. +obj-$(CONFIG_OCF_KIRKWOOD) += mv_cesa.o
  29124. +
  29125. +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
  29126. +
  29127. +# Extra objects required by the CESA driver
  29128. +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
  29129. +
  29130. +ifdef src
  29131. +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)
  29132. +endif
  29133. +
  29134. +EXTRA_CFLAGS += -DMV_LINUX -DMV_CPU_LE -DMV_ARM -DMV_INCLUDE_CESA -DMV_INCLUDE_PEX -DMV_CACHE_COHERENCY=3
  29135. +ifdef TOPDIR
  29136. +-include $(TOPDIR)/Rules.make
  29137. +endif
  29138. +
  29139. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mv802_3.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mv802_3.h
  29140. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mv802_3.h 1970-01-01 01:00:00.000000000 +0100
  29141. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mv802_3.h 2010-08-05 22:02:13.203840755 +0200
  29142. @@ -0,0 +1,213 @@
  29143. +/*******************************************************************************
  29144. +Copyright (C) Marvell International Ltd. and its affiliates
  29145. +
  29146. +This software file (the "File") is owned and distributed by Marvell
  29147. +International Ltd. and/or its affiliates ("Marvell") under the following
  29148. +alternative licensing terms. Once you have made an election to distribute the
  29149. +File under one of the following license alternatives, please (i) delete this
  29150. +introductory statement regarding license alternatives, (ii) delete the two
  29151. +license alternatives that you have not elected to use and (iii) preserve the
  29152. +Marvell copyright notice above.
  29153. +
  29154. +********************************************************************************
  29155. +Marvell Commercial License Option
  29156. +
  29157. +If you received this File from Marvell and you have entered into a commercial
  29158. +license agreement (a "Commercial License") with Marvell, the File is licensed
  29159. +to you under the terms of the applicable Commercial License.
  29160. +
  29161. +********************************************************************************
  29162. +Marvell GPL License Option
  29163. +
  29164. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29165. +modify this File in accordance with the terms and conditions of the General
  29166. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  29167. +available along with the File in the license.txt file or by writing to the Free
  29168. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  29169. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  29170. +
  29171. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  29172. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  29173. +DISCLAIMED. The GPL License provides additional details about this warranty
  29174. +disclaimer.
  29175. +********************************************************************************
  29176. +Marvell BSD License Option
  29177. +
  29178. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29179. +modify this File under the following licensing terms.
  29180. +Redistribution and use in source and binary forms, with or without modification,
  29181. +are permitted provided that the following conditions are met:
  29182. +
  29183. + * Redistributions of source code must retain the above copyright notice,
  29184. + this list of conditions and the following disclaimer.
  29185. +
  29186. + * Redistributions in binary form must reproduce the above copyright
  29187. + notice, this list of conditions and the following disclaimer in the
  29188. + documentation and/or other materials provided with the distribution.
  29189. +
  29190. + * Neither the name of Marvell nor the names of its contributors may be
  29191. + used to endorse or promote products derived from this software without
  29192. + specific prior written permission.
  29193. +
  29194. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  29195. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  29196. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  29197. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  29198. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  29199. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29200. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  29201. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29202. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29203. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29204. +
  29205. +*******************************************************************************/
  29206. +
  29207. +
  29208. +#ifndef __INCmv802_3h
  29209. +#define __INCmv802_3h
  29210. +
  29211. +
  29212. +/* includes */
  29213. +#include "mvTypes.h"
  29214. +
  29215. +/* Defines */
  29216. +#define MV_MAX_ETH_DATA 1500
  29217. +
  29218. +/* 802.3 types */
  29219. +#define MV_IP_TYPE 0x0800
  29220. +#define MV_IP_ARP_TYPE 0x0806
  29221. +#define MV_APPLE_TALK_ARP_TYPE 0x80F3
  29222. +#define MV_NOVELL_IPX_TYPE 0x8137
  29223. +#define MV_EAPOL_TYPE 0x888e
  29224. +
  29225. +
  29226. +
  29227. +/* Encapsulation header for RFC1042 and Ethernet_tunnel */
  29228. +
  29229. +#define MV_RFC1042_SNAP_HEADER {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}
  29230. +
  29231. +#define MV_ETH_SNAP_LSB 0xF8
  29232. +
  29233. +
  29234. +#define MV_MAC_ADDR_SIZE (6)
  29235. +#define MV_MAC_STR_SIZE (20)
  29236. +#define MV_VLAN_HLEN (4)
  29237. +
  29238. +/* This macro checks for a multicast mac address */
  29239. +#define MV_IS_MULTICAST_MAC(mac) (((mac)[0] & 0x1) == 1)
  29240. +
  29241. +
  29242. +/* This macro checks for an broadcast mac address */
  29243. +#define MV_IS_BROADCAST_MAC(mac) \
  29244. + (((mac)[0] == 0xFF) && \
  29245. + ((mac)[1] == 0xFF) && \
  29246. + ((mac)[2] == 0xFF) && \
  29247. + ((mac)[3] == 0xFF) && \
  29248. + ((mac)[4] == 0xFF) && \
  29249. + ((mac)[5] == 0xFF))
  29250. +
  29251. +
  29252. +/* Typedefs */
  29253. +typedef struct
  29254. +{
  29255. + MV_U8 pDA[MV_MAC_ADDR_SIZE];
  29256. + MV_U8 pSA[MV_MAC_ADDR_SIZE];
  29257. + MV_U16 typeOrLen;
  29258. +
  29259. +} MV_802_3_HEADER;
  29260. +
  29261. +enum {
  29262. + MV_IP_PROTO_NULL = 0, /* Dummy protocol for TCP */
  29263. + MV_IP_PROTO_ICMP = 1, /* Internet Control Message Protocol */
  29264. + MV_IP_PROTO_IGMP = 2, /* Internet Group Management Protocol */
  29265. + MV_IP_PROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
  29266. + MV_IP_PROTO_TCP = 6, /* Transmission Control Protocol */
  29267. + MV_IP_PROTO_EGP = 8, /* Exterior Gateway Protocol */
  29268. + MV_IP_PROTO_PUP = 12, /* PUP protocol */
  29269. + MV_IP_PROTO_UDP = 17, /* User Datagram Protocol */
  29270. + MV_IP_PROTO_IDP = 22, /* XNS IDP protocol */
  29271. + MV_IP_PROTO_DCCP = 33, /* Datagram Congestion Control Protocol */
  29272. + MV_IP_PROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */
  29273. + MV_IP_PROTO_RSVP = 46, /* RSVP protocol */
  29274. + MV_IP_PROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */
  29275. + MV_IP_PROTO_ESP = 50, /* Encapsulation Security Payload protocol */
  29276. + MV_IP_PROTO_AH = 51, /* Authentication Header protocol */
  29277. + MV_IP_PROTO_BEETPH = 94, /* IP option pseudo header for BEET */
  29278. + MV_IP_PROTO_PIM = 103,
  29279. + MV_IP_PROTO_COMP = 108, /* Compression Header protocol */
  29280. + MV_IP_PROTO_ZERO_HOP = 114, /* Any 0 hop protocol (IANA) */
  29281. + MV_IP_PROTO_SCTP = 132, /* Stream Control Transport Protocol */
  29282. + MV_IP_PROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */
  29283. +
  29284. + MV_IP_PROTO_RAW = 255, /* Raw IP packets */
  29285. + MV_IP_PROTO_MAX
  29286. +};
  29287. +
  29288. +typedef struct
  29289. +{
  29290. + MV_U8 version;
  29291. + MV_U8 tos;
  29292. + MV_U16 totalLength;
  29293. + MV_U16 identifier;
  29294. + MV_U16 fragmentCtrl;
  29295. + MV_U8 ttl;
  29296. + MV_U8 protocol;
  29297. + MV_U16 checksum;
  29298. + MV_U32 srcIP;
  29299. + MV_U32 dstIP;
  29300. +
  29301. +} MV_IP_HEADER;
  29302. +
  29303. +typedef struct
  29304. +{
  29305. + MV_U32 spi;
  29306. + MV_U32 seqNum;
  29307. +} MV_ESP_HEADER;
  29308. +
  29309. +#define MV_ICMP_ECHOREPLY 0 /* Echo Reply */
  29310. +#define MV_ICMP_DEST_UNREACH 3 /* Destination Unreachable */
  29311. +#define MV_ICMP_SOURCE_QUENCH 4 /* Source Quench */
  29312. +#define MV_ICMP_REDIRECT 5 /* Redirect (change route) */
  29313. +#define MV_ICMP_ECHO 8 /* Echo Request */
  29314. +#define MV_ICMP_TIME_EXCEEDED 11 /* Time Exceeded */
  29315. +#define MV_ICMP_PARAMETERPROB 12 /* Parameter Problem */
  29316. +#define MV_ICMP_TIMESTAMP 13 /* Timestamp Request */
  29317. +#define MV_ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */
  29318. +#define MV_ICMP_INFO_REQUEST 15 /* Information Request */
  29319. +#define MV_ICMP_INFO_REPLY 16 /* Information Reply */
  29320. +#define MV_ICMP_ADDRESS 17 /* Address Mask Request */
  29321. +#define MV_ICMP_ADDRESSREPLY 18 /* Address Mask Reply */
  29322. +
  29323. +typedef struct
  29324. +{
  29325. + MV_U8 type;
  29326. + MV_U8 code;
  29327. + MV_U16 checksum;
  29328. + MV_U16 id;
  29329. + MV_U16 sequence;
  29330. +
  29331. +} MV_ICMP_ECHO_HEADER;
  29332. +
  29333. +typedef struct
  29334. +{
  29335. + MV_U16 source;
  29336. + MV_U16 dest;
  29337. + MV_U32 seq;
  29338. + MV_U32 ack_seq;
  29339. + MV_U16 flags;
  29340. + MV_U16 window;
  29341. + MV_U16 chksum;
  29342. + MV_U16 urg_offset;
  29343. +
  29344. +} MV_TCP_HEADER;
  29345. +
  29346. +typedef struct
  29347. +{
  29348. + MV_U16 source;
  29349. + MV_U16 dest;
  29350. + MV_U16 len;
  29351. + MV_U16 check;
  29352. +
  29353. +} MV_UDP_HEADER;
  29354. +
  29355. +#endif /* __INCmv802_3h */
  29356. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mvCommon.c
  29357. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.c 1970-01-01 01:00:00.000000000 +0100
  29358. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mvCommon.c 2010-08-05 22:02:13.363625698 +0200
  29359. @@ -0,0 +1,277 @@
  29360. +/*******************************************************************************
  29361. +Copyright (C) Marvell International Ltd. and its affiliates
  29362. +
  29363. +This software file (the "File") is owned and distributed by Marvell
  29364. +International Ltd. and/or its affiliates ("Marvell") under the following
  29365. +alternative licensing terms. Once you have made an election to distribute the
  29366. +File under one of the following license alternatives, please (i) delete this
  29367. +introductory statement regarding license alternatives, (ii) delete the two
  29368. +license alternatives that you have not elected to use and (iii) preserve the
  29369. +Marvell copyright notice above.
  29370. +
  29371. +********************************************************************************
  29372. +Marvell Commercial License Option
  29373. +
  29374. +If you received this File from Marvell and you have entered into a commercial
  29375. +license agreement (a "Commercial License") with Marvell, the File is licensed
  29376. +to you under the terms of the applicable Commercial License.
  29377. +
  29378. +********************************************************************************
  29379. +Marvell GPL License Option
  29380. +
  29381. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29382. +modify this File in accordance with the terms and conditions of the General
  29383. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  29384. +available along with the File in the license.txt file or by writing to the Free
  29385. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  29386. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  29387. +
  29388. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  29389. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  29390. +DISCLAIMED. The GPL License provides additional details about this warranty
  29391. +disclaimer.
  29392. +********************************************************************************
  29393. +Marvell BSD License Option
  29394. +
  29395. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29396. +modify this File under the following licensing terms.
  29397. +Redistribution and use in source and binary forms, with or without modification,
  29398. +are permitted provided that the following conditions are met:
  29399. +
  29400. + * Redistributions of source code must retain the above copyright notice,
  29401. + this list of conditions and the following disclaimer.
  29402. +
  29403. + * Redistributions in binary form must reproduce the above copyright
  29404. + notice, this list of conditions and the following disclaimer in the
  29405. + documentation and/or other materials provided with the distribution.
  29406. +
  29407. + * Neither the name of Marvell nor the names of its contributors may be
  29408. + used to endorse or promote products derived from this software without
  29409. + specific prior written permission.
  29410. +
  29411. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  29412. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  29413. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  29414. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  29415. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  29416. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29417. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  29418. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29419. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29420. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29421. +
  29422. +*******************************************************************************/
  29423. +
  29424. +#include "mvOs.h"
  29425. +#include "mv802_3.h"
  29426. +#include "mvCommon.h"
  29427. +
  29428. +
  29429. +/*******************************************************************************
  29430. +* mvMacStrToHex - Convert MAC format string to hex.
  29431. +*
  29432. +* DESCRIPTION:
  29433. +* This function convert MAC format string to hex.
  29434. +*
  29435. +* INPUT:
  29436. +* macStr - MAC address string. Fornat of address string is
  29437. +* uu:vv:ww:xx:yy:zz, where ":" can be any delimiter.
  29438. +*
  29439. +* OUTPUT:
  29440. +* macHex - MAC in hex format.
  29441. +*
  29442. +* RETURN:
  29443. +* None.
  29444. +*
  29445. +*******************************************************************************/
  29446. +MV_STATUS mvMacStrToHex(const char* macStr, MV_U8* macHex)
  29447. +{
  29448. + int i;
  29449. + char tmp[3];
  29450. +
  29451. + for(i = 0; i < MV_MAC_ADDR_SIZE; i++)
  29452. + {
  29453. + tmp[0] = macStr[(i * 3) + 0];
  29454. + tmp[1] = macStr[(i * 3) + 1];
  29455. + tmp[2] = '\0';
  29456. + macHex[i] = (MV_U8) (strtol(tmp, NULL, 16));
  29457. + }
  29458. + return MV_OK;
  29459. +}
  29460. +
  29461. +/*******************************************************************************
  29462. +* mvMacHexToStr - Convert MAC in hex format to string format.
  29463. +*
  29464. +* DESCRIPTION:
  29465. +* This function convert MAC in hex format to string format.
  29466. +*
  29467. +* INPUT:
  29468. +* macHex - MAC in hex format.
  29469. +*
  29470. +* OUTPUT:
  29471. +* macStr - MAC address string. String format is uu:vv:ww:xx:yy:zz.
  29472. +*
  29473. +* RETURN:
  29474. +* None.
  29475. +*
  29476. +*******************************************************************************/
  29477. +MV_STATUS mvMacHexToStr(MV_U8* macHex, char* macStr)
  29478. +{
  29479. + int i;
  29480. +
  29481. + for(i = 0; i < MV_MAC_ADDR_SIZE; i++)
  29482. + {
  29483. + mvOsSPrintf(&macStr[i * 3], "%02x:", macHex[i]);
  29484. + }
  29485. + macStr[(i * 3) - 1] = '\0';
  29486. +
  29487. + return MV_OK;
  29488. +}
  29489. +
  29490. +/*******************************************************************************
  29491. +* mvSizePrint - Print the given size with size unit description.
  29492. +*
  29493. +* DESCRIPTION:
  29494. +* This function print the given size with size unit description.
  29495. +* FOr example when size paramter is 0x180000, the function prints:
  29496. +* "size 1MB+500KB"
  29497. +*
  29498. +* INPUT:
  29499. +* size - Size in bytes.
  29500. +*
  29501. +* OUTPUT:
  29502. +* None.
  29503. +*
  29504. +* RETURN:
  29505. +* None.
  29506. +*
  29507. +*******************************************************************************/
  29508. +MV_VOID mvSizePrint(MV_U32 size)
  29509. +{
  29510. + mvOsOutput("size ");
  29511. +
  29512. + if(size >= _1G)
  29513. + {
  29514. + mvOsOutput("%3dGB ", size / _1G);
  29515. + size %= _1G;
  29516. + if(size)
  29517. + mvOsOutput("+");
  29518. + }
  29519. + if(size >= _1M )
  29520. + {
  29521. + mvOsOutput("%3dMB ", size / _1M);
  29522. + size %= _1M;
  29523. + if(size)
  29524. + mvOsOutput("+");
  29525. + }
  29526. + if(size >= _1K)
  29527. + {
  29528. + mvOsOutput("%3dKB ", size / _1K);
  29529. + size %= _1K;
  29530. + if(size)
  29531. + mvOsOutput("+");
  29532. + }
  29533. + if(size > 0)
  29534. + {
  29535. + mvOsOutput("%3dB ", size);
  29536. + }
  29537. +}
  29538. +
  29539. +/*******************************************************************************
  29540. +* mvHexToBin - Convert hex to binary
  29541. +*
  29542. +* DESCRIPTION:
  29543. +* This function Convert hex to binary.
  29544. +*
  29545. +* INPUT:
  29546. +* pHexStr - hex buffer pointer.
  29547. +* size - Size to convert.
  29548. +*
  29549. +* OUTPUT:
  29550. +* pBin - Binary buffer pointer.
  29551. +*
  29552. +* RETURN:
  29553. +* None.
  29554. +*
  29555. +*******************************************************************************/
  29556. +MV_VOID mvHexToBin(const char* pHexStr, MV_U8* pBin, int size)
  29557. +{
  29558. + int j, i;
  29559. + char tmp[3];
  29560. + MV_U8 byte;
  29561. +
  29562. + for(j=0, i=0; j<size; j++, i+=2)
  29563. + {
  29564. + tmp[0] = pHexStr[i];
  29565. + tmp[1] = pHexStr[i+1];
  29566. + tmp[2] = '\0';
  29567. + byte = (MV_U8) (strtol(tmp, NULL, 16) & 0xFF);
  29568. + pBin[j] = byte;
  29569. + }
  29570. +}
  29571. +
  29572. +void mvAsciiToHex(const char* asciiStr, char* hexStr)
  29573. +{
  29574. + int i=0;
  29575. +
  29576. + while(asciiStr[i] != 0)
  29577. + {
  29578. + mvOsSPrintf(&hexStr[i*2], "%02x", asciiStr[i]);
  29579. + i++;
  29580. + }
  29581. + hexStr[i*2] = 0;
  29582. +}
  29583. +
  29584. +
  29585. +void mvBinToHex(const MV_U8* bin, char* hexStr, int size)
  29586. +{
  29587. + int i;
  29588. +
  29589. + for(i=0; i<size; i++)
  29590. + {
  29591. + mvOsSPrintf(&hexStr[i*2], "%02x", bin[i]);
  29592. + }
  29593. + hexStr[i*2] = '\0';
  29594. +}
  29595. +
  29596. +void mvBinToAscii(const MV_U8* bin, char* asciiStr, int size)
  29597. +{
  29598. + int i;
  29599. +
  29600. + for(i=0; i<size; i++)
  29601. + {
  29602. + mvOsSPrintf(&asciiStr[i*2], "%c", bin[i]);
  29603. + }
  29604. + asciiStr[i*2] = '\0';
  29605. +}
  29606. +
  29607. +/*******************************************************************************
  29608. +* mvLog2 -
  29609. +*
  29610. +* DESCRIPTION:
  29611. +* Calculate the Log2 of a given number.
  29612. +*
  29613. +* INPUT:
  29614. +* num - A number to calculate the Log2 for.
  29615. +*
  29616. +* OUTPUT:
  29617. +* None.
  29618. +*
  29619. +* RETURN:
  29620. +* Log 2 of the input number, or 0xFFFFFFFF if input is 0.
  29621. +*
  29622. +*******************************************************************************/
  29623. +MV_U32 mvLog2(MV_U32 num)
  29624. +{
  29625. + MV_U32 result = 0;
  29626. + if(num == 0)
  29627. + return 0xFFFFFFFF;
  29628. + while(num != 1)
  29629. + {
  29630. + num = num >> 1;
  29631. + result++;
  29632. + }
  29633. + return result;
  29634. +}
  29635. +
  29636. +
  29637. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mvCommon.h
  29638. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.h 1970-01-01 01:00:00.000000000 +0100
  29639. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mvCommon.h 2010-08-05 22:02:13.514035180 +0200
  29640. @@ -0,0 +1,308 @@
  29641. +/*******************************************************************************
  29642. +Copyright (C) Marvell International Ltd. and its affiliates
  29643. +
  29644. +This software file (the "File") is owned and distributed by Marvell
  29645. +International Ltd. and/or its affiliates ("Marvell") under the following
  29646. +alternative licensing terms. Once you have made an election to distribute the
  29647. +File under one of the following license alternatives, please (i) delete this
  29648. +introductory statement regarding license alternatives, (ii) delete the two
  29649. +license alternatives that you have not elected to use and (iii) preserve the
  29650. +Marvell copyright notice above.
  29651. +
  29652. +********************************************************************************
  29653. +Marvell Commercial License Option
  29654. +
  29655. +If you received this File from Marvell and you have entered into a commercial
  29656. +license agreement (a "Commercial License") with Marvell, the File is licensed
  29657. +to you under the terms of the applicable Commercial License.
  29658. +
  29659. +********************************************************************************
  29660. +Marvell GPL License Option
  29661. +
  29662. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29663. +modify this File in accordance with the terms and conditions of the General
  29664. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  29665. +available along with the File in the license.txt file or by writing to the Free
  29666. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  29667. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  29668. +
  29669. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  29670. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  29671. +DISCLAIMED. The GPL License provides additional details about this warranty
  29672. +disclaimer.
  29673. +********************************************************************************
  29674. +Marvell BSD License Option
  29675. +
  29676. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29677. +modify this File under the following licensing terms.
  29678. +Redistribution and use in source and binary forms, with or without modification,
  29679. +are permitted provided that the following conditions are met:
  29680. +
  29681. + * Redistributions of source code must retain the above copyright notice,
  29682. + this list of conditions and the following disclaimer.
  29683. +
  29684. + * Redistributions in binary form must reproduce the above copyright
  29685. + notice, this list of conditions and the following disclaimer in the
  29686. + documentation and/or other materials provided with the distribution.
  29687. +
  29688. + * Neither the name of Marvell nor the names of its contributors may be
  29689. + used to endorse or promote products derived from this software without
  29690. + specific prior written permission.
  29691. +
  29692. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  29693. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  29694. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  29695. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  29696. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  29697. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29698. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  29699. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29700. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29701. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29702. +
  29703. +*******************************************************************************/
  29704. +
  29705. +
  29706. +
  29707. +#ifndef __INCmvCommonh
  29708. +#define __INCmvCommonh
  29709. +
  29710. +#include "mvTypes.h"
  29711. +
  29712. +/* Swap tool */
  29713. +
  29714. +/* 16bit nibble swap. For example 0x1234 -> 0x2143 */
  29715. +#define MV_NIBBLE_SWAP_16BIT(X) (((X&0xf) << 4) | \
  29716. + ((X&0xf0) >> 4) | \
  29717. + ((X&0xf00) << 4) | \
  29718. + ((X&0xf000) >> 4))
  29719. +
  29720. +/* 32bit nibble swap. For example 0x12345678 -> 0x21436587 */
  29721. +#define MV_NIBBLE_SWAP_32BIT(X) (((X&0xf) << 4) | \
  29722. + ((X&0xf0) >> 4) | \
  29723. + ((X&0xf00) << 4) | \
  29724. + ((X&0xf000) >> 4) | \
  29725. + ((X&0xf0000) << 4) | \
  29726. + ((X&0xf00000) >> 4) | \
  29727. + ((X&0xf000000) << 4) | \
  29728. + ((X&0xf0000000) >> 4))
  29729. +
  29730. +/* 16bit byte swap. For example 0x1122 -> 0x2211 */
  29731. +#define MV_BYTE_SWAP_16BIT(X) ((((X)&0xff)<<8) | (((X)&0xff00)>>8))
  29732. +
  29733. +/* 32bit byte swap. For example 0x11223344 -> 0x44332211 */
  29734. +#define MV_BYTE_SWAP_32BIT(X) ((((X)&0xff)<<24) | \
  29735. + (((X)&0xff00)<<8) | \
  29736. + (((X)&0xff0000)>>8) | \
  29737. + (((X)&0xff000000)>>24))
  29738. +
  29739. +/* 64bit byte swap. For example 0x11223344.55667788 -> 0x88776655.44332211 */
  29740. +#define MV_BYTE_SWAP_64BIT(X) ((l64) ((((X)&0xffULL)<<56) | \
  29741. + (((X)&0xff00ULL)<<40) | \
  29742. + (((X)&0xff0000ULL)<<24) | \
  29743. + (((X)&0xff000000ULL)<<8) | \
  29744. + (((X)&0xff00000000ULL)>>8) | \
  29745. + (((X)&0xff0000000000ULL)>>24) | \
  29746. + (((X)&0xff000000000000ULL)>>40) | \
  29747. + (((X)&0xff00000000000000ULL)>>56)))
  29748. +
  29749. +/* Endianess macros. */
  29750. +#if defined(MV_CPU_LE)
  29751. + #define MV_16BIT_LE(X) (X)
  29752. + #define MV_32BIT_LE(X) (X)
  29753. + #define MV_64BIT_LE(X) (X)
  29754. + #define MV_16BIT_BE(X) MV_BYTE_SWAP_16BIT(X)
  29755. + #define MV_32BIT_BE(X) MV_BYTE_SWAP_32BIT(X)
  29756. + #define MV_64BIT_BE(X) MV_BYTE_SWAP_64BIT(X)
  29757. +#elif defined(MV_CPU_BE)
  29758. + #define MV_16BIT_LE(X) MV_BYTE_SWAP_16BIT(X)
  29759. + #define MV_32BIT_LE(X) MV_BYTE_SWAP_32BIT(X)
  29760. + #define MV_64BIT_LE(X) MV_BYTE_SWAP_64BIT(X)
  29761. + #define MV_16BIT_BE(X) (X)
  29762. + #define MV_32BIT_BE(X) (X)
  29763. + #define MV_64BIT_BE(X) (X)
  29764. +#else
  29765. + #error "CPU endianess isn't defined!\n"
  29766. +#endif
  29767. +
  29768. +
  29769. +/* Bit field definitions */
  29770. +#define NO_BIT 0x00000000
  29771. +#define BIT0 0x00000001
  29772. +#define BIT1 0x00000002
  29773. +#define BIT2 0x00000004
  29774. +#define BIT3 0x00000008
  29775. +#define BIT4 0x00000010
  29776. +#define BIT5 0x00000020
  29777. +#define BIT6 0x00000040
  29778. +#define BIT7 0x00000080
  29779. +#define BIT8 0x00000100
  29780. +#define BIT9 0x00000200
  29781. +#define BIT10 0x00000400
  29782. +#define BIT11 0x00000800
  29783. +#define BIT12 0x00001000
  29784. +#define BIT13 0x00002000
  29785. +#define BIT14 0x00004000
  29786. +#define BIT15 0x00008000
  29787. +#define BIT16 0x00010000
  29788. +#define BIT17 0x00020000
  29789. +#define BIT18 0x00040000
  29790. +#define BIT19 0x00080000
  29791. +#define BIT20 0x00100000
  29792. +#define BIT21 0x00200000
  29793. +#define BIT22 0x00400000
  29794. +#define BIT23 0x00800000
  29795. +#define BIT24 0x01000000
  29796. +#define BIT25 0x02000000
  29797. +#define BIT26 0x04000000
  29798. +#define BIT27 0x08000000
  29799. +#define BIT28 0x10000000
  29800. +#define BIT29 0x20000000
  29801. +#define BIT30 0x40000000
  29802. +#define BIT31 0x80000000
  29803. +
  29804. +/* Handy sizes */
  29805. +#define _1K 0x00000400
  29806. +#define _2K 0x00000800
  29807. +#define _4K 0x00001000
  29808. +#define _8K 0x00002000
  29809. +#define _16K 0x00004000
  29810. +#define _32K 0x00008000
  29811. +#define _64K 0x00010000
  29812. +#define _128K 0x00020000
  29813. +#define _256K 0x00040000
  29814. +#define _512K 0x00080000
  29815. +
  29816. +#define _1M 0x00100000
  29817. +#define _2M 0x00200000
  29818. +#define _4M 0x00400000
  29819. +#define _8M 0x00800000
  29820. +#define _16M 0x01000000
  29821. +#define _32M 0x02000000
  29822. +#define _64M 0x04000000
  29823. +#define _128M 0x08000000
  29824. +#define _256M 0x10000000
  29825. +#define _512M 0x20000000
  29826. +
  29827. +#define _1G 0x40000000
  29828. +#define _2G 0x80000000
  29829. +
  29830. +/* Tclock and Sys clock define */
  29831. +#define _100MHz 100000000
  29832. +#define _125MHz 125000000
  29833. +#define _133MHz 133333334
  29834. +#define _150MHz 150000000
  29835. +#define _160MHz 160000000
  29836. +#define _166MHz 166666667
  29837. +#define _175MHz 175000000
  29838. +#define _178MHz 178000000
  29839. +#define _183MHz 183333334
  29840. +#define _187MHz 187000000
  29841. +#define _192MHz 192000000
  29842. +#define _194MHz 194000000
  29843. +#define _200MHz 200000000
  29844. +#define _233MHz 233333334
  29845. +#define _250MHz 250000000
  29846. +#define _266MHz 266666667
  29847. +#define _300MHz 300000000
  29848. +
  29849. +/* For better address window table readability */
  29850. +#define EN MV_TRUE
  29851. +#define DIS MV_FALSE
  29852. +#define N_A -1 /* Not applicable */
  29853. +
  29854. +/* Cache configuration options for memory (DRAM, SRAM, ... ) */
  29855. +
  29856. +/* Memory uncached, HW or SW cache coherency is not needed */
  29857. +#define MV_UNCACHED 0
  29858. +/* Memory cached, HW cache coherency supported in WriteThrough mode */
  29859. +#define MV_CACHE_COHER_HW_WT 1
  29860. +/* Memory cached, HW cache coherency supported in WriteBack mode */
  29861. +#define MV_CACHE_COHER_HW_WB 2
  29862. +/* Memory cached, No HW cache coherency, Cache coherency must be in SW */
  29863. +#define MV_CACHE_COHER_SW 3
  29864. +
  29865. +
  29866. +/* Macro for testing aligment. Positive if number is NOT aligned */
  29867. +#define MV_IS_NOT_ALIGN(number, align) ((number) & ((align) - 1))
  29868. +
  29869. +/* Macro for alignment up. For example, MV_ALIGN_UP(0x0330, 0x20) = 0x0340 */
  29870. +#define MV_ALIGN_UP(number, align) \
  29871. +(((number) & ((align) - 1)) ? (((number) + (align)) & ~((align)-1)) : (number))
  29872. +
  29873. +/* Macro for alignment down. For example, MV_ALIGN_UP(0x0330, 0x20) = 0x0320 */
  29874. +#define MV_ALIGN_DOWN(number, align) ((number) & ~((align)-1))
  29875. +
  29876. +/* This macro returns absolute value */
  29877. +#define MV_ABS(number) (((int)(number) < 0) ? -(int)(number) : (int)(number))
  29878. +
  29879. +
  29880. +/* Bit fields manipulation macros */
  29881. +
  29882. +/* An integer word which its 'x' bit is set */
  29883. +#define MV_BIT_MASK(bitNum) (1 << (bitNum) )
  29884. +
  29885. +/* Checks wheter bit 'x' in integer word is set */
  29886. +#define MV_BIT_CHECK(word, bitNum) ( (word) & MV_BIT_MASK(bitNum) )
  29887. +
  29888. +/* Clear (reset) bit 'x' in integer word (RMW - Read-Modify-Write) */
  29889. +#define MV_BIT_CLEAR(word, bitNum) ( (word) &= ~(MV_BIT_MASK(bitNum)) )
  29890. +
  29891. +/* Set bit 'x' in integer word (RMW) */
  29892. +#define MV_BIT_SET(word, bitNum) ( (word) |= MV_BIT_MASK(bitNum) )
  29893. +
  29894. +/* Invert bit 'x' in integer word (RMW) */
  29895. +#define MV_BIT_INV(word, bitNum) ( (word) ^= MV_BIT_MASK(bitNum) )
  29896. +
  29897. +/* Get the min between 'a' or 'b' */
  29898. +#define MV_MIN(a,b) (((a) < (b)) ? (a) : (b))
  29899. +
  29900. +/* Get the max between 'a' or 'b' */
  29901. +#define MV_MAX(a,b) (((a) < (b)) ? (b) : (a))
  29902. +
  29903. +/* Temporary */
  29904. +#define mvOsDivide(num, div) \
  29905. +({ \
  29906. + int i=0, rem=(num); \
  29907. + \
  29908. + while(rem >= (div)) \
  29909. + { \
  29910. + rem -= (div); \
  29911. + i++; \
  29912. + } \
  29913. + (i); \
  29914. +})
  29915. +
  29916. +/* Temporary */
  29917. +#define mvOsReminder(num, div) \
  29918. +({ \
  29919. + int rem = (num); \
  29920. + \
  29921. + while(rem >= (div)) \
  29922. + rem -= (div); \
  29923. + (rem); \
  29924. +})
  29925. +
  29926. +#define MV_IP_QUAD(ipAddr) ((ipAddr >> 24) & 0xFF), ((ipAddr >> 16) & 0xFF), \
  29927. + ((ipAddr >> 8) & 0xFF), ((ipAddr >> 0) & 0xFF)
  29928. +
  29929. +#define MV_IS_POWER_OF_2(num) ((num != 0) && ((num & (num - 1)) == 0))
  29930. +
  29931. +#ifndef MV_ASMLANGUAGE
  29932. +/* mvCommon API list */
  29933. +
  29934. +MV_VOID mvHexToBin(const char* pHexStr, MV_U8* pBin, int size);
  29935. +void mvAsciiToHex(const char* asciiStr, char* hexStr);
  29936. +void mvBinToHex(const MV_U8* bin, char* hexStr, int size);
  29937. +void mvBinToAscii(const MV_U8* bin, char* asciiStr, int size);
  29938. +
  29939. +MV_STATUS mvMacStrToHex(const char* macStr, MV_U8* macHex);
  29940. +MV_STATUS mvMacHexToStr(MV_U8* macHex, char* macStr);
  29941. +void mvSizePrint(MV_U32);
  29942. +
  29943. +MV_U32 mvLog2(MV_U32 num);
  29944. +
  29945. +#endif /* MV_ASMLANGUAGE */
  29946. +
  29947. +
  29948. +#endif /* __INCmvCommonh */
  29949. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mvDebug.c
  29950. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.c 1970-01-01 01:00:00.000000000 +0100
  29951. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mvDebug.c 2010-08-05 22:02:13.693624840 +0200
  29952. @@ -0,0 +1,326 @@
  29953. +/*******************************************************************************
  29954. +Copyright (C) Marvell International Ltd. and its affiliates
  29955. +
  29956. +This software file (the "File") is owned and distributed by Marvell
  29957. +International Ltd. and/or its affiliates ("Marvell") under the following
  29958. +alternative licensing terms. Once you have made an election to distribute the
  29959. +File under one of the following license alternatives, please (i) delete this
  29960. +introductory statement regarding license alternatives, (ii) delete the two
  29961. +license alternatives that you have not elected to use and (iii) preserve the
  29962. +Marvell copyright notice above.
  29963. +
  29964. +********************************************************************************
  29965. +Marvell Commercial License Option
  29966. +
  29967. +If you received this File from Marvell and you have entered into a commercial
  29968. +license agreement (a "Commercial License") with Marvell, the File is licensed
  29969. +to you under the terms of the applicable Commercial License.
  29970. +
  29971. +********************************************************************************
  29972. +Marvell GPL License Option
  29973. +
  29974. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29975. +modify this File in accordance with the terms and conditions of the General
  29976. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  29977. +available along with the File in the license.txt file or by writing to the Free
  29978. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  29979. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  29980. +
  29981. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  29982. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  29983. +DISCLAIMED. The GPL License provides additional details about this warranty
  29984. +disclaimer.
  29985. +********************************************************************************
  29986. +Marvell BSD License Option
  29987. +
  29988. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29989. +modify this File under the following licensing terms.
  29990. +Redistribution and use in source and binary forms, with or without modification,
  29991. +are permitted provided that the following conditions are met:
  29992. +
  29993. + * Redistributions of source code must retain the above copyright notice,
  29994. + this list of conditions and the following disclaimer.
  29995. +
  29996. + * Redistributions in binary form must reproduce the above copyright
  29997. + notice, this list of conditions and the following disclaimer in the
  29998. + documentation and/or other materials provided with the distribution.
  29999. +
  30000. + * Neither the name of Marvell nor the names of its contributors may be
  30001. + used to endorse or promote products derived from this software without
  30002. + specific prior written permission.
  30003. +
  30004. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  30005. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  30006. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  30007. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  30008. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  30009. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30010. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30011. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30012. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30013. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30014. +
  30015. +*******************************************************************************/
  30016. +
  30017. +
  30018. +
  30019. +/* includes */
  30020. +#include "mvOs.h"
  30021. +#include "mv802_3.h"
  30022. +#include "mvCommon.h"
  30023. +#include "mvDebug.h"
  30024. +
  30025. +/* Global variables effect on behave MV_DEBUG_PRINT and MV_DEBUG_CODE macros
  30026. + * mvDebug - map of bits (one for each module) bit=1 means enable
  30027. + * debug code and messages for this module
  30028. + * mvModuleDebug - array of 32 bits varables one for each module
  30029. + */
  30030. +MV_U32 mvDebug = 0;
  30031. +MV_U32 mvDebugModules[MV_MODULE_MAX];
  30032. +
  30033. +/* Init mvModuleDebug array to default values */
  30034. +void mvDebugInit(void)
  30035. +{
  30036. + int bit;
  30037. +
  30038. + mvDebug = 0;
  30039. + for(bit=0; bit<MV_MODULE_MAX; bit++)
  30040. + {
  30041. + mvDebugModules[bit] = MV_DEBUG_FLAG_ERR | MV_DEBUG_FLAG_STATS;
  30042. + mvDebug |= MV_BIT_MASK(bit);
  30043. + }
  30044. +}
  30045. +
  30046. +void mvDebugModuleEnable(MV_MODULE_ID module, MV_BOOL isEnable)
  30047. +{
  30048. + if (isEnable)
  30049. + {
  30050. + MV_BIT_SET(mvDebug, module);
  30051. + }
  30052. + else
  30053. + MV_BIT_CLEAR(mvDebug, module);
  30054. +}
  30055. +
  30056. +void mvDebugModuleSetFlags(MV_MODULE_ID module, MV_U32 flags)
  30057. +{
  30058. + mvDebugModules[module] |= flags;
  30059. +}
  30060. +
  30061. +void mvDebugModuleClearFlags(MV_MODULE_ID module, MV_U32 flags)
  30062. +{
  30063. + mvDebugModules[module] &= ~flags;
  30064. +}
  30065. +
  30066. +/* Dump memory in specific format:
  30067. + * address: X1X1X1X1 X2X2X2X2 ... X8X8X8X8
  30068. + */
  30069. +void mvDebugMemDump(void* addr, int size, int access)
  30070. +{
  30071. + int i, j;
  30072. + MV_U32 memAddr = (MV_U32)addr;
  30073. +
  30074. + if(access == 0)
  30075. + access = 1;
  30076. +
  30077. + if( (access != 4) && (access != 2) && (access != 1) )
  30078. + {
  30079. + mvOsPrintf("%d wrong access size. Access must be 1 or 2 or 4\n",
  30080. + access);
  30081. + return;
  30082. + }
  30083. + memAddr = MV_ALIGN_DOWN( (unsigned int)addr, 4);
  30084. + size = MV_ALIGN_UP(size, 4);
  30085. + addr = (void*)MV_ALIGN_DOWN( (unsigned int)addr, access);
  30086. + while(size > 0)
  30087. + {
  30088. + mvOsPrintf("%08x: ", memAddr);
  30089. + i = 0;
  30090. + /* 32 bytes in the line */
  30091. + while(i < 32)
  30092. + {
  30093. + if(memAddr >= (MV_U32)addr)
  30094. + {
  30095. + switch(access)
  30096. + {
  30097. + case 1:
  30098. + if( memAddr == CPU_PHY_MEM(memAddr) )
  30099. + {
  30100. + mvOsPrintf("%02x ", MV_MEMIO8_READ(memAddr));
  30101. + }
  30102. + else
  30103. + {
  30104. + mvOsPrintf("%02x ", *((MV_U8*)memAddr));
  30105. + }
  30106. + break;
  30107. +
  30108. + case 2:
  30109. + if( memAddr == CPU_PHY_MEM(memAddr) )
  30110. + {
  30111. + mvOsPrintf("%04x ", MV_MEMIO16_READ(memAddr));
  30112. + }
  30113. + else
  30114. + {
  30115. + mvOsPrintf("%04x ", *((MV_U16*)memAddr));
  30116. + }
  30117. + break;
  30118. +
  30119. + case 4:
  30120. + if( memAddr == CPU_PHY_MEM(memAddr) )
  30121. + {
  30122. + mvOsPrintf("%08x ", MV_MEMIO32_READ(memAddr));
  30123. + }
  30124. + else
  30125. + {
  30126. + mvOsPrintf("%08x ", *((MV_U32*)memAddr));
  30127. + }
  30128. + break;
  30129. + }
  30130. + }
  30131. + else
  30132. + {
  30133. + for(j=0; j<(access*2+1); j++)
  30134. + mvOsPrintf(" ");
  30135. + }
  30136. + i += access;
  30137. + memAddr += access;
  30138. + size -= access;
  30139. + if(size <= 0)
  30140. + break;
  30141. + }
  30142. + mvOsPrintf("\n");
  30143. + }
  30144. +}
  30145. +
  30146. +void mvDebugPrintBufInfo(BUF_INFO* pBufInfo, int size, int access)
  30147. +{
  30148. + if(pBufInfo == NULL)
  30149. + {
  30150. + mvOsPrintf("\n!!! pBufInfo = NULL\n");
  30151. + return;
  30152. + }
  30153. + mvOsPrintf("\n*** pBufInfo=0x%x, cmdSts=0x%08x, pBuf=0x%x, bufSize=%d\n",
  30154. + (unsigned int)pBufInfo,
  30155. + (unsigned int)pBufInfo->cmdSts,
  30156. + (unsigned int)pBufInfo->pBuff,
  30157. + (unsigned int)pBufInfo->bufSize);
  30158. + mvOsPrintf("pData=0x%x, byteCnt=%d, pNext=0x%x, uInfo1=0x%x, uInfo2=0x%x\n",
  30159. + (unsigned int)pBufInfo->pData,
  30160. + (unsigned int)pBufInfo->byteCnt,
  30161. + (unsigned int)pBufInfo->pNextBufInfo,
  30162. + (unsigned int)pBufInfo->userInfo1,
  30163. + (unsigned int)pBufInfo->userInfo2);
  30164. + if(pBufInfo->pData != NULL)
  30165. + {
  30166. + if(size > pBufInfo->byteCnt)
  30167. + size = pBufInfo->byteCnt;
  30168. + mvDebugMemDump(pBufInfo->pData, size, access);
  30169. + }
  30170. +}
  30171. +
  30172. +void mvDebugPrintPktInfo(MV_PKT_INFO* pPktInfo, int size, int access)
  30173. +{
  30174. + int frag, len;
  30175. +
  30176. + if(pPktInfo == NULL)
  30177. + {
  30178. + mvOsPrintf("\n!!! pPktInfo = NULL\n");
  30179. + return;
  30180. + }
  30181. + mvOsPrintf("\npPkt=%p, stat=0x%08x, numFr=%d, size=%d, pFr=%p, osInfo=0x%lx\n",
  30182. + pPktInfo, pPktInfo->status, pPktInfo->numFrags, pPktInfo->pktSize,
  30183. + pPktInfo->pFrags, pPktInfo->osInfo);
  30184. +
  30185. + for(frag=0; frag<pPktInfo->numFrags; frag++)
  30186. + {
  30187. + mvOsPrintf("#%2d. bufVirt=%p, bufSize=%d\n",
  30188. + frag, pPktInfo->pFrags[frag].bufVirtPtr,
  30189. + pPktInfo->pFrags[frag].bufSize);
  30190. + if(size > 0)
  30191. + {
  30192. + len = MV_MIN((int)pPktInfo->pFrags[frag].bufSize, size);
  30193. + mvDebugMemDump(pPktInfo->pFrags[frag].bufVirtPtr, len, access);
  30194. + size -= len;
  30195. + }
  30196. + }
  30197. +
  30198. +}
  30199. +
  30200. +void mvDebugPrintIpAddr(MV_U32 ipAddr)
  30201. +{
  30202. + mvOsPrintf("%d.%d.%d.%d", ((ipAddr >> 24) & 0xFF), ((ipAddr >> 16) & 0xFF),
  30203. + ((ipAddr >> 8) & 0xFF), ((ipAddr >> 0) & 0xFF));
  30204. +}
  30205. +
  30206. +void mvDebugPrintMacAddr(const MV_U8* pMacAddr)
  30207. +{
  30208. + int i;
  30209. +
  30210. + mvOsPrintf("%02x", (unsigned int)pMacAddr[0]);
  30211. + for(i=1; i<MV_MAC_ADDR_SIZE; i++)
  30212. + {
  30213. + mvOsPrintf(":%02x", pMacAddr[i]);
  30214. + }
  30215. + /* mvOsPrintf("\n");*/
  30216. +}
  30217. +
  30218. +
  30219. +/******* There are three functions deals with MV_DEBUG_TIMES structure ********/
  30220. +
  30221. +/* Reset MV_DEBUG_TIMES entry */
  30222. +void mvDebugResetTimeEntry(MV_DEBUG_TIMES* pTimeEntry, int count, char* pName)
  30223. +{
  30224. + pTimeEntry->begin = 0;
  30225. + pTimeEntry->count = count;
  30226. + pTimeEntry->end = 0;
  30227. + pTimeEntry->left = pTimeEntry->count;
  30228. + pTimeEntry->total = 0;
  30229. + pTimeEntry->min = 0xFFFFFFFF;
  30230. + pTimeEntry->max = 0x0;
  30231. + strncpy(pTimeEntry->name, pName, sizeof(pTimeEntry->name)-1);
  30232. + pTimeEntry->name[sizeof(pTimeEntry->name)-1] = '\0';
  30233. +}
  30234. +
  30235. +/* Print out MV_DEBUG_TIMES entry */
  30236. +void mvDebugPrintTimeEntry(MV_DEBUG_TIMES* pTimeEntry, MV_BOOL isTitle)
  30237. +{
  30238. + int num;
  30239. +
  30240. + if(isTitle == MV_TRUE)
  30241. + mvOsPrintf("Event NumOfEvents TotalTime Average Min Max\n");
  30242. +
  30243. + num = pTimeEntry->count-pTimeEntry->left;
  30244. + if(num > 0)
  30245. + {
  30246. + mvOsPrintf("%-11s %6u 0x%08lx %6lu %6lu %6lu\n",
  30247. + pTimeEntry->name, num, pTimeEntry->total, pTimeEntry->total/num,
  30248. + pTimeEntry->min, pTimeEntry->max);
  30249. + }
  30250. +}
  30251. +
  30252. +/* Update MV_DEBUG_TIMES entry */
  30253. +void mvDebugUpdateTimeEntry(MV_DEBUG_TIMES* pTimeEntry)
  30254. +{
  30255. + MV_U32 delta;
  30256. +
  30257. + if(pTimeEntry->left > 0)
  30258. + {
  30259. + if(pTimeEntry->end <= pTimeEntry->begin)
  30260. + {
  30261. + delta = pTimeEntry->begin - pTimeEntry->end;
  30262. + }
  30263. + else
  30264. + {
  30265. + delta = ((MV_U32)0x10000 - pTimeEntry->end) + pTimeEntry->begin;
  30266. + }
  30267. + pTimeEntry->total += delta;
  30268. +
  30269. + if(delta < pTimeEntry->min)
  30270. + pTimeEntry->min = delta;
  30271. +
  30272. + if(delta > pTimeEntry->max)
  30273. + pTimeEntry->max = delta;
  30274. +
  30275. + pTimeEntry->left--;
  30276. + }
  30277. +}
  30278. +
  30279. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mvDebug.h
  30280. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.h 1970-01-01 01:00:00.000000000 +0100
  30281. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mvDebug.h 2010-08-05 22:02:13.833624989 +0200
  30282. @@ -0,0 +1,178 @@
  30283. +/*******************************************************************************
  30284. +Copyright (C) Marvell International Ltd. and its affiliates
  30285. +
  30286. +This software file (the "File") is owned and distributed by Marvell
  30287. +International Ltd. and/or its affiliates ("Marvell") under the following
  30288. +alternative licensing terms. Once you have made an election to distribute the
  30289. +File under one of the following license alternatives, please (i) delete this
  30290. +introductory statement regarding license alternatives, (ii) delete the two
  30291. +license alternatives that you have not elected to use and (iii) preserve the
  30292. +Marvell copyright notice above.
  30293. +
  30294. +********************************************************************************
  30295. +Marvell Commercial License Option
  30296. +
  30297. +If you received this File from Marvell and you have entered into a commercial
  30298. +license agreement (a "Commercial License") with Marvell, the File is licensed
  30299. +to you under the terms of the applicable Commercial License.
  30300. +
  30301. +********************************************************************************
  30302. +Marvell GPL License Option
  30303. +
  30304. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30305. +modify this File in accordance with the terms and conditions of the General
  30306. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  30307. +available along with the File in the license.txt file or by writing to the Free
  30308. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  30309. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  30310. +
  30311. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  30312. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  30313. +DISCLAIMED. The GPL License provides additional details about this warranty
  30314. +disclaimer.
  30315. +********************************************************************************
  30316. +Marvell BSD License Option
  30317. +
  30318. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30319. +modify this File under the following licensing terms.
  30320. +Redistribution and use in source and binary forms, with or without modification,
  30321. +are permitted provided that the following conditions are met:
  30322. +
  30323. + * Redistributions of source code must retain the above copyright notice,
  30324. + this list of conditions and the following disclaimer.
  30325. +
  30326. + * Redistributions in binary form must reproduce the above copyright
  30327. + notice, this list of conditions and the following disclaimer in the
  30328. + documentation and/or other materials provided with the distribution.
  30329. +
  30330. + * Neither the name of Marvell nor the names of its contributors may be
  30331. + used to endorse or promote products derived from this software without
  30332. + specific prior written permission.
  30333. +
  30334. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  30335. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  30336. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  30337. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  30338. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  30339. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30340. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30341. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30342. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30343. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30344. +
  30345. +*******************************************************************************/
  30346. +
  30347. +
  30348. +
  30349. +#ifndef __INCmvDebugh
  30350. +#define __INCmvDebugh
  30351. +
  30352. +/* includes */
  30353. +#include "mvTypes.h"
  30354. +
  30355. +typedef enum
  30356. +{
  30357. + MV_MODULE_INVALID = -1,
  30358. + MV_MODULE_ETH = 0,
  30359. + MV_MODULE_IDMA,
  30360. + MV_MODULE_XOR,
  30361. + MV_MODULE_TWASI,
  30362. + MV_MODULE_MGI,
  30363. + MV_MODULE_USB,
  30364. + MV_MODULE_CESA,
  30365. +
  30366. + MV_MODULE_MAX
  30367. +}MV_MODULE_ID;
  30368. +
  30369. +/* Define generic flags useful for most of modules */
  30370. +#define MV_DEBUG_FLAG_ALL (0)
  30371. +#define MV_DEBUG_FLAG_INIT (1 << 0)
  30372. +#define MV_DEBUG_FLAG_RX (1 << 1)
  30373. +#define MV_DEBUG_FLAG_TX (1 << 2)
  30374. +#define MV_DEBUG_FLAG_ERR (1 << 3)
  30375. +#define MV_DEBUG_FLAG_TRACE (1 << 4)
  30376. +#define MV_DEBUG_FLAG_DUMP (1 << 5)
  30377. +#define MV_DEBUG_FLAG_CACHE (1 << 6)
  30378. +#define MV_DEBUG_FLAG_IOCTL (1 << 7)
  30379. +#define MV_DEBUG_FLAG_STATS (1 << 8)
  30380. +
  30381. +extern MV_U32 mvDebug;
  30382. +extern MV_U32 mvDebugModules[MV_MODULE_MAX];
  30383. +
  30384. +#ifdef MV_DEBUG
  30385. +# define MV_DEBUG_PRINT(module, flags, msg) mvOsPrintf msg
  30386. +# define MV_DEBUG_CODE(module, flags, code) code
  30387. +#elif defined(MV_RT_DEBUG)
  30388. +# define MV_DEBUG_PRINT(module, flags, msg) \
  30389. + if( (mvDebug & (1<<(module))) && \
  30390. + ((mvDebugModules[(module)] & (flags)) == (flags)) ) \
  30391. + mvOsPrintf msg
  30392. +# define MV_DEBUG_CODE(module, flags, code) \
  30393. + if( (mvDebug & (1<<(module))) && \
  30394. + ((mvDebugModules[(module)] & (flags)) == (flags)) ) \
  30395. + code
  30396. +#else
  30397. +# define MV_DEBUG_PRINT(module, flags, msg)
  30398. +# define MV_DEBUG_CODE(module, flags, code)
  30399. +#endif
  30400. +
  30401. +
  30402. +
  30403. +/* typedefs */
  30404. +
  30405. +/* time measurement structure used to check how much time pass between
  30406. + * two points
  30407. + */
  30408. +typedef struct {
  30409. + char name[20]; /* name of the entry */
  30410. + unsigned long begin; /* time measured on begin point */
  30411. + unsigned long end; /* time measured on end point */
  30412. + unsigned long total; /* Accumulated time */
  30413. + unsigned long left; /* The rest measurement actions */
  30414. + unsigned long count; /* Maximum measurement actions */
  30415. + unsigned long min; /* Minimum time from begin to end */
  30416. + unsigned long max; /* Maximum time from begin to end */
  30417. +} MV_DEBUG_TIMES;
  30418. +
  30419. +
  30420. +/* mvDebug.h API list */
  30421. +
  30422. +/****** Error Recording ******/
  30423. +
  30424. +/* Dump memory in specific format:
  30425. + * address: X1X1X1X1 X2X2X2X2 ... X8X8X8X8
  30426. + */
  30427. +void mvDebugMemDump(void* addr, int size, int access);
  30428. +
  30429. +void mvDebugPrintBufInfo(BUF_INFO* pBufInfo, int size, int access);
  30430. +
  30431. +void mvDebugPrintPktInfo(MV_PKT_INFO* pPktInfo, int size, int access);
  30432. +
  30433. +void mvDebugPrintIpAddr(MV_U32 ipAddr);
  30434. +
  30435. +void mvDebugPrintMacAddr(const MV_U8* pMacAddr);
  30436. +
  30437. +/**** There are three functions deals with MV_DEBUG_TIMES structure ****/
  30438. +
  30439. +/* Reset MV_DEBUG_TIMES entry */
  30440. +void mvDebugResetTimeEntry(MV_DEBUG_TIMES* pTimeEntry, int count, char* name);
  30441. +
  30442. +/* Update MV_DEBUG_TIMES entry */
  30443. +void mvDebugUpdateTimeEntry(MV_DEBUG_TIMES* pTimeEntry);
  30444. +
  30445. +/* Print out MV_DEBUG_TIMES entry */
  30446. +void mvDebugPrintTimeEntry(MV_DEBUG_TIMES* pTimeEntry, MV_BOOL isTitle);
  30447. +
  30448. +
  30449. +/******** General ***********/
  30450. +
  30451. +/* Change value of mvDebugPrint global variable */
  30452. +
  30453. +void mvDebugInit(void);
  30454. +void mvDebugModuleEnable(MV_MODULE_ID module, MV_BOOL isEnable);
  30455. +void mvDebugModuleSetFlags(MV_MODULE_ID module, MV_U32 flags);
  30456. +void mvDebugModuleClearFlags(MV_MODULE_ID module, MV_U32 flags);
  30457. +
  30458. +
  30459. +#endif /* __INCmvDebug.h */
  30460. +
  30461. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h
  30462. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h 1970-01-01 01:00:00.000000000 +0100
  30463. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h 2010-08-05 22:02:14.043624933 +0200
  30464. @@ -0,0 +1,225 @@
  30465. +/*******************************************************************************
  30466. +Copyright (C) Marvell International Ltd. and its affiliates
  30467. +
  30468. +This software file (the "File") is owned and distributed by Marvell
  30469. +International Ltd. and/or its affiliates ("Marvell") under the following
  30470. +alternative licensing terms. Once you have made an election to distribute the
  30471. +File under one of the following license alternatives, please (i) delete this
  30472. +introductory statement regarding license alternatives, (ii) delete the two
  30473. +license alternatives that you have not elected to use and (iii) preserve the
  30474. +Marvell copyright notice above.
  30475. +
  30476. +********************************************************************************
  30477. +Marvell Commercial License Option
  30478. +
  30479. +If you received this File from Marvell and you have entered into a commercial
  30480. +license agreement (a "Commercial License") with Marvell, the File is licensed
  30481. +to you under the terms of the applicable Commercial License.
  30482. +
  30483. +********************************************************************************
  30484. +Marvell GPL License Option
  30485. +
  30486. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30487. +modify this File in accordance with the terms and conditions of the General
  30488. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  30489. +available along with the File in the license.txt file or by writing to the Free
  30490. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  30491. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  30492. +
  30493. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  30494. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  30495. +DISCLAIMED. The GPL License provides additional details about this warranty
  30496. +disclaimer.
  30497. +********************************************************************************
  30498. +Marvell BSD License Option
  30499. +
  30500. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30501. +modify this File under the following licensing terms.
  30502. +Redistribution and use in source and binary forms, with or without modification,
  30503. +are permitted provided that the following conditions are met:
  30504. +
  30505. + * Redistributions of source code must retain the above copyright notice,
  30506. + this list of conditions and the following disclaimer.
  30507. +
  30508. + * Redistributions in binary form must reproduce the above copyright
  30509. + notice, this list of conditions and the following disclaimer in the
  30510. + documentation and/or other materials provided with the distribution.
  30511. +
  30512. + * Neither the name of Marvell nor the names of its contributors may be
  30513. + used to endorse or promote products derived from this software without
  30514. + specific prior written permission.
  30515. +
  30516. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  30517. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  30518. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  30519. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  30520. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  30521. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30522. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30523. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30524. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30525. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30526. +
  30527. +*******************************************************************************/
  30528. +
  30529. +#ifndef __INCmvDeviceIdh
  30530. +#define __INCmvDeviceIdh
  30531. +
  30532. +#ifdef __cplusplus
  30533. +extern "C" {
  30534. +#endif /* __cplusplus */
  30535. +
  30536. +/* defines */
  30537. +#define MARVELL_VEN_ID 0x11ab
  30538. +
  30539. +/* Disco-3 */
  30540. +#define MV64460_DEV_ID 0x6480
  30541. +#define MV64460B_DEV_ID 0x6485
  30542. +#define MV64430_DEV_ID 0x6420
  30543. +
  30544. +/* Disco-5 */
  30545. +#define MV64560_DEV_ID 0x6450
  30546. +
  30547. +/* Disco-6 */
  30548. +#define MV64660_DEV_ID 0x6460
  30549. +
  30550. +/* Orion */
  30551. +#define MV_1181_DEV_ID 0x1181
  30552. +#define MV_5181_DEV_ID 0x5181
  30553. +#define MV_5281_DEV_ID 0x5281
  30554. +#define MV_5182_DEV_ID 0x5182
  30555. +#define MV_8660_DEV_ID 0x8660
  30556. +#define MV_5180_DEV_ID 0x5180
  30557. +#define MV_5082_DEV_ID 0x5082
  30558. +#define MV_1281_DEV_ID 0x1281
  30559. +#define MV_6082_DEV_ID 0x6082
  30560. +#define MV_6183_DEV_ID 0x6183
  30561. +#define MV_6183L_DEV_ID 0x6083
  30562. +
  30563. +#define MV_5281_D0_REV 0x4
  30564. +#define MV_5281_D0_ID ((MV_5281_DEV_ID << 16) | MV_5281_D0_REV)
  30565. +#define MV_5281_D0_NAME "88F5281 D0"
  30566. +
  30567. +#define MV_5281_D1_REV 0x5
  30568. +#define MV_5281_D1_ID ((MV_5281_DEV_ID << 16) | MV_5281_D1_REV)
  30569. +#define MV_5281_D1_NAME "88F5281 D1"
  30570. +
  30571. +#define MV_5281_D2_REV 0x6
  30572. +#define MV_5281_D2_ID ((MV_5281_DEV_ID << 16) | MV_5281_D2_REV)
  30573. +#define MV_5281_D2_NAME "88F5281 D2"
  30574. +
  30575. +
  30576. +#define MV_5181L_A0_REV 0x8 /* need for PCIE Er */
  30577. +#define MV_5181_A1_REV 0x1 /* for USB Er ..*/
  30578. +#define MV_5181_B0_REV 0x2
  30579. +#define MV_5181_B1_REV 0x3
  30580. +#define MV_5182_A1_REV 0x1
  30581. +#define MV_5180N_B1_REV 0x3
  30582. +#define MV_5181L_A0_ID ((MV_5181_DEV_ID << 16) | MV_5181L_A0_REV)
  30583. +
  30584. +
  30585. +
  30586. +/* kw */
  30587. +#define MV_6281_DEV_ID 0x6281
  30588. +#define MV_6192_DEV_ID 0x6192
  30589. +#define MV_6190_DEV_ID 0x6190
  30590. +#define MV_6180_DEV_ID 0x6180
  30591. +
  30592. +#define MV_6281_A0_REV 0x2
  30593. +#define MV_6281_A0_ID ((MV_6281_DEV_ID << 16) | MV_6281_A0_REV)
  30594. +#define MV_6281_A0_NAME "88F6281 A0"
  30595. +
  30596. +#define MV_6192_A0_REV 0x2
  30597. +#define MV_6192_A0_ID ((MV_6192_DEV_ID << 16) | MV_6192_A0_REV)
  30598. +#define MV_6192_A0_NAME "88F6192 A0"
  30599. +
  30600. +#define MV_6190_A0_REV 0x2
  30601. +#define MV_6190_A0_ID ((MV_6190_DEV_ID << 16) | MV_6190_A0_REV)
  30602. +#define MV_6190_A0_NAME "88F6190 A0"
  30603. +
  30604. +#define MV_6180_A0_REV 0x2
  30605. +#define MV_6180_A0_ID ((MV_6180_DEV_ID << 16) | MV_6180_A0_REV)
  30606. +#define MV_6180_A0_NAME "88F6180 A0"
  30607. +
  30608. +#define MV_6281_A1_REV 0x3
  30609. +#define MV_6281_A1_ID ((MV_6281_DEV_ID << 16) | MV_6281_A1_REV)
  30610. +#define MV_6281_A1_NAME "88F6281 A1"
  30611. +
  30612. +#define MV_6192_A1_REV 0x3
  30613. +#define MV_6192_A1_ID ((MV_6192_DEV_ID << 16) | MV_6192_A1_REV)
  30614. +#define MV_6192_A1_NAME "88F6192 A1"
  30615. +
  30616. +#define MV_6190_A1_REV 0x3
  30617. +#define MV_6190_A1_ID ((MV_6190_DEV_ID << 16) | MV_6190_A1_REV)
  30618. +#define MV_6190_A1_NAME "88F6190 A1"
  30619. +
  30620. +#define MV_6180_A1_REV 0x3
  30621. +#define MV_6180_A1_ID ((MV_6180_DEV_ID << 16) | MV_6180_A1_REV)
  30622. +#define MV_6180_A1_NAME "88F6180 A1"
  30623. +
  30624. +#define MV_88F6XXX_A0_REV 0x2
  30625. +#define MV_88F6XXX_A1_REV 0x3
  30626. +/* Disco-Duo */
  30627. +#define MV_78XX0_ZY_DEV_ID 0x6381
  30628. +#define MV_78XX0_ZY_NAME "MV78X00"
  30629. +
  30630. +#define MV_78XX0_Z0_REV 0x1
  30631. +#define MV_78XX0_Z0_ID ((MV_78XX0_ZY_DEV_ID << 16) | MV_78XX0_Z0_REV)
  30632. +#define MV_78XX0_Z0_NAME "78X00 Z0"
  30633. +
  30634. +#define MV_78XX0_Y0_REV 0x2
  30635. +#define MV_78XX0_Y0_ID ((MV_78XX0_ZY_DEV_ID << 16) | MV_78XX0_Y0_REV)
  30636. +#define MV_78XX0_Y0_NAME "78X00 Y0"
  30637. +
  30638. +#define MV_78XX0_DEV_ID 0x7800
  30639. +#define MV_78XX0_NAME "MV78X00"
  30640. +
  30641. +#define MV_76100_DEV_ID 0x7610
  30642. +#define MV_78200_DEV_ID 0x7820
  30643. +#define MV_78100_DEV_ID 0x7810
  30644. +#define MV_78XX0_A0_REV 0x1
  30645. +#define MV_78XX0_A1_REV 0x2
  30646. +
  30647. +#define MV_76100_NAME "MV76100"
  30648. +#define MV_78100_NAME "MV78100"
  30649. +#define MV_78200_NAME "MV78200"
  30650. +
  30651. +#define MV_76100_A0_ID ((MV_76100_DEV_ID << 16) | MV_78XX0_A0_REV)
  30652. +#define MV_78100_A0_ID ((MV_78100_DEV_ID << 16) | MV_78XX0_A0_REV)
  30653. +#define MV_78200_A0_ID ((MV_78200_DEV_ID << 16) | MV_78XX0_A0_REV)
  30654. +
  30655. +#define MV_76100_A1_ID ((MV_76100_DEV_ID << 16) | MV_78XX0_A1_REV)
  30656. +#define MV_78100_A1_ID ((MV_78100_DEV_ID << 16) | MV_78XX0_A1_REV)
  30657. +#define MV_78200_A1_ID ((MV_78200_DEV_ID << 16) | MV_78XX0_A1_REV)
  30658. +
  30659. +#define MV_76100_A0_NAME "MV76100 A0"
  30660. +#define MV_78100_A0_NAME "MV78100 A0"
  30661. +#define MV_78200_A0_NAME "MV78200 A0"
  30662. +#define MV_78XX0_A0_NAME "MV78XX0 A0"
  30663. +
  30664. +#define MV_76100_A1_NAME "MV76100 A1"
  30665. +#define MV_78100_A1_NAME "MV78100 A1"
  30666. +#define MV_78200_A1_NAME "MV78200 A1"
  30667. +#define MV_78XX0_A1_NAME "MV78XX0 A1"
  30668. +
  30669. +/*MV88F632X family*/
  30670. +#define MV_6321_DEV_ID 0x6321
  30671. +#define MV_6322_DEV_ID 0x6322
  30672. +#define MV_6323_DEV_ID 0x6323
  30673. +
  30674. +#define MV_6321_NAME "88F6321"
  30675. +#define MV_6322_NAME "88F6322"
  30676. +#define MV_6323_NAME "88F6323"
  30677. +
  30678. +#define MV_632X_A1_REV 0x2
  30679. +
  30680. +#define MV_6321_A1_ID ((MV_6321_DEV_ID << 16) | MV_632X_A1_REV)
  30681. +#define MV_6322_A1_ID ((MV_6322_DEV_ID << 16) | MV_632X_A1_REV)
  30682. +#define MV_6323_A1_ID ((MV_6323_DEV_ID << 16) | MV_632X_A1_REV)
  30683. +
  30684. +#define MV_6321_A1_NAME "88F6321 A1"
  30685. +#define MV_6322_A1_NAME "88F6322 A1"
  30686. +#define MV_6323_A1_NAME "88F6323 A1"
  30687. +
  30688. +
  30689. +#endif /* __INCmvDeviceIdh */
  30690. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h
  30691. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h 1970-01-01 01:00:00.000000000 +0100
  30692. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h 2010-08-05 22:02:14.524868483 +0200
  30693. @@ -0,0 +1,73 @@
  30694. +/*******************************************************************************
  30695. +Copyright (C) Marvell International Ltd. and its affiliates
  30696. +
  30697. +This software file (the "File") is owned and distributed by Marvell
  30698. +International Ltd. and/or its affiliates ("Marvell") under the following
  30699. +alternative licensing terms. Once you have made an election to distribute the
  30700. +File under one of the following license alternatives, please (i) delete this
  30701. +introductory statement regarding license alternatives, (ii) delete the two
  30702. +license alternatives that you have not elected to use and (iii) preserve the
  30703. +Marvell copyright notice above.
  30704. +
  30705. +********************************************************************************
  30706. +Marvell Commercial License Option
  30707. +
  30708. +If you received this File from Marvell and you have entered into a commercial
  30709. +license agreement (a "Commercial License") with Marvell, the File is licensed
  30710. +to you under the terms of the applicable Commercial License.
  30711. +
  30712. +********************************************************************************
  30713. +Marvell GPL License Option
  30714. +
  30715. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30716. +modify this File in accordance with the terms and conditions of the General
  30717. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  30718. +available along with the File in the license.txt file or by writing to the Free
  30719. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  30720. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  30721. +
  30722. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  30723. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  30724. +DISCLAIMED. The GPL License provides additional details about this warranty
  30725. +disclaimer.
  30726. +********************************************************************************
  30727. +Marvell BSD License Option
  30728. +
  30729. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30730. +modify this File under the following licensing terms.
  30731. +Redistribution and use in source and binary forms, with or without modification,
  30732. +are permitted provided that the following conditions are met:
  30733. +
  30734. + * Redistributions of source code must retain the above copyright notice,
  30735. + this list of conditions and the following disclaimer.
  30736. +
  30737. + * Redistributions in binary form must reproduce the above copyright
  30738. + notice, this list of conditions and the following disclaimer in the
  30739. + documentation and/or other materials provided with the distribution.
  30740. +
  30741. + * Neither the name of Marvell nor the names of its contributors may be
  30742. + used to endorse or promote products derived from this software without
  30743. + specific prior written permission.
  30744. +
  30745. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  30746. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  30747. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  30748. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  30749. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  30750. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30751. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30752. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30753. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30754. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30755. +
  30756. +*******************************************************************************/
  30757. +
  30758. +
  30759. +#ifndef __INCmvHalVerh
  30760. +#define __INCmvHalVerh
  30761. +
  30762. +/* Defines */
  30763. +#define MV_HAL_VERSION "FEROCEON_HAL_3_1_7"
  30764. +#define MV_RELEASE_BASELINE "SoCandControllers_FEROCEON_RELEASE_7_9_2009_KW_4_3_4_DD_2_1_4_6183_1_1_4"
  30765. +
  30766. +#endif /* __INCmvHalVerh */
  30767. \ No newline at end of file
  30768. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mvStack.c
  30769. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.c 1970-01-01 01:00:00.000000000 +0100
  30770. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mvStack.c 2010-08-05 22:02:14.774868276 +0200
  30771. @@ -0,0 +1,100 @@
  30772. +/*******************************************************************************
  30773. +* Copyright 2003, Marvell Semiconductor Israel LTD. *
  30774. +* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL. *
  30775. +* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT *
  30776. +* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE *
  30777. +* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL. *
  30778. +* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED, *
  30779. +* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE. *
  30780. +* *
  30781. +* MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES, *
  30782. +* MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL *
  30783. +* SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K. *
  30784. +* (MJKK), MARVELL SEMICONDUCTOR ISRAEL LTD (MSIL). *
  30785. +********************************************************************************
  30786. +* mvQueue.c
  30787. +*
  30788. +* FILENAME: $Workfile: mvStack.c $
  30789. +* REVISION: $Revision: 1.1 $
  30790. +* LAST UPDATE: $Modtime: $
  30791. +*
  30792. +* DESCRIPTION:
  30793. +* This file implements simple Stack LIFO functionality.
  30794. +*******************************************************************************/
  30795. +
  30796. +/* includes */
  30797. +#include "mvOs.h"
  30798. +#include "mvTypes.h"
  30799. +#include "mvDebug.h"
  30800. +#include "mvStack.h"
  30801. +
  30802. +/* defines */
  30803. +
  30804. +
  30805. +/* Public functions */
  30806. +
  30807. +
  30808. +/* Purpose: Create new stack
  30809. + * Inputs:
  30810. + * - MV_U32 noOfElements - maximum number of elements in the stack.
  30811. + * Each element 4 bytes size
  30812. + * Return: void* - pointer to created stack.
  30813. + */
  30814. +void* mvStackCreate(int numOfElements)
  30815. +{
  30816. + MV_STACK* pStack;
  30817. + MV_U32* pStackElements;
  30818. +
  30819. + pStack = (MV_STACK*)mvOsMalloc(sizeof(MV_STACK));
  30820. + pStackElements = (MV_U32*)mvOsMalloc(numOfElements*sizeof(MV_U32));
  30821. + if( (pStack == NULL) || (pStackElements == NULL) )
  30822. + {
  30823. + mvOsPrintf("mvStack: Can't create new stack\n");
  30824. + return NULL;
  30825. + }
  30826. + memset(pStackElements, 0, numOfElements*sizeof(MV_U32));
  30827. + pStack->numOfElements = numOfElements;
  30828. + pStack->stackIdx = 0;
  30829. + pStack->stackElements = pStackElements;
  30830. +
  30831. + return pStack;
  30832. +}
  30833. +
  30834. +/* Purpose: Delete existing stack
  30835. + * Inputs:
  30836. + * - void* stackHndl - Stack handle as returned by "mvStackCreate()" function
  30837. + *
  30838. + * Return: MV_STATUS MV_NOT_FOUND - Failure. StackHandle is not valid.
  30839. + * MV_OK - Success.
  30840. + */
  30841. +MV_STATUS mvStackDelete(void* stackHndl)
  30842. +{
  30843. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  30844. +
  30845. + if( (pStack == NULL) || (pStack->stackElements == NULL) )
  30846. + return MV_NOT_FOUND;
  30847. +
  30848. + mvOsFree(pStack->stackElements);
  30849. + mvOsFree(pStack);
  30850. +
  30851. + return MV_OK;
  30852. +}
  30853. +
  30854. +
  30855. +/* PrintOut status of the stack */
  30856. +void mvStackStatus(void* stackHndl, MV_BOOL isPrintElements)
  30857. +{
  30858. + int i;
  30859. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  30860. +
  30861. + mvOsPrintf("StackHandle=%p, pElements=%p, numElements=%d, stackIdx=%d\n",
  30862. + stackHndl, pStack->stackElements, pStack->numOfElements,
  30863. + pStack->stackIdx);
  30864. + if(isPrintElements == MV_TRUE)
  30865. + {
  30866. + for(i=0; i<pStack->stackIdx; i++)
  30867. + {
  30868. + mvOsPrintf("%3d. Value=0x%x\n", i, pStack->stackElements[i]);
  30869. + }
  30870. + }
  30871. +}
  30872. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mvStack.h
  30873. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.h 1970-01-01 01:00:00.000000000 +0100
  30874. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mvStack.h 2010-08-05 22:02:14.973624080 +0200
  30875. @@ -0,0 +1,140 @@
  30876. +/*******************************************************************************
  30877. +* Copyright 2003, Marvell Semiconductor Israel LTD. *
  30878. +* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL. *
  30879. +* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT *
  30880. +* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE *
  30881. +* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL. *
  30882. +* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED, *
  30883. +* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE. *
  30884. +* *
  30885. +* MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES, *
  30886. +* MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL *
  30887. +* SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K. *
  30888. +* (MJKK), MARVELL SEMICONDUCTOR ISRAEL LTD (MSIL). *
  30889. +********************************************************************************
  30890. +* mvStack.h - Header File for :
  30891. +*
  30892. +* FILENAME: $Workfile: mvStack.h $
  30893. +* REVISION: $Revision: 1.1 $
  30894. +* LAST UPDATE: $Modtime: $
  30895. +*
  30896. +* DESCRIPTION:
  30897. +* This file defines simple Stack (LIFO) functionality.
  30898. +*
  30899. +*******************************************************************************/
  30900. +
  30901. +#ifndef __mvStack_h__
  30902. +#define __mvStack_h__
  30903. +
  30904. +
  30905. +/* includes */
  30906. +#include "mvTypes.h"
  30907. +
  30908. +
  30909. +/* defines */
  30910. +
  30911. +
  30912. +/* typedefs */
  30913. +/* Data structure describes general purpose Stack */
  30914. +typedef struct
  30915. +{
  30916. + int stackIdx;
  30917. + int numOfElements;
  30918. + MV_U32* stackElements;
  30919. +} MV_STACK;
  30920. +
  30921. +static INLINE MV_BOOL mvStackIsFull(void* stackHndl)
  30922. +{
  30923. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  30924. +
  30925. + if(pStack->stackIdx == pStack->numOfElements)
  30926. + return MV_TRUE;
  30927. +
  30928. + return MV_FALSE;
  30929. +}
  30930. +
  30931. +static INLINE MV_BOOL mvStackIsEmpty(void* stackHndl)
  30932. +{
  30933. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  30934. +
  30935. + if(pStack->stackIdx == 0)
  30936. + return MV_TRUE;
  30937. +
  30938. + return MV_FALSE;
  30939. +}
  30940. +/* Purpose: Push new element to stack
  30941. + * Inputs:
  30942. + * - void* stackHndl - Stack handle as returned by "mvStackCreate()" function.
  30943. + * - MV_U32 value - New element.
  30944. + *
  30945. + * Return: MV_STATUS MV_FULL - Failure. Stack is full.
  30946. + * MV_OK - Success. Element is put to stack.
  30947. + */
  30948. +static INLINE void mvStackPush(void* stackHndl, MV_U32 value)
  30949. +{
  30950. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  30951. +
  30952. +#ifdef MV_RT_DEBUG
  30953. + if(pStack->stackIdx == pStack->numOfElements)
  30954. + {
  30955. + mvOsPrintf("mvStackPush: Stack is FULL\n");
  30956. + return;
  30957. + }
  30958. +#endif /* MV_RT_DEBUG */
  30959. +
  30960. + pStack->stackElements[pStack->stackIdx] = value;
  30961. + pStack->stackIdx++;
  30962. +}
  30963. +
  30964. +/* Purpose: Pop element from the top of stack and copy it to "pValue"
  30965. + * Inputs:
  30966. + * - void* stackHndl - Stack handle as returned by "mvStackCreate()" function.
  30967. + * - MV_U32 value - Element in the top of stack.
  30968. + *
  30969. + * Return: MV_STATUS MV_EMPTY - Failure. Stack is empty.
  30970. + * MV_OK - Success. Element is removed from the stack and
  30971. + * copied to pValue argument
  30972. + */
  30973. +static INLINE MV_U32 mvStackPop(void* stackHndl)
  30974. +{
  30975. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  30976. +
  30977. +#ifdef MV_RT_DEBUG
  30978. + if(pStack->stackIdx == 0)
  30979. + {
  30980. + mvOsPrintf("mvStackPop: Stack is EMPTY\n");
  30981. + return 0;
  30982. + }
  30983. +#endif /* MV_RT_DEBUG */
  30984. +
  30985. + pStack->stackIdx--;
  30986. + return pStack->stackElements[pStack->stackIdx];
  30987. +}
  30988. +
  30989. +static INLINE int mvStackIndex(void* stackHndl)
  30990. +{
  30991. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  30992. +
  30993. + return pStack->stackIdx;
  30994. +}
  30995. +
  30996. +static INLINE int mvStackFreeElements(void* stackHndl)
  30997. +{
  30998. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  30999. +
  31000. + return (pStack->numOfElements - pStack->stackIdx);
  31001. +}
  31002. +
  31003. +/* mvStack.h API list */
  31004. +
  31005. +/* Create new Stack */
  31006. +void* mvStackCreate(int numOfElements);
  31007. +
  31008. +/* Delete existing stack */
  31009. +MV_STATUS mvStackDelete(void* stackHndl);
  31010. +
  31011. +/* Print status of the stack */
  31012. +void mvStackStatus(void* stackHndl, MV_BOOL isPrintElements);
  31013. +
  31014. +#endif /* __mvStack_h__ */
  31015. +
  31016. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mvTypes.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mvTypes.h
  31017. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/common/mvTypes.h 1970-01-01 01:00:00.000000000 +0100
  31018. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/common/mvTypes.h 2010-08-05 22:02:15.143620168 +0200
  31019. @@ -0,0 +1,245 @@
  31020. +/*******************************************************************************
  31021. +Copyright (C) Marvell International Ltd. and its affiliates
  31022. +
  31023. +This software file (the "File") is owned and distributed by Marvell
  31024. +International Ltd. and/or its affiliates ("Marvell") under the following
  31025. +alternative licensing terms. Once you have made an election to distribute the
  31026. +File under one of the following license alternatives, please (i) delete this
  31027. +introductory statement regarding license alternatives, (ii) delete the two
  31028. +license alternatives that you have not elected to use and (iii) preserve the
  31029. +Marvell copyright notice above.
  31030. +
  31031. +********************************************************************************
  31032. +Marvell Commercial License Option
  31033. +
  31034. +If you received this File from Marvell and you have entered into a commercial
  31035. +license agreement (a "Commercial License") with Marvell, the File is licensed
  31036. +to you under the terms of the applicable Commercial License.
  31037. +
  31038. +********************************************************************************
  31039. +Marvell GPL License Option
  31040. +
  31041. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31042. +modify this File in accordance with the terms and conditions of the General
  31043. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  31044. +available along with the File in the license.txt file or by writing to the Free
  31045. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  31046. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  31047. +
  31048. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  31049. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  31050. +DISCLAIMED. The GPL License provides additional details about this warranty
  31051. +disclaimer.
  31052. +********************************************************************************
  31053. +Marvell BSD License Option
  31054. +
  31055. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31056. +modify this File under the following licensing terms.
  31057. +Redistribution and use in source and binary forms, with or without modification,
  31058. +are permitted provided that the following conditions are met:
  31059. +
  31060. + * Redistributions of source code must retain the above copyright notice,
  31061. + this list of conditions and the following disclaimer.
  31062. +
  31063. + * Redistributions in binary form must reproduce the above copyright
  31064. + notice, this list of conditions and the following disclaimer in the
  31065. + documentation and/or other materials provided with the distribution.
  31066. +
  31067. + * Neither the name of Marvell nor the names of its contributors may be
  31068. + used to endorse or promote products derived from this software without
  31069. + specific prior written permission.
  31070. +
  31071. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  31072. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  31073. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31074. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  31075. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  31076. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  31077. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  31078. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31079. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31080. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31081. +
  31082. +*******************************************************************************/
  31083. +
  31084. +
  31085. +#ifndef __INCmvTypesh
  31086. +#define __INCmvTypesh
  31087. +
  31088. +/* Defines */
  31089. +
  31090. +/* The following is a list of Marvell status */
  31091. +#define MV_ERROR (-1)
  31092. +#define MV_OK (0x00) /* Operation succeeded */
  31093. +#define MV_FAIL (0x01) /* Operation failed */
  31094. +#define MV_BAD_VALUE (0x02) /* Illegal value (general) */
  31095. +#define MV_OUT_OF_RANGE (0x03) /* The value is out of range */
  31096. +#define MV_BAD_PARAM (0x04) /* Illegal parameter in function called */
  31097. +#define MV_BAD_PTR (0x05) /* Illegal pointer value */
  31098. +#define MV_BAD_SIZE (0x06) /* Illegal size */
  31099. +#define MV_BAD_STATE (0x07) /* Illegal state of state machine */
  31100. +#define MV_SET_ERROR (0x08) /* Set operation failed */
  31101. +#define MV_GET_ERROR (0x09) /* Get operation failed */
  31102. +#define MV_CREATE_ERROR (0x0A) /* Fail while creating an item */
  31103. +#define MV_NOT_FOUND (0x0B) /* Item not found */
  31104. +#define MV_NO_MORE (0x0C) /* No more items found */
  31105. +#define MV_NO_SUCH (0x0D) /* No such item */
  31106. +#define MV_TIMEOUT (0x0E) /* Time Out */
  31107. +#define MV_NO_CHANGE (0x0F) /* Parameter(s) is already in this value */
  31108. +#define MV_NOT_SUPPORTED (0x10) /* This request is not support */
  31109. +#define MV_NOT_IMPLEMENTED (0x11) /* Request supported but not implemented */
  31110. +#define MV_NOT_INITIALIZED (0x12) /* The item is not initialized */
  31111. +#define MV_NO_RESOURCE (0x13) /* Resource not available (memory ...) */
  31112. +#define MV_FULL (0x14) /* Item is full (Queue or table etc...) */
  31113. +#define MV_EMPTY (0x15) /* Item is empty (Queue or table etc...) */
  31114. +#define MV_INIT_ERROR (0x16) /* Error occured while INIT process */
  31115. +#define MV_HW_ERROR (0x17) /* Hardware error */
  31116. +#define MV_TX_ERROR (0x18) /* Transmit operation not succeeded */
  31117. +#define MV_RX_ERROR (0x19) /* Recieve operation not succeeded */
  31118. +#define MV_NOT_READY (0x1A) /* The other side is not ready yet */
  31119. +#define MV_ALREADY_EXIST (0x1B) /* Tried to create existing item */
  31120. +#define MV_OUT_OF_CPU_MEM (0x1C) /* Cpu memory allocation failed. */
  31121. +#define MV_NOT_STARTED (0x1D) /* Not started yet */
  31122. +#define MV_BUSY (0x1E) /* Item is busy. */
  31123. +#define MV_TERMINATE (0x1F) /* Item terminates it's work. */
  31124. +#define MV_NOT_ALIGNED (0x20) /* Wrong alignment */
  31125. +#define MV_NOT_ALLOWED (0x21) /* Operation NOT allowed */
  31126. +#define MV_WRITE_PROTECT (0x22) /* Write protected */
  31127. +
  31128. +
  31129. +#define MV_INVALID (int)(-1)
  31130. +
  31131. +#define MV_FALSE 0
  31132. +#define MV_TRUE (!(MV_FALSE))
  31133. +
  31134. +
  31135. +#ifndef NULL
  31136. +#define NULL ((void*)0)
  31137. +#endif
  31138. +
  31139. +
  31140. +#ifndef MV_ASMLANGUAGE
  31141. +/* typedefs */
  31142. +
  31143. +typedef char MV_8;
  31144. +typedef unsigned char MV_U8;
  31145. +
  31146. +typedef int MV_32;
  31147. +typedef unsigned int MV_U32;
  31148. +
  31149. +typedef short MV_16;
  31150. +typedef unsigned short MV_U16;
  31151. +
  31152. +#ifdef MV_PPC64
  31153. +typedef long MV_64;
  31154. +typedef unsigned long MV_U64;
  31155. +#else
  31156. +typedef long long MV_64;
  31157. +typedef unsigned long long MV_U64;
  31158. +#endif
  31159. +
  31160. +typedef long MV_LONG; /* 32/64 */
  31161. +typedef unsigned long MV_ULONG; /* 32/64 */
  31162. +
  31163. +typedef int MV_STATUS;
  31164. +typedef int MV_BOOL;
  31165. +typedef void MV_VOID;
  31166. +typedef float MV_FLOAT;
  31167. +
  31168. +typedef int (*MV_FUNCPTR) (void); /* ptr to function returning int */
  31169. +typedef void (*MV_VOIDFUNCPTR) (void); /* ptr to function returning void */
  31170. +typedef double (*MV_DBLFUNCPTR) (void); /* ptr to function returning double*/
  31171. +typedef float (*MV_FLTFUNCPTR) (void); /* ptr to function returning float */
  31172. +
  31173. +typedef MV_U32 MV_KHZ;
  31174. +typedef MV_U32 MV_MHZ;
  31175. +typedef MV_U32 MV_HZ;
  31176. +
  31177. +
  31178. +/* This enumerator describes the set of commands that can be applied on */
  31179. +/* an engine (e.g. IDMA, XOR). Appling a comman depends on the current */
  31180. +/* status (see MV_STATE enumerator) */
  31181. +/* Start can be applied only when status is IDLE */
  31182. +/* Stop can be applied only when status is IDLE, ACTIVE or PAUSED */
  31183. +/* Pause can be applied only when status is ACTIVE */
  31184. +/* Restart can be applied only when status is PAUSED */
  31185. +typedef enum _mvCommand
  31186. +{
  31187. + MV_START, /* Start */
  31188. + MV_STOP, /* Stop */
  31189. + MV_PAUSE, /* Pause */
  31190. + MV_RESTART /* Restart */
  31191. +} MV_COMMAND;
  31192. +
  31193. +/* This enumerator describes the set of state conditions. */
  31194. +/* Moving from one state to other is stricted. */
  31195. +typedef enum _mvState
  31196. +{
  31197. + MV_IDLE,
  31198. + MV_ACTIVE,
  31199. + MV_PAUSED,
  31200. + MV_UNDEFINED_STATE
  31201. +} MV_STATE;
  31202. +
  31203. +
  31204. +/* This structure describes address space window. Window base can be */
  31205. +/* 64 bit, window size up to 4GB */
  31206. +typedef struct _mvAddrWin
  31207. +{
  31208. + MV_U32 baseLow; /* 32bit base low */
  31209. + MV_U32 baseHigh; /* 32bit base high */
  31210. + MV_U32 size; /* 32bit size */
  31211. +}MV_ADDR_WIN;
  31212. +
  31213. +/* This binary enumerator describes protection attribute status */
  31214. +typedef enum _mvProtRight
  31215. +{
  31216. + ALLOWED, /* Protection attribute allowed */
  31217. + FORBIDDEN /* Protection attribute forbidden */
  31218. +}MV_PROT_RIGHT;
  31219. +
  31220. +/* Unified struct for Rx and Tx packet operations. The user is required to */
  31221. +/* be familier only with Tx/Rx descriptor command status. */
  31222. +typedef struct _bufInfo
  31223. +{
  31224. + MV_U32 cmdSts; /* Tx/Rx command status */
  31225. + MV_U16 byteCnt; /* Size of valid data in the buffer */
  31226. + MV_U16 bufSize; /* Total size of the buffer */
  31227. + MV_U8 *pBuff; /* Pointer to Buffer */
  31228. + MV_U8 *pData; /* Pointer to data in the Buffer */
  31229. + MV_U32 userInfo1; /* Tx/Rx attached user information 1 */
  31230. + MV_U32 userInfo2; /* Tx/Rx attached user information 2 */
  31231. + struct _bufInfo *pNextBufInfo; /* Next buffer in packet */
  31232. +} BUF_INFO;
  31233. +
  31234. +/* This structure contains information describing one of buffers
  31235. + * (fragments) they are built Ethernet packet.
  31236. + */
  31237. +typedef struct
  31238. +{
  31239. + MV_U8* bufVirtPtr;
  31240. + MV_ULONG bufPhysAddr;
  31241. + MV_U32 bufSize;
  31242. + MV_U32 dataSize;
  31243. + MV_U32 memHandle;
  31244. + MV_32 bufAddrShift;
  31245. +} MV_BUF_INFO;
  31246. +
  31247. +/* This structure contains information describing Ethernet packet.
  31248. + * The packet can be divided for few buffers (fragments)
  31249. + */
  31250. +typedef struct
  31251. +{
  31252. + MV_ULONG osInfo;
  31253. + MV_BUF_INFO *pFrags;
  31254. + MV_U32 status;
  31255. + MV_U16 pktSize;
  31256. + MV_U16 numFrags;
  31257. + MV_U32 ownerId;
  31258. + MV_U32 fragIP;
  31259. +} MV_PKT_INFO;
  31260. +
  31261. +#endif /* MV_ASMLANGUAGE */
  31262. +
  31263. +#endif /* __INCmvTypesh */
  31264. +
  31265. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/dbg-trace.c
  31266. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.c 1970-01-01 01:00:00.000000000 +0100
  31267. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/dbg-trace.c 2010-08-05 22:02:15.343645113 +0200
  31268. @@ -0,0 +1,110 @@
  31269. +#include <linux/kernel.h>
  31270. +#include <linux/slab.h>
  31271. +#include <linux/time.h>
  31272. +#include "dbg-trace.h"
  31273. +
  31274. +#define TRACE_ARR_LEN 800
  31275. +#define STR_LEN 128
  31276. +struct trace {
  31277. + struct timeval tv;
  31278. + char str[STR_LEN];
  31279. + unsigned int callback_val1;
  31280. + unsigned int callback_val2;
  31281. + char valid;
  31282. +};
  31283. +static unsigned int (*trc_callback1) (unsigned char) = NULL;
  31284. +static unsigned int (*trc_callback2) (unsigned char) = NULL;
  31285. +static unsigned char trc_param1 = 0;
  31286. +static unsigned char trc_param2 = 0;
  31287. +struct trace *trc_arr;
  31288. +static int trc_index;
  31289. +static int trc_active = 0;
  31290. +
  31291. +void TRC_START()
  31292. +{
  31293. + trc_active = 1;
  31294. +}
  31295. +
  31296. +void TRC_STOP()
  31297. +{
  31298. + trc_active = 0;
  31299. +}
  31300. +
  31301. +void TRC_INIT(void *callback1, void *callback2, unsigned char callback1_param, unsigned char callback2_param)
  31302. +{
  31303. + printk("Marvell debug tracing is on\n");
  31304. + trc_arr = (struct trace *)kmalloc(TRACE_ARR_LEN*sizeof(struct trace),GFP_KERNEL);
  31305. + if(trc_arr == NULL)
  31306. + {
  31307. + printk("Can't allocate Debug Trace buffer\n");
  31308. + return;
  31309. + }
  31310. + memset(trc_arr,0,TRACE_ARR_LEN*sizeof(struct trace));
  31311. + trc_index = 0;
  31312. + trc_callback1 = callback1;
  31313. + trc_callback2 = callback2;
  31314. + trc_param1 = callback1_param;
  31315. + trc_param2 = callback2_param;
  31316. +}
  31317. +void TRC_REC(char *fmt,...)
  31318. +{
  31319. + va_list args;
  31320. + struct trace *trc = &trc_arr[trc_index];
  31321. +
  31322. + if(trc_active == 0)
  31323. + return;
  31324. +
  31325. + do_gettimeofday(&trc->tv);
  31326. + if(trc_callback1)
  31327. + trc->callback_val1 = trc_callback1(trc_param1);
  31328. + if(trc_callback2)
  31329. + trc->callback_val2 = trc_callback2(trc_param2);
  31330. + va_start(args, fmt);
  31331. + vsprintf(trc->str,fmt,args);
  31332. + va_end(args);
  31333. + trc->valid = 1;
  31334. + if((++trc_index) == TRACE_ARR_LEN) {
  31335. + trc_index = 0;
  31336. + }
  31337. +}
  31338. +void TRC_OUTPUT(void)
  31339. +{
  31340. + int i,j;
  31341. + struct trace *p;
  31342. + printk("\n\nTrace %d items\n",TRACE_ARR_LEN);
  31343. + for(i=0,j=trc_index; i<TRACE_ARR_LEN; i++,j++) {
  31344. + if(j == TRACE_ARR_LEN)
  31345. + j = 0;
  31346. + p = &trc_arr[j];
  31347. + if(p->valid) {
  31348. + unsigned long uoffs;
  31349. + struct trace *plast;
  31350. + if(p == &trc_arr[0])
  31351. + plast = &trc_arr[TRACE_ARR_LEN-1];
  31352. + else
  31353. + plast = p-1;
  31354. + if(p->tv.tv_sec == ((plast)->tv.tv_sec))
  31355. + uoffs = (p->tv.tv_usec - ((plast)->tv.tv_usec));
  31356. + else
  31357. + uoffs = (1000000 - ((plast)->tv.tv_usec)) +
  31358. + ((p->tv.tv_sec - ((plast)->tv.tv_sec) - 1) * 1000000) +
  31359. + p->tv.tv_usec;
  31360. + printk("%03d: [+%ld usec]", j, (unsigned long)uoffs);
  31361. + if(trc_callback1)
  31362. + printk("[%u]",p->callback_val1);
  31363. + if(trc_callback2)
  31364. + printk("[%u]",p->callback_val2);
  31365. + printk(": %s",p->str);
  31366. + }
  31367. + p->valid = 0;
  31368. + }
  31369. + memset(trc_arr,0,TRACE_ARR_LEN*sizeof(struct trace));
  31370. + trc_index = 0;
  31371. +}
  31372. +void TRC_RELEASE(void)
  31373. +{
  31374. + kfree(trc_arr);
  31375. + trc_index = 0;
  31376. +}
  31377. +
  31378. +
  31379. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/dbg-trace.h
  31380. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.h 1970-01-01 01:00:00.000000000 +0100
  31381. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/dbg-trace.h 2010-08-05 22:02:15.463674719 +0200
  31382. @@ -0,0 +1,24 @@
  31383. +
  31384. +#ifndef _MV_DBG_TRCE_H_
  31385. +#define _MV_DBG_TRCE_H_
  31386. +
  31387. +#ifdef CONFIG_MV_DBG_TRACE
  31388. +void TRC_INIT(void *callback1, void *callback2,
  31389. + unsigned char callback1_param, unsigned char callback2_param);
  31390. +void TRC_REC(char *fmt,...);
  31391. +void TRC_OUTPUT(void);
  31392. +void TRC_RELEASE(void);
  31393. +void TRC_START(void);
  31394. +void TRC_STOP(void);
  31395. +
  31396. +#else
  31397. +#define TRC_INIT(x1,x2,x3,x4)
  31398. +#define TRC_REC(X...)
  31399. +#define TRC_OUTPUT()
  31400. +#define TRC_RELEASE()
  31401. +#define TRC_START()
  31402. +#define TRC_STOP()
  31403. +#endif
  31404. +
  31405. +
  31406. +#endif
  31407. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c
  31408. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c 1970-01-01 01:00:00.000000000 +0100
  31409. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c 2010-08-05 22:02:15.605467640 +0200
  31410. @@ -0,0 +1,2513 @@
  31411. +/*******************************************************************************
  31412. +Copyright (C) Marvell International Ltd. and its affiliates
  31413. +
  31414. +This software file (the "File") is owned and distributed by Marvell
  31415. +International Ltd. and/or its affiliates ("Marvell") under the following
  31416. +alternative licensing terms. Once you have made an election to distribute the
  31417. +File under one of the following license alternatives, please (i) delete this
  31418. +introductory statement regarding license alternatives, (ii) delete the two
  31419. +license alternatives that you have not elected to use and (iii) preserve the
  31420. +Marvell copyright notice above.
  31421. +
  31422. +********************************************************************************
  31423. +Marvell Commercial License Option
  31424. +
  31425. +If you received this File from Marvell and you have entered into a commercial
  31426. +license agreement (a "Commercial License") with Marvell, the File is licensed
  31427. +to you under the terms of the applicable Commercial License.
  31428. +
  31429. +********************************************************************************
  31430. +Marvell GPL License Option
  31431. +
  31432. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31433. +modify this File in accordance with the terms and conditions of the General
  31434. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  31435. +available along with the File in the license.txt file or by writing to the Free
  31436. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  31437. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  31438. +
  31439. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  31440. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  31441. +DISCLAIMED. The GPL License provides additional details about this warranty
  31442. +disclaimer.
  31443. +********************************************************************************
  31444. +Marvell BSD License Option
  31445. +
  31446. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31447. +modify this File under the following licensing terms.
  31448. +Redistribution and use in source and binary forms, with or without modification,
  31449. +are permitted provided that the following conditions are met:
  31450. +
  31451. + * Redistributions of source code must retain the above copyright notice,
  31452. + this list of conditions and the following disclaimer.
  31453. +
  31454. + * Redistributions in binary form must reproduce the above copyright
  31455. + notice, this list of conditions and the following disclaimer in the
  31456. + documentation and/or other materials provided with the distribution.
  31457. +
  31458. + * Neither the name of Marvell nor the names of its contributors may be
  31459. + used to endorse or promote products derived from this software without
  31460. + specific prior written permission.
  31461. +
  31462. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  31463. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  31464. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31465. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  31466. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  31467. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  31468. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  31469. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31470. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31471. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31472. +
  31473. +*******************************************************************************/
  31474. +
  31475. +#include "boardEnv/mvBoardEnvLib.h"
  31476. +#include "ctrlEnv/mvCtrlEnvLib.h"
  31477. +#include "ctrlEnv/sys/mvCpuIf.h"
  31478. +#include "cpu/mvCpu.h"
  31479. +#include "cntmr/mvCntmr.h"
  31480. +#include "gpp/mvGpp.h"
  31481. +#include "twsi/mvTwsi.h"
  31482. +#include "pex/mvPex.h"
  31483. +#include "device/mvDevice.h"
  31484. +#include "eth/gbe/mvEthRegs.h"
  31485. +
  31486. +/* defines */
  31487. +/* #define MV_DEBUG */
  31488. +#ifdef MV_DEBUG
  31489. + #define DB(x) x
  31490. +#else
  31491. + #define DB(x)
  31492. +#endif
  31493. +
  31494. +extern MV_CPU_ARM_CLK _cpuARMDDRCLK[];
  31495. +
  31496. +#define CODE_IN_ROM MV_FALSE
  31497. +#define CODE_IN_RAM MV_TRUE
  31498. +
  31499. +extern MV_BOARD_INFO* boardInfoTbl[];
  31500. +#define BOARD_INFO(boardId) boardInfoTbl[boardId - BOARD_ID_BASE]
  31501. +
  31502. +/* Locals */
  31503. +static MV_DEV_CS_INFO* boardGetDevEntry(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  31504. +
  31505. +MV_U32 tClkRate = -1;
  31506. +
  31507. +
  31508. +/*******************************************************************************
  31509. +* mvBoardEnvInit - Init board
  31510. +*
  31511. +* DESCRIPTION:
  31512. +* In this function the board environment take care of device bank
  31513. +* initialization.
  31514. +*
  31515. +* INPUT:
  31516. +* None.
  31517. +*
  31518. +* OUTPUT:
  31519. +* None.
  31520. +*
  31521. +* RETURN:
  31522. +* None.
  31523. +*
  31524. +*******************************************************************************/
  31525. +MV_VOID mvBoardEnvInit(MV_VOID)
  31526. +{
  31527. + MV_U32 boardId= mvBoardIdGet();
  31528. +
  31529. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  31530. + {
  31531. + mvOsPrintf("mvBoardEnvInit:Board unknown.\n");
  31532. + return;
  31533. +
  31534. + }
  31535. +
  31536. + /* Set GPP Out value */
  31537. + MV_REG_WRITE(GPP_DATA_OUT_REG(0), BOARD_INFO(boardId)->gppOutValLow);
  31538. + MV_REG_WRITE(GPP_DATA_OUT_REG(1), BOARD_INFO(boardId)->gppOutValHigh);
  31539. +
  31540. + /* set GPP polarity */
  31541. + mvGppPolaritySet(0, 0xFFFFFFFF, BOARD_INFO(boardId)->gppPolarityValLow);
  31542. + mvGppPolaritySet(1, 0xFFFFFFFF, BOARD_INFO(boardId)->gppPolarityValHigh);
  31543. +
  31544. + /* Workaround for Erratum FE-MISC-70*/
  31545. + if(mvCtrlRevGet()==MV_88F6XXX_A0_REV)
  31546. + {
  31547. + BOARD_INFO(boardId)->gppOutEnValLow &= 0xfffffffd;
  31548. + BOARD_INFO(boardId)->gppOutEnValLow |= (BOARD_INFO(boardId)->gppOutEnValHigh) & 0x00000002;
  31549. + } /*End of WA*/
  31550. +
  31551. + /* Set GPP Out Enable*/
  31552. + mvGppTypeSet(0, 0xFFFFFFFF, BOARD_INFO(boardId)->gppOutEnValLow);
  31553. + mvGppTypeSet(1, 0xFFFFFFFF, BOARD_INFO(boardId)->gppOutEnValHigh);
  31554. +
  31555. + /* Nand CE */
  31556. + MV_REG_BIT_SET(NAND_CTRL_REG, NAND_ACTCEBOOT_BIT);
  31557. +}
  31558. +
  31559. +/*******************************************************************************
  31560. +* mvBoardModelGet - Get Board model
  31561. +*
  31562. +* DESCRIPTION:
  31563. +* This function returns 16bit describing board model.
  31564. +* Board model is constructed of one byte major and minor numbers in the
  31565. +* following manner:
  31566. +*
  31567. +* INPUT:
  31568. +* None.
  31569. +*
  31570. +* OUTPUT:
  31571. +* None.
  31572. +*
  31573. +* RETURN:
  31574. +* String describing board model.
  31575. +*
  31576. +*******************************************************************************/
  31577. +MV_U16 mvBoardModelGet(MV_VOID)
  31578. +{
  31579. + return (mvBoardIdGet() >> 16);
  31580. +}
  31581. +
  31582. +/*******************************************************************************
  31583. +* mbBoardRevlGet - Get Board revision
  31584. +*
  31585. +* DESCRIPTION:
  31586. +* This function returns a 32bit describing the board revision.
  31587. +* Board revision is constructed of 4bytes. 2bytes describes major number
  31588. +* and the other 2bytes describes minor munber.
  31589. +* For example for board revision 3.4 the function will return
  31590. +* 0x00030004.
  31591. +*
  31592. +* INPUT:
  31593. +* None.
  31594. +*
  31595. +* OUTPUT:
  31596. +* None.
  31597. +*
  31598. +* RETURN:
  31599. +* String describing board model.
  31600. +*
  31601. +*******************************************************************************/
  31602. +MV_U16 mvBoardRevGet(MV_VOID)
  31603. +{
  31604. + return (mvBoardIdGet() & 0xFFFF);
  31605. +}
  31606. +
  31607. +/*******************************************************************************
  31608. +* mvBoardNameGet - Get Board name
  31609. +*
  31610. +* DESCRIPTION:
  31611. +* This function returns a string describing the board model and revision.
  31612. +* String is extracted from board I2C EEPROM.
  31613. +*
  31614. +* INPUT:
  31615. +* None.
  31616. +*
  31617. +* OUTPUT:
  31618. +* pNameBuff - Buffer to contain board name string. Minimum size 32 chars.
  31619. +*
  31620. +* RETURN:
  31621. +*
  31622. +* MV_ERROR if informantion can not be read.
  31623. +*******************************************************************************/
  31624. +MV_STATUS mvBoardNameGet(char *pNameBuff)
  31625. +{
  31626. + MV_U32 boardId= mvBoardIdGet();
  31627. +
  31628. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  31629. + {
  31630. + mvOsSPrintf (pNameBuff, "Board unknown.\n");
  31631. + return MV_ERROR;
  31632. +
  31633. + }
  31634. +
  31635. + mvOsSPrintf (pNameBuff, "%s",BOARD_INFO(boardId)->boardName);
  31636. +
  31637. + return MV_OK;
  31638. +}
  31639. +
  31640. +/*******************************************************************************
  31641. +* mvBoardIsPortInSgmii -
  31642. +*
  31643. +* DESCRIPTION:
  31644. +* This routine returns MV_TRUE for port number works in SGMII or MV_FALSE
  31645. +* For all other options.
  31646. +*
  31647. +* INPUT:
  31648. +* ethPortNum - Ethernet port number.
  31649. +*
  31650. +* OUTPUT:
  31651. +* None.
  31652. +*
  31653. +* RETURN:
  31654. +* MV_TRUE - port in SGMII.
  31655. +* MV_FALSE - other.
  31656. +*
  31657. +*******************************************************************************/
  31658. +MV_BOOL mvBoardIsPortInSgmii(MV_U32 ethPortNum)
  31659. +{
  31660. + MV_BOOL ethPortSgmiiSupport[BOARD_ETH_PORT_NUM] = MV_ETH_PORT_SGMII;
  31661. +
  31662. + if(ethPortNum >= BOARD_ETH_PORT_NUM)
  31663. + {
  31664. + mvOsPrintf ("Invalid portNo=%d\n", ethPortNum);
  31665. + return MV_FALSE;
  31666. + }
  31667. + return ethPortSgmiiSupport[ethPortNum];
  31668. +}
  31669. +
  31670. +/*******************************************************************************
  31671. +* mvBoardIsPortInGmii -
  31672. +*
  31673. +* DESCRIPTION:
  31674. +* This routine returns MV_TRUE for port number works in GMII or MV_FALSE
  31675. +* For all other options.
  31676. +*
  31677. +* INPUT:
  31678. +*
  31679. +* OUTPUT:
  31680. +* None.
  31681. +*
  31682. +* RETURN:
  31683. +* MV_TRUE - port in GMII.
  31684. +* MV_FALSE - other.
  31685. +*
  31686. +*******************************************************************************/
  31687. +MV_BOOL mvBoardIsPortInGmii(MV_VOID)
  31688. +{
  31689. + MV_U32 devClassId, devClass = 0;
  31690. + if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_AUTO)
  31691. + {
  31692. + /* Get MPP module ID */
  31693. + devClassId = mvBoarModuleTypeGet(devClass);
  31694. + if (MV_BOARD_MODULE_GMII_ID == devClassId)
  31695. + return MV_TRUE;
  31696. + }
  31697. + else if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_GMII)
  31698. + return MV_TRUE;
  31699. +
  31700. + return MV_FALSE;
  31701. +}
  31702. +/*******************************************************************************
  31703. +* mvBoardPhyAddrGet - Get the phy address
  31704. +*
  31705. +* DESCRIPTION:
  31706. +* This routine returns the Phy address of a given ethernet port.
  31707. +*
  31708. +* INPUT:
  31709. +* ethPortNum - Ethernet port number.
  31710. +*
  31711. +* OUTPUT:
  31712. +* None.
  31713. +*
  31714. +* RETURN:
  31715. +* 32bit describing Phy address, -1 if the port number is wrong.
  31716. +*
  31717. +*******************************************************************************/
  31718. +MV_32 mvBoardPhyAddrGet(MV_U32 ethPortNum)
  31719. +{
  31720. + MV_U32 boardId= mvBoardIdGet();
  31721. +
  31722. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  31723. + {
  31724. + mvOsPrintf("mvBoardPhyAddrGet: Board unknown.\n");
  31725. + return MV_ERROR;
  31726. + }
  31727. +
  31728. + return BOARD_INFO(boardId)->pBoardMacInfo[ethPortNum].boardEthSmiAddr;
  31729. +}
  31730. +
  31731. +/*******************************************************************************
  31732. +* mvBoardMacSpeedGet - Get the Mac speed
  31733. +*
  31734. +* DESCRIPTION:
  31735. +* This routine returns the Mac speed if pre define of a given ethernet port.
  31736. +*
  31737. +* INPUT:
  31738. +* ethPortNum - Ethernet port number.
  31739. +*
  31740. +* OUTPUT:
  31741. +* None.
  31742. +*
  31743. +* RETURN:
  31744. +* MV_BOARD_MAC_SPEED, -1 if the port number is wrong.
  31745. +*
  31746. +*******************************************************************************/
  31747. +MV_BOARD_MAC_SPEED mvBoardMacSpeedGet(MV_U32 ethPortNum)
  31748. +{
  31749. + MV_U32 boardId= mvBoardIdGet();
  31750. +
  31751. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  31752. + {
  31753. + mvOsPrintf("mvBoardMacSpeedGet: Board unknown.\n");
  31754. + return MV_ERROR;
  31755. + }
  31756. +
  31757. + return BOARD_INFO(boardId)->pBoardMacInfo[ethPortNum].boardMacSpeed;
  31758. +}
  31759. +
  31760. +/*******************************************************************************
  31761. +* mvBoardLinkStatusIrqGet - Get the IRQ number for the link status indication
  31762. +*
  31763. +* DESCRIPTION:
  31764. +* This routine returns the IRQ number for the link status indication.
  31765. +*
  31766. +* INPUT:
  31767. +* ethPortNum - Ethernet port number.
  31768. +*
  31769. +* OUTPUT:
  31770. +* None.
  31771. +*
  31772. +* RETURN:
  31773. +* the number of the IRQ for the link status indication, -1 if the port
  31774. +* number is wrong or if not relevant.
  31775. +*
  31776. +*******************************************************************************/
  31777. +MV_32 mvBoardLinkStatusIrqGet(MV_U32 ethPortNum)
  31778. +{
  31779. + MV_U32 boardId = mvBoardIdGet();
  31780. +
  31781. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  31782. + {
  31783. + mvOsPrintf("mvBoardLinkStatusIrqGet: Board unknown.\n");
  31784. + return MV_ERROR;
  31785. + }
  31786. +
  31787. + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].linkStatusIrq;
  31788. +}
  31789. +
  31790. +/*******************************************************************************
  31791. +* mvBoardSwitchPortGet - Get the mapping between the board connector and the
  31792. +* Ethernet Switch port
  31793. +*
  31794. +* DESCRIPTION:
  31795. +* This routine returns the matching Switch port.
  31796. +*
  31797. +* INPUT:
  31798. +* ethPortNum - Ethernet port number.
  31799. +* boardPortNum - logical number of the connector on the board
  31800. +*
  31801. +* OUTPUT:
  31802. +* None.
  31803. +*
  31804. +* RETURN:
  31805. +* the matching Switch port, -1 if the port number is wrong or if not relevant.
  31806. +*
  31807. +*******************************************************************************/
  31808. +MV_32 mvBoardSwitchPortGet(MV_U32 ethPortNum, MV_U8 boardPortNum)
  31809. +{
  31810. + MV_U32 boardId = mvBoardIdGet();
  31811. +
  31812. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  31813. + {
  31814. + mvOsPrintf("mvBoardSwitchPortGet: Board unknown.\n");
  31815. + return MV_ERROR;
  31816. + }
  31817. + if (boardPortNum >= BOARD_ETH_SWITCH_PORT_NUM)
  31818. + {
  31819. + mvOsPrintf("mvBoardSwitchPortGet: Illegal board port number.\n");
  31820. + return MV_ERROR;
  31821. + }
  31822. +
  31823. + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].qdPort[boardPortNum];
  31824. +}
  31825. +
  31826. +/*******************************************************************************
  31827. +* mvBoardSwitchCpuPortGet - Get the the Ethernet Switch CPU port
  31828. +*
  31829. +* DESCRIPTION:
  31830. +* This routine returns the Switch CPU port.
  31831. +*
  31832. +* INPUT:
  31833. +* ethPortNum - Ethernet port number.
  31834. +*
  31835. +* OUTPUT:
  31836. +* None.
  31837. +*
  31838. +* RETURN:
  31839. +* the Switch CPU port, -1 if the port number is wrong or if not relevant.
  31840. +*
  31841. +*******************************************************************************/
  31842. +MV_32 mvBoardSwitchCpuPortGet(MV_U32 ethPortNum)
  31843. +{
  31844. + MV_U32 boardId = mvBoardIdGet();
  31845. +
  31846. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  31847. + {
  31848. + mvOsPrintf("mvBoardSwitchCpuPortGet: Board unknown.\n");
  31849. + return MV_ERROR;
  31850. + }
  31851. +
  31852. + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].qdCpuPort;
  31853. +}
  31854. +
  31855. +/*******************************************************************************
  31856. +* mvBoardIsSwitchConnected - Get switch connection status
  31857. +* DESCRIPTION:
  31858. +* This routine returns port's connection status
  31859. +*
  31860. +* INPUT:
  31861. +* ethPortNum - Ethernet port number.
  31862. +*
  31863. +* OUTPUT:
  31864. +* None.
  31865. +*
  31866. +* RETURN:
  31867. +* 1 - if ethPortNum is connected to switch, 0 otherwise
  31868. +*
  31869. +*******************************************************************************/
  31870. +MV_32 mvBoardIsSwitchConnected(MV_U32 ethPortNum)
  31871. +{
  31872. + MV_U32 boardId = mvBoardIdGet();
  31873. +
  31874. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  31875. + {
  31876. + mvOsPrintf("mvBoardIsSwitchConnected: Board unknown.\n");
  31877. + return MV_ERROR;
  31878. + }
  31879. +
  31880. + if(ethPortNum >= BOARD_INFO(boardId)->numBoardMacInfo)
  31881. + {
  31882. + mvOsPrintf("mvBoardIsSwitchConnected: Illegal port number(%u)\n", ethPortNum);
  31883. + return MV_ERROR;
  31884. + }
  31885. +
  31886. + if((MV_32)(BOARD_INFO(boardId)->pSwitchInfo))
  31887. + return (MV_32)(BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].switchOnPort == ethPortNum);
  31888. + else
  31889. + return 0;
  31890. +}
  31891. +/*******************************************************************************
  31892. +* mvBoardSmiScanModeGet - Get Switch SMI scan mode
  31893. +*
  31894. +* DESCRIPTION:
  31895. +* This routine returns Switch SMI scan mode.
  31896. +*
  31897. +* INPUT:
  31898. +* ethPortNum - Ethernet port number.
  31899. +*
  31900. +* OUTPUT:
  31901. +* None.
  31902. +*
  31903. +* RETURN:
  31904. +* 1 for SMI_MANUAL_MODE, -1 if the port number is wrong or if not relevant.
  31905. +*
  31906. +*******************************************************************************/
  31907. +MV_32 mvBoardSmiScanModeGet(MV_U32 ethPortNum)
  31908. +{
  31909. + MV_U32 boardId = mvBoardIdGet();
  31910. +
  31911. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  31912. + {
  31913. + mvOsPrintf("mvBoardSmiScanModeGet: Board unknown.\n");
  31914. + return MV_ERROR;
  31915. + }
  31916. +
  31917. + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].smiScanMode;
  31918. +}
  31919. +/*******************************************************************************
  31920. +* mvBoardSpecInitGet -
  31921. +*
  31922. +* DESCRIPTION:
  31923. +*
  31924. +* INPUT:
  31925. +*
  31926. +* OUTPUT:
  31927. +* None.
  31928. +*
  31929. +* RETURN: Return MV_TRUE and parameters in case board need spesific phy init,
  31930. +* otherwise return MV_FALSE.
  31931. +*
  31932. +*
  31933. +*******************************************************************************/
  31934. +
  31935. +MV_BOOL mvBoardSpecInitGet(MV_U32* regOff, MV_U32* data)
  31936. +{
  31937. + return MV_FALSE;
  31938. +}
  31939. +
  31940. +/*******************************************************************************
  31941. +* mvBoardTclkGet - Get the board Tclk (Controller clock)
  31942. +*
  31943. +* DESCRIPTION:
  31944. +* This routine extract the controller core clock.
  31945. +* This function uses the controller counters to make identification.
  31946. +* Note: In order to avoid interference, make sure task context switch
  31947. +* and interrupts will not occure during this function operation
  31948. +*
  31949. +* INPUT:
  31950. +* countNum - Counter number.
  31951. +*
  31952. +* OUTPUT:
  31953. +* None.
  31954. +*
  31955. +* RETURN:
  31956. +* 32bit clock cycles in Hertz.
  31957. +*
  31958. +*******************************************************************************/
  31959. +MV_U32 mvBoardTclkGet(MV_VOID)
  31960. +{
  31961. + if(mvCtrlModelGet()==MV_6281_DEV_ID)
  31962. + {
  31963. +#if defined(TCLK_AUTO_DETECT)
  31964. + MV_U32 tmpTClkRate = MV_BOARD_TCLK_166MHZ;
  31965. +
  31966. + tmpTClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  31967. + tmpTClkRate &= MSAR_TCLCK_MASK;
  31968. +
  31969. + switch (tmpTClkRate)
  31970. + {
  31971. + case MSAR_TCLCK_166:
  31972. + return MV_BOARD_TCLK_166MHZ;
  31973. + break;
  31974. + case MSAR_TCLCK_200:
  31975. + return MV_BOARD_TCLK_200MHZ;
  31976. + break;
  31977. + }
  31978. +#else
  31979. + return MV_BOARD_TCLK_200MHZ;
  31980. +#endif
  31981. + }
  31982. +
  31983. + return MV_BOARD_TCLK_166MHZ;
  31984. +
  31985. +}
  31986. +/*******************************************************************************
  31987. +* mvBoardSysClkGet - Get the board SysClk (CPU bus clock)
  31988. +*
  31989. +* DESCRIPTION:
  31990. +* This routine extract the CPU bus clock.
  31991. +*
  31992. +* INPUT:
  31993. +* countNum - Counter number.
  31994. +*
  31995. +* OUTPUT:
  31996. +* None.
  31997. +*
  31998. +* RETURN:
  31999. +* 32bit clock cycles in Hertz.
  32000. +*
  32001. +*******************************************************************************/
  32002. +static MV_U32 mvBoard6180SysClkGet(MV_VOID)
  32003. +{
  32004. + MV_U32 sysClkRate=0;
  32005. + MV_CPU_ARM_CLK _cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;
  32006. +
  32007. + sysClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  32008. + sysClkRate = sysClkRate & MSAR_CPUCLCK_MASK_6180;
  32009. + sysClkRate = sysClkRate >> MSAR_CPUCLCK_OFFS_6180;
  32010. +
  32011. + sysClkRate = _cpu6180_ddr_l2_CLK[sysClkRate].ddrClk;
  32012. +
  32013. + return sysClkRate;
  32014. +
  32015. +}
  32016. +
  32017. +MV_U32 mvBoardSysClkGet(MV_VOID)
  32018. +{
  32019. +#ifdef SYSCLK_AUTO_DETECT
  32020. + MV_U32 sysClkRate, tmp, pClkRate, indexDdrRtio;
  32021. + MV_U32 cpuCLK[] = MV_CPU_CLCK_TBL;
  32022. + MV_U32 ddrRtio[][2] = MV_DDR_CLCK_RTIO_TBL;
  32023. +
  32024. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  32025. + return mvBoard6180SysClkGet();
  32026. +
  32027. + tmp = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  32028. + pClkRate = MSAR_CPUCLCK_EXTRACT(tmp);
  32029. + pClkRate = cpuCLK[pClkRate];
  32030. +
  32031. + indexDdrRtio = tmp & MSAR_DDRCLCK_RTIO_MASK;
  32032. + indexDdrRtio = indexDdrRtio >> MSAR_DDRCLCK_RTIO_OFFS;
  32033. + if(ddrRtio[indexDdrRtio][0] != 0)
  32034. + sysClkRate = ((pClkRate * ddrRtio[indexDdrRtio][1]) / ddrRtio[indexDdrRtio][0]);
  32035. + else
  32036. + sysClkRate = 0;
  32037. + return sysClkRate;
  32038. +#else
  32039. + return MV_BOARD_DEFAULT_SYSCLK;
  32040. +#endif
  32041. +}
  32042. +
  32043. +
  32044. +/*******************************************************************************
  32045. +* mvBoardPexBridgeIntPinGet - Get PEX to PCI bridge interrupt pin number
  32046. +*
  32047. +* DESCRIPTION:
  32048. +* Multi-ported PCI Express bridges that is implemented on the board
  32049. +* collapse interrupts across multiple conventional PCI/PCI-X buses.
  32050. +* A dual-headed PCI Express bridge would map (or "swizzle") the
  32051. +* interrupts per the following table (in accordance with the respective
  32052. +* logical PCI/PCI-X bridge's Device Number), collapse the INTA#-INTD#
  32053. +* signals from its two logical PCI/PCI-X bridges, collapse the
  32054. +* INTA#-INTD# signals from any internal sources, and convert the
  32055. +* signals to in-band PCI Express messages. 10
  32056. +* This function returns the upstream interrupt as it was converted by
  32057. +* the bridge, according to board configuration and the following table:
  32058. +* PCI dev num
  32059. +* Interrupt pin 7, 8, 9
  32060. +* A -> A D C
  32061. +* B -> B A D
  32062. +* C -> C B A
  32063. +* D -> D C B
  32064. +*
  32065. +*
  32066. +* INPUT:
  32067. +* devNum - PCI/PCIX device number.
  32068. +* intPin - PCI Int pin
  32069. +*
  32070. +* OUTPUT:
  32071. +* None.
  32072. +*
  32073. +* RETURN:
  32074. +* Int pin connected to the Interrupt controller
  32075. +*
  32076. +*******************************************************************************/
  32077. +MV_U32 mvBoardPexBridgeIntPinGet(MV_U32 devNum, MV_U32 intPin)
  32078. +{
  32079. + MV_U32 realIntPin = ((intPin + (3 - (devNum % 4))) %4 );
  32080. +
  32081. + if (realIntPin == 0) return 4;
  32082. + else return realIntPin;
  32083. +
  32084. +}
  32085. +
  32086. +/*******************************************************************************
  32087. +* mvBoardDebugLedNumGet - Get number of debug Leds
  32088. +*
  32089. +* DESCRIPTION:
  32090. +* INPUT:
  32091. +* boardId
  32092. +*
  32093. +* OUTPUT:
  32094. +* None.
  32095. +*
  32096. +* RETURN:
  32097. +* None.
  32098. +*
  32099. +*******************************************************************************/
  32100. +MV_U32 mvBoardDebugLedNumGet(MV_U32 boardId)
  32101. +{
  32102. + return BOARD_INFO(boardId)->activeLedsNumber;
  32103. +}
  32104. +
  32105. +/*******************************************************************************
  32106. +* mvBoardDebugLeg - Set the board debug Leds
  32107. +*
  32108. +* DESCRIPTION: turn on/off status leds.
  32109. +* Note: assume MPP leds are part of group 0 only.
  32110. +*
  32111. +* INPUT:
  32112. +* hexNum - Number to be displied in hex by Leds.
  32113. +*
  32114. +* OUTPUT:
  32115. +* None.
  32116. +*
  32117. +* RETURN:
  32118. +* None.
  32119. +*
  32120. +*******************************************************************************/
  32121. +MV_VOID mvBoardDebugLed(MV_U32 hexNum)
  32122. +{
  32123. + MV_U32 val = 0,totalMask, currentBitMask = 1,i;
  32124. + MV_U32 boardId= mvBoardIdGet();
  32125. +
  32126. + if (BOARD_INFO(boardId)->pLedGppPin == NULL)
  32127. + return;
  32128. +
  32129. + totalMask = (1 << BOARD_INFO(boardId)->activeLedsNumber) -1;
  32130. + hexNum &= totalMask;
  32131. + totalMask = 0;
  32132. +
  32133. + for (i = 0 ; i < BOARD_INFO(boardId)->activeLedsNumber ; i++)
  32134. + {
  32135. + if (hexNum & currentBitMask)
  32136. + {
  32137. + val |= (1 << BOARD_INFO(boardId)->pLedGppPin[i]);
  32138. + }
  32139. +
  32140. + totalMask |= (1 << BOARD_INFO(boardId)->pLedGppPin[i]);
  32141. +
  32142. + currentBitMask = (currentBitMask << 1);
  32143. + }
  32144. +
  32145. + if (BOARD_INFO(boardId)->ledsPolarity)
  32146. + {
  32147. + mvGppValueSet(0, totalMask, val);
  32148. + }
  32149. + else
  32150. + {
  32151. + mvGppValueSet(0, totalMask, ~val);
  32152. + }
  32153. +}
  32154. +
  32155. +
  32156. +/*******************************************************************************
  32157. +* mvBoarGpioPinGet - mvBoarGpioPinGet
  32158. +*
  32159. +* DESCRIPTION:
  32160. +*
  32161. +* INPUT:
  32162. +* class - MV_BOARD_GPP_CLASS enum.
  32163. +*
  32164. +* OUTPUT:
  32165. +* None.
  32166. +*
  32167. +* RETURN:
  32168. +* GPIO pin number. The function return -1 for bad parameters.
  32169. +*
  32170. +*******************************************************************************/
  32171. +MV_32 mvBoarGpioPinNumGet(MV_BOARD_GPP_CLASS class, MV_U32 index)
  32172. +{
  32173. + MV_U32 boardId, i;
  32174. + MV_U32 indexFound = 0;
  32175. +
  32176. + boardId = mvBoardIdGet();
  32177. +
  32178. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32179. + {
  32180. + mvOsPrintf("mvBoardRTCGpioPinGet:Board unknown.\n");
  32181. + return MV_ERROR;
  32182. +
  32183. + }
  32184. +
  32185. + for (i = 0; i < BOARD_INFO(boardId)->numBoardGppInfo; i++)
  32186. + if (BOARD_INFO(boardId)->pBoardGppInfo[i].devClass == class) {
  32187. + if (indexFound == index)
  32188. + return (MV_U32)BOARD_INFO(boardId)->pBoardGppInfo[i].gppPinNum;
  32189. + else
  32190. + indexFound++;
  32191. +
  32192. + }
  32193. +
  32194. + return MV_ERROR;
  32195. +}
  32196. +
  32197. +
  32198. +/*******************************************************************************
  32199. +* mvBoardRTCGpioPinGet - mvBoardRTCGpioPinGet
  32200. +*
  32201. +* DESCRIPTION:
  32202. +*
  32203. +* INPUT:
  32204. +* None.
  32205. +*
  32206. +* OUTPUT:
  32207. +* None.
  32208. +*
  32209. +* RETURN:
  32210. +* GPIO pin number. The function return -1 for bad parameters.
  32211. +*
  32212. +*******************************************************************************/
  32213. +MV_32 mvBoardRTCGpioPinGet(MV_VOID)
  32214. +{
  32215. + return mvBoarGpioPinNumGet(BOARD_GPP_RTC, 0);
  32216. +}
  32217. +
  32218. +
  32219. +/*******************************************************************************
  32220. +* mvBoardReset - mvBoardReset
  32221. +*
  32222. +* DESCRIPTION:
  32223. +* Reset the board
  32224. +* INPUT:
  32225. +* None.
  32226. +*
  32227. +* OUTPUT:
  32228. +* None.
  32229. +*
  32230. +* RETURN:
  32231. +* None
  32232. +*
  32233. +*******************************************************************************/
  32234. +MV_VOID mvBoardReset(MV_VOID)
  32235. +{
  32236. + MV_32 resetPin;
  32237. +
  32238. + /* Get gpp reset pin if define */
  32239. + resetPin = mvBoardResetGpioPinGet();
  32240. + if (resetPin != MV_ERROR)
  32241. + {
  32242. + MV_REG_BIT_RESET( GPP_DATA_OUT_REG(0) ,(1 << resetPin));
  32243. + MV_REG_BIT_RESET( GPP_DATA_OUT_EN_REG(0) ,(1 << resetPin));
  32244. +
  32245. + }
  32246. + else
  32247. + {
  32248. + /* No gpp reset pin was found, try to reset ussing
  32249. + system reset out */
  32250. + MV_REG_BIT_SET( CPU_RSTOUTN_MASK_REG , BIT2);
  32251. + MV_REG_BIT_SET( CPU_SYS_SOFT_RST_REG , BIT0);
  32252. + }
  32253. +}
  32254. +
  32255. +/*******************************************************************************
  32256. +* mvBoardResetGpioPinGet - mvBoardResetGpioPinGet
  32257. +*
  32258. +* DESCRIPTION:
  32259. +*
  32260. +* INPUT:
  32261. +* None.
  32262. +*
  32263. +* OUTPUT:
  32264. +* None.
  32265. +*
  32266. +* RETURN:
  32267. +* GPIO pin number. The function return -1 for bad parameters.
  32268. +*
  32269. +*******************************************************************************/
  32270. +MV_32 mvBoardResetGpioPinGet(MV_VOID)
  32271. +{
  32272. + return mvBoarGpioPinNumGet(BOARD_GPP_RESET, 0);
  32273. +}
  32274. +/*******************************************************************************
  32275. +* mvBoardSDIOGpioPinGet - mvBoardSDIOGpioPinGet
  32276. +*
  32277. +* DESCRIPTION:
  32278. +* used for hotswap detection
  32279. +* INPUT:
  32280. +* None.
  32281. +*
  32282. +* OUTPUT:
  32283. +* None.
  32284. +*
  32285. +* RETURN:
  32286. +* GPIO pin number. The function return -1 for bad parameters.
  32287. +*
  32288. +*******************************************************************************/
  32289. +MV_32 mvBoardSDIOGpioPinGet(MV_VOID)
  32290. +{
  32291. + return mvBoarGpioPinNumGet(BOARD_GPP_SDIO_DETECT, 0);
  32292. +}
  32293. +
  32294. +/*******************************************************************************
  32295. +* mvBoardUSBVbusGpioPinGet - return Vbus input GPP
  32296. +*
  32297. +* DESCRIPTION:
  32298. +*
  32299. +* INPUT:
  32300. +* int devNo.
  32301. +*
  32302. +* OUTPUT:
  32303. +* None.
  32304. +*
  32305. +* RETURN:
  32306. +* GPIO pin number. The function return -1 for bad parameters.
  32307. +*
  32308. +*******************************************************************************/
  32309. +MV_32 mvBoardUSBVbusGpioPinGet(MV_32 devId)
  32310. +{
  32311. + return mvBoarGpioPinNumGet(BOARD_GPP_USB_VBUS, devId);
  32312. +}
  32313. +
  32314. +/*******************************************************************************
  32315. +* mvBoardUSBVbusEnGpioPinGet - return Vbus Enable output GPP
  32316. +*
  32317. +* DESCRIPTION:
  32318. +*
  32319. +* INPUT:
  32320. +* int devNo.
  32321. +*
  32322. +* OUTPUT:
  32323. +* None.
  32324. +*
  32325. +* RETURN:
  32326. +* GPIO pin number. The function return -1 for bad parameters.
  32327. +*
  32328. +*******************************************************************************/
  32329. +MV_32 mvBoardUSBVbusEnGpioPinGet(MV_32 devId)
  32330. +{
  32331. + return mvBoarGpioPinNumGet(BOARD_GPP_USB_VBUS_EN, devId);
  32332. +}
  32333. +
  32334. +
  32335. +/*******************************************************************************
  32336. +* mvBoardGpioIntMaskGet - Get GPIO mask for interrupt pins
  32337. +*
  32338. +* DESCRIPTION:
  32339. +* This function returns a 32-bit mask of GPP pins that connected to
  32340. +* interrupt generating sources on board.
  32341. +* For example if UART channel A is hardwired to GPP pin 8 and
  32342. +* UART channel B is hardwired to GPP pin 4 the fuinction will return
  32343. +* the value 0x000000110
  32344. +*
  32345. +* INPUT:
  32346. +* None.
  32347. +*
  32348. +* OUTPUT:
  32349. +* None.
  32350. +*
  32351. +* RETURN:
  32352. +* See description. The function return -1 if board is not identified.
  32353. +*
  32354. +*******************************************************************************/
  32355. +MV_32 mvBoardGpioIntMaskLowGet(MV_VOID)
  32356. +{
  32357. + MV_U32 boardId;
  32358. +
  32359. + boardId = mvBoardIdGet();
  32360. +
  32361. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32362. + {
  32363. + mvOsPrintf("mvBoardGpioIntMaskGet:Board unknown.\n");
  32364. + return MV_ERROR;
  32365. +
  32366. + }
  32367. +
  32368. + return BOARD_INFO(boardId)->intsGppMaskLow;
  32369. +}
  32370. +MV_32 mvBoardGpioIntMaskHighGet(MV_VOID)
  32371. +{
  32372. + MV_U32 boardId;
  32373. +
  32374. + boardId = mvBoardIdGet();
  32375. +
  32376. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32377. + {
  32378. + mvOsPrintf("mvBoardGpioIntMaskGet:Board unknown.\n");
  32379. + return MV_ERROR;
  32380. +
  32381. + }
  32382. +
  32383. + return BOARD_INFO(boardId)->intsGppMaskHigh;
  32384. +}
  32385. +
  32386. +
  32387. +/*******************************************************************************
  32388. +* mvBoardMppGet - Get board dependent MPP register value
  32389. +*
  32390. +* DESCRIPTION:
  32391. +* MPP settings are derived from board design.
  32392. +* MPP group consist of 8 MPPs. An MPP group represent MPP
  32393. +* control register.
  32394. +* This function retrieves board dependend MPP register value.
  32395. +*
  32396. +* INPUT:
  32397. +* mppGroupNum - MPP group number.
  32398. +*
  32399. +* OUTPUT:
  32400. +* None.
  32401. +*
  32402. +* RETURN:
  32403. +* 32bit value describing MPP control register value.
  32404. +*
  32405. +*******************************************************************************/
  32406. +MV_32 mvBoardMppGet(MV_U32 mppGroupNum)
  32407. +{
  32408. + MV_U32 boardId;
  32409. +
  32410. + boardId = mvBoardIdGet();
  32411. +
  32412. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32413. + {
  32414. + mvOsPrintf("mvBoardMppGet:Board unknown.\n");
  32415. + return MV_ERROR;
  32416. +
  32417. + }
  32418. +
  32419. + return BOARD_INFO(boardId)->pBoardMppConfigValue[0].mppGroup[mppGroupNum];
  32420. +}
  32421. +
  32422. +
  32423. +/*******************************************************************************
  32424. +* mvBoardMppGroupId - If MPP group type is AUTO then identify it using twsi
  32425. +*
  32426. +* DESCRIPTION:
  32427. +*
  32428. +* INPUT:
  32429. +*
  32430. +* OUTPUT:
  32431. +* None.
  32432. +*
  32433. +* RETURN:
  32434. +*
  32435. +*******************************************************************************/
  32436. +MV_VOID mvBoardMppGroupIdUpdate(MV_VOID)
  32437. +{
  32438. +
  32439. + MV_BOARD_MPP_GROUP_CLASS devClass;
  32440. + MV_BOARD_MODULE_ID_CLASS devClassId;
  32441. + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
  32442. + MV_U32 devId;
  32443. + MV_U32 maxMppGrp = 1;
  32444. +
  32445. + devId = mvCtrlModelGet();
  32446. +
  32447. + switch(devId){
  32448. + case MV_6281_DEV_ID:
  32449. + maxMppGrp = MV_6281_MPP_MAX_MODULE;
  32450. + break;
  32451. + case MV_6192_DEV_ID:
  32452. + maxMppGrp = MV_6192_MPP_MAX_MODULE;
  32453. + break;
  32454. + case MV_6190_DEV_ID:
  32455. + maxMppGrp = MV_6190_MPP_MAX_MODULE;
  32456. + break;
  32457. + case MV_6180_DEV_ID:
  32458. + maxMppGrp = MV_6180_MPP_MAX_MODULE;
  32459. + break;
  32460. + }
  32461. +
  32462. + for (devClass = 0; devClass < maxMppGrp; devClass++)
  32463. + {
  32464. + /* If MPP group can be defined by the module connected to it */
  32465. + if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_AUTO)
  32466. + {
  32467. + /* Get MPP module ID */
  32468. + devClassId = mvBoarModuleTypeGet(devClass);
  32469. + if (MV_ERROR != devClassId)
  32470. + {
  32471. + switch(devClassId)
  32472. + {
  32473. + case MV_BOARD_MODULE_TDM_ID:
  32474. + case MV_BOARD_MODULE_TDM_5CHAN_ID:
  32475. + mppGroupType = MV_BOARD_TDM;
  32476. + break;
  32477. + case MV_BOARD_MODULE_AUDIO_ID:
  32478. + mppGroupType = MV_BOARD_AUDIO;
  32479. + break;
  32480. + case MV_BOARD_MODULE_RGMII_ID:
  32481. + mppGroupType = MV_BOARD_RGMII;
  32482. + break;
  32483. + case MV_BOARD_MODULE_GMII_ID:
  32484. + mppGroupType = MV_BOARD_GMII;
  32485. + break;
  32486. + case MV_BOARD_MODULE_TS_ID:
  32487. + mppGroupType = MV_BOARD_TS;
  32488. + break;
  32489. + case MV_BOARD_MODULE_MII_ID:
  32490. + mppGroupType = MV_BOARD_MII;
  32491. + break;
  32492. + default:
  32493. + mppGroupType = MV_BOARD_OTHER;
  32494. + break;
  32495. + }
  32496. + }
  32497. + else
  32498. + /* The module bay is empty */
  32499. + mppGroupType = MV_BOARD_OTHER;
  32500. +
  32501. + /* Update MPP group type */
  32502. + mvBoardMppGroupTypeSet(devClass, mppGroupType);
  32503. + }
  32504. +
  32505. + /* Update MPP output voltage for RGMII 1.8V. Set port to GMII for GMII module */
  32506. + if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_RGMII))
  32507. + MV_REG_BIT_SET(MPP_OUTPUT_DRIVE_REG,MPP_1_8_RGMII1_OUTPUT_DRIVE | MPP_1_8_RGMII0_OUTPUT_DRIVE);
  32508. + else
  32509. + {
  32510. + if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_GMII))
  32511. + {
  32512. + MV_REG_BIT_RESET(MPP_OUTPUT_DRIVE_REG, BIT7 | BIT15);
  32513. + MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(0),BIT3);
  32514. + MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(1),BIT3);
  32515. + }
  32516. + else if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_MII))
  32517. + {
  32518. + /* Assumption that the MDC & MDIO should be 3.3V */
  32519. + MV_REG_BIT_RESET(MPP_OUTPUT_DRIVE_REG, BIT7 | BIT15);
  32520. + /* Assumption that only ETH1 can be MII when using modules on DB */
  32521. + MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(1),BIT3);
  32522. + }
  32523. + }
  32524. + }
  32525. +}
  32526. +
  32527. +/*******************************************************************************
  32528. +* mvBoardMppGroupTypeGet
  32529. +*
  32530. +* DESCRIPTION:
  32531. +*
  32532. +* INPUT:
  32533. +* mppGroupClass - MPP group number 0 for MPP[35:20] or 1 for MPP[49:36].
  32534. +*
  32535. +* OUTPUT:
  32536. +* None.
  32537. +*
  32538. +* RETURN:
  32539. +*
  32540. +*******************************************************************************/
  32541. +MV_BOARD_MPP_TYPE_CLASS mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass)
  32542. +{
  32543. + MV_U32 boardId;
  32544. +
  32545. + boardId = mvBoardIdGet();
  32546. +
  32547. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32548. + {
  32549. + mvOsPrintf("mvBoardMppGet:Board unknown.\n");
  32550. + return MV_ERROR;
  32551. +
  32552. + }
  32553. +
  32554. + if (mppGroupClass == MV_BOARD_MPP_GROUP_1)
  32555. + return BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup1;
  32556. + else
  32557. + return BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup2;
  32558. +}
  32559. +
  32560. +/*******************************************************************************
  32561. +* mvBoardMppGroupTypeSet
  32562. +*
  32563. +* DESCRIPTION:
  32564. +*
  32565. +* INPUT:
  32566. +* mppGroupClass - MPP group number 0 for MPP[35:20] or 1 for MPP[49:36].
  32567. +* mppGroupType - MPP group type for MPP[35:20] or for MPP[49:36].
  32568. +*
  32569. +* OUTPUT:
  32570. +* None.
  32571. +*
  32572. +* RETURN:
  32573. +*
  32574. +*******************************************************************************/
  32575. +MV_VOID mvBoardMppGroupTypeSet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass,
  32576. + MV_BOARD_MPP_TYPE_CLASS mppGroupType)
  32577. +{
  32578. + MV_U32 boardId;
  32579. +
  32580. + boardId = mvBoardIdGet();
  32581. +
  32582. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32583. + {
  32584. + mvOsPrintf("mvBoardMppGet:Board unknown.\n");
  32585. + }
  32586. +
  32587. + if (mppGroupClass == MV_BOARD_MPP_GROUP_1)
  32588. + BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup1 = mppGroupType;
  32589. + else
  32590. + BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup2 = mppGroupType;
  32591. +
  32592. +}
  32593. +
  32594. +/*******************************************************************************
  32595. +* mvBoardMppMuxSet - Update MPP mux
  32596. +*
  32597. +* DESCRIPTION:
  32598. +*
  32599. +* INPUT:
  32600. +*
  32601. +* OUTPUT:
  32602. +* None.
  32603. +*
  32604. +* RETURN:
  32605. +*
  32606. +*******************************************************************************/
  32607. +MV_VOID mvBoardMppMuxSet(MV_VOID)
  32608. +{
  32609. +
  32610. + MV_BOARD_MPP_GROUP_CLASS devClass;
  32611. + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
  32612. + MV_U32 devId;
  32613. + MV_U8 muxVal = 0xf;
  32614. + MV_U32 maxMppGrp = 1;
  32615. + MV_TWSI_SLAVE twsiSlave;
  32616. + MV_TWSI_ADDR slave;
  32617. +
  32618. + devId = mvCtrlModelGet();
  32619. +
  32620. + switch(devId){
  32621. + case MV_6281_DEV_ID:
  32622. + maxMppGrp = MV_6281_MPP_MAX_MODULE;
  32623. + break;
  32624. + case MV_6192_DEV_ID:
  32625. + maxMppGrp = MV_6192_MPP_MAX_MODULE;
  32626. + break;
  32627. + case MV_6190_DEV_ID:
  32628. + maxMppGrp = MV_6190_MPP_MAX_MODULE;
  32629. + break;
  32630. + case MV_6180_DEV_ID:
  32631. + maxMppGrp = MV_6180_MPP_MAX_MODULE;
  32632. + break;
  32633. + }
  32634. +
  32635. + for (devClass = 0; devClass < maxMppGrp; devClass++)
  32636. + {
  32637. + mppGroupType = mvBoardMppGroupTypeGet(devClass);
  32638. +
  32639. + switch(mppGroupType)
  32640. + {
  32641. + case MV_BOARD_TDM:
  32642. + muxVal &= ~(devClass ? (0x2 << (devClass * 2)):0x0);
  32643. + break;
  32644. + case MV_BOARD_AUDIO:
  32645. + muxVal &= ~(devClass ? 0x7 : 0x0); /*old Z0 value 0xd:0x0*/
  32646. + break;
  32647. + case MV_BOARD_TS:
  32648. + muxVal &= ~(devClass ? (0x2 << (devClass * 2)):0x0);
  32649. + break;
  32650. + default:
  32651. + muxVal |= (devClass ? 0xf : 0);
  32652. + break;
  32653. + }
  32654. + }
  32655. +
  32656. + /* TWSI init */
  32657. + slave.type = ADDR7_BIT;
  32658. + slave.address = 0;
  32659. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  32660. +
  32661. + /* Read MPP module ID */
  32662. + DB(mvOsPrintf("Board: twsi exp set\n"));
  32663. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(MV_BOARD_MUX_I2C_ADDR_ENTRY);
  32664. + twsiSlave.slaveAddr.type = mvBoardTwsiExpAddrTypeGet(MV_BOARD_MUX_I2C_ADDR_ENTRY);
  32665. + twsiSlave.validOffset = MV_TRUE;
  32666. + /* Offset is the first command after the address which indicate the register number to be read
  32667. + in next operation */
  32668. + twsiSlave.offset = 2;
  32669. + twsiSlave.moreThen256 = MV_FALSE;
  32670. +
  32671. +
  32672. +
  32673. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  32674. + {
  32675. + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
  32676. + return;
  32677. + }
  32678. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  32679. +
  32680. + /* Change twsi exp to output */
  32681. + twsiSlave.offset = 6;
  32682. + muxVal = 0;
  32683. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  32684. + {
  32685. + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
  32686. + return;
  32687. + }
  32688. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  32689. +
  32690. +}
  32691. +
  32692. +/*******************************************************************************
  32693. +* mvBoardTdmMppSet - set MPPs in TDM module
  32694. +*
  32695. +* DESCRIPTION:
  32696. +*
  32697. +* INPUT: type of second telephony device
  32698. +*
  32699. +* OUTPUT:
  32700. +* None.
  32701. +*
  32702. +* RETURN:
  32703. +*
  32704. +*******************************************************************************/
  32705. +MV_VOID mvBoardTdmMppSet(MV_32 chType)
  32706. +{
  32707. +
  32708. + MV_BOARD_MPP_GROUP_CLASS devClass;
  32709. + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
  32710. + MV_U32 devId;
  32711. + MV_U8 muxVal = 1;
  32712. + MV_U8 muxValMask = 1;
  32713. + MV_U8 twsiVal;
  32714. + MV_U32 maxMppGrp = 1;
  32715. + MV_TWSI_SLAVE twsiSlave;
  32716. + MV_TWSI_ADDR slave;
  32717. +
  32718. + devId = mvCtrlModelGet();
  32719. +
  32720. + switch(devId){
  32721. + case MV_6281_DEV_ID:
  32722. + maxMppGrp = MV_6281_MPP_MAX_MODULE;
  32723. + break;
  32724. + case MV_6192_DEV_ID:
  32725. + maxMppGrp = MV_6192_MPP_MAX_MODULE;
  32726. + break;
  32727. + case MV_6190_DEV_ID:
  32728. + maxMppGrp = MV_6190_MPP_MAX_MODULE;
  32729. + break;
  32730. + case MV_6180_DEV_ID:
  32731. + maxMppGrp = MV_6180_MPP_MAX_MODULE;
  32732. + break;
  32733. + }
  32734. +
  32735. + for (devClass = 0; devClass < maxMppGrp; devClass++)
  32736. + {
  32737. + mppGroupType = mvBoardMppGroupTypeGet(devClass);
  32738. + if(mppGroupType == MV_BOARD_TDM)
  32739. + break;
  32740. + }
  32741. +
  32742. + if(devClass == maxMppGrp)
  32743. + return; /* TDM module not found */
  32744. +
  32745. + /* TWSI init */
  32746. + slave.type = ADDR7_BIT;
  32747. + slave.address = 0;
  32748. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  32749. +
  32750. + /* Read MPP module ID */
  32751. + DB(mvOsPrintf("Board: twsi exp set\n"));
  32752. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(devClass);
  32753. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  32754. + twsiSlave.validOffset = MV_TRUE;
  32755. + /* Offset is the first command after the address which indicate the register number to be read
  32756. + in next operation */
  32757. + twsiSlave.offset = 3;
  32758. + twsiSlave.moreThen256 = MV_FALSE;
  32759. +
  32760. + if(mvBoardIdGet() == RD_88F6281A_ID)
  32761. + {
  32762. + muxVal = 0xc;
  32763. + muxValMask = 0xf3;
  32764. + }
  32765. +
  32766. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  32767. + muxVal = (twsiVal & muxValMask) | muxVal;
  32768. +
  32769. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  32770. + {
  32771. + mvOsPrintf("Board: twsi exp out val fail\n");
  32772. + return;
  32773. + }
  32774. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  32775. +
  32776. + /* Change twsi exp to output */
  32777. + twsiSlave.offset = 7;
  32778. + muxVal = 0xfe;
  32779. + if(mvBoardIdGet() == RD_88F6281A_ID)
  32780. + muxVal = 0xf3;
  32781. +
  32782. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  32783. + muxVal = (twsiVal & muxVal);
  32784. +
  32785. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  32786. + {
  32787. + mvOsPrintf("Board: twsi exp change to out fail\n");
  32788. + return;
  32789. + }
  32790. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  32791. + /* reset the line to 0 */
  32792. + twsiSlave.offset = 3;
  32793. + muxVal = 0;
  32794. + muxValMask = 1;
  32795. +
  32796. + if(mvBoardIdGet() == RD_88F6281A_ID) {
  32797. + muxVal = 0x0;
  32798. + muxValMask = 0xf3;
  32799. + }
  32800. +
  32801. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  32802. + muxVal = (twsiVal & muxValMask) | muxVal;
  32803. +
  32804. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  32805. + {
  32806. + mvOsPrintf("Board: twsi exp out val fail\n");
  32807. + return;
  32808. + }
  32809. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  32810. +
  32811. + mvOsDelay(20);
  32812. +
  32813. + /* set the line to 1 */
  32814. + twsiSlave.offset = 3;
  32815. + muxVal = 1;
  32816. + muxValMask = 1;
  32817. +
  32818. + if(mvBoardIdGet() == RD_88F6281A_ID)
  32819. + {
  32820. + muxVal = 0xc;
  32821. + muxValMask = 0xf3;
  32822. + if(chType) /* FXS - issue reset properly */
  32823. + {
  32824. + MV_REG_BIT_SET(GPP_DATA_OUT_REG(1), MV_GPP12);
  32825. + mvOsDelay(50);
  32826. + MV_REG_BIT_RESET(GPP_DATA_OUT_REG(1), MV_GPP12);
  32827. + }
  32828. + else /* FXO - issue reset via TDM_CODEC_RST*/
  32829. + {
  32830. + /* change MPP44 type to TDM_CODEC_RST(0x2) */
  32831. + MV_REG_WRITE(MPP_CONTROL_REG5, ((MV_REG_READ(MPP_CONTROL_REG5) & 0xFFF0FFFF) | BIT17));
  32832. + }
  32833. + }
  32834. +
  32835. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  32836. + muxVal = (twsiVal & muxValMask) | muxVal;
  32837. +
  32838. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  32839. + {
  32840. + mvOsPrintf("Board: twsi exp out val fail\n");
  32841. + return;
  32842. + }
  32843. +
  32844. + /* TBD - 5 channels */
  32845. +#if defined(MV_TDM_5CHANNELS)
  32846. + /* change MPP38 type to GPIO(0x0) & polarity for TDM_STROBE */
  32847. + MV_REG_WRITE(MPP_CONTROL_REG4, (MV_REG_READ(MPP_CONTROL_REG4) & 0xF0FFFFFF));
  32848. + mvGppPolaritySet(1, MV_GPP6, 0);
  32849. +
  32850. + twsiSlave.offset = 6;
  32851. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(2);
  32852. +
  32853. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  32854. + muxVal = (twsiVal & ~BIT2);
  32855. +
  32856. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  32857. + {
  32858. + mvOsPrintf("Board: twsi exp change to out fail\n");
  32859. + return;
  32860. + }
  32861. +
  32862. +
  32863. + twsiSlave.offset = 2;
  32864. +
  32865. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  32866. + muxVal = (twsiVal & ~BIT2);
  32867. +
  32868. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  32869. + {
  32870. + mvOsPrintf("Board: twsi exp change to out fail\n");
  32871. + return;
  32872. + }
  32873. +#endif
  32874. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  32875. +
  32876. +
  32877. +}
  32878. +/*******************************************************************************
  32879. +* mvBoardVoiceConnModeGet - return SLIC/DAA connection & interrupt modes
  32880. +*
  32881. +* DESCRIPTION:
  32882. +*
  32883. +* INPUT:
  32884. +*
  32885. +* OUTPUT:
  32886. +* None.
  32887. +*
  32888. +* RETURN:
  32889. +*
  32890. +*******************************************************************************/
  32891. +
  32892. +MV_VOID mvBoardVoiceConnModeGet(MV_32* connMode, MV_32* irqMode)
  32893. +{
  32894. + switch(mvBoardIdGet())
  32895. + {
  32896. + case RD_88F6281A_ID:
  32897. + *connMode = DAISY_CHAIN_MODE;
  32898. + *irqMode = INTERRUPT_TO_TDM;
  32899. + break;
  32900. + case DB_88F6281A_BP_ID:
  32901. + *connMode = DUAL_CHIP_SELECT_MODE;
  32902. + *irqMode = INTERRUPT_TO_TDM;
  32903. + break;
  32904. + case RD_88F6192A_ID:
  32905. + *connMode = DUAL_CHIP_SELECT_MODE;
  32906. + *irqMode = INTERRUPT_TO_TDM;
  32907. + break;
  32908. + case DB_88F6192A_BP_ID:
  32909. + *connMode = DUAL_CHIP_SELECT_MODE;
  32910. + *irqMode = INTERRUPT_TO_TDM;
  32911. + break;
  32912. + default:
  32913. + *connMode = *irqMode = -1;
  32914. + mvOsPrintf("mvBoardVoiceAssembleModeGet: TDM not supported(boardId=0x%x)\n",mvBoardIdGet());
  32915. + }
  32916. + return;
  32917. +
  32918. +}
  32919. +
  32920. +/*******************************************************************************
  32921. +* mvBoardMppModuleTypePrint - print module detect
  32922. +*
  32923. +* DESCRIPTION:
  32924. +*
  32925. +* INPUT:
  32926. +*
  32927. +* OUTPUT:
  32928. +* None.
  32929. +*
  32930. +* RETURN:
  32931. +*
  32932. +*******************************************************************************/
  32933. +MV_VOID mvBoardMppModuleTypePrint(MV_VOID)
  32934. +{
  32935. +
  32936. + MV_BOARD_MPP_GROUP_CLASS devClass;
  32937. + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
  32938. + MV_U32 devId;
  32939. + MV_U32 maxMppGrp = 1;
  32940. +
  32941. + devId = mvCtrlModelGet();
  32942. +
  32943. + switch(devId){
  32944. + case MV_6281_DEV_ID:
  32945. + maxMppGrp = MV_6281_MPP_MAX_MODULE;
  32946. + break;
  32947. + case MV_6192_DEV_ID:
  32948. + maxMppGrp = MV_6192_MPP_MAX_MODULE;
  32949. + break;
  32950. + case MV_6190_DEV_ID:
  32951. + maxMppGrp = MV_6190_MPP_MAX_MODULE;
  32952. + break;
  32953. + case MV_6180_DEV_ID:
  32954. + maxMppGrp = MV_6180_MPP_MAX_MODULE;
  32955. + break;
  32956. + }
  32957. +
  32958. + for (devClass = 0; devClass < maxMppGrp; devClass++)
  32959. + {
  32960. + mppGroupType = mvBoardMppGroupTypeGet(devClass);
  32961. +
  32962. + switch(mppGroupType)
  32963. + {
  32964. + case MV_BOARD_TDM:
  32965. + if(devId != MV_6190_DEV_ID)
  32966. + mvOsPrintf("Module %d is TDM\n", devClass);
  32967. + break;
  32968. + case MV_BOARD_AUDIO:
  32969. + if(devId != MV_6190_DEV_ID)
  32970. + mvOsPrintf("Module %d is AUDIO\n", devClass);
  32971. + break;
  32972. + case MV_BOARD_RGMII:
  32973. + if(devId != MV_6190_DEV_ID)
  32974. + mvOsPrintf("Module %d is RGMII\n", devClass);
  32975. + break;
  32976. + case MV_BOARD_GMII:
  32977. + if(devId != MV_6190_DEV_ID)
  32978. + mvOsPrintf("Module %d is GMII\n", devClass);
  32979. + break;
  32980. + case MV_BOARD_TS:
  32981. + if(devId != MV_6190_DEV_ID)
  32982. + mvOsPrintf("Module %d is TS\n", devClass);
  32983. + break;
  32984. + default:
  32985. + break;
  32986. + }
  32987. + }
  32988. +}
  32989. +
  32990. +/* Board devices API managments */
  32991. +
  32992. +/*******************************************************************************
  32993. +* mvBoardGetDeviceNumber - Get number of device of some type on the board
  32994. +*
  32995. +* DESCRIPTION:
  32996. +*
  32997. +* INPUT:
  32998. +* devType - The device type ( Flash,RTC , etc .. )
  32999. +*
  33000. +* OUTPUT:
  33001. +* None.
  33002. +*
  33003. +* RETURN:
  33004. +* If the device is found on the board the then the functions returns the
  33005. +* number of those devices else the function returns 0
  33006. +*
  33007. +*
  33008. +*******************************************************************************/
  33009. +MV_32 mvBoardGetDevicesNumber(MV_BOARD_DEV_CLASS devClass)
  33010. +{
  33011. + MV_U32 foundIndex=0,devNum;
  33012. + MV_U32 boardId= mvBoardIdGet();
  33013. +
  33014. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33015. + {
  33016. + mvOsPrintf("mvBoardGetDeviceNumber:Board unknown.\n");
  33017. + return 0xFFFFFFFF;
  33018. +
  33019. + }
  33020. +
  33021. + for (devNum = START_DEV_CS; devNum < BOARD_INFO(boardId)->numBoardDeviceIf; devNum++)
  33022. + {
  33023. + if (BOARD_INFO(boardId)->pDevCsInfo[devNum].devClass == devClass)
  33024. + {
  33025. + foundIndex++;
  33026. + }
  33027. + }
  33028. +
  33029. + return foundIndex;
  33030. +
  33031. +}
  33032. +
  33033. +/*******************************************************************************
  33034. +* mvBoardGetDeviceBaseAddr - Get base address of a device existing on the board
  33035. +*
  33036. +* DESCRIPTION:
  33037. +*
  33038. +* INPUT:
  33039. +* devIndex - The device sequential number on the board
  33040. +* devType - The device type ( Flash,RTC , etc .. )
  33041. +*
  33042. +* OUTPUT:
  33043. +* None.
  33044. +*
  33045. +* RETURN:
  33046. +* If the device is found on the board the then the functions returns the
  33047. +* Base address else the function returns 0xffffffff
  33048. +*
  33049. +*
  33050. +*******************************************************************************/
  33051. +MV_32 mvBoardGetDeviceBaseAddr(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  33052. +{
  33053. + MV_DEV_CS_INFO* devEntry;
  33054. + devEntry = boardGetDevEntry(devNum,devClass);
  33055. + if (devEntry != NULL)
  33056. + {
  33057. + return mvCpuIfTargetWinBaseLowGet(DEV_TO_TARGET(devEntry->deviceCS));
  33058. +
  33059. + }
  33060. +
  33061. + return 0xFFFFFFFF;
  33062. +}
  33063. +
  33064. +/*******************************************************************************
  33065. +* mvBoardGetDeviceBusWidth - Get Bus width of a device existing on the board
  33066. +*
  33067. +* DESCRIPTION:
  33068. +*
  33069. +* INPUT:
  33070. +* devIndex - The device sequential number on the board
  33071. +* devType - The device type ( Flash,RTC , etc .. )
  33072. +*
  33073. +* OUTPUT:
  33074. +* None.
  33075. +*
  33076. +* RETURN:
  33077. +* If the device is found on the board the then the functions returns the
  33078. +* Bus width else the function returns 0xffffffff
  33079. +*
  33080. +*
  33081. +*******************************************************************************/
  33082. +MV_32 mvBoardGetDeviceBusWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  33083. +{
  33084. + MV_DEV_CS_INFO* devEntry;
  33085. +
  33086. + devEntry = boardGetDevEntry(devNum,devClass);
  33087. + if (devEntry != NULL)
  33088. + {
  33089. + return 8;
  33090. + }
  33091. +
  33092. + return 0xFFFFFFFF;
  33093. +
  33094. +}
  33095. +
  33096. +/*******************************************************************************
  33097. +* mvBoardGetDeviceWidth - Get dev width of a device existing on the board
  33098. +*
  33099. +* DESCRIPTION:
  33100. +*
  33101. +* INPUT:
  33102. +* devIndex - The device sequential number on the board
  33103. +* devType - The device type ( Flash,RTC , etc .. )
  33104. +*
  33105. +* OUTPUT:
  33106. +* None.
  33107. +*
  33108. +* RETURN:
  33109. +* If the device is found on the board the then the functions returns the
  33110. +* dev width else the function returns 0xffffffff
  33111. +*
  33112. +*
  33113. +*******************************************************************************/
  33114. +MV_32 mvBoardGetDeviceWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  33115. +{
  33116. + MV_DEV_CS_INFO* devEntry;
  33117. + MV_U32 boardId= mvBoardIdGet();
  33118. +
  33119. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33120. + {
  33121. + mvOsPrintf("Board unknown.\n");
  33122. + return 0xFFFFFFFF;
  33123. + }
  33124. +
  33125. + devEntry = boardGetDevEntry(devNum,devClass);
  33126. + if (devEntry != NULL)
  33127. + return devEntry->devWidth;
  33128. +
  33129. + return MV_ERROR;
  33130. +
  33131. +}
  33132. +
  33133. +/*******************************************************************************
  33134. +* mvBoardGetDeviceWinSize - Get the window size of a device existing on the board
  33135. +*
  33136. +* DESCRIPTION:
  33137. +*
  33138. +* INPUT:
  33139. +* devIndex - The device sequential number on the board
  33140. +* devType - The device type ( Flash,RTC , etc .. )
  33141. +*
  33142. +* OUTPUT:
  33143. +* None.
  33144. +*
  33145. +* RETURN:
  33146. +* If the device is found on the board the then the functions returns the
  33147. +* window size else the function returns 0xffffffff
  33148. +*
  33149. +*
  33150. +*******************************************************************************/
  33151. +MV_32 mvBoardGetDeviceWinSize(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  33152. +{
  33153. + MV_DEV_CS_INFO* devEntry;
  33154. + MV_U32 boardId = mvBoardIdGet();
  33155. +
  33156. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33157. + {
  33158. + mvOsPrintf("Board unknown.\n");
  33159. + return 0xFFFFFFFF;
  33160. + }
  33161. +
  33162. + devEntry = boardGetDevEntry(devNum,devClass);
  33163. + if (devEntry != NULL)
  33164. + {
  33165. + return mvCpuIfTargetWinSizeGet(DEV_TO_TARGET(devEntry->deviceCS));
  33166. + }
  33167. +
  33168. + return 0xFFFFFFFF;
  33169. +}
  33170. +
  33171. +
  33172. +/*******************************************************************************
  33173. +* boardGetDevEntry - returns the entry pointer of a device on the board
  33174. +*
  33175. +* DESCRIPTION:
  33176. +*
  33177. +* INPUT:
  33178. +* devIndex - The device sequential number on the board
  33179. +* devType - The device type ( Flash,RTC , etc .. )
  33180. +*
  33181. +* OUTPUT:
  33182. +* None.
  33183. +*
  33184. +* RETURN:
  33185. +* If the device is found on the board the then the functions returns the
  33186. +* dev number else the function returns 0x0
  33187. +*
  33188. +*
  33189. +*******************************************************************************/
  33190. +static MV_DEV_CS_INFO* boardGetDevEntry(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  33191. +{
  33192. + MV_U32 foundIndex=0,devIndex;
  33193. + MV_U32 boardId= mvBoardIdGet();
  33194. +
  33195. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33196. + {
  33197. + mvOsPrintf("boardGetDevEntry: Board unknown.\n");
  33198. + return NULL;
  33199. +
  33200. + }
  33201. +
  33202. + for (devIndex = START_DEV_CS; devIndex < BOARD_INFO(boardId)->numBoardDeviceIf; devIndex++)
  33203. + {
  33204. + /* TBR */
  33205. + /*if (BOARD_INFO(boardId)->pDevCsInfo[devIndex].deviceCS == MV_BOOTDEVICE_INDEX)
  33206. + continue;*/
  33207. +
  33208. + if (BOARD_INFO(boardId)->pDevCsInfo[devIndex].devClass == devClass)
  33209. + {
  33210. + if (foundIndex == devNum)
  33211. + {
  33212. + return &(BOARD_INFO(boardId)->pDevCsInfo[devIndex]);
  33213. + }
  33214. + foundIndex++;
  33215. + }
  33216. + }
  33217. +
  33218. + /* device not found */
  33219. + return NULL;
  33220. +}
  33221. +
  33222. +/* Get device CS number */
  33223. +
  33224. +MV_U32 boardGetDevCSNum(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  33225. +{
  33226. + MV_DEV_CS_INFO* devEntry;
  33227. + MV_U32 boardId= mvBoardIdGet();
  33228. +
  33229. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33230. + {
  33231. + mvOsPrintf("Board unknown.\n");
  33232. + return 0xFFFFFFFF;
  33233. +
  33234. + }
  33235. +
  33236. +
  33237. + devEntry = boardGetDevEntry(devNum,devClass);
  33238. + if (devEntry != NULL)
  33239. + return devEntry->deviceCS;
  33240. +
  33241. + return 0xFFFFFFFF;
  33242. +
  33243. +}
  33244. +
  33245. +/*******************************************************************************
  33246. +* mvBoardRtcTwsiAddrTypeGet -
  33247. +*
  33248. +* DESCRIPTION:
  33249. +*
  33250. +* INPUT:
  33251. +*
  33252. +* OUTPUT:
  33253. +* None.
  33254. +*
  33255. +* RETURN:
  33256. +*
  33257. +*
  33258. +*******************************************************************************/
  33259. +MV_U8 mvBoardRtcTwsiAddrTypeGet()
  33260. +{
  33261. + int i;
  33262. + MV_U32 boardId= mvBoardIdGet();
  33263. +
  33264. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  33265. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_RTC)
  33266. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
  33267. + return (MV_ERROR);
  33268. +}
  33269. +
  33270. +/*******************************************************************************
  33271. +* mvBoardRtcTwsiAddrGet -
  33272. +*
  33273. +* DESCRIPTION:
  33274. +*
  33275. +* INPUT:
  33276. +*
  33277. +* OUTPUT:
  33278. +* None.
  33279. +*
  33280. +* RETURN:
  33281. +*
  33282. +*
  33283. +*******************************************************************************/
  33284. +MV_U8 mvBoardRtcTwsiAddrGet()
  33285. +{
  33286. + int i;
  33287. + MV_U32 boardId= mvBoardIdGet();
  33288. +
  33289. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  33290. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_RTC)
  33291. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
  33292. + return (0xFF);
  33293. +}
  33294. +
  33295. +/*******************************************************************************
  33296. +* mvBoardA2DTwsiAddrTypeGet -
  33297. +*
  33298. +* DESCRIPTION:
  33299. +*
  33300. +* INPUT:
  33301. +*
  33302. +* OUTPUT:
  33303. +* None.
  33304. +*
  33305. +* RETURN:
  33306. +*
  33307. +*
  33308. +*******************************************************************************/
  33309. +MV_U8 mvBoardA2DTwsiAddrTypeGet()
  33310. +{
  33311. + int i;
  33312. + MV_U32 boardId= mvBoardIdGet();
  33313. +
  33314. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  33315. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_AUDIO_DEC)
  33316. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
  33317. + return (MV_ERROR);
  33318. +}
  33319. +
  33320. +/*******************************************************************************
  33321. +* mvBoardA2DTwsiAddrGet -
  33322. +*
  33323. +* DESCRIPTION:
  33324. +*
  33325. +* INPUT:
  33326. +*
  33327. +* OUTPUT:
  33328. +* None.
  33329. +*
  33330. +* RETURN:
  33331. +*
  33332. +*
  33333. +*******************************************************************************/
  33334. +MV_U8 mvBoardA2DTwsiAddrGet()
  33335. +{
  33336. + int i;
  33337. + MV_U32 boardId= mvBoardIdGet();
  33338. +
  33339. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  33340. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_AUDIO_DEC)
  33341. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
  33342. + return (0xFF);
  33343. +}
  33344. +
  33345. +/*******************************************************************************
  33346. +* mvBoardTwsiExpAddrTypeGet -
  33347. +*
  33348. +* DESCRIPTION:
  33349. +*
  33350. +* INPUT:
  33351. +*
  33352. +* OUTPUT:
  33353. +* None.
  33354. +*
  33355. +* RETURN:
  33356. +*
  33357. +*
  33358. +*******************************************************************************/
  33359. +MV_U8 mvBoardTwsiExpAddrTypeGet(MV_U32 index)
  33360. +{
  33361. + int i;
  33362. + MV_U32 indexFound = 0;
  33363. + MV_U32 boardId= mvBoardIdGet();
  33364. +
  33365. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  33366. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_EXP)
  33367. + {
  33368. + if (indexFound == index)
  33369. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
  33370. + else
  33371. + indexFound++;
  33372. + }
  33373. +
  33374. + return (MV_ERROR);
  33375. +}
  33376. +
  33377. +/*******************************************************************************
  33378. +* mvBoardTwsiExpAddrGet -
  33379. +*
  33380. +* DESCRIPTION:
  33381. +*
  33382. +* INPUT:
  33383. +*
  33384. +* OUTPUT:
  33385. +* None.
  33386. +*
  33387. +* RETURN:
  33388. +*
  33389. +*
  33390. +*******************************************************************************/
  33391. +MV_U8 mvBoardTwsiExpAddrGet(MV_U32 index)
  33392. +{
  33393. + int i;
  33394. + MV_U32 indexFound = 0;
  33395. + MV_U32 boardId= mvBoardIdGet();
  33396. +
  33397. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  33398. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_EXP)
  33399. + {
  33400. + if (indexFound == index)
  33401. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
  33402. + else
  33403. + indexFound++;
  33404. + }
  33405. +
  33406. + return (0xFF);
  33407. +}
  33408. +
  33409. +
  33410. +/*******************************************************************************
  33411. +* mvBoardTwsiSatRAddrTypeGet -
  33412. +*
  33413. +* DESCRIPTION:
  33414. +*
  33415. +* INPUT:
  33416. +*
  33417. +* OUTPUT:
  33418. +* None.
  33419. +*
  33420. +* RETURN:
  33421. +*
  33422. +*
  33423. +*******************************************************************************/
  33424. +MV_U8 mvBoardTwsiSatRAddrTypeGet(MV_U32 index)
  33425. +{
  33426. + int i;
  33427. + MV_U32 indexFound = 0;
  33428. + MV_U32 boardId= mvBoardIdGet();
  33429. +
  33430. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  33431. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_SATR)
  33432. + {
  33433. + if (indexFound == index)
  33434. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
  33435. + else
  33436. + indexFound++;
  33437. + }
  33438. +
  33439. + return (MV_ERROR);
  33440. +}
  33441. +
  33442. +/*******************************************************************************
  33443. +* mvBoardTwsiSatRAddrGet -
  33444. +*
  33445. +* DESCRIPTION:
  33446. +*
  33447. +* INPUT:
  33448. +*
  33449. +* OUTPUT:
  33450. +* None.
  33451. +*
  33452. +* RETURN:
  33453. +*
  33454. +*
  33455. +*******************************************************************************/
  33456. +MV_U8 mvBoardTwsiSatRAddrGet(MV_U32 index)
  33457. +{
  33458. + int i;
  33459. + MV_U32 indexFound = 0;
  33460. + MV_U32 boardId= mvBoardIdGet();
  33461. +
  33462. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  33463. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_SATR)
  33464. + {
  33465. + if (indexFound == index)
  33466. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
  33467. + else
  33468. + indexFound++;
  33469. + }
  33470. +
  33471. + return (0xFF);
  33472. +}
  33473. +
  33474. +/*******************************************************************************
  33475. +* mvBoardNandWidthGet -
  33476. +*
  33477. +* DESCRIPTION: Get the width of the first NAND device in byte.
  33478. +*
  33479. +* INPUT:
  33480. +*
  33481. +* OUTPUT:
  33482. +* None.
  33483. +*
  33484. +* RETURN: 1, 2, 4 or MV_ERROR
  33485. +*
  33486. +*
  33487. +*******************************************************************************/
  33488. +/* */
  33489. +MV_32 mvBoardNandWidthGet(void)
  33490. +{
  33491. + MV_U32 devNum;
  33492. + MV_U32 devWidth;
  33493. + MV_U32 boardId= mvBoardIdGet();
  33494. +
  33495. + for (devNum = START_DEV_CS; devNum < BOARD_INFO(boardId)->numBoardDeviceIf; devNum++)
  33496. + {
  33497. + devWidth = mvBoardGetDeviceWidth(devNum, BOARD_DEV_NAND_FLASH);
  33498. + if (devWidth != MV_ERROR)
  33499. + return (devWidth / 8);
  33500. + }
  33501. +
  33502. + /* NAND wasn't found */
  33503. + return MV_ERROR;
  33504. +}
  33505. +
  33506. +MV_U32 gBoardId = -1;
  33507. +
  33508. +/*******************************************************************************
  33509. +* mvBoardIdGet - Get Board model
  33510. +*
  33511. +* DESCRIPTION:
  33512. +* This function returns board ID.
  33513. +* Board ID is 32bit word constructed of board model (16bit) and
  33514. +* board revision (16bit) in the following way: 0xMMMMRRRR.
  33515. +*
  33516. +* INPUT:
  33517. +* None.
  33518. +*
  33519. +* OUTPUT:
  33520. +* None.
  33521. +*
  33522. +* RETURN:
  33523. +* 32bit board ID number, '-1' if board is undefined.
  33524. +*
  33525. +*******************************************************************************/
  33526. +MV_U32 mvBoardIdGet(MV_VOID)
  33527. +{
  33528. + MV_U32 tmpBoardId = -1;
  33529. +
  33530. + if(gBoardId == -1)
  33531. + {
  33532. + #if defined(DB_88F6281A)
  33533. + tmpBoardId = DB_88F6281A_BP_ID;
  33534. + #elif defined(RD_88F6281A)
  33535. + tmpBoardId = RD_88F6281A_ID;
  33536. + #elif defined(DB_88F6192A)
  33537. + tmpBoardId = DB_88F6192A_BP_ID;
  33538. + #elif defined(DB_88F6190A)
  33539. + tmpBoardId = DB_88F6190A_BP_ID;
  33540. + #elif defined(RD_88F6192A)
  33541. + tmpBoardId = RD_88F6192A_ID;
  33542. + #elif defined(RD_88F6190A)
  33543. + tmpBoardId = RD_88F6190A_ID;
  33544. + #elif defined(DB_88F6180A)
  33545. + tmpBoardId = DB_88F6180A_BP_ID;
  33546. + #elif defined(RD_88F6281A_PCAC)
  33547. + tmpBoardId = RD_88F6281A_PCAC_ID;
  33548. + #elif defined(RD_88F6281A_SHEEVA_PLUG)
  33549. + tmpBoardId = SHEEVA_PLUG_ID;
  33550. + #elif defined(DB_CUSTOMER)
  33551. + tmpBoardId = DB_CUSTOMER_ID;
  33552. + #endif
  33553. + gBoardId = tmpBoardId;
  33554. + }
  33555. +
  33556. + return gBoardId;
  33557. +}
  33558. +
  33559. +
  33560. +/*******************************************************************************
  33561. +* mvBoarModuleTypeGet - mvBoarModuleTypeGet
  33562. +*
  33563. +* DESCRIPTION:
  33564. +*
  33565. +* INPUT:
  33566. +* group num - MV_BOARD_MPP_GROUP_CLASS enum
  33567. +*
  33568. +* OUTPUT:
  33569. +* None.
  33570. +*
  33571. +* RETURN:
  33572. +* module num - MV_BOARD_MODULE_CLASS enum
  33573. +*
  33574. +*******************************************************************************/
  33575. +MV_BOARD_MODULE_ID_CLASS mvBoarModuleTypeGet(MV_BOARD_MPP_GROUP_CLASS devClass)
  33576. +{
  33577. + MV_TWSI_SLAVE twsiSlave;
  33578. + MV_TWSI_ADDR slave;
  33579. + MV_U8 data;
  33580. +
  33581. + /* TWSI init */
  33582. + slave.type = ADDR7_BIT;
  33583. + slave.address = 0;
  33584. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  33585. +
  33586. + /* Read MPP module ID */
  33587. + DB(mvOsPrintf("Board: Read MPP module ID\n"));
  33588. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(devClass);
  33589. + twsiSlave.slaveAddr.type = mvBoardTwsiExpAddrTypeGet(devClass);
  33590. + twsiSlave.validOffset = MV_TRUE;
  33591. + /* Offset is the first command after the address which indicate the register number to be read
  33592. + in next operation */
  33593. + twsiSlave.offset = 0;
  33594. + twsiSlave.moreThen256 = MV_FALSE;
  33595. +
  33596. +
  33597. +
  33598. + if( MV_OK != mvTwsiRead (0, &twsiSlave, &data, 1) )
  33599. + {
  33600. + DB(mvOsPrintf("Board: Read MPP module ID fail\n"));
  33601. + return MV_ERROR;
  33602. + }
  33603. + DB(mvOsPrintf("Board: Read MPP module ID succeded\n"));
  33604. +
  33605. + return data;
  33606. +}
  33607. +
  33608. +/*******************************************************************************
  33609. +* mvBoarTwsiSatRGet -
  33610. +*
  33611. +* DESCRIPTION:
  33612. +*
  33613. +* INPUT:
  33614. +* device num - one of three devices
  33615. +* reg num - 0 or 1
  33616. +*
  33617. +* OUTPUT:
  33618. +* None.
  33619. +*
  33620. +* RETURN:
  33621. +* reg value
  33622. +*
  33623. +*******************************************************************************/
  33624. +MV_U8 mvBoarTwsiSatRGet(MV_U8 devNum, MV_U8 regNum)
  33625. +{
  33626. + MV_TWSI_SLAVE twsiSlave;
  33627. + MV_TWSI_ADDR slave;
  33628. + MV_U8 data;
  33629. +
  33630. + /* TWSI init */
  33631. + slave.type = ADDR7_BIT;
  33632. + slave.address = 0;
  33633. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  33634. +
  33635. + /* Read MPP module ID */
  33636. + DB(mvOsPrintf("Board: Read S@R device read\n"));
  33637. + twsiSlave.slaveAddr.address = mvBoardTwsiSatRAddrGet(devNum);
  33638. + twsiSlave.slaveAddr.type = mvBoardTwsiSatRAddrTypeGet(devNum);
  33639. + twsiSlave.validOffset = MV_TRUE;
  33640. + /* Use offset as command */
  33641. + twsiSlave.offset = regNum;
  33642. + twsiSlave.moreThen256 = MV_FALSE;
  33643. +
  33644. + if( MV_OK != mvTwsiRead (0, &twsiSlave, &data, 1) )
  33645. + {
  33646. + DB(mvOsPrintf("Board: Read S@R fail\n"));
  33647. + return MV_ERROR;
  33648. + }
  33649. + DB(mvOsPrintf("Board: Read S@R succeded\n"));
  33650. +
  33651. + return data;
  33652. +}
  33653. +
  33654. +/*******************************************************************************
  33655. +* mvBoarTwsiSatRSet -
  33656. +*
  33657. +* DESCRIPTION:
  33658. +*
  33659. +* INPUT:
  33660. +* devNum - one of three devices
  33661. +* regNum - 0 or 1
  33662. +* regVal - value
  33663. +*
  33664. +*
  33665. +* OUTPUT:
  33666. +* None.
  33667. +*
  33668. +* RETURN:
  33669. +* reg value
  33670. +*
  33671. +*******************************************************************************/
  33672. +MV_STATUS mvBoarTwsiSatRSet(MV_U8 devNum, MV_U8 regNum, MV_U8 regVal)
  33673. +{
  33674. + MV_TWSI_SLAVE twsiSlave;
  33675. + MV_TWSI_ADDR slave;
  33676. +
  33677. + /* TWSI init */
  33678. + slave.type = ADDR7_BIT;
  33679. + slave.address = 0;
  33680. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  33681. +
  33682. + /* Read MPP module ID */
  33683. + twsiSlave.slaveAddr.address = mvBoardTwsiSatRAddrGet(devNum);
  33684. + twsiSlave.slaveAddr.type = mvBoardTwsiSatRAddrTypeGet(devNum);
  33685. + twsiSlave.validOffset = MV_TRUE;
  33686. + DB(mvOsPrintf("Board: Write S@R device addr %x, type %x, data %x\n", twsiSlave.slaveAddr.address,\
  33687. + twsiSlave.slaveAddr.type, regVal));
  33688. + /* Use offset as command */
  33689. + twsiSlave.offset = regNum;
  33690. + twsiSlave.moreThen256 = MV_FALSE;
  33691. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &regVal, 1) )
  33692. + {
  33693. + DB(mvOsPrintf("Board: Write S@R fail\n"));
  33694. + return MV_ERROR;
  33695. + }
  33696. + DB(mvOsPrintf("Board: Write S@R succeded\n"));
  33697. +
  33698. + return MV_OK;
  33699. +}
  33700. +
  33701. +/*******************************************************************************
  33702. +* mvBoardSlicGpioPinGet -
  33703. +*
  33704. +* DESCRIPTION:
  33705. +*
  33706. +* INPUT:
  33707. +*
  33708. +* OUTPUT:
  33709. +* None.
  33710. +*
  33711. +* RETURN:
  33712. +*
  33713. +*
  33714. +*******************************************************************************/
  33715. +MV_32 mvBoardSlicGpioPinGet(MV_U32 slicNum)
  33716. +{
  33717. + MV_U32 boardId;
  33718. + boardId = mvBoardIdGet();
  33719. +
  33720. + switch (boardId)
  33721. + {
  33722. + case DB_88F6281A_BP_ID:
  33723. + case RD_88F6281A_ID:
  33724. + default:
  33725. + return MV_ERROR;
  33726. + break;
  33727. +
  33728. + }
  33729. +}
  33730. +
  33731. +/*******************************************************************************
  33732. +* mvBoardFanPowerControl - Turn on/off the fan power control on the RD-6281A
  33733. +*
  33734. +* DESCRIPTION:
  33735. +*
  33736. +* INPUT:
  33737. +* mode - MV_TRUE = on ; MV_FALSE = off
  33738. +*
  33739. +* OUTPUT:
  33740. +* MV_STATUS - MV_OK , MV_ERROR.
  33741. +*
  33742. +* RETURN:
  33743. +*
  33744. +*******************************************************************************/
  33745. +MV_STATUS mvBoardFanPowerControl(MV_BOOL mode)
  33746. +{
  33747. +
  33748. + MV_U8 val = 1, twsiVal;
  33749. + MV_TWSI_SLAVE twsiSlave;
  33750. + MV_TWSI_ADDR slave;
  33751. +
  33752. + if(mvBoardIdGet() != RD_88F6281A_ID)
  33753. + return MV_ERROR;
  33754. +
  33755. + /* TWSI init */
  33756. + slave.type = ADDR7_BIT;
  33757. + slave.address = 0;
  33758. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  33759. +
  33760. + /* Read MPP module ID */
  33761. + DB(mvOsPrintf("Board: twsi exp set\n"));
  33762. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(1);
  33763. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  33764. + twsiSlave.validOffset = MV_TRUE;
  33765. + /* Offset is the first command after the address which indicate the register number to be read
  33766. + in next operation */
  33767. + twsiSlave.offset = 3;
  33768. + twsiSlave.moreThen256 = MV_FALSE;
  33769. + if(mode == MV_TRUE)
  33770. + val = 0x1;
  33771. + else
  33772. + val = 0;
  33773. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  33774. + val = (twsiVal & 0xfe) | val;
  33775. +
  33776. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  33777. + {
  33778. + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
  33779. + return MV_ERROR;
  33780. + }
  33781. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  33782. +
  33783. + /* Change twsi exp to output */
  33784. + twsiSlave.offset = 7;
  33785. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  33786. + val = (twsiVal & 0xfe);
  33787. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  33788. + {
  33789. + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
  33790. + return MV_ERROR;
  33791. + }
  33792. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  33793. + return MV_OK;
  33794. +}
  33795. +
  33796. +/*******************************************************************************
  33797. +* mvBoardHDDPowerControl - Turn on/off the HDD power control on the RD-6281A
  33798. +*
  33799. +* DESCRIPTION:
  33800. +*
  33801. +* INPUT:
  33802. +* mode - MV_TRUE = on ; MV_FALSE = off
  33803. +*
  33804. +* OUTPUT:
  33805. +* MV_STATUS - MV_OK , MV_ERROR.
  33806. +*
  33807. +* RETURN:
  33808. +*
  33809. +*******************************************************************************/
  33810. +MV_STATUS mvBoardHDDPowerControl(MV_BOOL mode)
  33811. +{
  33812. +
  33813. + MV_U8 val = 1, twsiVal;
  33814. + MV_TWSI_SLAVE twsiSlave;
  33815. + MV_TWSI_ADDR slave;
  33816. +
  33817. + if(mvBoardIdGet() != RD_88F6281A_ID)
  33818. + return MV_ERROR;
  33819. +
  33820. + /* TWSI init */
  33821. + slave.type = ADDR7_BIT;
  33822. + slave.address = 0;
  33823. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  33824. +
  33825. + /* Read MPP module ID */
  33826. + DB(mvOsPrintf("Board: twsi exp set\n"));
  33827. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(1);
  33828. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  33829. + twsiSlave.validOffset = MV_TRUE;
  33830. + /* Offset is the first command after the address which indicate the register number to be read
  33831. + in next operation */
  33832. + twsiSlave.offset = 3;
  33833. + twsiSlave.moreThen256 = MV_FALSE;
  33834. + if(mode == MV_TRUE)
  33835. + val = 0x2;
  33836. + else
  33837. + val = 0;
  33838. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  33839. + val = (twsiVal & 0xfd) | val;
  33840. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  33841. + {
  33842. + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
  33843. + return MV_ERROR;
  33844. + }
  33845. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  33846. +
  33847. + /* Change twsi exp to output */
  33848. + twsiSlave.offset = 7;
  33849. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  33850. + val = (twsiVal & 0xfd);
  33851. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  33852. + {
  33853. + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
  33854. + return MV_ERROR;
  33855. + }
  33856. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  33857. + return MV_OK;
  33858. +}
  33859. +
  33860. +/*******************************************************************************
  33861. +* mvBoardSDioWPControl - Turn on/off the SDIO WP on the RD-6281A
  33862. +*
  33863. +* DESCRIPTION:
  33864. +*
  33865. +* INPUT:
  33866. +* mode - MV_TRUE = on ; MV_FALSE = off
  33867. +*
  33868. +* OUTPUT:
  33869. +* MV_STATUS - MV_OK , MV_ERROR.
  33870. +*
  33871. +* RETURN:
  33872. +*
  33873. +*******************************************************************************/
  33874. +MV_STATUS mvBoardSDioWPControl(MV_BOOL mode)
  33875. +{
  33876. +
  33877. + MV_U8 val = 1, twsiVal;
  33878. + MV_TWSI_SLAVE twsiSlave;
  33879. + MV_TWSI_ADDR slave;
  33880. +
  33881. + if(mvBoardIdGet() != RD_88F6281A_ID)
  33882. + return MV_ERROR;
  33883. +
  33884. + /* TWSI init */
  33885. + slave.type = ADDR7_BIT;
  33886. + slave.address = 0;
  33887. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  33888. +
  33889. + /* Read MPP module ID */
  33890. + DB(mvOsPrintf("Board: twsi exp set\n"));
  33891. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(0);
  33892. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  33893. + twsiSlave.validOffset = MV_TRUE;
  33894. + /* Offset is the first command after the address which indicate the register number to be read
  33895. + in next operation */
  33896. + twsiSlave.offset = 3;
  33897. + twsiSlave.moreThen256 = MV_FALSE;
  33898. + if(mode == MV_TRUE)
  33899. + val = 0x10;
  33900. + else
  33901. + val = 0;
  33902. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  33903. + val = (twsiVal & 0xef) | val;
  33904. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  33905. + {
  33906. + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
  33907. + return MV_ERROR;
  33908. + }
  33909. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  33910. +
  33911. + /* Change twsi exp to output */
  33912. + twsiSlave.offset = 7;
  33913. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  33914. + val = (twsiVal & 0xef);
  33915. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  33916. + {
  33917. + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
  33918. + return MV_ERROR;
  33919. + }
  33920. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  33921. + return MV_OK;
  33922. +}
  33923. +
  33924. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h
  33925. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h 1970-01-01 01:00:00.000000000 +0100
  33926. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h 2010-08-05 22:02:15.713631957 +0200
  33927. @@ -0,0 +1,376 @@
  33928. +/*******************************************************************************
  33929. +Copyright (C) Marvell International Ltd. and its affiliates
  33930. +
  33931. +This software file (the "File") is owned and distributed by Marvell
  33932. +International Ltd. and/or its affiliates ("Marvell") under the following
  33933. +alternative licensing terms. Once you have made an election to distribute the
  33934. +File under one of the following license alternatives, please (i) delete this
  33935. +introductory statement regarding license alternatives, (ii) delete the two
  33936. +license alternatives that you have not elected to use and (iii) preserve the
  33937. +Marvell copyright notice above.
  33938. +
  33939. +********************************************************************************
  33940. +Marvell Commercial License Option
  33941. +
  33942. +If you received this File from Marvell and you have entered into a commercial
  33943. +license agreement (a "Commercial License") with Marvell, the File is licensed
  33944. +to you under the terms of the applicable Commercial License.
  33945. +
  33946. +********************************************************************************
  33947. +Marvell GPL License Option
  33948. +
  33949. +If you received this File from Marvell, you may opt to use, redistribute and/or
  33950. +modify this File in accordance with the terms and conditions of the General
  33951. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  33952. +available along with the File in the license.txt file or by writing to the Free
  33953. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  33954. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  33955. +
  33956. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  33957. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  33958. +DISCLAIMED. The GPL License provides additional details about this warranty
  33959. +disclaimer.
  33960. +********************************************************************************
  33961. +Marvell BSD License Option
  33962. +
  33963. +If you received this File from Marvell, you may opt to use, redistribute and/or
  33964. +modify this File under the following licensing terms.
  33965. +Redistribution and use in source and binary forms, with or without modification,
  33966. +are permitted provided that the following conditions are met:
  33967. +
  33968. + * Redistributions of source code must retain the above copyright notice,
  33969. + this list of conditions and the following disclaimer.
  33970. +
  33971. + * Redistributions in binary form must reproduce the above copyright
  33972. + notice, this list of conditions and the following disclaimer in the
  33973. + documentation and/or other materials provided with the distribution.
  33974. +
  33975. + * Neither the name of Marvell nor the names of its contributors may be
  33976. + used to endorse or promote products derived from this software without
  33977. + specific prior written permission.
  33978. +
  33979. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  33980. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  33981. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  33982. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  33983. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  33984. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  33985. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  33986. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  33987. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  33988. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  33989. +
  33990. +*******************************************************************************/
  33991. +#ifndef __INCmvBoardEnvLibh
  33992. +#define __INCmvBoardEnvLibh
  33993. +
  33994. +/* defines */
  33995. +/* The below constant macros defines the board I2C EEPROM data offsets */
  33996. +
  33997. +
  33998. +
  33999. +#include "ctrlEnv/mvCtrlEnvLib.h"
  34000. +#include "mvSysHwConfig.h"
  34001. +#include "boardEnv/mvBoardEnvSpec.h"
  34002. +
  34003. +
  34004. +/* DUART stuff for Tclk detection only */
  34005. +#define DUART_BAUD_RATE 115200
  34006. +#define MAX_CLOCK_MARGINE 5000000 /* Maximum detected clock margine */
  34007. +
  34008. +/* Voice devices assembly modes */
  34009. +#define DAISY_CHAIN_MODE 1
  34010. +#define DUAL_CHIP_SELECT_MODE 0
  34011. +#define INTERRUPT_TO_MPP 1
  34012. +#define INTERRUPT_TO_TDM 0
  34013. +
  34014. +
  34015. +#define BOARD_ETH_PORT_NUM MV_ETH_MAX_PORTS
  34016. +#define BOARD_ETH_SWITCH_PORT_NUM 5
  34017. +
  34018. +#define MV_BOARD_MAX_USB_IF 1
  34019. +#define MV_BOARD_MAX_MPP 7
  34020. +#define MV_BOARD_NAME_LEN 0x20
  34021. +
  34022. +typedef struct _boardData
  34023. +{
  34024. + MV_U32 magic;
  34025. + MV_U16 boardId;
  34026. + MV_U8 boardVer;
  34027. + MV_U8 boardRev;
  34028. + MV_U32 reserved1;
  34029. + MV_U32 reserved2;
  34030. +
  34031. +}BOARD_DATA;
  34032. +
  34033. +typedef enum _devBoardMppGroupClass
  34034. +{
  34035. + MV_BOARD_MPP_GROUP_1,
  34036. + MV_BOARD_MPP_GROUP_2,
  34037. + MV_BOARD_MAX_MPP_GROUP
  34038. +}MV_BOARD_MPP_GROUP_CLASS;
  34039. +
  34040. +typedef enum _devBoardMppTypeClass
  34041. +{
  34042. + MV_BOARD_AUTO,
  34043. + MV_BOARD_TDM,
  34044. + MV_BOARD_AUDIO,
  34045. + MV_BOARD_RGMII,
  34046. + MV_BOARD_GMII,
  34047. + MV_BOARD_TS,
  34048. + MV_BOARD_MII,
  34049. + MV_BOARD_OTHER
  34050. +}MV_BOARD_MPP_TYPE_CLASS;
  34051. +
  34052. +typedef enum _devBoardModuleIdClass
  34053. +{
  34054. + MV_BOARD_MODULE_TDM_ID = 1,
  34055. + MV_BOARD_MODULE_AUDIO_ID,
  34056. + MV_BOARD_MODULE_RGMII_ID,
  34057. + MV_BOARD_MODULE_GMII_ID,
  34058. + MV_BOARD_MODULE_TS_ID,
  34059. + MV_BOARD_MODULE_MII_ID,
  34060. + MV_BOARD_MODULE_TDM_5CHAN_ID,
  34061. + MV_BOARD_MODULE_OTHER_ID
  34062. +}MV_BOARD_MODULE_ID_CLASS;
  34063. +
  34064. +typedef struct _boardMppTypeInfo
  34065. +{
  34066. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup1;
  34067. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2;
  34068. +
  34069. +}MV_BOARD_MPP_TYPE_INFO;
  34070. +
  34071. +
  34072. +typedef enum _devBoardClass
  34073. +{
  34074. + BOARD_DEV_NOR_FLASH,
  34075. + BOARD_DEV_NAND_FLASH,
  34076. + BOARD_DEV_SEVEN_SEG,
  34077. + BOARD_DEV_FPGA,
  34078. + BOARD_DEV_SRAM,
  34079. + BOARD_DEV_SPI_FLASH,
  34080. + BOARD_DEV_OTHER,
  34081. +}MV_BOARD_DEV_CLASS;
  34082. +
  34083. +typedef enum _devTwsiBoardClass
  34084. +{
  34085. + BOARD_TWSI_RTC,
  34086. + BOARD_DEV_TWSI_EXP,
  34087. + BOARD_DEV_TWSI_SATR,
  34088. + BOARD_TWSI_AUDIO_DEC,
  34089. + BOARD_TWSI_OTHER
  34090. +}MV_BOARD_TWSI_CLASS;
  34091. +
  34092. +typedef enum _devGppBoardClass
  34093. +{
  34094. + BOARD_GPP_RTC,
  34095. + BOARD_GPP_MV_SWITCH,
  34096. + BOARD_GPP_USB_VBUS,
  34097. + BOARD_GPP_USB_VBUS_EN,
  34098. + BOARD_GPP_USB_OC,
  34099. + BOARD_GPP_USB_HOST_DEVICE,
  34100. + BOARD_GPP_REF_CLCK,
  34101. + BOARD_GPP_VOIP_SLIC,
  34102. + BOARD_GPP_LIFELINE,
  34103. + BOARD_GPP_BUTTON,
  34104. + BOARD_GPP_TS_BUTTON_C,
  34105. + BOARD_GPP_TS_BUTTON_U,
  34106. + BOARD_GPP_TS_BUTTON_D,
  34107. + BOARD_GPP_TS_BUTTON_L,
  34108. + BOARD_GPP_TS_BUTTON_R,
  34109. + BOARD_GPP_POWER_BUTTON,
  34110. + BOARD_GPP_RESTOR_BUTTON,
  34111. + BOARD_GPP_WPS_BUTTON,
  34112. + BOARD_GPP_HDD0_POWER,
  34113. + BOARD_GPP_HDD1_POWER,
  34114. + BOARD_GPP_FAN_POWER,
  34115. + BOARD_GPP_RESET,
  34116. + BOARD_GPP_POWER_ON_LED,
  34117. + BOARD_GPP_HDD_POWER,
  34118. + BOARD_GPP_SDIO_POWER,
  34119. + BOARD_GPP_SDIO_DETECT,
  34120. + BOARD_GPP_SDIO_WP,
  34121. + BOARD_GPP_SWITCH_PHY_INT,
  34122. + BOARD_GPP_TSU_DIRCTION,
  34123. + BOARD_GPP_OTHER
  34124. +}MV_BOARD_GPP_CLASS;
  34125. +
  34126. +
  34127. +typedef struct _devCsInfo
  34128. +{
  34129. + MV_U8 deviceCS;
  34130. + MV_U32 params;
  34131. + MV_U32 devClass; /* MV_BOARD_DEV_CLASS */
  34132. + MV_U8 devWidth;
  34133. +
  34134. +}MV_DEV_CS_INFO;
  34135. +
  34136. +
  34137. +#define MV_BOARD_PHY_FORCE_10MB 0x0
  34138. +#define MV_BOARD_PHY_FORCE_100MB 0x1
  34139. +#define MV_BOARD_PHY_FORCE_1000MB 0x2
  34140. +#define MV_BOARD_PHY_SPEED_AUTO 0x3
  34141. +
  34142. +typedef struct _boardSwitchInfo
  34143. +{
  34144. + MV_32 linkStatusIrq;
  34145. + MV_32 qdPort[BOARD_ETH_SWITCH_PORT_NUM];
  34146. + MV_32 qdCpuPort;
  34147. + MV_32 smiScanMode; /* 1 for SMI_MANUAL_MODE, 0 otherwise */
  34148. + MV_32 switchOnPort;
  34149. +
  34150. +}MV_BOARD_SWITCH_INFO;
  34151. +
  34152. +typedef struct _boardLedInfo
  34153. +{
  34154. + MV_U8 activeLedsNumber;
  34155. + MV_U8 ledsPolarity; /* '0' or '1' to turn on led */
  34156. + MV_U8* gppPinNum; /* Pointer to GPP values */
  34157. +
  34158. +}MV_BOARD_LED_INFO;
  34159. +
  34160. +typedef struct _boardGppInfo
  34161. +{
  34162. + MV_BOARD_GPP_CLASS devClass;
  34163. + MV_U8 gppPinNum;
  34164. +
  34165. +}MV_BOARD_GPP_INFO;
  34166. +
  34167. +
  34168. +typedef struct _boardTwsiInfo
  34169. +{
  34170. + MV_BOARD_TWSI_CLASS devClass;
  34171. + MV_U8 twsiDevAddr;
  34172. + MV_U8 twsiDevAddrType;
  34173. +
  34174. +}MV_BOARD_TWSI_INFO;
  34175. +
  34176. +
  34177. +typedef enum _boardMacSpeed
  34178. +{
  34179. + BOARD_MAC_SPEED_10M,
  34180. + BOARD_MAC_SPEED_100M,
  34181. + BOARD_MAC_SPEED_1000M,
  34182. + BOARD_MAC_SPEED_AUTO,
  34183. +
  34184. +}MV_BOARD_MAC_SPEED;
  34185. +
  34186. +typedef struct _boardMacInfo
  34187. +{
  34188. + MV_BOARD_MAC_SPEED boardMacSpeed;
  34189. + MV_U8 boardEthSmiAddr;
  34190. +
  34191. +}MV_BOARD_MAC_INFO;
  34192. +
  34193. +typedef struct _boardMppInfo
  34194. +{
  34195. + MV_U32 mppGroup[MV_BOARD_MAX_MPP];
  34196. +
  34197. +}MV_BOARD_MPP_INFO;
  34198. +
  34199. +typedef struct _boardInfo
  34200. +{
  34201. + char boardName[MV_BOARD_NAME_LEN];
  34202. + MV_U8 numBoardMppTypeValue;
  34203. + MV_BOARD_MPP_TYPE_INFO* pBoardMppTypeValue;
  34204. + MV_U8 numBoardMppConfigValue;
  34205. + MV_BOARD_MPP_INFO* pBoardMppConfigValue;
  34206. + MV_U32 intsGppMaskLow;
  34207. + MV_U32 intsGppMaskHigh;
  34208. + MV_U8 numBoardDeviceIf;
  34209. + MV_DEV_CS_INFO* pDevCsInfo;
  34210. + MV_U8 numBoardTwsiDev;
  34211. + MV_BOARD_TWSI_INFO* pBoardTwsiDev;
  34212. + MV_U8 numBoardMacInfo;
  34213. + MV_BOARD_MAC_INFO* pBoardMacInfo;
  34214. + MV_U8 numBoardGppInfo;
  34215. + MV_BOARD_GPP_INFO* pBoardGppInfo;
  34216. + MV_U8 activeLedsNumber;
  34217. + MV_U8* pLedGppPin;
  34218. + MV_U8 ledsPolarity; /* '0' or '1' to turn on led */
  34219. + /* GPP values */
  34220. + MV_U32 gppOutEnValLow;
  34221. + MV_U32 gppOutEnValHigh;
  34222. + MV_U32 gppOutValLow;
  34223. + MV_U32 gppOutValHigh;
  34224. + MV_U32 gppPolarityValLow;
  34225. + MV_U32 gppPolarityValHigh;
  34226. +
  34227. + /* Switch Configuration */
  34228. + MV_BOARD_SWITCH_INFO* pSwitchInfo;
  34229. +}MV_BOARD_INFO;
  34230. +
  34231. +
  34232. +
  34233. +MV_VOID mvBoardEnvInit(MV_VOID);
  34234. +MV_U32 mvBoardIdGet(MV_VOID);
  34235. +MV_U16 mvBoardModelGet(MV_VOID);
  34236. +MV_U16 mvBoardRevGet(MV_VOID);
  34237. +MV_STATUS mvBoardNameGet(char *pNameBuff);
  34238. +MV_32 mvBoardPhyAddrGet(MV_U32 ethPortNum);
  34239. +MV_BOARD_MAC_SPEED mvBoardMacSpeedGet(MV_U32 ethPortNum);
  34240. +MV_32 mvBoardLinkStatusIrqGet(MV_U32 ethPortNum);
  34241. +MV_32 mvBoardSwitchPortGet(MV_U32 ethPortNum, MV_U8 boardPortNum);
  34242. +MV_32 mvBoardSwitchCpuPortGet(MV_U32 ethPortNum);
  34243. +MV_32 mvBoardIsSwitchConnected(MV_U32 ethPortNum);
  34244. +MV_32 mvBoardSmiScanModeGet(MV_U32 ethPortNum);
  34245. +MV_BOOL mvBoardIsPortInSgmii(MV_U32 ethPortNum);
  34246. +MV_BOOL mvBoardIsPortInGmii(MV_VOID);
  34247. +MV_U32 mvBoardTclkGet(MV_VOID);
  34248. +MV_U32 mvBoardSysClkGet(MV_VOID);
  34249. +MV_U32 mvBoardDebugLedNumGet(MV_U32 boardId);
  34250. +MV_VOID mvBoardDebugLed(MV_U32 hexNum);
  34251. +MV_32 mvBoardMppGet(MV_U32 mppGroupNum);
  34252. +
  34253. +MV_U8 mvBoardRtcTwsiAddrTypeGet(MV_VOID);
  34254. +MV_U8 mvBoardRtcTwsiAddrGet(MV_VOID);
  34255. +
  34256. +MV_U8 mvBoardA2DTwsiAddrTypeGet(MV_VOID);
  34257. +MV_U8 mvBoardA2DTwsiAddrGet(MV_VOID);
  34258. +
  34259. +MV_U8 mvBoardTwsiExpAddrGet(MV_U32 index);
  34260. +MV_U8 mvBoardTwsiSatRAddrTypeGet(MV_U32 index);
  34261. +MV_U8 mvBoardTwsiSatRAddrGet(MV_U32 index);
  34262. +MV_U8 mvBoardTwsiExpAddrTypeGet(MV_U32 index);
  34263. +MV_BOARD_MODULE_ID_CLASS mvBoarModuleTypeGet(MV_BOARD_MPP_GROUP_CLASS devClass);
  34264. +MV_BOARD_MPP_TYPE_CLASS mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass);
  34265. +MV_VOID mvBoardMppGroupTypeSet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass,
  34266. + MV_BOARD_MPP_TYPE_CLASS mppGroupType);
  34267. +MV_VOID mvBoardMppGroupIdUpdate(MV_VOID);
  34268. +MV_VOID mvBoardMppMuxSet(MV_VOID);
  34269. +MV_VOID mvBoardTdmMppSet(MV_32 chType);
  34270. +MV_VOID mvBoardVoiceConnModeGet(MV_32* connMode, MV_32* irqMode);
  34271. +
  34272. +MV_VOID mvBoardMppModuleTypePrint(MV_VOID);
  34273. +MV_VOID mvBoardReset(MV_VOID);
  34274. +MV_U8 mvBoarTwsiSatRGet(MV_U8 devNum, MV_U8 regNum);
  34275. +MV_STATUS mvBoarTwsiSatRSet(MV_U8 devNum, MV_U8 regNum, MV_U8 regVal);
  34276. +MV_BOOL mvBoardSpecInitGet(MV_U32* regOff, MV_U32* data);
  34277. +/* Board devices API managments */
  34278. +MV_32 mvBoardGetDevicesNumber(MV_BOARD_DEV_CLASS devClass);
  34279. +MV_32 mvBoardGetDeviceBaseAddr(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  34280. +MV_32 mvBoardGetDeviceBusWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  34281. +MV_32 mvBoardGetDeviceWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  34282. +MV_32 mvBoardGetDeviceWinSize(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  34283. +MV_U32 boardGetDevCSNum(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  34284. +
  34285. +/* Gpio Pin Connections API */
  34286. +MV_32 mvBoardUSBVbusGpioPinGet(int devId);
  34287. +MV_32 mvBoardUSBVbusEnGpioPinGet(int devId);
  34288. +MV_U32 mvBoardPexBridgeIntPinGet(MV_U32 devNum, MV_U32 intPin);
  34289. +
  34290. +MV_32 mvBoardResetGpioPinGet(MV_VOID);
  34291. +MV_32 mvBoardRTCGpioPinGet(MV_VOID);
  34292. +MV_32 mvBoardGpioIntMaskLowGet(MV_VOID);
  34293. +MV_32 mvBoardGpioIntMaskHighGet(MV_VOID);
  34294. +MV_32 mvBoardSlicGpioPinGet(MV_U32 slicNum);
  34295. +
  34296. +MV_32 mvBoardSDIOGpioPinGet(MV_VOID);
  34297. +MV_STATUS mvBoardSDioWPControl(MV_BOOL mode);
  34298. +MV_32 mvBoarGpioPinNumGet(MV_BOARD_GPP_CLASS class, MV_U32 index);
  34299. +
  34300. +MV_32 mvBoardNandWidthGet(void);
  34301. +MV_STATUS mvBoardFanPowerControl(MV_BOOL mode);
  34302. +MV_STATUS mvBoardHDDPowerControl(MV_BOOL mode);
  34303. +#endif /* __INCmvBoardEnvLibh */
  34304. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c
  34305. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c 1970-01-01 01:00:00.000000000 +0100
  34306. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c 2010-08-05 22:02:15.853619328 +0200
  34307. @@ -0,0 +1,848 @@
  34308. +/*******************************************************************************
  34309. +Copyright (C) Marvell International Ltd. and its affiliates
  34310. +
  34311. +This software file (the "File") is owned and distributed by Marvell
  34312. +International Ltd. and/or its affiliates ("Marvell") under the following
  34313. +alternative licensing terms. Once you have made an election to distribute the
  34314. +File under one of the following license alternatives, please (i) delete this
  34315. +introductory statement regarding license alternatives, (ii) delete the two
  34316. +license alternatives that you have not elected to use and (iii) preserve the
  34317. +Marvell copyright notice above.
  34318. +
  34319. +********************************************************************************
  34320. +Marvell Commercial License Option
  34321. +
  34322. +If you received this File from Marvell and you have entered into a commercial
  34323. +license agreement (a "Commercial License") with Marvell, the File is licensed
  34324. +to you under the terms of the applicable Commercial License.
  34325. +
  34326. +********************************************************************************
  34327. +Marvell GPL License Option
  34328. +
  34329. +If you received this File from Marvell, you may opt to use, redistribute and/or
  34330. +modify this File in accordance with the terms and conditions of the General
  34331. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  34332. +available along with the File in the license.txt file or by writing to the Free
  34333. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  34334. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  34335. +
  34336. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  34337. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  34338. +DISCLAIMED. The GPL License provides additional details about this warranty
  34339. +disclaimer.
  34340. +********************************************************************************
  34341. +Marvell BSD License Option
  34342. +
  34343. +If you received this File from Marvell, you may opt to use, redistribute and/or
  34344. +modify this File under the following licensing terms.
  34345. +Redistribution and use in source and binary forms, with or without modification,
  34346. +are permitted provided that the following conditions are met:
  34347. +
  34348. + * Redistributions of source code must retain the above copyright notice,
  34349. + this list of conditions and the following disclaimer.
  34350. +
  34351. + * Redistributions in binary form must reproduce the above copyright
  34352. + notice, this list of conditions and the following disclaimer in the
  34353. + documentation and/or other materials provided with the distribution.
  34354. +
  34355. + * Neither the name of Marvell nor the names of its contributors may be
  34356. + used to endorse or promote products derived from this software without
  34357. + specific prior written permission.
  34358. +
  34359. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  34360. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  34361. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  34362. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  34363. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  34364. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  34365. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  34366. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  34367. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  34368. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  34369. +
  34370. +*******************************************************************************/
  34371. +#include "mvCommon.h"
  34372. +#include "mvBoardEnvLib.h"
  34373. +#include "mvBoardEnvSpec.h"
  34374. +#include "twsi/mvTwsi.h"
  34375. +
  34376. +#define DB_88F6281A_BOARD_PCI_IF_NUM 0x0
  34377. +#define DB_88F6281A_BOARD_TWSI_DEF_NUM 0x7
  34378. +#define DB_88F6281A_BOARD_MAC_INFO_NUM 0x2
  34379. +#define DB_88F6281A_BOARD_GPP_INFO_NUM 0x3
  34380. +#define DB_88F6281A_BOARD_MPP_CONFIG_NUM 0x1
  34381. +#define DB_88F6281A_BOARD_MPP_GROUP_TYPE_NUM 0x1
  34382. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  34383. + #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
  34384. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  34385. + #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x2
  34386. +#else
  34387. + #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
  34388. +#endif
  34389. +#define DB_88F6281A_BOARD_DEBUG_LED_NUM 0x0
  34390. +
  34391. +
  34392. +MV_BOARD_TWSI_INFO db88f6281AInfoBoardTwsiDev[] =
  34393. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  34394. + {
  34395. + {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},
  34396. + {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},
  34397. + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},
  34398. + {BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},
  34399. + {BOARD_DEV_TWSI_SATR, 0x4D, ADDR7_BIT},
  34400. + {BOARD_DEV_TWSI_SATR, 0x4E, ADDR7_BIT},
  34401. + {BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}
  34402. + };
  34403. +
  34404. +MV_BOARD_MAC_INFO db88f6281AInfoBoardMacInfo[] =
  34405. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  34406. + {
  34407. + {BOARD_MAC_SPEED_AUTO, 0x8},
  34408. + {BOARD_MAC_SPEED_AUTO, 0x9}
  34409. + };
  34410. +
  34411. +MV_BOARD_MPP_TYPE_INFO db88f6281AInfoBoardMppTypeInfo[] =
  34412. + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
  34413. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
  34414. + {{MV_BOARD_AUTO, MV_BOARD_AUTO}
  34415. + };
  34416. +
  34417. +MV_BOARD_GPP_INFO db88f6281AInfoBoardGppInfo[] =
  34418. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  34419. + {
  34420. + {BOARD_GPP_TSU_DIRCTION, 33}
  34421. + /*muxed with TDM/Audio module via IOexpender
  34422. + {BOARD_GPP_SDIO_DETECT, 38},
  34423. + {BOARD_GPP_USB_VBUS, 49}*/
  34424. + };
  34425. +
  34426. +MV_DEV_CS_INFO db88f6281AInfoBoardDeCsInfo[] =
  34427. + /*{deviceCS, params, devType, devWidth}*/
  34428. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  34429. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  34430. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  34431. + {
  34432. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  34433. + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  34434. + };
  34435. +#else
  34436. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  34437. +#endif
  34438. +
  34439. +MV_BOARD_MPP_INFO db88f6281AInfoBoardMppConfigValue[] =
  34440. + {{{
  34441. + DB_88F6281A_MPP0_7,
  34442. + DB_88F6281A_MPP8_15,
  34443. + DB_88F6281A_MPP16_23,
  34444. + DB_88F6281A_MPP24_31,
  34445. + DB_88F6281A_MPP32_39,
  34446. + DB_88F6281A_MPP40_47,
  34447. + DB_88F6281A_MPP48_55
  34448. + }}};
  34449. +
  34450. +
  34451. +MV_BOARD_INFO db88f6281AInfo = {
  34452. + "DB-88F6281A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
  34453. + DB_88F6281A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  34454. + db88f6281AInfoBoardMppTypeInfo,
  34455. + DB_88F6281A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  34456. + db88f6281AInfoBoardMppConfigValue,
  34457. + 0, /* intsGppMaskLow */
  34458. + 0, /* intsGppMaskHigh */
  34459. + DB_88F6281A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  34460. + db88f6281AInfoBoardDeCsInfo,
  34461. + DB_88F6281A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  34462. + db88f6281AInfoBoardTwsiDev,
  34463. + DB_88F6281A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  34464. + db88f6281AInfoBoardMacInfo,
  34465. + DB_88F6281A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  34466. + db88f6281AInfoBoardGppInfo,
  34467. + DB_88F6281A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  34468. + NULL,
  34469. + 0, /* ledsPolarity */
  34470. + DB_88F6281A_OE_LOW, /* gppOutEnLow */
  34471. + DB_88F6281A_OE_HIGH, /* gppOutEnHigh */
  34472. + DB_88F6281A_OE_VAL_LOW, /* gppOutValLow */
  34473. + DB_88F6281A_OE_VAL_HIGH, /* gppOutValHigh */
  34474. + 0, /* gppPolarityValLow */
  34475. + BIT6, /* gppPolarityValHigh */
  34476. + NULL /* pSwitchInfo */
  34477. +};
  34478. +
  34479. +
  34480. +#define RD_88F6281A_BOARD_PCI_IF_NUM 0x0
  34481. +#define RD_88F6281A_BOARD_TWSI_DEF_NUM 0x2
  34482. +#define RD_88F6281A_BOARD_MAC_INFO_NUM 0x2
  34483. +#define RD_88F6281A_BOARD_GPP_INFO_NUM 0x5
  34484. +#define RD_88F6281A_BOARD_MPP_GROUP_TYPE_NUM 0x1
  34485. +#define RD_88F6281A_BOARD_MPP_CONFIG_NUM 0x1
  34486. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  34487. + #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
  34488. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  34489. + #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x2
  34490. +#else
  34491. + #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
  34492. +#endif
  34493. +#define RD_88F6281A_BOARD_DEBUG_LED_NUM 0x0
  34494. +
  34495. +MV_BOARD_MAC_INFO rd88f6281AInfoBoardMacInfo[] =
  34496. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  34497. + {{BOARD_MAC_SPEED_1000M, 0xa},
  34498. + {BOARD_MAC_SPEED_AUTO, 0xb}
  34499. + };
  34500. +
  34501. +MV_BOARD_SWITCH_INFO rd88f6281AInfoBoardSwitchInfo[] =
  34502. + /* MV_32 linkStatusIrq, {MV_32 qdPort0, MV_32 qdPort1, MV_32 qdPort2, MV_32 qdPort3, MV_32 qdPort4},
  34503. + MV_32 qdCpuPort, MV_32 smiScanMode, MV_32 switchOnPort} */
  34504. + {{38, {0, 1, 2, 3, -1}, 5, 2, 0},
  34505. + {-1, {-1}, -1, -1, -1}};
  34506. +
  34507. +MV_BOARD_TWSI_INFO rd88f6281AInfoBoardTwsiDev[] =
  34508. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  34509. + {
  34510. + {BOARD_DEV_TWSI_EXP, 0xFF, ADDR7_BIT}, /* dummy entry to align with modules indexes */
  34511. + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT}
  34512. + };
  34513. +
  34514. +MV_BOARD_MPP_TYPE_INFO rd88f6281AInfoBoardMppTypeInfo[] =
  34515. + {{MV_BOARD_RGMII, MV_BOARD_TDM}
  34516. + };
  34517. +
  34518. +MV_DEV_CS_INFO rd88f6281AInfoBoardDeCsInfo[] =
  34519. + /*{deviceCS, params, devType, devWidth}*/
  34520. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  34521. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  34522. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  34523. + {
  34524. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  34525. + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  34526. + };
  34527. +#else
  34528. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  34529. +#endif
  34530. +
  34531. +MV_BOARD_GPP_INFO rd88f6281AInfoBoardGppInfo[] =
  34532. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  34533. + {{BOARD_GPP_SDIO_DETECT, 28},
  34534. + {BOARD_GPP_USB_OC, 29},
  34535. + {BOARD_GPP_WPS_BUTTON, 35},
  34536. + {BOARD_GPP_MV_SWITCH, 38},
  34537. + {BOARD_GPP_USB_VBUS, 49}
  34538. + };
  34539. +
  34540. +MV_BOARD_MPP_INFO rd88f6281AInfoBoardMppConfigValue[] =
  34541. + {{{
  34542. + RD_88F6281A_MPP0_7,
  34543. + RD_88F6281A_MPP8_15,
  34544. + RD_88F6281A_MPP16_23,
  34545. + RD_88F6281A_MPP24_31,
  34546. + RD_88F6281A_MPP32_39,
  34547. + RD_88F6281A_MPP40_47,
  34548. + RD_88F6281A_MPP48_55
  34549. + }}};
  34550. +
  34551. +MV_BOARD_INFO rd88f6281AInfo = {
  34552. + "RD-88F6281A", /* boardName[MAX_BOARD_NAME_LEN] */
  34553. + RD_88F6281A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  34554. + rd88f6281AInfoBoardMppTypeInfo,
  34555. + RD_88F6281A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  34556. + rd88f6281AInfoBoardMppConfigValue,
  34557. + 0, /* intsGppMaskLow */
  34558. + (1 << 3), /* intsGppMaskHigh */
  34559. + RD_88F6281A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  34560. + rd88f6281AInfoBoardDeCsInfo,
  34561. + RD_88F6281A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  34562. + rd88f6281AInfoBoardTwsiDev,
  34563. + RD_88F6281A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  34564. + rd88f6281AInfoBoardMacInfo,
  34565. + RD_88F6281A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  34566. + rd88f6281AInfoBoardGppInfo,
  34567. + RD_88F6281A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  34568. + NULL,
  34569. + 0, /* ledsPolarity */
  34570. + RD_88F6281A_OE_LOW, /* gppOutEnLow */
  34571. + RD_88F6281A_OE_HIGH, /* gppOutEnHigh */
  34572. + RD_88F6281A_OE_VAL_LOW, /* gppOutValLow */
  34573. + RD_88F6281A_OE_VAL_HIGH, /* gppOutValHigh */
  34574. + 0, /* gppPolarityValLow */
  34575. + BIT6, /* gppPolarityValHigh */
  34576. + rd88f6281AInfoBoardSwitchInfo /* pSwitchInfo */
  34577. +};
  34578. +
  34579. +
  34580. +#define DB_88F6192A_BOARD_PCI_IF_NUM 0x0
  34581. +#define DB_88F6192A_BOARD_TWSI_DEF_NUM 0x7
  34582. +#define DB_88F6192A_BOARD_MAC_INFO_NUM 0x2
  34583. +#define DB_88F6192A_BOARD_GPP_INFO_NUM 0x3
  34584. +#define DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM 0x1
  34585. +#define DB_88F6192A_BOARD_MPP_CONFIG_NUM 0x1
  34586. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  34587. + #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x1
  34588. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  34589. + #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x2
  34590. +#else
  34591. + #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x1
  34592. +#endif
  34593. +#define DB_88F6192A_BOARD_DEBUG_LED_NUM 0x0
  34594. +
  34595. +MV_BOARD_TWSI_INFO db88f6192AInfoBoardTwsiDev[] =
  34596. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  34597. + {
  34598. + {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},
  34599. + {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},
  34600. + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},
  34601. + {BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},
  34602. + {BOARD_DEV_TWSI_SATR, 0x4D, ADDR7_BIT},
  34603. + {BOARD_DEV_TWSI_SATR, 0x4E, ADDR7_BIT},
  34604. + {BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}
  34605. + };
  34606. +
  34607. +MV_BOARD_MAC_INFO db88f6192AInfoBoardMacInfo[] =
  34608. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  34609. + {
  34610. + {BOARD_MAC_SPEED_AUTO, 0x8},
  34611. + {BOARD_MAC_SPEED_AUTO, 0x9}
  34612. + };
  34613. +
  34614. +MV_BOARD_MPP_TYPE_INFO db88f6192AInfoBoardMppTypeInfo[] =
  34615. + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
  34616. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
  34617. + {{MV_BOARD_AUTO, MV_BOARD_OTHER}
  34618. + };
  34619. +
  34620. +MV_DEV_CS_INFO db88f6192AInfoBoardDeCsInfo[] =
  34621. + /*{deviceCS, params, devType, devWidth}*/
  34622. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  34623. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  34624. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  34625. + {
  34626. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  34627. + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  34628. + };
  34629. +#else
  34630. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  34631. +#endif
  34632. +
  34633. +MV_BOARD_GPP_INFO db88f6192AInfoBoardGppInfo[] =
  34634. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  34635. + {
  34636. + {BOARD_GPP_SDIO_WP, 20},
  34637. + {BOARD_GPP_USB_VBUS, 22},
  34638. + {BOARD_GPP_SDIO_DETECT, 23},
  34639. + };
  34640. +
  34641. +MV_BOARD_MPP_INFO db88f6192AInfoBoardMppConfigValue[] =
  34642. + {{{
  34643. + DB_88F6192A_MPP0_7,
  34644. + DB_88F6192A_MPP8_15,
  34645. + DB_88F6192A_MPP16_23,
  34646. + DB_88F6192A_MPP24_31,
  34647. + DB_88F6192A_MPP32_35
  34648. + }}};
  34649. +
  34650. +MV_BOARD_INFO db88f6192AInfo = {
  34651. + "DB-88F6192A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
  34652. + DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  34653. + db88f6192AInfoBoardMppTypeInfo,
  34654. + DB_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  34655. + db88f6192AInfoBoardMppConfigValue,
  34656. + 0, /* intsGppMaskLow */
  34657. + (1 << 3), /* intsGppMaskHigh */
  34658. + DB_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  34659. + db88f6192AInfoBoardDeCsInfo,
  34660. + DB_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  34661. + db88f6192AInfoBoardTwsiDev,
  34662. + DB_88F6192A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  34663. + db88f6192AInfoBoardMacInfo,
  34664. + DB_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  34665. + db88f6192AInfoBoardGppInfo,
  34666. + DB_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  34667. + NULL,
  34668. + 0, /* ledsPolarity */
  34669. + DB_88F6192A_OE_LOW, /* gppOutEnLow */
  34670. + DB_88F6192A_OE_HIGH, /* gppOutEnHigh */
  34671. + DB_88F6192A_OE_VAL_LOW, /* gppOutValLow */
  34672. + DB_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
  34673. + 0, /* gppPolarityValLow */
  34674. + 0, /* gppPolarityValHigh */
  34675. + NULL /* pSwitchInfo */
  34676. +};
  34677. +
  34678. +#define DB_88F6190A_BOARD_MAC_INFO_NUM 0x1
  34679. +
  34680. +MV_BOARD_INFO db88f6190AInfo = {
  34681. + "DB-88F6190A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
  34682. + DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  34683. + db88f6192AInfoBoardMppTypeInfo,
  34684. + DB_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  34685. + db88f6192AInfoBoardMppConfigValue,
  34686. + 0, /* intsGppMaskLow */
  34687. + (1 << 3), /* intsGppMaskHigh */
  34688. + DB_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  34689. + db88f6192AInfoBoardDeCsInfo,
  34690. + DB_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  34691. + db88f6192AInfoBoardTwsiDev,
  34692. + DB_88F6190A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  34693. + db88f6192AInfoBoardMacInfo,
  34694. + DB_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  34695. + db88f6192AInfoBoardGppInfo,
  34696. + DB_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  34697. + NULL,
  34698. + 0, /* ledsPolarity */
  34699. + DB_88F6192A_OE_LOW, /* gppOutEnLow */
  34700. + DB_88F6192A_OE_HIGH, /* gppOutEnHigh */
  34701. + DB_88F6192A_OE_VAL_LOW, /* gppOutValLow */
  34702. + DB_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
  34703. + 0, /* gppPolarityValLow */
  34704. + 0, /* gppPolarityValHigh */
  34705. + NULL /* pSwitchInfo */
  34706. +};
  34707. +
  34708. +#define RD_88F6192A_BOARD_PCI_IF_NUM 0x0
  34709. +#define RD_88F6192A_BOARD_TWSI_DEF_NUM 0x0
  34710. +#define RD_88F6192A_BOARD_MAC_INFO_NUM 0x1
  34711. +#define RD_88F6192A_BOARD_GPP_INFO_NUM 0xE
  34712. +#define RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM 0x1
  34713. +#define RD_88F6192A_BOARD_MPP_CONFIG_NUM 0x1
  34714. +#define RD_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x1
  34715. +#define RD_88F6192A_BOARD_DEBUG_LED_NUM 0x3
  34716. +
  34717. +MV_U8 rd88f6192AInfoBoardDebugLedIf[] =
  34718. + {17, 28, 29};
  34719. +
  34720. +MV_BOARD_MAC_INFO rd88f6192AInfoBoardMacInfo[] =
  34721. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  34722. + {{BOARD_MAC_SPEED_AUTO, 0x8}
  34723. + };
  34724. +
  34725. +MV_BOARD_MPP_TYPE_INFO rd88f6192AInfoBoardMppTypeInfo[] =
  34726. + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
  34727. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
  34728. + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
  34729. + };
  34730. +
  34731. +MV_DEV_CS_INFO rd88f6192AInfoBoardDeCsInfo[] =
  34732. + /*{deviceCS, params, devType, devWidth}*/
  34733. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  34734. +
  34735. +MV_BOARD_GPP_INFO rd88f6192AInfoBoardGppInfo[] =
  34736. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  34737. + {
  34738. + {BOARD_GPP_USB_VBUS_EN, 10},
  34739. + {BOARD_GPP_USB_HOST_DEVICE, 11},
  34740. + {BOARD_GPP_RESET, 14},
  34741. + {BOARD_GPP_POWER_ON_LED, 15},
  34742. + {BOARD_GPP_HDD_POWER, 16},
  34743. + {BOARD_GPP_WPS_BUTTON, 24},
  34744. + {BOARD_GPP_TS_BUTTON_C, 25},
  34745. + {BOARD_GPP_USB_VBUS, 26},
  34746. + {BOARD_GPP_USB_OC, 27},
  34747. + {BOARD_GPP_TS_BUTTON_U, 30},
  34748. + {BOARD_GPP_TS_BUTTON_R, 31},
  34749. + {BOARD_GPP_TS_BUTTON_L, 32},
  34750. + {BOARD_GPP_TS_BUTTON_D, 34},
  34751. + {BOARD_GPP_FAN_POWER, 35}
  34752. + };
  34753. +
  34754. +MV_BOARD_MPP_INFO rd88f6192AInfoBoardMppConfigValue[] =
  34755. + {{{
  34756. + RD_88F6192A_MPP0_7,
  34757. + RD_88F6192A_MPP8_15,
  34758. + RD_88F6192A_MPP16_23,
  34759. + RD_88F6192A_MPP24_31,
  34760. + RD_88F6192A_MPP32_35
  34761. + }}};
  34762. +
  34763. +MV_BOARD_INFO rd88f6192AInfo = {
  34764. + "RD-88F6192A-NAS", /* boardName[MAX_BOARD_NAME_LEN] */
  34765. + RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  34766. + rd88f6192AInfoBoardMppTypeInfo,
  34767. + RD_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  34768. + rd88f6192AInfoBoardMppConfigValue,
  34769. + 0, /* intsGppMaskLow */
  34770. + (1 << 3), /* intsGppMaskHigh */
  34771. + RD_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  34772. + rd88f6192AInfoBoardDeCsInfo,
  34773. + RD_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  34774. + NULL,
  34775. + RD_88F6192A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  34776. + rd88f6192AInfoBoardMacInfo,
  34777. + RD_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  34778. + rd88f6192AInfoBoardGppInfo,
  34779. + RD_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  34780. + rd88f6192AInfoBoardDebugLedIf,
  34781. + 0, /* ledsPolarity */
  34782. + RD_88F6192A_OE_LOW, /* gppOutEnLow */
  34783. + RD_88F6192A_OE_HIGH, /* gppOutEnHigh */
  34784. + RD_88F6192A_OE_VAL_LOW, /* gppOutValLow */
  34785. + RD_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
  34786. + 0, /* gppPolarityValLow */
  34787. + 0, /* gppPolarityValHigh */
  34788. + NULL /* pSwitchInfo */
  34789. +};
  34790. +
  34791. +MV_BOARD_INFO rd88f6190AInfo = {
  34792. + "RD-88F6190A-NAS", /* boardName[MAX_BOARD_NAME_LEN] */
  34793. + RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  34794. + rd88f6192AInfoBoardMppTypeInfo,
  34795. + RD_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  34796. + rd88f6192AInfoBoardMppConfigValue,
  34797. + 0, /* intsGppMaskLow */
  34798. + (1 << 3), /* intsGppMaskHigh */
  34799. + RD_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  34800. + rd88f6192AInfoBoardDeCsInfo,
  34801. + RD_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  34802. + NULL,
  34803. + RD_88F6192A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  34804. + rd88f6192AInfoBoardMacInfo,
  34805. + RD_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  34806. + rd88f6192AInfoBoardGppInfo,
  34807. + RD_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  34808. + rd88f6192AInfoBoardDebugLedIf,
  34809. + 0, /* ledsPolarity */
  34810. + RD_88F6192A_OE_LOW, /* gppOutEnLow */
  34811. + RD_88F6192A_OE_HIGH, /* gppOutEnHigh */
  34812. + RD_88F6192A_OE_VAL_LOW, /* gppOutValLow */
  34813. + RD_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
  34814. + 0, /* gppPolarityValLow */
  34815. + 0, /* gppPolarityValHigh */
  34816. + NULL /* pSwitchInfo */
  34817. +};
  34818. +
  34819. +#define DB_88F6180A_BOARD_PCI_IF_NUM 0x0
  34820. +#define DB_88F6180A_BOARD_TWSI_DEF_NUM 0x5
  34821. +#define DB_88F6180A_BOARD_MAC_INFO_NUM 0x1
  34822. +#define DB_88F6180A_BOARD_GPP_INFO_NUM 0x0
  34823. +#define DB_88F6180A_BOARD_MPP_GROUP_TYPE_NUM 0x2
  34824. +#define DB_88F6180A_BOARD_MPP_CONFIG_NUM 0x1
  34825. +#define DB_88F6180A_BOARD_DEVICE_CONFIG_NUM 0x1
  34826. +#define DB_88F6180A_BOARD_DEBUG_LED_NUM 0x0
  34827. +
  34828. +MV_BOARD_TWSI_INFO db88f6180AInfoBoardTwsiDev[] =
  34829. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  34830. + {
  34831. + {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},
  34832. + {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},
  34833. + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},
  34834. + {BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},
  34835. + {BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}
  34836. + };
  34837. +
  34838. +MV_BOARD_MAC_INFO db88f6180AInfoBoardMacInfo[] =
  34839. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  34840. + {{BOARD_MAC_SPEED_AUTO, 0x8}
  34841. + };
  34842. +
  34843. +MV_BOARD_GPP_INFO db88f6180AInfoBoardGppInfo[] =
  34844. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  34845. + {
  34846. + /* Muxed with TDM/Audio module via IOexpender
  34847. + {BOARD_GPP_USB_VBUS, 6} */
  34848. + };
  34849. +
  34850. +MV_BOARD_MPP_TYPE_INFO db88f6180AInfoBoardMppTypeInfo[] =
  34851. + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
  34852. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
  34853. + {{MV_BOARD_OTHER, MV_BOARD_AUTO}
  34854. + };
  34855. +
  34856. +MV_DEV_CS_INFO db88f6180AInfoBoardDeCsInfo[] =
  34857. + /*{deviceCS, params, devType, devWidth}*/
  34858. +#if defined(MV_NAND_BOOT)
  34859. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  34860. +#else
  34861. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  34862. +#endif
  34863. +
  34864. +MV_BOARD_MPP_INFO db88f6180AInfoBoardMppConfigValue[] =
  34865. + {{{
  34866. + DB_88F6180A_MPP0_7,
  34867. + DB_88F6180A_MPP8_15,
  34868. + DB_88F6180A_MPP16_23,
  34869. + DB_88F6180A_MPP24_31,
  34870. + DB_88F6180A_MPP32_39,
  34871. + DB_88F6180A_MPP40_44
  34872. + }}};
  34873. +
  34874. +MV_BOARD_INFO db88f6180AInfo = {
  34875. + "DB-88F6180A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
  34876. + DB_88F6180A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  34877. + db88f6180AInfoBoardMppTypeInfo,
  34878. + DB_88F6180A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  34879. + db88f6180AInfoBoardMppConfigValue,
  34880. + 0, /* intsGppMaskLow */
  34881. + 0, /* intsGppMaskHigh */
  34882. + DB_88F6180A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  34883. + db88f6180AInfoBoardDeCsInfo,
  34884. + DB_88F6180A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  34885. + db88f6180AInfoBoardTwsiDev,
  34886. + DB_88F6180A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  34887. + db88f6180AInfoBoardMacInfo,
  34888. + DB_88F6180A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  34889. + NULL,
  34890. + DB_88F6180A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  34891. + NULL,
  34892. + 0, /* ledsPolarity */
  34893. + DB_88F6180A_OE_LOW, /* gppOutEnLow */
  34894. + DB_88F6180A_OE_HIGH, /* gppOutEnHigh */
  34895. + DB_88F6180A_OE_VAL_LOW, /* gppOutValLow */
  34896. + DB_88F6180A_OE_VAL_HIGH, /* gppOutValHigh */
  34897. + 0, /* gppPolarityValLow */
  34898. + 0, /* gppPolarityValHigh */
  34899. + NULL /* pSwitchInfo */
  34900. +};
  34901. +
  34902. +
  34903. +#define RD_88F6281A_PCAC_BOARD_PCI_IF_NUM 0x0
  34904. +#define RD_88F6281A_PCAC_BOARD_TWSI_DEF_NUM 0x1
  34905. +#define RD_88F6281A_PCAC_BOARD_MAC_INFO_NUM 0x1
  34906. +#define RD_88F6281A_PCAC_BOARD_GPP_INFO_NUM 0x0
  34907. +#define RD_88F6281A_PCAC_BOARD_MPP_GROUP_TYPE_NUM 0x1
  34908. +#define RD_88F6281A_PCAC_BOARD_MPP_CONFIG_NUM 0x1
  34909. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  34910. + #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM 0x1
  34911. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  34912. + #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM 0x2
  34913. +#else
  34914. + #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM 0x1
  34915. +#endif
  34916. +#define RD_88F6281A_PCAC_BOARD_DEBUG_LED_NUM 0x4
  34917. +
  34918. +MV_U8 rd88f6281APcacInfoBoardDebugLedIf[] =
  34919. + {38, 39, 40, 41};
  34920. +
  34921. +MV_BOARD_MAC_INFO rd88f6281APcacInfoBoardMacInfo[] =
  34922. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  34923. + {{BOARD_MAC_SPEED_AUTO, 0x8}
  34924. + };
  34925. +
  34926. +MV_BOARD_TWSI_INFO rd88f6281APcacInfoBoardTwsiDev[] =
  34927. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  34928. + {
  34929. + {BOARD_TWSI_OTHER, 0xa7, ADDR7_BIT}
  34930. + };
  34931. +
  34932. +MV_BOARD_MPP_TYPE_INFO rd88f6281APcacInfoBoardMppTypeInfo[] =
  34933. + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
  34934. + };
  34935. +
  34936. +MV_DEV_CS_INFO rd88f6281APcacInfoBoardDeCsInfo[] =
  34937. + /*{deviceCS, params, devType, devWidth}*/
  34938. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  34939. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  34940. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  34941. + {
  34942. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  34943. + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  34944. + };
  34945. +#else
  34946. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  34947. +#endif
  34948. +
  34949. +MV_BOARD_MPP_INFO rd88f6281APcacInfoBoardMppConfigValue[] =
  34950. + {{{
  34951. + RD_88F6281A_PCAC_MPP0_7,
  34952. + RD_88F6281A_PCAC_MPP8_15,
  34953. + RD_88F6281A_PCAC_MPP16_23,
  34954. + RD_88F6281A_PCAC_MPP24_31,
  34955. + RD_88F6281A_PCAC_MPP32_39,
  34956. + RD_88F6281A_PCAC_MPP40_47,
  34957. + RD_88F6281A_PCAC_MPP48_55
  34958. + }}};
  34959. +
  34960. +MV_BOARD_INFO rd88f6281APcacInfo = {
  34961. + "RD-88F6281A-PCAC", /* boardName[MAX_BOARD_NAME_LEN] */
  34962. + RD_88F6281A_PCAC_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  34963. + rd88f6281APcacInfoBoardMppTypeInfo,
  34964. + RD_88F6281A_PCAC_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  34965. + rd88f6281APcacInfoBoardMppConfigValue,
  34966. + 0, /* intsGppMaskLow */
  34967. + (1 << 3), /* intsGppMaskHigh */
  34968. + RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  34969. + rd88f6281APcacInfoBoardDeCsInfo,
  34970. + RD_88F6281A_PCAC_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  34971. + rd88f6281APcacInfoBoardTwsiDev,
  34972. + RD_88F6281A_PCAC_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  34973. + rd88f6281APcacInfoBoardMacInfo,
  34974. + RD_88F6281A_PCAC_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  34975. + 0,
  34976. + RD_88F6281A_PCAC_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  34977. + NULL,
  34978. + 0, /* ledsPolarity */
  34979. + RD_88F6281A_PCAC_OE_LOW, /* gppOutEnLow */
  34980. + RD_88F6281A_PCAC_OE_HIGH, /* gppOutEnHigh */
  34981. + RD_88F6281A_PCAC_OE_VAL_LOW, /* gppOutValLow */
  34982. + RD_88F6281A_PCAC_OE_VAL_HIGH, /* gppOutValHigh */
  34983. + 0, /* gppPolarityValLow */
  34984. + 0, /* gppPolarityValHigh */
  34985. + NULL /* pSwitchInfo */
  34986. +};
  34987. +
  34988. +
  34989. +/* 6281 Sheeva Plug*/
  34990. +
  34991. +#define SHEEVA_PLUG_BOARD_PCI_IF_NUM 0x0
  34992. +#define SHEEVA_PLUG_BOARD_TWSI_DEF_NUM 0x0
  34993. +#define SHEEVA_PLUG_BOARD_MAC_INFO_NUM 0x1
  34994. +#define SHEEVA_PLUG_BOARD_GPP_INFO_NUM 0x0
  34995. +#define SHEEVA_PLUG_BOARD_MPP_GROUP_TYPE_NUN 0x1
  34996. +#define SHEEVA_PLUG_BOARD_MPP_CONFIG_NUM 0x1
  34997. +#define SHEEVA_PLUG_BOARD_DEVICE_CONFIG_NUM 0x1
  34998. +#define SHEEVA_PLUG_BOARD_DEBUG_LED_NUM 0x1
  34999. +
  35000. +MV_U8 sheevaPlugInfoBoardDebugLedIf[] =
  35001. + {49};
  35002. +
  35003. +MV_BOARD_MAC_INFO sheevaPlugInfoBoardMacInfo[] =
  35004. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  35005. + {{BOARD_MAC_SPEED_AUTO, 0x0}};
  35006. +
  35007. +MV_BOARD_TWSI_INFO sheevaPlugInfoBoardTwsiDev[] =
  35008. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  35009. + {{BOARD_TWSI_OTHER, 0x0, ADDR7_BIT}};
  35010. +
  35011. +MV_BOARD_MPP_TYPE_INFO sheevaPlugInfoBoardMppTypeInfo[] =
  35012. + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
  35013. + };
  35014. +
  35015. +MV_DEV_CS_INFO sheevaPlugInfoBoardDeCsInfo[] =
  35016. + /*{deviceCS, params, devType, devWidth}*/
  35017. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  35018. +
  35019. +MV_BOARD_MPP_INFO sheevaPlugInfoBoardMppConfigValue[] =
  35020. + {{{
  35021. + RD_SHEEVA_PLUG_MPP0_7,
  35022. + RD_SHEEVA_PLUG_MPP8_15,
  35023. + RD_SHEEVA_PLUG_MPP16_23,
  35024. + RD_SHEEVA_PLUG_MPP24_31,
  35025. + RD_SHEEVA_PLUG_MPP32_39,
  35026. + RD_SHEEVA_PLUG_MPP40_47,
  35027. + RD_SHEEVA_PLUG_MPP48_55
  35028. + }}};
  35029. +
  35030. +MV_BOARD_INFO sheevaPlugInfo = {
  35031. + "SHEEVA PLUG", /* boardName[MAX_BOARD_NAME_LEN] */
  35032. + SHEEVA_PLUG_BOARD_MPP_GROUP_TYPE_NUN, /* numBoardMppGroupType */
  35033. + sheevaPlugInfoBoardMppTypeInfo,
  35034. + SHEEVA_PLUG_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  35035. + sheevaPlugInfoBoardMppConfigValue,
  35036. + 0, /* intsGppMaskLow */
  35037. + 0, /* intsGppMaskHigh */
  35038. + SHEEVA_PLUG_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  35039. + sheevaPlugInfoBoardDeCsInfo,
  35040. + SHEEVA_PLUG_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  35041. + sheevaPlugInfoBoardTwsiDev,
  35042. + SHEEVA_PLUG_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  35043. + sheevaPlugInfoBoardMacInfo,
  35044. + SHEEVA_PLUG_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  35045. + 0,
  35046. + SHEEVA_PLUG_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  35047. + sheevaPlugInfoBoardDebugLedIf,
  35048. + 0, /* ledsPolarity */
  35049. + RD_SHEEVA_PLUG_OE_LOW, /* gppOutEnLow */
  35050. + RD_SHEEVA_PLUG_OE_HIGH, /* gppOutEnHigh */
  35051. + RD_SHEEVA_PLUG_OE_VAL_LOW, /* gppOutValLow */
  35052. + RD_SHEEVA_PLUG_OE_VAL_HIGH, /* gppOutValHigh */
  35053. + 0, /* gppPolarityValLow */
  35054. + 0, /* gppPolarityValHigh */
  35055. + NULL /* pSwitchInfo */
  35056. +};
  35057. +
  35058. +/* Customer specific board place holder*/
  35059. +
  35060. +#define DB_CUSTOMER_BOARD_PCI_IF_NUM 0x0
  35061. +#define DB_CUSTOMER_BOARD_TWSI_DEF_NUM 0x0
  35062. +#define DB_CUSTOMER_BOARD_MAC_INFO_NUM 0x0
  35063. +#define DB_CUSTOMER_BOARD_GPP_INFO_NUM 0x0
  35064. +#define DB_CUSTOMER_BOARD_MPP_GROUP_TYPE_NUN 0x0
  35065. +#define DB_CUSTOMER_BOARD_MPP_CONFIG_NUM 0x0
  35066. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  35067. + #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM 0x0
  35068. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  35069. + #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM 0x0
  35070. +#else
  35071. + #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM 0x0
  35072. +#endif
  35073. +#define DB_CUSTOMER_BOARD_DEBUG_LED_NUM 0x0
  35074. +
  35075. +MV_U8 dbCustomerInfoBoardDebugLedIf[] =
  35076. + {0};
  35077. +
  35078. +MV_BOARD_MAC_INFO dbCustomerInfoBoardMacInfo[] =
  35079. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  35080. + {{BOARD_MAC_SPEED_AUTO, 0x0}};
  35081. +
  35082. +MV_BOARD_TWSI_INFO dbCustomerInfoBoardTwsiDev[] =
  35083. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  35084. + {{BOARD_TWSI_OTHER, 0x0, ADDR7_BIT}};
  35085. +
  35086. +MV_BOARD_MPP_TYPE_INFO dbCustomerInfoBoardMppTypeInfo[] =
  35087. + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
  35088. + };
  35089. +
  35090. +MV_DEV_CS_INFO dbCustomerInfoBoardDeCsInfo[] =
  35091. + /*{deviceCS, params, devType, devWidth}*/
  35092. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  35093. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  35094. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  35095. + {
  35096. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  35097. + {2, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  35098. + };
  35099. +#else
  35100. + {{2, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  35101. +#endif
  35102. +
  35103. +MV_BOARD_MPP_INFO dbCustomerInfoBoardMppConfigValue[] =
  35104. + {{{
  35105. + DB_CUSTOMER_MPP0_7,
  35106. + DB_CUSTOMER_MPP8_15,
  35107. + DB_CUSTOMER_MPP16_23,
  35108. + DB_CUSTOMER_MPP24_31,
  35109. + DB_CUSTOMER_MPP32_39,
  35110. + DB_CUSTOMER_MPP40_47,
  35111. + DB_CUSTOMER_MPP48_55
  35112. + }}};
  35113. +
  35114. +MV_BOARD_INFO dbCustomerInfo = {
  35115. + "DB-CUSTOMER", /* boardName[MAX_BOARD_NAME_LEN] */
  35116. + DB_CUSTOMER_BOARD_MPP_GROUP_TYPE_NUN, /* numBoardMppGroupType */
  35117. + dbCustomerInfoBoardMppTypeInfo,
  35118. + DB_CUSTOMER_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  35119. + dbCustomerInfoBoardMppConfigValue,
  35120. + 0, /* intsGppMaskLow */
  35121. + 0, /* intsGppMaskHigh */
  35122. + DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  35123. + dbCustomerInfoBoardDeCsInfo,
  35124. + DB_CUSTOMER_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  35125. + dbCustomerInfoBoardTwsiDev,
  35126. + DB_CUSTOMER_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  35127. + dbCustomerInfoBoardMacInfo,
  35128. + DB_CUSTOMER_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  35129. + 0,
  35130. + DB_CUSTOMER_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  35131. + NULL,
  35132. + 0, /* ledsPolarity */
  35133. + DB_CUSTOMER_OE_LOW, /* gppOutEnLow */
  35134. + DB_CUSTOMER_OE_HIGH, /* gppOutEnHigh */
  35135. + DB_CUSTOMER_OE_VAL_LOW, /* gppOutValLow */
  35136. + DB_CUSTOMER_OE_VAL_HIGH, /* gppOutValHigh */
  35137. + 0, /* gppPolarityValLow */
  35138. + 0, /* gppPolarityValHigh */
  35139. + NULL /* pSwitchInfo */
  35140. +};
  35141. +
  35142. +MV_BOARD_INFO* boardInfoTbl[] = {
  35143. + &db88f6281AInfo,
  35144. + &rd88f6281AInfo,
  35145. + &db88f6192AInfo,
  35146. + &rd88f6192AInfo,
  35147. + &db88f6180AInfo,
  35148. + &db88f6190AInfo,
  35149. + &rd88f6190AInfo,
  35150. + &rd88f6281APcacInfo,
  35151. + &dbCustomerInfo,
  35152. + &sheevaPlugInfo
  35153. + };
  35154. +
  35155. +
  35156. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h
  35157. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h 1970-01-01 01:00:00.000000000 +0100
  35158. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h 2010-08-05 22:02:15.954784544 +0200
  35159. @@ -0,0 +1,262 @@
  35160. +/*******************************************************************************
  35161. +Copyright (C) Marvell International Ltd. and its affiliates
  35162. +
  35163. +This software file (the "File") is owned and distributed by Marvell
  35164. +International Ltd. and/or its affiliates ("Marvell") under the following
  35165. +alternative licensing terms. Once you have made an election to distribute the
  35166. +File under one of the following license alternatives, please (i) delete this
  35167. +introductory statement regarding license alternatives, (ii) delete the two
  35168. +license alternatives that you have not elected to use and (iii) preserve the
  35169. +Marvell copyright notice above.
  35170. +
  35171. +********************************************************************************
  35172. +Marvell Commercial License Option
  35173. +
  35174. +If you received this File from Marvell and you have entered into a commercial
  35175. +license agreement (a "Commercial License") with Marvell, the File is licensed
  35176. +to you under the terms of the applicable Commercial License.
  35177. +
  35178. +********************************************************************************
  35179. +Marvell GPL License Option
  35180. +
  35181. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35182. +modify this File in accordance with the terms and conditions of the General
  35183. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  35184. +available along with the File in the license.txt file or by writing to the Free
  35185. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  35186. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  35187. +
  35188. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  35189. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  35190. +DISCLAIMED. The GPL License provides additional details about this warranty
  35191. +disclaimer.
  35192. +********************************************************************************
  35193. +Marvell BSD License Option
  35194. +
  35195. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35196. +modify this File under the following licensing terms.
  35197. +Redistribution and use in source and binary forms, with or without modification,
  35198. +are permitted provided that the following conditions are met:
  35199. +
  35200. + * Redistributions of source code must retain the above copyright notice,
  35201. + this list of conditions and the following disclaimer.
  35202. +
  35203. + * Redistributions in binary form must reproduce the above copyright
  35204. + notice, this list of conditions and the following disclaimer in the
  35205. + documentation and/or other materials provided with the distribution.
  35206. +
  35207. + * Neither the name of Marvell nor the names of its contributors may be
  35208. + used to endorse or promote products derived from this software without
  35209. + specific prior written permission.
  35210. +
  35211. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  35212. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  35213. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  35214. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  35215. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  35216. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  35217. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  35218. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  35219. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  35220. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35221. +
  35222. +*******************************************************************************/
  35223. +
  35224. +
  35225. +#ifndef __INCmvBoardEnvSpech
  35226. +#define __INCmvBoardEnvSpech
  35227. +
  35228. +#include "mvSysHwConfig.h"
  35229. +
  35230. +
  35231. +/* For future use */
  35232. +#define BD_ID_DATA_START_OFFS 0x0
  35233. +#define BD_DETECT_SEQ_OFFS 0x0
  35234. +#define BD_SYS_NUM_OFFS 0x4
  35235. +#define BD_NAME_OFFS 0x8
  35236. +
  35237. +/* I2C bus addresses */
  35238. +#define MV_BOARD_CTRL_I2C_ADDR 0x0 /* Controller slave addr */
  35239. +#define MV_BOARD_CTRL_I2C_ADDR_TYPE ADDR7_BIT
  35240. +#define MV_BOARD_DIMM0_I2C_ADDR 0x56
  35241. +#define MV_BOARD_DIMM0_I2C_ADDR_TYPE ADDR7_BIT
  35242. +#define MV_BOARD_DIMM1_I2C_ADDR 0x54
  35243. +#define MV_BOARD_DIMM1_I2C_ADDR_TYPE ADDR7_BIT
  35244. +#define MV_BOARD_EEPROM_I2C_ADDR 0x51
  35245. +#define MV_BOARD_EEPROM_I2C_ADDR_TYPE ADDR7_BIT
  35246. +#define MV_BOARD_MAIN_EEPROM_I2C_ADDR 0x50
  35247. +#define MV_BOARD_MAIN_EEPROM_I2C_ADDR_TYPE ADDR7_BIT
  35248. +#define MV_BOARD_MUX_I2C_ADDR_ENTRY 0x2
  35249. +#define MV_BOARD_DIMM_I2C_CHANNEL 0x0
  35250. +
  35251. +#define BOOT_FLASH_INDEX 0
  35252. +#define MAIN_FLASH_INDEX 1
  35253. +
  35254. +#define BOARD_ETH_START_PORT_NUM 0
  35255. +
  35256. +/* Supported clocks */
  35257. +#define MV_BOARD_TCLK_100MHZ 100000000
  35258. +#define MV_BOARD_TCLK_125MHZ 125000000
  35259. +#define MV_BOARD_TCLK_133MHZ 133333333
  35260. +#define MV_BOARD_TCLK_150MHZ 150000000
  35261. +#define MV_BOARD_TCLK_166MHZ 166666667
  35262. +#define MV_BOARD_TCLK_200MHZ 200000000
  35263. +
  35264. +#define MV_BOARD_SYSCLK_100MHZ 100000000
  35265. +#define MV_BOARD_SYSCLK_125MHZ 125000000
  35266. +#define MV_BOARD_SYSCLK_133MHZ 133333333
  35267. +#define MV_BOARD_SYSCLK_150MHZ 150000000
  35268. +#define MV_BOARD_SYSCLK_166MHZ 166666667
  35269. +#define MV_BOARD_SYSCLK_200MHZ 200000000
  35270. +#define MV_BOARD_SYSCLK_233MHZ 233333333
  35271. +#define MV_BOARD_SYSCLK_250MHZ 250000000
  35272. +#define MV_BOARD_SYSCLK_267MHZ 266666667
  35273. +#define MV_BOARD_SYSCLK_300MHZ 300000000
  35274. +#define MV_BOARD_SYSCLK_333MHZ 333333334
  35275. +#define MV_BOARD_SYSCLK_400MHZ 400000000
  35276. +
  35277. +#define MV_BOARD_REFCLK_25MHZ 25000000
  35278. +
  35279. +/* Board specific */
  35280. +/* =============================== */
  35281. +
  35282. +/* boards ID numbers */
  35283. +
  35284. +#define BOARD_ID_BASE 0x0
  35285. +
  35286. +/* New board ID numbers */
  35287. +#define DB_88F6281A_BP_ID (BOARD_ID_BASE)
  35288. +#define DB_88F6281_BP_MLL_ID 1680
  35289. +#define RD_88F6281A_ID (BOARD_ID_BASE+0x1)
  35290. +#define RD_88F6281_MLL_ID 1682
  35291. +#define DB_88F6192A_BP_ID (BOARD_ID_BASE+0x2)
  35292. +#define RD_88F6192A_ID (BOARD_ID_BASE+0x3)
  35293. +#define RD_88F6192_MLL_ID 1681
  35294. +#define DB_88F6180A_BP_ID (BOARD_ID_BASE+0x4)
  35295. +#define DB_88F6190A_BP_ID (BOARD_ID_BASE+0x5)
  35296. +#define RD_88F6190A_ID (BOARD_ID_BASE+0x6)
  35297. +#define RD_88F6281A_PCAC_ID (BOARD_ID_BASE+0x7)
  35298. +#define DB_CUSTOMER_ID (BOARD_ID_BASE+0x8)
  35299. +#define SHEEVA_PLUG_ID (BOARD_ID_BASE+0x9)
  35300. +#define MV_MAX_BOARD_ID (SHEEVA_PLUG_ID + 1)
  35301. +
  35302. +/* DB-88F6281A-BP */
  35303. +#if defined(MV_NAND)
  35304. + #define DB_88F6281A_MPP0_7 0x21111111
  35305. +#else
  35306. + #define DB_88F6281A_MPP0_7 0x21112220
  35307. +#endif
  35308. +#define DB_88F6281A_MPP8_15 0x11113311
  35309. +#define DB_88F6281A_MPP16_23 0x00551111
  35310. +#define DB_88F6281A_MPP24_31 0x00000000
  35311. +#define DB_88F6281A_MPP32_39 0x00000000
  35312. +#define DB_88F6281A_MPP40_47 0x00000000
  35313. +#define DB_88F6281A_MPP48_55 0x00000000
  35314. +#define DB_88F6281A_OE_LOW 0x0
  35315. +#if defined(MV_TDM_5CHANNELS)
  35316. + #define DB_88F6281A_OE_HIGH (BIT6)
  35317. +#else
  35318. +#define DB_88F6281A_OE_HIGH 0x0
  35319. +#endif
  35320. +#define DB_88F6281A_OE_VAL_LOW 0x0
  35321. +#define DB_88F6281A_OE_VAL_HIGH 0x0
  35322. +
  35323. +/* RD-88F6281A */
  35324. +#if defined(MV_NAND)
  35325. + #define RD_88F6281A_MPP0_7 0x21111111
  35326. +#else
  35327. + #define RD_88F6281A_MPP0_7 0x21112220
  35328. +#endif
  35329. +#define RD_88F6281A_MPP8_15 0x11113311
  35330. +#define RD_88F6281A_MPP16_23 0x33331111
  35331. +#define RD_88F6281A_MPP24_31 0x33003333
  35332. +#define RD_88F6281A_MPP32_39 0x20440533
  35333. +#define RD_88F6281A_MPP40_47 0x22202222
  35334. +#define RD_88F6281A_MPP48_55 0x00000002
  35335. +#define RD_88F6281A_OE_LOW (BIT28 | BIT29)
  35336. +#define RD_88F6281A_OE_HIGH (BIT3 | BIT6 | BIT17)
  35337. +#define RD_88F6281A_OE_VAL_LOW 0x0
  35338. +#define RD_88F6281A_OE_VAL_HIGH 0x0
  35339. +
  35340. +/* DB-88F6192A-BP */
  35341. +#if defined(MV_NAND)
  35342. + #define DB_88F6192A_MPP0_7 0x21111111
  35343. +#else
  35344. + #define DB_88F6192A_MPP0_7 0x21112220
  35345. +#endif
  35346. +#define DB_88F6192A_MPP8_15 0x11113311
  35347. +#define DB_88F6192A_MPP16_23 0x00501111
  35348. +#define DB_88F6192A_MPP24_31 0x00000000
  35349. +#define DB_88F6192A_MPP32_35 0x00000000
  35350. +#define DB_88F6192A_OE_LOW (BIT22 | BIT23)
  35351. +#define DB_88F6192A_OE_HIGH 0x0
  35352. +#define DB_88F6192A_OE_VAL_LOW 0x0
  35353. +#define DB_88F6192A_OE_VAL_HIGH 0x0
  35354. +
  35355. +/* RD-88F6192A */
  35356. +#define RD_88F6192A_MPP0_7 0x01222222
  35357. +#define RD_88F6192A_MPP8_15 0x00000011
  35358. +#define RD_88F6192A_MPP16_23 0x05550000
  35359. +#define RD_88F6192A_MPP24_31 0x0
  35360. +#define RD_88F6192A_MPP32_35 0x0
  35361. +#define RD_88F6192A_OE_LOW (BIT11 | BIT14 | BIT24 | BIT25 | BIT26 | BIT27 | BIT30 | BIT31)
  35362. +#define RD_88F6192A_OE_HIGH (BIT0 | BIT2)
  35363. +#define RD_88F6192A_OE_VAL_LOW 0x18400
  35364. +#define RD_88F6192A_OE_VAL_HIGH 0x8
  35365. +
  35366. +/* DB-88F6180A-BP */
  35367. +#if defined(MV_NAND)
  35368. + #define DB_88F6180A_MPP0_7 0x21111111
  35369. +#else
  35370. + #define DB_88F6180A_MPP0_7 0x01112222
  35371. +#endif
  35372. +#define DB_88F6180A_MPP8_15 0x11113311
  35373. +#define DB_88F6180A_MPP16_23 0x00001111
  35374. +#define DB_88F6180A_MPP24_31 0x0
  35375. +#define DB_88F6180A_MPP32_39 0x4444c000
  35376. +#define DB_88F6180A_MPP40_44 0x00044444
  35377. +#define DB_88F6180A_OE_LOW 0x0
  35378. +#define DB_88F6180A_OE_HIGH 0x0
  35379. +#define DB_88F6180A_OE_VAL_LOW 0x0
  35380. +#define DB_88F6180A_OE_VAL_HIGH 0x0
  35381. +
  35382. +/* RD-88F6281A_PCAC */
  35383. +#define RD_88F6281A_PCAC_MPP0_7 0x21111111
  35384. +#define RD_88F6281A_PCAC_MPP8_15 0x00003311
  35385. +#define RD_88F6281A_PCAC_MPP16_23 0x00001100
  35386. +#define RD_88F6281A_PCAC_MPP24_31 0x00000000
  35387. +#define RD_88F6281A_PCAC_MPP32_39 0x00000000
  35388. +#define RD_88F6281A_PCAC_MPP40_47 0x00000000
  35389. +#define RD_88F6281A_PCAC_MPP48_55 0x00000000
  35390. +#define RD_88F6281A_PCAC_OE_LOW 0x0
  35391. +#define RD_88F6281A_PCAC_OE_HIGH 0x0
  35392. +#define RD_88F6281A_PCAC_OE_VAL_LOW 0x0
  35393. +#define RD_88F6281A_PCAC_OE_VAL_HIGH 0x0
  35394. +
  35395. +/* SHEEVA PLUG */
  35396. +#define RD_SHEEVA_PLUG_MPP0_7 0x01111111
  35397. +#define RD_SHEEVA_PLUG_MPP8_15 0x11113322
  35398. +#define RD_SHEEVA_PLUG_MPP16_23 0x00001111
  35399. +#define RD_SHEEVA_PLUG_MPP24_31 0x00100000
  35400. +#define RD_SHEEVA_PLUG_MPP32_39 0x00000000
  35401. +#define RD_SHEEVA_PLUG_MPP40_47 0x00000000
  35402. +#define RD_SHEEVA_PLUG_MPP48_55 0x00000000
  35403. +#define RD_SHEEVA_PLUG_OE_LOW 0x0
  35404. +#define RD_SHEEVA_PLUG_OE_HIGH 0x0
  35405. +#define RD_SHEEVA_PLUG_OE_VAL_LOW (BIT29)
  35406. +#define RD_SHEEVA_PLUG_OE_VAL_HIGH ((~(BIT17 | BIT16 | BIT15)) | BIT14)
  35407. +
  35408. +/* DB-CUSTOMER */
  35409. +#define DB_CUSTOMER_MPP0_7 0x21111111
  35410. +#define DB_CUSTOMER_MPP8_15 0x00003311
  35411. +#define DB_CUSTOMER_MPP16_23 0x00001100
  35412. +#define DB_CUSTOMER_MPP24_31 0x00000000
  35413. +#define DB_CUSTOMER_MPP32_39 0x00000000
  35414. +#define DB_CUSTOMER_MPP40_47 0x00000000
  35415. +#define DB_CUSTOMER_MPP48_55 0x00000000
  35416. +#define DB_CUSTOMER_OE_LOW 0x0
  35417. +#define DB_CUSTOMER_OE_HIGH (~((BIT6) | (BIT7) | (BIT8) | (BIT9)))
  35418. +#define DB_CUSTOMER_OE_VAL_LOW 0x0
  35419. +#define DB_CUSTOMER_OE_VAL_HIGH 0x0
  35420. +
  35421. +#endif /* __INCmvBoardEnvSpech */
  35422. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c
  35423. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c 1970-01-01 01:00:00.000000000 +0100
  35424. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c 2010-08-05 22:02:16.064868492 +0200
  35425. @@ -0,0 +1,320 @@
  35426. +/*******************************************************************************
  35427. +Copyright (C) Marvell International Ltd. and its affiliates
  35428. +
  35429. +This software file (the "File") is owned and distributed by Marvell
  35430. +International Ltd. and/or its affiliates ("Marvell") under the following
  35431. +alternative licensing terms. Once you have made an election to distribute the
  35432. +File under one of the following license alternatives, please (i) delete this
  35433. +introductory statement regarding license alternatives, (ii) delete the two
  35434. +license alternatives that you have not elected to use and (iii) preserve the
  35435. +Marvell copyright notice above.
  35436. +
  35437. +********************************************************************************
  35438. +Marvell Commercial License Option
  35439. +
  35440. +If you received this File from Marvell and you have entered into a commercial
  35441. +license agreement (a "Commercial License") with Marvell, the File is licensed
  35442. +to you under the terms of the applicable Commercial License.
  35443. +
  35444. +********************************************************************************
  35445. +Marvell GPL License Option
  35446. +
  35447. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35448. +modify this File in accordance with the terms and conditions of the General
  35449. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  35450. +available along with the File in the license.txt file or by writing to the Free
  35451. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  35452. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  35453. +
  35454. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  35455. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  35456. +DISCLAIMED. The GPL License provides additional details about this warranty
  35457. +disclaimer.
  35458. +********************************************************************************
  35459. +Marvell BSD License Option
  35460. +
  35461. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35462. +modify this File under the following licensing terms.
  35463. +Redistribution and use in source and binary forms, with or without modification,
  35464. +are permitted provided that the following conditions are met:
  35465. +
  35466. + * Redistributions of source code must retain the above copyright notice,
  35467. + this list of conditions and the following disclaimer.
  35468. +
  35469. + * Redistributions in binary form must reproduce the above copyright
  35470. + notice, this list of conditions and the following disclaimer in the
  35471. + documentation and/or other materials provided with the distribution.
  35472. +
  35473. + * Neither the name of Marvell nor the names of its contributors may be
  35474. + used to endorse or promote products derived from this software without
  35475. + specific prior written permission.
  35476. +
  35477. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  35478. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  35479. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  35480. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  35481. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  35482. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  35483. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  35484. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  35485. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  35486. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35487. +
  35488. +*******************************************************************************/
  35489. +
  35490. +
  35491. +#include "cpu/mvCpu.h"
  35492. +#include "ctrlEnv/mvCtrlEnvLib.h"
  35493. +#include "ctrlEnv/mvCtrlEnvRegs.h"
  35494. +#include "ctrlEnv/sys/mvCpuIfRegs.h"
  35495. +
  35496. +/* defines */
  35497. +#ifdef MV_DEBUG
  35498. + #define DB(x) x
  35499. +#else
  35500. + #define DB(x)
  35501. +#endif
  35502. +
  35503. +/* locals */
  35504. +
  35505. +/*******************************************************************************
  35506. +* mvCpuPclkGet - Get the CPU pClk (pipe clock)
  35507. +*
  35508. +* DESCRIPTION:
  35509. +* This routine extract the CPU core clock.
  35510. +*
  35511. +* INPUT:
  35512. +* None.
  35513. +*
  35514. +* OUTPUT:
  35515. +* None.
  35516. +*
  35517. +* RETURN:
  35518. +* 32bit clock cycles in MHertz.
  35519. +*
  35520. +*******************************************************************************/
  35521. +/* 6180 have different clk reset sampling */
  35522. +
  35523. +static MV_U32 mvCpu6180PclkGet(MV_VOID)
  35524. +{
  35525. + MV_U32 tmpPClkRate=0;
  35526. + MV_CPU_ARM_CLK cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;
  35527. +
  35528. + tmpPClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  35529. + tmpPClkRate = tmpPClkRate & MSAR_CPUCLCK_MASK_6180;
  35530. + tmpPClkRate = tmpPClkRate >> MSAR_CPUCLCK_OFFS_6180;
  35531. +
  35532. + tmpPClkRate = cpu6180_ddr_l2_CLK[tmpPClkRate].cpuClk;
  35533. +
  35534. + return tmpPClkRate;
  35535. +}
  35536. +
  35537. +
  35538. +MV_U32 mvCpuPclkGet(MV_VOID)
  35539. +{
  35540. +#if defined(PCLCK_AUTO_DETECT)
  35541. + MV_U32 tmpPClkRate=0;
  35542. + MV_U32 cpuCLK[] = MV_CPU_CLCK_TBL;
  35543. +
  35544. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  35545. + return mvCpu6180PclkGet();
  35546. +
  35547. + tmpPClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  35548. + tmpPClkRate = MSAR_CPUCLCK_EXTRACT(tmpPClkRate);
  35549. + tmpPClkRate = cpuCLK[tmpPClkRate];
  35550. +
  35551. + return tmpPClkRate;
  35552. +#else
  35553. + return MV_DEFAULT_PCLK
  35554. +#endif
  35555. +}
  35556. +
  35557. +/*******************************************************************************
  35558. +* mvCpuL2ClkGet - Get the CPU L2 (CPU bus clock)
  35559. +*
  35560. +* DESCRIPTION:
  35561. +* This routine extract the CPU L2 clock.
  35562. +*
  35563. +* RETURN:
  35564. +* 32bit clock cycles in Hertz.
  35565. +*
  35566. +*******************************************************************************/
  35567. +static MV_U32 mvCpu6180L2ClkGet(MV_VOID)
  35568. +{
  35569. + MV_U32 L2ClkRate=0;
  35570. + MV_CPU_ARM_CLK _cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;
  35571. +
  35572. + L2ClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  35573. + L2ClkRate = L2ClkRate & MSAR_CPUCLCK_MASK_6180;
  35574. + L2ClkRate = L2ClkRate >> MSAR_CPUCLCK_OFFS_6180;
  35575. +
  35576. + L2ClkRate = _cpu6180_ddr_l2_CLK[L2ClkRate].l2Clk;
  35577. +
  35578. + return L2ClkRate;
  35579. +
  35580. +}
  35581. +
  35582. +MV_U32 mvCpuL2ClkGet(MV_VOID)
  35583. +{
  35584. +#ifdef L2CLK_AUTO_DETECT
  35585. + MV_U32 L2ClkRate, tmp, pClkRate, indexL2Rtio;
  35586. + MV_U32 L2Rtio[][2] = MV_L2_CLCK_RTIO_TBL;
  35587. +
  35588. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  35589. + return mvCpu6180L2ClkGet();
  35590. +
  35591. + pClkRate = mvCpuPclkGet();
  35592. +
  35593. + tmp = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  35594. + indexL2Rtio = MSAR_L2CLCK_EXTRACT(tmp);
  35595. +
  35596. + L2ClkRate = ((pClkRate * L2Rtio[indexL2Rtio][1]) / L2Rtio[indexL2Rtio][0]);
  35597. +
  35598. + return L2ClkRate;
  35599. +#else
  35600. + return MV_BOARD_DEFAULT_L2CLK;
  35601. +#endif
  35602. +}
  35603. +
  35604. +
  35605. +/*******************************************************************************
  35606. +* mvCpuNameGet - Get CPU name
  35607. +*
  35608. +* DESCRIPTION:
  35609. +* This function returns a string describing the CPU model and revision.
  35610. +*
  35611. +* INPUT:
  35612. +* None.
  35613. +*
  35614. +* OUTPUT:
  35615. +* pNameBuff - Buffer to contain board name string. Minimum size 32 chars.
  35616. +*
  35617. +* RETURN:
  35618. +* None.
  35619. +*******************************************************************************/
  35620. +MV_VOID mvCpuNameGet(char *pNameBuff)
  35621. +{
  35622. + MV_U32 cpuModel;
  35623. +
  35624. + cpuModel = mvOsCpuPartGet();
  35625. +
  35626. + /* The CPU module is indicated in the Processor Version Register (PVR) */
  35627. + switch(cpuModel)
  35628. + {
  35629. + case CPU_PART_MRVL131:
  35630. + mvOsSPrintf(pNameBuff, "%s (Rev %d)", "Marvell Feroceon",mvOsCpuRevGet());
  35631. + break;
  35632. + case CPU_PART_ARM926:
  35633. + mvOsSPrintf(pNameBuff, "%s (Rev %d)", "ARM926",mvOsCpuRevGet());
  35634. + break;
  35635. + case CPU_PART_ARM946:
  35636. + mvOsSPrintf(pNameBuff, "%s (Rev %d)", "ARM946",mvOsCpuRevGet());
  35637. + break;
  35638. + default:
  35639. + mvOsSPrintf(pNameBuff,"??? (0x%04x) (Rev %d)",cpuModel,mvOsCpuRevGet());
  35640. + break;
  35641. + } /* switch */
  35642. +
  35643. + return;
  35644. +}
  35645. +
  35646. +
  35647. +#define MV_PROC_STR_SIZE 50
  35648. +
  35649. +static void mvCpuIfGetL2EccMode(MV_8 *buf)
  35650. +{
  35651. + MV_U32 regVal = MV_REG_READ(CPU_L2_CONFIG_REG);
  35652. + if (regVal & BIT2)
  35653. + mvOsSPrintf(buf, "L2 ECC Enabled");
  35654. + else
  35655. + mvOsSPrintf(buf, "L2 ECC Disabled");
  35656. +}
  35657. +
  35658. +static void mvCpuIfGetL2Mode(MV_8 *buf)
  35659. +{
  35660. + MV_U32 regVal = 0;
  35661. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  35662. + if (regVal & BIT22)
  35663. + mvOsSPrintf(buf, "L2 Enabled");
  35664. + else
  35665. + mvOsSPrintf(buf, "L2 Disabled");
  35666. +}
  35667. +
  35668. +static void mvCpuIfGetL2PrefetchMode(MV_8 *buf)
  35669. +{
  35670. + MV_U32 regVal = 0;
  35671. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  35672. + if (regVal & BIT24)
  35673. + mvOsSPrintf(buf, "L2 Prefetch Disabled");
  35674. + else
  35675. + mvOsSPrintf(buf, "L2 Prefetch Enabled");
  35676. +}
  35677. +
  35678. +static void mvCpuIfGetWriteAllocMode(MV_8 *buf)
  35679. +{
  35680. + MV_U32 regVal = 0;
  35681. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  35682. + if (regVal & BIT28)
  35683. + mvOsSPrintf(buf, "Write Allocate Enabled");
  35684. + else
  35685. + mvOsSPrintf(buf, "Write Allocate Disabled");
  35686. +}
  35687. +
  35688. +static void mvCpuIfGetCpuStreamMode(MV_8 *buf)
  35689. +{
  35690. + MV_U32 regVal = 0;
  35691. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  35692. + if (regVal & BIT29)
  35693. + mvOsSPrintf(buf, "CPU Streaming Enabled");
  35694. + else
  35695. + mvOsSPrintf(buf, "CPU Streaming Disabled");
  35696. +}
  35697. +
  35698. +static void mvCpuIfPrintCpuRegs(void)
  35699. +{
  35700. + MV_U32 regVal = 0;
  35701. +
  35702. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  35703. + mvOsPrintf("Extra Feature Reg = 0x%x\n",regVal);
  35704. +
  35705. + __asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r" (regVal)); /* Read Control register */
  35706. + mvOsPrintf("Control Reg = 0x%x\n",regVal);
  35707. +
  35708. + __asm volatile ("mrc p15, 0, %0, c0, c0, 0" : "=r" (regVal)); /* Read ID Code register */
  35709. + mvOsPrintf("ID Code Reg = 0x%x\n",regVal);
  35710. +
  35711. + __asm volatile ("mrc p15, 0, %0, c0, c0, 1" : "=r" (regVal)); /* Read Cache Type register */
  35712. + mvOsPrintf("Cache Type Reg = 0x%x\n",regVal);
  35713. +
  35714. +}
  35715. +
  35716. +MV_U32 mvCpuIfPrintSystemConfig(MV_8 *buffer, MV_U32 index)
  35717. +{
  35718. + MV_U32 count = 0;
  35719. +
  35720. + MV_8 L2_ECC_str[MV_PROC_STR_SIZE];
  35721. + MV_8 L2_En_str[MV_PROC_STR_SIZE];
  35722. + MV_8 L2_Prefetch_str[MV_PROC_STR_SIZE];
  35723. + MV_8 Write_Alloc_str[MV_PROC_STR_SIZE];
  35724. + MV_8 Cpu_Stream_str[MV_PROC_STR_SIZE];
  35725. +
  35726. + mvCpuIfGetL2Mode(L2_En_str);
  35727. + mvCpuIfGetL2EccMode(L2_ECC_str);
  35728. + mvCpuIfGetL2PrefetchMode(L2_Prefetch_str);
  35729. + mvCpuIfGetWriteAllocMode(Write_Alloc_str);
  35730. + mvCpuIfGetCpuStreamMode(Cpu_Stream_str);
  35731. + mvCpuIfPrintCpuRegs();
  35732. +
  35733. + count += mvOsSPrintf(buffer + count + index, "%s\n", L2_En_str);
  35734. + count += mvOsSPrintf(buffer + count + index, "%s\n", L2_ECC_str);
  35735. + count += mvOsSPrintf(buffer + count + index, "%s\n", L2_Prefetch_str);
  35736. + count += mvOsSPrintf(buffer + count + index, "%s\n", Write_Alloc_str);
  35737. + count += mvOsSPrintf(buffer + count + index, "%s\n", Cpu_Stream_str);
  35738. + return count;
  35739. +}
  35740. +
  35741. +MV_U32 whoAmI(MV_VOID)
  35742. +{
  35743. + return 0;
  35744. +}
  35745. +
  35746. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h
  35747. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h 1970-01-01 01:00:00.000000000 +0100
  35748. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h 2010-08-05 22:02:16.254829572 +0200
  35749. @@ -0,0 +1,99 @@
  35750. +/*******************************************************************************
  35751. +Copyright (C) Marvell International Ltd. and its affiliates
  35752. +
  35753. +This software file (the "File") is owned and distributed by Marvell
  35754. +International Ltd. and/or its affiliates ("Marvell") under the following
  35755. +alternative licensing terms. Once you have made an election to distribute the
  35756. +File under one of the following license alternatives, please (i) delete this
  35757. +introductory statement regarding license alternatives, (ii) delete the two
  35758. +license alternatives that you have not elected to use and (iii) preserve the
  35759. +Marvell copyright notice above.
  35760. +
  35761. +********************************************************************************
  35762. +Marvell Commercial License Option
  35763. +
  35764. +If you received this File from Marvell and you have entered into a commercial
  35765. +license agreement (a "Commercial License") with Marvell, the File is licensed
  35766. +to you under the terms of the applicable Commercial License.
  35767. +
  35768. +********************************************************************************
  35769. +Marvell GPL License Option
  35770. +
  35771. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35772. +modify this File in accordance with the terms and conditions of the General
  35773. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  35774. +available along with the File in the license.txt file or by writing to the Free
  35775. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  35776. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  35777. +
  35778. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  35779. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  35780. +DISCLAIMED. The GPL License provides additional details about this warranty
  35781. +disclaimer.
  35782. +********************************************************************************
  35783. +Marvell BSD License Option
  35784. +
  35785. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35786. +modify this File under the following licensing terms.
  35787. +Redistribution and use in source and binary forms, with or without modification,
  35788. +are permitted provided that the following conditions are met:
  35789. +
  35790. + * Redistributions of source code must retain the above copyright notice,
  35791. + this list of conditions and the following disclaimer.
  35792. +
  35793. + * Redistributions in binary form must reproduce the above copyright
  35794. + notice, this list of conditions and the following disclaimer in the
  35795. + documentation and/or other materials provided with the distribution.
  35796. +
  35797. + * Neither the name of Marvell nor the names of its contributors may be
  35798. + used to endorse or promote products derived from this software without
  35799. + specific prior written permission.
  35800. +
  35801. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  35802. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  35803. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  35804. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  35805. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  35806. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  35807. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  35808. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  35809. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  35810. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35811. +
  35812. +*******************************************************************************/
  35813. +
  35814. +
  35815. +#ifndef __INCmvCpuh
  35816. +#define __INCmvCpuh
  35817. +
  35818. +#include "mvCommon.h"
  35819. +#include "mvOs.h"
  35820. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  35821. +
  35822. +/* defines */
  35823. +#define CPU_PART_MRVL131 0x131
  35824. +#define CPU_PART_ARM926 0x926
  35825. +#define CPU_PART_ARM946 0x946
  35826. +#define MV_CPU_ARM_CLK_ELM_SIZE 12
  35827. +#define MV_CPU_ARM_CLK_RATIO_OFF 8
  35828. +#define MV_CPU_ARM_CLK_DDR_OFF 4
  35829. +
  35830. +#ifndef MV_ASMLANGUAGE
  35831. +typedef struct _mvCpuArmClk
  35832. +{
  35833. + MV_U32 cpuClk; /* CPU clock in MHz */
  35834. + MV_U32 ddrClk; /* DDR clock in MHz */
  35835. + MV_U32 l2Clk; /* CPU DDR clock ratio */
  35836. +
  35837. +}MV_CPU_ARM_CLK;
  35838. +
  35839. +MV_U32 mvCpuPclkGet(MV_VOID);
  35840. +MV_VOID mvCpuNameGet(char *pNameBuff);
  35841. +MV_U32 mvCpuL2ClkGet(MV_VOID);
  35842. +MV_U32 mvCpuIfPrintSystemConfig(MV_8 *buffer, MV_U32 index);
  35843. +MV_U32 whoAmI(MV_VOID);
  35844. +
  35845. +#endif /* MV_ASMLANGUAGE */
  35846. +
  35847. +
  35848. +#endif /* __INCmvCpuh */
  35849. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c
  35850. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c 1970-01-01 01:00:00.000000000 +0100
  35851. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c 2010-08-05 22:02:16.394867946 +0200
  35852. @@ -0,0 +1,296 @@
  35853. +/*******************************************************************************
  35854. +Copyright (C) Marvell International Ltd. and its affiliates
  35855. +
  35856. +This software file (the "File") is owned and distributed by Marvell
  35857. +International Ltd. and/or its affiliates ("Marvell") under the following
  35858. +alternative licensing terms. Once you have made an election to distribute the
  35859. +File under one of the following license alternatives, please (i) delete this
  35860. +introductory statement regarding license alternatives, (ii) delete the two
  35861. +license alternatives that you have not elected to use and (iii) preserve the
  35862. +Marvell copyright notice above.
  35863. +
  35864. +********************************************************************************
  35865. +Marvell Commercial License Option
  35866. +
  35867. +If you received this File from Marvell and you have entered into a commercial
  35868. +license agreement (a "Commercial License") with Marvell, the File is licensed
  35869. +to you under the terms of the applicable Commercial License.
  35870. +
  35871. +********************************************************************************
  35872. +Marvell GPL License Option
  35873. +
  35874. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35875. +modify this File in accordance with the terms and conditions of the General
  35876. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  35877. +available along with the File in the license.txt file or by writing to the Free
  35878. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  35879. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  35880. +
  35881. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  35882. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  35883. +DISCLAIMED. The GPL License provides additional details about this warranty
  35884. +disclaimer.
  35885. +********************************************************************************
  35886. +Marvell BSD License Option
  35887. +
  35888. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35889. +modify this File under the following licensing terms.
  35890. +Redistribution and use in source and binary forms, with or without modification,
  35891. +are permitted provided that the following conditions are met:
  35892. +
  35893. + * Redistributions of source code must retain the above copyright notice,
  35894. + this list of conditions and the following disclaimer.
  35895. +
  35896. + * Redistributions in binary form must reproduce the above copyright
  35897. + notice, this list of conditions and the following disclaimer in the
  35898. + documentation and/or other materials provided with the distribution.
  35899. +
  35900. + * Neither the name of Marvell nor the names of its contributors may be
  35901. + used to endorse or promote products derived from this software without
  35902. + specific prior written permission.
  35903. +
  35904. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  35905. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  35906. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  35907. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  35908. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  35909. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  35910. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  35911. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  35912. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  35913. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35914. +
  35915. +*******************************************************************************/
  35916. +
  35917. +/*******************************************************************************
  35918. +* mvCtrlEnvAddrDec.h - Marvell controller address decode library
  35919. +*
  35920. +* DESCRIPTION:
  35921. +*
  35922. +* DEPENDENCIES:
  35923. +* None.
  35924. +*
  35925. +*******************************************************************************/
  35926. +
  35927. +/* includes */
  35928. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  35929. +#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
  35930. +#include "ddr2/mvDramIfRegs.h"
  35931. +#include "pex/mvPexRegs.h"
  35932. +
  35933. +#define MV_DEBUG
  35934. +
  35935. +/* defines */
  35936. +#ifdef MV_DEBUG
  35937. + #define DB(x) x
  35938. +#else
  35939. + #define DB(x)
  35940. +#endif
  35941. +
  35942. +/* Default Attributes array */
  35943. +MV_TARGET_ATTRIB mvTargetDefaultsArray[] = TARGETS_DEF_ARRAY;
  35944. +extern MV_TARGET *sampleAtResetTargetArray;
  35945. +/* Dram\AHBToMbus\PEX share regsiter */
  35946. +
  35947. +#define CTRL_DEC_BASE_OFFS 16
  35948. +#define CTRL_DEC_BASE_MASK (0xffff << CTRL_DEC_BASE_OFFS)
  35949. +#define CTRL_DEC_BASE_ALIGNMENT 0x10000
  35950. +
  35951. +#define CTRL_DEC_SIZE_OFFS 16
  35952. +#define CTRL_DEC_SIZE_MASK (0xffff << CTRL_DEC_SIZE_OFFS)
  35953. +#define CTRL_DEC_SIZE_ALIGNMENT 0x10000
  35954. +
  35955. +#define CTRL_DEC_WIN_EN BIT0
  35956. +
  35957. +
  35958. +
  35959. +/*******************************************************************************
  35960. +* mvCtrlAddrDecToReg - Get address decode register format values
  35961. +*
  35962. +* DESCRIPTION:
  35963. +*
  35964. +* INPUT:
  35965. +*
  35966. +* OUTPUT:
  35967. +*
  35968. +* RETURN:
  35969. +*
  35970. +*******************************************************************************/
  35971. +MV_STATUS mvCtrlAddrDecToReg(MV_ADDR_WIN *pAddrDecWin, MV_DEC_REGS *pAddrDecRegs)
  35972. +{
  35973. +
  35974. + MV_U32 baseToReg=0 , sizeToReg=0;
  35975. +
  35976. + /* BaseLow[31:16] => base register [31:16] */
  35977. + baseToReg = pAddrDecWin->baseLow & CTRL_DEC_BASE_MASK;
  35978. +
  35979. + /* Write to address decode Base Address Register */
  35980. + pAddrDecRegs->baseReg &= ~CTRL_DEC_BASE_MASK;
  35981. + pAddrDecRegs->baseReg |= baseToReg;
  35982. +
  35983. + /* Get size register value according to window size */
  35984. + sizeToReg = ctrlSizeToReg(pAddrDecWin->size, CTRL_DEC_SIZE_ALIGNMENT);
  35985. +
  35986. + /* Size parameter validity check. */
  35987. + if (-1 == sizeToReg)
  35988. + {
  35989. + return MV_BAD_PARAM;
  35990. + }
  35991. +
  35992. + /* set size */
  35993. + pAddrDecRegs->sizeReg &= ~CTRL_DEC_SIZE_MASK;
  35994. + pAddrDecRegs->sizeReg |= (sizeToReg << CTRL_DEC_SIZE_OFFS);
  35995. +
  35996. +
  35997. + return MV_OK;
  35998. +
  35999. +}
  36000. +
  36001. +/*******************************************************************************
  36002. +* mvCtrlRegToAddrDec - Extract address decode struct from registers.
  36003. +*
  36004. +* DESCRIPTION:
  36005. +* This function extract address decode struct from address decode
  36006. +* registers given as parameters.
  36007. +*
  36008. +* INPUT:
  36009. +* pAddrDecRegs - Address decode register struct.
  36010. +*
  36011. +* OUTPUT:
  36012. +* pAddrDecWin - Target window data structure.
  36013. +*
  36014. +* RETURN:
  36015. +* MV_BAD_PARAM if address decode registers data is invalid.
  36016. +*
  36017. +*******************************************************************************/
  36018. +MV_STATUS mvCtrlRegToAddrDec(MV_DEC_REGS *pAddrDecRegs, MV_ADDR_WIN *pAddrDecWin)
  36019. +{
  36020. + MV_U32 sizeRegVal;
  36021. +
  36022. + sizeRegVal = (pAddrDecRegs->sizeReg & CTRL_DEC_SIZE_MASK) >>
  36023. + CTRL_DEC_SIZE_OFFS;
  36024. +
  36025. + pAddrDecWin->size = ctrlRegToSize(sizeRegVal, CTRL_DEC_SIZE_ALIGNMENT);
  36026. +
  36027. +
  36028. + /* Extract base address */
  36029. + /* Base register [31:16] ==> baseLow[31:16] */
  36030. + pAddrDecWin->baseLow = pAddrDecRegs->baseReg & CTRL_DEC_BASE_MASK;
  36031. +
  36032. + pAddrDecWin->baseHigh = 0;
  36033. +
  36034. + return MV_OK;
  36035. +
  36036. +}
  36037. +
  36038. +/*******************************************************************************
  36039. +* mvCtrlAttribGet -
  36040. +*
  36041. +* DESCRIPTION:
  36042. +*
  36043. +* INPUT:
  36044. +*
  36045. +* OUTPUT:
  36046. +*
  36047. +* RETURN:
  36048. +*
  36049. +*******************************************************************************/
  36050. +
  36051. +MV_STATUS mvCtrlAttribGet(MV_TARGET target,
  36052. + MV_TARGET_ATTRIB *targetAttrib)
  36053. +{
  36054. +
  36055. + targetAttrib->attrib = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].attrib;
  36056. + targetAttrib->targetId = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].targetId;
  36057. +
  36058. + return MV_OK;
  36059. +
  36060. +}
  36061. +
  36062. +/*******************************************************************************
  36063. +* mvCtrlGetAttrib -
  36064. +*
  36065. +* DESCRIPTION:
  36066. +*
  36067. +* INPUT:
  36068. +*
  36069. +* OUTPUT:
  36070. +*
  36071. +* RETURN:
  36072. +*
  36073. +*******************************************************************************/
  36074. +MV_TARGET mvCtrlTargetGet(MV_TARGET_ATTRIB *targetAttrib)
  36075. +{
  36076. + MV_TARGET target;
  36077. + MV_TARGET x;
  36078. + for (target = SDRAM_CS0; target < MAX_TARGETS ; target ++)
  36079. + {
  36080. + x = MV_CHANGE_BOOT_CS(target);
  36081. + if ((mvTargetDefaultsArray[x].attrib == targetAttrib->attrib) &&
  36082. + (mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].targetId == targetAttrib->targetId))
  36083. + {
  36084. + /* found it */
  36085. + break;
  36086. + }
  36087. + }
  36088. +
  36089. + return target;
  36090. +}
  36091. +
  36092. +MV_STATUS mvCtrlAddrDecToParams(MV_DEC_WIN *pAddrDecWin,
  36093. + MV_DEC_WIN_PARAMS *pWinParam)
  36094. +{
  36095. + MV_U32 baseToReg=0, sizeToReg=0;
  36096. +
  36097. + /* BaseLow[31:16] => base register [31:16] */
  36098. + baseToReg = pAddrDecWin->addrWin.baseLow & CTRL_DEC_BASE_MASK;
  36099. +
  36100. + /* Write to address decode Base Address Register */
  36101. + pWinParam->baseAddr &= ~CTRL_DEC_BASE_MASK;
  36102. + pWinParam->baseAddr |= baseToReg;
  36103. +
  36104. + /* Get size register value according to window size */
  36105. + sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, CTRL_DEC_SIZE_ALIGNMENT);
  36106. +
  36107. + /* Size parameter validity check. */
  36108. + if (-1 == sizeToReg)
  36109. + {
  36110. + mvOsPrintf("mvCtrlAddrDecToParams: ERR. ctrlSizeToReg failed.\n");
  36111. + return MV_BAD_PARAM;
  36112. + }
  36113. + pWinParam->size = sizeToReg;
  36114. +
  36115. + pWinParam->attrib = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(pAddrDecWin->target)].attrib;
  36116. + pWinParam->targetId = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(pAddrDecWin->target)].targetId;
  36117. +
  36118. + return MV_OK;
  36119. +}
  36120. +
  36121. +MV_STATUS mvCtrlParamsToAddrDec(MV_DEC_WIN_PARAMS *pWinParam,
  36122. + MV_DEC_WIN *pAddrDecWin)
  36123. +{
  36124. + MV_TARGET_ATTRIB targetAttrib;
  36125. +
  36126. + pAddrDecWin->addrWin.baseLow = pWinParam->baseAddr;
  36127. +
  36128. + /* Upper 32bit address base is supported under PCI High Address remap */
  36129. + pAddrDecWin->addrWin.baseHigh = 0;
  36130. +
  36131. + /* Prepare sizeReg to ctrlRegToSize function */
  36132. + pAddrDecWin->addrWin.size = ctrlRegToSize(pWinParam->size, CTRL_DEC_SIZE_ALIGNMENT);
  36133. +
  36134. + if (-1 == pAddrDecWin->addrWin.size)
  36135. + {
  36136. + DB(mvOsPrintf("mvCtrlParamsToAddrDec: ERR. ctrlRegToSize failed.\n"));
  36137. + return MV_BAD_PARAM;
  36138. + }
  36139. + targetAttrib.targetId = pWinParam->targetId;
  36140. + targetAttrib.attrib = pWinParam->attrib;
  36141. +
  36142. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  36143. +
  36144. + return MV_OK;
  36145. +}
  36146. +
  36147. +
  36148. +
  36149. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h
  36150. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h 1970-01-01 01:00:00.000000000 +0100
  36151. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h 2010-08-05 22:02:16.913703708 +0200
  36152. @@ -0,0 +1,203 @@
  36153. +/*******************************************************************************
  36154. +Copyright (C) Marvell International Ltd. and its affiliates
  36155. +
  36156. +This software file (the "File") is owned and distributed by Marvell
  36157. +International Ltd. and/or its affiliates ("Marvell") under the following
  36158. +alternative licensing terms. Once you have made an election to distribute the
  36159. +File under one of the following license alternatives, please (i) delete this
  36160. +introductory statement regarding license alternatives, (ii) delete the two
  36161. +license alternatives that you have not elected to use and (iii) preserve the
  36162. +Marvell copyright notice above.
  36163. +
  36164. +********************************************************************************
  36165. +Marvell Commercial License Option
  36166. +
  36167. +If you received this File from Marvell and you have entered into a commercial
  36168. +license agreement (a "Commercial License") with Marvell, the File is licensed
  36169. +to you under the terms of the applicable Commercial License.
  36170. +
  36171. +********************************************************************************
  36172. +Marvell GPL License Option
  36173. +
  36174. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36175. +modify this File in accordance with the terms and conditions of the General
  36176. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  36177. +available along with the File in the license.txt file or by writing to the Free
  36178. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  36179. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  36180. +
  36181. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  36182. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  36183. +DISCLAIMED. The GPL License provides additional details about this warranty
  36184. +disclaimer.
  36185. +********************************************************************************
  36186. +Marvell BSD License Option
  36187. +
  36188. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36189. +modify this File under the following licensing terms.
  36190. +Redistribution and use in source and binary forms, with or without modification,
  36191. +are permitted provided that the following conditions are met:
  36192. +
  36193. + * Redistributions of source code must retain the above copyright notice,
  36194. + this list of conditions and the following disclaimer.
  36195. +
  36196. + * Redistributions in binary form must reproduce the above copyright
  36197. + notice, this list of conditions and the following disclaimer in the
  36198. + documentation and/or other materials provided with the distribution.
  36199. +
  36200. + * Neither the name of Marvell nor the names of its contributors may be
  36201. + used to endorse or promote products derived from this software without
  36202. + specific prior written permission.
  36203. +
  36204. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  36205. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  36206. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  36207. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  36208. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  36209. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  36210. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  36211. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  36212. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  36213. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36214. +
  36215. +*******************************************************************************/
  36216. +
  36217. +
  36218. +#ifndef __INCmvCtrlEnvAddrDech
  36219. +#define __INCmvCtrlEnvAddrDech
  36220. +
  36221. +/* includes */
  36222. +#include "ctrlEnv/mvCtrlEnvLib.h"
  36223. +#include "ctrlEnv/mvCtrlEnvRegs.h"
  36224. +
  36225. +
  36226. +/* defines */
  36227. +/* DUnit attributes */
  36228. +#define ATMWCR_WIN_DUNIT_CS0_OFFS 0
  36229. +#define ATMWCR_WIN_DUNIT_CS0_MASK BIT0
  36230. +#define ATMWCR_WIN_DUNIT_CS0_REQ (0 << ATMWCR_WIN_DUNIT_CS0_OFFS)
  36231. +
  36232. +#define ATMWCR_WIN_DUNIT_CS1_OFFS 1
  36233. +#define ATMWCR_WIN_DUNIT_CS1_MASK BIT1
  36234. +#define ATMWCR_WIN_DUNIT_CS1_REQ (0 << ATMWCR_WIN_DUNIT_CS1_OFFS)
  36235. +
  36236. +#define ATMWCR_WIN_DUNIT_CS2_OFFS 2
  36237. +#define ATMWCR_WIN_DUNIT_CS2_MASK BIT2
  36238. +#define ATMWCR_WIN_DUNIT_CS2_REQ (0 << ATMWCR_WIN_DUNIT_CS2_OFFS)
  36239. +
  36240. +#define ATMWCR_WIN_DUNIT_CS3_OFFS 3
  36241. +#define ATMWCR_WIN_DUNIT_CS3_MASK BIT3
  36242. +#define ATMWCR_WIN_DUNIT_CS3_REQ (0 << ATMWCR_WIN_DUNIT_CS3_OFFS)
  36243. +
  36244. +/* RUnit (Device) attributes */
  36245. +#define ATMWCR_WIN_RUNIT_DEVCS0_OFFS 0
  36246. +#define ATMWCR_WIN_RUNIT_DEVCS0_MASK BIT0
  36247. +#define ATMWCR_WIN_RUNIT_DEVCS0_REQ (0 << ATMWCR_WIN_RUNIT_DEVCS0_OFFS)
  36248. +
  36249. +#define ATMWCR_WIN_RUNIT_DEVCS1_OFFS 1
  36250. +#define ATMWCR_WIN_RUNIT_DEVCS1_MASK BIT1
  36251. +#define ATMWCR_WIN_RUNIT_DEVCS1_REQ (0 << ATMWCR_WIN_RUNIT_DEVCS1_OFFS)
  36252. +
  36253. +#define ATMWCR_WIN_RUNIT_DEVCS2_OFFS 2
  36254. +#define ATMWCR_WIN_RUNIT_DEVCS2_MASK BIT2
  36255. +#define ATMWCR_WIN_RUNIT_DEVCS2_REQ (0 << ATMWCR_WIN_RUNIT_DEVCS2_OFFS)
  36256. +
  36257. +#define ATMWCR_WIN_RUNIT_BOOTCS_OFFS 4
  36258. +#define ATMWCR_WIN_RUNIT_BOOTCS_MASK BIT4
  36259. +#define ATMWCR_WIN_RUNIT_BOOTCS_REQ (0 << ATMWCR_WIN_RUNIT_BOOTCS_OFFS)
  36260. +
  36261. +/* LMaster (PCI) attributes */
  36262. +#define ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS 0
  36263. +#define ATMWCR_WIN_LUNIT_BYTE_SWP_MASK BIT0
  36264. +#define ATMWCR_WIN_LUNIT_BYTE_SWP (0 << ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS)
  36265. +#define ATMWCR_WIN_LUNIT_BYTE_NO_SWP (1 << ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS)
  36266. +
  36267. +
  36268. +#define ATMWCR_WIN_LUNIT_WORD_SWP_OFFS 1
  36269. +#define ATMWCR_WIN_LUNIT_WORD_SWP_MASK BIT1
  36270. +#define ATMWCR_WIN_LUNIT_WORD_SWP (0 << ATMWCR_WIN_LUNIT_WORD_SWP_OFFS)
  36271. +#define ATMWCR_WIN_LUNIT_WORD_NO_SWP (1 << ATMWCR_WIN_LUNIT_WORD_SWP_OFFS)
  36272. +
  36273. +#define ATMWCR_WIN_LUNIT_NO_SNOOP BIT2
  36274. +
  36275. +#define ATMWCR_WIN_LUNIT_TYPE_OFFS 3
  36276. +#define ATMWCR_WIN_LUNIT_TYPE_MASK BIT3
  36277. +#define ATMWCR_WIN_LUNIT_TYPE_IO (0 << ATMWCR_WIN_LUNIT_TYPE_OFFS)
  36278. +#define ATMWCR_WIN_LUNIT_TYPE_MEM (1 << ATMWCR_WIN_LUNIT_TYPE_OFFS)
  36279. +
  36280. +#define ATMWCR_WIN_LUNIT_FORCE64_OFFS 4
  36281. +#define ATMWCR_WIN_LUNIT_FORCE64_MASK BIT4
  36282. +#define ATMWCR_WIN_LUNIT_FORCE64 (0 << ATMWCR_WIN_LUNIT_FORCE64_OFFS)
  36283. +
  36284. +#define ATMWCR_WIN_LUNIT_ORDERING_OFFS 6
  36285. +#define ATMWCR_WIN_LUNIT_ORDERING_MASK BIT6
  36286. +#define ATMWCR_WIN_LUNIT_ORDERING (1 << ATMWCR_WIN_LUNIT_FORCE64_OFFS)
  36287. +
  36288. +/* PEX Attributes */
  36289. +#define ATMWCR_WIN_PEX_TYPE_OFFS 3
  36290. +#define ATMWCR_WIN_PEX_TYPE_MASK BIT3
  36291. +#define ATMWCR_WIN_PEX_TYPE_IO (0 << ATMWCR_WIN_PEX_TYPE_OFFS)
  36292. +#define ATMWCR_WIN_PEX_TYPE_MEM (1 << ATMWCR_WIN_PEX_TYPE_OFFS)
  36293. +
  36294. +/* typedefs */
  36295. +
  36296. +/* Unsupported attributes for address decode: */
  36297. +/* 2) PCI0/1_REQ64n control */
  36298. +
  36299. +typedef struct _mvDecRegs
  36300. +{
  36301. + MV_U32 baseReg;
  36302. + MV_U32 baseRegHigh;
  36303. + MV_U32 sizeReg;
  36304. +
  36305. +}MV_DEC_REGS;
  36306. +
  36307. +typedef struct _mvTargetAttrib
  36308. +{
  36309. + MV_U8 attrib; /* chip select attributes */
  36310. + MV_TARGET_ID targetId; /* Target Id of this MV_TARGET */
  36311. +
  36312. +}MV_TARGET_ATTRIB;
  36313. +
  36314. +
  36315. +/* This structure describes address decode window */
  36316. +typedef struct _mvDecWin
  36317. +{
  36318. + MV_TARGET target; /* Target for addr decode window */
  36319. + MV_ADDR_WIN addrWin; /* Address window of target */
  36320. + MV_BOOL enable; /* Window enable/disable */
  36321. +}MV_DEC_WIN;
  36322. +
  36323. +typedef struct _mvDecWinParams
  36324. +{
  36325. + MV_TARGET_ID targetId; /* Target ID field */
  36326. + MV_U8 attrib; /* Attribute field */
  36327. + MV_U32 baseAddr; /* Base address in register format */
  36328. + MV_U32 size; /* Size in register format */
  36329. +}MV_DEC_WIN_PARAMS;
  36330. +
  36331. +
  36332. +/* mvCtrlEnvAddrDec API list */
  36333. +
  36334. +MV_STATUS mvCtrlAddrDecToReg(MV_ADDR_WIN *pAddrDecWin,
  36335. + MV_DEC_REGS *pAddrDecRegs);
  36336. +
  36337. +MV_STATUS mvCtrlRegToAddrDec(MV_DEC_REGS *pAddrDecRegs,
  36338. + MV_ADDR_WIN *pAddrDecWin);
  36339. +
  36340. +MV_STATUS mvCtrlAttribGet(MV_TARGET target,
  36341. + MV_TARGET_ATTRIB *targetAttrib);
  36342. +
  36343. +MV_TARGET mvCtrlTargetGet(MV_TARGET_ATTRIB *targetAttrib);
  36344. +
  36345. +
  36346. +MV_STATUS mvCtrlAddrDecToParams(MV_DEC_WIN *pAddrDecWin,
  36347. + MV_DEC_WIN_PARAMS *pWinParam);
  36348. +
  36349. +MV_STATUS mvCtrlParamsToAddrDec(MV_DEC_WIN_PARAMS *pWinParam,
  36350. + MV_DEC_WIN *pAddrDecWin);
  36351. +
  36352. +
  36353. +
  36354. +
  36355. +#endif /* __INCmvCtrlEnvAddrDech */
  36356. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h
  36357. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h 1970-01-01 01:00:00.000000000 +0100
  36358. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h 2010-08-05 22:02:16.993851613 +0200
  36359. @@ -0,0 +1,98 @@
  36360. +/*******************************************************************************
  36361. +Copyright (C) Marvell International Ltd. and its affiliates
  36362. +
  36363. +This software file (the "File") is owned and distributed by Marvell
  36364. +International Ltd. and/or its affiliates ("Marvell") under the following
  36365. +alternative licensing terms. Once you have made an election to distribute the
  36366. +File under one of the following license alternatives, please (i) delete this
  36367. +introductory statement regarding license alternatives, (ii) delete the two
  36368. +license alternatives that you have not elected to use and (iii) preserve the
  36369. +Marvell copyright notice above.
  36370. +
  36371. +********************************************************************************
  36372. +Marvell Commercial License Option
  36373. +
  36374. +If you received this File from Marvell and you have entered into a commercial
  36375. +license agreement (a "Commercial License") with Marvell, the File is licensed
  36376. +to you under the terms of the applicable Commercial License.
  36377. +
  36378. +********************************************************************************
  36379. +Marvell GPL License Option
  36380. +
  36381. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36382. +modify this File in accordance with the terms and conditions of the General
  36383. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  36384. +available along with the File in the license.txt file or by writing to the Free
  36385. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  36386. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  36387. +
  36388. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  36389. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  36390. +DISCLAIMED. The GPL License provides additional details about this warranty
  36391. +disclaimer.
  36392. +********************************************************************************
  36393. +Marvell BSD License Option
  36394. +
  36395. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36396. +modify this File under the following licensing terms.
  36397. +Redistribution and use in source and binary forms, with or without modification,
  36398. +are permitted provided that the following conditions are met:
  36399. +
  36400. + * Redistributions of source code must retain the above copyright notice,
  36401. + this list of conditions and the following disclaimer.
  36402. +
  36403. + * Redistributions in binary form must reproduce the above copyright
  36404. + notice, this list of conditions and the following disclaimer in the
  36405. + documentation and/or other materials provided with the distribution.
  36406. +
  36407. + * Neither the name of Marvell nor the names of its contributors may be
  36408. + used to endorse or promote products derived from this software without
  36409. + specific prior written permission.
  36410. +
  36411. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  36412. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  36413. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  36414. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  36415. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  36416. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  36417. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  36418. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  36419. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  36420. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36421. +
  36422. +*******************************************************************************/
  36423. +
  36424. +
  36425. +#ifndef __INCmvCtrlEnvAsmh
  36426. +#define __INCmvCtrlEnvAsmh
  36427. +#include "pex/mvPexRegs.h"
  36428. +
  36429. +#define CHIP_BOND_REG 0x10034
  36430. +#define PCKG_OPT_MASK_AS #3
  36431. +#define PXCCARI_REVID_MASK_AS #PXCCARI_REVID_MASK
  36432. +
  36433. +/* Read device ID into toReg bits 15:0 from 0xd0000000 */
  36434. +/* defines */
  36435. +#define MV_DV_CTRL_MODEL_GET_ASM(toReg, tmpReg) \
  36436. + MV_DV_REG_READ_ASM(toReg, tmpReg, CHIP_BOND_REG);\
  36437. + and toReg, toReg, PCKG_OPT_MASK_AS /* Mask for package ID */
  36438. +
  36439. +/* Read device ID into toReg bits 15:0 from 0xf1000000*/
  36440. +#define MV_CTRL_MODEL_GET_ASM(toReg, tmpReg) \
  36441. + MV_REG_READ_ASM(toReg, tmpReg, CHIP_BOND_REG);\
  36442. + and toReg, toReg, PCKG_OPT_MASK_AS /* Mask for package ID */
  36443. +
  36444. +/* Read Revision into toReg bits 7:0 0xd0000000*/
  36445. +#define MV_DV_CTRL_REV_GET_ASM(toReg, tmpReg) \
  36446. + /* Read device revision */ \
  36447. + MV_DV_REG_READ_ASM(toReg, tmpReg, PEX_CFG_DIRECT_ACCESS(0,PEX_CLASS_CODE_AND_REVISION_ID));\
  36448. + and toReg, toReg, PXCCARI_REVID_MASK_AS /* Mask for calss ID */
  36449. +
  36450. +/* Read Revision into toReg bits 7:0 0xf1000000*/
  36451. +#define MV_CTRL_REV_GET_ASM(toReg, tmpReg) \
  36452. + /* Read device revision */ \
  36453. + MV_REG_READ_ASM(toReg, tmpReg, PEX_CFG_DIRECT_ACCESS(0,PEX_CLASS_CODE_AND_REVISION_ID));\
  36454. + and toReg, toReg, PXCCARI_REVID_MASK_AS /* Mask for calss ID */
  36455. +
  36456. +
  36457. +#endif /* __INCmvCtrlEnvAsmh */
  36458. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c
  36459. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c 1970-01-01 01:00:00.000000000 +0100
  36460. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c 2010-08-05 22:02:17.183795530 +0200
  36461. @@ -0,0 +1,1825 @@
  36462. +/*******************************************************************************
  36463. +Copyright (C) Marvell International Ltd. and its affiliates
  36464. +
  36465. +This software file (the "File") is owned and distributed by Marvell
  36466. +International Ltd. and/or its affiliates ("Marvell") under the following
  36467. +alternative licensing terms. Once you have made an election to distribute the
  36468. +File under one of the following license alternatives, please (i) delete this
  36469. +introductory statement regarding license alternatives, (ii) delete the two
  36470. +license alternatives that you have not elected to use and (iii) preserve the
  36471. +Marvell copyright notice above.
  36472. +
  36473. +********************************************************************************
  36474. +Marvell Commercial License Option
  36475. +
  36476. +If you received this File from Marvell and you have entered into a commercial
  36477. +license agreement (a "Commercial License") with Marvell, the File is licensed
  36478. +to you under the terms of the applicable Commercial License.
  36479. +
  36480. +********************************************************************************
  36481. +Marvell GPL License Option
  36482. +
  36483. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36484. +modify this File in accordance with the terms and conditions of the General
  36485. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  36486. +available along with the File in the license.txt file or by writing to the Free
  36487. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  36488. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  36489. +
  36490. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  36491. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  36492. +DISCLAIMED. The GPL License provides additional details about this warranty
  36493. +disclaimer.
  36494. +********************************************************************************
  36495. +Marvell BSD License Option
  36496. +
  36497. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36498. +modify this File under the following licensing terms.
  36499. +Redistribution and use in source and binary forms, with or without modification,
  36500. +are permitted provided that the following conditions are met:
  36501. +
  36502. + * Redistributions of source code must retain the above copyright notice,
  36503. + this list of conditions and the following disclaimer.
  36504. +
  36505. + * Redistributions in binary form must reproduce the above copyright
  36506. + notice, this list of conditions and the following disclaimer in the
  36507. + documentation and/or other materials provided with the distribution.
  36508. +
  36509. + * Neither the name of Marvell nor the names of its contributors may be
  36510. + used to endorse or promote products derived from this software without
  36511. + specific prior written permission.
  36512. +
  36513. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  36514. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  36515. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  36516. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  36517. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  36518. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  36519. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  36520. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  36521. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  36522. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36523. +
  36524. +*******************************************************************************/
  36525. +
  36526. +
  36527. +/* includes */
  36528. +#include "mvCommon.h"
  36529. +#include "mvCtrlEnvLib.h"
  36530. +#include "ctrlEnv/sys/mvCpuIf.h"
  36531. +
  36532. +#if defined(MV_INCLUDE_PEX)
  36533. +#include "pex/mvPex.h"
  36534. +#include "ctrlEnv/sys/mvSysPex.h"
  36535. +#endif
  36536. +
  36537. +#if defined(MV_INCLUDE_GIG_ETH)
  36538. +#include "ctrlEnv/sys/mvSysGbe.h"
  36539. +#endif
  36540. +
  36541. +#if defined(MV_INCLUDE_XOR)
  36542. +#include "ctrlEnv/sys/mvSysXor.h"
  36543. +#endif
  36544. +
  36545. +#if defined(MV_INCLUDE_SATA)
  36546. +#include "ctrlEnv/sys/mvSysSata.h"
  36547. +#endif
  36548. +
  36549. +#if defined(MV_INCLUDE_USB)
  36550. +#include "ctrlEnv/sys/mvSysUsb.h"
  36551. +#endif
  36552. +
  36553. +#if defined(MV_INCLUDE_AUDIO)
  36554. +#include "ctrlEnv/sys/mvSysAudio.h"
  36555. +#endif
  36556. +
  36557. +#if defined(MV_INCLUDE_CESA)
  36558. +#include "ctrlEnv/sys/mvSysCesa.h"
  36559. +#endif
  36560. +
  36561. +#if defined(MV_INCLUDE_TS)
  36562. +#include "ctrlEnv/sys/mvSysTs.h"
  36563. +#endif
  36564. +
  36565. +/* defines */
  36566. +#ifdef MV_DEBUG
  36567. + #define DB(x) x
  36568. +#else
  36569. + #define DB(x)
  36570. +#endif
  36571. +
  36572. +/*******************************************************************************
  36573. +* mvCtrlEnvInit - Initialize Marvell controller environment.
  36574. +*
  36575. +* DESCRIPTION:
  36576. +* This function get environment information and initialize controller
  36577. +* internal/external environment. For example
  36578. +* 1) MPP settings according to board MPP macros.
  36579. +* NOTE: It is the user responsibility to shut down all DMA channels
  36580. +* in device and disable controller sub units interrupts during
  36581. +* boot process.
  36582. +*
  36583. +* INPUT:
  36584. +* None.
  36585. +*
  36586. +* OUTPUT:
  36587. +* None.
  36588. +*
  36589. +* RETURN:
  36590. +* None.
  36591. +*
  36592. +*******************************************************************************/
  36593. +MV_STATUS mvCtrlEnvInit(MV_VOID)
  36594. +{
  36595. + MV_U32 mppGroup;
  36596. + MV_U32 devId;
  36597. + MV_U32 boardId;
  36598. + MV_U32 i;
  36599. + MV_U32 maxMppGrp = 1;
  36600. + MV_U32 mppVal = 0;
  36601. + MV_U32 bootVal = 0;
  36602. + MV_U32 mppGroupType = 0;
  36603. + MV_U32 mppGroup1[][3] = MPP_GROUP_1_TYPE;
  36604. + MV_U32 mppGroup2[][3] = MPP_GROUP_2_TYPE;
  36605. +
  36606. + devId = mvCtrlModelGet();
  36607. + boardId= mvBoardIdGet();
  36608. +
  36609. + switch(devId){
  36610. + case MV_6281_DEV_ID:
  36611. + maxMppGrp = MV_6281_MPP_MAX_GROUP;
  36612. + break;
  36613. + case MV_6192_DEV_ID:
  36614. + maxMppGrp = MV_6192_MPP_MAX_GROUP;
  36615. + break;
  36616. + case MV_6190_DEV_ID:
  36617. + maxMppGrp = MV_6190_MPP_MAX_GROUP;
  36618. + break;
  36619. + case MV_6180_DEV_ID:
  36620. + maxMppGrp = MV_6180_MPP_MAX_GROUP;
  36621. + break;
  36622. + }
  36623. +
  36624. + /* MPP Init */
  36625. + /* We split mpp init to 3 phases:
  36626. + * 1. We init mpp[19:0] from the board info. mpp[23:20] will be over write
  36627. + * in phase 2.
  36628. + * 2. We detect the mpp group type and according the mpp values [35:20].
  36629. + * 3. We detect the mpp group type and according the mpp values [49:36].
  36630. + */
  36631. + /* Mpp phase 1 mpp[19:0] */
  36632. + /* Read MPP group from board level and assign to MPP register */
  36633. + for (mppGroup = 0; mppGroup < 3; mppGroup++)
  36634. + {
  36635. + mppVal = mvBoardMppGet(mppGroup);
  36636. + if (mppGroup == 0)
  36637. + {
  36638. + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
  36639. + if (mvCtrlIsBootFromSPI())
  36640. + {
  36641. + mppVal &= ~0xffff;
  36642. + bootVal &= 0xffff;
  36643. + mppVal |= bootVal;
  36644. + }
  36645. + else if (mvCtrlIsBootFromSPIUseNAND())
  36646. + {
  36647. + mppVal &= ~0xf0000000;
  36648. + bootVal &= 0xf0000000;
  36649. + mppVal |= bootVal;
  36650. + }
  36651. + else if (mvCtrlIsBootFromNAND())
  36652. + {
  36653. + mppVal &= ~0xffffff;
  36654. + bootVal &= 0xffffff;
  36655. + mppVal |= bootVal;
  36656. + }
  36657. + }
  36658. +
  36659. + if (mppGroup == 2)
  36660. + {
  36661. + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
  36662. + if (mvCtrlIsBootFromNAND())
  36663. + {
  36664. + mppVal &= ~0xff00;
  36665. + bootVal &= 0xff00;
  36666. + mppVal |= bootVal;
  36667. + }
  36668. + }
  36669. +
  36670. + MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
  36671. + }
  36672. +
  36673. + /* Identify MPPs group */
  36674. + mvBoardMppGroupIdUpdate();
  36675. +
  36676. + /* Update MPPs mux relevent only on Marvell DB */
  36677. + if ((boardId == DB_88F6281A_BP_ID) ||
  36678. + (boardId == DB_88F6180A_BP_ID))
  36679. + mvBoardMppMuxSet();
  36680. +
  36681. + mppGroupType = mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_1);
  36682. +
  36683. + /* Mpp phase 2 */
  36684. + /* Read MPP group from board level and assign to MPP register */
  36685. + if (devId != MV_6180_DEV_ID)
  36686. + {
  36687. + i = 0;
  36688. + for (mppGroup = 2; mppGroup < 5; mppGroup++)
  36689. + {
  36690. + if ((mppGroupType == MV_BOARD_OTHER) ||
  36691. + (boardId == RD_88F6281A_ID) ||
  36692. + (boardId == RD_88F6192A_ID) ||
  36693. + (boardId == RD_88F6190A_ID) ||
  36694. + (boardId == RD_88F6281A_PCAC_ID) ||
  36695. + (boardId == SHEEVA_PLUG_ID))
  36696. + mppVal = mvBoardMppGet(mppGroup);
  36697. + else
  36698. + {
  36699. + mppVal = mppGroup1[mppGroupType][i];
  36700. + i++;
  36701. + }
  36702. +
  36703. + /* Group 2 is shared mpp[23:16] */
  36704. + if (mppGroup == 2)
  36705. + {
  36706. + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
  36707. + mppVal &= ~0xffff;
  36708. + bootVal &= 0xffff;
  36709. + mppVal |= bootVal;
  36710. + }
  36711. +
  36712. + MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
  36713. + }
  36714. + }
  36715. +
  36716. + if ((devId == MV_6192_DEV_ID) || (devId == MV_6190_DEV_ID))
  36717. + return MV_OK;
  36718. +
  36719. + /* Mpp phase 3 */
  36720. + mppGroupType = mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_2);
  36721. + /* Read MPP group from board level and assign to MPP register */
  36722. + i = 0;
  36723. + for (mppGroup = 4; mppGroup < 7; mppGroup++)
  36724. + {
  36725. + if ((mppGroupType == MV_BOARD_OTHER) ||
  36726. + (boardId == RD_88F6281A_ID) ||
  36727. + (boardId == RD_88F6281A_PCAC_ID) ||
  36728. + (boardId == SHEEVA_PLUG_ID))
  36729. + mppVal = mvBoardMppGet(mppGroup);
  36730. + else
  36731. + {
  36732. + mppVal = mppGroup2[mppGroupType][i];
  36733. + i++;
  36734. + }
  36735. +
  36736. + /* Group 4 is shared mpp[35:32] */
  36737. + if (mppGroup == 4)
  36738. + {
  36739. + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
  36740. + mppVal &= ~0xffff;
  36741. + bootVal &= 0xffff;
  36742. + mppVal |= bootVal;
  36743. + }
  36744. +
  36745. + MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
  36746. + }
  36747. + /* Update SSCG configuration register*/
  36748. + if(mvBoardIdGet() == DB_88F6281A_BP_ID || mvBoardIdGet() == DB_88F6192A_BP_ID ||
  36749. + mvBoardIdGet() == DB_88F6190A_BP_ID || mvBoardIdGet() == DB_88F6180A_BP_ID)
  36750. + MV_REG_WRITE(0x100d8, 0x53);
  36751. +
  36752. + return MV_OK;
  36753. +}
  36754. +
  36755. +/*******************************************************************************
  36756. +* mvCtrlMppRegGet - return reg address of mpp group
  36757. +*
  36758. +* DESCRIPTION:
  36759. +*
  36760. +* INPUT:
  36761. +* mppGroup - MPP group.
  36762. +*
  36763. +* OUTPUT:
  36764. +* None.
  36765. +*
  36766. +* RETURN:
  36767. +* MV_U32 - Register address.
  36768. +*
  36769. +*******************************************************************************/
  36770. +MV_U32 mvCtrlMppRegGet(MV_U32 mppGroup)
  36771. +{
  36772. + MV_U32 ret;
  36773. +
  36774. + switch(mppGroup){
  36775. + case (0): ret = MPP_CONTROL_REG0;
  36776. + break;
  36777. + case (1): ret = MPP_CONTROL_REG1;
  36778. + break;
  36779. + case (2): ret = MPP_CONTROL_REG2;
  36780. + break;
  36781. + case (3): ret = MPP_CONTROL_REG3;
  36782. + break;
  36783. + case (4): ret = MPP_CONTROL_REG4;
  36784. + break;
  36785. + case (5): ret = MPP_CONTROL_REG5;
  36786. + break;
  36787. + case (6): ret = MPP_CONTROL_REG6;
  36788. + break;
  36789. + default: ret = MPP_CONTROL_REG0;
  36790. + break;
  36791. + }
  36792. + return ret;
  36793. +}
  36794. +#if defined(MV_INCLUDE_PEX)
  36795. +/*******************************************************************************
  36796. +* mvCtrlPexMaxIfGet - Get Marvell controller number of PEX interfaces.
  36797. +*
  36798. +* DESCRIPTION:
  36799. +* This function returns Marvell controller number of PEX interfaces.
  36800. +*
  36801. +* INPUT:
  36802. +* None.
  36803. +*
  36804. +* OUTPUT:
  36805. +* None.
  36806. +*
  36807. +* RETURN:
  36808. +* Marvell controller number of PEX interfaces. If controller
  36809. +* ID is undefined the function returns '0'.
  36810. +*
  36811. +*******************************************************************************/
  36812. +MV_U32 mvCtrlPexMaxIfGet(MV_VOID)
  36813. +{
  36814. +
  36815. + return MV_PEX_MAX_IF;
  36816. +}
  36817. +#endif
  36818. +
  36819. +#if defined(MV_INCLUDE_GIG_ETH)
  36820. +/*******************************************************************************
  36821. +* mvCtrlEthMaxPortGet - Get Marvell controller number of etherent ports.
  36822. +*
  36823. +* DESCRIPTION:
  36824. +* This function returns Marvell controller number of etherent port.
  36825. +*
  36826. +* INPUT:
  36827. +* None.
  36828. +*
  36829. +* OUTPUT:
  36830. +* None.
  36831. +*
  36832. +* RETURN:
  36833. +* Marvell controller number of etherent port.
  36834. +*
  36835. +*******************************************************************************/
  36836. +MV_U32 mvCtrlEthMaxPortGet(MV_VOID)
  36837. +{
  36838. + MV_U32 devId;
  36839. +
  36840. + devId = mvCtrlModelGet();
  36841. +
  36842. + switch(devId){
  36843. + case MV_6281_DEV_ID:
  36844. + return MV_6281_ETH_MAX_PORTS;
  36845. + break;
  36846. + case MV_6192_DEV_ID:
  36847. + return MV_6192_ETH_MAX_PORTS;
  36848. + break;
  36849. + case MV_6190_DEV_ID:
  36850. + return MV_6190_ETH_MAX_PORTS;
  36851. + break;
  36852. + case MV_6180_DEV_ID:
  36853. + return MV_6180_ETH_MAX_PORTS;
  36854. + break;
  36855. + }
  36856. + return 0;
  36857. +
  36858. +}
  36859. +#endif
  36860. +
  36861. +#if defined(MV_INCLUDE_XOR)
  36862. +/*******************************************************************************
  36863. +* mvCtrlXorMaxChanGet - Get Marvell controller number of XOR channels.
  36864. +*
  36865. +* DESCRIPTION:
  36866. +* This function returns Marvell controller number of XOR channels.
  36867. +*
  36868. +* INPUT:
  36869. +* None.
  36870. +*
  36871. +* OUTPUT:
  36872. +* None.
  36873. +*
  36874. +* RETURN:
  36875. +* Marvell controller number of XOR channels.
  36876. +*
  36877. +*******************************************************************************/
  36878. +MV_U32 mvCtrlXorMaxChanGet(MV_VOID)
  36879. +{
  36880. + return MV_XOR_MAX_CHAN;
  36881. +}
  36882. +#endif
  36883. +
  36884. +#if defined(MV_INCLUDE_USB)
  36885. +/*******************************************************************************
  36886. +* mvCtrlUsbHostMaxGet - Get number of Marvell Usb controllers
  36887. +*
  36888. +* DESCRIPTION:
  36889. +*
  36890. +* INPUT:
  36891. +* None.
  36892. +*
  36893. +* OUTPUT:
  36894. +* None.
  36895. +*
  36896. +* RETURN:
  36897. +* returns number of Marvell USB controllers.
  36898. +*
  36899. +*******************************************************************************/
  36900. +MV_U32 mvCtrlUsbMaxGet(void)
  36901. +{
  36902. + return MV_USB_MAX_PORTS;
  36903. +}
  36904. +#endif
  36905. +
  36906. +
  36907. +#if defined(MV_INCLUDE_NAND)
  36908. +/*******************************************************************************
  36909. +* mvCtrlNandSupport - Return if this controller has integrated NAND flash support
  36910. +*
  36911. +* DESCRIPTION:
  36912. +*
  36913. +* INPUT:
  36914. +* None.
  36915. +*
  36916. +* OUTPUT:
  36917. +* None.
  36918. +*
  36919. +* RETURN:
  36920. +* MV_TRUE if NAND is supported and MV_FALSE otherwise
  36921. +*
  36922. +*******************************************************************************/
  36923. +MV_U32 mvCtrlNandSupport(MV_VOID)
  36924. +{
  36925. + MV_U32 devId;
  36926. +
  36927. + devId = mvCtrlModelGet();
  36928. +
  36929. + switch(devId){
  36930. + case MV_6281_DEV_ID:
  36931. + return MV_6281_NAND;
  36932. + break;
  36933. + case MV_6192_DEV_ID:
  36934. + return MV_6192_NAND;
  36935. + break;
  36936. + case MV_6190_DEV_ID:
  36937. + return MV_6190_NAND;
  36938. + break;
  36939. + case MV_6180_DEV_ID:
  36940. + return MV_6180_NAND;
  36941. + break;
  36942. + }
  36943. + return 0;
  36944. +
  36945. +}
  36946. +#endif
  36947. +
  36948. +#if defined(MV_INCLUDE_SDIO)
  36949. +/*******************************************************************************
  36950. +* mvCtrlSdioSupport - Return if this controller has integrated SDIO flash support
  36951. +*
  36952. +* DESCRIPTION:
  36953. +*
  36954. +* INPUT:
  36955. +* None.
  36956. +*
  36957. +* OUTPUT:
  36958. +* None.
  36959. +*
  36960. +* RETURN:
  36961. +* MV_TRUE if SDIO is supported and MV_FALSE otherwise
  36962. +*
  36963. +*******************************************************************************/
  36964. +MV_U32 mvCtrlSdioSupport(MV_VOID)
  36965. +{
  36966. + MV_U32 devId;
  36967. +
  36968. + devId = mvCtrlModelGet();
  36969. +
  36970. + switch(devId){
  36971. + case MV_6281_DEV_ID:
  36972. + return MV_6281_SDIO;
  36973. + break;
  36974. + case MV_6192_DEV_ID:
  36975. + return MV_6192_SDIO;
  36976. + break;
  36977. + case MV_6190_DEV_ID:
  36978. + return MV_6190_SDIO;
  36979. + break;
  36980. + case MV_6180_DEV_ID:
  36981. + return MV_6180_SDIO;
  36982. + break;
  36983. + }
  36984. + return 0;
  36985. +
  36986. +}
  36987. +#endif
  36988. +
  36989. +#if defined(MV_INCLUDE_TS)
  36990. +/*******************************************************************************
  36991. +* mvCtrlTsSupport - Return if this controller has integrated TS flash support
  36992. +*
  36993. +* DESCRIPTION:
  36994. +*
  36995. +* INPUT:
  36996. +* None.
  36997. +*
  36998. +* OUTPUT:
  36999. +* None.
  37000. +*
  37001. +* RETURN:
  37002. +* MV_TRUE if TS is supported and MV_FALSE otherwise
  37003. +*
  37004. +*******************************************************************************/
  37005. +MV_U32 mvCtrlTsSupport(MV_VOID)
  37006. +{
  37007. + MV_U32 devId;
  37008. +
  37009. + devId = mvCtrlModelGet();
  37010. +
  37011. + switch(devId){
  37012. + case MV_6281_DEV_ID:
  37013. + return MV_6281_TS;
  37014. + break;
  37015. + case MV_6192_DEV_ID:
  37016. + return MV_6192_TS;
  37017. + break;
  37018. + case MV_6190_DEV_ID:
  37019. + return MV_6190_TS;
  37020. + break;
  37021. + case MV_6180_DEV_ID:
  37022. + return MV_6180_TS;
  37023. + break;
  37024. + }
  37025. + return 0;
  37026. +}
  37027. +#endif
  37028. +
  37029. +#if defined(MV_INCLUDE_AUDIO)
  37030. +/*******************************************************************************
  37031. +* mvCtrlAudioSupport - Return if this controller has integrated AUDIO flash support
  37032. +*
  37033. +* DESCRIPTION:
  37034. +*
  37035. +* INPUT:
  37036. +* None.
  37037. +*
  37038. +* OUTPUT:
  37039. +* None.
  37040. +*
  37041. +* RETURN:
  37042. +* MV_TRUE if AUDIO is supported and MV_FALSE otherwise
  37043. +*
  37044. +*******************************************************************************/
  37045. +MV_U32 mvCtrlAudioSupport(MV_VOID)
  37046. +{
  37047. + MV_U32 devId;
  37048. +
  37049. + devId = mvCtrlModelGet();
  37050. +
  37051. + switch(devId){
  37052. + case MV_6281_DEV_ID:
  37053. + return MV_6281_AUDIO;
  37054. + break;
  37055. + case MV_6192_DEV_ID:
  37056. + return MV_6192_AUDIO;
  37057. + break;
  37058. + case MV_6190_DEV_ID:
  37059. + return MV_6190_AUDIO;
  37060. + break;
  37061. + case MV_6180_DEV_ID:
  37062. + return MV_6180_AUDIO;
  37063. + break;
  37064. + }
  37065. + return 0;
  37066. +
  37067. +}
  37068. +#endif
  37069. +
  37070. +#if defined(MV_INCLUDE_TDM)
  37071. +/*******************************************************************************
  37072. +* mvCtrlTdmSupport - Return if this controller has integrated TDM flash support
  37073. +*
  37074. +* DESCRIPTION:
  37075. +*
  37076. +* INPUT:
  37077. +* None.
  37078. +*
  37079. +* OUTPUT:
  37080. +* None.
  37081. +*
  37082. +* RETURN:
  37083. +* MV_TRUE if TDM is supported and MV_FALSE otherwise
  37084. +*
  37085. +*******************************************************************************/
  37086. +MV_U32 mvCtrlTdmSupport(MV_VOID)
  37087. +{
  37088. + MV_U32 devId;
  37089. +
  37090. + devId = mvCtrlModelGet();
  37091. +
  37092. + switch(devId){
  37093. + case MV_6281_DEV_ID:
  37094. + return MV_6281_TDM;
  37095. + break;
  37096. + case MV_6192_DEV_ID:
  37097. + return MV_6192_TDM;
  37098. + break;
  37099. + case MV_6190_DEV_ID:
  37100. + return MV_6190_TDM;
  37101. + break;
  37102. + case MV_6180_DEV_ID:
  37103. + return MV_6180_TDM;
  37104. + break;
  37105. + }
  37106. + return 0;
  37107. +
  37108. +}
  37109. +#endif
  37110. +
  37111. +/*******************************************************************************
  37112. +* mvCtrlModelGet - Get Marvell controller device model (Id)
  37113. +*
  37114. +* DESCRIPTION:
  37115. +* This function returns 16bit describing the device model (ID) as defined
  37116. +* in PCI Device and Vendor ID configuration register offset 0x0.
  37117. +*
  37118. +* INPUT:
  37119. +* None.
  37120. +*
  37121. +* OUTPUT:
  37122. +* None.
  37123. +*
  37124. +* RETURN:
  37125. +* 16bit desscribing Marvell controller ID
  37126. +*
  37127. +*******************************************************************************/
  37128. +MV_U16 mvCtrlModelGet(MV_VOID)
  37129. +{
  37130. + MV_U32 devId;
  37131. +
  37132. + devId = MV_REG_READ(CHIP_BOND_REG);
  37133. + devId &= PCKG_OPT_MASK;
  37134. +
  37135. + switch(devId){
  37136. + case 2:
  37137. + return MV_6281_DEV_ID;
  37138. + break;
  37139. + case 1:
  37140. + if (((MV_REG_READ(PEX_CFG_DIRECT_ACCESS(0,PEX_DEVICE_AND_VENDOR_ID))& 0xffff0000) >> 16)
  37141. + == MV_6190_DEV_ID)
  37142. + return MV_6190_DEV_ID;
  37143. + else
  37144. + return MV_6192_DEV_ID;
  37145. + break;
  37146. + case 0:
  37147. + return MV_6180_DEV_ID;
  37148. + break;
  37149. + }
  37150. +
  37151. + return 0;
  37152. +}
  37153. +/*******************************************************************************
  37154. +* mvCtrlRevGet - Get Marvell controller device revision number
  37155. +*
  37156. +* DESCRIPTION:
  37157. +* This function returns 8bit describing the device revision as defined
  37158. +* in PCI Express Class Code and Revision ID Register.
  37159. +*
  37160. +* INPUT:
  37161. +* None.
  37162. +*
  37163. +* OUTPUT:
  37164. +* None.
  37165. +*
  37166. +* RETURN:
  37167. +* 8bit desscribing Marvell controller revision number
  37168. +*
  37169. +*******************************************************************************/
  37170. +MV_U8 mvCtrlRevGet(MV_VOID)
  37171. +{
  37172. + MV_U8 revNum;
  37173. +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
  37174. + /* Check pex power state */
  37175. + MV_U32 pexPower;
  37176. + pexPower = mvCtrlPwrClckGet(PEX_UNIT_ID,0);
  37177. + if (pexPower == MV_FALSE)
  37178. + mvCtrlPwrClckSet(PEX_UNIT_ID, 0, MV_TRUE);
  37179. +#endif
  37180. + revNum = (MV_U8)MV_REG_READ(PEX_CFG_DIRECT_ACCESS(0,PCI_CLASS_CODE_AND_REVISION_ID));
  37181. +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
  37182. + /* Return to power off state */
  37183. + if (pexPower == MV_FALSE)
  37184. + mvCtrlPwrClckSet(PEX_UNIT_ID, 0, MV_FALSE);
  37185. +#endif
  37186. + return ((revNum & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS);
  37187. +}
  37188. +
  37189. +/*******************************************************************************
  37190. +* mvCtrlNameGet - Get Marvell controller name
  37191. +*
  37192. +* DESCRIPTION:
  37193. +* This function returns a string describing the device model and revision.
  37194. +*
  37195. +* INPUT:
  37196. +* None.
  37197. +*
  37198. +* OUTPUT:
  37199. +* pNameBuff - Buffer to contain device name string. Minimum size 30 chars.
  37200. +*
  37201. +* RETURN:
  37202. +*
  37203. +* MV_ERROR if informantion can not be read.
  37204. +*******************************************************************************/
  37205. +MV_STATUS mvCtrlNameGet(char *pNameBuff)
  37206. +{
  37207. + mvOsSPrintf (pNameBuff, "%s%x Rev %d", SOC_NAME_PREFIX,
  37208. + mvCtrlModelGet(), mvCtrlRevGet());
  37209. +
  37210. + return MV_OK;
  37211. +}
  37212. +
  37213. +/*******************************************************************************
  37214. +* mvCtrlModelRevGet - Get Controller Model (Device ID) and Revision
  37215. +*
  37216. +* DESCRIPTION:
  37217. +* This function returns 32bit value describing both Device ID and Revision
  37218. +* as defined in PCI Express Device and Vendor ID Register and device revision
  37219. +* as defined in PCI Express Class Code and Revision ID Register.
  37220. +
  37221. +*
  37222. +* INPUT:
  37223. +* None.
  37224. +*
  37225. +* OUTPUT:
  37226. +* None.
  37227. +*
  37228. +* RETURN:
  37229. +* 32bit describing both controller device ID and revision number
  37230. +*
  37231. +*******************************************************************************/
  37232. +MV_U32 mvCtrlModelRevGet(MV_VOID)
  37233. +{
  37234. + return ((mvCtrlModelGet() << 16) | mvCtrlRevGet());
  37235. +}
  37236. +
  37237. +/*******************************************************************************
  37238. +* mvCtrlModelRevNameGet - Get Marvell controller name
  37239. +*
  37240. +* DESCRIPTION:
  37241. +* This function returns a string describing the device model and revision.
  37242. +*
  37243. +* INPUT:
  37244. +* None.
  37245. +*
  37246. +* OUTPUT:
  37247. +* pNameBuff - Buffer to contain device name string. Minimum size 30 chars.
  37248. +*
  37249. +* RETURN:
  37250. +*
  37251. +* MV_ERROR if informantion can not be read.
  37252. +*******************************************************************************/
  37253. +
  37254. +MV_STATUS mvCtrlModelRevNameGet(char *pNameBuff)
  37255. +{
  37256. +
  37257. + switch (mvCtrlModelRevGet())
  37258. + {
  37259. + case MV_6281_A0_ID:
  37260. + mvOsSPrintf (pNameBuff, "%s",MV_6281_A0_NAME);
  37261. + break;
  37262. + case MV_6192_A0_ID:
  37263. + mvOsSPrintf (pNameBuff, "%s",MV_6192_A0_NAME);
  37264. + break;
  37265. + case MV_6180_A0_ID:
  37266. + mvOsSPrintf (pNameBuff, "%s",MV_6180_A0_NAME);
  37267. + break;
  37268. + case MV_6190_A0_ID:
  37269. + mvOsSPrintf (pNameBuff, "%s",MV_6190_A0_NAME);
  37270. + break;
  37271. + case MV_6281_A1_ID:
  37272. + mvOsSPrintf (pNameBuff, "%s",MV_6281_A1_NAME);
  37273. + break;
  37274. + case MV_6192_A1_ID:
  37275. + mvOsSPrintf (pNameBuff, "%s",MV_6192_A1_NAME);
  37276. + break;
  37277. + case MV_6180_A1_ID:
  37278. + mvOsSPrintf (pNameBuff, "%s",MV_6180_A1_NAME);
  37279. + break;
  37280. + case MV_6190_A1_ID:
  37281. + mvOsSPrintf (pNameBuff, "%s",MV_6190_A1_NAME);
  37282. + break;
  37283. + default:
  37284. + mvCtrlNameGet(pNameBuff);
  37285. + break;
  37286. + }
  37287. +
  37288. + return MV_OK;
  37289. +}
  37290. +
  37291. +
  37292. +/*******************************************************************************
  37293. +* ctrlWinOverlapTest - Test address windows for overlaping.
  37294. +*
  37295. +* DESCRIPTION:
  37296. +* This function checks the given two address windows for overlaping.
  37297. +*
  37298. +* INPUT:
  37299. +* pAddrWin1 - Address window 1.
  37300. +* pAddrWin2 - Address window 2.
  37301. +*
  37302. +* OUTPUT:
  37303. +* None.
  37304. +*
  37305. +* RETURN:
  37306. +*
  37307. +* MV_TRUE if address window overlaps, MV_FALSE otherwise.
  37308. +*******************************************************************************/
  37309. +MV_STATUS ctrlWinOverlapTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2)
  37310. +{
  37311. + MV_U32 winBase1, winBase2;
  37312. + MV_U32 winTop1, winTop2;
  37313. +
  37314. + /* check if we have overflow than 4G*/
  37315. + if (((0xffffffff - pAddrWin1->baseLow) < pAddrWin1->size-1)||
  37316. + ((0xffffffff - pAddrWin2->baseLow) < pAddrWin2->size-1))
  37317. + {
  37318. + return MV_TRUE;
  37319. + }
  37320. +
  37321. + winBase1 = pAddrWin1->baseLow;
  37322. + winBase2 = pAddrWin2->baseLow;
  37323. + winTop1 = winBase1 + pAddrWin1->size-1;
  37324. + winTop2 = winBase2 + pAddrWin2->size-1;
  37325. +
  37326. +
  37327. + if (((winBase1 <= winTop2 ) && ( winTop2 <= winTop1)) ||
  37328. + ((winBase1 <= winBase2) && (winBase2 <= winTop1)))
  37329. + {
  37330. + return MV_TRUE;
  37331. + }
  37332. + else
  37333. + {
  37334. + return MV_FALSE;
  37335. + }
  37336. +}
  37337. +
  37338. +/*******************************************************************************
  37339. +* ctrlWinWithinWinTest - Test address windows for overlaping.
  37340. +*
  37341. +* DESCRIPTION:
  37342. +* This function checks the given win1 boundries is within
  37343. +* win2 boundries.
  37344. +*
  37345. +* INPUT:
  37346. +* pAddrWin1 - Address window 1.
  37347. +* pAddrWin2 - Address window 2.
  37348. +*
  37349. +* OUTPUT:
  37350. +* None.
  37351. +*
  37352. +* RETURN:
  37353. +*
  37354. +* MV_TRUE if found win1 inside win2, MV_FALSE otherwise.
  37355. +*******************************************************************************/
  37356. +MV_STATUS ctrlWinWithinWinTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2)
  37357. +{
  37358. + MV_U32 winBase1, winBase2;
  37359. + MV_U32 winTop1, winTop2;
  37360. +
  37361. + winBase1 = pAddrWin1->baseLow;
  37362. + winBase2 = pAddrWin2->baseLow;
  37363. + winTop1 = winBase1 + pAddrWin1->size -1;
  37364. + winTop2 = winBase2 + pAddrWin2->size -1;
  37365. +
  37366. + if (((winBase1 >= winBase2 ) && ( winBase1 <= winTop2)) ||
  37367. + ((winTop1 >= winBase2) && (winTop1 <= winTop2)))
  37368. + {
  37369. + return MV_TRUE;
  37370. + }
  37371. + else
  37372. + {
  37373. + return MV_FALSE;
  37374. + }
  37375. +}
  37376. +
  37377. +static const char* cntrlName[] = TARGETS_NAME_ARRAY;
  37378. +
  37379. +/*******************************************************************************
  37380. +* mvCtrlTargetNameGet - Get Marvell controller target name
  37381. +*
  37382. +* DESCRIPTION:
  37383. +* This function convert the trget enumeration to string.
  37384. +*
  37385. +* INPUT:
  37386. +* None.
  37387. +*
  37388. +* OUTPUT:
  37389. +* None.
  37390. +*
  37391. +* RETURN:
  37392. +* Target name (const MV_8 *)
  37393. +*******************************************************************************/
  37394. +const MV_8* mvCtrlTargetNameGet( MV_TARGET target )
  37395. +{
  37396. +
  37397. + if (target >= MAX_TARGETS)
  37398. + {
  37399. + return "target unknown";
  37400. + }
  37401. +
  37402. + return cntrlName[target];
  37403. +}
  37404. +
  37405. +/*******************************************************************************
  37406. +* mvCtrlAddrDecShow - Print the Controller units address decode map.
  37407. +*
  37408. +* DESCRIPTION:
  37409. +* This function the Controller units address decode map.
  37410. +*
  37411. +* INPUT:
  37412. +* None.
  37413. +*
  37414. +* OUTPUT:
  37415. +* None.
  37416. +*
  37417. +* RETURN:
  37418. +* None.
  37419. +*
  37420. +*******************************************************************************/
  37421. +MV_VOID mvCtrlAddrDecShow(MV_VOID)
  37422. +{
  37423. + mvCpuIfAddDecShow();
  37424. + mvAhbToMbusAddDecShow();
  37425. +#if defined(MV_INCLUDE_PEX)
  37426. + mvPexAddrDecShow();
  37427. +#endif
  37428. +#if defined(MV_INCLUDE_USB)
  37429. + mvUsbAddrDecShow();
  37430. +#endif
  37431. +#if defined(MV_INCLUDE_GIG_ETH)
  37432. + mvEthAddrDecShow();
  37433. +#endif
  37434. +#if defined(MV_INCLUDE_XOR)
  37435. + mvXorAddrDecShow();
  37436. +#endif
  37437. +#if defined(MV_INCLUDE_SATA)
  37438. + mvSataAddrDecShow();
  37439. +#endif
  37440. +#if defined(MV_INCLUDE_AUDIO)
  37441. + mvAudioAddrDecShow();
  37442. +#endif
  37443. +#if defined(MV_INCLUDE_TS)
  37444. + mvTsuAddrDecShow();
  37445. +#endif
  37446. +}
  37447. +
  37448. +/*******************************************************************************
  37449. +* ctrlSizeToReg - Extract size value for register assignment.
  37450. +*
  37451. +* DESCRIPTION:
  37452. +* Address decode size parameter must be programed from LSB to MSB as
  37453. +* sequence of 1's followed by sequence of 0's. The number of 1's
  37454. +* specifies the size of the window in 64 KB granularity (e.g. a
  37455. +* value of 0x00ff specifies 256x64k = 16 MB).
  37456. +* This function extract the size value from the size parameter according
  37457. +* to given aligment paramter. For example for size 0x1000000 (16MB) and
  37458. +* aligment 0x10000 (64KB) the function will return 0x00FF.
  37459. +*
  37460. +* INPUT:
  37461. +* size - Size.
  37462. +* alignment - Size alignment. Note that alignment must be power of 2!
  37463. +*
  37464. +* OUTPUT:
  37465. +* None.
  37466. +*
  37467. +* RETURN:
  37468. +* 32bit describing size register value correspond to size parameter.
  37469. +* If value is '-1' size parameter or aligment are invalid.
  37470. +*******************************************************************************/
  37471. +MV_U32 ctrlSizeToReg(MV_U32 size, MV_U32 alignment)
  37472. +{
  37473. + MV_U32 retVal;
  37474. +
  37475. + /* Check size parameter alignment */
  37476. + if ((0 == size) || (MV_IS_NOT_ALIGN(size, alignment)))
  37477. + {
  37478. + DB(mvOsPrintf("ctrlSizeToReg: ERR. Size is zero or not aligned.\n"));
  37479. + return -1;
  37480. + }
  37481. +
  37482. + /* Take out the "alignment" portion out of the size parameter */
  37483. + alignment--; /* Now the alignmet is a sequance of '1' (e.g. 0xffff) */
  37484. + /* and size is 0x1000000 (16MB) for example */
  37485. + while(alignment & 1) /* Check that alignmet LSB is set */
  37486. + {
  37487. + size = (size >> 1); /* If LSB is set, move 'size' one bit to right */
  37488. + alignment = (alignment >> 1);
  37489. + }
  37490. +
  37491. + /* If after the alignment first '0' was met we still have '1' in */
  37492. + /* it then aligment is invalid (not power of 2) */
  37493. + if (alignment)
  37494. + {
  37495. + DB(mvOsPrintf("ctrlSizeToReg: ERR. Alignment parameter 0x%x invalid.\n",
  37496. + (MV_U32)alignment));
  37497. + return -1;
  37498. + }
  37499. +
  37500. + /* Now the size is shifted right according to aligment: 0x0100 */
  37501. + size--; /* Now the size is a sequance of '1': 0x00ff */
  37502. +
  37503. + retVal = size ;
  37504. +
  37505. + /* Check that LSB to MSB is sequence of 1's followed by sequence of 0's */
  37506. + while(size & 1) /* Check that LSB is set */
  37507. + {
  37508. + size = (size >> 1); /* If LSB is set, move one bit to the right */
  37509. + }
  37510. +
  37511. + if (size) /* Sequance of 1's is over. Check that we have no other 1's */
  37512. + {
  37513. + DB(mvOsPrintf("ctrlSizeToReg: ERR. Size parameter 0x%x invalid.\n",
  37514. + size));
  37515. + return -1;
  37516. + }
  37517. +
  37518. + return retVal;
  37519. +
  37520. +}
  37521. +
  37522. +/*******************************************************************************
  37523. +* ctrlRegToSize - Extract size value from register value.
  37524. +*
  37525. +* DESCRIPTION:
  37526. +* This function extract a size value from the register size parameter
  37527. +* according to given aligment paramter. For example for register size
  37528. +* value 0xff and aligment 0x10000 the function will return 0x01000000.
  37529. +*
  37530. +* INPUT:
  37531. +* regSize - Size as in register format. See ctrlSizeToReg.
  37532. +* alignment - Size alignment. Note that alignment must be power of 2!
  37533. +*
  37534. +* OUTPUT:
  37535. +* None.
  37536. +*
  37537. +* RETURN:
  37538. +* 32bit describing size.
  37539. +* If value is '-1' size parameter or aligment are invalid.
  37540. +*******************************************************************************/
  37541. +MV_U32 ctrlRegToSize(MV_U32 regSize, MV_U32 alignment)
  37542. +{
  37543. + MV_U32 temp;
  37544. +
  37545. + /* Check that LSB to MSB is sequence of 1's followed by sequence of 0's */
  37546. + temp = regSize; /* Now the size is a sequance of '1': 0x00ff */
  37547. +
  37548. + while(temp & 1) /* Check that LSB is set */
  37549. + {
  37550. + temp = (temp >> 1); /* If LSB is set, move one bit to the right */
  37551. + }
  37552. +
  37553. + if (temp) /* Sequance of 1's is over. Check that we have no other 1's */
  37554. + {
  37555. + DB(mvOsPrintf("ctrlRegToSize: ERR. Size parameter 0x%x invalid.\n",
  37556. + regSize));
  37557. + return -1;
  37558. + }
  37559. +
  37560. +
  37561. + /* Check that aligment is a power of two */
  37562. + temp = alignment - 1;/* Now the alignmet is a sequance of '1' (0xffff) */
  37563. +
  37564. + while(temp & 1) /* Check that alignmet LSB is set */
  37565. + {
  37566. + temp = (temp >> 1); /* If LSB is set, move 'size' one bit to right */
  37567. + }
  37568. +
  37569. + /* If after the 'temp' first '0' was met we still have '1' in 'temp' */
  37570. + /* then 'temp' is invalid (not power of 2) */
  37571. + if (temp)
  37572. + {
  37573. + DB(mvOsPrintf("ctrlSizeToReg: ERR. Alignment parameter 0x%x invalid.\n",
  37574. + alignment));
  37575. + return -1;
  37576. + }
  37577. +
  37578. + regSize++; /* Now the size is 0x0100 */
  37579. +
  37580. + /* Add in the "alignment" portion to the register size parameter */
  37581. + alignment--; /* Now the alignmet is a sequance of '1' (e.g. 0xffff) */
  37582. +
  37583. + while(alignment & 1) /* Check that alignmet LSB is set */
  37584. + {
  37585. + regSize = (regSize << 1); /* LSB is set, move 'size' one bit left */
  37586. + alignment = (alignment >> 1);
  37587. + }
  37588. +
  37589. + return regSize;
  37590. +}
  37591. +
  37592. +
  37593. +/*******************************************************************************
  37594. +* ctrlSizeRegRoundUp - Round up given size
  37595. +*
  37596. +* DESCRIPTION:
  37597. +* This function round up a given size to a size that fits the
  37598. +* restrictions of size format given an aligment parameter.
  37599. +* to given aligment paramter. For example for size parameter 0xa1000 and
  37600. +* aligment 0x1000 the function will return 0xFF000.
  37601. +*
  37602. +* INPUT:
  37603. +* size - Size.
  37604. +* alignment - Size alignment. Note that alignment must be power of 2!
  37605. +*
  37606. +* OUTPUT:
  37607. +* None.
  37608. +*
  37609. +* RETURN:
  37610. +* 32bit describing size value correspond to size in register.
  37611. +*******************************************************************************/
  37612. +MV_U32 ctrlSizeRegRoundUp(MV_U32 size, MV_U32 alignment)
  37613. +{
  37614. + MV_U32 msbBit = 0;
  37615. + MV_U32 retSize;
  37616. +
  37617. + /* Check if size parameter is already comply with restriction */
  37618. + if (!(-1 == ctrlSizeToReg(size, alignment)))
  37619. + {
  37620. + return size;
  37621. + }
  37622. +
  37623. + while(size)
  37624. + {
  37625. + size = (size >> 1);
  37626. + msbBit++;
  37627. + }
  37628. +
  37629. + retSize = (1 << msbBit);
  37630. +
  37631. + if (retSize < alignment)
  37632. + {
  37633. + return alignment;
  37634. + }
  37635. + else
  37636. + {
  37637. + return retSize;
  37638. + }
  37639. +}
  37640. +/*******************************************************************************
  37641. +* mvCtrlSysRstLengthCounterGet - Return number of milliseconds the reset button
  37642. +* was pressed and clear counter
  37643. +*
  37644. +* DESCRIPTION:
  37645. +*
  37646. +* INPUT:
  37647. +*
  37648. +* OUTPUT:
  37649. +*
  37650. +* RETURN: number of milliseconds the reset button was pressed
  37651. +*******************************************************************************/
  37652. +MV_U32 mvCtrlSysRstLengthCounterGet(MV_VOID)
  37653. +{
  37654. + static volatile MV_U32 Count = 0;
  37655. +
  37656. + if(!Count) {
  37657. + Count = (MV_REG_READ(SYSRST_LENGTH_COUNTER_REG) & SLCR_COUNT_MASK);
  37658. + Count = (Count / (MV_BOARD_REFCLK_25MHZ / 1000));
  37659. + /* clear counter for next boot */
  37660. + MV_REG_BIT_SET(SYSRST_LENGTH_COUNTER_REG, SLCR_CLR_MASK);
  37661. + }
  37662. +
  37663. + DB(mvOsPrintf("mvCtrlSysRstLengthCounterGet: Reset button was pressed for %u milliseconds\n", Count));
  37664. +
  37665. + return Count;
  37666. +}
  37667. +
  37668. +MV_BOOL mvCtrlIsBootFromSPI(MV_VOID)
  37669. +{
  37670. + MV_U32 satr = 0;
  37671. + satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  37672. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  37673. + {
  37674. + if (MSAR_BOOT_MODE_6180(satr) == MSAR_BOOT_SPI_WITH_BOOTROM_6180)
  37675. + return MV_TRUE;
  37676. + else
  37677. + return MV_FALSE;
  37678. + }
  37679. + satr = satr & MSAR_BOOT_MODE_MASK;
  37680. + if (satr == MSAR_BOOT_SPI_WITH_BOOTROM)
  37681. + return MV_TRUE;
  37682. + else
  37683. + return MV_FALSE;
  37684. +}
  37685. +
  37686. +MV_BOOL mvCtrlIsBootFromSPIUseNAND(MV_VOID)
  37687. +{
  37688. + MV_U32 satr = 0;
  37689. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  37690. + return MV_FALSE;
  37691. + satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  37692. + satr = satr & MSAR_BOOT_MODE_MASK;
  37693. +
  37694. + if (satr == MSAR_BOOT_SPI_USE_NAND_WITH_BOOTROM)
  37695. + return MV_TRUE;
  37696. + else
  37697. + return MV_FALSE;
  37698. +}
  37699. +
  37700. +MV_BOOL mvCtrlIsBootFromNAND(MV_VOID)
  37701. +{
  37702. + MV_U32 satr = 0;
  37703. + satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  37704. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  37705. + {
  37706. + if (MSAR_BOOT_MODE_6180(satr) == MSAR_BOOT_NAND_WITH_BOOTROM_6180)
  37707. + return MV_TRUE;
  37708. + else
  37709. + return MV_FALSE;
  37710. + }
  37711. + satr = satr & MSAR_BOOT_MODE_MASK;
  37712. + if ((satr == MSAR_BOOT_NAND_WITH_BOOTROM))
  37713. + return MV_TRUE;
  37714. + else
  37715. + return MV_FALSE;
  37716. +}
  37717. +
  37718. +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
  37719. +/*******************************************************************************
  37720. +* mvCtrlPwrSaveOn - Set Power save mode
  37721. +*
  37722. +* DESCRIPTION:
  37723. +*
  37724. +* INPUT:
  37725. +*
  37726. +* OUTPUT:
  37727. +*
  37728. +* RETURN:
  37729. +*******************************************************************************/
  37730. +MV_VOID mvCtrlPwrSaveOn(MV_VOID)
  37731. +{
  37732. + unsigned long old,temp;
  37733. + /* Disable int */
  37734. + __asm__ __volatile__("mrs %0, cpsr\n"
  37735. + "orr %1, %0, #0xc0\n"
  37736. + "msr cpsr_c, %1"
  37737. + : "=r" (old), "=r" (temp)
  37738. + :
  37739. + : "memory");
  37740. +
  37741. + /* Set SoC in power save */
  37742. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, BIT11);
  37743. + /* Wait for int */
  37744. + __asm__ __volatile__("mcr p15, 0, r0, c7, c0, 4");
  37745. +
  37746. + /* Enabled int */
  37747. + __asm__ __volatile__("msr cpsr_c, %0"
  37748. + :
  37749. + : "r" (old)
  37750. + : "memory");
  37751. +}
  37752. +
  37753. +
  37754. +
  37755. +/*******************************************************************************
  37756. +* mvCtrlPwrSaveOff - Go out of power save mode
  37757. +*
  37758. +* DESCRIPTION:
  37759. +*
  37760. +* INPUT:
  37761. +*
  37762. +* OUTPUT:
  37763. +*
  37764. +* RETURN:
  37765. +*******************************************************************************/
  37766. +MV_VOID mvCtrlPwrSaveOff(MV_VOID)
  37767. +{
  37768. + unsigned long old,temp;
  37769. + /* Disable int */
  37770. + __asm__ __volatile__("mrs %0, cpsr\n"
  37771. + "orr %1, %0, #0xc0\n"
  37772. + "msr cpsr_c, %1"
  37773. + : "=r" (old), "=r" (temp)
  37774. + :
  37775. + : "memory");
  37776. +
  37777. + /* Set SoC in power save */
  37778. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, BIT11);
  37779. + /* Wait for int */
  37780. + __asm__ __volatile__("mcr p15, 0, r0, c7, c0, 4");
  37781. +
  37782. + /* Enabled int */
  37783. + __asm__ __volatile__("msr cpsr_c, %0"
  37784. + :
  37785. + : "r" (old)
  37786. + : "memory");
  37787. +}
  37788. +
  37789. +/*******************************************************************************
  37790. +* mvCtrlPwrClckSet - Set Power State for specific Unit
  37791. +*
  37792. +* DESCRIPTION:
  37793. +*
  37794. +* INPUT:
  37795. +*
  37796. +* OUTPUT:
  37797. +*
  37798. +* RETURN:
  37799. +*******************************************************************************/
  37800. +MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable)
  37801. +{
  37802. + switch (unitId)
  37803. + {
  37804. +#if defined(MV_INCLUDE_PEX)
  37805. + case PEX_UNIT_ID:
  37806. + if (enable == MV_FALSE)
  37807. + {
  37808. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_PEXSTOPCLOCK_MASK);
  37809. + }
  37810. + else
  37811. + {
  37812. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_PEXSTOPCLOCK_MASK);
  37813. + }
  37814. + break;
  37815. +#endif
  37816. +#if defined(MV_INCLUDE_GIG_ETH)
  37817. + case ETH_GIG_UNIT_ID:
  37818. + if (enable == MV_FALSE)
  37819. + {
  37820. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_GESTOPCLOCK_MASK(index));
  37821. + }
  37822. + else
  37823. + {
  37824. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_GESTOPCLOCK_MASK(index));
  37825. + }
  37826. + break;
  37827. +#endif
  37828. +#if defined(MV_INCLUDE_INTEG_SATA)
  37829. + case SATA_UNIT_ID:
  37830. + if (enable == MV_FALSE)
  37831. + {
  37832. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SATASTOPCLOCK_MASK(index));
  37833. + }
  37834. + else
  37835. + {
  37836. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SATASTOPCLOCK_MASK(index));
  37837. + }
  37838. + break;
  37839. +#endif
  37840. +#if defined(MV_INCLUDE_CESA)
  37841. + case CESA_UNIT_ID:
  37842. + if (enable == MV_FALSE)
  37843. + {
  37844. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SESTOPCLOCK_MASK);
  37845. + }
  37846. + else
  37847. + {
  37848. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SESTOPCLOCK_MASK);
  37849. + }
  37850. + break;
  37851. +#endif
  37852. +#if defined(MV_INCLUDE_USB)
  37853. + case USB_UNIT_ID:
  37854. + if (enable == MV_FALSE)
  37855. + {
  37856. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_USBSTOPCLOCK_MASK);
  37857. + }
  37858. + else
  37859. + {
  37860. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_USBSTOPCLOCK_MASK);
  37861. + }
  37862. + break;
  37863. +#endif
  37864. +#if defined(MV_INCLUDE_AUDIO)
  37865. + case AUDIO_UNIT_ID:
  37866. + if (enable == MV_FALSE)
  37867. + {
  37868. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_AUDIOSTOPCLOCK_MASK);
  37869. + }
  37870. + else
  37871. + {
  37872. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_AUDIOSTOPCLOCK_MASK);
  37873. + }
  37874. + break;
  37875. +#endif
  37876. +#if defined(MV_INCLUDE_TS)
  37877. + case TS_UNIT_ID:
  37878. + if (enable == MV_FALSE)
  37879. + {
  37880. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_TSSTOPCLOCK_MASK);
  37881. + }
  37882. + else
  37883. + {
  37884. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_TSSTOPCLOCK_MASK);
  37885. + }
  37886. + break;
  37887. +#endif
  37888. +#if defined(MV_INCLUDE_SDIO)
  37889. + case SDIO_UNIT_ID:
  37890. + if (enable == MV_FALSE)
  37891. + {
  37892. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SDIOSTOPCLOCK_MASK);
  37893. + }
  37894. + else
  37895. + {
  37896. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SDIOSTOPCLOCK_MASK);
  37897. + }
  37898. + break;
  37899. +#endif
  37900. +#if defined(MV_INCLUDE_TDM)
  37901. + case TDM_UNIT_ID:
  37902. + if (enable == MV_FALSE)
  37903. + {
  37904. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_TDMSTOPCLOCK_MASK);
  37905. + }
  37906. + else
  37907. + {
  37908. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_TDMSTOPCLOCK_MASK);
  37909. + }
  37910. + break;
  37911. +#endif
  37912. +
  37913. + default:
  37914. +
  37915. + break;
  37916. +
  37917. + }
  37918. +}
  37919. +
  37920. +/*******************************************************************************
  37921. +* mvCtrlPwrClckGet - Get Power State of specific Unit
  37922. +*
  37923. +* DESCRIPTION:
  37924. +*
  37925. +* INPUT:
  37926. +*
  37927. +* OUTPUT:
  37928. +*
  37929. +* RETURN:
  37930. +******************************************************************************/
  37931. +MV_BOOL mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index)
  37932. +{
  37933. + MV_U32 reg = MV_REG_READ(POWER_MNG_CTRL_REG);
  37934. + MV_BOOL state = MV_TRUE;
  37935. +
  37936. + switch (unitId)
  37937. + {
  37938. +#if defined(MV_INCLUDE_PEX)
  37939. + case PEX_UNIT_ID:
  37940. + if ((reg & PMC_PEXSTOPCLOCK_MASK) == PMC_PEXSTOPCLOCK_STOP)
  37941. + {
  37942. + state = MV_FALSE;
  37943. + }
  37944. + else state = MV_TRUE;
  37945. +
  37946. + break;
  37947. +#endif
  37948. +#if defined(MV_INCLUDE_GIG_ETH)
  37949. + case ETH_GIG_UNIT_ID:
  37950. + if ((reg & PMC_GESTOPCLOCK_MASK(index)) == PMC_GESTOPCLOCK_STOP(index))
  37951. + {
  37952. + state = MV_FALSE;
  37953. + }
  37954. + else state = MV_TRUE;
  37955. + break;
  37956. +#endif
  37957. +#if defined(MV_INCLUDE_SATA)
  37958. + case SATA_UNIT_ID:
  37959. + if ((reg & PMC_SATASTOPCLOCK_MASK(index)) == PMC_SATASTOPCLOCK_STOP(index))
  37960. + {
  37961. + state = MV_FALSE;
  37962. + }
  37963. + else state = MV_TRUE;
  37964. + break;
  37965. +#endif
  37966. +#if defined(MV_INCLUDE_CESA)
  37967. + case CESA_UNIT_ID:
  37968. + if ((reg & PMC_SESTOPCLOCK_MASK) == PMC_SESTOPCLOCK_STOP)
  37969. + {
  37970. + state = MV_FALSE;
  37971. + }
  37972. + else state = MV_TRUE;
  37973. + break;
  37974. +#endif
  37975. +#if defined(MV_INCLUDE_USB)
  37976. + case USB_UNIT_ID:
  37977. + if ((reg & PMC_USBSTOPCLOCK_MASK) == PMC_USBSTOPCLOCK_STOP)
  37978. + {
  37979. + state = MV_FALSE;
  37980. + }
  37981. + else state = MV_TRUE;
  37982. + break;
  37983. +#endif
  37984. +#if defined(MV_INCLUDE_AUDIO)
  37985. + case AUDIO_UNIT_ID:
  37986. + if ((reg & PMC_AUDIOSTOPCLOCK_MASK) == PMC_AUDIOSTOPCLOCK_STOP)
  37987. + {
  37988. + state = MV_FALSE;
  37989. + }
  37990. + else state = MV_TRUE;
  37991. + break;
  37992. +#endif
  37993. +#if defined(MV_INCLUDE_TS)
  37994. + case TS_UNIT_ID:
  37995. + if ((reg & PMC_TSSTOPCLOCK_MASK) == PMC_TSSTOPCLOCK_STOP)
  37996. + {
  37997. + state = MV_FALSE;
  37998. + }
  37999. + else state = MV_TRUE;
  38000. + break;
  38001. +#endif
  38002. +#if defined(MV_INCLUDE_SDIO)
  38003. + case SDIO_UNIT_ID:
  38004. + if ((reg & PMC_SDIOSTOPCLOCK_MASK)== PMC_SDIOSTOPCLOCK_STOP)
  38005. + {
  38006. + state = MV_FALSE;
  38007. + }
  38008. + else state = MV_TRUE;
  38009. + break;
  38010. +#endif
  38011. +#if defined(MV_INCLUDE_TDM)
  38012. + case TDM_UNIT_ID:
  38013. + if ((reg & PMC_TDMSTOPCLOCK_MASK) == PMC_TDMSTOPCLOCK_STOP)
  38014. + {
  38015. + state = MV_FALSE;
  38016. + }
  38017. + else state = MV_TRUE;
  38018. + break;
  38019. +#endif
  38020. +
  38021. + default:
  38022. + state = MV_TRUE;
  38023. + break;
  38024. + }
  38025. +
  38026. +
  38027. + return state;
  38028. +}
  38029. +/*******************************************************************************
  38030. +* mvCtrlPwrMemSet - Set Power State for memory on specific Unit
  38031. +*
  38032. +* DESCRIPTION:
  38033. +*
  38034. +* INPUT:
  38035. +*
  38036. +* OUTPUT:
  38037. +*
  38038. +* RETURN:
  38039. +*******************************************************************************/
  38040. +MV_VOID mvCtrlPwrMemSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable)
  38041. +{
  38042. + switch (unitId)
  38043. + {
  38044. +#if defined(MV_INCLUDE_PEX)
  38045. + case PEX_UNIT_ID:
  38046. + if (enable == MV_FALSE)
  38047. + {
  38048. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_PEXSTOPMEM_MASK);
  38049. + }
  38050. + else
  38051. + {
  38052. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_PEXSTOPMEM_MASK);
  38053. + }
  38054. + break;
  38055. +#endif
  38056. +#if defined(MV_INCLUDE_GIG_ETH)
  38057. + case ETH_GIG_UNIT_ID:
  38058. + if (enable == MV_FALSE)
  38059. + {
  38060. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_GESTOPMEM_MASK(index));
  38061. + }
  38062. + else
  38063. + {
  38064. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_GESTOPMEM_MASK(index));
  38065. + }
  38066. + break;
  38067. +#endif
  38068. +#if defined(MV_INCLUDE_INTEG_SATA)
  38069. + case SATA_UNIT_ID:
  38070. + if (enable == MV_FALSE)
  38071. + {
  38072. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_SATASTOPMEM_MASK(index));
  38073. + }
  38074. + else
  38075. + {
  38076. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_SATASTOPMEM_MASK(index));
  38077. + }
  38078. + break;
  38079. +#endif
  38080. +#if defined(MV_INCLUDE_CESA)
  38081. + case CESA_UNIT_ID:
  38082. + if (enable == MV_FALSE)
  38083. + {
  38084. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_SESTOPMEM_MASK);
  38085. + }
  38086. + else
  38087. + {
  38088. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_SESTOPMEM_MASK);
  38089. + }
  38090. + break;
  38091. +#endif
  38092. +#if defined(MV_INCLUDE_USB)
  38093. + case USB_UNIT_ID:
  38094. + if (enable == MV_FALSE)
  38095. + {
  38096. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_USBSTOPMEM_MASK);
  38097. + }
  38098. + else
  38099. + {
  38100. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_USBSTOPMEM_MASK);
  38101. + }
  38102. + break;
  38103. +#endif
  38104. +#if defined(MV_INCLUDE_AUDIO)
  38105. + case AUDIO_UNIT_ID:
  38106. + if (enable == MV_FALSE)
  38107. + {
  38108. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_AUDIOSTOPMEM_MASK);
  38109. + }
  38110. + else
  38111. + {
  38112. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_AUDIOSTOPMEM_MASK);
  38113. + }
  38114. + break;
  38115. +#endif
  38116. +#if defined(MV_INCLUDE_XOR)
  38117. + case XOR_UNIT_ID:
  38118. + if (enable == MV_FALSE)
  38119. + {
  38120. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_XORSTOPMEM_MASK(index));
  38121. + }
  38122. + else
  38123. + {
  38124. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_XORSTOPMEM_MASK(index));
  38125. + }
  38126. + break;
  38127. +#endif
  38128. + default:
  38129. +
  38130. + break;
  38131. +
  38132. + }
  38133. +}
  38134. +
  38135. +/*******************************************************************************
  38136. +* mvCtrlPwrMemGet - Get Power State of memory on specific Unit
  38137. +*
  38138. +* DESCRIPTION:
  38139. +*
  38140. +* INPUT:
  38141. +*
  38142. +* OUTPUT:
  38143. +*
  38144. +* RETURN:
  38145. +******************************************************************************/
  38146. +MV_BOOL mvCtrlPwrMemGet(MV_UNIT_ID unitId, MV_U32 index)
  38147. +{
  38148. + MV_U32 reg = MV_REG_READ(POWER_MNG_MEM_CTRL_REG);
  38149. + MV_BOOL state = MV_TRUE;
  38150. +
  38151. + switch (unitId)
  38152. + {
  38153. +#if defined(MV_INCLUDE_PEX)
  38154. + case PEX_UNIT_ID:
  38155. + if ((reg & PMC_PEXSTOPMEM_MASK) == PMC_PEXSTOPMEM_STOP)
  38156. + {
  38157. + state = MV_FALSE;
  38158. + }
  38159. + else state = MV_TRUE;
  38160. +
  38161. + break;
  38162. +#endif
  38163. +#if defined(MV_INCLUDE_GIG_ETH)
  38164. + case ETH_GIG_UNIT_ID:
  38165. + if ((reg & PMC_GESTOPMEM_MASK(index)) == PMC_GESTOPMEM_STOP(index))
  38166. + {
  38167. + state = MV_FALSE;
  38168. + }
  38169. + else state = MV_TRUE;
  38170. + break;
  38171. +#endif
  38172. +#if defined(MV_INCLUDE_SATA)
  38173. + case SATA_UNIT_ID:
  38174. + if ((reg & PMC_SATASTOPMEM_MASK(index)) == PMC_SATASTOPMEM_STOP(index))
  38175. + {
  38176. + state = MV_FALSE;
  38177. + }
  38178. + else state = MV_TRUE;
  38179. + break;
  38180. +#endif
  38181. +#if defined(MV_INCLUDE_CESA)
  38182. + case CESA_UNIT_ID:
  38183. + if ((reg & PMC_SESTOPMEM_MASK) == PMC_SESTOPMEM_STOP)
  38184. + {
  38185. + state = MV_FALSE;
  38186. + }
  38187. + else state = MV_TRUE;
  38188. + break;
  38189. +#endif
  38190. +#if defined(MV_INCLUDE_USB)
  38191. + case USB_UNIT_ID:
  38192. + if ((reg & PMC_USBSTOPMEM_MASK) == PMC_USBSTOPMEM_STOP)
  38193. + {
  38194. + state = MV_FALSE;
  38195. + }
  38196. + else state = MV_TRUE;
  38197. + break;
  38198. +#endif
  38199. +#if defined(MV_INCLUDE_AUDIO)
  38200. + case AUDIO_UNIT_ID:
  38201. + if ((reg & PMC_AUDIOSTOPMEM_MASK) == PMC_AUDIOSTOPMEM_STOP)
  38202. + {
  38203. + state = MV_FALSE;
  38204. + }
  38205. + else state = MV_TRUE;
  38206. + break;
  38207. +#endif
  38208. +#if defined(MV_INCLUDE_XOR)
  38209. + case XOR_UNIT_ID:
  38210. + if ((reg & PMC_XORSTOPMEM_MASK(index)) == PMC_XORSTOPMEM_STOP(index))
  38211. + {
  38212. + state = MV_FALSE;
  38213. + }
  38214. + else state = MV_TRUE;
  38215. + break;
  38216. +#endif
  38217. +
  38218. + default:
  38219. + state = MV_TRUE;
  38220. + break;
  38221. + }
  38222. +
  38223. +
  38224. + return state;
  38225. +}
  38226. +#else
  38227. +MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable) {return;}
  38228. +MV_BOOL mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index) {return MV_TRUE;}
  38229. +#endif /* #if defined(MV_INCLUDE_CLK_PWR_CNTRL) */
  38230. +
  38231. +
  38232. +/*******************************************************************************
  38233. +* mvMPPConfigToSPI - Change MPP[3:0] configuration to SPI mode
  38234. +*
  38235. +* DESCRIPTION:
  38236. +*
  38237. +* INPUT:
  38238. +*
  38239. +* OUTPUT:
  38240. +*
  38241. +* RETURN:
  38242. +******************************************************************************/
  38243. +MV_VOID mvMPPConfigToSPI(MV_VOID)
  38244. +{
  38245. + MV_U32 mppVal = 0;
  38246. + MV_U32 bootVal = 0;
  38247. +
  38248. + if(!mvCtrlIsBootFromSPIUseNAND())
  38249. + return;
  38250. + mppVal = 0x00002220; /* Set MPP [3:1] to SPI mode */
  38251. + bootVal = MV_REG_READ(mvCtrlMppRegGet(0));
  38252. + bootVal &= 0xffff000f;
  38253. + mppVal |= bootVal;
  38254. +
  38255. + MV_REG_WRITE(mvCtrlMppRegGet(0), mppVal);
  38256. +}
  38257. +
  38258. +
  38259. +/*******************************************************************************
  38260. +* mvMPPConfigToDefault - Change MPP[7:0] configuration to default configuration
  38261. +*
  38262. +* DESCRIPTION:
  38263. +*
  38264. +* INPUT:
  38265. +*
  38266. +* OUTPUT:
  38267. +*
  38268. +* RETURN:
  38269. +******************************************************************************/
  38270. +MV_VOID mvMPPConfigToDefault(MV_VOID)
  38271. +{
  38272. + MV_U32 mppVal = 0;
  38273. + MV_U32 bootVal = 0;
  38274. +
  38275. + if(!mvCtrlIsBootFromSPIUseNAND())
  38276. + return;
  38277. + mppVal = mvBoardMppGet(0);
  38278. + bootVal = MV_REG_READ(mvCtrlMppRegGet(0));
  38279. + mppVal &= ~0xffff000f;
  38280. + bootVal &= 0xffff000f;
  38281. + mppVal |= bootVal;
  38282. +
  38283. + MV_REG_WRITE(mvCtrlMppRegGet(0), mppVal);
  38284. +}
  38285. +
  38286. +
  38287. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h
  38288. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h 1970-01-01 01:00:00.000000000 +0100
  38289. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h 2010-08-05 22:02:17.393619759 +0200
  38290. @@ -0,0 +1,185 @@
  38291. +/*******************************************************************************
  38292. +Copyright (C) Marvell International Ltd. and its affiliates
  38293. +
  38294. +This software file (the "File") is owned and distributed by Marvell
  38295. +International Ltd. and/or its affiliates ("Marvell") under the following
  38296. +alternative licensing terms. Once you have made an election to distribute the
  38297. +File under one of the following license alternatives, please (i) delete this
  38298. +introductory statement regarding license alternatives, (ii) delete the two
  38299. +license alternatives that you have not elected to use and (iii) preserve the
  38300. +Marvell copyright notice above.
  38301. +
  38302. +********************************************************************************
  38303. +Marvell Commercial License Option
  38304. +
  38305. +If you received this File from Marvell and you have entered into a commercial
  38306. +license agreement (a "Commercial License") with Marvell, the File is licensed
  38307. +to you under the terms of the applicable Commercial License.
  38308. +
  38309. +********************************************************************************
  38310. +Marvell GPL License Option
  38311. +
  38312. +If you received this File from Marvell, you may opt to use, redistribute and/or
  38313. +modify this File in accordance with the terms and conditions of the General
  38314. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  38315. +available along with the File in the license.txt file or by writing to the Free
  38316. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  38317. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  38318. +
  38319. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  38320. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  38321. +DISCLAIMED. The GPL License provides additional details about this warranty
  38322. +disclaimer.
  38323. +********************************************************************************
  38324. +Marvell BSD License Option
  38325. +
  38326. +If you received this File from Marvell, you may opt to use, redistribute and/or
  38327. +modify this File under the following licensing terms.
  38328. +Redistribution and use in source and binary forms, with or without modification,
  38329. +are permitted provided that the following conditions are met:
  38330. +
  38331. + * Redistributions of source code must retain the above copyright notice,
  38332. + this list of conditions and the following disclaimer.
  38333. +
  38334. + * Redistributions in binary form must reproduce the above copyright
  38335. + notice, this list of conditions and the following disclaimer in the
  38336. + documentation and/or other materials provided with the distribution.
  38337. +
  38338. + * Neither the name of Marvell nor the names of its contributors may be
  38339. + used to endorse or promote products derived from this software without
  38340. + specific prior written permission.
  38341. +
  38342. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  38343. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  38344. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38345. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  38346. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  38347. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  38348. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  38349. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38350. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  38351. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38352. +
  38353. +*******************************************************************************/
  38354. +
  38355. +
  38356. +#ifndef __INCmvCtrlEnvLibh
  38357. +#define __INCmvCtrlEnvLibh
  38358. +
  38359. +/* includes */
  38360. +#include "mvSysHwConfig.h"
  38361. +#include "mvCommon.h"
  38362. +#include "mvTypes.h"
  38363. +#include "mvOs.h"
  38364. +#include "boardEnv/mvBoardEnvLib.h"
  38365. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  38366. +#include "ctrlEnv/mvCtrlEnvRegs.h"
  38367. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  38368. +
  38369. +
  38370. +/* typedefs */
  38371. +
  38372. +/* This enumerator describes the possible HW cache coherency policies the */
  38373. +/* controllers supports. */
  38374. +typedef enum _mvCachePolicy
  38375. +{
  38376. + NO_COHERENCY, /* No HW cache coherency support */
  38377. + WT_COHERENCY, /* HW cache coherency supported in Write Through policy */
  38378. + WB_COHERENCY /* HW cache coherency supported in Write Back policy */
  38379. +}MV_CACHE_POLICY;
  38380. +
  38381. +
  38382. +/* The swapping is referred to a 64-bit words (as this is the controller */
  38383. +/* internal data path width). This enumerator describes the possible */
  38384. +/* data swap types. Below is an example of the data 0x0011223344556677 */
  38385. +typedef enum _mvSwapType
  38386. +{
  38387. + MV_BYTE_SWAP, /* Byte Swap 77 66 55 44 33 22 11 00 */
  38388. + MV_NO_SWAP, /* No swapping 00 11 22 33 44 55 66 77 */
  38389. + MV_BYTE_WORD_SWAP, /* Both byte and word swap 33 22 11 00 77 66 55 44 */
  38390. + MV_WORD_SWAP, /* Word swap 44 55 66 77 00 11 22 33 */
  38391. + SWAP_TYPE_MAX /* Delimiter for this enumerator */
  38392. +}MV_SWAP_TYPE;
  38393. +
  38394. +/* This structure describes access rights for Access protection windows */
  38395. +/* that can be found in IDMA, XOR, Ethernet and MPSC units. */
  38396. +/* Note that the permission enumerator coresponds to its register format. */
  38397. +/* For example, Read only premission is presented as "1" in register field. */
  38398. +typedef enum _mvAccessRights
  38399. +{
  38400. + NO_ACCESS_ALLOWED = 0, /* No access allowed */
  38401. + READ_ONLY = 1, /* Read only permission */
  38402. + ACC_RESERVED = 2, /* Reserved access right */
  38403. + FULL_ACCESS = 3, /* Read and Write permission */
  38404. + MAX_ACC_RIGHTS
  38405. +}MV_ACCESS_RIGHTS;
  38406. +
  38407. +
  38408. +/* mcspLib.h API list */
  38409. +
  38410. +MV_STATUS mvCtrlEnvInit(MV_VOID);
  38411. +MV_U32 mvCtrlMppRegGet(MV_U32 mppGroup);
  38412. +
  38413. +#if defined(MV_INCLUDE_PEX)
  38414. +MV_U32 mvCtrlPexMaxIfGet(MV_VOID);
  38415. +#else
  38416. +#define mvCtrlPexMaxIfGet() (0)
  38417. +#endif
  38418. +
  38419. +#define mvCtrlPciIfMaxIfGet() (0)
  38420. +
  38421. +#if defined(MV_INCLUDE_GIG_ETH)
  38422. +MV_U32 mvCtrlEthMaxPortGet(MV_VOID);
  38423. +#endif
  38424. +#if defined(MV_INCLUDE_XOR)
  38425. +MV_U32 mvCtrlXorMaxChanGet(MV_VOID);
  38426. +#endif
  38427. +#if defined(MV_INCLUDE_USB)
  38428. +MV_U32 mvCtrlUsbMaxGet(MV_VOID);
  38429. +#endif
  38430. +#if defined(MV_INCLUDE_NAND)
  38431. +MV_U32 mvCtrlNandSupport(MV_VOID);
  38432. +#endif
  38433. +#if defined(MV_INCLUDE_SDIO)
  38434. +MV_U32 mvCtrlSdioSupport(MV_VOID);
  38435. +#endif
  38436. +#if defined(MV_INCLUDE_TS)
  38437. +MV_U32 mvCtrlTsSupport(MV_VOID);
  38438. +#endif
  38439. +#if defined(MV_INCLUDE_AUDIO)
  38440. +MV_U32 mvCtrlAudioSupport(MV_VOID);
  38441. +#endif
  38442. +#if defined(MV_INCLUDE_TDM)
  38443. +MV_U32 mvCtrlTdmSupport(MV_VOID);
  38444. +#endif
  38445. +
  38446. +MV_U16 mvCtrlModelGet(MV_VOID);
  38447. +MV_U8 mvCtrlRevGet(MV_VOID);
  38448. +MV_STATUS mvCtrlNameGet(char *pNameBuff);
  38449. +MV_U32 mvCtrlModelRevGet(MV_VOID);
  38450. +MV_STATUS mvCtrlModelRevNameGet(char *pNameBuff);
  38451. +MV_VOID mvCtrlAddrDecShow(MV_VOID);
  38452. +const MV_8* mvCtrlTargetNameGet(MV_TARGET target);
  38453. +MV_U32 ctrlSizeToReg(MV_U32 size, MV_U32 alignment);
  38454. +MV_U32 ctrlRegToSize(MV_U32 regSize, MV_U32 alignment);
  38455. +MV_U32 ctrlSizeRegRoundUp(MV_U32 size, MV_U32 alignment);
  38456. +MV_U32 mvCtrlSysRstLengthCounterGet(MV_VOID);
  38457. +MV_STATUS ctrlWinOverlapTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2);
  38458. +MV_STATUS ctrlWinWithinWinTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2);
  38459. +
  38460. +MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable);
  38461. +MV_BOOL mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index);
  38462. +MV_VOID mvCtrlPwrMemSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable);
  38463. +MV_BOOL mvCtrlIsBootFromSPI(MV_VOID);
  38464. +MV_BOOL mvCtrlIsBootFromSPIUseNAND(MV_VOID);
  38465. +MV_BOOL mvCtrlIsBootFromNAND(MV_VOID);
  38466. +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
  38467. +MV_VOID mvCtrlPwrSaveOn(MV_VOID);
  38468. +MV_VOID mvCtrlPwrSaveOff(MV_VOID);
  38469. +#endif
  38470. +MV_BOOL mvCtrlPwrMemGet(MV_UNIT_ID unitId, MV_U32 index);
  38471. +MV_VOID mvMPPConfigToSPI(MV_VOID);
  38472. +MV_VOID mvMPPConfigToDefault(MV_VOID);
  38473. +
  38474. +
  38475. +#endif /* __INCmvCtrlEnvLibh */
  38476. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h
  38477. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h 1970-01-01 01:00:00.000000000 +0100
  38478. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h 2010-08-05 22:02:17.643620102 +0200
  38479. @@ -0,0 +1,419 @@
  38480. +/*******************************************************************************
  38481. +Copyright (C) Marvell International Ltd. and its affiliates
  38482. +
  38483. +This software file (the "File") is owned and distributed by Marvell
  38484. +International Ltd. and/or its affiliates ("Marvell") under the following
  38485. +alternative licensing terms. Once you have made an election to distribute the
  38486. +File under one of the following license alternatives, please (i) delete this
  38487. +introductory statement regarding license alternatives, (ii) delete the two
  38488. +license alternatives that you have not elected to use and (iii) preserve the
  38489. +Marvell copyright notice above.
  38490. +
  38491. +********************************************************************************
  38492. +Marvell Commercial License Option
  38493. +
  38494. +If you received this File from Marvell and you have entered into a commercial
  38495. +license agreement (a "Commercial License") with Marvell, the File is licensed
  38496. +to you under the terms of the applicable Commercial License.
  38497. +
  38498. +********************************************************************************
  38499. +Marvell GPL License Option
  38500. +
  38501. +If you received this File from Marvell, you may opt to use, redistribute and/or
  38502. +modify this File in accordance with the terms and conditions of the General
  38503. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  38504. +available along with the File in the license.txt file or by writing to the Free
  38505. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  38506. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  38507. +
  38508. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  38509. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  38510. +DISCLAIMED. The GPL License provides additional details about this warranty
  38511. +disclaimer.
  38512. +********************************************************************************
  38513. +Marvell BSD License Option
  38514. +
  38515. +If you received this File from Marvell, you may opt to use, redistribute and/or
  38516. +modify this File under the following licensing terms.
  38517. +Redistribution and use in source and binary forms, with or without modification,
  38518. +are permitted provided that the following conditions are met:
  38519. +
  38520. + * Redistributions of source code must retain the above copyright notice,
  38521. + this list of conditions and the following disclaimer.
  38522. +
  38523. + * Redistributions in binary form must reproduce the above copyright
  38524. + notice, this list of conditions and the following disclaimer in the
  38525. + documentation and/or other materials provided with the distribution.
  38526. +
  38527. + * Neither the name of Marvell nor the names of its contributors may be
  38528. + used to endorse or promote products derived from this software without
  38529. + specific prior written permission.
  38530. +
  38531. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  38532. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  38533. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38534. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  38535. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  38536. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  38537. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  38538. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38539. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  38540. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38541. +
  38542. +*******************************************************************************/
  38543. +
  38544. +#ifndef __INCmvCtrlEnvRegsh
  38545. +#define __INCmvCtrlEnvRegsh
  38546. +
  38547. +#ifdef __cplusplus
  38548. +extern "C" {
  38549. +#endif /* __cplusplus */
  38550. +
  38551. +/* CV Support */
  38552. +#define PEX0_MEM0 PEX0_MEM
  38553. +#define PCI0_MEM0 PEX0_MEM
  38554. +
  38555. +/* Controller revision info */
  38556. +#define PCI_CLASS_CODE_AND_REVISION_ID 0x008
  38557. +#define PCCRIR_REVID_OFFS 0 /* Revision ID */
  38558. +#define PCCRIR_REVID_MASK (0xff << PCCRIR_REVID_OFFS)
  38559. +
  38560. +/* Controler environment registers offsets */
  38561. +
  38562. +/* Power Managment Control */
  38563. +#define POWER_MNG_MEM_CTRL_REG 0x20118
  38564. +
  38565. +#define PMC_GESTOPMEM_OFFS(port) ((port)? 13 : 0)
  38566. +#define PMC_GESTOPMEM_MASK(port) (1 << PMC_GESTOPMEM_OFFS(port))
  38567. +#define PMC_GESTOPMEM_EN(port) (0 << PMC_GESTOPMEM_OFFS(port))
  38568. +#define PMC_GESTOPMEM_STOP(port) (1 << PMC_GESTOPMEM_OFFS(port))
  38569. +
  38570. +#define PMC_PEXSTOPMEM_OFFS 1
  38571. +#define PMC_PEXSTOPMEM_MASK (1 << PMC_PEXSTOPMEM_OFFS)
  38572. +#define PMC_PEXSTOPMEM_EN (0 << PMC_PEXSTOPMEM_OFFS)
  38573. +#define PMC_PEXSTOPMEM_STOP (1 << PMC_PEXSTOPMEM_OFFS)
  38574. +
  38575. +#define PMC_USBSTOPMEM_OFFS 2
  38576. +#define PMC_USBSTOPMEM_MASK (1 << PMC_USBSTOPMEM_OFFS)
  38577. +#define PMC_USBSTOPMEM_EN (0 << PMC_USBSTOPMEM_OFFS)
  38578. +#define PMC_USBSTOPMEM_STOP (1 << PMC_USBSTOPMEM_OFFS)
  38579. +
  38580. +#define PMC_DUNITSTOPMEM_OFFS 3
  38581. +#define PMC_DUNITSTOPMEM_MASK (1 << PMC_DUNITSTOPMEM_OFFS)
  38582. +#define PMC_DUNITSTOPMEM_EN (0 << PMC_DUNITSTOPMEM_OFFS)
  38583. +#define PMC_DUNITSTOPMEM_STOP (1 << PMC_DUNITSTOPMEM_OFFS)
  38584. +
  38585. +#define PMC_RUNITSTOPMEM_OFFS 4
  38586. +#define PMC_RUNITSTOPMEM_MASK (1 << PMC_RUNITSTOPMEM_OFFS)
  38587. +#define PMC_RUNITSTOPMEM_EN (0 << PMC_RUNITSTOPMEM_OFFS)
  38588. +#define PMC_RUNITSTOPMEM_STOP (1 << PMC_RUNITSTOPMEM_OFFS)
  38589. +
  38590. +#define PMC_XORSTOPMEM_OFFS(port) (5+(port*2))
  38591. +#define PMC_XORSTOPMEM_MASK(port) (1 << PMC_XORSTOPMEM_OFFS(port))
  38592. +#define PMC_XORSTOPMEM_EN(port) (0 << PMC_XORSTOPMEM_OFFS(port))
  38593. +#define PMC_XORSTOPMEM_STOP(port) (1 << PMC_XORSTOPMEM_OFFS(port))
  38594. +
  38595. +#define PMC_SATASTOPMEM_OFFS(port) (6+(port*5))
  38596. +#define PMC_SATASTOPMEM_MASK(port) (1 << PMC_SATASTOPMEM_OFFS(port))
  38597. +#define PMC_SATASTOPMEM_EN(port) (0 << PMC_SATASTOPMEM_OFFS(port))
  38598. +#define PMC_SATASTOPMEM_STOP(port) (1 << PMC_SATASTOPMEM_OFFS(port))
  38599. +
  38600. +#define PMC_SESTOPMEM_OFFS 8
  38601. +#define PMC_SESTOPMEM_MASK (1 << PMC_SESTOPMEM_OFFS)
  38602. +#define PMC_SESTOPMEM_EN (0 << PMC_SESTOPMEM_OFFS)
  38603. +#define PMC_SESTOPMEM_STOP (1 << PMC_SESTOPMEM_OFFS)
  38604. +
  38605. +#define PMC_AUDIOSTOPMEM_OFFS 9
  38606. +#define PMC_AUDIOSTOPMEM_MASK (1 << PMC_AUDIOSTOPMEM_OFFS)
  38607. +#define PMC_AUDIOSTOPMEM_EN (0 << PMC_AUDIOSTOPMEM_OFFS)
  38608. +#define PMC_AUDIOSTOPMEM_STOP (1 << PMC_AUDIOSTOPMEM_OFFS)
  38609. +
  38610. +#define POWER_MNG_CTRL_REG 0x2011C
  38611. +
  38612. +#define PMC_GESTOPCLOCK_OFFS(port) ((port)? 19 : 0)
  38613. +#define PMC_GESTOPCLOCK_MASK(port) (1 << PMC_GESTOPCLOCK_OFFS(port))
  38614. +#define PMC_GESTOPCLOCK_EN(port) (1 << PMC_GESTOPCLOCK_OFFS(port))
  38615. +#define PMC_GESTOPCLOCK_STOP(port) (0 << PMC_GESTOPCLOCK_OFFS(port))
  38616. +
  38617. +#define PMC_PEXPHYSTOPCLOCK_OFFS 1
  38618. +#define PMC_PEXPHYSTOPCLOCK_MASK (1 << PMC_PEXPHYSTOPCLOCK_OFFS)
  38619. +#define PMC_PEXPHYSTOPCLOCK_EN (1 << PMC_PEXPHYSTOPCLOCK_OFFS)
  38620. +#define PMC_PEXPHYSTOPCLOCK_STOP (0 << PMC_PEXPHYSTOPCLOCK_OFFS)
  38621. +
  38622. +#define PMC_PEXSTOPCLOCK_OFFS 2
  38623. +#define PMC_PEXSTOPCLOCK_MASK (1 << PMC_PEXSTOPCLOCK_OFFS)
  38624. +#define PMC_PEXSTOPCLOCK_EN (1 << PMC_PEXSTOPCLOCK_OFFS)
  38625. +#define PMC_PEXSTOPCLOCK_STOP (0 << PMC_PEXSTOPCLOCK_OFFS)
  38626. +
  38627. +#define PMC_USBSTOPCLOCK_OFFS 3
  38628. +#define PMC_USBSTOPCLOCK_MASK (1 << PMC_USBSTOPCLOCK_OFFS)
  38629. +#define PMC_USBSTOPCLOCK_EN (1 << PMC_USBSTOPCLOCK_OFFS)
  38630. +#define PMC_USBSTOPCLOCK_STOP (0 << PMC_USBSTOPCLOCK_OFFS)
  38631. +
  38632. +#define PMC_SDIOSTOPCLOCK_OFFS 4
  38633. +#define PMC_SDIOSTOPCLOCK_MASK (1 << PMC_SDIOSTOPCLOCK_OFFS)
  38634. +#define PMC_SDIOSTOPCLOCK_EN (1 << PMC_SDIOSTOPCLOCK_OFFS)
  38635. +#define PMC_SDIOSTOPCLOCK_STOP (0 << PMC_SDIOSTOPCLOCK_OFFS)
  38636. +
  38637. +#define PMC_TSSTOPCLOCK_OFFS 5
  38638. +#define PMC_TSSTOPCLOCK_MASK (1 << PMC_TSSTOPCLOCK_OFFS)
  38639. +#define PMC_TSSTOPCLOCK_EN (1 << PMC_TSSTOPCLOCK_OFFS)
  38640. +#define PMC_TSSTOPCLOCK_STOP (0 << PMC_TSSTOPCLOCK_OFFS)
  38641. +
  38642. +#define PMC_AUDIOSTOPCLOCK_OFFS 9
  38643. +#define PMC_AUDIOSTOPCLOCK_MASK (1 << PMC_AUDIOSTOPCLOCK_OFFS)
  38644. +#define PMC_AUDIOSTOPCLOCK_EN (1 << PMC_AUDIOSTOPCLOCK_OFFS)
  38645. +#define PMC_AUDIOSTOPCLOCK_STOP (0 << PMC_AUDIOSTOPCLOCK_OFFS)
  38646. +
  38647. +#define PMC_POWERSAVE_OFFS 11
  38648. +#define PMC_POWERSAVE_MASK (1 << PMC_POWERSAVE_OFFS)
  38649. +#define PMC_POWERSAVE_EN (1 << PMC_POWERSAVE_OFFS)
  38650. +#define PMC_POWERSAVE_STOP (0 << PMC_POWERSAVE_OFFS)
  38651. +
  38652. +
  38653. +
  38654. +
  38655. +#define PMC_SATASTOPCLOCK_OFFS(port) (14+(port))
  38656. +#define PMC_SATASTOPCLOCK_MASK(port) (1 << PMC_SATASTOPCLOCK_OFFS(port))
  38657. +#define PMC_SATASTOPCLOCK_EN(port) (1 << PMC_SATASTOPCLOCK_OFFS(port))
  38658. +#define PMC_SATASTOPCLOCK_STOP(port) (0 << PMC_SATASTOPCLOCK_OFFS(port))
  38659. +
  38660. +#define PMC_SESTOPCLOCK_OFFS 17
  38661. +#define PMC_SESTOPCLOCK_MASK (1 << PMC_SESTOPCLOCK_OFFS)
  38662. +#define PMC_SESTOPCLOCK_EN (1 << PMC_SESTOPCLOCK_OFFS)
  38663. +#define PMC_SESTOPCLOCK_STOP (0 << PMC_SESTOPCLOCK_OFFS)
  38664. +
  38665. +#define PMC_TDMSTOPCLOCK_OFFS 20
  38666. +#define PMC_TDMSTOPCLOCK_MASK (1 << PMC_TDMSTOPCLOCK_OFFS)
  38667. +#define PMC_TDMSTOPCLOCK_EN (1 << PMC_TDMSTOPCLOCK_OFFS)
  38668. +#define PMC_TDMSTOPCLOCK_STOP (0 << PMC_TDMSTOPCLOCK_OFFS)
  38669. +
  38670. +
  38671. +/* Controler environment registers offsets */
  38672. +#define MPP_CONTROL_REG0 0x10000
  38673. +#define MPP_CONTROL_REG1 0x10004
  38674. +#define MPP_CONTROL_REG2 0x10008
  38675. +#define MPP_CONTROL_REG3 0x1000C
  38676. +#define MPP_CONTROL_REG4 0x10010
  38677. +#define MPP_CONTROL_REG5 0x10014
  38678. +#define MPP_CONTROL_REG6 0x10018
  38679. +#define MPP_SAMPLE_AT_RESET 0x10030
  38680. +#define CHIP_BOND_REG 0x10034
  38681. +#define SYSRST_LENGTH_COUNTER_REG 0x10050
  38682. +#define SLCR_COUNT_OFFS 0
  38683. +#define SLCR_COUNT_MASK (0x1FFFFFFF << SLCR_COUNT_OFFS)
  38684. +#define SLCR_CLR_OFFS 31
  38685. +#define SLCR_CLR_MASK (1 << SLCR_CLR_OFFS)
  38686. +#define PCKG_OPT_MASK 0x3
  38687. +#define MPP_OUTPUT_DRIVE_REG 0x100E0
  38688. +#define MPP_RGMII0_OUTPUT_DRIVE_OFFS 7
  38689. +#define MPP_3_3_RGMII0_OUTPUT_DRIVE (0x0 << MPP_RGMII0_OUTPUT_DRIVE_OFFS)
  38690. +#define MPP_1_8_RGMII0_OUTPUT_DRIVE (0x1 << MPP_RGMII0_OUTPUT_DRIVE_OFFS)
  38691. +#define MPP_RGMII1_OUTPUT_DRIVE_OFFS 15
  38692. +#define MPP_3_3_RGMII1_OUTPUT_DRIVE (0x0 << MPP_RGMII1_OUTPUT_DRIVE_OFFS)
  38693. +#define MPP_1_8_RGMII1_OUTPUT_DRIVE (0x1 << MPP_RGMII1_OUTPUT_DRIVE_OFFS)
  38694. +
  38695. +#define MSAR_BOOT_MODE_OFFS 12
  38696. +#define MSAR_BOOT_MODE_MASK (0x7 << MSAR_BOOT_MODE_OFFS)
  38697. +#define MSAR_BOOT_NAND_WITH_BOOTROM (0x5 << MSAR_BOOT_MODE_OFFS)
  38698. +#define MSAR_BOOT_SPI_WITH_BOOTROM (0x4 << MSAR_BOOT_MODE_OFFS)
  38699. +#define MSAR_BOOT_SPI_USE_NAND_WITH_BOOTROM (0x2 << MSAR_BOOT_MODE_OFFS)
  38700. +
  38701. +#define MSAR_BOOT_MODE_6180(X) (((X & 0x3000) >> 12) | \
  38702. + ((X & 0x2) << 1))
  38703. +#define MSAR_BOOT_SPI_WITH_BOOTROM_6180 0x1
  38704. +#define MSAR_BOOT_NAND_WITH_BOOTROM_6180 0x5
  38705. +
  38706. +#define MSAR_TCLCK_OFFS 21
  38707. +#define MSAR_TCLCK_MASK (0x1 << MSAR_TCLCK_OFFS)
  38708. +#define MSAR_TCLCK_166 (0x1 << MSAR_TCLCK_OFFS)
  38709. +#define MSAR_TCLCK_200 (0x0 << MSAR_TCLCK_OFFS)
  38710. +
  38711. +
  38712. +#define MSAR_CPUCLCK_EXTRACT(X) (((X & 0x2) >> 1) | ((X & 0x400000) >> 21) | \
  38713. + ((X & 0x18) >> 1))
  38714. +
  38715. +#define MSAR_CPUCLCK_OFFS_6180 2
  38716. +#define MSAR_CPUCLCK_MASK_6180 (0x7 << MSAR_CPUCLCK_OFFS_6180)
  38717. +
  38718. +#define MSAR_DDRCLCK_RTIO_OFFS 5
  38719. +#define MSAR_DDRCLCK_RTIO_MASK (0xF << MSAR_DDRCLCK_RTIO_OFFS)
  38720. +
  38721. +#define MSAR_L2CLCK_EXTRACT(X) (((X & 0x600) >> 9) | ((X & 0x80000) >> 17))
  38722. +
  38723. +#ifndef MV_ASMLANGUAGE
  38724. +/* CPU clock for 6281,6192 0->Resereved */
  38725. +#define MV_CPU_CLCK_TBL { 0, 0, 0, 0, \
  38726. + 600000000, 0, 800000000, 1000000000, \
  38727. + 0, 1200000000, 0, 0, \
  38728. + 1500000000, 0, 0, 0}
  38729. +
  38730. +/* DDR clock RATIO for 6281,6192 {0,0}->Reserved */
  38731. +#define MV_DDR_CLCK_RTIO_TBL {\
  38732. + {0, 0}, {0, 0}, {2, 1}, {0, 0}, \
  38733. + {3, 1}, {0, 0}, {4, 1}, {9, 2}, \
  38734. + {5, 1}, {6, 1}, {0, 0}, {0, 0}, \
  38735. + {0, 0}, {0, 0}, {0, 0}, {0, 0} \
  38736. +}
  38737. +
  38738. +/* L2 clock RATIO for 6281,6192 {1,1}->Reserved */
  38739. +#define MV_L2_CLCK_RTIO_TBL {\
  38740. + {0, 0}, {2, 1}, {0, 0}, {3, 1}, \
  38741. + {0, 0}, {0, 0}, {0, 0}, {0, 0} \
  38742. +}
  38743. +
  38744. +/* 6180 have different clk reset sampling */
  38745. +/* ARM CPU, DDR, L2 clock for 6180 {0,0,0}->Reserved */
  38746. +#define MV_CPU6180_DDR_L2_CLCK_TBL { \
  38747. + {0, 0, 0 },\
  38748. + {0, 0, 0 },\
  38749. + {0, 0, 0 },\
  38750. + {0, 0, 0 },\
  38751. + {0, 0, 0 },\
  38752. + {600000000, 200000000, 300000000 },\
  38753. + {800000000, 200000000, 400000000 },\
  38754. + {0, 0, 0 }\
  38755. +}
  38756. +
  38757. +
  38758. +
  38759. +/* These macros help units to identify a target Mbus Arbiter group */
  38760. +#define MV_TARGET_IS_DRAM(target) \
  38761. + ((target >= SDRAM_CS0) && (target <= SDRAM_CS3))
  38762. +
  38763. +#define MV_TARGET_IS_PEX0(target) \
  38764. + ((target >= PEX0_MEM) && (target <= PEX0_IO))
  38765. +
  38766. +#define MV_TARGET_IS_PEX1(target) 0
  38767. +
  38768. +#define MV_TARGET_IS_PEX(target) (MV_TARGET_IS_PEX0(target) || MV_TARGET_IS_PEX1(target))
  38769. +
  38770. +#define MV_TARGET_IS_DEVICE(target) \
  38771. + ((target >= DEVICE_CS0) && (target <= DEVICE_CS3))
  38772. +
  38773. +#define MV_PCI_DRAM_BAR_TO_DRAM_TARGET(bar) 0
  38774. +
  38775. +#define MV_TARGET_IS_AS_BOOT(target) ((target) == (sampleAtResetTargetArray[ \
  38776. + (mvCtrlModelGet() == MV_6180_DEV_ID)? MSAR_BOOT_MODE_6180 \
  38777. + (MV_REG_READ(MPP_SAMPLE_AT_RESET)):((MV_REG_READ(MPP_SAMPLE_AT_RESET)\
  38778. + & MSAR_BOOT_MODE_MASK) >> MSAR_BOOT_MODE_OFFS)]))
  38779. +
  38780. +
  38781. +#define MV_CHANGE_BOOT_CS(target) (((target) == DEV_BOOCS)?\
  38782. + sampleAtResetTargetArray[(mvCtrlModelGet() == MV_6180_DEV_ID)? \
  38783. + MSAR_BOOT_MODE_6180(MV_REG_READ(MPP_SAMPLE_AT_RESET)): \
  38784. + ((MV_REG_READ(MPP_SAMPLE_AT_RESET) & MSAR_BOOT_MODE_MASK)\
  38785. + >> MSAR_BOOT_MODE_OFFS)]:(target))
  38786. +
  38787. +#define TCLK_TO_COUNTER_RATIO 1 /* counters running in Tclk */
  38788. +
  38789. +#define BOOT_TARGETS_NAME_ARRAY { \
  38790. + TBL_TERM, \
  38791. + TBL_TERM, \
  38792. + BOOT_ROM_CS, \
  38793. + TBL_TERM, \
  38794. + BOOT_ROM_CS, \
  38795. + BOOT_ROM_CS, \
  38796. + TBL_TERM, \
  38797. + TBL_TERM \
  38798. +}
  38799. +
  38800. +#define BOOT_TARGETS_NAME_ARRAY_6180 { \
  38801. + TBL_TERM, \
  38802. + BOOT_ROM_CS, \
  38803. + TBL_TERM, \
  38804. + TBL_TERM, \
  38805. + TBL_TERM, \
  38806. + BOOT_ROM_CS, \
  38807. + TBL_TERM, \
  38808. + TBL_TERM \
  38809. +}
  38810. +
  38811. +
  38812. +/* For old competability */
  38813. +#define DEVICE_CS0 NFLASH_CS
  38814. +#define DEVICE_CS1 SPI_CS
  38815. +#define DEVICE_CS2 BOOT_ROM_CS
  38816. +#define DEVICE_CS3 DEV_BOOCS
  38817. +#define MV_BOOTDEVICE_INDEX 0
  38818. +
  38819. +#define START_DEV_CS DEV_CS0
  38820. +#define DEV_TO_TARGET(dev) ((dev) + DEVICE_CS0)
  38821. +
  38822. +#define PCI_IF0_MEM0 PEX0_MEM
  38823. +#define PCI_IF0_IO PEX0_IO
  38824. +
  38825. +
  38826. +/* This enumerator defines the Marvell controller target ID */
  38827. +typedef enum _mvTargetId
  38828. +{
  38829. + DRAM_TARGET_ID = 0 , /* Port 0 -> DRAM interface */
  38830. + DEV_TARGET_ID = 1, /* Port 1 -> Nand/SPI */
  38831. + PEX0_TARGET_ID = 4 , /* Port 4 -> PCI Express0 */
  38832. + CRYPT_TARGET_ID = 3 , /* Port 3 --> Crypto Engine */
  38833. + SAGE_TARGET_ID = 12 , /* Port 12 -> SAGE Unit */
  38834. + MAX_TARGETS_ID
  38835. +}MV_TARGET_ID;
  38836. +
  38837. +
  38838. +/* This enumerator described the possible Controller paripheral targets. */
  38839. +/* Controller peripherals are designated memory/IO address spaces that the */
  38840. +/* controller can access. They are also refered as "targets" */
  38841. +typedef enum _mvTarget
  38842. +{
  38843. + TBL_TERM = -1, /* none valid target, used as targets list terminator*/
  38844. + SDRAM_CS0, /* SDRAM chip select 0 */
  38845. + SDRAM_CS1, /* SDRAM chip select 1 */
  38846. + SDRAM_CS2, /* SDRAM chip select 2 */
  38847. + SDRAM_CS3, /* SDRAM chip select 3 */
  38848. + PEX0_MEM, /* PCI Express 0 Memory */
  38849. + PEX0_IO, /* PCI Express 0 IO */
  38850. + INTER_REGS, /* Internal registers */
  38851. + NFLASH_CS, /* NFLASH_CS */
  38852. + SPI_CS, /* SPI_CS */
  38853. + BOOT_ROM_CS, /* BOOT_ROM_CS */
  38854. + DEV_BOOCS, /* DEV_BOOCS */
  38855. + CRYPT_ENG, /* Crypto Engine */
  38856. +#ifdef MV_INCLUDE_SAGE
  38857. + SAGE_UNIT, /* SAGE Unit */
  38858. +#endif
  38859. + MAX_TARGETS
  38860. +
  38861. +}MV_TARGET;
  38862. +
  38863. +#define TARGETS_DEF_ARRAY { \
  38864. + {0x0E, DRAM_TARGET_ID }, /* SDRAM_CS0 */ \
  38865. + {0x0D, DRAM_TARGET_ID }, /* SDRAM_CS1 */ \
  38866. + {0x0B, DRAM_TARGET_ID }, /* SDRAM_CS0 */ \
  38867. + {0x07, DRAM_TARGET_ID }, /* SDRAM_CS1 */ \
  38868. + {0xE8, PEX0_TARGET_ID }, /* PEX0_MEM */ \
  38869. + {0xE0, PEX0_TARGET_ID }, /* PEX0_IO */ \
  38870. + {0xFF, 0xFF }, /* INTER_REGS */ \
  38871. + {0x2F, DEV_TARGET_ID }, /* NFLASH_CS */ \
  38872. + {0x1E, DEV_TARGET_ID }, /* SPI_CS */ \
  38873. + {0x1D, DEV_TARGET_ID }, /* BOOT_ROM_CS */ \
  38874. + {0x1E, DEV_TARGET_ID }, /* DEV_BOOCS */ \
  38875. + {0x01, CRYPT_TARGET_ID}, /* CRYPT_ENG */ \
  38876. + {0x00, SAGE_TARGET_ID } \
  38877. +}
  38878. +
  38879. +
  38880. +#define TARGETS_NAME_ARRAY { \
  38881. + "SDRAM_CS0", /* SDRAM_CS0 */ \
  38882. + "SDRAM_CS1", /* SDRAM_CS1 */ \
  38883. + "SDRAM_CS2", /* SDRAM_CS2 */ \
  38884. + "SDRAM_CS3", /* SDRAM_CS3 */ \
  38885. + "PEX0_MEM", /* PEX0_MEM */ \
  38886. + "PEX0_IO", /* PEX0_IO */ \
  38887. + "INTER_REGS", /* INTER_REGS */ \
  38888. + "NFLASH_CS", /* NFLASH_CS */ \
  38889. + "SPI_CS", /* SPI_CS */ \
  38890. + "BOOT_ROM_CS", /* BOOT_ROM_CS */ \
  38891. + "DEV_BOOTCS", /* DEV_BOOCS */ \
  38892. + "CRYPT_ENG", /* CRYPT_ENG */ \
  38893. + "SAGE_UNIT" /* SAGE_UNIT */ \
  38894. +}
  38895. +#endif /* MV_ASMLANGUAGE */
  38896. +
  38897. +
  38898. +#endif
  38899. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h
  38900. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h 1970-01-01 01:00:00.000000000 +0100
  38901. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h 2010-08-05 22:02:17.933623924 +0200
  38902. @@ -0,0 +1,257 @@
  38903. +/*******************************************************************************
  38904. +Copyright (C) Marvell International Ltd. and its affiliates
  38905. +
  38906. +This software file (the "File") is owned and distributed by Marvell
  38907. +International Ltd. and/or its affiliates ("Marvell") under the following
  38908. +alternative licensing terms. Once you have made an election to distribute the
  38909. +File under one of the following license alternatives, please (i) delete this
  38910. +introductory statement regarding license alternatives, (ii) delete the two
  38911. +license alternatives that you have not elected to use and (iii) preserve the
  38912. +Marvell copyright notice above.
  38913. +
  38914. +********************************************************************************
  38915. +Marvell Commercial License Option
  38916. +
  38917. +If you received this File from Marvell and you have entered into a commercial
  38918. +license agreement (a "Commercial License") with Marvell, the File is licensed
  38919. +to you under the terms of the applicable Commercial License.
  38920. +
  38921. +********************************************************************************
  38922. +Marvell GPL License Option
  38923. +
  38924. +If you received this File from Marvell, you may opt to use, redistribute and/or
  38925. +modify this File in accordance with the terms and conditions of the General
  38926. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  38927. +available along with the File in the license.txt file or by writing to the Free
  38928. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  38929. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  38930. +
  38931. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  38932. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  38933. +DISCLAIMED. The GPL License provides additional details about this warranty
  38934. +disclaimer.
  38935. +********************************************************************************
  38936. +Marvell BSD License Option
  38937. +
  38938. +If you received this File from Marvell, you may opt to use, redistribute and/or
  38939. +modify this File under the following licensing terms.
  38940. +Redistribution and use in source and binary forms, with or without modification,
  38941. +are permitted provided that the following conditions are met:
  38942. +
  38943. + * Redistributions of source code must retain the above copyright notice,
  38944. + this list of conditions and the following disclaimer.
  38945. +
  38946. + * Redistributions in binary form must reproduce the above copyright
  38947. + notice, this list of conditions and the following disclaimer in the
  38948. + documentation and/or other materials provided with the distribution.
  38949. +
  38950. + * Neither the name of Marvell nor the names of its contributors may be
  38951. + used to endorse or promote products derived from this software without
  38952. + specific prior written permission.
  38953. +
  38954. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  38955. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  38956. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38957. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  38958. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  38959. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  38960. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  38961. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38962. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  38963. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38964. +
  38965. +*******************************************************************************/
  38966. +
  38967. +#ifndef __INCmvCtrlEnvSpech
  38968. +#define __INCmvCtrlEnvSpech
  38969. +
  38970. +#include "mvDeviceId.h"
  38971. +#include "mvSysHwConfig.h"
  38972. +
  38973. +#ifdef __cplusplus
  38974. +extern "C" {
  38975. +#endif /* __cplusplus */
  38976. +
  38977. +#define MV_ARM_SOC
  38978. +#define SOC_NAME_PREFIX "MV88F"
  38979. +
  38980. +
  38981. +/* units base and port numbers */
  38982. +#ifdef MV_ASMLANGUAGE
  38983. +#define XOR_UNIT_BASE(unit) 0x60800
  38984. +#else
  38985. +#define MV_XOR_REG_BASE 0x60000
  38986. +#define XOR_UNIT_BASE(unit) ((unit)? 0x60900:0x60800)
  38987. +#endif
  38988. +
  38989. +#define TDM_REG_BASE 0xD0000
  38990. +#define USB_REG_BASE(dev) 0x50000
  38991. +#define AUDIO_REG_BASE 0xA0000
  38992. +#define SATA_REG_BASE 0x80000
  38993. +#define MV_CESA_REG_BASE 0x3D000
  38994. +#define MV_CESA_TDMA_REG_BASE 0x30000
  38995. +#define MV_SDIO_REG_BASE 0x90000
  38996. +#define MV_ETH_REG_BASE(port) (((port) == 0) ? 0x72000 : 0x76000)
  38997. +#define MV_UART_CHAN_BASE(chanNum) (0x12000 + (chanNum * 0x100))
  38998. +#define DRAM_BASE 0x0
  38999. +#define CNTMR_BASE 0x20300
  39000. +#define TWSI_SLAVE_BASE(chanNum) 0x11000
  39001. +#define PEX_IF_BASE(pexIf) 0x40000
  39002. +#define MPP_REG_BASE 0x10000
  39003. +#define TSU_GLOBAL_REG_BASE 0xB4000
  39004. +#define MAX_AHB_TO_MBUS_REG_BASE 0x20000
  39005. +
  39006. +#define INTER_REGS_SIZE _1M
  39007. +/* This define describes the TWSI interrupt bit and location */
  39008. +#define TWSI_CPU_MAIN_INT_CAUSE_REG 0x20200
  39009. +#define TWSI0_CPU_MAIN_INT_BIT (1<<29)
  39010. +#define TWSI_SPEED 100000
  39011. +
  39012. +#define MV_GPP_MAX_GROUP 2
  39013. +#define MV_CNTMR_MAX_COUNTER 2
  39014. +#define MV_UART_MAX_CHAN 2
  39015. +#define MV_XOR_MAX_UNIT 2
  39016. +#define MV_XOR_MAX_CHAN 4 /* total channels for all units together*/
  39017. +#define MV_XOR_MAX_CHAN_PER_UNIT 2 /* channels for units */
  39018. +#define MV_SATA_MAX_CHAN 2
  39019. +
  39020. +#define MV_6281_MPP_MAX_MODULE 2
  39021. +#define MV_6192_MPP_MAX_MODULE 1
  39022. +#define MV_6190_MPP_MAX_MODULE 1
  39023. +#define MV_6180_MPP_MAX_MODULE 2
  39024. +#define MV_6281_MPP_MAX_GROUP 7
  39025. +#define MV_6192_MPP_MAX_GROUP 4
  39026. +#define MV_6190_MPP_MAX_GROUP 4
  39027. +#define MV_6180_MPP_MAX_GROUP 3
  39028. +
  39029. +#define MV_DRAM_MAX_CS 4
  39030. +
  39031. +/* This define describes the maximum number of supported PCI\PCIX Interfaces*/
  39032. +#define MV_PCI_MAX_IF 0
  39033. +#define MV_PCI_START_IF 0
  39034. +
  39035. +/* This define describes the maximum number of supported PEX Interfaces */
  39036. +#define MV_INCLUDE_PEX0
  39037. +#define MV_DISABLE_PEX_DEVICE_BAR
  39038. +#define MV_PEX_MAX_IF 1
  39039. +#define MV_PEX_START_IF MV_PCI_MAX_IF
  39040. +
  39041. +/* This define describes the maximum number of supported PCI Interfaces */
  39042. +#define MV_PCI_IF_MAX_IF (MV_PEX_MAX_IF+MV_PCI_MAX_IF)
  39043. +
  39044. +#define MV_ETH_MAX_PORTS 2
  39045. +#define MV_6281_ETH_MAX_PORTS 2
  39046. +#define MV_6192_ETH_MAX_PORTS 2
  39047. +#define MV_6190_ETH_MAX_PORTS 1
  39048. +#define MV_6180_ETH_MAX_PORTS 1
  39049. +
  39050. +#define MV_IDMA_MAX_CHAN 0
  39051. +
  39052. +#define MV_USB_MAX_PORTS 1
  39053. +
  39054. +#define MV_USB_VERSION 1
  39055. +
  39056. +
  39057. +#define MV_6281_NAND 1
  39058. +#define MV_6192_NAND 1
  39059. +#define MV_6190_NAND 1
  39060. +#define MV_6180_NAND 0
  39061. +
  39062. +#define MV_6281_SDIO 1
  39063. +#define MV_6192_SDIO 1
  39064. +#define MV_6190_SDIO 1
  39065. +#define MV_6180_SDIO 1
  39066. +
  39067. +#define MV_6281_TS 1
  39068. +#define MV_6192_TS 1
  39069. +#define MV_6190_TS 0
  39070. +#define MV_6180_TS 0
  39071. +
  39072. +#define MV_6281_AUDIO 1
  39073. +#define MV_6192_AUDIO 1
  39074. +#define MV_6190_AUDIO 0
  39075. +#define MV_6180_AUDIO 1
  39076. +
  39077. +#define MV_6281_TDM 1
  39078. +#define MV_6192_TDM 1
  39079. +#define MV_6190_TDM 0
  39080. +#define MV_6180_TDM 0
  39081. +
  39082. +#define MV_DEVICE_MAX_CS 4
  39083. +
  39084. +/* Others */
  39085. +#define PEX_HOST_BUS_NUM(pciIf) (pciIf)
  39086. +#define PEX_HOST_DEV_NUM(pciIf) 0
  39087. +
  39088. +#define PCI_IO(pciIf) (PEX0_IO)
  39089. +#define PCI_MEM(pciIf, memNum) (PEX0_MEM0)
  39090. +/* CESA version #2: One channel, 2KB SRAM, TDMA */
  39091. +#if defined(MV_CESA_CHAIN_MODE_SUPPORT)
  39092. + #define MV_CESA_VERSION 3
  39093. +#else
  39094. +#define MV_CESA_VERSION 2
  39095. +#endif
  39096. +#define MV_CESA_SRAM_SIZE 2*1024
  39097. +/* This define describes the maximum number of supported Ethernet ports */
  39098. +#define MV_ETH_VERSION 4
  39099. +#define MV_ETH_MAX_RXQ 8
  39100. +#define MV_ETH_MAX_TXQ 8
  39101. +#define MV_ETH_PORT_SGMII { MV_FALSE, MV_FALSE }
  39102. +/* This define describes the the support of USB */
  39103. +#define MV_USB_VERSION 1
  39104. +
  39105. +#define MV_INCLUDE_SDRAM_CS0
  39106. +#define MV_INCLUDE_SDRAM_CS1
  39107. +#define MV_INCLUDE_SDRAM_CS2
  39108. +#define MV_INCLUDE_SDRAM_CS3
  39109. +
  39110. +#define MV_INCLUDE_DEVICE_CS0
  39111. +#define MV_INCLUDE_DEVICE_CS1
  39112. +#define MV_INCLUDE_DEVICE_CS2
  39113. +#define MV_INCLUDE_DEVICE_CS3
  39114. +
  39115. +#define MPP_GROUP_1_TYPE {\
  39116. + {0, 0, 0}, /* Reserved for AUTO */ \
  39117. + {0x22220000, 0x22222222, 0x2222}, /* TDM */ \
  39118. + {0x44440000, 0x00044444, 0x0000}, /* AUDIO */ \
  39119. + {0x33330000, 0x33003333, 0x0033}, /* RGMII */ \
  39120. + {0x33330000, 0x03333333, 0x0033}, /* GMII */ \
  39121. + {0x11110000, 0x11111111, 0x0001}, /* TS */ \
  39122. + {0x33330000, 0x33333333, 0x3333} /* MII */ \
  39123. +}
  39124. +
  39125. +#define MPP_GROUP_2_TYPE {\
  39126. + {0, 0, 0}, /* Reserved for AUTO */ \
  39127. + {0x22220000, 0x22222222, 0x22}, /* TDM */ \
  39128. + {0x44440000, 0x00044444, 0x0}, /* AUDIO */ \
  39129. + {0, 0, 0}, /* N_A */ \
  39130. + {0, 0, 0}, /* N_A */ \
  39131. + {0x11110000, 0x11111111, 0x01} /* TS */ \
  39132. +}
  39133. +
  39134. +#ifndef MV_ASMLANGUAGE
  39135. +
  39136. +/* This enumerator defines the Marvell Units ID */
  39137. +typedef enum _mvUnitId
  39138. +{
  39139. + DRAM_UNIT_ID,
  39140. + PEX_UNIT_ID,
  39141. + ETH_GIG_UNIT_ID,
  39142. + USB_UNIT_ID,
  39143. + IDMA_UNIT_ID,
  39144. + XOR_UNIT_ID,
  39145. + SATA_UNIT_ID,
  39146. + TDM_UNIT_ID,
  39147. + UART_UNIT_ID,
  39148. + CESA_UNIT_ID,
  39149. + SPI_UNIT_ID,
  39150. + AUDIO_UNIT_ID,
  39151. + SDIO_UNIT_ID,
  39152. + TS_UNIT_ID,
  39153. + MAX_UNITS_ID
  39154. +
  39155. +}MV_UNIT_ID;
  39156. +
  39157. +#endif
  39158. +
  39159. +#endif /* __INCmvCtrlEnvSpech */
  39160. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c
  39161. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c 1970-01-01 01:00:00.000000000 +0100
  39162. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c 2010-08-05 22:02:18.113687258 +0200
  39163. @@ -0,0 +1,1048 @@
  39164. +/*******************************************************************************
  39165. +Copyright (C) Marvell International Ltd. and its affiliates
  39166. +
  39167. +This software file (the "File") is owned and distributed by Marvell
  39168. +International Ltd. and/or its affiliates ("Marvell") under the following
  39169. +alternative licensing terms. Once you have made an election to distribute the
  39170. +File under one of the following license alternatives, please (i) delete this
  39171. +introductory statement regarding license alternatives, (ii) delete the two
  39172. +license alternatives that you have not elected to use and (iii) preserve the
  39173. +Marvell copyright notice above.
  39174. +
  39175. +********************************************************************************
  39176. +Marvell Commercial License Option
  39177. +
  39178. +If you received this File from Marvell and you have entered into a commercial
  39179. +license agreement (a "Commercial License") with Marvell, the File is licensed
  39180. +to you under the terms of the applicable Commercial License.
  39181. +
  39182. +********************************************************************************
  39183. +Marvell GPL License Option
  39184. +
  39185. +If you received this File from Marvell, you may opt to use, redistribute and/or
  39186. +modify this File in accordance with the terms and conditions of the General
  39187. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  39188. +available along with the File in the license.txt file or by writing to the Free
  39189. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  39190. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  39191. +
  39192. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  39193. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  39194. +DISCLAIMED. The GPL License provides additional details about this warranty
  39195. +disclaimer.
  39196. +********************************************************************************
  39197. +Marvell BSD License Option
  39198. +
  39199. +If you received this File from Marvell, you may opt to use, redistribute and/or
  39200. +modify this File under the following licensing terms.
  39201. +Redistribution and use in source and binary forms, with or without modification,
  39202. +are permitted provided that the following conditions are met:
  39203. +
  39204. + * Redistributions of source code must retain the above copyright notice,
  39205. + this list of conditions and the following disclaimer.
  39206. +
  39207. + * Redistributions in binary form must reproduce the above copyright
  39208. + notice, this list of conditions and the following disclaimer in the
  39209. + documentation and/or other materials provided with the distribution.
  39210. +
  39211. + * Neither the name of Marvell nor the names of its contributors may be
  39212. + used to endorse or promote products derived from this software without
  39213. + specific prior written permission.
  39214. +
  39215. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  39216. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  39217. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39218. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  39219. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  39220. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  39221. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  39222. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  39223. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  39224. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  39225. +
  39226. +*******************************************************************************/
  39227. +
  39228. +
  39229. +/* includes */
  39230. +#include "ctrlEnv/sys/mvAhbToMbus.h"
  39231. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  39232. +
  39233. +#undef MV_DEBUG
  39234. +/* defines */
  39235. +#ifdef MV_DEBUG
  39236. + #define DB(x) x
  39237. +#else
  39238. + #define DB(x)
  39239. +#endif
  39240. +
  39241. +/* typedefs */
  39242. +
  39243. +
  39244. +/* CPU address remap registers offsets are inconsecutive. This struct */
  39245. +/* describes address remap register offsets */
  39246. +typedef struct _ahbToMbusRemapRegOffs
  39247. +{
  39248. + MV_U32 lowRegOffs; /* Low 32-bit remap register offset */
  39249. + MV_U32 highRegOffs; /* High 32 bit remap register offset */
  39250. +}AHB_TO_MBUS_REMAP_REG_OFFS;
  39251. +
  39252. +/* locals */
  39253. +static MV_STATUS ahbToMbusRemapRegOffsGet (MV_U32 winNum,
  39254. + AHB_TO_MBUS_REMAP_REG_OFFS *pRemapRegs);
  39255. +
  39256. +/*******************************************************************************
  39257. +* mvAhbToMbusInit - Initialize Ahb To Mbus Address Map !
  39258. +*
  39259. +* DESCRIPTION:
  39260. +*
  39261. +* INPUT:
  39262. +* None.
  39263. +*
  39264. +* OUTPUT:
  39265. +* None.
  39266. +*
  39267. +* RETURN:
  39268. +* MV_OK laways.
  39269. +*
  39270. +*******************************************************************************/
  39271. +MV_STATUS mvAhbToMbusInit(void)
  39272. +{
  39273. + return MV_OK;
  39274. +
  39275. +}
  39276. +
  39277. +/*******************************************************************************
  39278. +* mvAhbToMbusWinSet - Set CPU-to-peripheral winNum address window
  39279. +*
  39280. +* DESCRIPTION:
  39281. +* This function sets
  39282. +* address window, also known as address decode window.
  39283. +* A new address decode window is set for specified winNum address window.
  39284. +* If address decode window parameter structure enables the window,
  39285. +* the routine will also enable the winNum window, allowing CPU to access
  39286. +* the winNum window.
  39287. +*
  39288. +* INPUT:
  39289. +* winNum - Windows number.
  39290. +* pAddrDecWin - CPU winNum window data structure.
  39291. +*
  39292. +* OUTPUT:
  39293. +* N/A
  39294. +*
  39295. +* RETURN:
  39296. +* MV_OK if CPU winNum window was set correctly, MV_ERROR in case of
  39297. +* address window overlapps with other active CPU winNum window or
  39298. +* trying to assign 36bit base address while CPU does not support that.
  39299. +* The function returns MV_NOT_SUPPORTED, if the winNum is unsupported.
  39300. +*
  39301. +*******************************************************************************/
  39302. +MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin)
  39303. +{
  39304. + MV_TARGET_ATTRIB targetAttribs;
  39305. + MV_DEC_REGS decRegs;
  39306. +
  39307. + /* Parameter checking */
  39308. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  39309. + {
  39310. + mvOsPrintf("mvAhbToMbusWinSet: ERR. Invalid winNum %d\n", winNum);
  39311. + return MV_NOT_SUPPORTED;
  39312. + }
  39313. +
  39314. +
  39315. + /* read base register*/
  39316. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  39317. + {
  39318. + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
  39319. + }
  39320. + else
  39321. + {
  39322. + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG);
  39323. + }
  39324. +
  39325. + /* check if address is aligned to the size */
  39326. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  39327. + {
  39328. + mvOsPrintf("mvAhbToMbusWinSet:Error setting AHB to MBUS window %d to "\
  39329. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  39330. + winNum,
  39331. + mvCtrlTargetNameGet(pAddrDecWin->target),
  39332. + pAddrDecWin->addrWin.baseLow,
  39333. + pAddrDecWin->addrWin.size);
  39334. + return MV_ERROR;
  39335. + }
  39336. +
  39337. + /* read control register*/
  39338. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  39339. + {
  39340. + decRegs.sizeReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
  39341. + }
  39342. +
  39343. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  39344. + {
  39345. + mvOsPrintf("mvAhbToMbusWinSet:mvCtrlAddrDecToReg Failed\n");
  39346. + return MV_ERROR;
  39347. + }
  39348. +
  39349. + /* enable\Disable */
  39350. + if (MV_TRUE == pAddrDecWin->enable)
  39351. + {
  39352. + decRegs.sizeReg |= ATMWCR_WIN_ENABLE;
  39353. + }
  39354. + else
  39355. + {
  39356. + decRegs.sizeReg &= ~ATMWCR_WIN_ENABLE;
  39357. + }
  39358. +
  39359. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  39360. +
  39361. + /* set attributes */
  39362. + decRegs.sizeReg &= ~ATMWCR_WIN_ATTR_MASK;
  39363. + decRegs.sizeReg |= targetAttribs.attrib << ATMWCR_WIN_ATTR_OFFS;
  39364. + /* set target ID */
  39365. + decRegs.sizeReg &= ~ATMWCR_WIN_TARGET_MASK;
  39366. + decRegs.sizeReg |= targetAttribs.targetId << ATMWCR_WIN_TARGET_OFFS;
  39367. +
  39368. +#if !defined(MV_RUN_FROM_FLASH)
  39369. + /* To be on the safe side we disable the window before writing the */
  39370. + /* new values. */
  39371. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  39372. + {
  39373. + mvAhbToMbusWinEnable(winNum,MV_FALSE);
  39374. + }
  39375. +#endif
  39376. +
  39377. + /* 3) Write to address decode Base Address Register */
  39378. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  39379. + {
  39380. + MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum), decRegs.baseReg);
  39381. + }
  39382. + else
  39383. + {
  39384. + MV_REG_WRITE(AHB_TO_MBUS_WIN_INTEREG_REG, decRegs.baseReg);
  39385. + }
  39386. +
  39387. +
  39388. + /* Internal register space have no size */
  39389. + /* register. Do not perform size register assigment for those targets */
  39390. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  39391. + {
  39392. + /* Write to address decode Size Register */
  39393. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum), decRegs.sizeReg);
  39394. + }
  39395. +
  39396. + return MV_OK;
  39397. +}
  39398. +
  39399. +/*******************************************************************************
  39400. +* mvAhbToMbusWinGet - Get CPU-to-peripheral winNum address window
  39401. +*
  39402. +* DESCRIPTION:
  39403. +* Get the CPU peripheral winNum address window.
  39404. +*
  39405. +* INPUT:
  39406. +* winNum - Peripheral winNum enumerator
  39407. +*
  39408. +* OUTPUT:
  39409. +* pAddrDecWin - CPU winNum window information data structure.
  39410. +*
  39411. +* RETURN:
  39412. +* MV_OK if winNum exist, MV_ERROR otherwise.
  39413. +*
  39414. +*******************************************************************************/
  39415. +MV_STATUS mvAhbToMbusWinGet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin)
  39416. +{
  39417. + MV_DEC_REGS decRegs;
  39418. + MV_TARGET_ATTRIB targetAttrib;
  39419. +
  39420. +
  39421. + /* Parameter checking */
  39422. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  39423. + {
  39424. + mvOsPrintf("mvAhbToMbusWinGet: ERR. Invalid winNum %d\n", winNum);
  39425. + return MV_NOT_SUPPORTED;
  39426. + }
  39427. +
  39428. +
  39429. + /* Internal register space size have no size register*/
  39430. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  39431. + {
  39432. + decRegs.sizeReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
  39433. + }
  39434. + else
  39435. + {
  39436. + decRegs.sizeReg = 0;
  39437. + }
  39438. +
  39439. +
  39440. + /* Read base and size */
  39441. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  39442. + {
  39443. + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
  39444. + }
  39445. + else
  39446. + {
  39447. + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG);
  39448. + }
  39449. +
  39450. +
  39451. +
  39452. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  39453. + {
  39454. + mvOsPrintf("mvAhbToMbusWinGet: mvCtrlRegToAddrDec Failed \n");
  39455. + return MV_ERROR;
  39456. + }
  39457. +
  39458. + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
  39459. + {
  39460. + pAddrDecWin->addrWin.size = INTER_REGS_SIZE;
  39461. + pAddrDecWin->target = INTER_REGS;
  39462. + pAddrDecWin->enable = MV_TRUE;
  39463. +
  39464. + return MV_OK;
  39465. + }
  39466. +
  39467. +
  39468. + if (decRegs.sizeReg & ATMWCR_WIN_ENABLE)
  39469. + {
  39470. + pAddrDecWin->enable = MV_TRUE;
  39471. + }
  39472. + else
  39473. + {
  39474. + pAddrDecWin->enable = MV_FALSE;
  39475. +
  39476. + }
  39477. +
  39478. +
  39479. +
  39480. + if (-1 == pAddrDecWin->addrWin.size)
  39481. + {
  39482. + return MV_ERROR;
  39483. + }
  39484. +
  39485. + /* attrib and targetId */
  39486. + targetAttrib.attrib = (decRegs.sizeReg & ATMWCR_WIN_ATTR_MASK) >>
  39487. + ATMWCR_WIN_ATTR_OFFS;
  39488. + targetAttrib.targetId = (decRegs.sizeReg & ATMWCR_WIN_TARGET_MASK) >>
  39489. + ATMWCR_WIN_TARGET_OFFS;
  39490. +
  39491. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  39492. +
  39493. + return MV_OK;
  39494. +}
  39495. +
  39496. +/*******************************************************************************
  39497. +* mvAhbToMbusWinTargetGet - Get Window number associated with target
  39498. +*
  39499. +* DESCRIPTION:
  39500. +*
  39501. +* INPUT:
  39502. +*
  39503. +* OUTPUT:
  39504. +*
  39505. +* RETURN:
  39506. +*
  39507. +*******************************************************************************/
  39508. +MV_U32 mvAhbToMbusWinTargetGet(MV_TARGET target)
  39509. +{
  39510. + MV_AHB_TO_MBUS_DEC_WIN decWin;
  39511. + MV_U32 winNum;
  39512. +
  39513. + /* Check parameters */
  39514. + if (target >= MAX_TARGETS)
  39515. + {
  39516. + mvOsPrintf("mvAhbToMbusWinTargetGet: target %d is Illigal\n", target);
  39517. + return 0xffffffff;
  39518. + }
  39519. +
  39520. + if (INTER_REGS == target)
  39521. + {
  39522. + return MV_AHB_TO_MBUS_INTREG_WIN;
  39523. + }
  39524. +
  39525. + for (winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS ; winNum++)
  39526. + {
  39527. + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
  39528. + continue;
  39529. +
  39530. + if (mvAhbToMbusWinGet(winNum,&decWin) != MV_OK)
  39531. + {
  39532. + mvOsPrintf("mvAhbToMbusWinTargetGet: mvAhbToMbusWinGet fail\n");
  39533. + return 0xffffffff;
  39534. +
  39535. + }
  39536. +
  39537. + if (decWin.enable == MV_TRUE)
  39538. + {
  39539. + if (decWin.target == target)
  39540. + {
  39541. + return winNum;
  39542. + }
  39543. +
  39544. + }
  39545. +
  39546. + }
  39547. +
  39548. + return 0xFFFFFFFF;
  39549. +
  39550. +
  39551. +}
  39552. +
  39553. +/*******************************************************************************
  39554. +* mvAhbToMbusWinAvailGet - Get First Available window number.
  39555. +*
  39556. +* DESCRIPTION:
  39557. +*
  39558. +* INPUT:
  39559. +*
  39560. +* OUTPUT:
  39561. +*
  39562. +* RETURN:
  39563. +*
  39564. +*******************************************************************************/
  39565. +MV_U32 mvAhbToMbusWinAvailGet(MV_VOID)
  39566. +{
  39567. + MV_AHB_TO_MBUS_DEC_WIN decWin;
  39568. + MV_U32 winNum;
  39569. +
  39570. + for (winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS ; winNum++)
  39571. + {
  39572. + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
  39573. + continue;
  39574. +
  39575. + if (mvAhbToMbusWinGet(winNum,&decWin) != MV_OK)
  39576. + {
  39577. + mvOsPrintf("mvAhbToMbusWinTargetGet: mvAhbToMbusWinGet fail\n");
  39578. + return 0xffffffff;
  39579. +
  39580. + }
  39581. +
  39582. + if (decWin.enable == MV_FALSE)
  39583. + {
  39584. + return winNum;
  39585. + }
  39586. +
  39587. + }
  39588. +
  39589. + return 0xFFFFFFFF;
  39590. +}
  39591. +
  39592. +
  39593. +/*******************************************************************************
  39594. +* mvAhbToMbusWinEnable - Enable/disable a CPU address decode window
  39595. +*
  39596. +* DESCRIPTION:
  39597. +* This function enable/disable a CPU address decode window.
  39598. +* if parameter 'enable' == MV_TRUE the routine will enable the
  39599. +* window, thus enabling CPU accesses (before enabling the window it is
  39600. +* tested for overlapping). Otherwise, the window will be disabled.
  39601. +*
  39602. +* INPUT:
  39603. +* winNum - Peripheral winNum enumerator.
  39604. +* enable - Enable/disable parameter.
  39605. +*
  39606. +* OUTPUT:
  39607. +* N/A
  39608. +*
  39609. +* RETURN:
  39610. +* MV_ERROR if protection window number was wrong, or the window
  39611. +* overlapps other winNum window.
  39612. +*
  39613. +*******************************************************************************/
  39614. +MV_STATUS mvAhbToMbusWinEnable(MV_U32 winNum, MV_BOOL enable)
  39615. +{
  39616. +
  39617. + /* Parameter checking */
  39618. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  39619. + {
  39620. + mvOsPrintf("mvAhbToMbusWinEnable: ERR. Invalid winNum %d\n", winNum);
  39621. + return MV_NOT_SUPPORTED;
  39622. + }
  39623. +
  39624. + /* Internal registers bar can't be disable or enabled */
  39625. + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
  39626. + {
  39627. + return (enable ? MV_OK : MV_ERROR);
  39628. + }
  39629. +
  39630. + if (enable == MV_TRUE)
  39631. + {
  39632. + /* enable the window */
  39633. + MV_REG_BIT_SET(AHB_TO_MBUS_WIN_CTRL_REG(winNum), ATMWCR_WIN_ENABLE);
  39634. + }
  39635. + else
  39636. + { /* Disable address decode winNum window */
  39637. + MV_REG_BIT_RESET(AHB_TO_MBUS_WIN_CTRL_REG(winNum), ATMWCR_WIN_ENABLE);
  39638. + }
  39639. +
  39640. + return MV_OK;
  39641. +}
  39642. +
  39643. +
  39644. +/*******************************************************************************
  39645. +* mvAhbToMbusWinRemap - Set CPU remap register for address windows.
  39646. +*
  39647. +* DESCRIPTION:
  39648. +* After a CPU address hits one of PCI address decode windows there is an
  39649. +* option to remap the address to a different one. For example, CPU
  39650. +* executes a read from PCI winNum window address 0x1200.0000. This
  39651. +* can be modified so the address on the PCI bus would be 0x1400.0000
  39652. +* Using the PCI address remap mechanism.
  39653. +*
  39654. +* INPUT:
  39655. +* winNum - Peripheral winNum enumerator. Must be a PCI winNum.
  39656. +* pAddrDecWin - CPU winNum window information data structure.
  39657. +* Note that caller has to fill in the base field only. The
  39658. +* size field is ignored.
  39659. +*
  39660. +* OUTPUT:
  39661. +* None.
  39662. +*
  39663. +* RETURN:
  39664. +* MV_ERROR if winNum is not a PCI one, MV_OK otherwise.
  39665. +*
  39666. +*******************************************************************************/
  39667. +MV_U32 mvAhbToMbusWinRemap(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  39668. +{
  39669. + MV_U32 baseAddr;
  39670. + AHB_TO_MBUS_REMAP_REG_OFFS remapRegOffs;
  39671. +
  39672. + MV_U32 effectiveBaseAddress=0,
  39673. + baseAddrValue=0,windowSizeValue=0;
  39674. +
  39675. +
  39676. + /* Get registers offsets of given winNum */
  39677. + if (MV_NO_SUCH == ahbToMbusRemapRegOffsGet(winNum, &remapRegOffs))
  39678. + {
  39679. + return 0xffffffff;
  39680. + }
  39681. +
  39682. + /* 1) Set address remap low */
  39683. + baseAddr = pAddrWin->baseLow;
  39684. +
  39685. + /* Check base address aligment */
  39686. + /*
  39687. + if (MV_IS_NOT_ALIGN(baseAddr, ATMWRLR_REMAP_LOW_ALIGNMENT))
  39688. + {
  39689. + mvOsPrintf("mvAhbToMbusPciRemap: Warning. Target base 0x%x unaligned\n",
  39690. + baseAddr);
  39691. + return MV_ERROR;
  39692. + }
  39693. + */
  39694. +
  39695. + /* BaseLow[31:16] => base register [31:16] */
  39696. + baseAddr = baseAddr & ATMWRLR_REMAP_LOW_MASK;
  39697. +
  39698. + MV_REG_WRITE(remapRegOffs.lowRegOffs, baseAddr);
  39699. +
  39700. + MV_REG_WRITE(remapRegOffs.highRegOffs, pAddrWin->baseHigh);
  39701. +
  39702. +
  39703. + baseAddrValue = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
  39704. + windowSizeValue = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
  39705. +
  39706. + baseAddrValue &= ATMWBR_BASE_MASK;
  39707. + windowSizeValue &=ATMWCR_WIN_SIZE_MASK;
  39708. +
  39709. + /* Start calculating the effective Base Address */
  39710. + effectiveBaseAddress = baseAddrValue ;
  39711. +
  39712. + /* The effective base address will be combined from the chopped (if any)
  39713. + remap value (according to the size value and remap mechanism) and the
  39714. + window's base address */
  39715. + effectiveBaseAddress |= (((windowSizeValue) | 0xffff) & pAddrWin->baseLow);
  39716. + /* If the effectiveBaseAddress exceed the window boundaries return an
  39717. + invalid value. */
  39718. +
  39719. + if (effectiveBaseAddress > (baseAddrValue + (windowSizeValue | 0xffff)))
  39720. + {
  39721. + mvOsPrintf("mvAhbToMbusPciRemap: Error\n");
  39722. + return 0xffffffff;
  39723. + }
  39724. +
  39725. + return effectiveBaseAddress;
  39726. +
  39727. +
  39728. +}
  39729. +/*******************************************************************************
  39730. +* mvAhbToMbusWinTargetSwap - Swap AhbToMbus windows between targets
  39731. +*
  39732. +* DESCRIPTION:
  39733. +*
  39734. +* INPUT:
  39735. +* target1 - CPU Interface target 1
  39736. +* target2 - CPU Interface target 2
  39737. +*
  39738. +* OUTPUT:
  39739. +* None.
  39740. +*
  39741. +* RETURN:
  39742. +* MV_ERROR if targets are illigal, or if one of the targets is not
  39743. +* associated to a valid window .
  39744. +* MV_OK otherwise.
  39745. +*
  39746. +*******************************************************************************/
  39747. +
  39748. +
  39749. +MV_STATUS mvAhbToMbusWinTargetSwap(MV_TARGET target1,MV_TARGET target2)
  39750. +{
  39751. + MV_U32 winNum1,winNum2;
  39752. + MV_AHB_TO_MBUS_DEC_WIN winDec1,winDec2,winDecTemp;
  39753. + AHB_TO_MBUS_REMAP_REG_OFFS remapRegs1,remapRegs2;
  39754. + MV_U32 remapBaseLow1=0,remapBaseLow2=0;
  39755. + MV_U32 remapBaseHigh1=0,remapBaseHigh2=0;
  39756. +
  39757. +
  39758. + /* Check parameters */
  39759. + if (target1 >= MAX_TARGETS)
  39760. + {
  39761. + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d is Illigal\n", target1);
  39762. + return MV_ERROR;
  39763. + }
  39764. +
  39765. + if (target2 >= MAX_TARGETS)
  39766. + {
  39767. + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d is Illigal\n", target1);
  39768. + return MV_ERROR;
  39769. + }
  39770. +
  39771. +
  39772. + /* get window associated with this target */
  39773. + winNum1 = mvAhbToMbusWinTargetGet(target1);
  39774. +
  39775. + if (winNum1 == 0xffffffff)
  39776. + {
  39777. + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d has illigal win %d\n",
  39778. + target1,winNum1);
  39779. + return MV_ERROR;
  39780. +
  39781. + }
  39782. +
  39783. + /* get window associated with this target */
  39784. + winNum2 = mvAhbToMbusWinTargetGet(target2);
  39785. +
  39786. + if (winNum2 == 0xffffffff)
  39787. + {
  39788. + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d has illigal win %d\n",
  39789. + target2,winNum2);
  39790. + return MV_ERROR;
  39791. +
  39792. + }
  39793. +
  39794. + /* now Get original values of both Windows */
  39795. + if (MV_OK != mvAhbToMbusWinGet(winNum1,&winDec1))
  39796. + {
  39797. + mvOsPrintf("mvAhbToMbusWinTargetSwap: mvAhbToMbusWinGet failed win %d\n",
  39798. + winNum1);
  39799. + return MV_ERROR;
  39800. +
  39801. + }
  39802. + if (MV_OK != mvAhbToMbusWinGet(winNum2,&winDec2))
  39803. + {
  39804. + mvOsPrintf("mvAhbToMbusWinTargetSwap: mvAhbToMbusWinGet failed win %d\n",
  39805. + winNum2);
  39806. + return MV_ERROR;
  39807. +
  39808. + }
  39809. +
  39810. +
  39811. + /* disable both windows */
  39812. + if (MV_OK != mvAhbToMbusWinEnable(winNum1,MV_FALSE))
  39813. + {
  39814. + mvOsPrintf("mvAhbToMbusWinTargetSwap: failed to enable window %d\n",
  39815. + winNum1);
  39816. + return MV_ERROR;
  39817. +
  39818. + }
  39819. + if (MV_OK != mvAhbToMbusWinEnable(winNum2,MV_FALSE))
  39820. + {
  39821. + mvOsPrintf("mvAhbToMbusWinTargetSwap: failed to enable windo %d\n",
  39822. + winNum2);
  39823. + return MV_ERROR;
  39824. +
  39825. + }
  39826. +
  39827. +
  39828. + /* now swap targets */
  39829. +
  39830. + /* first save winDec2 values */
  39831. + winDecTemp.addrWin.baseHigh = winDec2.addrWin.baseHigh;
  39832. + winDecTemp.addrWin.baseLow = winDec2.addrWin.baseLow;
  39833. + winDecTemp.addrWin.size = winDec2.addrWin.size;
  39834. + winDecTemp.enable = winDec2.enable;
  39835. + winDecTemp.target = winDec2.target;
  39836. +
  39837. + /* winDec2 = winDec1 */
  39838. + winDec2.addrWin.baseHigh = winDec1.addrWin.baseHigh;
  39839. + winDec2.addrWin.baseLow = winDec1.addrWin.baseLow;
  39840. + winDec2.addrWin.size = winDec1.addrWin.size;
  39841. + winDec2.enable = winDec1.enable;
  39842. + winDec2.target = winDec1.target;
  39843. +
  39844. +
  39845. + /* winDec1 = winDecTemp */
  39846. + winDec1.addrWin.baseHigh = winDecTemp.addrWin.baseHigh;
  39847. + winDec1.addrWin.baseLow = winDecTemp.addrWin.baseLow;
  39848. + winDec1.addrWin.size = winDecTemp.addrWin.size;
  39849. + winDec1.enable = winDecTemp.enable;
  39850. + winDec1.target = winDecTemp.target;
  39851. +
  39852. +
  39853. + /* now set the new values */
  39854. +
  39855. +
  39856. + mvAhbToMbusWinSet(winNum1,&winDec1);
  39857. + mvAhbToMbusWinSet(winNum2,&winDec2);
  39858. +
  39859. +
  39860. +
  39861. +
  39862. +
  39863. + /* now we will treat the remap windows if exist */
  39864. +
  39865. +
  39866. + /* now check if one or both windows has a remap window
  39867. + as well after the swap ! */
  39868. +
  39869. + /* if a window had a remap value differnt than the base value
  39870. + before the swap , then after the swap the remap value will be
  39871. + equal to the base value unless both windows has a remap windows*/
  39872. +
  39873. + /* first get old values */
  39874. + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum1,&remapRegs1))
  39875. + {
  39876. + remapBaseLow1 = MV_REG_READ(remapRegs1.lowRegOffs);
  39877. + remapBaseHigh1 = MV_REG_READ(remapRegs1.highRegOffs);
  39878. +
  39879. + }
  39880. + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))
  39881. + {
  39882. + remapBaseLow2 = MV_REG_READ(remapRegs2.lowRegOffs);
  39883. + remapBaseHigh2 = MV_REG_READ(remapRegs2.highRegOffs);
  39884. +
  39885. +
  39886. + }
  39887. +
  39888. + /* now do the swap */
  39889. + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum1,&remapRegs1))
  39890. + {
  39891. + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))
  39892. + {
  39893. + /* Two windows has a remap !!! so swap */
  39894. +
  39895. + MV_REG_WRITE(remapRegs2.highRegOffs,remapBaseHigh1);
  39896. + MV_REG_WRITE(remapRegs2.lowRegOffs,remapBaseLow1);
  39897. +
  39898. + MV_REG_WRITE(remapRegs1.highRegOffs,remapBaseHigh2);
  39899. + MV_REG_WRITE(remapRegs1.lowRegOffs,remapBaseLow2);
  39900. +
  39901. +
  39902. +
  39903. + }
  39904. + else
  39905. + {
  39906. + /* remap == base */
  39907. + MV_REG_WRITE(remapRegs1.highRegOffs,winDec1.addrWin.baseHigh);
  39908. + MV_REG_WRITE(remapRegs1.lowRegOffs,winDec1.addrWin.baseLow);
  39909. +
  39910. + }
  39911. +
  39912. + }
  39913. + else if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))
  39914. + {
  39915. + /* remap == base */
  39916. + MV_REG_WRITE(remapRegs2.highRegOffs,winDec2.addrWin.baseHigh);
  39917. + MV_REG_WRITE(remapRegs2.lowRegOffs,winDec2.addrWin.baseLow);
  39918. +
  39919. + }
  39920. +
  39921. +
  39922. +
  39923. + return MV_OK;
  39924. +
  39925. +
  39926. +}
  39927. +
  39928. +
  39929. +
  39930. +#if defined(MV_88F1181)
  39931. +
  39932. +/*******************************************************************************
  39933. +* mvAhbToMbusXbarCtrlSet - Set The CPU master Xbar arbitration.
  39934. +*
  39935. +* DESCRIPTION:
  39936. +* This function sets CPU Mbus Arbiter
  39937. +*
  39938. +* INPUT:
  39939. +* pPizzaArbArray - A priority Structure describing 16 "pizza slices". At
  39940. +* each clock cycle, the crossbar arbiter samples all
  39941. +* requests and gives the bus to the next agent according
  39942. +* to the "pizza".
  39943. +*
  39944. +* OUTPUT:
  39945. +* N/A
  39946. +*
  39947. +* RETURN:
  39948. +* MV_ERROR if paramers to function invalid.
  39949. +*
  39950. +*******************************************************************************/
  39951. +MV_STATUS mvMbusArbSet(MV_MBUS_ARB_TARGET *pPizzaArbArray)
  39952. +{
  39953. + MV_U32 sliceNum;
  39954. + MV_U32 xbarCtrl = 0;
  39955. + MV_MBUS_ARB_TARGET xbarTarget;
  39956. +
  39957. + /* 1) Set crossbar control low register */
  39958. + for (sliceNum = 0; sliceNum < MRLR_SLICE_NUM; sliceNum++)
  39959. + {
  39960. + xbarTarget = pPizzaArbArray[sliceNum];
  39961. +
  39962. + /* sliceNum parameter check */
  39963. + if (xbarTarget > MAX_MBUS_ARB_TARGETS)
  39964. + {
  39965. + mvOsPrintf("mvAhbToMbusXbarCtrlSet: ERR. Can't set Target %d\n",
  39966. + xbarTarget);
  39967. + return MV_ERROR;
  39968. + }
  39969. + xbarCtrl |= (xbarTarget << MRLR_LOW_ARB_OFFS(sliceNum));
  39970. + }
  39971. + /* Write to crossbar control low register */
  39972. + MV_REG_WRITE(MBUS_ARBITER_LOW_REG, xbarCtrl);
  39973. +
  39974. + xbarCtrl = 0;
  39975. +
  39976. + /* 2) Set crossbar control high register */
  39977. + for (sliceNum = MRLR_SLICE_NUM;
  39978. + sliceNum < MRLR_SLICE_NUM+MRHR_SLICE_NUM;
  39979. + sliceNum++)
  39980. + {
  39981. +
  39982. + xbarTarget = pPizzaArbArray[sliceNum];
  39983. +
  39984. + /* sliceNum parameter check */
  39985. + if (xbarTarget > MAX_MBUS_ARB_TARGETS)
  39986. + {
  39987. + mvOsPrintf("mvAhbToMbusXbarCtrlSet: ERR. Can't set Target %d\n",
  39988. + xbarTarget);
  39989. + return MV_ERROR;
  39990. + }
  39991. + xbarCtrl |= (xbarTarget << MRHR_HIGH_ARB_OFFS(sliceNum));
  39992. + }
  39993. + /* Write to crossbar control high register */
  39994. + MV_REG_WRITE(MBUS_ARBITER_HIGH_REG, xbarCtrl);
  39995. +
  39996. + return MV_OK;
  39997. +}
  39998. +
  39999. +/*******************************************************************************
  40000. +* mvMbusArbCtrlSet - Set MBus Arbiter control register
  40001. +*
  40002. +* DESCRIPTION:
  40003. +*
  40004. +* INPUT:
  40005. +* ctrl - pointer to MV_MBUS_ARB_CTRL register
  40006. +*
  40007. +* OUTPUT:
  40008. +* N/A
  40009. +*
  40010. +* RETURN:
  40011. +* MV_ERROR if paramers to function invalid.
  40012. +*
  40013. +*******************************************************************************/
  40014. +MV_STATUS mvMbusArbCtrlSet(MV_MBUS_ARB_CTRL *ctrl)
  40015. +{
  40016. +
  40017. + if (ctrl->highPrio == MV_FALSE)
  40018. + {
  40019. + MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_ARM_TOP);
  40020. + }
  40021. + else
  40022. + {
  40023. + MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_ARM_TOP);
  40024. + }
  40025. +
  40026. + if (ctrl->fixedRoundRobin == MV_FALSE)
  40027. + {
  40028. + MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_TARGET_FIXED);
  40029. + }
  40030. + else
  40031. + {
  40032. + MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_TARGET_FIXED);
  40033. + }
  40034. +
  40035. + if (ctrl->starvEn == MV_FALSE)
  40036. + {
  40037. + MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_REQ_CTRL_EN);
  40038. + }
  40039. + else
  40040. + {
  40041. + MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_REQ_CTRL_EN);
  40042. + }
  40043. +
  40044. + return MV_OK;
  40045. +}
  40046. +
  40047. +/*******************************************************************************
  40048. +* mvMbusArbCtrlGet - Get MBus Arbiter control register
  40049. +*
  40050. +* DESCRIPTION:
  40051. +*
  40052. +* INPUT:
  40053. +* ctrl - pointer to MV_MBUS_ARB_CTRL register
  40054. +*
  40055. +* OUTPUT:
  40056. +* ctrl - pointer to MV_MBUS_ARB_CTRL register
  40057. +*
  40058. +* RETURN:
  40059. +* MV_ERROR if paramers to function invalid.
  40060. +*
  40061. +*******************************************************************************/
  40062. +MV_STATUS mvMbusArbCtrlGet(MV_MBUS_ARB_CTRL *ctrl)
  40063. +{
  40064. +
  40065. + MV_U32 ctrlReg = MV_REG_READ(MBUS_ARBITER_CTRL_REG);
  40066. +
  40067. + if (ctrlReg & MACR_ARB_ARM_TOP)
  40068. + {
  40069. + ctrl->highPrio = MV_TRUE;
  40070. + }
  40071. + else
  40072. + {
  40073. + ctrl->highPrio = MV_FALSE;
  40074. + }
  40075. +
  40076. + if (ctrlReg & MACR_ARB_TARGET_FIXED)
  40077. + {
  40078. + ctrl->fixedRoundRobin = MV_TRUE;
  40079. + }
  40080. + else
  40081. + {
  40082. + ctrl->fixedRoundRobin = MV_FALSE;
  40083. + }
  40084. +
  40085. + if (ctrlReg & MACR_ARB_REQ_CTRL_EN)
  40086. + {
  40087. + ctrl->starvEn = MV_TRUE;
  40088. + }
  40089. + else
  40090. + {
  40091. + ctrl->starvEn = MV_FALSE;
  40092. + }
  40093. +
  40094. +
  40095. + return MV_OK;
  40096. +}
  40097. +
  40098. +#endif /* #if defined(MV_88F1181) */
  40099. +
  40100. +
  40101. +
  40102. +/*******************************************************************************
  40103. +* ahbToMbusRemapRegOffsGet - Get CPU address remap register offsets
  40104. +*
  40105. +* DESCRIPTION:
  40106. +* CPU to PCI address remap registers offsets are inconsecutive.
  40107. +* This function returns PCI address remap registers offsets.
  40108. +*
  40109. +* INPUT:
  40110. +* winNum - Address decode window number. See MV_U32 enumerator.
  40111. +*
  40112. +* OUTPUT:
  40113. +* None.
  40114. +*
  40115. +* RETURN:
  40116. +* MV_ERROR if winNum is not a PCI one.
  40117. +*
  40118. +*******************************************************************************/
  40119. +static MV_STATUS ahbToMbusRemapRegOffsGet(MV_U32 winNum,
  40120. + AHB_TO_MBUS_REMAP_REG_OFFS *pRemapRegs)
  40121. +{
  40122. + switch (winNum)
  40123. + {
  40124. + case 0:
  40125. + case 1:
  40126. + pRemapRegs->lowRegOffs = AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum);
  40127. + pRemapRegs->highRegOffs = AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum);
  40128. + break;
  40129. + case 2:
  40130. + case 3:
  40131. + if((mvCtrlModelGet() == MV_5281_DEV_ID) ||
  40132. + (mvCtrlModelGet() == MV_1281_DEV_ID) ||
  40133. + (mvCtrlModelGet() == MV_6183_DEV_ID) ||
  40134. + (mvCtrlModelGet() == MV_6183L_DEV_ID))
  40135. + {
  40136. + pRemapRegs->lowRegOffs = AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum);
  40137. + pRemapRegs->highRegOffs = AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum);
  40138. + break;
  40139. + }
  40140. + else
  40141. + {
  40142. + pRemapRegs->lowRegOffs = 0;
  40143. + pRemapRegs->highRegOffs = 0;
  40144. +
  40145. + DB(mvOsPrintf("ahbToMbusRemapRegOffsGet: ERR. Invalid winNum %d\n",
  40146. + winNum));
  40147. + return MV_NO_SUCH;
  40148. + }
  40149. + default:
  40150. + {
  40151. + pRemapRegs->lowRegOffs = 0;
  40152. + pRemapRegs->highRegOffs = 0;
  40153. +
  40154. + DB(mvOsPrintf("ahbToMbusRemapRegOffsGet: ERR. Invalid winNum %d\n",
  40155. + winNum));
  40156. + return MV_NO_SUCH;
  40157. + }
  40158. + }
  40159. +
  40160. + return MV_OK;
  40161. +}
  40162. +
  40163. +/*******************************************************************************
  40164. +* mvAhbToMbusAddDecShow - Print the AHB to MBus bridge address decode map.
  40165. +*
  40166. +* DESCRIPTION:
  40167. +* This function print the CPU address decode map.
  40168. +*
  40169. +* INPUT:
  40170. +* None.
  40171. +*
  40172. +* OUTPUT:
  40173. +* None.
  40174. +*
  40175. +* RETURN:
  40176. +* None.
  40177. +*
  40178. +*******************************************************************************/
  40179. +MV_VOID mvAhbToMbusAddDecShow(MV_VOID)
  40180. +{
  40181. + MV_AHB_TO_MBUS_DEC_WIN win;
  40182. + MV_U32 winNum;
  40183. + mvOsOutput( "\n" );
  40184. + mvOsOutput( "AHB To MBUS Bridge:\n" );
  40185. + mvOsOutput( "-------------------\n" );
  40186. +
  40187. + for( winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS; winNum++ )
  40188. + {
  40189. + memset( &win, 0, sizeof(MV_AHB_TO_MBUS_DEC_WIN) );
  40190. +
  40191. + mvOsOutput( "win%d - ", winNum );
  40192. +
  40193. + if( mvAhbToMbusWinGet( winNum, &win ) == MV_OK )
  40194. + {
  40195. + if( win.enable )
  40196. + {
  40197. + mvOsOutput( "%s base %08x, ",
  40198. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  40199. + mvOsOutput( "...." );
  40200. + mvSizePrint( win.addrWin.size );
  40201. +
  40202. + mvOsOutput( "\n" );
  40203. +
  40204. + }
  40205. + else
  40206. + mvOsOutput( "disable\n" );
  40207. + }
  40208. + }
  40209. +
  40210. +}
  40211. +
  40212. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h
  40213. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h 1970-01-01 01:00:00.000000000 +0100
  40214. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h 2010-08-05 22:02:18.303619369 +0200
  40215. @@ -0,0 +1,130 @@
  40216. +/*******************************************************************************
  40217. +Copyright (C) Marvell International Ltd. and its affiliates
  40218. +
  40219. +This software file (the "File") is owned and distributed by Marvell
  40220. +International Ltd. and/or its affiliates ("Marvell") under the following
  40221. +alternative licensing terms. Once you have made an election to distribute the
  40222. +File under one of the following license alternatives, please (i) delete this
  40223. +introductory statement regarding license alternatives, (ii) delete the two
  40224. +license alternatives that you have not elected to use and (iii) preserve the
  40225. +Marvell copyright notice above.
  40226. +
  40227. +********************************************************************************
  40228. +Marvell Commercial License Option
  40229. +
  40230. +If you received this File from Marvell and you have entered into a commercial
  40231. +license agreement (a "Commercial License") with Marvell, the File is licensed
  40232. +to you under the terms of the applicable Commercial License.
  40233. +
  40234. +********************************************************************************
  40235. +Marvell GPL License Option
  40236. +
  40237. +If you received this File from Marvell, you may opt to use, redistribute and/or
  40238. +modify this File in accordance with the terms and conditions of the General
  40239. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  40240. +available along with the File in the license.txt file or by writing to the Free
  40241. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  40242. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  40243. +
  40244. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  40245. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  40246. +DISCLAIMED. The GPL License provides additional details about this warranty
  40247. +disclaimer.
  40248. +********************************************************************************
  40249. +Marvell BSD License Option
  40250. +
  40251. +If you received this File from Marvell, you may opt to use, redistribute and/or
  40252. +modify this File under the following licensing terms.
  40253. +Redistribution and use in source and binary forms, with or without modification,
  40254. +are permitted provided that the following conditions are met:
  40255. +
  40256. + * Redistributions of source code must retain the above copyright notice,
  40257. + this list of conditions and the following disclaimer.
  40258. +
  40259. + * Redistributions in binary form must reproduce the above copyright
  40260. + notice, this list of conditions and the following disclaimer in the
  40261. + documentation and/or other materials provided with the distribution.
  40262. +
  40263. + * Neither the name of Marvell nor the names of its contributors may be
  40264. + used to endorse or promote products derived from this software without
  40265. + specific prior written permission.
  40266. +
  40267. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  40268. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  40269. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  40270. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  40271. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  40272. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  40273. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  40274. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  40275. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  40276. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40277. +
  40278. +*******************************************************************************/
  40279. +
  40280. +
  40281. +#ifndef __INCmvAhbToMbush
  40282. +#define __INCmvAhbToMbush
  40283. +
  40284. +/* includes */
  40285. +#include "ctrlEnv/mvCtrlEnvLib.h"
  40286. +#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
  40287. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  40288. +
  40289. +/* defines */
  40290. +
  40291. +#if defined(MV_88F1181)
  40292. +/* This enumerator defines the Marvell controller possible MBUS arbiter */
  40293. +/* target ports. It is used to define crossbar priority scheame (pizza) */
  40294. +typedef enum _mvMBusArbTargetId
  40295. +{
  40296. + DRAM_MBUS_ARB_TARGET = 0, /* Port 0 -> DRAM interface */
  40297. + TWSI_MBUS_ARB_TARGET = 1, /* Port 1 -> TWSI */
  40298. + ARM_MBUS_ARB_TARGET = 2, /* Port 2 -> ARM */
  40299. + PEX1_MBUS_ARB_TARGET = 3, /* Port 3 -> PCI Express 1 */
  40300. + PEX0_MBUS_ARB_TARGET = 4, /* Port 4 -> PCI Express0 */
  40301. + MAX_MBUS_ARB_TARGETS
  40302. +}MV_MBUS_ARB_TARGET;
  40303. +
  40304. +typedef struct _mvMBusArbCtrl
  40305. +{
  40306. + MV_BOOL starvEn;
  40307. + MV_BOOL highPrio;
  40308. + MV_BOOL fixedRoundRobin;
  40309. +
  40310. +}MV_MBUS_ARB_CTRL;
  40311. +
  40312. +#endif /* #if defined(MV_88F1181) */
  40313. +
  40314. +typedef struct _mvAhbtoMbusDecWin
  40315. +{
  40316. + MV_TARGET target;
  40317. + MV_ADDR_WIN addrWin; /* An address window*/
  40318. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  40319. +
  40320. +}MV_AHB_TO_MBUS_DEC_WIN;
  40321. +
  40322. +/* mvAhbToMbus.h API list */
  40323. +
  40324. +MV_STATUS mvAhbToMbusInit(MV_VOID);
  40325. +MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin);
  40326. +MV_STATUS mvAhbToMbusWinGet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin);
  40327. +MV_STATUS mvAhbToMbusWinEnable(MV_U32 winNum,MV_BOOL enable);
  40328. +MV_U32 mvAhbToMbusWinRemap(MV_U32 winNum, MV_ADDR_WIN *pAddrDecWin);
  40329. +MV_U32 mvAhbToMbusWinTargetGet(MV_TARGET target);
  40330. +MV_U32 mvAhbToMbusWinAvailGet(MV_VOID);
  40331. +MV_STATUS mvAhbToMbusWinTargetSwap(MV_TARGET target1,MV_TARGET target2);
  40332. +
  40333. +#if defined(MV_88F1181)
  40334. +
  40335. +MV_STATUS mvMbusArbSet(MV_MBUS_ARB_TARGET *pPizzaArbArray);
  40336. +MV_STATUS mvMbusArbCtrlSet(MV_MBUS_ARB_CTRL *ctrl);
  40337. +MV_STATUS mvMbusArbCtrlGet(MV_MBUS_ARB_CTRL *ctrl);
  40338. +
  40339. +#endif /* #if defined(MV_88F1181) */
  40340. +
  40341. +
  40342. +MV_VOID mvAhbToMbusAddDecShow(MV_VOID);
  40343. +
  40344. +
  40345. +#endif /* __INCmvAhbToMbush */
  40346. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h
  40347. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h 1970-01-01 01:00:00.000000000 +0100
  40348. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h 2010-08-05 22:02:18.493623144 +0200
  40349. @@ -0,0 +1,143 @@
  40350. +/*******************************************************************************
  40351. +Copyright (C) Marvell International Ltd. and its affiliates
  40352. +
  40353. +This software file (the "File") is owned and distributed by Marvell
  40354. +International Ltd. and/or its affiliates ("Marvell") under the following
  40355. +alternative licensing terms. Once you have made an election to distribute the
  40356. +File under one of the following license alternatives, please (i) delete this
  40357. +introductory statement regarding license alternatives, (ii) delete the two
  40358. +license alternatives that you have not elected to use and (iii) preserve the
  40359. +Marvell copyright notice above.
  40360. +
  40361. +********************************************************************************
  40362. +Marvell Commercial License Option
  40363. +
  40364. +If you received this File from Marvell and you have entered into a commercial
  40365. +license agreement (a "Commercial License") with Marvell, the File is licensed
  40366. +to you under the terms of the applicable Commercial License.
  40367. +
  40368. +********************************************************************************
  40369. +Marvell GPL License Option
  40370. +
  40371. +If you received this File from Marvell, you may opt to use, redistribute and/or
  40372. +modify this File in accordance with the terms and conditions of the General
  40373. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  40374. +available along with the File in the license.txt file or by writing to the Free
  40375. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  40376. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  40377. +
  40378. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  40379. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  40380. +DISCLAIMED. The GPL License provides additional details about this warranty
  40381. +disclaimer.
  40382. +********************************************************************************
  40383. +Marvell BSD License Option
  40384. +
  40385. +If you received this File from Marvell, you may opt to use, redistribute and/or
  40386. +modify this File under the following licensing terms.
  40387. +Redistribution and use in source and binary forms, with or without modification,
  40388. +are permitted provided that the following conditions are met:
  40389. +
  40390. + * Redistributions of source code must retain the above copyright notice,
  40391. + this list of conditions and the following disclaimer.
  40392. +
  40393. + * Redistributions in binary form must reproduce the above copyright
  40394. + notice, this list of conditions and the following disclaimer in the
  40395. + documentation and/or other materials provided with the distribution.
  40396. +
  40397. + * Neither the name of Marvell nor the names of its contributors may be
  40398. + used to endorse or promote products derived from this software without
  40399. + specific prior written permission.
  40400. +
  40401. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  40402. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  40403. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  40404. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  40405. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  40406. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  40407. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  40408. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  40409. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  40410. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40411. +
  40412. +*******************************************************************************/
  40413. +
  40414. +
  40415. +#ifndef __INCmvAhbToMbusRegsh
  40416. +#define __INCmvAhbToMbusRegsh
  40417. +
  40418. +/******************************/
  40419. +/* ARM Address Map Registers */
  40420. +/******************************/
  40421. +
  40422. +#define MAX_AHB_TO_MBUS_WINS 9
  40423. +#define MV_AHB_TO_MBUS_INTREG_WIN 8
  40424. +
  40425. +
  40426. +#define AHB_TO_MBUS_WIN_CTRL_REG(winNum) (0x20000 + (winNum)*0x10)
  40427. +#define AHB_TO_MBUS_WIN_BASE_REG(winNum) (0x20004 + (winNum)*0x10)
  40428. +#define AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum) (0x20008 + (winNum)*0x10)
  40429. +#define AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum) (0x2000C + (winNum)*0x10)
  40430. +#define AHB_TO_MBUS_WIN_INTEREG_REG 0x20080
  40431. +
  40432. +/* Window Control Register */
  40433. +/* AHB_TO_MBUS_WIN_CTRL_REG (ATMWCR)*/
  40434. +#define ATMWCR_WIN_ENABLE BIT0 /* Window Enable */
  40435. +
  40436. +#define ATMWCR_WIN_TARGET_OFFS 4 /* The target interface associated
  40437. + with this window*/
  40438. +#define ATMWCR_WIN_TARGET_MASK (0xf << ATMWCR_WIN_TARGET_OFFS)
  40439. +
  40440. +#define ATMWCR_WIN_ATTR_OFFS 8 /* The target interface attributes
  40441. + Associated with this window */
  40442. +#define ATMWCR_WIN_ATTR_MASK (0xff << ATMWCR_WIN_ATTR_OFFS)
  40443. +
  40444. +
  40445. +/*
  40446. +Used with the Base register to set the address window size and location
  40447. +Must be programed from LSB to MSB as sequence of 1’s followed
  40448. +by sequence of 0’s. The number of 1’s specifies the size of the window
  40449. +in 64 KB granularity (e.g. a value of 0x00FF specifies 256 = 16 MB).
  40450. +
  40451. +NOTE: A value of 0x0 specifies 64KB size.
  40452. +*/
  40453. +#define ATMWCR_WIN_SIZE_OFFS 16 /* Window Size */
  40454. +#define ATMWCR_WIN_SIZE_MASK (0xffff << ATMWCR_WIN_SIZE_OFFS)
  40455. +#define ATMWCR_WIN_SIZE_ALIGNMENT 0x10000
  40456. +
  40457. +/* Window Base Register */
  40458. +/* AHB_TO_MBUS_WIN_BASE_REG (ATMWBR) */
  40459. +
  40460. +/*
  40461. +Used with the size field to set the address window size and location.
  40462. +Corresponds to transaction address[31:16]
  40463. +*/
  40464. +#define ATMWBR_BASE_OFFS 16 /* Base Address */
  40465. +#define ATMWBR_BASE_MASK (0xffff << ATMWBR_BASE_OFFS)
  40466. +#define ATMWBR_BASE_ALIGNMENT 0x10000
  40467. +
  40468. +/* Window Remap Low Register */
  40469. +/* AHB_TO_MBUS_WIN_REMAP_LOW_REG (ATMWRLR) */
  40470. +
  40471. +/*
  40472. +Used with the size field to specifies address bits[31:0] to be driven to
  40473. +the target interface.:
  40474. +target_addr[31:16] = (addr[31:16] & size[15:0]) | (remap[31:16] & ~size[15:0])
  40475. +*/
  40476. +#define ATMWRLR_REMAP_LOW_OFFS 16 /* Remap Address */
  40477. +#define ATMWRLR_REMAP_LOW_MASK (0xffff << ATMWRLR_REMAP_LOW_OFFS)
  40478. +#define ATMWRLR_REMAP_LOW_ALIGNMENT 0x10000
  40479. +
  40480. +/* Window Remap High Register */
  40481. +/* AHB_TO_MBUS_WIN_REMAP_HIGH_REG (ATMWRHR) */
  40482. +
  40483. +/*
  40484. +Specifies address bits[63:32] to be driven to the target interface.
  40485. +target_addr[63:32] = (RemapHigh[31:0]
  40486. +*/
  40487. +#define ATMWRHR_REMAP_HIGH_OFFS 0 /* Remap Address */
  40488. +#define ATMWRHR_REMAP_HIGH_MASK (0xffffffff << ATMWRHR_REMAP_HIGH_OFFS)
  40489. +
  40490. +
  40491. +#endif /* __INCmvAhbToMbusRegsh */
  40492. +
  40493. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c
  40494. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c 1970-01-01 01:00:00.000000000 +0100
  40495. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c 2010-08-05 22:02:18.633619324 +0200
  40496. @@ -0,0 +1,1036 @@
  40497. +/*******************************************************************************
  40498. +Copyright (C) Marvell International Ltd. and its affiliates
  40499. +
  40500. +This software file (the "File") is owned and distributed by Marvell
  40501. +International Ltd. and/or its affiliates ("Marvell") under the following
  40502. +alternative licensing terms. Once you have made an election to distribute the
  40503. +File under one of the following license alternatives, please (i) delete this
  40504. +introductory statement regarding license alternatives, (ii) delete the two
  40505. +license alternatives that you have not elected to use and (iii) preserve the
  40506. +Marvell copyright notice above.
  40507. +
  40508. +********************************************************************************
  40509. +Marvell Commercial License Option
  40510. +
  40511. +If you received this File from Marvell and you have entered into a commercial
  40512. +license agreement (a "Commercial License") with Marvell, the File is licensed
  40513. +to you under the terms of the applicable Commercial License.
  40514. +
  40515. +********************************************************************************
  40516. +Marvell GPL License Option
  40517. +
  40518. +If you received this File from Marvell, you may opt to use, redistribute and/or
  40519. +modify this File in accordance with the terms and conditions of the General
  40520. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  40521. +available along with the File in the license.txt file or by writing to the Free
  40522. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  40523. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  40524. +
  40525. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  40526. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  40527. +DISCLAIMED. The GPL License provides additional details about this warranty
  40528. +disclaimer.
  40529. +********************************************************************************
  40530. +Marvell BSD License Option
  40531. +
  40532. +If you received this File from Marvell, you may opt to use, redistribute and/or
  40533. +modify this File under the following licensing terms.
  40534. +Redistribution and use in source and binary forms, with or without modification,
  40535. +are permitted provided that the following conditions are met:
  40536. +
  40537. + * Redistributions of source code must retain the above copyright notice,
  40538. + this list of conditions and the following disclaimer.
  40539. +
  40540. + * Redistributions in binary form must reproduce the above copyright
  40541. + notice, this list of conditions and the following disclaimer in the
  40542. + documentation and/or other materials provided with the distribution.
  40543. +
  40544. + * Neither the name of Marvell nor the names of its contributors may be
  40545. + used to endorse or promote products derived from this software without
  40546. + specific prior written permission.
  40547. +
  40548. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  40549. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  40550. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  40551. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  40552. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  40553. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  40554. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  40555. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  40556. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  40557. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40558. +
  40559. +*******************************************************************************/
  40560. +
  40561. +
  40562. +/* includes */
  40563. +#include "ctrlEnv/sys/mvCpuIf.h"
  40564. +#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
  40565. +#include "cpu/mvCpu.h"
  40566. +#include "ctrlEnv/mvCtrlEnvLib.h"
  40567. +#include "mvSysHwConfig.h"
  40568. +#include "mvSysDram.h"
  40569. +
  40570. +/*#define MV_DEBUG*/
  40571. +/* defines */
  40572. +
  40573. +#ifdef MV_DEBUG
  40574. + #define DB(x) x
  40575. +#else
  40576. + #define DB(x)
  40577. +#endif
  40578. +
  40579. +/* locals */
  40580. +/* static functions */
  40581. +static MV_BOOL cpuTargetWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
  40582. +
  40583. +MV_TARGET * sampleAtResetTargetArray;
  40584. +MV_TARGET sampleAtResetTargetArrayP[] = BOOT_TARGETS_NAME_ARRAY;
  40585. +MV_TARGET sampleAtResetTargetArray6180P[] = BOOT_TARGETS_NAME_ARRAY_6180;
  40586. +/*******************************************************************************
  40587. +* mvCpuIfInit - Initialize Controller CPU interface
  40588. +*
  40589. +* DESCRIPTION:
  40590. +* This function initialize Controller CPU interface:
  40591. +* 1. Set CPU interface configuration registers.
  40592. +* 2. Set CPU master Pizza arbiter control according to static
  40593. +* configuration described in configuration file.
  40594. +* 3. Opens CPU address decode windows. DRAM windows are assumed to be
  40595. +* already set (auto detection).
  40596. +*
  40597. +* INPUT:
  40598. +* None.
  40599. +*
  40600. +* OUTPUT:
  40601. +* None.
  40602. +*
  40603. +* RETURN:
  40604. +* None.
  40605. +*
  40606. +*******************************************************************************/
  40607. +MV_STATUS mvCpuIfInit(MV_CPU_DEC_WIN *cpuAddrWinMap)
  40608. +{
  40609. + MV_U32 regVal;
  40610. + MV_TARGET target;
  40611. + MV_ADDR_WIN addrWin;
  40612. +
  40613. + if (cpuAddrWinMap == NULL)
  40614. + {
  40615. + DB(mvOsPrintf("mvCpuIfInit:ERR. cpuAddrWinMap == NULL\n"));
  40616. + return MV_ERROR;
  40617. + }
  40618. +
  40619. + /*Initialize the boot target array according to device type*/
  40620. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  40621. + sampleAtResetTargetArray = sampleAtResetTargetArray6180P;
  40622. + else
  40623. + sampleAtResetTargetArray = sampleAtResetTargetArrayP;
  40624. +
  40625. + /* Set ARM Configuration register */
  40626. + regVal = MV_REG_READ(CPU_CONFIG_REG);
  40627. + regVal &= ~CPU_CONFIG_DEFAULT_MASK;
  40628. + regVal |= CPU_CONFIG_DEFAULT;
  40629. + MV_REG_WRITE(CPU_CONFIG_REG,regVal);
  40630. +
  40631. + /* First disable all CPU target windows */
  40632. + for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++)
  40633. + {
  40634. + if ((MV_TARGET_IS_DRAM(target))||(target == INTER_REGS))
  40635. + {
  40636. + continue;
  40637. + }
  40638. +
  40639. +#if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA)
  40640. + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
  40641. + if (MV_TARGET_IS_PCI(target))
  40642. + {
  40643. + continue;
  40644. + }
  40645. +#endif
  40646. +
  40647. +#if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA)
  40648. + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
  40649. + if (MV_TARGET_IS_PEX(target))
  40650. + {
  40651. + continue;
  40652. + }
  40653. +#endif
  40654. +#if defined(MV_RUN_FROM_FLASH)
  40655. + /* Don't disable the boot device. */
  40656. + if (target == DEV_BOOCS)
  40657. + {
  40658. + continue;
  40659. + }
  40660. +#endif /* MV_RUN_FROM_FLASH */
  40661. + mvCpuIfTargetWinEnable(MV_CHANGE_BOOT_CS(target),MV_FALSE);
  40662. + }
  40663. +
  40664. +#if defined(MV_RUN_FROM_FLASH)
  40665. + /* Resize the bootcs windows before other windows, because this */
  40666. + /* window is enabled and will cause an overlap if not resized. */
  40667. + target = DEV_BOOCS;
  40668. +
  40669. + if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target]))
  40670. + {
  40671. + DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n"));
  40672. + return MV_ERROR;
  40673. + }
  40674. +
  40675. + addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow;
  40676. + addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh;
  40677. + if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin))
  40678. + {
  40679. + DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n",
  40680. + cpuAddrWinMap[target].winNum));
  40681. + }
  40682. +
  40683. +#endif /* MV_RUN_FROM_FLASH */
  40684. +
  40685. + /* Go through all targets in user table until table terminator */
  40686. + for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++)
  40687. + {
  40688. +
  40689. +#if defined(MV_RUN_FROM_FLASH)
  40690. + if (target == DEV_BOOCS)
  40691. + {
  40692. + continue;
  40693. + }
  40694. +#endif /* MV_RUN_FROM_FLASH */
  40695. +
  40696. + /* if DRAM auto sizing is used do not initialized DRAM target windows, */
  40697. + /* assuming this already has been done earlier. */
  40698. +#ifdef MV_DRAM_AUTO_SIZE
  40699. + if (MV_TARGET_IS_DRAM(target))
  40700. + {
  40701. + continue;
  40702. + }
  40703. +#endif
  40704. +
  40705. +#if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA)
  40706. + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
  40707. + if (MV_TARGET_IS_PCI(target))
  40708. + {
  40709. + continue;
  40710. + }
  40711. +#endif
  40712. +
  40713. +#if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA)
  40714. + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
  40715. + if (MV_TARGET_IS_PEX(target))
  40716. + {
  40717. + continue;
  40718. + }
  40719. +#endif
  40720. + /* If the target attribute is the same as the boot device attribute */
  40721. + /* then it's stays disable */
  40722. + if (MV_TARGET_IS_AS_BOOT(target))
  40723. + {
  40724. + continue;
  40725. + }
  40726. +
  40727. + if((0 == cpuAddrWinMap[target].addrWin.size) ||
  40728. + (DIS == cpuAddrWinMap[target].enable))
  40729. +
  40730. + {
  40731. + if (MV_OK != mvCpuIfTargetWinEnable(target, MV_FALSE))
  40732. + {
  40733. + DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinEnable fail\n"));
  40734. + return MV_ERROR;
  40735. + }
  40736. +
  40737. + }
  40738. + else
  40739. + {
  40740. + if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target]))
  40741. + {
  40742. + DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n"));
  40743. + return MV_ERROR;
  40744. + }
  40745. +
  40746. + addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow;
  40747. + addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh;
  40748. + if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin))
  40749. + {
  40750. + DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n",
  40751. + cpuAddrWinMap[target].winNum));
  40752. + }
  40753. +
  40754. +
  40755. + }
  40756. + }
  40757. +
  40758. + return MV_OK;
  40759. +
  40760. +
  40761. +}
  40762. +
  40763. +
  40764. +/*******************************************************************************
  40765. +* mvCpuIfTargetWinSet - Set CPU-to-peripheral target address window
  40766. +*
  40767. +* DESCRIPTION:
  40768. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI0_MEM0)
  40769. +* address window, also known as address decode window.
  40770. +* A new address decode window is set for specified target address window.
  40771. +* If address decode window parameter structure enables the window,
  40772. +* the routine will also enable the target window, allowing CPU to access
  40773. +* the target window.
  40774. +*
  40775. +* INPUT:
  40776. +* target - Peripheral target enumerator.
  40777. +* pAddrDecWin - CPU target window data structure.
  40778. +*
  40779. +* OUTPUT:
  40780. +* N/A
  40781. +*
  40782. +* RETURN:
  40783. +* MV_OK if CPU target window was set correctly, MV_ERROR in case of
  40784. +* address window overlapps with other active CPU target window or
  40785. +* trying to assign 36bit base address while CPU does not support that.
  40786. +* The function returns MV_NOT_SUPPORTED, if the target is unsupported.
  40787. +*
  40788. +*******************************************************************************/
  40789. +MV_STATUS mvCpuIfTargetWinSet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin)
  40790. +{
  40791. + MV_AHB_TO_MBUS_DEC_WIN decWin;
  40792. + MV_U32 existingWinNum;
  40793. + MV_DRAM_DEC_WIN addrDecWin;
  40794. +
  40795. + target = MV_CHANGE_BOOT_CS(target);
  40796. +
  40797. + /* Check parameters */
  40798. + if (target >= MAX_TARGETS)
  40799. + {
  40800. + mvOsPrintf("mvCpuIfTargetWinSet: target %d is Illigal\n", target);
  40801. + return MV_ERROR;
  40802. + }
  40803. +
  40804. + /* 2) Check if the requested window overlaps with current windows */
  40805. + if (MV_TRUE == cpuTargetWinOverlap(target, &pAddrDecWin->addrWin))
  40806. + {
  40807. + mvOsPrintf("mvCpuIfTargetWinSet: ERR. Target %d overlap\n", target);
  40808. + return MV_BAD_PARAM;
  40809. + }
  40810. +
  40811. + if (MV_TARGET_IS_DRAM(target))
  40812. + {
  40813. + /* copy relevant data to MV_DRAM_DEC_WIN structure */
  40814. + addrDecWin.addrWin.baseHigh = pAddrDecWin->addrWin.baseHigh;
  40815. + addrDecWin.addrWin.baseLow = pAddrDecWin->addrWin.baseLow;
  40816. + addrDecWin.addrWin.size = pAddrDecWin->addrWin.size;
  40817. + addrDecWin.enable = pAddrDecWin->enable;
  40818. +
  40819. +
  40820. + if (mvDramIfWinSet(target,&addrDecWin) != MV_OK);
  40821. + {
  40822. + mvOsPrintf("mvCpuIfTargetWinSet: mvDramIfWinSet Failed\n");
  40823. + return MV_ERROR;
  40824. + }
  40825. +
  40826. + }
  40827. + else
  40828. + {
  40829. + /* copy relevant data to MV_AHB_TO_MBUS_DEC_WIN structure */
  40830. + decWin.addrWin.baseLow = pAddrDecWin->addrWin.baseLow;
  40831. + decWin.addrWin.baseHigh = pAddrDecWin->addrWin.baseHigh;
  40832. + decWin.addrWin.size = pAddrDecWin->addrWin.size;
  40833. + decWin.enable = pAddrDecWin->enable;
  40834. + decWin.target = target;
  40835. +
  40836. + existingWinNum = mvAhbToMbusWinTargetGet(target);
  40837. +
  40838. + /* check if there is already another Window configured
  40839. + for this target */
  40840. + if ((existingWinNum < MAX_AHB_TO_MBUS_WINS )&&
  40841. + (existingWinNum != pAddrDecWin->winNum))
  40842. + {
  40843. + /* if we want to enable the new winow number
  40844. + passed by the user , then the old one should
  40845. + be disabled */
  40846. + if (MV_TRUE == pAddrDecWin->enable)
  40847. + {
  40848. + /* be sure it is disabled */
  40849. + mvAhbToMbusWinEnable(existingWinNum , MV_FALSE);
  40850. + }
  40851. + }
  40852. +
  40853. + if (mvAhbToMbusWinSet(pAddrDecWin->winNum,&decWin) != MV_OK)
  40854. + {
  40855. + mvOsPrintf("mvCpuIfTargetWinSet: mvAhbToMbusWinSet Failed\n");
  40856. + return MV_ERROR;
  40857. + }
  40858. +
  40859. + }
  40860. +
  40861. + return MV_OK;
  40862. +}
  40863. +
  40864. +/*******************************************************************************
  40865. +* mvCpuIfTargetWinGet - Get CPU-to-peripheral target address window
  40866. +*
  40867. +* DESCRIPTION:
  40868. +* Get the CPU peripheral target address window.
  40869. +*
  40870. +* INPUT:
  40871. +* target - Peripheral target enumerator
  40872. +*
  40873. +* OUTPUT:
  40874. +* pAddrDecWin - CPU target window information data structure.
  40875. +*
  40876. +* RETURN:
  40877. +* MV_OK if target exist, MV_ERROR otherwise.
  40878. +*
  40879. +*******************************************************************************/
  40880. +MV_STATUS mvCpuIfTargetWinGet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin)
  40881. +{
  40882. +
  40883. + MV_U32 winNum=0xffffffff;
  40884. + MV_AHB_TO_MBUS_DEC_WIN decWin;
  40885. + MV_DRAM_DEC_WIN addrDecWin;
  40886. +
  40887. + target = MV_CHANGE_BOOT_CS(target);
  40888. +
  40889. + /* Check parameters */
  40890. + if (target >= MAX_TARGETS)
  40891. + {
  40892. + mvOsPrintf("mvCpuIfTargetWinGet: target %d is Illigal\n", target);
  40893. + return MV_ERROR;
  40894. + }
  40895. +
  40896. + if (MV_TARGET_IS_DRAM(target))
  40897. + {
  40898. + if (mvDramIfWinGet(target,&addrDecWin) != MV_OK)
  40899. + {
  40900. + mvOsPrintf("mvCpuIfTargetWinGet: Failed to get window target %d\n",
  40901. + target);
  40902. + return MV_ERROR;
  40903. + }
  40904. +
  40905. + /* copy relevant data to MV_CPU_DEC_WIN structure */
  40906. + pAddrDecWin->addrWin.baseLow = addrDecWin.addrWin.baseLow;
  40907. + pAddrDecWin->addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  40908. + pAddrDecWin->addrWin.size = addrDecWin.addrWin.size;
  40909. + pAddrDecWin->enable = addrDecWin.enable;
  40910. + pAddrDecWin->winNum = 0xffffffff;
  40911. +
  40912. + }
  40913. + else
  40914. + {
  40915. + /* get the Window number associated with this target */
  40916. +
  40917. + winNum = mvAhbToMbusWinTargetGet(target);
  40918. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  40919. + {
  40920. + return MV_NO_SUCH;
  40921. +
  40922. + }
  40923. +
  40924. + if (mvAhbToMbusWinGet(winNum , &decWin) != MV_OK)
  40925. + {
  40926. + mvOsPrintf("%s: mvAhbToMbusWinGet Failed at winNum = %d\n",
  40927. + __FUNCTION__, winNum);
  40928. + return MV_ERROR;
  40929. +
  40930. + }
  40931. +
  40932. + /* copy relevant data to MV_CPU_DEC_WIN structure */
  40933. + pAddrDecWin->addrWin.baseLow = decWin.addrWin.baseLow;
  40934. + pAddrDecWin->addrWin.baseHigh = decWin.addrWin.baseHigh;
  40935. + pAddrDecWin->addrWin.size = decWin.addrWin.size;
  40936. + pAddrDecWin->enable = decWin.enable;
  40937. + pAddrDecWin->winNum = winNum;
  40938. +
  40939. + }
  40940. +
  40941. +
  40942. +
  40943. +
  40944. + return MV_OK;
  40945. +}
  40946. +
  40947. +
  40948. +/*******************************************************************************
  40949. +* mvCpuIfTargetWinEnable - Enable/disable a CPU address decode window
  40950. +*
  40951. +* DESCRIPTION:
  40952. +* This function enable/disable a CPU address decode window.
  40953. +* if parameter 'enable' == MV_TRUE the routine will enable the
  40954. +* window, thus enabling CPU accesses (before enabling the window it is
  40955. +* tested for overlapping). Otherwise, the window will be disabled.
  40956. +*
  40957. +* INPUT:
  40958. +* target - Peripheral target enumerator.
  40959. +* enable - Enable/disable parameter.
  40960. +*
  40961. +* OUTPUT:
  40962. +* N/A
  40963. +*
  40964. +* RETURN:
  40965. +* MV_ERROR if protection window number was wrong, or the window
  40966. +* overlapps other target window.
  40967. +*
  40968. +*******************************************************************************/
  40969. +MV_STATUS mvCpuIfTargetWinEnable(MV_TARGET target,MV_BOOL enable)
  40970. +{
  40971. + MV_U32 winNum, temp;
  40972. + MV_CPU_DEC_WIN addrDecWin;
  40973. +
  40974. + target = MV_CHANGE_BOOT_CS(target);
  40975. +
  40976. + /* Check parameters */
  40977. + if (target >= MAX_TARGETS)
  40978. + {
  40979. + mvOsPrintf("mvCpuIfTargetWinEnable: target %d is Illigal\n", target);
  40980. + return MV_ERROR;
  40981. + }
  40982. +
  40983. + /* get the window and check if it exist */
  40984. + temp = mvCpuIfTargetWinGet(target, &addrDecWin);
  40985. + if (MV_NO_SUCH == temp)
  40986. + {
  40987. + return (enable? MV_ERROR: MV_OK);
  40988. + }
  40989. + else if( MV_OK != temp)
  40990. + {
  40991. + mvOsPrintf("%s: ERR. Getting target %d failed.\n",__FUNCTION__, target);
  40992. + return MV_ERROR;
  40993. + }
  40994. +
  40995. +
  40996. + /* check overlap */
  40997. +
  40998. + if (MV_TRUE == enable)
  40999. + {
  41000. + if (MV_TRUE == cpuTargetWinOverlap(target, &addrDecWin.addrWin))
  41001. + {
  41002. + DB(mvOsPrintf("%s: ERR. Target %d overlap\n",__FUNCTION__, target));
  41003. + return MV_ERROR;
  41004. + }
  41005. +
  41006. + }
  41007. +
  41008. +
  41009. + if (MV_TARGET_IS_DRAM(target))
  41010. + {
  41011. + if (mvDramIfWinEnable(target , enable) != MV_OK)
  41012. + {
  41013. + mvOsPrintf("mvCpuIfTargetWinGet: mvDramIfWinEnable Failed at \n");
  41014. + return MV_ERROR;
  41015. +
  41016. + }
  41017. +
  41018. + }
  41019. + else
  41020. + {
  41021. + /* get the Window number associated with this target */
  41022. +
  41023. + winNum = mvAhbToMbusWinTargetGet(target);
  41024. +
  41025. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  41026. + {
  41027. + return (enable? MV_ERROR: MV_OK);
  41028. + }
  41029. +
  41030. + if (mvAhbToMbusWinEnable(winNum , enable) != MV_OK)
  41031. + {
  41032. + mvOsPrintf("mvCpuIfTargetWinGet: Failed to enable window = %d\n",
  41033. + winNum);
  41034. + return MV_ERROR;
  41035. +
  41036. + }
  41037. +
  41038. + }
  41039. +
  41040. + return MV_OK;
  41041. +}
  41042. +
  41043. +
  41044. +/*******************************************************************************
  41045. +* mvCpuIfTargetWinSizeGet - Get CPU target address window size
  41046. +*
  41047. +* DESCRIPTION:
  41048. +* Get the size of CPU-to-peripheral target window.
  41049. +*
  41050. +* INPUT:
  41051. +* target - Peripheral target enumerator
  41052. +*
  41053. +* OUTPUT:
  41054. +* None.
  41055. +*
  41056. +* RETURN:
  41057. +* 32bit size. Function also returns '0' if window is closed.
  41058. +* Function returns 0xFFFFFFFF in case of an error.
  41059. +*
  41060. +*******************************************************************************/
  41061. +MV_U32 mvCpuIfTargetWinSizeGet(MV_TARGET target)
  41062. +{
  41063. + MV_CPU_DEC_WIN addrDecWin;
  41064. +
  41065. + target = MV_CHANGE_BOOT_CS(target);
  41066. +
  41067. + /* Check parameters */
  41068. + if (target >= MAX_TARGETS)
  41069. + {
  41070. + mvOsPrintf("mvCpuIfTargetWinSizeGet: target %d is Illigal\n", target);
  41071. + return 0;
  41072. + }
  41073. +
  41074. + /* Get the winNum window */
  41075. + if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))
  41076. + {
  41077. + mvOsPrintf("mvCpuIfTargetWinSizeGet:ERR. Getting target %d failed.\n",
  41078. + target);
  41079. + return 0;
  41080. + }
  41081. +
  41082. + /* Check if window is enabled */
  41083. + if (addrDecWin.enable == MV_TRUE)
  41084. + {
  41085. + return (addrDecWin.addrWin.size);
  41086. + }
  41087. + else
  41088. + {
  41089. + return 0; /* Window disabled. return 0 */
  41090. + }
  41091. +}
  41092. +
  41093. +/*******************************************************************************
  41094. +* mvCpuIfTargetWinBaseLowGet - Get CPU target address window base low
  41095. +*
  41096. +* DESCRIPTION:
  41097. +* CPU-to-peripheral target address window base is constructed of
  41098. +* two parts: Low and high.
  41099. +* This function gets the CPU peripheral target low base address.
  41100. +*
  41101. +* INPUT:
  41102. +* target - Peripheral target enumerator
  41103. +*
  41104. +* OUTPUT:
  41105. +* None.
  41106. +*
  41107. +* RETURN:
  41108. +* 32bit low base address.
  41109. +*
  41110. +*******************************************************************************/
  41111. +MV_U32 mvCpuIfTargetWinBaseLowGet(MV_TARGET target)
  41112. +{
  41113. + MV_CPU_DEC_WIN addrDecWin;
  41114. +
  41115. + target = MV_CHANGE_BOOT_CS(target);
  41116. +
  41117. + /* Check parameters */
  41118. + if (target >= MAX_TARGETS)
  41119. + {
  41120. + mvOsPrintf("mvCpuIfTargetWinBaseLowGet: target %d is Illigal\n", target);
  41121. + return 0xffffffff;
  41122. + }
  41123. +
  41124. + /* Get the target window */
  41125. + if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))
  41126. + {
  41127. + mvOsPrintf("mvCpuIfTargetWinBaseLowGet:ERR. Getting target %d failed.\n",
  41128. + target);
  41129. + return 0xffffffff;
  41130. + }
  41131. +
  41132. + if (MV_FALSE == addrDecWin.enable)
  41133. + {
  41134. + return 0xffffffff;
  41135. + }
  41136. + return (addrDecWin.addrWin.baseLow);
  41137. +}
  41138. +
  41139. +/*******************************************************************************
  41140. +* mvCpuIfTargetWinBaseHighGet - Get CPU target address window base high
  41141. +*
  41142. +* DESCRIPTION:
  41143. +* CPU-to-peripheral target address window base is constructed of
  41144. +* two parts: Low and high.
  41145. +* This function gets the CPU peripheral target high base address.
  41146. +*
  41147. +* INPUT:
  41148. +* target - Peripheral target enumerator
  41149. +*
  41150. +* OUTPUT:
  41151. +* None.
  41152. +*
  41153. +* RETURN:
  41154. +* 32bit high base address.
  41155. +*
  41156. +*******************************************************************************/
  41157. +MV_U32 mvCpuIfTargetWinBaseHighGet(MV_TARGET target)
  41158. +{
  41159. + MV_CPU_DEC_WIN addrDecWin;
  41160. +
  41161. + target = MV_CHANGE_BOOT_CS(target);
  41162. +
  41163. + /* Check parameters */
  41164. + if (target >= MAX_TARGETS)
  41165. + {
  41166. + mvOsPrintf("mvCpuIfTargetWinBaseLowGet: target %d is Illigal\n", target);
  41167. + return 0xffffffff;
  41168. + }
  41169. +
  41170. + /* Get the target window */
  41171. + if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))
  41172. + {
  41173. + mvOsPrintf("mvCpuIfTargetWinBaseHighGet:ERR. Getting target %d failed.\n",
  41174. + target);
  41175. + return 0xffffffff;
  41176. + }
  41177. +
  41178. + if (MV_FALSE == addrDecWin.enable)
  41179. + {
  41180. + return 0;
  41181. + }
  41182. +
  41183. + return (addrDecWin.addrWin.baseHigh);
  41184. +}
  41185. +
  41186. +#if defined(MV_INCLUDE_PEX)
  41187. +/*******************************************************************************
  41188. +* mvCpuIfPexRemap - Set CPU remap register for address windows.
  41189. +*
  41190. +* DESCRIPTION:
  41191. +*
  41192. +* INPUT:
  41193. +* pexTarget - Peripheral target enumerator. Must be a PEX target.
  41194. +* pAddrDecWin - CPU target window information data structure.
  41195. +* Note that caller has to fill in the base field only. The
  41196. +* size field is ignored.
  41197. +*
  41198. +* OUTPUT:
  41199. +* None.
  41200. +*
  41201. +* RETURN:
  41202. +* MV_ERROR if target is not a PEX one, MV_OK otherwise.
  41203. +*
  41204. +*******************************************************************************/
  41205. +MV_U32 mvCpuIfPexRemap(MV_TARGET pexTarget, MV_ADDR_WIN *pAddrDecWin)
  41206. +{
  41207. + MV_U32 winNum;
  41208. +
  41209. + /* Check parameters */
  41210. +
  41211. + if (mvCtrlPexMaxIfGet() > 1)
  41212. + {
  41213. + if ((!MV_TARGET_IS_PEX1(pexTarget))&&(!MV_TARGET_IS_PEX0(pexTarget)))
  41214. + {
  41215. + mvOsPrintf("mvCpuIfPexRemap: target %d is Illigal\n",pexTarget);
  41216. + return 0xffffffff;
  41217. + }
  41218. +
  41219. + }
  41220. + else
  41221. + {
  41222. + if (!MV_TARGET_IS_PEX0(pexTarget))
  41223. + {
  41224. + mvOsPrintf("mvCpuIfPexRemap: target %d is Illigal\n",pexTarget);
  41225. + return 0xffffffff;
  41226. + }
  41227. +
  41228. + }
  41229. +
  41230. + /* get the Window number associated with this target */
  41231. + winNum = mvAhbToMbusWinTargetGet(pexTarget);
  41232. +
  41233. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  41234. + {
  41235. + mvOsPrintf("mvCpuIfPexRemap: mvAhbToMbusWinTargetGet Failed\n");
  41236. + return 0xffffffff;
  41237. +
  41238. + }
  41239. +
  41240. + return mvAhbToMbusWinRemap(winNum , pAddrDecWin);
  41241. +}
  41242. +
  41243. +#endif
  41244. +
  41245. +#if defined(MV_INCLUDE_PCI)
  41246. +/*******************************************************************************
  41247. +* mvCpuIfPciRemap - Set CPU remap register for address windows.
  41248. +*
  41249. +* DESCRIPTION:
  41250. +*
  41251. +* INPUT:
  41252. +* pciTarget - Peripheral target enumerator. Must be a PCI target.
  41253. +* pAddrDecWin - CPU target window information data structure.
  41254. +* Note that caller has to fill in the base field only. The
  41255. +* size field is ignored.
  41256. +*
  41257. +* OUTPUT:
  41258. +* None.
  41259. +*
  41260. +* RETURN:
  41261. +* MV_ERROR if target is not a PCI one, MV_OK otherwise.
  41262. +*
  41263. +*******************************************************************************/
  41264. +MV_U32 mvCpuIfPciRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin)
  41265. +{
  41266. + MV_U32 winNum;
  41267. +
  41268. + /* Check parameters */
  41269. + if (!MV_TARGET_IS_PCI(pciTarget))
  41270. + {
  41271. + mvOsPrintf("mvCpuIfPciRemap: target %d is Illigal\n",pciTarget);
  41272. + return 0xffffffff;
  41273. + }
  41274. +
  41275. + /* get the Window number associated with this target */
  41276. + winNum = mvAhbToMbusWinTargetGet(pciTarget);
  41277. +
  41278. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  41279. + {
  41280. + mvOsPrintf("mvCpuIfPciRemap: mvAhbToMbusWinTargetGet Failed\n");
  41281. + return 0xffffffff;
  41282. +
  41283. + }
  41284. +
  41285. + return mvAhbToMbusWinRemap(winNum , pAddrDecWin);
  41286. +}
  41287. +#endif /* MV_INCLUDE_PCI */
  41288. +
  41289. +
  41290. +/*******************************************************************************
  41291. +* mvCpuIfPciIfRemap - Set CPU remap register for address windows.
  41292. +*
  41293. +* DESCRIPTION:
  41294. +*
  41295. +* INPUT:
  41296. +* pciTarget - Peripheral target enumerator. Must be a PCI target.
  41297. +* pAddrDecWin - CPU target window information data structure.
  41298. +* Note that caller has to fill in the base field only. The
  41299. +* size field is ignored.
  41300. +*
  41301. +* OUTPUT:
  41302. +* None.
  41303. +*
  41304. +* RETURN:
  41305. +* MV_ERROR if target is not a PCI one, MV_OK otherwise.
  41306. +*
  41307. +*******************************************************************************/
  41308. +MV_U32 mvCpuIfPciIfRemap(MV_TARGET pciIfTarget, MV_ADDR_WIN *pAddrDecWin)
  41309. +{
  41310. +#if defined(MV_INCLUDE_PEX)
  41311. + if (MV_TARGET_IS_PEX(pciIfTarget))
  41312. + {
  41313. + return mvCpuIfPexRemap(pciIfTarget,pAddrDecWin);
  41314. + }
  41315. +#endif
  41316. +#if defined(MV_INCLUDE_PCI)
  41317. +
  41318. + if (MV_TARGET_IS_PCI(pciIfTarget))
  41319. + {
  41320. + return mvCpuIfPciRemap(pciIfTarget,pAddrDecWin);
  41321. + }
  41322. +#endif
  41323. + return 0;
  41324. +}
  41325. +
  41326. +
  41327. +
  41328. +/*******************************************************************************
  41329. +* mvCpuIfTargetOfBaseAddressGet - Get the target according to base address
  41330. +*
  41331. +* DESCRIPTION:
  41332. +*
  41333. +* INPUT:
  41334. +* baseAddress - base address to be checked
  41335. +*
  41336. +* OUTPUT:
  41337. +* None.
  41338. +*
  41339. +* RETURN:
  41340. +* the target number that baseAddress belongs to or MAX_TARGETS is not
  41341. +* found
  41342. +*
  41343. +*******************************************************************************/
  41344. +
  41345. +MV_TARGET mvCpuIfTargetOfBaseAddressGet(MV_U32 baseAddress)
  41346. +{
  41347. + MV_CPU_DEC_WIN win;
  41348. + MV_U32 target;
  41349. +
  41350. + for( target = 0; target < MAX_TARGETS; target++ )
  41351. + {
  41352. + if( mvCpuIfTargetWinGet( target, &win ) == MV_OK )
  41353. + {
  41354. + if( win.enable )
  41355. + {
  41356. + if ((baseAddress >= win.addrWin.baseLow) &&
  41357. + (baseAddress < win.addrWin.baseLow + win.addrWin.size)) break;
  41358. + }
  41359. + }
  41360. + else return MAX_TARGETS;
  41361. +
  41362. + }
  41363. +
  41364. + return target;
  41365. +}
  41366. +/*******************************************************************************
  41367. +* cpuTargetWinOverlap - Detect CPU address decode windows overlapping
  41368. +*
  41369. +* DESCRIPTION:
  41370. +* An unpredicted behaviur is expected in case CPU address decode
  41371. +* windows overlapps.
  41372. +* This function detects CPU address decode windows overlapping of a
  41373. +* specified target. The function does not check the target itself for
  41374. +* overlapping. The function also skipps disabled address decode windows.
  41375. +*
  41376. +* INPUT:
  41377. +* target - Peripheral target enumerator.
  41378. +* pAddrDecWin - An address decode window struct.
  41379. +*
  41380. +* OUTPUT:
  41381. +* None.
  41382. +*
  41383. +* RETURN:
  41384. +* MV_TRUE if the given address window overlaps current address
  41385. +* decode map, MV_FALSE otherwise.
  41386. +*
  41387. +*******************************************************************************/
  41388. +static MV_BOOL cpuTargetWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
  41389. +{
  41390. + MV_U32 targetNum;
  41391. + MV_CPU_DEC_WIN addrDecWin;
  41392. + MV_STATUS status;
  41393. +
  41394. +
  41395. + for(targetNum = 0; targetNum < MAX_TARGETS; targetNum++)
  41396. + {
  41397. +#if defined(MV_RUN_FROM_FLASH)
  41398. + if(MV_TARGET_IS_AS_BOOT(target))
  41399. + {
  41400. + if (MV_CHANGE_BOOT_CS(targetNum) == target)
  41401. + continue;
  41402. + }
  41403. +#endif /* MV_RUN_FROM_FLASH */
  41404. +
  41405. + /* don't check our target or illegal targets */
  41406. + if (targetNum == target)
  41407. + {
  41408. + continue;
  41409. + }
  41410. +
  41411. + /* Get window parameters */
  41412. + status = mvCpuIfTargetWinGet(targetNum, &addrDecWin);
  41413. + if(MV_NO_SUCH == status)
  41414. + {
  41415. + continue;
  41416. + }
  41417. + if(MV_OK != status)
  41418. + {
  41419. + DB(mvOsPrintf("cpuTargetWinOverlap: ERR. TargetWinGet failed\n"));
  41420. + return MV_TRUE;
  41421. + }
  41422. +
  41423. + /* Do not check disabled windows */
  41424. + if (MV_FALSE == addrDecWin.enable)
  41425. + {
  41426. + continue;
  41427. + }
  41428. +
  41429. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
  41430. + {
  41431. + DB(mvOsPrintf(
  41432. + "cpuTargetWinOverlap: Required target %d overlap current %d\n",
  41433. + target, targetNum));
  41434. + return MV_TRUE;
  41435. + }
  41436. + }
  41437. +
  41438. + return MV_FALSE;
  41439. +
  41440. +}
  41441. +
  41442. +/*******************************************************************************
  41443. +* mvCpuIfAddDecShow - Print the CPU address decode map.
  41444. +*
  41445. +* DESCRIPTION:
  41446. +* This function print the CPU address decode map.
  41447. +*
  41448. +* INPUT:
  41449. +* None.
  41450. +*
  41451. +* OUTPUT:
  41452. +* None.
  41453. +*
  41454. +* RETURN:
  41455. +* None.
  41456. +*
  41457. +*******************************************************************************/
  41458. +MV_VOID mvCpuIfAddDecShow(MV_VOID)
  41459. +{
  41460. + MV_CPU_DEC_WIN win;
  41461. + MV_U32 target;
  41462. + mvOsOutput( "\n" );
  41463. + mvOsOutput( "CPU Interface\n" );
  41464. + mvOsOutput( "-------------\n" );
  41465. +
  41466. + for( target = 0; target < MAX_TARGETS; target++ )
  41467. + {
  41468. +
  41469. + memset( &win, 0, sizeof(MV_CPU_DEC_WIN) );
  41470. +
  41471. + mvOsOutput( "%s ",mvCtrlTargetNameGet(target));
  41472. + mvOsOutput( "...." );
  41473. +
  41474. + if( mvCpuIfTargetWinGet( target, &win ) == MV_OK )
  41475. + {
  41476. + if( win.enable )
  41477. + {
  41478. + mvOsOutput( "base %08x, ", win.addrWin.baseLow );
  41479. + mvSizePrint( win.addrWin.size );
  41480. + mvOsOutput( "\n" );
  41481. +
  41482. + }
  41483. + else
  41484. + mvOsOutput( "disable\n" );
  41485. + }
  41486. + else if( mvCpuIfTargetWinGet( target, &win ) == MV_NO_SUCH )
  41487. + {
  41488. + mvOsOutput( "no such\n" );
  41489. + }
  41490. + }
  41491. +}
  41492. +
  41493. +/*******************************************************************************
  41494. +* mvCpuIfEnablePex - Enable PCI Express.
  41495. +*
  41496. +* DESCRIPTION:
  41497. +* This function Enable PCI Express.
  41498. +*
  41499. +* INPUT:
  41500. +* pexIf - PEX interface number.
  41501. +* pexType - MV_PEX_ROOT_COMPLEX - root complex device
  41502. +* MV_PEX_END_POINT - end point device
  41503. +* OUTPUT:
  41504. +* None.
  41505. +*
  41506. +* RETURN:
  41507. +* None.
  41508. +*
  41509. +*******************************************************************************/
  41510. +#if defined(MV_INCLUDE_PEX)
  41511. +MV_VOID mvCpuIfEnablePex(MV_U32 pexIf, MV_PEX_TYPE pexType)
  41512. +{
  41513. + /* Set pex mode incase S@R not exist */
  41514. + if( pexType == MV_PEX_END_POINT)
  41515. + {
  41516. + MV_REG_BIT_RESET(PEX_CTRL_REG(pexIf),PXCR_DEV_TYPE_CTRL_MASK);
  41517. + /* Change pex mode in capability reg */
  41518. + MV_REG_BIT_RESET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_CAPABILITY_REG), BIT22);
  41519. + MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_CAPABILITY_REG), BIT20);
  41520. +
  41521. + }
  41522. + else
  41523. + {
  41524. + MV_REG_BIT_SET(PEX_CTRL_REG(pexIf),PXCR_DEV_TYPE_CTRL_MASK);
  41525. + }
  41526. +
  41527. + /* CPU config register Pex enable */
  41528. + MV_REG_BIT_SET(CPU_CTRL_STAT_REG,CCSR_PCI_ACCESS_MASK);
  41529. +}
  41530. +#endif
  41531. +
  41532. +
  41533. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h
  41534. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h 1970-01-01 01:00:00.000000000 +0100
  41535. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h 2010-08-05 22:02:19.153619191 +0200
  41536. @@ -0,0 +1,120 @@
  41537. +/*******************************************************************************
  41538. +Copyright (C) Marvell International Ltd. and its affiliates
  41539. +
  41540. +This software file (the "File") is owned and distributed by Marvell
  41541. +International Ltd. and/or its affiliates ("Marvell") under the following
  41542. +alternative licensing terms. Once you have made an election to distribute the
  41543. +File under one of the following license alternatives, please (i) delete this
  41544. +introductory statement regarding license alternatives, (ii) delete the two
  41545. +license alternatives that you have not elected to use and (iii) preserve the
  41546. +Marvell copyright notice above.
  41547. +
  41548. +********************************************************************************
  41549. +Marvell Commercial License Option
  41550. +
  41551. +If you received this File from Marvell and you have entered into a commercial
  41552. +license agreement (a "Commercial License") with Marvell, the File is licensed
  41553. +to you under the terms of the applicable Commercial License.
  41554. +
  41555. +********************************************************************************
  41556. +Marvell GPL License Option
  41557. +
  41558. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41559. +modify this File in accordance with the terms and conditions of the General
  41560. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  41561. +available along with the File in the license.txt file or by writing to the Free
  41562. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  41563. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  41564. +
  41565. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  41566. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  41567. +DISCLAIMED. The GPL License provides additional details about this warranty
  41568. +disclaimer.
  41569. +********************************************************************************
  41570. +Marvell BSD License Option
  41571. +
  41572. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41573. +modify this File under the following licensing terms.
  41574. +Redistribution and use in source and binary forms, with or without modification,
  41575. +are permitted provided that the following conditions are met:
  41576. +
  41577. + * Redistributions of source code must retain the above copyright notice,
  41578. + this list of conditions and the following disclaimer.
  41579. +
  41580. + * Redistributions in binary form must reproduce the above copyright
  41581. + notice, this list of conditions and the following disclaimer in the
  41582. + documentation and/or other materials provided with the distribution.
  41583. +
  41584. + * Neither the name of Marvell nor the names of its contributors may be
  41585. + used to endorse or promote products derived from this software without
  41586. + specific prior written permission.
  41587. +
  41588. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  41589. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  41590. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  41591. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  41592. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  41593. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  41594. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  41595. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  41596. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  41597. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  41598. +
  41599. +*******************************************************************************/
  41600. +
  41601. +
  41602. +#ifndef __INCmvCpuIfh
  41603. +#define __INCmvCpuIfh
  41604. +
  41605. +/* includes */
  41606. +#include "ctrlEnv/mvCtrlEnvLib.h"
  41607. +#include "ctrlEnv/sys/mvCpuIfRegs.h"
  41608. +#include "ctrlEnv/sys/mvAhbToMbus.h"
  41609. +#include "ddr2/mvDramIf.h"
  41610. +#include "ctrlEnv/sys/mvSysDram.h"
  41611. +#if defined(MV_INCLUDE_PEX)
  41612. +#include "pex/mvPex.h"
  41613. +#endif
  41614. +
  41615. +/* defines */
  41616. +
  41617. +/* typedefs */
  41618. +/* This structure describes CPU interface address decode window */
  41619. +typedef struct _mvCpuIfDecWin
  41620. +{
  41621. + MV_ADDR_WIN addrWin; /* An address window*/
  41622. + MV_U32 winNum; /* Window Number in the AHB To Mbus bridge */
  41623. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  41624. +
  41625. +}MV_CPU_DEC_WIN;
  41626. +
  41627. +
  41628. +
  41629. +/* mvCpuIfLib.h API list */
  41630. +
  41631. +/* mvCpuIfLib.h API list */
  41632. +
  41633. +MV_STATUS mvCpuIfInit(MV_CPU_DEC_WIN *cpuAddrWinMap);
  41634. +MV_STATUS mvCpuIfTargetWinSet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin);
  41635. +MV_STATUS mvCpuIfTargetWinGet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin);
  41636. +MV_STATUS mvCpuIfTargetWinEnable(MV_TARGET target,MV_BOOL enable);
  41637. +MV_U32 mvCpuIfTargetWinSizeGet(MV_TARGET target);
  41638. +MV_U32 mvCpuIfTargetWinBaseLowGet(MV_TARGET target);
  41639. +MV_U32 mvCpuIfTargetWinBaseHighGet(MV_TARGET target);
  41640. +MV_TARGET mvCpuIfTargetOfBaseAddressGet(MV_U32 baseAddress);
  41641. +#if defined(MV_INCLUDE_PEX)
  41642. +MV_U32 mvCpuIfPexRemap(MV_TARGET pexTarget, MV_ADDR_WIN *pAddrDecWin);
  41643. +MV_VOID mvCpuIfEnablePex(MV_U32 pexIf, MV_PEX_TYPE pexType);
  41644. +#endif
  41645. +#if defined(MV_INCLUDE_PCI)
  41646. +MV_U32 mvCpuIfPciRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin);
  41647. +#endif
  41648. +MV_U32 mvCpuIfPciIfRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin);
  41649. +
  41650. +MV_VOID mvCpuIfAddDecShow(MV_VOID);
  41651. +
  41652. +#if defined(MV88F6281)
  41653. +MV_STATUS mvCpuIfBridgeReorderWAInit(void);
  41654. +#endif
  41655. +
  41656. +#endif /* __INCmvCpuIfh */
  41657. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h
  41658. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h 1970-01-01 01:00:00.000000000 +0100
  41659. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h 2010-08-05 22:02:19.293640559 +0200
  41660. @@ -0,0 +1,304 @@
  41661. +/*******************************************************************************
  41662. +Copyright (C) Marvell International Ltd. and its affiliates
  41663. +
  41664. +This software file (the "File") is owned and distributed by Marvell
  41665. +International Ltd. and/or its affiliates ("Marvell") under the following
  41666. +alternative licensing terms. Once you have made an election to distribute the
  41667. +File under one of the following license alternatives, please (i) delete this
  41668. +introductory statement regarding license alternatives, (ii) delete the two
  41669. +license alternatives that you have not elected to use and (iii) preserve the
  41670. +Marvell copyright notice above.
  41671. +
  41672. +********************************************************************************
  41673. +Marvell Commercial License Option
  41674. +
  41675. +If you received this File from Marvell and you have entered into a commercial
  41676. +license agreement (a "Commercial License") with Marvell, the File is licensed
  41677. +to you under the terms of the applicable Commercial License.
  41678. +
  41679. +********************************************************************************
  41680. +Marvell GPL License Option
  41681. +
  41682. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41683. +modify this File in accordance with the terms and conditions of the General
  41684. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  41685. +available along with the File in the license.txt file or by writing to the Free
  41686. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  41687. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  41688. +
  41689. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  41690. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  41691. +DISCLAIMED. The GPL License provides additional details about this warranty
  41692. +disclaimer.
  41693. +********************************************************************************
  41694. +Marvell BSD License Option
  41695. +
  41696. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41697. +modify this File under the following licensing terms.
  41698. +Redistribution and use in source and binary forms, with or without modification,
  41699. +are permitted provided that the following conditions are met:
  41700. +
  41701. + * Redistributions of source code must retain the above copyright notice,
  41702. + this list of conditions and the following disclaimer.
  41703. +
  41704. + * Redistributions in binary form must reproduce the above copyright
  41705. + notice, this list of conditions and the following disclaimer in the
  41706. + documentation and/or other materials provided with the distribution.
  41707. +
  41708. + * Neither the name of Marvell nor the names of its contributors may be
  41709. + used to endorse or promote products derived from this software without
  41710. + specific prior written permission.
  41711. +
  41712. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  41713. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  41714. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  41715. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  41716. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  41717. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  41718. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  41719. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  41720. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  41721. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  41722. +
  41723. +*******************************************************************************/
  41724. +
  41725. +
  41726. +#ifndef __INCmvCpuIfRegsh
  41727. +#define __INCmvCpuIfRegsh
  41728. +
  41729. +/****************************************/
  41730. +/* ARM Control and Status Registers Map */
  41731. +/****************************************/
  41732. +
  41733. +#define CPU_CONFIG_REG 0x20100
  41734. +#define CPU_CTRL_STAT_REG 0x20104
  41735. +#define CPU_RSTOUTN_MASK_REG 0x20108
  41736. +#define CPU_SYS_SOFT_RST_REG 0x2010C
  41737. +#define CPU_AHB_MBUS_CAUSE_INT_REG 0x20110
  41738. +#define CPU_AHB_MBUS_MASK_INT_REG 0x20114
  41739. +#define CPU_FTDLL_CONFIG_REG 0x20120
  41740. +#define CPU_L2_CONFIG_REG 0x20128
  41741. +
  41742. +
  41743. +
  41744. +/* ARM Configuration register */
  41745. +/* CPU_CONFIG_REG (CCR) */
  41746. +
  41747. +
  41748. +/* Reset vector location */
  41749. +#define CCR_VEC_INIT_LOC_OFFS 1
  41750. +#define CCR_VEC_INIT_LOC_MASK BIT1
  41751. +/* reset at 0x00000000 */
  41752. +#define CCR_VEC_INIT_LOC_0000 (0 << CCR_VEC_INIT_LOC_OFFS)
  41753. +/* reset at 0xFFFF0000 */
  41754. +#define CCR_VEC_INIT_LOC_FF00 (1 << CCR_VEC_INIT_LOC_OFFS)
  41755. +
  41756. +
  41757. +#define CCR_AHB_ERROR_PROP_OFFS 2
  41758. +#define CCR_AHB_ERROR_PROP_MASK BIT2
  41759. +/* Erros are not propogated to AHB */
  41760. +#define CCR_AHB_ERROR_PROP_NO_INDICATE (0 << CCR_AHB_ERROR_PROP_OFFS)
  41761. +/* Erros are propogated to AHB */
  41762. +#define CCR_AHB_ERROR_PROP_INDICATE (1 << CCR_AHB_ERROR_PROP_OFFS)
  41763. +
  41764. +
  41765. +#define CCR_ENDIAN_INIT_OFFS 3
  41766. +#define CCR_ENDIAN_INIT_MASK BIT3
  41767. +#define CCR_ENDIAN_INIT_LITTLE (0 << CCR_ENDIAN_INIT_OFFS)
  41768. +#define CCR_ENDIAN_INIT_BIG (1 << CCR_ENDIAN_INIT_OFFS)
  41769. +
  41770. +
  41771. +#define CCR_INCR_EN_OFFS 4
  41772. +#define CCR_INCR_EN_MASK BIT4
  41773. +#define CCR_INCR_EN BIT4
  41774. +
  41775. +
  41776. +#define CCR_NCB_BLOCKING_OFFS 5
  41777. +#define CCR_NCB_BLOCKING_MASK (1 << CCR_NCB_BLOCKING_OFFS)
  41778. +#define CCR_NCB_BLOCKING_NON (0 << CCR_NCB_BLOCKING_OFFS)
  41779. +#define CCR_NCB_BLOCKING_EN (1 << CCR_NCB_BLOCKING_OFFS)
  41780. +
  41781. +#define CCR_CPU_2_MBUSL_TICK_DRV_OFFS 8
  41782. +#define CCR_CPU_2_MBUSL_TICK_DRV_MASK (0xF << CCR_CPU_2_MBUSL_TICK_DRV_OFFS)
  41783. +#define CCR_CPU_2_MBUSL_TICK_SMPL_OFFS 12
  41784. +#define CCR_CPU_2_MBUSL_TICK_SMPL_MASK (0xF << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS)
  41785. +#define CCR_ICACH_PREF_BUF_ENABLE BIT16
  41786. +#define CCR_DCACH_PREF_BUF_ENABLE BIT17
  41787. +
  41788. +/* Ratio options for CPU to DDR for 6281/6192/6190 */
  41789. +#define CPU_2_DDR_CLK_1x3 4
  41790. +#define CPU_2_DDR_CLK_1x4 6
  41791. +
  41792. +/* Ratio options for CPU to DDR for 6281 only */
  41793. +#define CPU_2_DDR_CLK_2x9 7
  41794. +#define CPU_2_DDR_CLK_1x5 8
  41795. +#define CPU_2_DDR_CLK_1x6 9
  41796. +
  41797. +/* Ratio options for CPU to DDR for 6180 only */
  41798. +#define CPU_2_DDR_CLK_1x3_1 0x5
  41799. +#define CPU_2_DDR_CLK_1x4_1 0x6
  41800. +
  41801. +/* Default values for CPU to Mbus-L DDR Interface Tick Driver and */
  41802. +/* CPU to Mbus-L Tick Sample fields in CPU config register */
  41803. +
  41804. +#define TICK_DRV_1x1 0
  41805. +#define TICK_DRV_1x2 0
  41806. +#define TICK_DRV_1x3 1
  41807. +#define TICK_DRV_1x4 2
  41808. +#define TICK_SMPL_1x1 0
  41809. +#define TICK_SMPL_1x2 1
  41810. +#define TICK_SMPL_1x3 0
  41811. +#define TICK_SMPL_1x4 0
  41812. +
  41813. +#define CPU_2_MBUSL_DDR_CLK_1x2 \
  41814. + ((TICK_DRV_1x2 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
  41815. + (TICK_SMPL_1x2 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
  41816. +#define CPU_2_MBUSL_DDR_CLK_1x3 \
  41817. + ((TICK_DRV_1x3 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
  41818. + (TICK_SMPL_1x3 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
  41819. +#define CPU_2_MBUSL_DDR_CLK_1x4 \
  41820. + ((TICK_DRV_1x4 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
  41821. + (TICK_SMPL_1x4 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
  41822. +
  41823. +/* ARM Control and Status register */
  41824. +/* CPU_CTRL_STAT_REG (CCSR) */
  41825. +
  41826. +
  41827. +/*
  41828. +This is used to block PCI express\PCI from access Socrates/Feroceon GP
  41829. +while ARM boot is still in progress
  41830. +*/
  41831. +
  41832. +#define CCSR_PCI_ACCESS_OFFS 0
  41833. +#define CCSR_PCI_ACCESS_MASK BIT0
  41834. +#define CCSR_PCI_ACCESS_ENABLE (0 << CCSR_PCI_ACCESS_OFFS)
  41835. +#define CCSR_PCI_ACCESS_DISBALE (1 << CCSR_PCI_ACCESS_OFFS)
  41836. +
  41837. +#define CCSR_ARM_RESET BIT1
  41838. +#define CCSR_SELF_INT BIT2
  41839. +#define CCSR_BIG_ENDIAN BIT15
  41840. +
  41841. +
  41842. +/* RSTOUTn Mask Register */
  41843. +/* CPU_RSTOUTN_MASK_REG (CRMR) */
  41844. +
  41845. +#define CRMR_PEX_RST_OUT_OFFS 0
  41846. +#define CRMR_PEX_RST_OUT_MASK BIT0
  41847. +#define CRMR_PEX_RST_OUT_ENABLE (1 << CRMR_PEX_RST_OUT_OFFS)
  41848. +#define CRMR_PEX_RST_OUT_DISABLE (0 << CRMR_PEX_RST_OUT_OFFS)
  41849. +
  41850. +#define CRMR_WD_RST_OUT_OFFS 1
  41851. +#define CRMR_WD_RST_OUT_MASK BIT1
  41852. +#define CRMR_WD_RST_OUT_ENABLE (1 << CRMR_WD_RST_OUT_OFFS)
  41853. +#define CRMR_WD_RST_OUT_DISBALE (0 << CRMR_WD_RST_OUT_OFFS)
  41854. +
  41855. +#define CRMR_SOFT_RST_OUT_OFFS 2
  41856. +#define CRMR_SOFT_RST_OUT_MASK BIT2
  41857. +#define CRMR_SOFT_RST_OUT_ENABLE (1 << CRMR_SOFT_RST_OUT_OFFS)
  41858. +#define CRMR_SOFT_RST_OUT_DISBALE (0 << CRMR_SOFT_RST_OUT_OFFS)
  41859. +
  41860. +/* System Software Reset Register */
  41861. +/* CPU_SYS_SOFT_RST_REG (CSSRR) */
  41862. +
  41863. +#define CSSRR_SYSTEM_SOFT_RST BIT0
  41864. +
  41865. +/* AHB to Mbus Bridge Interrupt Cause Register*/
  41866. +/* CPU_AHB_MBUS_CAUSE_INT_REG (CAMCIR) */
  41867. +
  41868. +#define CAMCIR_ARM_SELF_INT BIT0
  41869. +#define CAMCIR_ARM_TIMER0_INT_REQ BIT1
  41870. +#define CAMCIR_ARM_TIMER1_INT_REQ BIT2
  41871. +#define CAMCIR_ARM_WD_TIMER_INT_REQ BIT3
  41872. +
  41873. +
  41874. +/* AHB to Mbus Bridge Interrupt Mask Register*/
  41875. +/* CPU_AHB_MBUS_MASK_INT_REG (CAMMIR) */
  41876. +
  41877. +#define CAMCIR_ARM_SELF_INT_OFFS 0
  41878. +#define CAMCIR_ARM_SELF_INT_MASK BIT0
  41879. +#define CAMCIR_ARM_SELF_INT_EN (1 << CAMCIR_ARM_SELF_INT_OFFS)
  41880. +#define CAMCIR_ARM_SELF_INT_DIS (0 << CAMCIR_ARM_SELF_INT_OFFS)
  41881. +
  41882. +
  41883. +#define CAMCIR_ARM_TIMER0_INT_REQ_OFFS 1
  41884. +#define CAMCIR_ARM_TIMER0_INT_REQ_MASK BIT1
  41885. +#define CAMCIR_ARM_TIMER0_INT_REQ_EN (1 << CAMCIR_ARM_TIMER0_INT_REQ_OFFS)
  41886. +#define CAMCIR_ARM_TIMER0_INT_REQ_DIS (0 << CAMCIR_ARM_TIMER0_INT_REQ_OFFS)
  41887. +
  41888. +#define CAMCIR_ARM_TIMER1_INT_REQ_OFFS 2
  41889. +#define CAMCIR_ARM_TIMER1_INT_REQ_MASK BIT2
  41890. +#define CAMCIR_ARM_TIMER1_INT_REQ_EN (1 << CAMCIR_ARM_TIMER1_INT_REQ_OFFS)
  41891. +#define CAMCIR_ARM_TIMER1_INT_REQ_DIS (0 << CAMCIR_ARM_TIMER1_INT_REQ_OFFS)
  41892. +
  41893. +#define CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS 3
  41894. +#define CAMCIR_ARM_WD_TIMER_INT_REQ_MASK BIT3
  41895. +#define CAMCIR_ARM_WD_TIMER_INT_REQ_EN (1 << CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS)
  41896. +#define CAMCIR_ARM_WD_TIMER_INT_REQ_DIS (0 << CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS)
  41897. +
  41898. +/* CPU FTDLL Config register (CFCR) fields */
  41899. +#define CFCR_FTDLL_ICACHE_TAG_OFFS 0
  41900. +#define CFCR_FTDLL_ICACHE_TAG_MASK (0x7F << CFCR_FTDLL_ICACHE_TAG_OFFS)
  41901. +#define CFCR_FTDLL_DCACHE_TAG_OFFS 8
  41902. +#define CFCR_FTDLL_DCACHE_TAG_MASK (0x7F << CFCR_FTDLL_DCACHE_TAG_OFFS)
  41903. +#define CFCR_FTDLL_OVERWRITE_ENABLE (1 << 15)
  41904. +/* For Orion 2 D2 only */
  41905. +#define CFCR_MRVL_CPU_ID_OFFS 16
  41906. +#define CFCR_MRVL_CPU_ID_MASK (0x1 << CFCR_MRVL_CPU_ID_OFFS)
  41907. +#define CFCR_ARM_CPU_ID (0x0 << CFCR_MRVL_CPU_ID_OFFS)
  41908. +#define CFCR_MRVL_CPU_ID (0x1 << CFCR_MRVL_CPU_ID_OFFS)
  41909. +#define CFCR_VFP_SUB_ARC_NUM_OFFS 7
  41910. +#define CFCR_VFP_SUB_ARC_NUM_MASK (0x1 << CFCR_VFP_SUB_ARC_NUM_OFFS)
  41911. +#define CFCR_VFP_SUB_ARC_NUM_1 (0x0 << CFCR_VFP_SUB_ARC_NUM_OFFS)
  41912. +#define CFCR_VFP_SUB_ARC_NUM_2 (0x1 << CFCR_VFP_SUB_ARC_NUM_OFFS)
  41913. +
  41914. +/* CPU_L2_CONFIG_REG fields */
  41915. +#ifdef MV_CPU_LE
  41916. +#define CL2CR_L2_ECC_EN_OFFS 2
  41917. +#define CL2CR_L2_WT_MODE_OFFS 4
  41918. +#else
  41919. +#define CL2CR_L2_ECC_EN_OFFS 26
  41920. +#define CL2CR_L2_WT_MODE_OFFS 28
  41921. +#endif
  41922. +
  41923. +#define CL2CR_L2_ECC_EN_MASK (1 << CL2CR_L2_ECC_EN_OFFS)
  41924. +#define CL2CR_L2_WT_MODE_MASK (1 << CL2CR_L2_WT_MODE_OFFS)
  41925. +
  41926. +/*******************************************/
  41927. +/* Main Interrupt Controller Registers Map */
  41928. +/*******************************************/
  41929. +
  41930. +#define CPU_MAIN_INT_CAUSE_REG 0x20200
  41931. +#define CPU_MAIN_IRQ_MASK_REG 0x20204
  41932. +#define CPU_MAIN_FIQ_MASK_REG 0x20208
  41933. +#define CPU_ENPOINT_MASK_REG 0x2020C
  41934. +#define CPU_MAIN_INT_CAUSE_HIGH_REG 0x20210
  41935. +#define CPU_MAIN_IRQ_MASK_HIGH_REG 0x20214
  41936. +#define CPU_MAIN_FIQ_MASK_HIGH_REG 0x20218
  41937. +#define CPU_ENPOINT_MASK_HIGH_REG 0x2021C
  41938. +
  41939. +
  41940. +/*******************************************/
  41941. +/* ARM Doorbell Registers Map */
  41942. +/*******************************************/
  41943. +
  41944. +#define CPU_HOST_TO_ARM_DRBL_REG 0x20400
  41945. +#define CPU_HOST_TO_ARM_MASK_REG 0x20404
  41946. +#define CPU_ARM_TO_HOST_DRBL_REG 0x20408
  41947. +#define CPU_ARM_TO_HOST_MASK_REG 0x2040C
  41948. +
  41949. +
  41950. +
  41951. +/* CPU control register map */
  41952. +/* Set bits means value is about to change according to new value */
  41953. +#define CPU_CONFIG_DEFAULT_MASK (CCR_VEC_INIT_LOC_MASK | CCR_AHB_ERROR_PROP_MASK)
  41954. +
  41955. +#define CPU_CONFIG_DEFAULT (CCR_VEC_INIT_LOC_FF00)
  41956. +
  41957. +/* CPU Control and status defaults */
  41958. +#define CPU_CTRL_STAT_DEFAULT_MASK (CCSR_PCI_ACCESS_MASK)
  41959. +
  41960. +
  41961. +#define CPU_CTRL_STAT_DEFAULT (CCSR_PCI_ACCESS_ENABLE)
  41962. +
  41963. +#endif /* __INCmvCpuIfRegsh */
  41964. +
  41965. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c
  41966. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c 1970-01-01 01:00:00.000000000 +0100
  41967. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c 2010-08-05 22:02:19.533627251 +0200
  41968. @@ -0,0 +1,324 @@
  41969. +/*******************************************************************************
  41970. +Copyright (C) Marvell International Ltd. and its affiliates
  41971. +
  41972. +This software file (the "File") is owned and distributed by Marvell
  41973. +International Ltd. and/or its affiliates ("Marvell") under the following
  41974. +alternative licensing terms. Once you have made an election to distribute the
  41975. +File under one of the following license alternatives, please (i) delete this
  41976. +introductory statement regarding license alternatives, (ii) delete the two
  41977. +license alternatives that you have not elected to use and (iii) preserve the
  41978. +Marvell copyright notice above.
  41979. +
  41980. +********************************************************************************
  41981. +Marvell Commercial License Option
  41982. +
  41983. +If you received this File from Marvell and you have entered into a commercial
  41984. +license agreement (a "Commercial License") with Marvell, the File is licensed
  41985. +to you under the terms of the applicable Commercial License.
  41986. +
  41987. +********************************************************************************
  41988. +Marvell GPL License Option
  41989. +
  41990. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41991. +modify this File in accordance with the terms and conditions of the General
  41992. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  41993. +available along with the File in the license.txt file or by writing to the Free
  41994. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  41995. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  41996. +
  41997. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  41998. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  41999. +DISCLAIMED. The GPL License provides additional details about this warranty
  42000. +disclaimer.
  42001. +********************************************************************************
  42002. +Marvell BSD License Option
  42003. +
  42004. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42005. +modify this File under the following licensing terms.
  42006. +Redistribution and use in source and binary forms, with or without modification,
  42007. +are permitted provided that the following conditions are met:
  42008. +
  42009. + * Redistributions of source code must retain the above copyright notice,
  42010. + this list of conditions and the following disclaimer.
  42011. +
  42012. + * Redistributions in binary form must reproduce the above copyright
  42013. + notice, this list of conditions and the following disclaimer in the
  42014. + documentation and/or other materials provided with the distribution.
  42015. +
  42016. + * Neither the name of Marvell nor the names of its contributors may be
  42017. + used to endorse or promote products derived from this software without
  42018. + specific prior written permission.
  42019. +
  42020. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  42021. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  42022. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  42023. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  42024. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  42025. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42026. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  42027. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42028. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  42029. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42030. +
  42031. +*******************************************************************************/
  42032. +#include "mvSysAudio.h"
  42033. +
  42034. +/*******************************************************************************
  42035. +* mvAudioWinSet - Set AUDIO target address window
  42036. +*
  42037. +* DESCRIPTION:
  42038. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  42039. +* address window, also known as address decode window.
  42040. +* After setting this target window, the AUDIO will be able to access the
  42041. +* target within the address window.
  42042. +*
  42043. +* INPUT:
  42044. +* winNum - AUDIO target address decode window number.
  42045. +* pAddrDecWin - AUDIO target window data structure.
  42046. +*
  42047. +* OUTPUT:
  42048. +* None.
  42049. +*
  42050. +* RETURN:
  42051. +* MV_ERROR if address window overlapps with other address decode windows.
  42052. +* MV_BAD_PARAM if base address is invalid parameter or target is
  42053. +* unknown.
  42054. +*
  42055. +*******************************************************************************/
  42056. +MV_STATUS mvAudioWinSet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin)
  42057. +{
  42058. + MV_TARGET_ATTRIB targetAttribs;
  42059. + MV_DEC_REGS decRegs;
  42060. +
  42061. + /* Parameter checking */
  42062. + if (winNum >= MV_AUDIO_MAX_ADDR_DECODE_WIN)
  42063. + {
  42064. + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
  42065. + return MV_BAD_PARAM;
  42066. + }
  42067. +
  42068. + /* check if address is aligned to the size */
  42069. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  42070. + {
  42071. + mvOsPrintf("mvAudioWinSet:Error setting AUDIO window %d to "\
  42072. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  42073. + winNum,
  42074. + mvCtrlTargetNameGet(pAddrDecWin->target),
  42075. + pAddrDecWin->addrWin.baseLow,
  42076. + pAddrDecWin->addrWin.size);
  42077. + return MV_ERROR;
  42078. + }
  42079. +
  42080. + decRegs.baseReg = 0;
  42081. + decRegs.sizeReg = 0;
  42082. +
  42083. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  42084. + {
  42085. + mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
  42086. + return MV_ERROR;
  42087. + }
  42088. +
  42089. + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
  42090. +
  42091. + /* set attributes */
  42092. + decRegs.sizeReg &= ~MV_AUDIO_WIN_ATTR_MASK;
  42093. + decRegs.sizeReg |= (targetAttribs.attrib << MV_AUDIO_WIN_ATTR_OFFSET);
  42094. +
  42095. + /* set target ID */
  42096. + decRegs.sizeReg &= ~MV_AUDIO_WIN_TARGET_MASK;
  42097. + decRegs.sizeReg |= (targetAttribs.targetId << MV_AUDIO_WIN_TARGET_OFFSET);
  42098. +
  42099. + if (pAddrDecWin->enable == MV_TRUE)
  42100. + {
  42101. + decRegs.sizeReg |= MV_AUDIO_WIN_ENABLE_MASK;
  42102. + }
  42103. + else
  42104. + {
  42105. + decRegs.sizeReg &= ~MV_AUDIO_WIN_ENABLE_MASK;
  42106. + }
  42107. +
  42108. + MV_REG_WRITE( MV_AUDIO_WIN_CTRL_REG(winNum), decRegs.sizeReg);
  42109. + MV_REG_WRITE( MV_AUDIO_WIN_BASE_REG(winNum), decRegs.baseReg);
  42110. +
  42111. + return MV_OK;
  42112. +}
  42113. +
  42114. +/*******************************************************************************
  42115. +* mvAudioWinGet - Get AUDIO peripheral target address window.
  42116. +*
  42117. +* DESCRIPTION:
  42118. +* Get AUDIO peripheral target address window.
  42119. +*
  42120. +* INPUT:
  42121. +* winNum - AUDIO target address decode window number.
  42122. +*
  42123. +* OUTPUT:
  42124. +* pAddrDecWin - AUDIO target window data structure.
  42125. +*
  42126. +* RETURN:
  42127. +* MV_ERROR if register parameters are invalid.
  42128. +*
  42129. +*******************************************************************************/
  42130. +MV_STATUS mvAudioWinGet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin)
  42131. +{
  42132. + MV_DEC_REGS decRegs;
  42133. + MV_TARGET_ATTRIB targetAttrib;
  42134. +
  42135. + /* Parameter checking */
  42136. + if (winNum >= MV_AUDIO_MAX_ADDR_DECODE_WIN)
  42137. + {
  42138. + mvOsPrintf("%s : ERR. Invalid winNum %d\n",
  42139. + __FUNCTION__, winNum);
  42140. + return MV_NOT_SUPPORTED;
  42141. + }
  42142. +
  42143. + decRegs.baseReg = MV_REG_READ( MV_AUDIO_WIN_BASE_REG(winNum) );
  42144. + decRegs.sizeReg = MV_REG_READ( MV_AUDIO_WIN_CTRL_REG(winNum) );
  42145. +
  42146. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
  42147. + {
  42148. + mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
  42149. + return MV_ERROR;
  42150. + }
  42151. +
  42152. + /* attrib and targetId */
  42153. + targetAttrib.attrib = (decRegs.sizeReg & MV_AUDIO_WIN_ATTR_MASK) >>
  42154. + MV_AUDIO_WIN_ATTR_OFFSET;
  42155. + targetAttrib.targetId = (decRegs.sizeReg & MV_AUDIO_WIN_TARGET_MASK) >>
  42156. + MV_AUDIO_WIN_TARGET_OFFSET;
  42157. +
  42158. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  42159. +
  42160. + /* Check if window is enabled */
  42161. + if(decRegs.sizeReg & MV_AUDIO_WIN_ENABLE_MASK)
  42162. + {
  42163. + pAddrDecWin->enable = MV_TRUE;
  42164. + }
  42165. + else
  42166. + {
  42167. + pAddrDecWin->enable = MV_FALSE;
  42168. + }
  42169. + return MV_OK;
  42170. +}
  42171. +/*******************************************************************************
  42172. +* mvAudioAddrDecShow - Print the AUDIO address decode map.
  42173. +*
  42174. +* DESCRIPTION:
  42175. +* This function print the AUDIO address decode map.
  42176. +*
  42177. +* INPUT:
  42178. +* None.
  42179. +*
  42180. +* OUTPUT:
  42181. +* None.
  42182. +*
  42183. +* RETURN:
  42184. +* None.
  42185. +*
  42186. +*******************************************************************************/
  42187. +MV_VOID mvAudioAddrDecShow(MV_VOID)
  42188. +{
  42189. +
  42190. + MV_AUDIO_DEC_WIN win;
  42191. + int i;
  42192. +
  42193. + if (MV_FALSE == mvCtrlPwrClckGet(AUDIO_UNIT_ID, 0))
  42194. + return;
  42195. +
  42196. +
  42197. + mvOsOutput( "\n" );
  42198. + mvOsOutput( "AUDIO:\n" );
  42199. + mvOsOutput( "----\n" );
  42200. +
  42201. + for( i = 0; i < MV_AUDIO_MAX_ADDR_DECODE_WIN; i++ )
  42202. + {
  42203. + memset( &win, 0, sizeof(MV_AUDIO_DEC_WIN) );
  42204. +
  42205. + mvOsOutput( "win%d - ", i );
  42206. +
  42207. + if( mvAudioWinGet( i, &win ) == MV_OK )
  42208. + {
  42209. + if( win.enable )
  42210. + {
  42211. + mvOsOutput( "%s base %08x, ",
  42212. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  42213. + mvOsOutput( "...." );
  42214. +
  42215. + mvSizePrint( win.addrWin.size );
  42216. +
  42217. + mvOsOutput( "\n" );
  42218. + }
  42219. + else
  42220. + mvOsOutput( "disable\n" );
  42221. + }
  42222. + }
  42223. +}
  42224. +
  42225. +
  42226. +/*******************************************************************************
  42227. +* mvAudioWinInit - Initialize the integrated AUDIO target address window.
  42228. +*
  42229. +* DESCRIPTION:
  42230. +* Initialize the AUDIO peripheral target address window.
  42231. +*
  42232. +* INPUT:
  42233. +*
  42234. +*
  42235. +* OUTPUT:
  42236. +*
  42237. +*
  42238. +* RETURN:
  42239. +* MV_ERROR if register parameters are invalid.
  42240. +*
  42241. +*******************************************************************************/
  42242. +MV_STATUS mvAudioInit(MV_VOID)
  42243. +{
  42244. + int winNum;
  42245. + MV_AUDIO_DEC_WIN audioWin;
  42246. + MV_CPU_DEC_WIN cpuAddrDecWin;
  42247. + MV_U32 status;
  42248. +
  42249. + mvAudioHalInit();
  42250. +
  42251. + /* Initiate Audio address decode */
  42252. +
  42253. + /* First disable all address decode windows */
  42254. + for(winNum = 0; winNum < MV_AUDIO_MAX_ADDR_DECODE_WIN; winNum++)
  42255. + {
  42256. + MV_U32 regVal = MV_REG_READ(MV_AUDIO_WIN_CTRL_REG(winNum));
  42257. + regVal &= ~MV_AUDIO_WIN_ENABLE_MASK;
  42258. + MV_REG_WRITE(MV_AUDIO_WIN_CTRL_REG(winNum), regVal);
  42259. + }
  42260. +
  42261. + for(winNum = 0; winNum < MV_AUDIO_MAX_ADDR_DECODE_WIN; winNum++)
  42262. + {
  42263. +
  42264. + /* We will set the Window to DRAM_CS0 in default */
  42265. + /* first get attributes from CPU If */
  42266. + status = mvCpuIfTargetWinGet(SDRAM_CS0,
  42267. + &cpuAddrDecWin);
  42268. +
  42269. + if (MV_OK != status)
  42270. + {
  42271. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  42272. + return MV_ERROR;
  42273. + }
  42274. +
  42275. + if (cpuAddrDecWin.enable == MV_TRUE)
  42276. + {
  42277. + audioWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  42278. + audioWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  42279. + audioWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  42280. + audioWin.enable = MV_TRUE;
  42281. + audioWin.target = SDRAM_CS0;
  42282. +
  42283. + if(MV_OK != mvAudioWinSet(winNum, &audioWin))
  42284. + {
  42285. + return MV_ERROR;
  42286. + }
  42287. + }
  42288. + }
  42289. +
  42290. + return MV_OK;
  42291. +}
  42292. +
  42293. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h
  42294. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h 1970-01-01 01:00:00.000000000 +0100
  42295. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h 2010-08-05 22:02:19.743618673 +0200
  42296. @@ -0,0 +1,123 @@
  42297. +/*******************************************************************************
  42298. +Copyright (C) Marvell International Ltd. and its affiliates
  42299. +
  42300. +This software file (the "File") is owned and distributed by Marvell
  42301. +International Ltd. and/or its affiliates ("Marvell") under the following
  42302. +alternative licensing terms. Once you have made an election to distribute the
  42303. +File under one of the following license alternatives, please (i) delete this
  42304. +introductory statement regarding license alternatives, (ii) delete the two
  42305. +license alternatives that you have not elected to use and (iii) preserve the
  42306. +Marvell copyright notice above.
  42307. +
  42308. +********************************************************************************
  42309. +Marvell Commercial License Option
  42310. +
  42311. +If you received this File from Marvell and you have entered into a commercial
  42312. +license agreement (a "Commercial License") with Marvell, the File is licensed
  42313. +to you under the terms of the applicable Commercial License.
  42314. +
  42315. +********************************************************************************
  42316. +Marvell GPL License Option
  42317. +
  42318. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42319. +modify this File in accordance with the terms and conditions of the General
  42320. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  42321. +available along with the File in the license.txt file or by writing to the Free
  42322. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  42323. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  42324. +
  42325. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  42326. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  42327. +DISCLAIMED. The GPL License provides additional details about this warranty
  42328. +disclaimer.
  42329. +********************************************************************************
  42330. +Marvell BSD License Option
  42331. +
  42332. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42333. +modify this File under the following licensing terms.
  42334. +Redistribution and use in source and binary forms, with or without modification,
  42335. +are permitted provided that the following conditions are met:
  42336. +
  42337. + * Redistributions of source code must retain the above copyright notice,
  42338. + this list of conditions and the following disclaimer.
  42339. +
  42340. + * Redistributions in binary form must reproduce the above copyright
  42341. + notice, this list of conditions and the following disclaimer in the
  42342. + documentation and/or other materials provided with the distribution.
  42343. +
  42344. + * Neither the name of Marvell nor the names of its contributors may be
  42345. + used to endorse or promote products derived from this software without
  42346. + specific prior written permission.
  42347. +
  42348. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  42349. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  42350. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  42351. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  42352. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  42353. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42354. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  42355. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42356. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  42357. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42358. +
  42359. +*******************************************************************************/
  42360. +#ifndef __INCMVSysAudioH
  42361. +#define __INCMVSysAudioH
  42362. +
  42363. +#include "mvCommon.h"
  42364. +#include "audio/mvAudio.h"
  42365. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  42366. +#include "ctrlEnv/sys/mvCpuIf.h"
  42367. +
  42368. +/***********************************/
  42369. +/* Audio Address Decoding registers*/
  42370. +/***********************************/
  42371. +
  42372. +#define MV_AUDIO_MAX_ADDR_DECODE_WIN 2
  42373. +#define MV_AUDIO_RECORD_WIN_NUM 0
  42374. +#define MV_AUDIO_PLAYBACK_WIN_NUM 1
  42375. +
  42376. +#define MV_AUDIO_WIN_CTRL_REG(win) (AUDIO_REG_BASE + 0xA04 + ((win)<<3))
  42377. +#define MV_AUDIO_WIN_BASE_REG(win) (AUDIO_REG_BASE + 0xA00 + ((win)<<3))
  42378. +
  42379. +#define MV_AUDIO_RECORD_WIN_CTRL_REG MV_AUDIO_WIN_CTRL_REG(MV_AUDIO_RECORD_WIN_NUM)
  42380. +#define MV_AUDIO_RECORD_WIN_BASE_REG MV_AUDIO_WIN_BASE_REG(MV_AUDIO_RECORD_WIN_NUM)
  42381. +#define MV_AUDIO_PLAYBACK_WIN_CTRL_REG MV_AUDIO_WIN_CTRL_REG(MV_AUDIO_PLAYBACK_WIN_NUM)
  42382. +#define MV_AUDIO_PLAYBACK_WIN_BASE_REG MV_AUDIO_WIN_BASE_REG(MV_AUDIO_PLAYBACK_WIN_NUM)
  42383. +
  42384. +
  42385. +/* BITs in Windows 0-3 Control and Base Registers */
  42386. +#define MV_AUDIO_WIN_ENABLE_BIT 0
  42387. +#define MV_AUDIO_WIN_ENABLE_MASK (1<<MV_AUDIO_WIN_ENABLE_BIT)
  42388. +
  42389. +#define MV_AUDIO_WIN_TARGET_OFFSET 4
  42390. +#define MV_AUDIO_WIN_TARGET_MASK (0xF<<MV_AUDIO_WIN_TARGET_OFFSET)
  42391. +
  42392. +#define MV_AUDIO_WIN_ATTR_OFFSET 8
  42393. +#define MV_AUDIO_WIN_ATTR_MASK (0xFF<<MV_AUDIO_WIN_ATTR_OFFSET)
  42394. +
  42395. +#define MV_AUDIO_WIN_SIZE_OFFSET 16
  42396. +#define MV_AUDIO_WIN_SIZE_MASK (0xFFFF<<MV_AUDIO_WIN_SIZE_OFFSET)
  42397. +
  42398. +#define MV_AUDIO_WIN_BASE_OFFSET 16
  42399. +#define MV_AUDIO_WIN_BASE_MASK (0xFFFF<<MV_AUDIO_WIN_BASE_OFFSET)
  42400. +
  42401. +
  42402. +typedef struct _mvAudioDecWin
  42403. +{
  42404. + MV_TARGET target;
  42405. + MV_ADDR_WIN addrWin; /* An address window*/
  42406. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  42407. +
  42408. +} MV_AUDIO_DEC_WIN;
  42409. +
  42410. +
  42411. +MV_STATUS mvAudioInit(MV_VOID);
  42412. +MV_STATUS mvAudioWinGet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin);
  42413. +MV_STATUS mvAudioWinSet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin);
  42414. +MV_STATUS mvAudioWinInit(MV_VOID);
  42415. +MV_VOID mvAudioAddrDecShow(MV_VOID);
  42416. +
  42417. +
  42418. +#endif
  42419. +
  42420. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c
  42421. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c 1970-01-01 01:00:00.000000000 +0100
  42422. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c 2010-08-05 22:02:19.963622969 +0200
  42423. @@ -0,0 +1,382 @@
  42424. +/*******************************************************************************
  42425. +Copyright (C) Marvell International Ltd. and its affiliates
  42426. +
  42427. +This software file (the "File") is owned and distributed by Marvell
  42428. +International Ltd. and/or its affiliates ("Marvell") under the following
  42429. +alternative licensing terms. Once you have made an election to distribute the
  42430. +File under one of the following license alternatives, please (i) delete this
  42431. +introductory statement regarding license alternatives, (ii) delete the two
  42432. +license alternatives that you have not elected to use and (iii) preserve the
  42433. +Marvell copyright notice above.
  42434. +
  42435. +********************************************************************************
  42436. +Marvell Commercial License Option
  42437. +
  42438. +If you received this File from Marvell and you have entered into a commercial
  42439. +license agreement (a "Commercial License") with Marvell, the File is licensed
  42440. +to you under the terms of the applicable Commercial License.
  42441. +
  42442. +********************************************************************************
  42443. +Marvell GPL License Option
  42444. +
  42445. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42446. +modify this File in accordance with the terms and conditions of the General
  42447. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  42448. +available along with the File in the license.txt file or by writing to the Free
  42449. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  42450. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  42451. +
  42452. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  42453. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  42454. +DISCLAIMED. The GPL License provides additional details about this warranty
  42455. +disclaimer.
  42456. +********************************************************************************
  42457. +Marvell BSD License Option
  42458. +
  42459. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42460. +modify this File under the following licensing terms.
  42461. +Redistribution and use in source and binary forms, with or without modification,
  42462. +are permitted provided that the following conditions are met:
  42463. +
  42464. + * Redistributions of source code must retain the above copyright notice,
  42465. + this list of conditions and the following disclaimer.
  42466. +
  42467. + * Redistributions in binary form must reproduce the above copyright
  42468. + notice, this list of conditions and the following disclaimer in the
  42469. + documentation and/or other materials provided with the distribution.
  42470. +
  42471. + * Neither the name of Marvell nor the names of its contributors may be
  42472. + used to endorse or promote products derived from this software without
  42473. + specific prior written permission.
  42474. +
  42475. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  42476. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  42477. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  42478. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  42479. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  42480. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42481. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  42482. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42483. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  42484. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42485. +
  42486. +*******************************************************************************/
  42487. +
  42488. +#include "mvSysCesa.h"
  42489. +
  42490. +#if (MV_CESA_VERSION >= 2)
  42491. +MV_TARGET tdmaAddrDecPrioTable[] =
  42492. +{
  42493. +#if defined(MV_INCLUDE_SDRAM_CS0)
  42494. + SDRAM_CS0,
  42495. +#endif
  42496. +#if defined(MV_INCLUDE_SDRAM_CS1)
  42497. + SDRAM_CS1,
  42498. +#endif
  42499. +#if defined(MV_INCLUDE_SDRAM_CS2)
  42500. + SDRAM_CS2,
  42501. +#endif
  42502. +#if defined(MV_INCLUDE_SDRAM_CS3)
  42503. + SDRAM_CS3,
  42504. +#endif
  42505. +#if defined(MV_INCLUDE_PEX)
  42506. + PEX0_MEM,
  42507. +#endif
  42508. +
  42509. + TBL_TERM
  42510. +};
  42511. +
  42512. +/*******************************************************************************
  42513. +* mvCesaWinGet - Get TDMA target address window.
  42514. +*
  42515. +* DESCRIPTION:
  42516. +* Get TDMA target address window.
  42517. +*
  42518. +* INPUT:
  42519. +* winNum - TDMA target address decode window number.
  42520. +*
  42521. +* OUTPUT:
  42522. +* pDecWin - TDMA target window data structure.
  42523. +*
  42524. +* RETURN:
  42525. +* MV_ERROR if register parameters are invalid.
  42526. +*
  42527. +*******************************************************************************/
  42528. +static MV_STATUS mvCesaWinGet(MV_U32 winNum, MV_DEC_WIN *pDecWin)
  42529. +{
  42530. + MV_DEC_WIN_PARAMS winParam;
  42531. + MV_U32 sizeReg, baseReg;
  42532. +
  42533. + /* Parameter checking */
  42534. + if (winNum >= MV_CESA_TDMA_ADDR_DEC_WIN)
  42535. + {
  42536. + mvOsPrintf("%s : ERR. Invalid winNum %d\n",
  42537. + __FUNCTION__, winNum);
  42538. + return MV_NOT_SUPPORTED;
  42539. + }
  42540. +
  42541. + baseReg = MV_REG_READ( MV_CESA_TDMA_BASE_ADDR_REG(winNum) );
  42542. + sizeReg = MV_REG_READ( MV_CESA_TDMA_WIN_CTRL_REG(winNum) );
  42543. +
  42544. + /* Check if window is enabled */
  42545. + if(sizeReg & MV_CESA_TDMA_WIN_ENABLE_MASK)
  42546. + {
  42547. + pDecWin->enable = MV_TRUE;
  42548. +
  42549. + /* Extract window parameters from registers */
  42550. + winParam.targetId = (sizeReg & MV_CESA_TDMA_WIN_TARGET_MASK) >> MV_CESA_TDMA_WIN_TARGET_OFFSET;
  42551. + winParam.attrib = (sizeReg & MV_CESA_TDMA_WIN_ATTR_MASK) >> MV_CESA_TDMA_WIN_ATTR_OFFSET;
  42552. + winParam.size = (sizeReg & MV_CESA_TDMA_WIN_SIZE_MASK) >> MV_CESA_TDMA_WIN_SIZE_OFFSET;
  42553. + winParam.baseAddr = (baseReg & MV_CESA_TDMA_WIN_BASE_MASK);
  42554. +
  42555. + /* Translate the decode window parameters to address decode struct */
  42556. + if (MV_OK != mvCtrlParamsToAddrDec(&winParam, pDecWin))
  42557. + {
  42558. + mvOsPrintf("Failed to translate register parameters to CESA address" \
  42559. + " decode window structure\n");
  42560. + return MV_ERROR;
  42561. + }
  42562. + }
  42563. + else
  42564. + {
  42565. + pDecWin->enable = MV_FALSE;
  42566. + }
  42567. + return MV_OK;
  42568. +}
  42569. +
  42570. +/*******************************************************************************
  42571. +* cesaWinOverlapDetect - Detect CESA TDMA address windows overlapping
  42572. +*
  42573. +* DESCRIPTION:
  42574. +* An unpredicted behaviur is expected in case TDMA address decode
  42575. +* windows overlapps.
  42576. +* This function detects TDMA address decode windows overlapping of a
  42577. +* specified window. The function does not check the window itself for
  42578. +* overlapping. The function also skipps disabled address decode windows.
  42579. +*
  42580. +* INPUT:
  42581. +* winNum - address decode window number.
  42582. +* pAddrDecWin - An address decode window struct.
  42583. +*
  42584. +* OUTPUT:
  42585. +* None.
  42586. +*
  42587. +* RETURN:
  42588. +* MV_TRUE - if the given address window overlap current address
  42589. +* decode map,
  42590. +* MV_FALSE - otherwise, MV_ERROR if reading invalid data
  42591. +* from registers.
  42592. +*
  42593. +*******************************************************************************/
  42594. +static MV_STATUS cesaWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  42595. +{
  42596. + MV_U32 winNumIndex;
  42597. + MV_DEC_WIN addrDecWin;
  42598. +
  42599. + for(winNumIndex=0; winNumIndex<MV_CESA_TDMA_ADDR_DEC_WIN; winNumIndex++)
  42600. + {
  42601. + /* Do not check window itself */
  42602. + if (winNumIndex == winNum)
  42603. + {
  42604. + continue;
  42605. + }
  42606. +
  42607. + /* Get window parameters */
  42608. + if (MV_OK != mvCesaWinGet(winNumIndex, &addrDecWin))
  42609. + {
  42610. + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
  42611. + return MV_ERROR;
  42612. + }
  42613. +
  42614. + /* Do not check disabled windows */
  42615. + if(addrDecWin.enable == MV_FALSE)
  42616. + {
  42617. + continue;
  42618. + }
  42619. +
  42620. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  42621. + {
  42622. + return MV_TRUE;
  42623. + }
  42624. + }
  42625. + return MV_FALSE;
  42626. +}
  42627. +
  42628. +/*******************************************************************************
  42629. +* mvCesaTdmaWinSet - Set CESA TDMA target address window
  42630. +*
  42631. +* DESCRIPTION:
  42632. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  42633. +* address window, also known as address decode window.
  42634. +* After setting this target window, the CESA TDMA will be able to access the
  42635. +* target within the address window.
  42636. +*
  42637. +* INPUT:
  42638. +* winNum - CESA TDMA target address decode window number.
  42639. +* pAddrDecWin - CESA TDMA target window data structure.
  42640. +*
  42641. +* OUTPUT:
  42642. +* None.
  42643. +*
  42644. +* RETURN:
  42645. +* MV_ERROR - if address window overlapps with other address decode windows.
  42646. +* MV_BAD_PARAM - if base address is invalid parameter or target is
  42647. +* unknown.
  42648. +*
  42649. +*******************************************************************************/
  42650. +static MV_STATUS mvCesaTdmaWinSet(MV_U32 winNum, MV_DEC_WIN *pDecWin)
  42651. +{
  42652. + MV_DEC_WIN_PARAMS winParams;
  42653. + MV_U32 sizeReg, baseReg;
  42654. +
  42655. + /* Parameter checking */
  42656. + if (winNum >= MV_CESA_TDMA_ADDR_DEC_WIN)
  42657. + {
  42658. + mvOsPrintf("mvCesaTdmaWinSet: ERR. Invalid win num %d\n",winNum);
  42659. + return MV_BAD_PARAM;
  42660. + }
  42661. +
  42662. + /* Check if the requested window overlapps with current windows */
  42663. + if (MV_TRUE == cesaWinOverlapDetect(winNum, &pDecWin->addrWin))
  42664. + {
  42665. + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
  42666. + return MV_ERROR;
  42667. + }
  42668. +
  42669. + /* check if address is aligned to the size */
  42670. + if(MV_IS_NOT_ALIGN(pDecWin->addrWin.baseLow, pDecWin->addrWin.size))
  42671. + {
  42672. + mvOsPrintf("mvCesaTdmaWinSet: Error setting CESA TDMA window %d to "\
  42673. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  42674. + winNum,
  42675. + mvCtrlTargetNameGet(pDecWin->target),
  42676. + pDecWin->addrWin.baseLow,
  42677. + pDecWin->addrWin.size);
  42678. + return MV_ERROR;
  42679. + }
  42680. +
  42681. + if(MV_OK != mvCtrlAddrDecToParams(pDecWin, &winParams))
  42682. + {
  42683. + mvOsPrintf("%s: mvCtrlAddrDecToParams Failed\n", __FUNCTION__);
  42684. + return MV_ERROR;
  42685. + }
  42686. +
  42687. + /* set Size, Attributes and TargetID */
  42688. + sizeReg = (((winParams.targetId << MV_CESA_TDMA_WIN_TARGET_OFFSET) & MV_CESA_TDMA_WIN_TARGET_MASK) |
  42689. + ((winParams.attrib << MV_CESA_TDMA_WIN_ATTR_OFFSET) & MV_CESA_TDMA_WIN_ATTR_MASK) |
  42690. + ((winParams.size << MV_CESA_TDMA_WIN_SIZE_OFFSET) & MV_CESA_TDMA_WIN_SIZE_MASK));
  42691. +
  42692. + if (pDecWin->enable == MV_TRUE)
  42693. + {
  42694. + sizeReg |= MV_CESA_TDMA_WIN_ENABLE_MASK;
  42695. + }
  42696. + else
  42697. + {
  42698. + sizeReg &= ~MV_CESA_TDMA_WIN_ENABLE_MASK;
  42699. + }
  42700. +
  42701. + /* Update Base value */
  42702. + baseReg = (winParams.baseAddr & MV_CESA_TDMA_WIN_BASE_MASK);
  42703. +
  42704. + MV_REG_WRITE( MV_CESA_TDMA_WIN_CTRL_REG(winNum), sizeReg);
  42705. + MV_REG_WRITE( MV_CESA_TDMA_BASE_ADDR_REG(winNum), baseReg);
  42706. +
  42707. + return MV_OK;
  42708. +}
  42709. +
  42710. +
  42711. +static MV_STATUS mvCesaTdmaAddrDecInit (void)
  42712. +{
  42713. + MV_U32 winNum;
  42714. + MV_STATUS status;
  42715. + MV_CPU_DEC_WIN cpuAddrDecWin;
  42716. + MV_DEC_WIN cesaWin;
  42717. + MV_U32 winPrioIndex = 0;
  42718. +
  42719. + /* First disable all address decode windows */
  42720. + for(winNum=0; winNum<MV_CESA_TDMA_ADDR_DEC_WIN; winNum++)
  42721. + {
  42722. + MV_REG_BIT_RESET(MV_CESA_TDMA_WIN_CTRL_REG(winNum), MV_CESA_TDMA_WIN_ENABLE_MASK);
  42723. + }
  42724. +
  42725. + /* Go through all windows in user table until table terminator */
  42726. + winNum = 0;
  42727. + while( (tdmaAddrDecPrioTable[winPrioIndex] != TBL_TERM) &&
  42728. + (winNum < MV_CESA_TDMA_ADDR_DEC_WIN) ) {
  42729. +
  42730. + /* first get attributes from CPU If */
  42731. + status = mvCpuIfTargetWinGet(tdmaAddrDecPrioTable[winPrioIndex],
  42732. + &cpuAddrDecWin);
  42733. + if(MV_NO_SUCH == status){
  42734. + winPrioIndex++;
  42735. + continue;
  42736. + }
  42737. +
  42738. + if (MV_OK != status)
  42739. + {
  42740. + mvOsPrintf("cesaInit: TargetWinGet failed. winNum=%d, winIdx=%d, target=%d, status=0x%x\n",
  42741. + winNum, winPrioIndex, tdmaAddrDecPrioTable[winPrioIndex], status);
  42742. + return MV_ERROR;
  42743. + }
  42744. + if (cpuAddrDecWin.enable == MV_TRUE)
  42745. + {
  42746. + cesaWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  42747. + cesaWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  42748. + cesaWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  42749. + cesaWin.enable = MV_TRUE;
  42750. + cesaWin.target = tdmaAddrDecPrioTable[winPrioIndex];
  42751. +
  42752. +#if defined(MV646xx)
  42753. + /* Get the default attributes for that target window */
  42754. + mvCtrlDefAttribGet(cesaWin.target, &cesaWin.addrWinAttr);
  42755. +#endif /* MV646xx */
  42756. +
  42757. + if(MV_OK != mvCesaTdmaWinSet(winNum, &cesaWin))
  42758. + {
  42759. + mvOsPrintf("mvCesaTdmaWinSet FAILED: winNum=%d\n",
  42760. + winNum);
  42761. + return MV_ERROR;
  42762. + }
  42763. + winNum++;
  42764. + }
  42765. + winPrioIndex++;
  42766. + }
  42767. + return MV_OK;
  42768. +}
  42769. +#endif /* MV_CESA_VERSION >= 2 */
  42770. +
  42771. +
  42772. +
  42773. +
  42774. +MV_STATUS mvCesaInit (int numOfSession, int queueDepth, char* pSramBase, void *osHandle)
  42775. +{
  42776. + MV_U32 cesaCryptEngBase;
  42777. + MV_CPU_DEC_WIN addrDecWin;
  42778. +
  42779. + if(sizeof(MV_CESA_SRAM_MAP) > MV_CESA_SRAM_SIZE)
  42780. + {
  42781. + mvOsPrintf("mvCesaInit: Wrong SRAM map - %ld > %d\n",
  42782. + sizeof(MV_CESA_SRAM_MAP), MV_CESA_SRAM_SIZE);
  42783. + return MV_FAIL;
  42784. + }
  42785. +#if 0
  42786. + if (mvCpuIfTargetWinGet(CRYPT_ENG, &addrDecWin) == MV_OK)
  42787. + cesaCryptEngBase = addrDecWin.addrWin.baseLow;
  42788. + else
  42789. + {
  42790. + mvOsPrintf("mvCesaInit: ERR. mvCpuIfTargetWinGet failed\n");
  42791. + return MV_ERROR;
  42792. + }
  42793. +#else
  42794. + cesaCryptEngBase = (MV_U32)pSramBase;
  42795. +#endif
  42796. +
  42797. +#if 0 /* Already done in the platform init */
  42798. +#if (MV_CESA_VERSION >= 2)
  42799. + mvCesaTdmaAddrDecInit();
  42800. +#endif /* MV_CESA_VERSION >= 2 */
  42801. +#endif
  42802. + return mvCesaHalInit(numOfSession, queueDepth, pSramBase, cesaCryptEngBase,
  42803. + osHandle);
  42804. +
  42805. +}
  42806. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h
  42807. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h 1970-01-01 01:00:00.000000000 +0100
  42808. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h 2010-08-05 22:02:20.254042081 +0200
  42809. @@ -0,0 +1,100 @@
  42810. +/*******************************************************************************
  42811. +Copyright (C) Marvell International Ltd. and its affiliates
  42812. +
  42813. +This software file (the "File") is owned and distributed by Marvell
  42814. +International Ltd. and/or its affiliates ("Marvell") under the following
  42815. +alternative licensing terms. Once you have made an election to distribute the
  42816. +File under one of the following license alternatives, please (i) delete this
  42817. +introductory statement regarding license alternatives, (ii) delete the two
  42818. +license alternatives that you have not elected to use and (iii) preserve the
  42819. +Marvell copyright notice above.
  42820. +
  42821. +********************************************************************************
  42822. +Marvell Commercial License Option
  42823. +
  42824. +If you received this File from Marvell and you have entered into a commercial
  42825. +license agreement (a "Commercial License") with Marvell, the File is licensed
  42826. +to you under the terms of the applicable Commercial License.
  42827. +
  42828. +********************************************************************************
  42829. +Marvell GPL License Option
  42830. +
  42831. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42832. +modify this File in accordance with the terms and conditions of the General
  42833. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  42834. +available along with the File in the license.txt file or by writing to the Free
  42835. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  42836. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  42837. +
  42838. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  42839. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  42840. +DISCLAIMED. The GPL License provides additional details about this warranty
  42841. +disclaimer.
  42842. +********************************************************************************
  42843. +Marvell BSD License Option
  42844. +
  42845. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42846. +modify this File under the following licensing terms.
  42847. +Redistribution and use in source and binary forms, with or without modification,
  42848. +are permitted provided that the following conditions are met:
  42849. +
  42850. + * Redistributions of source code must retain the above copyright notice,
  42851. + this list of conditions and the following disclaimer.
  42852. +
  42853. + * Redistributions in binary form must reproduce the above copyright
  42854. + notice, this list of conditions and the following disclaimer in the
  42855. + documentation and/or other materials provided with the distribution.
  42856. +
  42857. + * Neither the name of Marvell nor the names of its contributors may be
  42858. + used to endorse or promote products derived from this software without
  42859. + specific prior written permission.
  42860. +
  42861. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  42862. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  42863. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  42864. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  42865. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  42866. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42867. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  42868. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42869. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  42870. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42871. +
  42872. +*******************************************************************************/
  42873. +
  42874. +#ifndef __mvSysCesa_h__
  42875. +#define __mvSysCesa_h__
  42876. +
  42877. +
  42878. +#include "mvCommon.h"
  42879. +#include "cesa/mvCesa.h"
  42880. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  42881. +#include "ctrlEnv/sys/mvCpuIf.h"
  42882. +
  42883. +/***************************** TDMA Registers *************************************/
  42884. +
  42885. +#define MV_CESA_TDMA_ADDR_DEC_WIN 4
  42886. +
  42887. +#define MV_CESA_TDMA_BASE_ADDR_REG(win) (MV_CESA_TDMA_REG_BASE + 0xa00 + (win<<3))
  42888. +
  42889. +#define MV_CESA_TDMA_WIN_CTRL_REG(win) (MV_CESA_TDMA_REG_BASE + 0xa04 + (win<<3))
  42890. +
  42891. +#define MV_CESA_TDMA_WIN_ENABLE_BIT 0
  42892. +#define MV_CESA_TDMA_WIN_ENABLE_MASK (1 << MV_CESA_TDMA_WIN_ENABLE_BIT)
  42893. +
  42894. +#define MV_CESA_TDMA_WIN_TARGET_OFFSET 4
  42895. +#define MV_CESA_TDMA_WIN_TARGET_MASK (0xf << MV_CESA_TDMA_WIN_TARGET_OFFSET)
  42896. +
  42897. +#define MV_CESA_TDMA_WIN_ATTR_OFFSET 8
  42898. +#define MV_CESA_TDMA_WIN_ATTR_MASK (0xff << MV_CESA_TDMA_WIN_ATTR_OFFSET)
  42899. +
  42900. +#define MV_CESA_TDMA_WIN_SIZE_OFFSET 16
  42901. +#define MV_CESA_TDMA_WIN_SIZE_MASK (0xFFFF << MV_CESA_TDMA_WIN_SIZE_OFFSET)
  42902. +
  42903. +#define MV_CESA_TDMA_WIN_BASE_OFFSET 16
  42904. +#define MV_CESA_TDMA_WIN_BASE_MASK (0xFFFF << MV_CESA_TDMA_WIN_BASE_OFFSET)
  42905. +
  42906. +
  42907. +MV_STATUS mvCesaInit (int numOfSession, int queueDepth, char* pSramBase, void *osHandle);
  42908. +
  42909. +#endif
  42910. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c
  42911. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c 1970-01-01 01:00:00.000000000 +0100
  42912. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c 2010-08-05 22:02:20.493619625 +0200
  42913. @@ -0,0 +1,348 @@
  42914. +/*******************************************************************************
  42915. +Copyright (C) Marvell International Ltd. and its affiliates
  42916. +
  42917. +This software file (the "File") is owned and distributed by Marvell
  42918. +International Ltd. and/or its affiliates ("Marvell") under the following
  42919. +alternative licensing terms. Once you have made an election to distribute the
  42920. +File under one of the following license alternatives, please (i) delete this
  42921. +introductory statement regarding license alternatives, (ii) delete the two
  42922. +license alternatives that you have not elected to use and (iii) preserve the
  42923. +Marvell copyright notice above.
  42924. +
  42925. +********************************************************************************
  42926. +Marvell Commercial License Option
  42927. +
  42928. +If you received this File from Marvell and you have entered into a commercial
  42929. +license agreement (a "Commercial License") with Marvell, the File is licensed
  42930. +to you under the terms of the applicable Commercial License.
  42931. +
  42932. +********************************************************************************
  42933. +Marvell GPL License Option
  42934. +
  42935. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42936. +modify this File in accordance with the terms and conditions of the General
  42937. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  42938. +available along with the File in the license.txt file or by writing to the Free
  42939. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  42940. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  42941. +
  42942. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  42943. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  42944. +DISCLAIMED. The GPL License provides additional details about this warranty
  42945. +disclaimer.
  42946. +********************************************************************************
  42947. +Marvell BSD License Option
  42948. +
  42949. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42950. +modify this File under the following licensing terms.
  42951. +Redistribution and use in source and binary forms, with or without modification,
  42952. +are permitted provided that the following conditions are met:
  42953. +
  42954. + * Redistributions of source code must retain the above copyright notice,
  42955. + this list of conditions and the following disclaimer.
  42956. +
  42957. + * Redistributions in binary form must reproduce the above copyright
  42958. + notice, this list of conditions and the following disclaimer in the
  42959. + documentation and/or other materials provided with the distribution.
  42960. +
  42961. + * Neither the name of Marvell nor the names of its contributors may be
  42962. + used to endorse or promote products derived from this software without
  42963. + specific prior written permission.
  42964. +
  42965. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  42966. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  42967. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  42968. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  42969. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  42970. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42971. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  42972. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42973. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  42974. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42975. +
  42976. +*******************************************************************************/
  42977. +
  42978. +
  42979. +/* includes */
  42980. +
  42981. +#include "ddr2/mvDramIf.h"
  42982. +#include "ctrlEnv/sys/mvCpuIf.h"
  42983. +#include "ctrlEnv/sys/mvSysDram.h"
  42984. +
  42985. +/* #define MV_DEBUG */
  42986. +#ifdef MV_DEBUG
  42987. +#define DB(x) x
  42988. +#else
  42989. +#define DB(x)
  42990. +#endif
  42991. +
  42992. +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
  42993. +
  42994. +/*******************************************************************************
  42995. +* mvDramIfWinSet - Set DRAM interface address decode window
  42996. +*
  42997. +* DESCRIPTION:
  42998. +* This function sets DRAM interface address decode window.
  42999. +*
  43000. +* INPUT:
  43001. +* target - System target. Use only SDRAM targets.
  43002. +* pAddrDecWin - SDRAM address window structure.
  43003. +*
  43004. +* OUTPUT:
  43005. +* None
  43006. +*
  43007. +* RETURN:
  43008. +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
  43009. +* otherwise.
  43010. +*******************************************************************************/
  43011. +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
  43012. +{
  43013. + MV_U32 baseReg=0,sizeReg=0;
  43014. + MV_U32 baseToReg=0 , sizeToReg=0;
  43015. +
  43016. + /* Check parameters */
  43017. + if (!MV_TARGET_IS_DRAM(target))
  43018. + {
  43019. + mvOsPrintf("mvDramIfWinSet: target %d is not SDRAM\n", target);
  43020. + return MV_BAD_PARAM;
  43021. + }
  43022. +
  43023. + /* Check if the requested window overlaps with current enabled windows */
  43024. + if (MV_TRUE == sdramIfWinOverlap(target, &pAddrDecWin->addrWin))
  43025. + {
  43026. + mvOsPrintf("mvDramIfWinSet: ERR. Target %d overlaps\n", target);
  43027. + return MV_BAD_PARAM;
  43028. + }
  43029. +
  43030. + /* check if address is aligned to the size */
  43031. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  43032. + {
  43033. + mvOsPrintf("mvDramIfWinSet:Error setting DRAM interface window %d."\
  43034. + "\nAddress 0x%08x is unaligned to size 0x%x.\n",
  43035. + target,
  43036. + pAddrDecWin->addrWin.baseLow,
  43037. + pAddrDecWin->addrWin.size);
  43038. + return MV_ERROR;
  43039. + }
  43040. +
  43041. + /* read base register*/
  43042. + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(0,target));
  43043. +
  43044. + /* read size register */
  43045. + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(0,target));
  43046. +
  43047. + /* BaseLow[31:16] => base register [31:16] */
  43048. + baseToReg = pAddrDecWin->addrWin.baseLow & SCBAR_BASE_MASK;
  43049. +
  43050. + /* Write to address decode Base Address Register */
  43051. + baseReg &= ~SCBAR_BASE_MASK;
  43052. + baseReg |= baseToReg;
  43053. +
  43054. + /* Translate the given window size to register format */
  43055. + sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, SCSR_SIZE_ALIGNMENT);
  43056. +
  43057. + /* Size parameter validity check. */
  43058. + if (-1 == sizeToReg)
  43059. + {
  43060. + mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n",target);
  43061. + return MV_BAD_PARAM;
  43062. + }
  43063. +
  43064. + /* set size */
  43065. + sizeReg &= ~SCSR_SIZE_MASK;
  43066. + /* Size is located at upper 16 bits */
  43067. + sizeReg |= (sizeToReg << SCSR_SIZE_OFFS);
  43068. +
  43069. + /* enable/Disable */
  43070. + if (MV_TRUE == pAddrDecWin->enable)
  43071. + {
  43072. + sizeReg |= SCSR_WIN_EN;
  43073. + }
  43074. + else
  43075. + {
  43076. + sizeReg &= ~SCSR_WIN_EN;
  43077. + }
  43078. +
  43079. + /* 3) Write to address decode Base Address Register */
  43080. + MV_REG_WRITE(SDRAM_BASE_ADDR_REG(0,target), baseReg);
  43081. +
  43082. + /* Write to address decode Size Register */
  43083. + MV_REG_WRITE(SDRAM_SIZE_REG(0,target), sizeReg);
  43084. +
  43085. + return MV_OK;
  43086. +}
  43087. +/*******************************************************************************
  43088. +* mvDramIfWinGet - Get DRAM interface address decode window
  43089. +*
  43090. +* DESCRIPTION:
  43091. +* This function gets DRAM interface address decode window.
  43092. +*
  43093. +* INPUT:
  43094. +* target - System target. Use only SDRAM targets.
  43095. +*
  43096. +* OUTPUT:
  43097. +* pAddrDecWin - SDRAM address window structure.
  43098. +*
  43099. +* RETURN:
  43100. +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
  43101. +* otherwise.
  43102. +*******************************************************************************/
  43103. +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
  43104. +{
  43105. + MV_U32 baseReg,sizeReg;
  43106. + MV_U32 sizeRegVal;
  43107. + /* Check parameters */
  43108. + if (!MV_TARGET_IS_DRAM(target))
  43109. + {
  43110. + mvOsPrintf("mvDramIfWinGet: target %d is Illigal\n", target);
  43111. + return MV_ERROR;
  43112. + }
  43113. +
  43114. + /* Read base and size registers */
  43115. + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(0,target));
  43116. + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(0,target));
  43117. +
  43118. + sizeRegVal = (sizeReg & SCSR_SIZE_MASK) >> SCSR_SIZE_OFFS;
  43119. +
  43120. + pAddrDecWin->addrWin.size = ctrlRegToSize(sizeRegVal,
  43121. + SCSR_SIZE_ALIGNMENT);
  43122. +
  43123. + /* Check if ctrlRegToSize returned OK */
  43124. + if (-1 == pAddrDecWin->addrWin.size)
  43125. + {
  43126. + mvOsPrintf("mvDramIfWinGet: size of target %d is Illigal\n", target);
  43127. + return MV_ERROR;
  43128. + }
  43129. +
  43130. + /* Extract base address */
  43131. + /* Base register [31:16] ==> baseLow[31:16] */
  43132. + pAddrDecWin->addrWin.baseLow = baseReg & SCBAR_BASE_MASK;
  43133. +
  43134. + pAddrDecWin->addrWin.baseHigh = 0;
  43135. +
  43136. +
  43137. + if (sizeReg & SCSR_WIN_EN)
  43138. + {
  43139. + pAddrDecWin->enable = MV_TRUE;
  43140. + }
  43141. + else
  43142. + {
  43143. + pAddrDecWin->enable = MV_FALSE;
  43144. + }
  43145. +
  43146. + return MV_OK;
  43147. +}
  43148. +/*******************************************************************************
  43149. +* mvDramIfWinEnable - Enable/Disable SDRAM address decode window
  43150. +*
  43151. +* DESCRIPTION:
  43152. +* This function enable/Disable SDRAM address decode window.
  43153. +*
  43154. +* INPUT:
  43155. +* target - System target. Use only SDRAM targets.
  43156. +*
  43157. +* OUTPUT:
  43158. +* None.
  43159. +*
  43160. +* RETURN:
  43161. +* MV_ERROR in case function parameter are invalid, MV_OK otherewise.
  43162. +*
  43163. +*******************************************************************************/
  43164. +MV_STATUS mvDramIfWinEnable(MV_TARGET target, MV_BOOL enable)
  43165. +{
  43166. + MV_DRAM_DEC_WIN addrDecWin;
  43167. +
  43168. + /* Check parameters */
  43169. + if (!MV_TARGET_IS_DRAM(target))
  43170. + {
  43171. + mvOsPrintf("mvDramIfWinEnable: target %d is Illigal\n", target);
  43172. + return MV_ERROR;
  43173. + }
  43174. +
  43175. + if (enable == MV_TRUE)
  43176. + { /* First check for overlap with other enabled windows */
  43177. + if (MV_OK != mvDramIfWinGet(target, &addrDecWin))
  43178. + {
  43179. + mvOsPrintf("mvDramIfWinEnable:ERR. Getting target %d failed.\n",
  43180. + target);
  43181. + return MV_ERROR;
  43182. + }
  43183. + /* Check for overlapping */
  43184. + if (MV_FALSE == sdramIfWinOverlap(target, &(addrDecWin.addrWin)))
  43185. + {
  43186. + /* No Overlap. Enable address decode winNum window */
  43187. + MV_REG_BIT_SET(SDRAM_SIZE_REG(0,target), SCSR_WIN_EN);
  43188. + }
  43189. + else
  43190. + { /* Overlap detected */
  43191. + mvOsPrintf("mvDramIfWinEnable: ERR. Target %d overlap detect\n",
  43192. + target);
  43193. + return MV_ERROR;
  43194. + }
  43195. + }
  43196. + else
  43197. + { /* Disable address decode winNum window */
  43198. + MV_REG_BIT_RESET(SDRAM_SIZE_REG(0, target), SCSR_WIN_EN);
  43199. + }
  43200. +
  43201. + return MV_OK;
  43202. +}
  43203. +
  43204. +/*******************************************************************************
  43205. +* sdramIfWinOverlap - Check if an address window overlap an SDRAM address window
  43206. +*
  43207. +* DESCRIPTION:
  43208. +* This function scan each SDRAM address decode window to test if it
  43209. +* overlapps the given address windoow
  43210. +*
  43211. +* INPUT:
  43212. +* target - SDRAM target where the function skips checking.
  43213. +* pAddrDecWin - The tested address window for overlapping with
  43214. +* SDRAM windows.
  43215. +*
  43216. +* OUTPUT:
  43217. +* None.
  43218. +*
  43219. +* RETURN:
  43220. +* MV_TRUE if the given address window overlaps any enabled address
  43221. +* decode map, MV_FALSE otherwise.
  43222. +*
  43223. +*******************************************************************************/
  43224. +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
  43225. +{
  43226. + MV_TARGET targetNum;
  43227. + MV_DRAM_DEC_WIN addrDecWin;
  43228. +
  43229. + for(targetNum = SDRAM_CS0; targetNum < MV_DRAM_MAX_CS ; targetNum++)
  43230. + {
  43231. + /* don't check our winNum or illegal targets */
  43232. + if (targetNum == target)
  43233. + {
  43234. + continue;
  43235. + }
  43236. +
  43237. + /* Get window parameters */
  43238. + if (MV_OK != mvDramIfWinGet(targetNum, &addrDecWin))
  43239. + {
  43240. + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
  43241. + return MV_ERROR;
  43242. + }
  43243. +
  43244. + /* Do not check disabled windows */
  43245. + if (MV_FALSE == addrDecWin.enable)
  43246. + {
  43247. + continue;
  43248. + }
  43249. +
  43250. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
  43251. + {
  43252. + mvOsPrintf(
  43253. + "sdramIfWinOverlap: Required target %d overlap winNum %d\n",
  43254. + target, targetNum);
  43255. + return MV_TRUE;
  43256. + }
  43257. + }
  43258. +
  43259. + return MV_FALSE;
  43260. +}
  43261. +
  43262. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h
  43263. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h 1970-01-01 01:00:00.000000000 +0100
  43264. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h 2010-08-05 22:02:20.733652680 +0200
  43265. @@ -0,0 +1,80 @@
  43266. +/*******************************************************************************
  43267. +Copyright (C) Marvell International Ltd. and its affiliates
  43268. +
  43269. +This software file (the "File") is owned and distributed by Marvell
  43270. +International Ltd. and/or its affiliates ("Marvell") under the following
  43271. +alternative licensing terms. Once you have made an election to distribute the
  43272. +File under one of the following license alternatives, please (i) delete this
  43273. +introductory statement regarding license alternatives, (ii) delete the two
  43274. +license alternatives that you have not elected to use and (iii) preserve the
  43275. +Marvell copyright notice above.
  43276. +
  43277. +********************************************************************************
  43278. +Marvell Commercial License Option
  43279. +
  43280. +If you received this File from Marvell and you have entered into a commercial
  43281. +license agreement (a "Commercial License") with Marvell, the File is licensed
  43282. +to you under the terms of the applicable Commercial License.
  43283. +
  43284. +********************************************************************************
  43285. +Marvell GPL License Option
  43286. +
  43287. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43288. +modify this File in accordance with the terms and conditions of the General
  43289. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  43290. +available along with the File in the license.txt file or by writing to the Free
  43291. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  43292. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  43293. +
  43294. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  43295. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  43296. +DISCLAIMED. The GPL License provides additional details about this warranty
  43297. +disclaimer.
  43298. +********************************************************************************
  43299. +Marvell BSD License Option
  43300. +
  43301. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43302. +modify this File under the following licensing terms.
  43303. +Redistribution and use in source and binary forms, with or without modification,
  43304. +are permitted provided that the following conditions are met:
  43305. +
  43306. + * Redistributions of source code must retain the above copyright notice,
  43307. + this list of conditions and the following disclaimer.
  43308. +
  43309. + * Redistributions in binary form must reproduce the above copyright
  43310. + notice, this list of conditions and the following disclaimer in the
  43311. + documentation and/or other materials provided with the distribution.
  43312. +
  43313. + * Neither the name of Marvell nor the names of its contributors may be
  43314. + used to endorse or promote products derived from this software without
  43315. + specific prior written permission.
  43316. +
  43317. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  43318. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  43319. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  43320. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  43321. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  43322. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  43323. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  43324. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  43325. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  43326. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  43327. +
  43328. +*******************************************************************************/
  43329. +
  43330. +
  43331. +#ifndef __sysDram
  43332. +#define __sysDram
  43333. +
  43334. +/* This structure describes CPU interface address decode window */
  43335. +typedef struct _mvDramIfDecWin
  43336. +{
  43337. + MV_ADDR_WIN addrWin; /* An address window*/
  43338. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  43339. +}MV_DRAM_DEC_WIN;
  43340. +
  43341. +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
  43342. +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
  43343. +MV_STATUS mvDramIfWinEnable(MV_TARGET target, MV_BOOL enable);
  43344. +
  43345. +#endif
  43346. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c
  43347. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c 1970-01-01 01:00:00.000000000 +0100
  43348. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c 2010-08-05 22:02:21.073745697 +0200
  43349. @@ -0,0 +1,658 @@
  43350. +/*******************************************************************************
  43351. +Copyright (C) Marvell International Ltd. and its affiliates
  43352. +
  43353. +This software file (the "File") is owned and distributed by Marvell
  43354. +International Ltd. and/or its affiliates ("Marvell") under the following
  43355. +alternative licensing terms. Once you have made an election to distribute the
  43356. +File under one of the following license alternatives, please (i) delete this
  43357. +introductory statement regarding license alternatives, (ii) delete the two
  43358. +license alternatives that you have not elected to use and (iii) preserve the
  43359. +Marvell copyright notice above.
  43360. +
  43361. +********************************************************************************
  43362. +Marvell Commercial License Option
  43363. +
  43364. +If you received this File from Marvell and you have entered into a commercial
  43365. +license agreement (a "Commercial License") with Marvell, the File is licensed
  43366. +to you under the terms of the applicable Commercial License.
  43367. +
  43368. +********************************************************************************
  43369. +Marvell GPL License Option
  43370. +
  43371. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43372. +modify this File in accordance with the terms and conditions of the General
  43373. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  43374. +available along with the File in the license.txt file or by writing to the Free
  43375. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  43376. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  43377. +
  43378. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  43379. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  43380. +DISCLAIMED. The GPL License provides additional details about this warranty
  43381. +disclaimer.
  43382. +********************************************************************************
  43383. +Marvell BSD License Option
  43384. +
  43385. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43386. +modify this File under the following licensing terms.
  43387. +Redistribution and use in source and binary forms, with or without modification,
  43388. +are permitted provided that the following conditions are met:
  43389. +
  43390. + * Redistributions of source code must retain the above copyright notice,
  43391. + this list of conditions and the following disclaimer.
  43392. +
  43393. + * Redistributions in binary form must reproduce the above copyright
  43394. + notice, this list of conditions and the following disclaimer in the
  43395. + documentation and/or other materials provided with the distribution.
  43396. +
  43397. + * Neither the name of Marvell nor the names of its contributors may be
  43398. + used to endorse or promote products derived from this software without
  43399. + specific prior written permission.
  43400. +
  43401. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  43402. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  43403. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  43404. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  43405. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  43406. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  43407. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  43408. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  43409. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  43410. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  43411. +
  43412. +*******************************************************************************/
  43413. +
  43414. +
  43415. +#include "ctrlEnv/sys/mvSysGbe.h"
  43416. +
  43417. +
  43418. +
  43419. +typedef struct _mvEthDecWin
  43420. +{
  43421. + MV_TARGET target;
  43422. + MV_ADDR_WIN addrWin; /* An address window*/
  43423. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  43424. +
  43425. +}MV_ETH_DEC_WIN;
  43426. +
  43427. +MV_TARGET ethAddrDecPrioTap[] =
  43428. +{
  43429. +#if defined(MV_INCLUDE_SDRAM_CS0)
  43430. + SDRAM_CS0,
  43431. +#endif
  43432. +#if defined(MV_INCLUDE_SDRAM_CS1)
  43433. + SDRAM_CS1,
  43434. +#endif
  43435. +#if defined(MV_INCLUDE_SDRAM_CS2)
  43436. + SDRAM_CS2,
  43437. +#endif
  43438. +#if defined(MV_INCLUDE_SDRAM_CS3)
  43439. + SDRAM_CS3,
  43440. +#endif
  43441. +#if defined(MV_INCLUDE_DEVICE_CS0)
  43442. + DEVICE_CS0,
  43443. +#endif
  43444. +#if defined(MV_INCLUDE_DEVICE_CS1)
  43445. + DEVICE_CS1,
  43446. +#endif
  43447. +#if defined(MV_INCLUDE_DEVICE_CS2)
  43448. + DEVICE_CS2,
  43449. +#endif
  43450. +#if defined(MV_INCLUDE_DEVICE_CS3)
  43451. + DEVICE_CS3,
  43452. +#endif
  43453. +#if defined(MV_INCLUDE_PEX)
  43454. + PEX0_IO,
  43455. +#endif
  43456. + TBL_TERM
  43457. +};
  43458. +
  43459. +static MV_STATUS ethWinOverlapDetect(int port, MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
  43460. +static MV_STATUS mvEthWinSet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin);
  43461. +static MV_STATUS mvEthWinGet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin);
  43462. +
  43463. +
  43464. +/*******************************************************************************
  43465. +* mvEthWinInit - Initialize ETH address decode windows
  43466. +*
  43467. +* DESCRIPTION:
  43468. +* This function initialize ETH window decode unit. It set the
  43469. +* default address decode windows of the unit.
  43470. +*
  43471. +* INPUT:
  43472. +* None.
  43473. +*
  43474. +* OUTPUT:
  43475. +* None.
  43476. +*
  43477. +* RETURN:
  43478. +* MV_ERROR if setting fail.
  43479. +*******************************************************************************/
  43480. +/* Configure EthDrv memory map registes. */
  43481. +MV_STATUS mvEthWinInit (int port)
  43482. +{
  43483. + MV_U32 winNum, status, winPrioIndex=0, i, regVal=0;
  43484. + MV_ETH_DEC_WIN ethWin;
  43485. + MV_CPU_DEC_WIN cpuAddrDecWin;
  43486. + static MV_U32 accessProtReg = 0;
  43487. +
  43488. +#if (MV_ETH_VERSION <= 1)
  43489. + static MV_BOOL isFirst = MV_TRUE;
  43490. +
  43491. + if(isFirst == MV_FALSE)
  43492. + {
  43493. + MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(port), accessProtReg);
  43494. + return MV_OK;
  43495. + }
  43496. + isFirst = MV_FALSE;
  43497. +#endif /* MV_GIGA_ETH_VERSION */
  43498. +
  43499. + /* Initiate Ethernet address decode */
  43500. +
  43501. + /* First disable all address decode windows */
  43502. + for(winNum=0; winNum<ETH_MAX_DECODE_WIN; winNum++)
  43503. + {
  43504. + regVal |= MV_BIT_MASK(winNum);
  43505. + }
  43506. + MV_REG_WRITE(ETH_BASE_ADDR_ENABLE_REG(port), regVal);
  43507. +
  43508. + /* Go through all windows in user table until table terminator */
  43509. + for (winNum=0; ((ethAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
  43510. + (winNum < ETH_MAX_DECODE_WIN)); )
  43511. + {
  43512. + /* first get attributes from CPU If */
  43513. + status = mvCpuIfTargetWinGet(ethAddrDecPrioTap[winPrioIndex],
  43514. + &cpuAddrDecWin);
  43515. +
  43516. + if(MV_NO_SUCH == status)
  43517. + {
  43518. + winPrioIndex++;
  43519. + continue;
  43520. + }
  43521. + if (MV_OK != status)
  43522. + {
  43523. + mvOsPrintf("mvEthWinInit: ERR. mvCpuIfTargetWinGet failed\n");
  43524. + return MV_ERROR;
  43525. + }
  43526. +
  43527. + if (cpuAddrDecWin.enable == MV_TRUE)
  43528. + {
  43529. + ethWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  43530. + ethWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  43531. + ethWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  43532. + ethWin.enable = MV_TRUE;
  43533. + ethWin.target = ethAddrDecPrioTap[winPrioIndex];
  43534. +
  43535. + if(MV_OK != mvEthWinSet(port, winNum, &ethWin))
  43536. + {
  43537. + mvOsPrintf("mvEthWinInit: ERR. mvEthWinSet failed winNum=%d\n",
  43538. + winNum);
  43539. + return MV_ERROR;
  43540. + }
  43541. + winNum++;
  43542. + }
  43543. + winPrioIndex ++;
  43544. + }
  43545. +
  43546. + /* set full access to all windows. */
  43547. + for(i=0; i<winNum; i++)
  43548. + {
  43549. + accessProtReg |= (FULL_ACCESS << (i*2));
  43550. + }
  43551. + MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(port), accessProtReg);
  43552. +
  43553. + return MV_OK;
  43554. +}
  43555. +
  43556. +/*******************************************************************************
  43557. +* mvEthWinSet - Set ETH target address window
  43558. +*
  43559. +* DESCRIPTION:
  43560. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  43561. +* address window, also known as address decode window.
  43562. +* After setting this target window, the ETH will be able to access the
  43563. +* target within the address window.
  43564. +*
  43565. +* INPUT:
  43566. +* winNum - ETH to target address decode window number.
  43567. +* pAddrDecWin - ETH target window data structure.
  43568. +*
  43569. +* OUTPUT:
  43570. +* None.
  43571. +*
  43572. +* RETURN:
  43573. +* MV_ERROR if address window overlapps with other address decode windows.
  43574. +* MV_BAD_PARAM if base address is invalid parameter or target is
  43575. +* unknown.
  43576. +*
  43577. +*******************************************************************************/
  43578. +MV_STATUS mvEthWinSet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin)
  43579. +{
  43580. + MV_TARGET_ATTRIB targetAttribs;
  43581. + MV_DEC_REGS decRegs;
  43582. +
  43583. + /* Parameter checking */
  43584. + if (winNum >= ETH_MAX_DECODE_WIN)
  43585. + {
  43586. + mvOsPrintf("mvEthWinSet: ERR. Invalid win num %d\n",winNum);
  43587. + return MV_BAD_PARAM;
  43588. + }
  43589. +
  43590. + /* Check if the requested window overlapps with current windows */
  43591. + if (MV_TRUE == ethWinOverlapDetect(port, winNum, &pAddrDecWin->addrWin))
  43592. + {
  43593. + mvOsPrintf("mvEthWinSet: ERR. Window %d overlap\n", winNum);
  43594. + return MV_ERROR;
  43595. + }
  43596. +
  43597. + /* check if address is aligned to the size */
  43598. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  43599. + {
  43600. + mvOsPrintf("mvEthWinSet: Error setting Ethernet window %d to "\
  43601. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  43602. + winNum,
  43603. + mvCtrlTargetNameGet(pAddrDecWin->target),
  43604. + pAddrDecWin->addrWin.baseLow,
  43605. + pAddrDecWin->addrWin.size);
  43606. + return MV_ERROR;
  43607. + }
  43608. +
  43609. +
  43610. + decRegs.baseReg = MV_REG_READ(ETH_WIN_BASE_REG(port, winNum));
  43611. + decRegs.sizeReg = MV_REG_READ(ETH_WIN_SIZE_REG(port, winNum));
  43612. +
  43613. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  43614. + {
  43615. + mvOsPrintf("mvEthWinSet:mvCtrlAddrDecToReg Failed\n");
  43616. + return MV_ERROR;
  43617. + }
  43618. +
  43619. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  43620. +
  43621. + /* set attributes */
  43622. + decRegs.baseReg &= ~ETH_WIN_ATTR_MASK;
  43623. + decRegs.baseReg |= targetAttribs.attrib << ETH_WIN_ATTR_OFFS;
  43624. + /* set target ID */
  43625. + decRegs.baseReg &= ~ETH_WIN_TARGET_MASK;
  43626. + decRegs.baseReg |= targetAttribs.targetId << ETH_WIN_TARGET_OFFS;
  43627. +
  43628. + /* for the safe side we disable the window before writing the new
  43629. + values */
  43630. + mvEthWinEnable(port, winNum, MV_FALSE);
  43631. + MV_REG_WRITE(ETH_WIN_BASE_REG(port, winNum), decRegs.baseReg);
  43632. +
  43633. + /* Write to address decode Size Register */
  43634. + MV_REG_WRITE(ETH_WIN_SIZE_REG(port, winNum), decRegs.sizeReg);
  43635. +
  43636. + /* Enable address decode target window */
  43637. + if (pAddrDecWin->enable == MV_TRUE)
  43638. + {
  43639. + mvEthWinEnable(port, winNum, MV_TRUE);
  43640. + }
  43641. +
  43642. + return MV_OK;
  43643. +}
  43644. +
  43645. +/*******************************************************************************
  43646. +* mvETHWinGet - Get dma peripheral target address window.
  43647. +*
  43648. +* DESCRIPTION:
  43649. +* Get ETH peripheral target address window.
  43650. +*
  43651. +* INPUT:
  43652. +* winNum - ETH to target address decode window number.
  43653. +*
  43654. +* OUTPUT:
  43655. +* pAddrDecWin - ETH target window data structure.
  43656. +*
  43657. +* RETURN:
  43658. +* MV_ERROR if register parameters are invalid.
  43659. +*
  43660. +*******************************************************************************/
  43661. +MV_STATUS mvEthWinGet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin)
  43662. +{
  43663. + MV_DEC_REGS decRegs;
  43664. + MV_TARGET_ATTRIB targetAttrib;
  43665. +
  43666. + /* Parameter checking */
  43667. + if (winNum >= ETH_MAX_DECODE_WIN)
  43668. + {
  43669. + mvOsPrintf("mvEthWinGet: ERR. Invalid winNum %d\n", winNum);
  43670. + return MV_NOT_SUPPORTED;
  43671. + }
  43672. +
  43673. + decRegs.baseReg = MV_REG_READ(ETH_WIN_BASE_REG(port, winNum));
  43674. + decRegs.sizeReg = MV_REG_READ(ETH_WIN_SIZE_REG(port, winNum));
  43675. +
  43676. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  43677. + {
  43678. + mvOsPrintf("mvAhbToMbusWinGet: mvCtrlRegToAddrDec Failed \n");
  43679. + return MV_ERROR;
  43680. + }
  43681. +
  43682. + /* attrib and targetId */
  43683. + targetAttrib.attrib =
  43684. + (decRegs.baseReg & ETH_WIN_ATTR_MASK) >> ETH_WIN_ATTR_OFFS;
  43685. + targetAttrib.targetId =
  43686. + (decRegs.baseReg & ETH_WIN_TARGET_MASK) >> ETH_WIN_TARGET_OFFS;
  43687. +
  43688. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  43689. +
  43690. + /* Check if window is enabled */
  43691. + if (~(MV_REG_READ(ETH_BASE_ADDR_ENABLE_REG(port))) & (1 << winNum) )
  43692. + {
  43693. + pAddrDecWin->enable = MV_TRUE;
  43694. + }
  43695. + else
  43696. + {
  43697. + pAddrDecWin->enable = MV_FALSE;
  43698. + }
  43699. +
  43700. + return MV_OK;
  43701. +}
  43702. +
  43703. +/*******************************************************************************
  43704. +* mvEthWinEnable - Enable/disable a ETH to target address window
  43705. +*
  43706. +* DESCRIPTION:
  43707. +* This function enable/disable a ETH to target address window.
  43708. +* According to parameter 'enable' the routine will enable the
  43709. +* window, thus enabling ETH accesses (before enabling the window it is
  43710. +* tested for overlapping). Otherwise, the window will be disabled.
  43711. +*
  43712. +* INPUT:
  43713. +* winNum - ETH to target address decode window number.
  43714. +* enable - Enable/disable parameter.
  43715. +*
  43716. +* OUTPUT:
  43717. +* N/A
  43718. +*
  43719. +* RETURN:
  43720. +* MV_ERROR if decode window number was wrong or enabled window overlapps.
  43721. +*
  43722. +*******************************************************************************/
  43723. +MV_STATUS mvEthWinEnable(int port, MV_U32 winNum,MV_BOOL enable)
  43724. +{
  43725. + MV_ETH_DEC_WIN addrDecWin;
  43726. +
  43727. + /* Parameter checking */
  43728. + if (winNum >= ETH_MAX_DECODE_WIN)
  43729. + {
  43730. + mvOsPrintf("mvEthTargetWinEnable:ERR. Invalid winNum%d\n",winNum);
  43731. + return MV_ERROR;
  43732. + }
  43733. +
  43734. + if (enable == MV_TRUE)
  43735. + { /* First check for overlap with other enabled windows */
  43736. + /* Get current window */
  43737. + if (MV_OK != mvEthWinGet(port, winNum, &addrDecWin))
  43738. + {
  43739. + mvOsPrintf("mvEthTargetWinEnable:ERR. targetWinGet fail\n");
  43740. + return MV_ERROR;
  43741. + }
  43742. + /* Check for overlapping */
  43743. + if (MV_FALSE == ethWinOverlapDetect(port, winNum, &(addrDecWin.addrWin)))
  43744. + {
  43745. + /* No Overlap. Enable address decode target window */
  43746. + MV_REG_BIT_RESET(ETH_BASE_ADDR_ENABLE_REG(port), (1 << winNum));
  43747. + }
  43748. + else
  43749. + { /* Overlap detected */
  43750. + mvOsPrintf("mvEthTargetWinEnable:ERR. Overlap detected\n");
  43751. + return MV_ERROR;
  43752. + }
  43753. + }
  43754. + else
  43755. + { /* Disable address decode target window */
  43756. + MV_REG_BIT_SET(ETH_BASE_ADDR_ENABLE_REG(port), (1 << winNum));
  43757. + }
  43758. + return MV_OK;
  43759. +}
  43760. +
  43761. +/*******************************************************************************
  43762. +* mvEthWinTargetGet - Get Window number associated with target
  43763. +*
  43764. +* DESCRIPTION:
  43765. +*
  43766. +* INPUT:
  43767. +*
  43768. +* OUTPUT:
  43769. +*
  43770. +* RETURN:
  43771. +* window number
  43772. +*
  43773. +*******************************************************************************/
  43774. +MV_U32 mvEthWinTargetGet(int port, MV_TARGET target)
  43775. +{
  43776. + MV_ETH_DEC_WIN decWin;
  43777. + MV_U32 winNum;
  43778. +
  43779. + /* Check parameters */
  43780. + if (target >= MAX_TARGETS)
  43781. + {
  43782. + mvOsPrintf("mvAhbToMbusWinTargetGet: target %d is Illigal\n", target);
  43783. + return 0xffffffff;
  43784. + }
  43785. +
  43786. + for (winNum=0; winNum<ETH_MAX_DECODE_WIN; winNum++)
  43787. + {
  43788. + if (mvEthWinGet(port, winNum,&decWin) != MV_OK)
  43789. + {
  43790. + mvOsPrintf("mvAhbToMbusWinTargetGet: window returned error\n");
  43791. + return 0xffffffff;
  43792. + }
  43793. +
  43794. + if (decWin.enable == MV_TRUE)
  43795. + {
  43796. + if (decWin.target == target)
  43797. + {
  43798. + return winNum;
  43799. + }
  43800. + }
  43801. + }
  43802. + return 0xFFFFFFFF;
  43803. +}
  43804. +
  43805. +/*******************************************************************************
  43806. +* mvEthProtWinSet - Set access protection of Ethernet to target window.
  43807. +*
  43808. +* DESCRIPTION:
  43809. +* Each Ethernet port can be configured with access attributes for each
  43810. +* of the Ethenret to target windows (address decode windows). This
  43811. +* function sets access attributes to a given window for the given channel.
  43812. +*
  43813. +* INPUTS:
  43814. +* ethPort - ETH channel number. See MV_ETH_CHANNEL enumerator.
  43815. +* winNum - IETH to target address decode window number.
  43816. +* access - IETH access rights. See MV_ACCESS_RIGHTS enumerator.
  43817. +*
  43818. +* OUTPUT:
  43819. +* None.
  43820. +*
  43821. +* RETURN:
  43822. +* MV_ERROR in case window number is invalid or access right reserved.
  43823. +*
  43824. +*******************************************************************************/
  43825. +MV_STATUS mvEthProtWinSet(MV_U32 portNo, MV_U32 winNum, MV_ACCESS_RIGHTS access)
  43826. +{
  43827. + MV_U32 protReg;
  43828. +
  43829. + /* Parameter checking */
  43830. + if(portNo >= mvCtrlEthMaxPortGet())
  43831. + {
  43832. + mvOsPrintf("mvEthProtWinSet:ERR. Invalid port number %d\n", portNo);
  43833. + return MV_ERROR;
  43834. + }
  43835. +
  43836. + if (winNum >= ETH_MAX_DECODE_WIN)
  43837. + {
  43838. + mvOsPrintf("mvEthProtWinSet:ERR. Invalid winNum%d\n",winNum);
  43839. + return MV_ERROR;
  43840. + }
  43841. +
  43842. + if((access == ACC_RESERVED) || (access >= MAX_ACC_RIGHTS))
  43843. + {
  43844. + mvOsPrintf("mvEthProtWinSet:ERR. Inv access param %d\n", access);
  43845. + return MV_ERROR;
  43846. + }
  43847. + /* Read current protection register */
  43848. + protReg = MV_REG_READ(ETH_ACCESS_PROTECT_REG(portNo));
  43849. +
  43850. + /* Clear protection window field */
  43851. + protReg &= ~(ETH_PROT_WIN_MASK(winNum));
  43852. +
  43853. + /* Set new protection field value */
  43854. + protReg |= (access << (ETH_PROT_WIN_OFFS(winNum)));
  43855. +
  43856. + /* Write protection register back */
  43857. + MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(portNo), protReg);
  43858. +
  43859. + return MV_OK;
  43860. +}
  43861. +
  43862. +/*******************************************************************************
  43863. +* ethWinOverlapDetect - Detect ETH address windows overlapping
  43864. +*
  43865. +* DESCRIPTION:
  43866. +* An unpredicted behaviur is expected in case ETH address decode
  43867. +* windows overlapps.
  43868. +* This function detects ETH address decode windows overlapping of a
  43869. +* specified window. The function does not check the window itself for
  43870. +* overlapping. The function also skipps disabled address decode windows.
  43871. +*
  43872. +* INPUT:
  43873. +* winNum - address decode window number.
  43874. +* pAddrDecWin - An address decode window struct.
  43875. +*
  43876. +* OUTPUT:
  43877. +* None.
  43878. +*
  43879. +* RETURN:
  43880. +* MV_TRUE if the given address window overlap current address
  43881. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  43882. +* from registers.
  43883. +*
  43884. +*******************************************************************************/
  43885. +static MV_STATUS ethWinOverlapDetect(int port, MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  43886. +{
  43887. + MV_U32 baseAddrEnableReg;
  43888. + MV_U32 winNumIndex;
  43889. + MV_ETH_DEC_WIN addrDecWin;
  43890. +
  43891. + /* Read base address enable register. Do not check disabled windows */
  43892. + baseAddrEnableReg = MV_REG_READ(ETH_BASE_ADDR_ENABLE_REG(port));
  43893. +
  43894. + for (winNumIndex=0; winNumIndex<ETH_MAX_DECODE_WIN; winNumIndex++)
  43895. + {
  43896. + /* Do not check window itself */
  43897. + if (winNumIndex == winNum)
  43898. + {
  43899. + continue;
  43900. + }
  43901. +
  43902. + /* Do not check disabled windows */
  43903. + if (baseAddrEnableReg & (1 << winNumIndex))
  43904. + {
  43905. + continue;
  43906. + }
  43907. +
  43908. + /* Get window parameters */
  43909. + if (MV_OK != mvEthWinGet(port, winNumIndex, &addrDecWin))
  43910. + {
  43911. + mvOsPrintf("ethWinOverlapDetect: ERR. TargetWinGet failed\n");
  43912. + return MV_ERROR;
  43913. + }
  43914. +/*
  43915. + mvOsPrintf("ethWinOverlapDetect:\n
  43916. + winNumIndex =%d baseHigh =0x%x baseLow=0x%x size=0x%x enable=0x%x\n",
  43917. + winNumIndex,
  43918. + addrDecWin.addrWin.baseHigh,
  43919. + addrDecWin.addrWin.baseLow,
  43920. + addrDecWin.addrWin.size,
  43921. + addrDecWin.enable);
  43922. +*/
  43923. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  43924. + {
  43925. + return MV_TRUE;
  43926. + }
  43927. + }
  43928. + return MV_FALSE;
  43929. +}
  43930. +
  43931. +/*******************************************************************************
  43932. +* mvEthAddrDecShow - Print the Etherent address decode map.
  43933. +*
  43934. +* DESCRIPTION:
  43935. +* This function print the Etherent address decode map.
  43936. +*
  43937. +* INPUT:
  43938. +* None.
  43939. +*
  43940. +* OUTPUT:
  43941. +* None.
  43942. +*
  43943. +* RETURN:
  43944. +* None.
  43945. +*
  43946. +*******************************************************************************/
  43947. +void mvEthPortAddrDecShow(int port)
  43948. +{
  43949. + MV_ETH_DEC_WIN win;
  43950. + int i;
  43951. +
  43952. + mvOsOutput( "\n" );
  43953. + mvOsOutput( "ETH %d:\n", port );
  43954. + mvOsOutput( "----\n" );
  43955. +
  43956. + for( i = 0; i < ETH_MAX_DECODE_WIN; i++ )
  43957. + {
  43958. + memset( &win, 0, sizeof(ETH_MAX_DECODE_WIN) );
  43959. +
  43960. + mvOsOutput( "win%d - ", i );
  43961. +
  43962. + if( mvEthWinGet(port, i, &win ) == MV_OK )
  43963. + {
  43964. + if( win.enable )
  43965. + {
  43966. + mvOsOutput( "%s base %08x, ",
  43967. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  43968. + mvOsOutput( "...." );
  43969. + mvSizePrint( win.addrWin.size );
  43970. +
  43971. + mvOsOutput( "\n" );
  43972. + }
  43973. + else
  43974. + mvOsOutput( "disable\n" );
  43975. + }
  43976. + }
  43977. + return;
  43978. +}
  43979. +
  43980. +void mvEthAddrDecShow(void)
  43981. +{
  43982. + int port;
  43983. +
  43984. + for(port=0; port<mvCtrlEthMaxPortGet(); port++)
  43985. + {
  43986. + if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port)) continue;
  43987. +
  43988. + mvEthPortAddrDecShow(port);
  43989. + }
  43990. +}
  43991. +
  43992. +
  43993. +void mvEthInit(void)
  43994. +{
  43995. + MV_U32 port;
  43996. +
  43997. + /* Power down all existing ports */
  43998. + for(port=0; port<mvCtrlEthMaxPortGet(); port++)
  43999. + {
  44000. + if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port))
  44001. + continue;
  44002. +
  44003. + mvEthPortPowerUp(port);
  44004. + mvEthWinInit(port);
  44005. + }
  44006. + mvEthHalInit();
  44007. +}
  44008. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h
  44009. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h 1970-01-01 01:00:00.000000000 +0100
  44010. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h 2010-08-05 22:02:21.323824629 +0200
  44011. @@ -0,0 +1,113 @@
  44012. +/*******************************************************************************
  44013. +Copyright (C) Marvell International Ltd. and its affiliates
  44014. +
  44015. +This software file (the "File") is owned and distributed by Marvell
  44016. +International Ltd. and/or its affiliates ("Marvell") under the following
  44017. +alternative licensing terms. Once you have made an election to distribute the
  44018. +File under one of the following license alternatives, please (i) delete this
  44019. +introductory statement regarding license alternatives, (ii) delete the two
  44020. +license alternatives that you have not elected to use and (iii) preserve the
  44021. +Marvell copyright notice above.
  44022. +
  44023. +********************************************************************************
  44024. +Marvell Commercial License Option
  44025. +
  44026. +If you received this File from Marvell and you have entered into a commercial
  44027. +license agreement (a "Commercial License") with Marvell, the File is licensed
  44028. +to you under the terms of the applicable Commercial License.
  44029. +
  44030. +********************************************************************************
  44031. +Marvell GPL License Option
  44032. +
  44033. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44034. +modify this File in accordance with the terms and conditions of the General
  44035. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  44036. +available along with the File in the license.txt file or by writing to the Free
  44037. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  44038. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  44039. +
  44040. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  44041. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  44042. +DISCLAIMED. The GPL License provides additional details about this warranty
  44043. +disclaimer.
  44044. +********************************************************************************
  44045. +Marvell BSD License Option
  44046. +
  44047. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44048. +modify this File under the following licensing terms.
  44049. +Redistribution and use in source and binary forms, with or without modification,
  44050. +are permitted provided that the following conditions are met:
  44051. +
  44052. + * Redistributions of source code must retain the above copyright notice,
  44053. + this list of conditions and the following disclaimer.
  44054. +
  44055. + * Redistributions in binary form must reproduce the above copyright
  44056. + notice, this list of conditions and the following disclaimer in the
  44057. + documentation and/or other materials provided with the distribution.
  44058. +
  44059. + * Neither the name of Marvell nor the names of its contributors may be
  44060. + used to endorse or promote products derived from this software without
  44061. + specific prior written permission.
  44062. +
  44063. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  44064. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  44065. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  44066. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  44067. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  44068. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  44069. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  44070. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  44071. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  44072. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44073. +
  44074. +*******************************************************************************/
  44075. +
  44076. +#ifndef __INCmvSysGbeh
  44077. +#define __INCmvSysGbeh
  44078. +
  44079. +#include "mvCommon.h"
  44080. +#include "eth/mvEth.h"
  44081. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  44082. +#include "ctrlEnv/sys/mvCpuIf.h"
  44083. +
  44084. +#define ETH_WIN_BASE_REG(port, win) (MV_ETH_REG_BASE(port) + 0x200 + ((win)<<3))
  44085. +#define ETH_WIN_SIZE_REG(port, win) (MV_ETH_REG_BASE(port) + 0x204 + ((win)<<3))
  44086. +#define ETH_WIN_REMAP_REG(port, win) (MV_ETH_REG_BASE(port) + 0x280 + ((win)<<2))
  44087. +#define ETH_BASE_ADDR_ENABLE_REG(port) (MV_ETH_REG_BASE(port) + 0x290)
  44088. +#define ETH_ACCESS_PROTECT_REG(port) (MV_ETH_REG_BASE(port) + 0x294)
  44089. +
  44090. +/**** Address decode parameters ****/
  44091. +
  44092. +/* Ethernet Base Address Register bits */
  44093. +#define ETH_MAX_DECODE_WIN 6
  44094. +#define ETH_MAX_HIGH_ADDR_REMAP_WIN 4
  44095. +
  44096. +/* Ethernet Port Access Protect (EPAP) register */
  44097. +
  44098. +/* The target associated with this window*/
  44099. +#define ETH_WIN_TARGET_OFFS 0
  44100. +#define ETH_WIN_TARGET_MASK (0xf << ETH_WIN_TARGET_OFFS)
  44101. +/* The target attributes Associated with window */
  44102. +#define ETH_WIN_ATTR_OFFS 8
  44103. +#define ETH_WIN_ATTR_MASK (0xff << ETH_WIN_ATTR_OFFS)
  44104. +
  44105. +/* Ethernet Port Access Protect Register (EPAPR) */
  44106. +#define ETH_PROT_NO_ACCESS NO_ACCESS_ALLOWED
  44107. +#define ETH_PROT_READ_ONLY READ_ONLY
  44108. +#define ETH_PROT_FULL_ACCESS FULL_ACCESS
  44109. +#define ETH_PROT_WIN_OFFS(winNum) (2 * (winNum))
  44110. +#define ETH_PROT_WIN_MASK(winNum) (0x3 << ETH_PROT_WIN_OFFS(winNum))
  44111. +
  44112. +MV_STATUS mvEthWinInit (int port);
  44113. +MV_STATUS mvEthWinEnable(int port, MV_U32 winNum, MV_BOOL enable);
  44114. +MV_U32 mvEthWinTargetGet(int port, MV_TARGET target);
  44115. +MV_STATUS mvEthProtWinSet(MV_U32 portNo, MV_U32 winNum, MV_ACCESS_RIGHTS
  44116. + access);
  44117. +
  44118. +void mvEthPortAddrDecShow(int port);
  44119. +
  44120. +MV_VOID mvEthAddrDecShow(MV_VOID);
  44121. +
  44122. +void mvEthInit(void);
  44123. +
  44124. +#endif
  44125. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c
  44126. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c 1970-01-01 01:00:00.000000000 +0100
  44127. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c 2010-08-05 22:02:21.563623757 +0200
  44128. @@ -0,0 +1,1697 @@
  44129. +/*******************************************************************************
  44130. +Copyright (C) Marvell International Ltd. and its affiliates
  44131. +
  44132. +This software file (the "File") is owned and distributed by Marvell
  44133. +International Ltd. and/or its affiliates ("Marvell") under the following
  44134. +alternative licensing terms. Once you have made an election to distribute the
  44135. +File under one of the following license alternatives, please (i) delete this
  44136. +introductory statement regarding license alternatives, (ii) delete the two
  44137. +license alternatives that you have not elected to use and (iii) preserve the
  44138. +Marvell copyright notice above.
  44139. +
  44140. +********************************************************************************
  44141. +Marvell Commercial License Option
  44142. +
  44143. +If you received this File from Marvell and you have entered into a commercial
  44144. +license agreement (a "Commercial License") with Marvell, the File is licensed
  44145. +to you under the terms of the applicable Commercial License.
  44146. +
  44147. +********************************************************************************
  44148. +Marvell GPL License Option
  44149. +
  44150. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44151. +modify this File in accordance with the terms and conditions of the General
  44152. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  44153. +available along with the File in the license.txt file or by writing to the Free
  44154. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  44155. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  44156. +
  44157. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  44158. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  44159. +DISCLAIMED. The GPL License provides additional details about this warranty
  44160. +disclaimer.
  44161. +********************************************************************************
  44162. +Marvell BSD License Option
  44163. +
  44164. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44165. +modify this File under the following licensing terms.
  44166. +Redistribution and use in source and binary forms, with or without modification,
  44167. +are permitted provided that the following conditions are met:
  44168. +
  44169. + * Redistributions of source code must retain the above copyright notice,
  44170. + this list of conditions and the following disclaimer.
  44171. +
  44172. + * Redistributions in binary form must reproduce the above copyright
  44173. + notice, this list of conditions and the following disclaimer in the
  44174. + documentation and/or other materials provided with the distribution.
  44175. +
  44176. + * Neither the name of Marvell nor the names of its contributors may be
  44177. + used to endorse or promote products derived from this software without
  44178. + specific prior written permission.
  44179. +
  44180. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  44181. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  44182. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  44183. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  44184. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  44185. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  44186. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  44187. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  44188. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  44189. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44190. +
  44191. +*******************************************************************************/
  44192. +
  44193. +#include "ctrlEnv/sys/mvSysPex.h"
  44194. +
  44195. +/* this structure describes the mapping between a Pex Window and a CPU target*/
  44196. +typedef struct _pexWinToTarget
  44197. +{
  44198. + MV_TARGET target;
  44199. + MV_BOOL enable;
  44200. +
  44201. +}PEX_WIN_TO_TARGET;
  44202. +
  44203. +/* this array is a priority array that define How Pex windows should be
  44204. +configured , We have only 6 Pex Windows that can be configured , but we
  44205. +have maximum of 9 CPU target windows ! the following array is a priority
  44206. +array where the lowest index has the highest priotiy and the highest
  44207. +index has the lowest priority of being cnfigured */
  44208. +
  44209. +MV_U32 pexDevBarPrioTable[] =
  44210. +{
  44211. +#if defined(MV_INCLUDE_DEVICE_CS0)
  44212. + DEVICE_CS0,
  44213. +#endif
  44214. +#if defined(MV_INCLUDE_DEVICE_CS1)
  44215. + DEVICE_CS1,
  44216. +#endif
  44217. +#if defined(MV_INCLUDE_DEVICE_CS2)
  44218. + DEVICE_CS2,
  44219. +#endif
  44220. +#if defined(MV_INCLUDE_DEVICE_CS3)
  44221. + DEVICE_CS3,
  44222. +#endif
  44223. +/*
  44224. +#if defined(MV_INCLUDE_DEVICE_CS4)
  44225. + DEVICE_CS4,
  44226. +#endif
  44227. +*/
  44228. + TBL_TERM
  44229. +};
  44230. +
  44231. +
  44232. +/* PEX Wins registers offsets are inconsecutive. This struct describes WIN */
  44233. +/* register offsets and its function where its is located. */
  44234. +/* Also, PEX address remap registers offsets are inconsecutive. This struct */
  44235. +/* describes address remap register offsets */
  44236. +typedef struct _pexWinRegInfo
  44237. +{
  44238. + MV_U32 baseLowRegOffs;
  44239. + MV_U32 baseHighRegOffs;
  44240. + MV_U32 sizeRegOffs;
  44241. + MV_U32 remapLowRegOffs;
  44242. + MV_U32 remapHighRegOffs;
  44243. +
  44244. +}PEX_WIN_REG_INFO;
  44245. +
  44246. +static MV_STATUS pexWinOverlapDetect(MV_U32 pexIf, MV_U32 winNum,
  44247. + MV_ADDR_WIN *pAddrWin);
  44248. +static MV_STATUS pexWinRegInfoGet(MV_U32 pexIf, MV_U32 winNum,
  44249. + PEX_WIN_REG_INFO *pWinRegInfo);
  44250. +
  44251. +static MV_STATUS pexBarIsValid(MV_U32 baseLow, MV_U32 size);
  44252. +
  44253. +static MV_BOOL pexIsWinWithinBar(MV_U32 pexIf,MV_ADDR_WIN *pAddrWin);
  44254. +static MV_BOOL pexBarOverlapDetect(MV_U32 pexIf,MV_U32 barNum,
  44255. + MV_ADDR_WIN *pAddrWin);
  44256. +const MV_8* pexBarNameGet( MV_U32 bar );
  44257. +
  44258. +
  44259. +/*******************************************************************************
  44260. +* mvPexInit - Initialize PEX interfaces
  44261. +*
  44262. +* DESCRIPTION:
  44263. +*
  44264. +* This function is responsible of intialization of the Pex Interface , It
  44265. +* configure the Pex Bars and Windows in the following manner:
  44266. +*
  44267. +* Assumptions :
  44268. +* Bar0 is always internal registers bar
  44269. +* Bar1 is always the DRAM bar
  44270. +* Bar2 is always the Device bar
  44271. +*
  44272. +* 1) Sets the Internal registers bar base by obtaining the base from
  44273. +* the CPU Interface
  44274. +* 2) Sets the DRAM bar base and size by getting the base and size from
  44275. +* the CPU Interface when the size is the sum of all enabled DRAM
  44276. +* chip selects and the base is the base of CS0 .
  44277. +* 3) Sets the Device bar base and size by getting these values from the
  44278. +* CPU Interface when the base is the base of the lowest base of the
  44279. +* Device chip selects, and the
  44280. +*
  44281. +*
  44282. +* INPUT:
  44283. +*
  44284. +* pexIf - PEX interface number.
  44285. +*
  44286. +*
  44287. +* OUTPUT:
  44288. +* None.
  44289. +*
  44290. +* RETURN:
  44291. +* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
  44292. +*
  44293. +*******************************************************************************/
  44294. +MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType)
  44295. +{
  44296. + MV_U32 bar;
  44297. + MV_U32 winNum;
  44298. + MV_PEX_BAR pexBar;
  44299. + MV_PEX_DEC_WIN pexWin;
  44300. + MV_CPU_DEC_WIN addrDecWin;
  44301. + MV_TARGET target;
  44302. + MV_U32 pexCurrWin=0;
  44303. + MV_U32 status;
  44304. + /* default and exapntion rom
  44305. + are always configured */
  44306. +
  44307. +#ifndef MV_DISABLE_PEX_DEVICE_BAR
  44308. + MV_U32 winIndex;
  44309. + MV_U32 maxBase=0, sizeOfMaxBase=0;
  44310. + MV_U32 pexStartWindow;
  44311. +#endif
  44312. +
  44313. + /* Parameter checking */
  44314. + if(pexIf >= mvCtrlPexMaxIfGet())
  44315. + {
  44316. + mvOsPrintf("mvPexInit: ERR. Invalid PEX interface %d\n", pexIf);
  44317. + return MV_BAD_PARAM;
  44318. + }
  44319. +
  44320. + /* Enabled CPU access to PCI-Express */
  44321. + mvCpuIfEnablePex(pexIf, pexType);
  44322. +
  44323. + /* Start with bars */
  44324. + /* First disable all PEX bars*/
  44325. + for (bar = 0; bar < PEX_MAX_BARS; bar++)
  44326. + {
  44327. + if (PEX_INTER_REGS_BAR != bar)
  44328. + {
  44329. + if (MV_OK != mvPexBarEnable(pexIf, bar, MV_FALSE))
  44330. + {
  44331. + mvOsPrintf("mvPexInit:mvPexBarEnable bar =%d failed \n",bar);
  44332. + return MV_ERROR;
  44333. + }
  44334. +
  44335. + }
  44336. +
  44337. + }
  44338. +
  44339. + /* and disable all PEX target windows */
  44340. + for (winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++)
  44341. + {
  44342. + if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_FALSE))
  44343. + {
  44344. + mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n",
  44345. + winNum);
  44346. + return MV_ERROR;
  44347. +
  44348. + }
  44349. + }
  44350. +
  44351. + /* Now, go through all bars*/
  44352. +
  44353. +
  44354. +
  44355. +/******************************************************************************/
  44356. +/* Internal registers bar */
  44357. +/******************************************************************************/
  44358. + bar = PEX_INTER_REGS_BAR;
  44359. +
  44360. + /* we only open the bar , no need to open windows for this bar */
  44361. +
  44362. + /* first get the CS attribute from the CPU Interface */
  44363. + if (MV_OK !=mvCpuIfTargetWinGet(INTER_REGS,&addrDecWin))
  44364. + {
  44365. + mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",INTER_REGS);
  44366. + return MV_ERROR;
  44367. + }
  44368. +
  44369. + pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  44370. + pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  44371. + pexBar.addrWin.size = addrDecWin.addrWin.size;
  44372. + pexBar.enable = MV_TRUE;
  44373. +
  44374. + if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
  44375. + {
  44376. + mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
  44377. + return MV_ERROR;
  44378. + }
  44379. +
  44380. +/******************************************************************************/
  44381. +/* DRAM bar */
  44382. +/******************************************************************************/
  44383. +
  44384. + bar = PEX_DRAM_BAR;
  44385. +
  44386. + pexBar.addrWin.size = 0;
  44387. +
  44388. + for (target = SDRAM_CS0;target < MV_DRAM_MAX_CS; target++ )
  44389. + {
  44390. +
  44391. + status = mvCpuIfTargetWinGet(target,&addrDecWin);
  44392. +
  44393. + if((MV_NO_SUCH == status)&&(target != SDRAM_CS0))
  44394. + {
  44395. + continue;
  44396. + }
  44397. +
  44398. + /* first get attributes from CPU If */
  44399. + if (MV_OK != status)
  44400. + {
  44401. + mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target);
  44402. + return MV_ERROR;
  44403. + }
  44404. + if (addrDecWin.enable == MV_TRUE)
  44405. + {
  44406. + /* the base is the base of DRAM CS0 always */
  44407. + if (SDRAM_CS0 == target )
  44408. + {
  44409. + pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  44410. + pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  44411. +
  44412. + }
  44413. +
  44414. + /* increment the bar size to be the sum of the size of all
  44415. + DRAM chips selecs */
  44416. + pexBar.addrWin.size += addrDecWin.addrWin.size;
  44417. +
  44418. + /* set a Pex window for this target !
  44419. + DRAM CS always will have a Pex Window , and is not a
  44420. + part of the priority table */
  44421. + pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  44422. + pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  44423. + pexWin.addrWin.size = addrDecWin.addrWin.size;
  44424. +
  44425. + /* we disable the windows at first because we are not
  44426. + sure that it is witihin bar boundries */
  44427. + pexWin.enable =MV_FALSE;
  44428. + pexWin.target = target;
  44429. + pexWin.targetBar = bar;
  44430. +
  44431. + if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,&pexWin))
  44432. + {
  44433. + mvOsPrintf("mvPexInit: ERR. mvPexTargetWinSet failed\n");
  44434. + return MV_ERROR;
  44435. + }
  44436. + }
  44437. + }
  44438. +
  44439. + /* check if the size of the bar is illeggal */
  44440. + if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT))
  44441. + {
  44442. + /* try to get a good size */
  44443. + pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size,
  44444. + PXBCR_BAR_SIZE_ALIGNMENT);
  44445. + }
  44446. +
  44447. + /* check if the size and base are valid */
  44448. + if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin))
  44449. + {
  44450. + mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar);
  44451. + mvOsPrintf("it will be disabled\n");
  44452. + mvOsPrintf("please check Pex and CPU windows configuration\n");
  44453. + }
  44454. + else
  44455. + {
  44456. + pexBar.enable = MV_TRUE;
  44457. +
  44458. + /* configure the bar */
  44459. + if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
  44460. + {
  44461. + mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
  44462. + return MV_ERROR;
  44463. + }
  44464. +
  44465. + /* after the bar was configured then we enable the Pex windows*/
  44466. + for (winNum = 0;winNum < pexCurrWin ;winNum++)
  44467. + {
  44468. + if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE))
  44469. + {
  44470. + mvOsPrintf("mvPexInit: Can't enable window =%d\n",winNum);
  44471. + return MV_ERROR;
  44472. + }
  44473. +
  44474. + }
  44475. + }
  44476. +
  44477. +/******************************************************************************/
  44478. +/* DEVICE bar */
  44479. +/******************************************************************************/
  44480. +
  44481. +/* Open the Device BAR for non linux only */
  44482. +#ifndef MV_DISABLE_PEX_DEVICE_BAR
  44483. +
  44484. + /* then device bar*/
  44485. + bar = PEX_DEVICE_BAR;
  44486. +
  44487. + /* save the starting window */
  44488. + pexStartWindow = pexCurrWin;
  44489. + pexBar.addrWin.size = 0;
  44490. + pexBar.addrWin.baseLow = 0xffffffff;
  44491. + pexBar.addrWin.baseHigh = 0;
  44492. + maxBase = 0;
  44493. +
  44494. + for (target = DEV_TO_TARGET(START_DEV_CS);target < DEV_TO_TARGET(MV_DEV_MAX_CS); target++ )
  44495. + {
  44496. + status = mvCpuIfTargetWinGet(target,&addrDecWin);
  44497. +
  44498. + if (MV_NO_SUCH == status)
  44499. + {
  44500. + continue;
  44501. + }
  44502. +
  44503. + if (MV_OK != status)
  44504. + {
  44505. + mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target);
  44506. + return MV_ERROR;
  44507. + }
  44508. +
  44509. + if (addrDecWin.enable == MV_TRUE)
  44510. + {
  44511. + /* get the minimum base */
  44512. + if (addrDecWin.addrWin.baseLow < pexBar.addrWin.baseLow)
  44513. + {
  44514. + pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  44515. + }
  44516. +
  44517. + /* get the maximum base */
  44518. + if (addrDecWin.addrWin.baseLow > maxBase)
  44519. + {
  44520. + maxBase = addrDecWin.addrWin.baseLow;
  44521. + sizeOfMaxBase = addrDecWin.addrWin.size;
  44522. + }
  44523. +
  44524. + /* search in the priority table for this target */
  44525. + for (winIndex = 0; pexDevBarPrioTable[winIndex] != TBL_TERM;
  44526. + winIndex++)
  44527. + {
  44528. + if (pexDevBarPrioTable[winIndex] != target)
  44529. + {
  44530. + continue;
  44531. + }
  44532. + else if (pexDevBarPrioTable[winIndex] == target)
  44533. + {
  44534. + /*found it */
  44535. +
  44536. + /* if the index of this target in the prio table is valid
  44537. + then we set the Pex window for this target, a valid index is
  44538. + an index that is lower than the number of the windows that
  44539. + was not configured yet */
  44540. +
  44541. + /* we subtract 2 always because the default and expantion
  44542. + rom windows are always configured */
  44543. + if ( pexCurrWin < PEX_MAX_TARGET_WIN - 2)
  44544. + {
  44545. + /* set a Pex window for this target ! */
  44546. + pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  44547. + pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  44548. + pexWin.addrWin.size = addrDecWin.addrWin.size;
  44549. +
  44550. + /* we disable the windows at first because we are not
  44551. + sure that it is witihin bar boundries */
  44552. + pexWin.enable = MV_FALSE;
  44553. + pexWin.target = target;
  44554. + pexWin.targetBar = bar;
  44555. +
  44556. + if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,
  44557. + &pexWin))
  44558. + {
  44559. + mvOsPrintf("mvPexInit: ERR. Window Set failed\n");
  44560. + return MV_ERROR;
  44561. + }
  44562. + }
  44563. + }
  44564. + }
  44565. + }
  44566. + }
  44567. +
  44568. + pexBar.addrWin.size = maxBase - pexBar.addrWin.baseLow + sizeOfMaxBase;
  44569. + pexBar.enable = MV_TRUE;
  44570. +
  44571. + /* check if the size of the bar is illegal */
  44572. + if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT))
  44573. + {
  44574. + /* try to get a good size */
  44575. + pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size,
  44576. + PXBCR_BAR_SIZE_ALIGNMENT);
  44577. + }
  44578. +
  44579. + /* check if the size and base are valid */
  44580. + if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin))
  44581. + {
  44582. + mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar);
  44583. + mvOsPrintf("it will be disabled\n");
  44584. + mvOsPrintf("please check Pex and CPU windows configuration\n");
  44585. + }
  44586. + else
  44587. + {
  44588. + if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
  44589. + {
  44590. + mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
  44591. + return MV_ERROR;
  44592. + }
  44593. +
  44594. + /* now enable the windows */
  44595. + for (winNum = pexStartWindow; winNum < pexCurrWin ; winNum++)
  44596. + {
  44597. + if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE))
  44598. + {
  44599. + mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n",
  44600. + winNum);
  44601. + return MV_ERROR;
  44602. + }
  44603. + }
  44604. + }
  44605. +
  44606. +#endif
  44607. +
  44608. + return mvPexHalInit(pexIf, pexType);
  44609. +
  44610. +}
  44611. +
  44612. +/*******************************************************************************
  44613. +* mvPexTargetWinSet - Set PEX to peripheral target address window BAR
  44614. +*
  44615. +* DESCRIPTION:
  44616. +*
  44617. +* INPUT:
  44618. +*
  44619. +* OUTPUT:
  44620. +* N/A
  44621. +*
  44622. +* RETURN:
  44623. +* MV_OK if PEX BAR target window was set correctly,
  44624. +* MV_BAD_PARAM on bad params
  44625. +* MV_ERROR otherwise
  44626. +* (e.g. address window overlapps with other active PEX target window).
  44627. +*
  44628. +*******************************************************************************/
  44629. +MV_STATUS mvPexTargetWinSet(MV_U32 pexIf, MV_U32 winNum,
  44630. + MV_PEX_DEC_WIN *pAddrDecWin)
  44631. +{
  44632. +
  44633. + MV_DEC_REGS decRegs;
  44634. + PEX_WIN_REG_INFO winRegInfo;
  44635. + MV_TARGET_ATTRIB targetAttribs;
  44636. +
  44637. + /* Parameter checking */
  44638. + if(pexIf >= mvCtrlPexMaxIfGet())
  44639. + {
  44640. + mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX interface %d\n", pexIf);
  44641. + return MV_BAD_PARAM;
  44642. + }
  44643. +
  44644. + if (winNum >= PEX_MAX_TARGET_WIN)
  44645. + {
  44646. + mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX winNum %d\n", winNum);
  44647. + return MV_BAD_PARAM;
  44648. +
  44649. + }
  44650. +
  44651. + /* get the pex Window registers offsets */
  44652. + pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
  44653. +
  44654. +
  44655. + if (MV_TRUE == pAddrDecWin->enable)
  44656. + {
  44657. +
  44658. + /* 2) Check if the requested window overlaps with current windows */
  44659. + if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &pAddrDecWin->addrWin))
  44660. + {
  44661. + mvOsPrintf("mvPexTargetWinSet: ERR. Target %d overlap\n", winNum);
  44662. + return MV_BAD_PARAM;
  44663. + }
  44664. +
  44665. + /* 2) Check if the requested window overlaps with current windows */
  44666. + if (MV_FALSE == pexIsWinWithinBar(pexIf,&pAddrDecWin->addrWin))
  44667. + {
  44668. + mvOsPrintf("mvPexTargetWinSet: Win %d should be in bar boundries\n",
  44669. + winNum);
  44670. + return MV_BAD_PARAM;
  44671. + }
  44672. +
  44673. + }
  44674. +
  44675. +
  44676. +
  44677. + /* read base register*/
  44678. +
  44679. + if (winRegInfo.baseLowRegOffs)
  44680. + {
  44681. + decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs);
  44682. + }
  44683. + else
  44684. + {
  44685. + decRegs.baseReg = 0;
  44686. + }
  44687. +
  44688. + if (winRegInfo.sizeRegOffs)
  44689. + {
  44690. + decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs);
  44691. + }
  44692. + else
  44693. + {
  44694. + decRegs.sizeReg =0;
  44695. + }
  44696. +
  44697. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  44698. + {
  44699. + mvOsPrintf("mvPexTargetWinSet:mvCtrlAddrDecToReg Failed\n");
  44700. + return MV_ERROR;
  44701. + }
  44702. +
  44703. + /* enable\Disable */
  44704. + if (MV_TRUE == pAddrDecWin->enable)
  44705. + {
  44706. + decRegs.sizeReg |= PXWCR_WIN_EN;
  44707. + }
  44708. + else
  44709. + {
  44710. + decRegs.sizeReg &= ~PXWCR_WIN_EN;
  44711. + }
  44712. +
  44713. +
  44714. + /* clear bit location */
  44715. + decRegs.sizeReg &= ~PXWCR_WIN_BAR_MAP_MASK;
  44716. +
  44717. + /* set bar Mapping */
  44718. + if (pAddrDecWin->targetBar == 1)
  44719. + {
  44720. + decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR1;
  44721. + }
  44722. + else if (pAddrDecWin->targetBar == 2)
  44723. + {
  44724. + decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR2;
  44725. + }
  44726. +
  44727. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  44728. +
  44729. + /* set attributes */
  44730. + decRegs.sizeReg &= ~PXWCR_ATTRIB_MASK;
  44731. + decRegs.sizeReg |= targetAttribs.attrib << PXWCR_ATTRIB_OFFS;
  44732. + /* set target ID */
  44733. + decRegs.sizeReg &= ~PXWCR_TARGET_MASK;
  44734. + decRegs.sizeReg |= targetAttribs.targetId << PXWCR_TARGET_OFFS;
  44735. +
  44736. +
  44737. + /* 3) Write to address decode Base Address Register */
  44738. +
  44739. + if (winRegInfo.baseLowRegOffs)
  44740. + {
  44741. + MV_REG_WRITE(winRegInfo.baseLowRegOffs, decRegs.baseReg);
  44742. + }
  44743. +
  44744. + /* write size reg */
  44745. + if (winRegInfo.sizeRegOffs)
  44746. + {
  44747. + if ((MV_PEX_WIN_DEFAULT == winNum)||
  44748. + (MV_PEX_WIN_EXP_ROM == winNum))
  44749. + {
  44750. + /* clear size because there is no size field*/
  44751. + decRegs.sizeReg &= ~PXWCR_SIZE_MASK;
  44752. +
  44753. + /* clear enable because there is no enable field*/
  44754. + decRegs.sizeReg &= ~PXWCR_WIN_EN;
  44755. +
  44756. + }
  44757. +
  44758. + MV_REG_WRITE(winRegInfo.sizeRegOffs, decRegs.sizeReg);
  44759. + }
  44760. +
  44761. +
  44762. + return MV_OK;
  44763. +
  44764. +}
  44765. +
  44766. +/*******************************************************************************
  44767. +* mvPexTargetWinGet - Get PEX to peripheral target address window
  44768. +*
  44769. +* DESCRIPTION:
  44770. +* Get the PEX to peripheral target address window BAR.
  44771. +*
  44772. +* INPUT:
  44773. +* pexIf - PEX interface number.
  44774. +* bar - BAR to be accessed by slave.
  44775. +*
  44776. +* OUTPUT:
  44777. +* pAddrBarWin - PEX target window information data structure.
  44778. +*
  44779. +* RETURN:
  44780. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  44781. +*
  44782. +*******************************************************************************/
  44783. +MV_STATUS mvPexTargetWinGet(MV_U32 pexIf, MV_U32 winNum,
  44784. + MV_PEX_DEC_WIN *pAddrDecWin)
  44785. +{
  44786. + MV_TARGET_ATTRIB targetAttrib;
  44787. + MV_DEC_REGS decRegs;
  44788. +
  44789. + PEX_WIN_REG_INFO winRegInfo;
  44790. +
  44791. + /* Parameter checking */
  44792. + if(pexIf >= mvCtrlPexMaxIfGet())
  44793. + {
  44794. + mvOsPrintf("mvPexTargetWinGet: ERR. Invalid PEX interface %d\n", pexIf);
  44795. + return MV_BAD_PARAM;
  44796. + }
  44797. +
  44798. + if (winNum >= PEX_MAX_TARGET_WIN)
  44799. + {
  44800. + mvOsPrintf("mvPexTargetWinGet: ERR. Invalid PEX winNum %d\n", winNum);
  44801. + return MV_BAD_PARAM;
  44802. +
  44803. + }
  44804. +
  44805. + /* get the pex Window registers offsets */
  44806. + pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
  44807. +
  44808. + /* read base register*/
  44809. + if (winRegInfo.baseLowRegOffs)
  44810. + {
  44811. + decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs);
  44812. + }
  44813. + else
  44814. + {
  44815. + decRegs.baseReg = 0;
  44816. + }
  44817. +
  44818. + /* read size reg */
  44819. + if (winRegInfo.sizeRegOffs)
  44820. + {
  44821. + decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs);
  44822. + }
  44823. + else
  44824. + {
  44825. + decRegs.sizeReg =0;
  44826. + }
  44827. +
  44828. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  44829. + {
  44830. + mvOsPrintf("mvPexTargetWinGet: mvCtrlRegToAddrDec Failed \n");
  44831. + return MV_ERROR;
  44832. +
  44833. + }
  44834. +
  44835. + if (decRegs.sizeReg & PXWCR_WIN_EN)
  44836. + {
  44837. + pAddrDecWin->enable = MV_TRUE;
  44838. + }
  44839. + else
  44840. + {
  44841. + pAddrDecWin->enable = MV_FALSE;
  44842. +
  44843. + }
  44844. +
  44845. +
  44846. + #if 0
  44847. + if (-1 == pAddrDecWin->addrWin.size)
  44848. + {
  44849. + return MV_ERROR;
  44850. + }
  44851. + #endif
  44852. +
  44853. +
  44854. + /* get target bar */
  44855. + if ((decRegs.sizeReg & PXWCR_WIN_BAR_MAP_MASK) == PXWCR_WIN_BAR_MAP_BAR1 )
  44856. + {
  44857. + pAddrDecWin->targetBar = 1;
  44858. + }
  44859. + else if ((decRegs.sizeReg & PXWCR_WIN_BAR_MAP_MASK) ==
  44860. + PXWCR_WIN_BAR_MAP_BAR2 )
  44861. + {
  44862. + pAddrDecWin->targetBar = 2;
  44863. + }
  44864. +
  44865. + /* attrib and targetId */
  44866. + pAddrDecWin->attrib = (decRegs.sizeReg & PXWCR_ATTRIB_MASK) >>
  44867. + PXWCR_ATTRIB_OFFS;
  44868. + pAddrDecWin->targetId = (decRegs.sizeReg & PXWCR_TARGET_MASK) >>
  44869. + PXWCR_TARGET_OFFS;
  44870. +
  44871. + targetAttrib.attrib = pAddrDecWin->attrib;
  44872. + targetAttrib.targetId = pAddrDecWin->targetId;
  44873. +
  44874. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  44875. +
  44876. + return MV_OK;
  44877. +
  44878. +}
  44879. +
  44880. +
  44881. +/*******************************************************************************
  44882. +* mvPexTargetWinEnable - Enable/disable a PEX BAR window
  44883. +*
  44884. +* DESCRIPTION:
  44885. +* This function enable/disable a PEX BAR window.
  44886. +* if parameter 'enable' == MV_TRUE the routine will enable the
  44887. +* window, thus enabling PEX accesses for that BAR (before enabling the
  44888. +* window it is tested for overlapping). Otherwise, the window will
  44889. +* be disabled.
  44890. +*
  44891. +* INPUT:
  44892. +* pexIf - PEX interface number.
  44893. +* bar - BAR to be accessed by slave.
  44894. +* enable - Enable/disable parameter.
  44895. +*
  44896. +* OUTPUT:
  44897. +* None.
  44898. +*
  44899. +* RETURN:
  44900. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  44901. +*
  44902. +*******************************************************************************/
  44903. +MV_STATUS mvPexTargetWinEnable(MV_U32 pexIf,MV_U32 winNum, MV_BOOL enable)
  44904. +{
  44905. + PEX_WIN_REG_INFO winRegInfo;
  44906. + MV_PEX_DEC_WIN addrDecWin;
  44907. +
  44908. + /* Parameter checking */
  44909. + if(pexIf >= mvCtrlPexMaxIfGet())
  44910. + {
  44911. + mvOsPrintf("mvPexTargetWinEnable: ERR. Invalid PEX If %d\n", pexIf);
  44912. + return MV_BAD_PARAM;
  44913. + }
  44914. +
  44915. + if (winNum >= PEX_MAX_TARGET_WIN)
  44916. + {
  44917. + mvOsPrintf("mvPexTargetWinEnable ERR. Invalid PEX winNum %d\n", winNum);
  44918. + return MV_BAD_PARAM;
  44919. +
  44920. + }
  44921. +
  44922. +
  44923. + /* get the pex Window registers offsets */
  44924. + pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
  44925. +
  44926. +
  44927. + /* if the address windows is disabled , we only disable the appropriare
  44928. + pex window and ignore other settings */
  44929. +
  44930. + if (MV_FALSE == enable)
  44931. + {
  44932. +
  44933. + /* this is not relevant to default and expantion rom
  44934. + windows */
  44935. + if (winRegInfo.sizeRegOffs)
  44936. + {
  44937. + if ((MV_PEX_WIN_DEFAULT != winNum)&&
  44938. + (MV_PEX_WIN_EXP_ROM != winNum))
  44939. + {
  44940. + MV_REG_BIT_RESET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN);
  44941. + }
  44942. + }
  44943. +
  44944. + }
  44945. + else
  44946. + {
  44947. + if (MV_OK != mvPexTargetWinGet(pexIf,winNum, &addrDecWin))
  44948. + {
  44949. + mvOsPrintf("mvPexTargetWinEnable: mvPexTargetWinGet Failed\n");
  44950. + return MV_ERROR;
  44951. + }
  44952. +
  44953. + /* Check if the requested window overlaps with current windows */
  44954. + if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &addrDecWin.addrWin))
  44955. + {
  44956. + mvOsPrintf("mvPexTargetWinEnable: ERR. Target %d overlap\n", winNum);
  44957. + return MV_BAD_PARAM;
  44958. + }
  44959. +
  44960. + if (MV_FALSE == pexIsWinWithinBar(pexIf,&addrDecWin.addrWin))
  44961. + {
  44962. + mvOsPrintf("mvPexTargetWinEnable: Win %d should be in bar boundries\n",
  44963. + winNum);
  44964. + return MV_BAD_PARAM;
  44965. + }
  44966. +
  44967. +
  44968. + /* this is not relevant to default and expantion rom
  44969. + windows */
  44970. + if (winRegInfo.sizeRegOffs)
  44971. + {
  44972. + if ((MV_PEX_WIN_DEFAULT != winNum)&&
  44973. + (MV_PEX_WIN_EXP_ROM != winNum))
  44974. + {
  44975. + MV_REG_BIT_SET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN);
  44976. + }
  44977. + }
  44978. +
  44979. +
  44980. + }
  44981. +
  44982. + return MV_OK;
  44983. +
  44984. +}
  44985. +
  44986. +
  44987. +
  44988. +/*******************************************************************************
  44989. +* mvPexTargetWinRemap - Set PEX to target address window remap.
  44990. +*
  44991. +* DESCRIPTION:
  44992. +* The PEX interface supports remap of the BAR original address window.
  44993. +* For each BAR it is possible to define a remap address. For example
  44994. +* an address 0x12345678 that hits BAR 0x10 (SDRAM CS[0]) will be modified
  44995. +* according to remap register but will also be targeted to the
  44996. +* SDRAM CS[0].
  44997. +*
  44998. +* INPUT:
  44999. +* pexIf - PEX interface number.
  45000. +* bar - Peripheral target enumerator accessed by slave.
  45001. +* pAddrWin - Address window to be checked.
  45002. +*
  45003. +* OUTPUT:
  45004. +* None.
  45005. +*
  45006. +* RETURN:
  45007. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  45008. +*
  45009. +*******************************************************************************/
  45010. +MV_STATUS mvPexTargetWinRemap(MV_U32 pexIf, MV_U32 winNum,
  45011. + MV_PEX_REMAP_WIN *pAddrWin)
  45012. +{
  45013. +
  45014. + PEX_WIN_REG_INFO winRegInfo;
  45015. +
  45016. + /* Parameter checking */
  45017. + if (pexIf >= mvCtrlPexMaxIfGet())
  45018. + {
  45019. + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n",
  45020. + pexIf);
  45021. + return MV_BAD_PARAM;
  45022. + }
  45023. + if (MV_PEX_WIN_DEFAULT == winNum)
  45024. + {
  45025. + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n",
  45026. + winNum);
  45027. + return MV_BAD_PARAM;
  45028. +
  45029. + }
  45030. +
  45031. + if (MV_IS_NOT_ALIGN(pAddrWin->addrWin.baseLow, PXWRR_REMAP_ALIGNMENT))
  45032. + {
  45033. + mvOsPrintf("mvPexTargetWinRemap: Error remap PEX interface %d win %d."\
  45034. + "\nAddress 0x%08x is unaligned to size 0x%x.\n",
  45035. + pexIf,
  45036. + winNum,
  45037. + pAddrWin->addrWin.baseLow,
  45038. + pAddrWin->addrWin.size);
  45039. +
  45040. + return MV_ERROR;
  45041. + }
  45042. +
  45043. + pexWinRegInfoGet(pexIf, winNum, &winRegInfo);
  45044. +
  45045. + /* Set remap low register value */
  45046. + MV_REG_WRITE(winRegInfo.remapLowRegOffs, pAddrWin->addrWin.baseLow);
  45047. +
  45048. + /* Skip base high settings if the BAR has only base low (32-bit) */
  45049. + if (0 != winRegInfo.remapHighRegOffs)
  45050. + {
  45051. + MV_REG_WRITE(winRegInfo.remapHighRegOffs, pAddrWin->addrWin.baseHigh);
  45052. + }
  45053. +
  45054. +
  45055. + if (pAddrWin->enable == MV_TRUE)
  45056. + {
  45057. + MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
  45058. + }
  45059. + else
  45060. + {
  45061. + MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
  45062. + }
  45063. +
  45064. + return MV_OK;
  45065. +}
  45066. +
  45067. +/*******************************************************************************
  45068. +* mvPexTargetWinRemapEnable -
  45069. +*
  45070. +* DESCRIPTION:
  45071. +*
  45072. +* INPUT:
  45073. +*
  45074. +* OUTPUT:
  45075. +*
  45076. +* RETURN:
  45077. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  45078. +*
  45079. +*******************************************************************************/
  45080. +
  45081. +MV_STATUS mvPexTargetWinRemapEnable(MV_U32 pexIf, MV_U32 winNum,
  45082. + MV_BOOL enable)
  45083. +{
  45084. + PEX_WIN_REG_INFO winRegInfo;
  45085. +
  45086. + /* Parameter checking */
  45087. + if (pexIf >= mvCtrlPexMaxIfGet())
  45088. + {
  45089. + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n",
  45090. + pexIf);
  45091. + return MV_BAD_PARAM;
  45092. + }
  45093. + if (MV_PEX_WIN_DEFAULT == winNum)
  45094. + {
  45095. + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n",
  45096. + winNum);
  45097. + return MV_BAD_PARAM;
  45098. +
  45099. + }
  45100. +
  45101. +
  45102. + pexWinRegInfoGet(pexIf, winNum, &winRegInfo);
  45103. +
  45104. + if (enable == MV_TRUE)
  45105. + {
  45106. + MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
  45107. + }
  45108. + else
  45109. + {
  45110. + MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
  45111. + }
  45112. +
  45113. + return MV_OK;
  45114. +
  45115. +}
  45116. +
  45117. +/*******************************************************************************
  45118. +* mvPexBarSet - Set PEX bar address and size
  45119. +*
  45120. +* DESCRIPTION:
  45121. +*
  45122. +* INPUT:
  45123. +*
  45124. +* OUTPUT:
  45125. +* None.
  45126. +*
  45127. +* RETURN:
  45128. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  45129. +*
  45130. +*******************************************************************************/
  45131. +MV_STATUS mvPexBarSet(MV_U32 pexIf,
  45132. + MV_U32 barNum,
  45133. + MV_PEX_BAR *pAddrWin)
  45134. +{
  45135. + MV_U32 regBaseLow;
  45136. + MV_U32 regSize,sizeToReg;
  45137. +
  45138. +
  45139. + /* check parameters */
  45140. + if(pexIf >= mvCtrlPexMaxIfGet())
  45141. + {
  45142. + mvOsPrintf("mvPexBarSet: ERR. Invalid PEX interface %d\n", pexIf);
  45143. + return MV_BAD_PARAM;
  45144. + }
  45145. +
  45146. + if(barNum >= PEX_MAX_BARS)
  45147. + {
  45148. + mvOsPrintf("mvPexBarSet: ERR. Invalid bar number %d\n", barNum);
  45149. + return MV_BAD_PARAM;
  45150. + }
  45151. +
  45152. +
  45153. + if (pAddrWin->addrWin.size == 0)
  45154. + {
  45155. + mvOsPrintf("mvPexBarSet: Size zero is Illigal\n" );
  45156. + return MV_BAD_PARAM;
  45157. + }
  45158. +
  45159. +
  45160. + /* Check if the window complies with PEX spec */
  45161. + if (MV_TRUE != pexBarIsValid(pAddrWin->addrWin.baseLow,
  45162. + pAddrWin->addrWin.size))
  45163. + {
  45164. + mvOsPrintf("mvPexBarSet: ERR. Target %d window invalid\n", barNum);
  45165. + return MV_BAD_PARAM;
  45166. + }
  45167. +
  45168. + /* 2) Check if the requested bar overlaps with current bars */
  45169. + if (MV_TRUE == pexBarOverlapDetect(pexIf,barNum, &pAddrWin->addrWin))
  45170. + {
  45171. + mvOsPrintf("mvPexBarSet: ERR. Target %d overlap\n", barNum);
  45172. + return MV_BAD_PARAM;
  45173. + }
  45174. +
  45175. + /* Get size register value according to window size */
  45176. + sizeToReg = ctrlSizeToReg(pAddrWin->addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT);
  45177. +
  45178. + /* Read bar size */
  45179. + if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */
  45180. + {
  45181. + regSize = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum));
  45182. +
  45183. + /* Size parameter validity check. */
  45184. + if (-1 == sizeToReg)
  45185. + {
  45186. + mvOsPrintf("mvPexBarSet: ERR. Target BAR %d size invalid.\n",barNum);
  45187. + return MV_BAD_PARAM;
  45188. + }
  45189. +
  45190. + regSize &= ~PXBCR_BAR_SIZE_MASK;
  45191. + regSize |= (sizeToReg << PXBCR_BAR_SIZE_OFFS) ;
  45192. +
  45193. + MV_REG_WRITE(PEX_BAR_CTRL_REG(pexIf,barNum),regSize);
  45194. +
  45195. + }
  45196. +
  45197. + /* set size */
  45198. +
  45199. +
  45200. +
  45201. + /* Read base address low */
  45202. + regBaseLow = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,
  45203. + PEX_MV_BAR_BASE(barNum)));
  45204. +
  45205. + /* clear current base */
  45206. + if (PEX_INTER_REGS_BAR == barNum)
  45207. + {
  45208. + regBaseLow &= ~PXBIR_BASE_MASK;
  45209. + regBaseLow |= (pAddrWin->addrWin.baseLow & PXBIR_BASE_MASK);
  45210. + }
  45211. + else
  45212. + {
  45213. + regBaseLow &= ~PXBR_BASE_MASK;
  45214. + regBaseLow |= (pAddrWin->addrWin.baseLow & PXBR_BASE_MASK);
  45215. + }
  45216. +
  45217. + /* if we had a previous value that contain the bar type (MeM\IO), we want to
  45218. + restore it */
  45219. + regBaseLow |= PEX_BAR_DEFAULT_ATTRIB;
  45220. +
  45221. +
  45222. +
  45223. + /* write base low */
  45224. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)),
  45225. + regBaseLow);
  45226. +
  45227. + if (pAddrWin->addrWin.baseHigh != 0)
  45228. + {
  45229. + /* Read base address high */
  45230. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)),
  45231. + pAddrWin->addrWin.baseHigh);
  45232. +
  45233. + }
  45234. +
  45235. + /* lastly enable the Bar */
  45236. + if (pAddrWin->enable == MV_TRUE)
  45237. + {
  45238. + if (PEX_INTER_REGS_BAR != barNum) /* internal registers
  45239. + are enabled always */
  45240. + {
  45241. + MV_REG_BIT_SET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
  45242. + }
  45243. + }
  45244. + else if (MV_FALSE == pAddrWin->enable)
  45245. + {
  45246. + if (PEX_INTER_REGS_BAR != barNum) /* internal registers
  45247. + are enabled always */
  45248. + {
  45249. + MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
  45250. + }
  45251. +
  45252. + }
  45253. +
  45254. +
  45255. +
  45256. + return MV_OK;
  45257. +}
  45258. +
  45259. +
  45260. +/*******************************************************************************
  45261. +* mvPexBarGet - Get PEX bar address and size
  45262. +*
  45263. +* DESCRIPTION:
  45264. +*
  45265. +* INPUT:
  45266. +*
  45267. +* OUTPUT:
  45268. +* None.
  45269. +*
  45270. +* RETURN:
  45271. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  45272. +*
  45273. +*******************************************************************************/
  45274. +
  45275. +MV_STATUS mvPexBarGet(MV_U32 pexIf,
  45276. + MV_U32 barNum,
  45277. + MV_PEX_BAR *pAddrWin)
  45278. +{
  45279. + /* check parameters */
  45280. + if(pexIf >= mvCtrlPexMaxIfGet())
  45281. + {
  45282. + mvOsPrintf("mvPexBarGet: ERR. Invalid PEX interface %d\n", pexIf);
  45283. + return MV_BAD_PARAM;
  45284. + }
  45285. +
  45286. + if(barNum >= PEX_MAX_BARS)
  45287. + {
  45288. + mvOsPrintf("mvPexBarGet: ERR. Invalid bar number %d\n", barNum);
  45289. + return MV_BAD_PARAM;
  45290. + }
  45291. +
  45292. + /* read base low */
  45293. + pAddrWin->addrWin.baseLow =
  45294. + MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)));
  45295. +
  45296. +
  45297. + if (PEX_INTER_REGS_BAR == barNum)
  45298. + {
  45299. + pAddrWin->addrWin.baseLow &= PXBIR_BASE_MASK;
  45300. + }
  45301. + else
  45302. + {
  45303. + pAddrWin->addrWin.baseLow &= PXBR_BASE_MASK;
  45304. + }
  45305. +
  45306. +
  45307. + /* read base high */
  45308. + pAddrWin->addrWin.baseHigh =
  45309. + MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)));
  45310. +
  45311. +
  45312. + /* Read bar size */
  45313. + if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */
  45314. + {
  45315. + pAddrWin->addrWin.size = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum));
  45316. +
  45317. + /* check if enable or not */
  45318. + if (pAddrWin->addrWin.size & PXBCR_BAR_EN)
  45319. + {
  45320. + pAddrWin->enable = MV_TRUE;
  45321. + }
  45322. + else
  45323. + {
  45324. + pAddrWin->enable = MV_FALSE;
  45325. + }
  45326. +
  45327. + /* now get the size */
  45328. + pAddrWin->addrWin.size &= PXBCR_BAR_SIZE_MASK;
  45329. + pAddrWin->addrWin.size >>= PXBCR_BAR_SIZE_OFFS;
  45330. +
  45331. + pAddrWin->addrWin.size = ctrlRegToSize(pAddrWin->addrWin.size,
  45332. + PXBCR_BAR_SIZE_ALIGNMENT);
  45333. +
  45334. + }
  45335. + else /* PEX_INTER_REGS_BAR */
  45336. + {
  45337. + pAddrWin->addrWin.size = INTER_REGS_SIZE;
  45338. + pAddrWin->enable = MV_TRUE;
  45339. + }
  45340. +
  45341. +
  45342. + return MV_OK;
  45343. +}
  45344. +
  45345. +/*******************************************************************************
  45346. +* mvPexBarEnable -
  45347. +*
  45348. +* DESCRIPTION:
  45349. +*
  45350. +* INPUT:
  45351. +*
  45352. +* OUTPUT:
  45353. +* None.
  45354. +*
  45355. +* RETURN:
  45356. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  45357. +*
  45358. +*******************************************************************************/
  45359. +
  45360. +
  45361. +MV_STATUS mvPexBarEnable(MV_U32 pexIf, MV_U32 barNum, MV_BOOL enable)
  45362. +{
  45363. +
  45364. + MV_PEX_BAR pexBar;
  45365. +
  45366. + /* check parameters */
  45367. + if(pexIf >= mvCtrlPexMaxIfGet())
  45368. + {
  45369. + mvOsPrintf("mvPexBarEnable: ERR. Invalid PEX interface %d\n", pexIf);
  45370. + return MV_BAD_PARAM;
  45371. + }
  45372. +
  45373. +
  45374. + if(barNum >= PEX_MAX_BARS)
  45375. + {
  45376. + mvOsPrintf("mvPexBarEnable: ERR. Invalid bar number %d\n", barNum);
  45377. + return MV_BAD_PARAM;
  45378. + }
  45379. +
  45380. + if (PEX_INTER_REGS_BAR == barNum)
  45381. + {
  45382. + if (MV_TRUE == enable)
  45383. + {
  45384. + return MV_OK;
  45385. + }
  45386. + else
  45387. + {
  45388. + return MV_ERROR;
  45389. + }
  45390. + }
  45391. +
  45392. +
  45393. + if (MV_FALSE == enable)
  45394. + {
  45395. + /* disable bar and quit */
  45396. + MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
  45397. + return MV_OK;
  45398. + }
  45399. +
  45400. + /* else */
  45401. +
  45402. + if (mvPexBarGet(pexIf,barNum,&pexBar) != MV_OK)
  45403. + {
  45404. + mvOsPrintf("mvPexBarEnable: mvPexBarGet Failed\n");
  45405. + return MV_ERROR;
  45406. +
  45407. + }
  45408. +
  45409. + if (MV_TRUE == pexBar.enable)
  45410. + {
  45411. + /* it is already enabled !!! */
  45412. + return MV_OK;
  45413. + }
  45414. +
  45415. + /* else enable the bar*/
  45416. +
  45417. + pexBar.enable = MV_TRUE;
  45418. +
  45419. + if (mvPexBarSet(pexIf,barNum,&pexBar) != MV_OK)
  45420. + {
  45421. + mvOsPrintf("mvPexBarEnable: mvPexBarSet Failed\n");
  45422. + return MV_ERROR;
  45423. +
  45424. + }
  45425. +
  45426. + return MV_OK;
  45427. +}
  45428. +
  45429. +
  45430. +/*******************************************************************************
  45431. +* pexWinOverlapDetect - Detect address windows overlapping
  45432. +*
  45433. +* DESCRIPTION:
  45434. +* This function detects address window overlapping of a given address
  45435. +* window in PEX BARs.
  45436. +*
  45437. +* INPUT:
  45438. +* pAddrWin - Address window to be checked.
  45439. +* bar - BAR to be accessed by slave.
  45440. +*
  45441. +* OUTPUT:
  45442. +* None.
  45443. +*
  45444. +* RETURN:
  45445. +* MV_TRUE if the given address window overlap current address
  45446. +* decode map, MV_FALSE otherwise.
  45447. +*
  45448. +*******************************************************************************/
  45449. +static MV_BOOL pexWinOverlapDetect(MV_U32 pexIf,
  45450. + MV_U32 winNum,
  45451. + MV_ADDR_WIN *pAddrWin)
  45452. +{
  45453. + MV_U32 win;
  45454. + MV_PEX_DEC_WIN addrDecWin;
  45455. +
  45456. +
  45457. + for(win = 0; win < PEX_MAX_TARGET_WIN -2 ; win++)
  45458. + {
  45459. + /* don't check our target or illegal targets */
  45460. + if (winNum == win)
  45461. + {
  45462. + continue;
  45463. + }
  45464. +
  45465. + /* Get window parameters */
  45466. + if (MV_OK != mvPexTargetWinGet(pexIf, win, &addrDecWin))
  45467. + {
  45468. + mvOsPrintf("pexWinOverlapDetect: ERR. TargetWinGet failed win=%x\n",
  45469. + win);
  45470. + return MV_ERROR;
  45471. + }
  45472. +
  45473. + /* Do not check disabled windows */
  45474. + if (MV_FALSE == addrDecWin.enable)
  45475. + {
  45476. + continue;
  45477. + }
  45478. +
  45479. +
  45480. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
  45481. + {
  45482. + mvOsPrintf("pexWinOverlapDetect: winNum %d overlap current %d\n",
  45483. + winNum, win);
  45484. + return MV_TRUE;
  45485. + }
  45486. + }
  45487. +
  45488. + return MV_FALSE;
  45489. +}
  45490. +
  45491. +/*******************************************************************************
  45492. +* pexIsWinWithinBar - Detect if address is within PEX bar boundries
  45493. +*
  45494. +* DESCRIPTION:
  45495. +*
  45496. +* INPUT:
  45497. +*
  45498. +* OUTPUT:
  45499. +* None.
  45500. +*
  45501. +* RETURN:
  45502. +* MV_TRUE if the given address window overlap current address
  45503. +* decode map, MV_FALSE otherwise.
  45504. +*
  45505. +*******************************************************************************/
  45506. +static MV_BOOL pexIsWinWithinBar(MV_U32 pexIf,
  45507. + MV_ADDR_WIN *pAddrWin)
  45508. +{
  45509. + MV_U32 bar;
  45510. + MV_PEX_BAR addrDecWin;
  45511. +
  45512. + for(bar = 0; bar < PEX_MAX_BARS; bar++)
  45513. + {
  45514. +
  45515. + /* Get window parameters */
  45516. + if (MV_OK != mvPexBarGet(pexIf, bar, &addrDecWin))
  45517. + {
  45518. + mvOsPrintf("pexIsWinWithinBar: ERR. mvPexBarGet failed\n");
  45519. + return MV_ERROR;
  45520. + }
  45521. +
  45522. + /* Do not check disabled bars */
  45523. + if (MV_FALSE == addrDecWin.enable)
  45524. + {
  45525. + continue;
  45526. + }
  45527. +
  45528. +
  45529. + if(MV_TRUE == ctrlWinWithinWinTest(pAddrWin, &addrDecWin.addrWin))
  45530. + {
  45531. + return MV_TRUE;
  45532. + }
  45533. + }
  45534. +
  45535. + return MV_FALSE;
  45536. +
  45537. +}
  45538. +
  45539. +/*******************************************************************************
  45540. +* pexBarOverlapDetect - Detect address windows overlapping
  45541. +*
  45542. +* DESCRIPTION:
  45543. +* This function detects address window overlapping of a given address
  45544. +* window in PEX BARs.
  45545. +*
  45546. +* INPUT:
  45547. +* pAddrWin - Address window to be checked.
  45548. +* bar - BAR to be accessed by slave.
  45549. +*
  45550. +* OUTPUT:
  45551. +* None.
  45552. +*
  45553. +* RETURN:
  45554. +* MV_TRUE if the given address window overlap current address
  45555. +* decode map, MV_FALSE otherwise.
  45556. +*
  45557. +*******************************************************************************/
  45558. +static MV_BOOL pexBarOverlapDetect(MV_U32 pexIf,
  45559. + MV_U32 barNum,
  45560. + MV_ADDR_WIN *pAddrWin)
  45561. +{
  45562. + MV_U32 bar;
  45563. + MV_PEX_BAR barDecWin;
  45564. +
  45565. +
  45566. + for(bar = 0; bar < PEX_MAX_BARS; bar++)
  45567. + {
  45568. + /* don't check our target or illegal targets */
  45569. + if (barNum == bar)
  45570. + {
  45571. + continue;
  45572. + }
  45573. +
  45574. + /* Get window parameters */
  45575. + if (MV_OK != mvPexBarGet(pexIf, bar, &barDecWin))
  45576. + {
  45577. + mvOsPrintf("pexBarOverlapDetect: ERR. TargetWinGet failed\n");
  45578. + return MV_ERROR;
  45579. + }
  45580. +
  45581. + /* don'nt check disabled bars */
  45582. + if (barDecWin.enable == MV_FALSE)
  45583. + {
  45584. + continue;
  45585. + }
  45586. +
  45587. +
  45588. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &barDecWin.addrWin))
  45589. + {
  45590. + mvOsPrintf("pexBarOverlapDetect: winNum %d overlap current %d\n",
  45591. + barNum, bar);
  45592. + return MV_TRUE;
  45593. + }
  45594. + }
  45595. +
  45596. + return MV_FALSE;
  45597. +}
  45598. +
  45599. +/*******************************************************************************
  45600. +* pexBarIsValid - Check if the given address window is valid
  45601. +*
  45602. +* DESCRIPTION:
  45603. +* PEX spec restrict BAR base to be aligned to BAR size.
  45604. +* This function checks if the given address window is valid.
  45605. +*
  45606. +* INPUT:
  45607. +* baseLow - 32bit low base address.
  45608. +* size - Window size.
  45609. +*
  45610. +* OUTPUT:
  45611. +* None.
  45612. +*
  45613. +* RETURN:
  45614. +* MV_TRUE if the address window is valid, MV_FALSE otherwise.
  45615. +*
  45616. +*******************************************************************************/
  45617. +static MV_STATUS pexBarIsValid(MV_U32 baseLow, MV_U32 size)
  45618. +{
  45619. +
  45620. + /* PCI spec restrict BAR base to be aligned to BAR size */
  45621. + if(MV_IS_NOT_ALIGN(baseLow, size))
  45622. + {
  45623. + return MV_ERROR;
  45624. + }
  45625. + else
  45626. + {
  45627. + return MV_TRUE;
  45628. + }
  45629. +
  45630. + return MV_TRUE;
  45631. +}
  45632. +
  45633. +/*******************************************************************************
  45634. +* pexBarRegInfoGet - Get BAR register information
  45635. +*
  45636. +* DESCRIPTION:
  45637. +* PEX BARs registers offsets are inconsecutive.
  45638. +* This function gets a PEX BAR register information like register offsets
  45639. +* and function location of the BAR.
  45640. +*
  45641. +* INPUT:
  45642. +* pexIf - PEX interface number.
  45643. +* bar - The PEX BAR in question.
  45644. +*
  45645. +* OUTPUT:
  45646. +* pBarRegInfo - BAR register info struct.
  45647. +*
  45648. +* RETURN:
  45649. +* MV_BAD_PARAM when bad parameters ,MV_ERROR on error ,othewise MV_OK
  45650. +*
  45651. +*******************************************************************************/
  45652. +static MV_STATUS pexWinRegInfoGet(MV_U32 pexIf,
  45653. + MV_U32 winNum,
  45654. + PEX_WIN_REG_INFO *pWinRegInfo)
  45655. +{
  45656. +
  45657. + if ((winNum >= 0)&&(winNum <=3))
  45658. + {
  45659. + pWinRegInfo->baseLowRegOffs = PEX_WIN0_3_BASE_REG(pexIf,winNum);
  45660. + pWinRegInfo->baseHighRegOffs = 0;
  45661. + pWinRegInfo->sizeRegOffs = PEX_WIN0_3_CTRL_REG(pexIf,winNum);
  45662. + pWinRegInfo->remapLowRegOffs = PEX_WIN0_3_REMAP_REG(pexIf,winNum);
  45663. + pWinRegInfo->remapHighRegOffs = 0;
  45664. + }
  45665. + else if ((winNum >= 4)&&(winNum <=5))
  45666. + {
  45667. + pWinRegInfo->baseLowRegOffs = PEX_WIN4_5_BASE_REG(pexIf,winNum);
  45668. + pWinRegInfo->baseHighRegOffs = 0;
  45669. + pWinRegInfo->sizeRegOffs = PEX_WIN4_5_CTRL_REG(pexIf,winNum);
  45670. + pWinRegInfo->remapLowRegOffs = PEX_WIN4_5_REMAP_REG(pexIf,winNum);
  45671. + pWinRegInfo->remapHighRegOffs = PEX_WIN4_5_REMAP_HIGH_REG(pexIf,winNum);
  45672. +
  45673. + }
  45674. + else if (MV_PEX_WIN_DEFAULT == winNum)
  45675. + {
  45676. + pWinRegInfo->baseLowRegOffs = 0;
  45677. + pWinRegInfo->baseHighRegOffs = 0;
  45678. + pWinRegInfo->sizeRegOffs = PEX_WIN_DEFAULT_CTRL_REG(pexIf);
  45679. + pWinRegInfo->remapLowRegOffs = 0;
  45680. + pWinRegInfo->remapHighRegOffs = 0;
  45681. + }
  45682. + else if (MV_PEX_WIN_EXP_ROM == winNum)
  45683. + {
  45684. + pWinRegInfo->baseLowRegOffs = 0;
  45685. + pWinRegInfo->baseHighRegOffs = 0;
  45686. + pWinRegInfo->sizeRegOffs = PEX_WIN_EXP_ROM_CTRL_REG(pexIf);
  45687. + pWinRegInfo->remapLowRegOffs = PEX_WIN_EXP_ROM_REMAP_REG(pexIf);
  45688. + pWinRegInfo->remapHighRegOffs = 0;
  45689. +
  45690. + }
  45691. +
  45692. + return MV_OK;
  45693. +}
  45694. +
  45695. +/*******************************************************************************
  45696. +* pexBarNameGet - Get the string name of PEX BAR.
  45697. +*
  45698. +* DESCRIPTION:
  45699. +* This function get the string name of PEX BAR.
  45700. +*
  45701. +* INPUT:
  45702. +* bar - PEX bar number.
  45703. +*
  45704. +* OUTPUT:
  45705. +* None.
  45706. +*
  45707. +* RETURN:
  45708. +* pointer to the string name of PEX BAR.
  45709. +*
  45710. +*******************************************************************************/
  45711. +const MV_8* pexBarNameGet( MV_U32 bar )
  45712. +{
  45713. + switch( bar )
  45714. + {
  45715. + case PEX_INTER_REGS_BAR:
  45716. + return "Internal Regs Bar0....";
  45717. + case PEX_DRAM_BAR:
  45718. + return "DRAM Bar1.............";
  45719. + case PEX_DEVICE_BAR:
  45720. + return "Devices Bar2..........";
  45721. + default:
  45722. + return "Bar unknown";
  45723. + }
  45724. +}
  45725. +/*******************************************************************************
  45726. +* mvPexAddrDecShow - Print the PEX address decode map (BARs and windows).
  45727. +*
  45728. +* DESCRIPTION:
  45729. +* This function print the PEX address decode map (BARs and windows).
  45730. +*
  45731. +* INPUT:
  45732. +* None.
  45733. +*
  45734. +* OUTPUT:
  45735. +* None.
  45736. +*
  45737. +* RETURN:
  45738. +* None.
  45739. +*
  45740. +*******************************************************************************/
  45741. +MV_VOID mvPexAddrDecShow(MV_VOID)
  45742. +{
  45743. + MV_PEX_BAR pexBar;
  45744. + MV_PEX_DEC_WIN win;
  45745. + MV_U32 pexIf;
  45746. + MV_U32 bar,winNum;
  45747. +
  45748. + for( pexIf = 0; pexIf < mvCtrlPexMaxIfGet(); pexIf++ )
  45749. + {
  45750. + if (MV_FALSE == mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf)) continue;
  45751. + mvOsOutput( "\n" );
  45752. + mvOsOutput( "PEX%d:\n", pexIf );
  45753. + mvOsOutput( "-----\n" );
  45754. +
  45755. + mvOsOutput( "\nPex Bars \n\n");
  45756. +
  45757. + for( bar = 0; bar < PEX_MAX_BARS; bar++ )
  45758. + {
  45759. + memset( &pexBar, 0, sizeof(MV_PEX_BAR) );
  45760. +
  45761. + mvOsOutput( "%s ", pexBarNameGet(bar) );
  45762. +
  45763. + if( mvPexBarGet( pexIf, bar, &pexBar ) == MV_OK )
  45764. + {
  45765. + if( pexBar.enable )
  45766. + {
  45767. + mvOsOutput( "base %08x, ", pexBar.addrWin.baseLow );
  45768. + mvSizePrint( pexBar.addrWin.size );
  45769. + mvOsOutput( "\n" );
  45770. + }
  45771. + else
  45772. + mvOsOutput( "disable\n" );
  45773. + }
  45774. + }
  45775. + mvOsOutput( "\nPex Decode Windows\n\n");
  45776. +
  45777. + for( winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++)
  45778. + {
  45779. + memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
  45780. +
  45781. + mvOsOutput( "win%d - ", winNum );
  45782. +
  45783. + if ( mvPexTargetWinGet(pexIf,winNum,&win) == MV_OK)
  45784. + {
  45785. + if (win.enable)
  45786. + {
  45787. + mvOsOutput( "%s base %08x, ",
  45788. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  45789. + mvOsOutput( "...." );
  45790. + mvSizePrint( win.addrWin.size );
  45791. +
  45792. + mvOsOutput( "\n" );
  45793. + }
  45794. + else
  45795. + mvOsOutput( "disable\n" );
  45796. +
  45797. +
  45798. + }
  45799. + }
  45800. +
  45801. + memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
  45802. +
  45803. + mvOsOutput( "default win - " );
  45804. +
  45805. + if ( mvPexTargetWinGet(pexIf, MV_PEX_WIN_DEFAULT, &win) == MV_OK)
  45806. + {
  45807. + mvOsOutput( "%s ",
  45808. + mvCtrlTargetNameGet(win.target) );
  45809. + mvOsOutput( "\n" );
  45810. + }
  45811. + memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
  45812. +
  45813. + mvOsOutput( "Expansion ROM - " );
  45814. +
  45815. + if ( mvPexTargetWinGet(pexIf, MV_PEX_WIN_EXP_ROM, &win) == MV_OK)
  45816. + {
  45817. + mvOsOutput( "%s ",
  45818. + mvCtrlTargetNameGet(win.target) );
  45819. + mvOsOutput( "\n" );
  45820. + }
  45821. +
  45822. + }
  45823. +}
  45824. +
  45825. +
  45826. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h
  45827. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h 1970-01-01 01:00:00.000000000 +0100
  45828. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h 2010-08-05 22:02:21.813811855 +0200
  45829. @@ -0,0 +1,348 @@
  45830. +/*******************************************************************************
  45831. +Copyright (C) Marvell International Ltd. and its affiliates
  45832. +
  45833. +This software file (the "File") is owned and distributed by Marvell
  45834. +International Ltd. and/or its affiliates ("Marvell") under the following
  45835. +alternative licensing terms. Once you have made an election to distribute the
  45836. +File under one of the following license alternatives, please (i) delete this
  45837. +introductory statement regarding license alternatives, (ii) delete the two
  45838. +license alternatives that you have not elected to use and (iii) preserve the
  45839. +Marvell copyright notice above.
  45840. +
  45841. +********************************************************************************
  45842. +Marvell Commercial License Option
  45843. +
  45844. +If you received this File from Marvell and you have entered into a commercial
  45845. +license agreement (a "Commercial License") with Marvell, the File is licensed
  45846. +to you under the terms of the applicable Commercial License.
  45847. +
  45848. +********************************************************************************
  45849. +Marvell GPL License Option
  45850. +
  45851. +If you received this File from Marvell, you may opt to use, redistribute and/or
  45852. +modify this File in accordance with the terms and conditions of the General
  45853. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  45854. +available along with the File in the license.txt file or by writing to the Free
  45855. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  45856. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  45857. +
  45858. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  45859. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  45860. +DISCLAIMED. The GPL License provides additional details about this warranty
  45861. +disclaimer.
  45862. +********************************************************************************
  45863. +Marvell BSD License Option
  45864. +
  45865. +If you received this File from Marvell, you may opt to use, redistribute and/or
  45866. +modify this File under the following licensing terms.
  45867. +Redistribution and use in source and binary forms, with or without modification,
  45868. +are permitted provided that the following conditions are met:
  45869. +
  45870. + * Redistributions of source code must retain the above copyright notice,
  45871. + this list of conditions and the following disclaimer.
  45872. +
  45873. + * Redistributions in binary form must reproduce the above copyright
  45874. + notice, this list of conditions and the following disclaimer in the
  45875. + documentation and/or other materials provided with the distribution.
  45876. +
  45877. + * Neither the name of Marvell nor the names of its contributors may be
  45878. + used to endorse or promote products derived from this software without
  45879. + specific prior written permission.
  45880. +
  45881. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  45882. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  45883. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  45884. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  45885. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  45886. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  45887. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  45888. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  45889. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  45890. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  45891. +
  45892. +*******************************************************************************/
  45893. +
  45894. +#ifndef __INCSysPEXH
  45895. +#define __INCSysPEXH
  45896. +
  45897. +#include "mvCommon.h"
  45898. +#include "ctrlEnv/sys/mvCpuIf.h"
  45899. +#include "ctrlEnv/mvCtrlEnvLib.h"
  45900. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  45901. +
  45902. +/* 4KB granularity */
  45903. +#define MINIMUM_WINDOW_SIZE 0x1000
  45904. +#define MINIMUM_BAR_SIZE 0x1000
  45905. +#define MINIMUM_BAR_SIZE_MASK 0xFFFFF000
  45906. +#define BAR_SIZE_OFFS 12
  45907. +#define BAR_SIZE_MASK (0xFFFFF << BAR_SIZE_OFFS)
  45908. +
  45909. +
  45910. +
  45911. +#define MV_PEX_WIN_DEFAULT 6
  45912. +#define MV_PEX_WIN_EXP_ROM 7
  45913. +#define PEX_MAX_TARGET_WIN 8
  45914. +
  45915. +
  45916. +#define PEX_MAX_BARS 3
  45917. +#define PEX_INTER_REGS_BAR 0
  45918. +#define PEX_DRAM_BAR 1
  45919. +#define PEX_DEVICE_BAR 2
  45920. +
  45921. +/*************************************/
  45922. +/* PCI Express BAR Control Registers */
  45923. +/*************************************/
  45924. +#define PEX_BAR_CTRL_REG(pexIf,bar) (0x41804 + (bar-1)*4- (pexIf)*0x10000)
  45925. +#define PEX_EXP_ROM_BAR_CTRL_REG(pexIf) (0x4180C - (pexIf)*0x10000)
  45926. +
  45927. +
  45928. +/* PCI Express BAR Control Register */
  45929. +/* PEX_BAR_CTRL_REG (PXBCR) */
  45930. +
  45931. +#define PXBCR_BAR_EN BIT0
  45932. +#define PXBCR_BAR_SIZE_OFFS 16
  45933. +#define PXBCR_BAR_SIZE_MASK (0xffff << PXBCR_BAR_SIZE_OFFS)
  45934. +#define PXBCR_BAR_SIZE_ALIGNMENT 0x10000
  45935. +
  45936. +
  45937. +
  45938. +/* PCI Express Expansion ROM BAR Control Register */
  45939. +/* PEX_EXP_ROM_BAR_CTRL_REG (PXERBCR) */
  45940. +
  45941. +#define PXERBCR_EXPROM_EN BIT0
  45942. +#define PXERBCR_EXPROMSZ_OFFS 19
  45943. +#define PXERBCR_EXPROMSZ_MASK (0xf << PXERBCR_EXPROMSZ_OFFS)
  45944. +#define PXERBCR_EXPROMSZ_512KB (0x0 << PXERBCR_EXPROMSZ_OFFS)
  45945. +#define PXERBCR_EXPROMSZ_1024KB (0x1 << PXERBCR_EXPROMSZ_OFFS)
  45946. +#define PXERBCR_EXPROMSZ_2048KB (0x3 << PXERBCR_EXPROMSZ_OFFS)
  45947. +#define PXERBCR_EXPROMSZ_4096KB (0x7 << PXERBCR_EXPROMSZ_OFFS)
  45948. +
  45949. +/************************************************/
  45950. +/* PCI Express Address Window Control Registers */
  45951. +/************************************************/
  45952. +#define PEX_WIN0_3_CTRL_REG(pexIf,winNum) \
  45953. + (0x41820 + (winNum) * 0x10 - (pexIf) * 0x10000)
  45954. +#define PEX_WIN0_3_BASE_REG(pexIf,winNum) \
  45955. + (0x41824 + (winNum) * 0x10 - (pexIf) * 0x10000)
  45956. +#define PEX_WIN0_3_REMAP_REG(pexIf,winNum) \
  45957. + (0x4182C + (winNum) * 0x10 - (pexIf) * 0x10000)
  45958. +#define PEX_WIN4_5_CTRL_REG(pexIf,winNum) \
  45959. + (0x41860 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
  45960. +#define PEX_WIN4_5_BASE_REG(pexIf,winNum) \
  45961. + (0x41864 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
  45962. +#define PEX_WIN4_5_REMAP_REG(pexIf,winNum) \
  45963. + (0x4186C + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
  45964. +#define PEX_WIN4_5_REMAP_HIGH_REG(pexIf,winNum) \
  45965. + (0x41870 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
  45966. +
  45967. +#define PEX_WIN_DEFAULT_CTRL_REG(pexIf) (0x418B0 - (pexIf) * 0x10000)
  45968. +#define PEX_WIN_EXP_ROM_CTRL_REG(pexIf) (0x418C0 - (pexIf) * 0x10000)
  45969. +#define PEX_WIN_EXP_ROM_REMAP_REG(pexIf) (0x418C4 - (pexIf) * 0x10000)
  45970. +
  45971. +/* PCI Express Window Control Register */
  45972. +/* PEX_WIN_CTRL_REG (PXWCR) */
  45973. +
  45974. +#define PXWCR_WIN_EN BIT0 /* Window Enable.*/
  45975. +
  45976. +#define PXWCR_WIN_BAR_MAP_OFFS 1 /* Mapping to BAR.*/
  45977. +#define PXWCR_WIN_BAR_MAP_MASK BIT1
  45978. +#define PXWCR_WIN_BAR_MAP_BAR1 (0 << PXWCR_WIN_BAR_MAP_OFFS)
  45979. +#define PXWCR_WIN_BAR_MAP_BAR2 (1 << PXWCR_WIN_BAR_MAP_OFFS)
  45980. +
  45981. +#define PXWCR_TARGET_OFFS 4 /*Unit ID */
  45982. +#define PXWCR_TARGET_MASK (0xf << PXWCR_TARGET_OFFS)
  45983. +
  45984. +#define PXWCR_ATTRIB_OFFS 8 /* target attributes */
  45985. +#define PXWCR_ATTRIB_MASK (0xff << PXWCR_ATTRIB_OFFS)
  45986. +
  45987. +#define PXWCR_SIZE_OFFS 16 /* size */
  45988. +#define PXWCR_SIZE_MASK (0xffff << PXWCR_SIZE_OFFS)
  45989. +#define PXWCR_SIZE_ALIGNMENT 0x10000
  45990. +
  45991. +/* PCI Express Window Base Register */
  45992. +/* PEX_WIN_BASE_REG (PXWBR)*/
  45993. +
  45994. +#define PXWBR_BASE_OFFS 16 /* address[31:16] */
  45995. +#define PXWBR_BASE_MASK (0xffff << PXWBR_BASE_OFFS)
  45996. +#define PXWBR_BASE_ALIGNMENT 0x10000
  45997. +
  45998. +/* PCI Express Window Remap Register */
  45999. +/* PEX_WIN_REMAP_REG (PXWRR)*/
  46000. +
  46001. +#define PXWRR_REMAP_EN BIT0
  46002. +#define PXWRR_REMAP_OFFS 16
  46003. +#define PXWRR_REMAP_MASK (0xffff << PXWRR_REMAP_OFFS)
  46004. +#define PXWRR_REMAP_ALIGNMENT 0x10000
  46005. +
  46006. +/* PCI Express Window Remap (High) Register */
  46007. +/* PEX_WIN_REMAP_HIGH_REG (PXWRHR)*/
  46008. +
  46009. +#define PXWRHR_REMAP_HIGH_OFFS 0
  46010. +#define PXWRHR_REMAP_HIGH_MASK (0xffffffff << PXWRHR_REMAP_HIGH_OFFS)
  46011. +
  46012. +/* PCI Express Default Window Control Register */
  46013. +/* PEX_WIN_DEFAULT_CTRL_REG (PXWDCR) */
  46014. +
  46015. +#define PXWDCR_TARGET_OFFS 4 /*Unit ID */
  46016. +#define PXWDCR_TARGET_MASK (0xf << PXWDCR_TARGET_OFFS)
  46017. +#define PXWDCR_ATTRIB_OFFS 8 /* target attributes */
  46018. +#define PXWDCR_ATTRIB_MASK (0xff << PXWDCR_ATTRIB_OFFS)
  46019. +
  46020. +/* PCI Express Expansion ROM Window Control Register */
  46021. +/* PEX_WIN_EXP_ROM_CTRL_REG (PXWERCR)*/
  46022. +
  46023. +#define PXWERCR_TARGET_OFFS 4 /*Unit ID */
  46024. +#define PXWERCR_TARGET_MASK (0xf << PXWERCR_TARGET_OFFS)
  46025. +#define PXWERCR_ATTRIB_OFFS 8 /* target attributes */
  46026. +#define PXWERCR_ATTRIB_MASK (0xff << PXWERCR_ATTRIB_OFFS)
  46027. +
  46028. +/* PCI Express Expansion ROM Window Remap Register */
  46029. +/* PEX_WIN_EXP_ROM_REMAP_REG (PXWERRR)*/
  46030. +
  46031. +#define PXWERRR_REMAP_EN BIT0
  46032. +#define PXWERRR_REMAP_OFFS 16
  46033. +#define PXWERRR_REMAP_MASK (0xffff << PXWERRR_REMAP_OFFS)
  46034. +#define PXWERRR_REMAP_ALIGNMENT 0x10000
  46035. +
  46036. +
  46037. +
  46038. +/*PEX_MEMORY_BAR_BASE_ADDR(barNum) (PXMBBA)*/
  46039. +/* PCI Express BAR0 Internal Register*/
  46040. +/*PEX BAR0_INTER_REG (PXBIR)*/
  46041. +
  46042. +#define PXBIR_IOSPACE BIT0 /* Memory Space Indicator */
  46043. +
  46044. +#define PXBIR_TYPE_OFFS 1 /* BAR Type/Init Val. */
  46045. +#define PXBIR_TYPE_MASK (0x3 << PXBIR_TYPE_OFFS)
  46046. +#define PXBIR_TYPE_32BIT_ADDR (0x0 << PXBIR_TYPE_OFFS)
  46047. +#define PXBIR_TYPE_64BIT_ADDR (0x2 << PXBIR_TYPE_OFFS)
  46048. +
  46049. +#define PXBIR_PREFETCH_EN BIT3 /* Prefetch Enable */
  46050. +
  46051. +#define PXBIR_BASE_OFFS 20 /* Base address. Address bits [31:20] */
  46052. +#define PXBIR_BASE_MASK (0xfff << PXBIR_BASE_OFFS)
  46053. +#define PXBIR_BASE_ALIGNMET (1 << PXBIR_BASE_OFFS)
  46054. +
  46055. +
  46056. +/* PCI Express BAR0 Internal (High) Register*/
  46057. +/*PEX BAR0_INTER_REG_HIGH (PXBIRH)*/
  46058. +
  46059. +#define PXBIRH_BASE_OFFS 0 /* Base address. Bits [63:32] */
  46060. +#define PXBIRH_BASE_MASK (0xffffffff << PBBHR_BASE_OFFS)
  46061. +
  46062. +
  46063. +#define PEX_BAR_DEFAULT_ATTRIB 0xc /* Memory - Prefetch - 64 bit address */
  46064. +#define PEX_BAR0_DEFAULT_ATTRIB PEX_BAR_DEFAULT_ATTRIB
  46065. +#define PEX_BAR1_DEFAULT_ATTRIB PEX_BAR_DEFAULT_ATTRIB
  46066. +#define PEX_BAR2_DEFAULT_ATTRIB PEX_BAR_DEFAULT_ATTRIB
  46067. +
  46068. +
  46069. +/* PCI Express BAR1 Register */
  46070. +/* PCI Express BAR2 Register*/
  46071. +/*PEX BAR1_REG (PXBR)*/
  46072. +/*PEX BAR2_REG (PXBR)*/
  46073. +
  46074. +#define PXBR_IOSPACE BIT0 /* Memory Space Indicator */
  46075. +
  46076. +#define PXBR_TYPE_OFFS 1 /* BAR Type/Init Val. */
  46077. +#define PXBR_TYPE_MASK (0x3 << PXBR_TYPE_OFFS)
  46078. +#define PXBR_TYPE_32BIT_ADDR (0x0 << PXBR_TYPE_OFFS)
  46079. +#define PXBR_TYPE_64BIT_ADDR (0x2 << PXBR_TYPE_OFFS)
  46080. +
  46081. +#define PXBR_PREFETCH_EN BIT3 /* Prefetch Enable */
  46082. +
  46083. +#define PXBR_BASE_OFFS 16 /* Base address. Address bits [31:16] */
  46084. +#define PXBR_BASE_MASK (0xffff << PXBR_BASE_OFFS)
  46085. +#define PXBR_BASE_ALIGNMET (1 << PXBR_BASE_OFFS)
  46086. +
  46087. +
  46088. +/* PCI Express BAR1 (High) Register*/
  46089. +/* PCI Express BAR2 (High) Register*/
  46090. +/*PEX BAR1_REG_HIGH (PXBRH)*/
  46091. +/*PEX BAR2_REG_HIGH (PXBRH)*/
  46092. +
  46093. +#define PXBRH_BASE_OFFS 0 /* Base address. Address bits [63:32] */
  46094. +#define PXBRH_BASE_MASK (0xffffffff << PXBRH_BASE_OFFS)
  46095. +
  46096. +/* PCI Express Expansion ROM BAR Register*/
  46097. +/*PEX_EXPANSION_ROM_BASE_ADDR_REG (PXERBAR)*/
  46098. +
  46099. +#define PXERBAR_EXPROMEN BIT0 /* Expansion ROM Enable */
  46100. +
  46101. +#define PXERBAR_BASE_512K_OFFS 19 /* Expansion ROM Base Address */
  46102. +#define PXERBAR_BASE_512K_MASK (0x1fff << PXERBAR_BASE_512K_OFFS)
  46103. +
  46104. +#define PXERBAR_BASE_1MB_OFFS 20 /* Expansion ROM Base Address */
  46105. +#define PXERBAR_BASE_1MB_MASK (0xfff << PXERBAR_BASE_1MB_OFFS)
  46106. +
  46107. +#define PXERBAR_BASE_2MB_OFFS 21 /* Expansion ROM Base Address */
  46108. +#define PXERBAR_BASE_2MB_MASK (0x7ff << PXERBAR_BASE_2MB_OFFS)
  46109. +
  46110. +#define PXERBAR_BASE_4MB_OFFS 22 /* Expansion ROM Base Address */
  46111. +#define PXERBAR_BASE_4MB_MASK (0x3ff << PXERBAR_BASE_4MB_OFFS)
  46112. +
  46113. +/* PEX Bar attributes */
  46114. +typedef struct _mvPexBar
  46115. +{
  46116. + MV_ADDR_WIN addrWin; /* An address window*/
  46117. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  46118. +
  46119. +}MV_PEX_BAR;
  46120. +
  46121. +/* PEX Remap Window attributes */
  46122. +typedef struct _mvPexRemapWin
  46123. +{
  46124. + MV_ADDR_WIN addrWin; /* An address window*/
  46125. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  46126. +
  46127. +}MV_PEX_REMAP_WIN;
  46128. +
  46129. +/* PEX Remap Window attributes */
  46130. +typedef struct _mvPexDecWin
  46131. +{
  46132. + MV_TARGET target;
  46133. + MV_ADDR_WIN addrWin; /* An address window*/
  46134. + MV_U32 targetBar;
  46135. + MV_U8 attrib; /* chip select attributes */
  46136. + MV_TARGET_ID targetId; /* Target Id of this MV_TARGET */
  46137. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  46138. +
  46139. +}MV_PEX_DEC_WIN;
  46140. +
  46141. +/* Global Functions prototypes */
  46142. +/* mvPexHalInit - Initialize PEX interfaces*/
  46143. +MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType);
  46144. +
  46145. +
  46146. +/* mvPexTargetWinSet - Set PEX to peripheral target address window BAR*/
  46147. +MV_STATUS mvPexTargetWinSet(MV_U32 pexIf, MV_U32 winNum,
  46148. + MV_PEX_DEC_WIN *pAddrDecWin);
  46149. +
  46150. +/* mvPexTargetWinGet - Get PEX to peripheral target address window*/
  46151. +MV_STATUS mvPexTargetWinGet(MV_U32 pexIf, MV_U32 winNum,
  46152. + MV_PEX_DEC_WIN *pAddrDecWin);
  46153. +
  46154. +/* mvPexTargetWinEnable - Enable/disable a PEX BAR window*/
  46155. +MV_STATUS mvPexTargetWinEnable(MV_U32 pexIf,MV_U32 winNum, MV_BOOL enable);
  46156. +
  46157. +/* mvPexTargetWinRemap - Set PEX to target address window remap.*/
  46158. +MV_STATUS mvPexTargetWinRemap(MV_U32 pexIf, MV_U32 winNum,
  46159. + MV_PEX_REMAP_WIN *pAddrWin);
  46160. +
  46161. +/* mvPexTargetWinRemapEnable -enable\disable a PEX Window remap.*/
  46162. +MV_STATUS mvPexTargetWinRemapEnable(MV_U32 pexIf, MV_U32 winNum,
  46163. + MV_BOOL enable);
  46164. +
  46165. +/* mvPexBarSet - Set PEX bar address and size */
  46166. +MV_STATUS mvPexBarSet(MV_U32 pexIf, MV_U32 barNum, MV_PEX_BAR *addrWin);
  46167. +
  46168. +/* mvPexBarGet - Get PEX bar address and size */
  46169. +MV_STATUS mvPexBarGet(MV_U32 pexIf, MV_U32 barNum, MV_PEX_BAR *addrWin);
  46170. +
  46171. +/* mvPexBarEnable - enable\disable a PEX bar*/
  46172. +MV_STATUS mvPexBarEnable(MV_U32 pexIf, MV_U32 barNum, MV_BOOL enable);
  46173. +
  46174. +/* mvPexAddrDecShow - Display address decode windows attributes */
  46175. +MV_VOID mvPexAddrDecShow(MV_VOID);
  46176. +
  46177. +#endif
  46178. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c
  46179. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c 1970-01-01 01:00:00.000000000 +0100
  46180. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c 2010-08-05 22:02:22.384025589 +0200
  46181. @@ -0,0 +1,430 @@
  46182. +/*******************************************************************************
  46183. +Copyright (C) Marvell International Ltd. and its affiliates
  46184. +
  46185. +This software file (the "File") is owned and distributed by Marvell
  46186. +International Ltd. and/or its affiliates ("Marvell") under the following
  46187. +alternative licensing terms. Once you have made an election to distribute the
  46188. +File under one of the following license alternatives, please (i) delete this
  46189. +introductory statement regarding license alternatives, (ii) delete the two
  46190. +license alternatives that you have not elected to use and (iii) preserve the
  46191. +Marvell copyright notice above.
  46192. +
  46193. +********************************************************************************
  46194. +Marvell Commercial License Option
  46195. +
  46196. +If you received this File from Marvell and you have entered into a commercial
  46197. +license agreement (a "Commercial License") with Marvell, the File is licensed
  46198. +to you under the terms of the applicable Commercial License.
  46199. +
  46200. +********************************************************************************
  46201. +Marvell GPL License Option
  46202. +
  46203. +If you received this File from Marvell, you may opt to use, redistribute and/or
  46204. +modify this File in accordance with the terms and conditions of the General
  46205. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  46206. +available along with the File in the license.txt file or by writing to the Free
  46207. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  46208. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  46209. +
  46210. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  46211. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  46212. +DISCLAIMED. The GPL License provides additional details about this warranty
  46213. +disclaimer.
  46214. +********************************************************************************
  46215. +Marvell BSD License Option
  46216. +
  46217. +If you received this File from Marvell, you may opt to use, redistribute and/or
  46218. +modify this File under the following licensing terms.
  46219. +Redistribution and use in source and binary forms, with or without modification,
  46220. +are permitted provided that the following conditions are met:
  46221. +
  46222. + * Redistributions of source code must retain the above copyright notice,
  46223. + this list of conditions and the following disclaimer.
  46224. +
  46225. + * Redistributions in binary form must reproduce the above copyright
  46226. + notice, this list of conditions and the following disclaimer in the
  46227. + documentation and/or other materials provided with the distribution.
  46228. +
  46229. + * Neither the name of Marvell nor the names of its contributors may be
  46230. + used to endorse or promote products derived from this software without
  46231. + specific prior written permission.
  46232. +
  46233. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  46234. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  46235. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  46236. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  46237. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  46238. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46239. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  46240. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  46241. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  46242. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  46243. +
  46244. +*******************************************************************************/
  46245. +
  46246. +
  46247. +#include "mvTypes.h"
  46248. +#include "mvCommon.h"
  46249. +#include "mvOs.h"
  46250. +#include "ctrlEnv/mvCtrlEnvLib.h"
  46251. +#include "cpu/mvCpu.h"
  46252. +#include "ctrlEnv/sys/mvCpuIf.h"
  46253. +#include "sata/CoreDriver/mvRegs.h"
  46254. +#include "ctrlEnv/sys/mvSysSata.h"
  46255. +
  46256. +MV_TARGET sataAddrDecPrioTab[] =
  46257. +{
  46258. +#if defined(MV_INCLUDE_SDRAM_CS0)
  46259. + SDRAM_CS0,
  46260. +#endif
  46261. +#if defined(MV_INCLUDE_SDRAM_CS1)
  46262. + SDRAM_CS1,
  46263. +#endif
  46264. +#if defined(MV_INCLUDE_SDRAM_CS2)
  46265. + SDRAM_CS2,
  46266. +#endif
  46267. +#if defined(MV_INCLUDE_SDRAM_CS3)
  46268. + SDRAM_CS3,
  46269. +#endif
  46270. +#if defined(MV_INCLUDE_PEX)
  46271. + PEX0_MEM,
  46272. +#endif
  46273. + TBL_TERM
  46274. +};
  46275. +
  46276. +
  46277. +/*******************************************************************************
  46278. +* sataWinOverlapDetect - Detect SATA address windows overlapping
  46279. +*
  46280. +* DESCRIPTION:
  46281. +* An unpredicted behaviur is expected in case SATA address decode
  46282. +* windows overlapps.
  46283. +* This function detects SATA address decode windows overlapping of a
  46284. +* specified window. The function does not check the window itself for
  46285. +* overlapping. The function also skipps disabled address decode windows.
  46286. +*
  46287. +* INPUT:
  46288. +* winNum - address decode window number.
  46289. +* pAddrDecWin - An address decode window struct.
  46290. +*
  46291. +* OUTPUT:
  46292. +* None.
  46293. +*
  46294. +* RETURN:
  46295. +* MV_TRUE if the given address window overlap current address
  46296. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  46297. +* from registers.
  46298. +*
  46299. +*******************************************************************************/
  46300. +static MV_STATUS sataWinOverlapDetect(int dev, MV_U32 winNum,
  46301. + MV_ADDR_WIN *pAddrWin)
  46302. +{
  46303. + MV_U32 winNumIndex;
  46304. + MV_SATA_DEC_WIN addrDecWin;
  46305. +
  46306. + for(winNumIndex=0; winNumIndex<MV_SATA_MAX_ADDR_DECODE_WIN; winNumIndex++)
  46307. + {
  46308. + /* Do not check window itself */
  46309. + if (winNumIndex == winNum)
  46310. + {
  46311. + continue;
  46312. + }
  46313. +
  46314. + /* Get window parameters */
  46315. + if (MV_OK != mvSataWinGet(dev, winNumIndex, &addrDecWin))
  46316. + {
  46317. + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
  46318. + return MV_ERROR;
  46319. + }
  46320. +
  46321. + /* Do not check disabled windows */
  46322. + if(addrDecWin.enable == MV_FALSE)
  46323. + {
  46324. + continue;
  46325. + }
  46326. +
  46327. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  46328. + {
  46329. + return MV_TRUE;
  46330. + }
  46331. + }
  46332. + return MV_FALSE;
  46333. +}
  46334. +
  46335. +
  46336. +/*******************************************************************************
  46337. +* mvSataWinSet - Set SATA target address window
  46338. +*
  46339. +* DESCRIPTION:
  46340. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  46341. +* address window, also known as address decode window.
  46342. +* After setting this target window, the SATA will be able to access the
  46343. +* target within the address window.
  46344. +*
  46345. +* INPUT:
  46346. +* winNum - SATA target address decode window number.
  46347. +* pAddrDecWin - SATA target window data structure.
  46348. +*
  46349. +* OUTPUT:
  46350. +* None.
  46351. +*
  46352. +* RETURN:
  46353. +* MV_ERROR if address window overlapps with other address decode windows.
  46354. +* MV_BAD_PARAM if base address is invalid parameter or target is
  46355. +* unknown.
  46356. +*
  46357. +*******************************************************************************/
  46358. +MV_STATUS mvSataWinSet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin)
  46359. +{
  46360. + MV_TARGET_ATTRIB targetAttribs;
  46361. + MV_DEC_REGS decRegs;
  46362. +
  46363. + /* Parameter checking */
  46364. + if (winNum >= MV_SATA_MAX_ADDR_DECODE_WIN)
  46365. + {
  46366. + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
  46367. + return MV_BAD_PARAM;
  46368. + }
  46369. +
  46370. + /* Check if the requested window overlapps with current windows */
  46371. + if (MV_TRUE == sataWinOverlapDetect(dev, winNum, &pAddrDecWin->addrWin))
  46372. + {
  46373. + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
  46374. + return MV_ERROR;
  46375. + }
  46376. +
  46377. + /* check if address is aligned to the size */
  46378. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  46379. + {
  46380. + mvOsPrintf("mvSataWinSet:Error setting SATA window %d to "\
  46381. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  46382. + winNum,
  46383. + mvCtrlTargetNameGet(pAddrDecWin->target),
  46384. + pAddrDecWin->addrWin.baseLow,
  46385. + pAddrDecWin->addrWin.size);
  46386. + return MV_ERROR;
  46387. + }
  46388. +
  46389. + decRegs.baseReg = 0;
  46390. + decRegs.sizeReg = 0;
  46391. +
  46392. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  46393. + {
  46394. + mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
  46395. + return MV_ERROR;
  46396. + }
  46397. +
  46398. + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
  46399. +
  46400. + /* set attributes */
  46401. + decRegs.sizeReg &= ~MV_SATA_WIN_ATTR_MASK;
  46402. + decRegs.sizeReg |= (targetAttribs.attrib << MV_SATA_WIN_ATTR_OFFSET);
  46403. +
  46404. + /* set target ID */
  46405. + decRegs.sizeReg &= ~MV_SATA_WIN_TARGET_MASK;
  46406. + decRegs.sizeReg |= (targetAttribs.targetId << MV_SATA_WIN_TARGET_OFFSET);
  46407. +
  46408. + if (pAddrDecWin->enable == MV_TRUE)
  46409. + {
  46410. + decRegs.sizeReg |= MV_SATA_WIN_ENABLE_MASK;
  46411. + }
  46412. + else
  46413. + {
  46414. + decRegs.sizeReg &= ~MV_SATA_WIN_ENABLE_MASK;
  46415. + }
  46416. +
  46417. + MV_REG_WRITE( MV_SATA_WIN_CTRL_REG(dev, winNum), decRegs.sizeReg);
  46418. + MV_REG_WRITE( MV_SATA_WIN_BASE_REG(dev, winNum), decRegs.baseReg);
  46419. +
  46420. + return MV_OK;
  46421. +}
  46422. +
  46423. +/*******************************************************************************
  46424. +* mvSataWinGet - Get SATA peripheral target address window.
  46425. +*
  46426. +* DESCRIPTION:
  46427. +* Get SATA peripheral target address window.
  46428. +*
  46429. +* INPUT:
  46430. +* winNum - SATA target address decode window number.
  46431. +*
  46432. +* OUTPUT:
  46433. +* pAddrDecWin - SATA target window data structure.
  46434. +*
  46435. +* RETURN:
  46436. +* MV_ERROR if register parameters are invalid.
  46437. +*
  46438. +*******************************************************************************/
  46439. +MV_STATUS mvSataWinGet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin)
  46440. +{
  46441. + MV_DEC_REGS decRegs;
  46442. + MV_TARGET_ATTRIB targetAttrib;
  46443. +
  46444. + /* Parameter checking */
  46445. + if (winNum >= MV_SATA_MAX_ADDR_DECODE_WIN)
  46446. + {
  46447. + mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",
  46448. + __FUNCTION__, dev, winNum);
  46449. + return MV_NOT_SUPPORTED;
  46450. + }
  46451. +
  46452. + decRegs.baseReg = MV_REG_READ( MV_SATA_WIN_BASE_REG(dev, winNum) );
  46453. + decRegs.sizeReg = MV_REG_READ( MV_SATA_WIN_CTRL_REG(dev, winNum) );
  46454. +
  46455. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
  46456. + {
  46457. + mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
  46458. + return MV_ERROR;
  46459. + }
  46460. +
  46461. + /* attrib and targetId */
  46462. + targetAttrib.attrib = (decRegs.sizeReg & MV_SATA_WIN_ATTR_MASK) >>
  46463. + MV_SATA_WIN_ATTR_OFFSET;
  46464. + targetAttrib.targetId = (decRegs.sizeReg & MV_SATA_WIN_TARGET_MASK) >>
  46465. + MV_SATA_WIN_TARGET_OFFSET;
  46466. +
  46467. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  46468. +
  46469. + /* Check if window is enabled */
  46470. + if(decRegs.sizeReg & MV_SATA_WIN_ENABLE_MASK)
  46471. + {
  46472. + pAddrDecWin->enable = MV_TRUE;
  46473. + }
  46474. + else
  46475. + {
  46476. + pAddrDecWin->enable = MV_FALSE;
  46477. + }
  46478. + return MV_OK;
  46479. +}
  46480. +/*******************************************************************************
  46481. +* mvSataAddrDecShow - Print the SATA address decode map.
  46482. +*
  46483. +* DESCRIPTION:
  46484. +* This function print the SATA address decode map.
  46485. +*
  46486. +* INPUT:
  46487. +* None.
  46488. +*
  46489. +* OUTPUT:
  46490. +* None.
  46491. +*
  46492. +* RETURN:
  46493. +* None.
  46494. +*
  46495. +*******************************************************************************/
  46496. +MV_VOID mvSataAddrDecShow(MV_VOID)
  46497. +{
  46498. +
  46499. + MV_SATA_DEC_WIN win;
  46500. + int i,j;
  46501. +
  46502. +
  46503. +
  46504. + for( j = 0; j < MV_SATA_MAX_CHAN; j++ )
  46505. + {
  46506. + if (MV_FALSE == mvCtrlPwrClckGet(SATA_UNIT_ID, j))
  46507. + return;
  46508. +
  46509. + mvOsOutput( "\n" );
  46510. + mvOsOutput( "SATA %d:\n", j );
  46511. + mvOsOutput( "----\n" );
  46512. +
  46513. + for( i = 0; i < MV_SATA_MAX_ADDR_DECODE_WIN; i++ )
  46514. + {
  46515. + memset( &win, 0, sizeof(MV_SATA_DEC_WIN) );
  46516. +
  46517. + mvOsOutput( "win%d - ", i );
  46518. +
  46519. + if( mvSataWinGet(j, i, &win ) == MV_OK )
  46520. + {
  46521. + if( win.enable )
  46522. + {
  46523. + mvOsOutput( "%s base %08x, ",
  46524. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  46525. + mvOsOutput( "...." );
  46526. +
  46527. + mvSizePrint( win.addrWin.size );
  46528. +
  46529. + mvOsOutput( "\n" );
  46530. + }
  46531. + else
  46532. + mvOsOutput( "disable\n" );
  46533. + }
  46534. + }
  46535. + }
  46536. +}
  46537. +
  46538. +
  46539. +/*******************************************************************************
  46540. +* mvSataWinInit - Initialize the integrated SATA target address window.
  46541. +*
  46542. +* DESCRIPTION:
  46543. +* Initialize the SATA peripheral target address window.
  46544. +*
  46545. +* INPUT:
  46546. +*
  46547. +*
  46548. +* OUTPUT:
  46549. +*
  46550. +*
  46551. +* RETURN:
  46552. +* MV_ERROR if register parameters are invalid.
  46553. +*
  46554. +*******************************************************************************/
  46555. +MV_STATUS mvSataWinInit(MV_VOID)
  46556. +{
  46557. + int winNum;
  46558. + MV_SATA_DEC_WIN sataWin;
  46559. + MV_CPU_DEC_WIN cpuAddrDecWin;
  46560. + MV_U32 status, winPrioIndex = 0;
  46561. +
  46562. + /* Initiate Sata address decode */
  46563. +
  46564. + /* First disable all address decode windows */
  46565. + for(winNum = 0; winNum < MV_SATA_MAX_ADDR_DECODE_WIN; winNum++)
  46566. + {
  46567. + MV_U32 regVal = MV_REG_READ(MV_SATA_WIN_CTRL_REG(0, winNum));
  46568. + regVal &= ~MV_SATA_WIN_ENABLE_MASK;
  46569. + MV_REG_WRITE(MV_SATA_WIN_CTRL_REG(0, winNum), regVal);
  46570. + }
  46571. +
  46572. + winNum = 0;
  46573. + while( (sataAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
  46574. + (winNum < MV_SATA_MAX_ADDR_DECODE_WIN) )
  46575. + {
  46576. + /* first get attributes from CPU If */
  46577. + status = mvCpuIfTargetWinGet(sataAddrDecPrioTab[winPrioIndex],
  46578. + &cpuAddrDecWin);
  46579. +
  46580. + if(MV_NO_SUCH == status)
  46581. + {
  46582. + winPrioIndex++;
  46583. + continue;
  46584. + }
  46585. + if (MV_OK != status)
  46586. + {
  46587. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  46588. + return MV_ERROR;
  46589. + }
  46590. +
  46591. + if (cpuAddrDecWin.enable == MV_TRUE)
  46592. + {
  46593. + sataWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  46594. + sataWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  46595. + sataWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  46596. + sataWin.enable = MV_TRUE;
  46597. + sataWin.target = sataAddrDecPrioTab[winPrioIndex];
  46598. +
  46599. + if(MV_OK != mvSataWinSet(0/*dev*/, winNum, &sataWin))
  46600. + {
  46601. + return MV_ERROR;
  46602. + }
  46603. + winNum++;
  46604. + }
  46605. + winPrioIndex++;
  46606. + }
  46607. + return MV_OK;
  46608. +}
  46609. +
  46610. +
  46611. +
  46612. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h
  46613. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h 1970-01-01 01:00:00.000000000 +0100
  46614. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h 2010-08-05 22:02:22.473742718 +0200
  46615. @@ -0,0 +1,128 @@
  46616. +
  46617. +/*******************************************************************************
  46618. +Copyright (C) Marvell International Ltd. and its affiliates
  46619. +
  46620. +This software file (the "File") is owned and distributed by Marvell
  46621. +International Ltd. and/or its affiliates ("Marvell") under the following
  46622. +alternative licensing terms. Once you have made an election to distribute the
  46623. +File under one of the following license alternatives, please (i) delete this
  46624. +introductory statement regarding license alternatives, (ii) delete the two
  46625. +license alternatives that you have not elected to use and (iii) preserve the
  46626. +Marvell copyright notice above.
  46627. +
  46628. +********************************************************************************
  46629. +Marvell Commercial License Option
  46630. +
  46631. +If you received this File from Marvell and you have entered into a commercial
  46632. +license agreement (a "Commercial License") with Marvell, the File is licensed
  46633. +to you under the terms of the applicable Commercial License.
  46634. +
  46635. +********************************************************************************
  46636. +Marvell GPL License Option
  46637. +
  46638. +If you received this File from Marvell, you may opt to use, redistribute and/or
  46639. +modify this File in accordance with the terms and conditions of the General
  46640. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  46641. +available along with the File in the license.txt file or by writing to the Free
  46642. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  46643. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  46644. +
  46645. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  46646. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  46647. +DISCLAIMED. The GPL License provides additional details about this warranty
  46648. +disclaimer.
  46649. +********************************************************************************
  46650. +Marvell BSD License Option
  46651. +
  46652. +If you received this File from Marvell, you may opt to use, redistribute and/or
  46653. +modify this File under the following licensing terms.
  46654. +Redistribution and use in source and binary forms, with or without modification,
  46655. +are permitted provided that the following conditions are met:
  46656. +
  46657. + * Redistributions of source code must retain the above copyright notice,
  46658. + this list of conditions and the following disclaimer.
  46659. +
  46660. + * Redistributions in binary form must reproduce the above copyright
  46661. + notice, this list of conditions and the following disclaimer in the
  46662. + documentation and/or other materials provided with the distribution.
  46663. +
  46664. + * Neither the name of Marvell nor the names of its contributors may be
  46665. + used to endorse or promote products derived from this software without
  46666. + specific prior written permission.
  46667. +
  46668. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  46669. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  46670. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  46671. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  46672. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  46673. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46674. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  46675. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  46676. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  46677. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  46678. +
  46679. +*******************************************************************************/
  46680. +#ifndef __INCMVSysSataAddrDech
  46681. +#define __INCMVSysSataAddrDech
  46682. +
  46683. +#include "mvCommon.h"
  46684. +#include "ctrlEnv/mvCtrlEnvLib.h"
  46685. +#include "ctrlEnv/sys/mvCpuIf.h"
  46686. +
  46687. +
  46688. +#ifdef __cplusplus
  46689. +extern "C" {
  46690. +#endif
  46691. +
  46692. +typedef struct _mvSataDecWin
  46693. +{
  46694. + MV_TARGET target;
  46695. + MV_ADDR_WIN addrWin; /* An address window*/
  46696. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  46697. +
  46698. +} MV_SATA_DEC_WIN;
  46699. +
  46700. +
  46701. +#define MV_SATA_MAX_ADDR_DECODE_WIN 4
  46702. +
  46703. +#define MV_SATA_WIN_CTRL_REG(dev, win) (SATA_REG_BASE + 0x30 + ((win)<<4))
  46704. +#define MV_SATA_WIN_BASE_REG(dev, win) (SATA_REG_BASE + 0x34 + ((win)<<4))
  46705. +
  46706. +/* BITs in Bridge Interrupt Cause and Mask registers */
  46707. +#define MV_SATA_ADDR_DECODE_ERROR_BIT 0
  46708. +#define MV_SATA_ADDR_DECODE_ERROR_MASK (1<<MV_SATA_ADDR_DECODE_ERROR_BIT)
  46709. +
  46710. +/* BITs in Windows 0-3 Control and Base Registers */
  46711. +#define MV_SATA_WIN_ENABLE_BIT 0
  46712. +#define MV_SATA_WIN_ENABLE_MASK (1<<MV_SATA_WIN_ENABLE_BIT)
  46713. +
  46714. +#define MV_SATA_WIN_TARGET_OFFSET 4
  46715. +#define MV_SATA_WIN_TARGET_MASK (0xF<<MV_SATA_WIN_TARGET_OFFSET)
  46716. +
  46717. +#define MV_SATA_WIN_ATTR_OFFSET 8
  46718. +#define MV_SATA_WIN_ATTR_MASK (0xFF<<MV_SATA_WIN_ATTR_OFFSET)
  46719. +
  46720. +#define MV_SATA_WIN_SIZE_OFFSET 16
  46721. +#define MV_SATA_WIN_SIZE_MASK (0xFFFF<<MV_SATA_WIN_SIZE_OFFSET)
  46722. +
  46723. +#define MV_SATA_WIN_BASE_OFFSET 16
  46724. +#define MV_SATA_WIN_BASE_MASK (0xFFFF<<MV_SATA_WIN_BASE_OFFSET)
  46725. +
  46726. +MV_STATUS mvSataWinGet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin);
  46727. +MV_STATUS mvSataWinSet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin);
  46728. +MV_STATUS mvSataWinByTargetGet(MV_TARGET target, MV_SATA_DEC_WIN *pAddrDecWin);
  46729. +MV_STATUS mvSataWinInit(MV_VOID);
  46730. +MV_VOID mvSataAddrDecShow(MV_VOID);
  46731. +
  46732. +
  46733. +#ifdef __cplusplus
  46734. +}
  46735. +#endif
  46736. +
  46737. +
  46738. +#endif
  46739. +
  46740. +
  46741. +
  46742. +
  46743. +
  46744. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c
  46745. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c 1970-01-01 01:00:00.000000000 +0100
  46746. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c 2010-08-05 22:02:22.533704238 +0200
  46747. @@ -0,0 +1,427 @@
  46748. +/*******************************************************************************
  46749. +Copyright (C) Marvell International Ltd. and its affiliates
  46750. +
  46751. +This software file (the "File") is owned and distributed by Marvell
  46752. +International Ltd. and/or its affiliates ("Marvell") under the following
  46753. +alternative licensing terms. Once you have made an election to distribute the
  46754. +File under one of the following license alternatives, please (i) delete this
  46755. +introductory statement regarding license alternatives, (ii) delete the two
  46756. +license alternatives that you have not elected to use and (iii) preserve the
  46757. +Marvell copyright notice above.
  46758. +
  46759. +********************************************************************************
  46760. +Marvell Commercial License Option
  46761. +
  46762. +If you received this File from Marvell and you have entered into a commercial
  46763. +license agreement (a "Commercial License") with Marvell, the File is licensed
  46764. +to you under the terms of the applicable Commercial License.
  46765. +
  46766. +********************************************************************************
  46767. +Marvell GPL License Option
  46768. +
  46769. +If you received this File from Marvell, you may opt to use, redistribute and/or
  46770. +modify this File in accordance with the terms and conditions of the General
  46771. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  46772. +available along with the File in the license.txt file or by writing to the Free
  46773. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  46774. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  46775. +
  46776. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  46777. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  46778. +DISCLAIMED. The GPL License provides additional details about this warranty
  46779. +disclaimer.
  46780. +********************************************************************************
  46781. +Marvell BSD License Option
  46782. +
  46783. +If you received this File from Marvell, you may opt to use, redistribute and/or
  46784. +modify this File under the following licensing terms.
  46785. +Redistribution and use in source and binary forms, with or without modification,
  46786. +are permitted provided that the following conditions are met:
  46787. +
  46788. + * Redistributions of source code must retain the above copyright notice,
  46789. + this list of conditions and the following disclaimer.
  46790. +
  46791. + * Redistributions in binary form must reproduce the above copyright
  46792. + notice, this list of conditions and the following disclaimer in the
  46793. + documentation and/or other materials provided with the distribution.
  46794. +
  46795. + * Neither the name of Marvell nor the names of its contributors may be
  46796. + used to endorse or promote products derived from this software without
  46797. + specific prior written permission.
  46798. +
  46799. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  46800. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  46801. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  46802. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  46803. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  46804. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  46805. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  46806. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  46807. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  46808. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  46809. +
  46810. +*******************************************************************************/
  46811. +
  46812. +
  46813. +#include "mvTypes.h"
  46814. +#include "mvCommon.h"
  46815. +#include "mvOs.h"
  46816. +#include "ctrlEnv/mvCtrlEnvLib.h"
  46817. +#include "cpu/mvCpu.h"
  46818. +#include "ctrlEnv/sys/mvCpuIf.h"
  46819. +#include "mvRegs.h"
  46820. +#include "ctrlEnv/sys/mvSysSdmmc.h"
  46821. +
  46822. +MV_TARGET sdmmcAddrDecPrioTab[] =
  46823. +{
  46824. +#if defined(MV_INCLUDE_SDRAM_CS0)
  46825. + SDRAM_CS0,
  46826. +#endif
  46827. +#if defined(MV_INCLUDE_SDRAM_CS1)
  46828. + SDRAM_CS1,
  46829. +#endif
  46830. +#if defined(MV_INCLUDE_SDRAM_CS2)
  46831. + SDRAM_CS2,
  46832. +#endif
  46833. +#if defined(MV_INCLUDE_SDRAM_CS3)
  46834. + SDRAM_CS3,
  46835. +#endif
  46836. +#if defined(MV_INCLUDE_PEX)
  46837. + PEX0_MEM,
  46838. +#endif
  46839. + TBL_TERM
  46840. +};
  46841. +
  46842. +
  46843. +/*******************************************************************************
  46844. +* sdmmcWinOverlapDetect - Detect SDMMC address windows overlapping
  46845. +*
  46846. +* DESCRIPTION:
  46847. +* An unpredicted behaviur is expected in case SDMMC address decode
  46848. +* windows overlapps.
  46849. +* This function detects SDMMC address decode windows overlapping of a
  46850. +* specified window. The function does not check the window itself for
  46851. +* overlapping. The function also skipps disabled address decode windows.
  46852. +*
  46853. +* INPUT:
  46854. +* winNum - address decode window number.
  46855. +* pAddrDecWin - An address decode window struct.
  46856. +*
  46857. +* OUTPUT:
  46858. +* None.
  46859. +*
  46860. +* RETURN:
  46861. +* MV_TRUE if the given address window overlap current address
  46862. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  46863. +* from registers.
  46864. +*
  46865. +*******************************************************************************/
  46866. +static MV_STATUS sdmmcWinOverlapDetect(int dev, MV_U32 winNum,
  46867. + MV_ADDR_WIN *pAddrWin)
  46868. +{
  46869. + MV_U32 winNumIndex;
  46870. + MV_SDMMC_DEC_WIN addrDecWin;
  46871. +
  46872. + for(winNumIndex=0; winNumIndex<MV_SDMMC_MAX_ADDR_DECODE_WIN; winNumIndex++)
  46873. + {
  46874. + /* Do not check window itself */
  46875. + if (winNumIndex == winNum)
  46876. + {
  46877. + continue;
  46878. + }
  46879. +
  46880. + /* Get window parameters */
  46881. + if (MV_OK != mvSdmmcWinGet(dev, winNumIndex, &addrDecWin))
  46882. + {
  46883. + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
  46884. + return MV_ERROR;
  46885. + }
  46886. +
  46887. + /* Do not check disabled windows */
  46888. + if(addrDecWin.enable == MV_FALSE)
  46889. + {
  46890. + continue;
  46891. + }
  46892. +
  46893. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  46894. + {
  46895. + return MV_TRUE;
  46896. + }
  46897. + }
  46898. + return MV_FALSE;
  46899. +}
  46900. +
  46901. +
  46902. +/*******************************************************************************
  46903. +* mvSdmmcWinSet - Set SDMMC target address window
  46904. +*
  46905. +* DESCRIPTION:
  46906. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  46907. +* address window, also known as address decode window.
  46908. +* After setting this target window, the SDMMC will be able to access the
  46909. +* target within the address window.
  46910. +*
  46911. +* INPUT:
  46912. +* winNum - SDMMC target address decode window number.
  46913. +* pAddrDecWin - SDMMC target window data structure.
  46914. +*
  46915. +* OUTPUT:
  46916. +* None.
  46917. +*
  46918. +* RETURN:
  46919. +* MV_ERROR if address window overlapps with other address decode windows.
  46920. +* MV_BAD_PARAM if base address is invalid parameter or target is
  46921. +* unknown.
  46922. +*
  46923. +*******************************************************************************/
  46924. +MV_STATUS mvSdmmcWinSet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin)
  46925. +{
  46926. + MV_TARGET_ATTRIB targetAttribs;
  46927. + MV_DEC_REGS decRegs;
  46928. +
  46929. + /* Parameter checking */
  46930. + if (winNum >= MV_SDMMC_MAX_ADDR_DECODE_WIN)
  46931. + {
  46932. + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
  46933. + return MV_BAD_PARAM;
  46934. + }
  46935. +
  46936. + /* Check if the requested window overlapps with current windows */
  46937. + if (MV_TRUE == sdmmcWinOverlapDetect(dev, winNum, &pAddrDecWin->addrWin))
  46938. + {
  46939. + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
  46940. + return MV_ERROR;
  46941. + }
  46942. +
  46943. + /* check if address is aligned to the size */
  46944. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  46945. + {
  46946. + mvOsPrintf("mvSdmmcWinSet:Error setting SDMMC window %d to "\
  46947. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  46948. + winNum,
  46949. + mvCtrlTargetNameGet(pAddrDecWin->target),
  46950. + pAddrDecWin->addrWin.baseLow,
  46951. + pAddrDecWin->addrWin.size);
  46952. + return MV_ERROR;
  46953. + }
  46954. +
  46955. + decRegs.baseReg = 0;
  46956. + decRegs.sizeReg = 0;
  46957. +
  46958. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  46959. + {
  46960. + mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
  46961. + return MV_ERROR;
  46962. + }
  46963. +
  46964. + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
  46965. +
  46966. + /* set attributes */
  46967. + decRegs.sizeReg &= ~MV_SDMMC_WIN_ATTR_MASK;
  46968. + decRegs.sizeReg |= (targetAttribs.attrib << MV_SDMMC_WIN_ATTR_OFFSET);
  46969. +
  46970. + /* set target ID */
  46971. + decRegs.sizeReg &= ~MV_SDMMC_WIN_TARGET_MASK;
  46972. + decRegs.sizeReg |= (targetAttribs.targetId << MV_SDMMC_WIN_TARGET_OFFSET);
  46973. +
  46974. + if (pAddrDecWin->enable == MV_TRUE)
  46975. + {
  46976. + decRegs.sizeReg |= MV_SDMMC_WIN_ENABLE_MASK;
  46977. + }
  46978. + else
  46979. + {
  46980. + decRegs.sizeReg &= ~MV_SDMMC_WIN_ENABLE_MASK;
  46981. + }
  46982. +
  46983. + MV_REG_WRITE( MV_SDMMC_WIN_CTRL_REG(dev, winNum), decRegs.sizeReg);
  46984. + MV_REG_WRITE( MV_SDMMC_WIN_BASE_REG(dev, winNum), decRegs.baseReg);
  46985. +
  46986. + return MV_OK;
  46987. +}
  46988. +
  46989. +/*******************************************************************************
  46990. +* mvSdmmcWinGet - Get SDMMC peripheral target address window.
  46991. +*
  46992. +* DESCRIPTION:
  46993. +* Get SDMMC peripheral target address window.
  46994. +*
  46995. +* INPUT:
  46996. +* winNum - SDMMC target address decode window number.
  46997. +*d
  46998. +* OUTPUT:
  46999. +* pAddrDecWin - SDMMC target window data structure.
  47000. +*
  47001. +* RETURN:
  47002. +* MV_ERROR if register parameters are invalid.
  47003. +*
  47004. +*******************************************************************************/
  47005. +MV_STATUS mvSdmmcWinGet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin)
  47006. +{
  47007. + MV_DEC_REGS decRegs;
  47008. + MV_TARGET_ATTRIB targetAttrib;
  47009. +
  47010. + /* Parameter checking */
  47011. + if (winNum >= MV_SDMMC_MAX_ADDR_DECODE_WIN)
  47012. + {
  47013. + mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",
  47014. + __FUNCTION__, dev, winNum);
  47015. + return MV_NOT_SUPPORTED;
  47016. + }
  47017. +
  47018. + decRegs.baseReg = MV_REG_READ( MV_SDMMC_WIN_BASE_REG(dev, winNum) );
  47019. + decRegs.sizeReg = MV_REG_READ( MV_SDMMC_WIN_CTRL_REG(dev, winNum) );
  47020. +
  47021. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
  47022. + {
  47023. + mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
  47024. + return MV_ERROR;
  47025. + }
  47026. +
  47027. + /* attrib and targetId */
  47028. + targetAttrib.attrib = (decRegs.sizeReg & MV_SDMMC_WIN_ATTR_MASK) >>
  47029. + MV_SDMMC_WIN_ATTR_OFFSET;
  47030. + targetAttrib.targetId = (decRegs.sizeReg & MV_SDMMC_WIN_TARGET_MASK) >>
  47031. + MV_SDMMC_WIN_TARGET_OFFSET;
  47032. +
  47033. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  47034. +
  47035. + /* Check if window is enabled */
  47036. + if(decRegs.sizeReg & MV_SDMMC_WIN_ENABLE_MASK)
  47037. + {
  47038. + pAddrDecWin->enable = MV_TRUE;
  47039. + }
  47040. + else
  47041. + {
  47042. + pAddrDecWin->enable = MV_FALSE;
  47043. + }
  47044. + return MV_OK;
  47045. +}
  47046. +/*******************************************************************************
  47047. +* mvSdmmcAddrDecShow - Print the SDMMC address decode map.
  47048. +*
  47049. +* DESCRIPTION:
  47050. +* This function print the SDMMC address decode map.
  47051. +*
  47052. +* INPUT:
  47053. +* None.
  47054. +*
  47055. +* OUTPUT:
  47056. +* None.
  47057. +*
  47058. +* RETURN:
  47059. +* None.
  47060. +*
  47061. +*******************************************************************************/
  47062. +MV_VOID mvSdmmcAddrDecShow(MV_VOID)
  47063. +{
  47064. +
  47065. + MV_SDMMC_DEC_WIN win;
  47066. + int i,j=0;
  47067. +
  47068. +
  47069. +
  47070. + if (MV_FALSE == mvCtrlPwrClckGet(SDIO_UNIT_ID, 0))
  47071. + return;
  47072. +
  47073. + mvOsOutput( "\n" );
  47074. + mvOsOutput( "SDMMC %d:\n", j );
  47075. + mvOsOutput( "----\n" );
  47076. +
  47077. + for( i = 0; i < MV_SDMMC_MAX_ADDR_DECODE_WIN; i++ )
  47078. + {
  47079. + memset( &win, 0, sizeof(MV_SDMMC_DEC_WIN) );
  47080. +
  47081. + mvOsOutput( "win%d - ", i );
  47082. +
  47083. + if( mvSdmmcWinGet(j, i, &win ) == MV_OK )
  47084. + {
  47085. + if( win.enable )
  47086. + {
  47087. + mvOsOutput( "%s base %08x, ",
  47088. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  47089. + mvOsOutput( "...." );
  47090. +
  47091. + mvSizePrint( win.addrWin.size );
  47092. +
  47093. + mvOsOutput( "\n" );
  47094. + }
  47095. + else
  47096. + mvOsOutput( "disable\n" );
  47097. + }
  47098. + }
  47099. +}
  47100. +
  47101. +
  47102. +/*******************************************************************************
  47103. +* mvSdmmcWinInit - Initialize the integrated SDMMC target address window.
  47104. +*
  47105. +* DESCRIPTION:
  47106. +* Initialize the SDMMC peripheral target address window.
  47107. +*
  47108. +* INPUT:
  47109. +*
  47110. +*
  47111. +* OUTPUT:
  47112. +*
  47113. +*
  47114. +* RETURN:
  47115. +* MV_ERROR if register parameters are invalid.
  47116. +*
  47117. +*******************************************************************************/
  47118. +MV_STATUS mvSdmmcWinInit(MV_VOID)
  47119. +{
  47120. + int winNum;
  47121. + MV_SDMMC_DEC_WIN sdmmcWin;
  47122. + MV_CPU_DEC_WIN cpuAddrDecWin;
  47123. + MV_U32 status, winPrioIndex = 0;
  47124. +
  47125. + /* Initiate Sdmmc address decode */
  47126. +
  47127. + /* First disable all address decode windows */
  47128. + for(winNum = 0; winNum < MV_SDMMC_MAX_ADDR_DECODE_WIN; winNum++)
  47129. + {
  47130. + MV_U32 regVal = MV_REG_READ(MV_SDMMC_WIN_CTRL_REG(0, winNum));
  47131. + regVal &= ~MV_SDMMC_WIN_ENABLE_MASK;
  47132. + MV_REG_WRITE(MV_SDMMC_WIN_CTRL_REG(0, winNum), regVal);
  47133. + }
  47134. +
  47135. + winNum = 0;
  47136. + while( (sdmmcAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
  47137. + (winNum < MV_SDMMC_MAX_ADDR_DECODE_WIN) )
  47138. + {
  47139. + /* first get attributes from CPU If */
  47140. + status = mvCpuIfTargetWinGet(sdmmcAddrDecPrioTab[winPrioIndex],
  47141. + &cpuAddrDecWin);
  47142. +
  47143. + if(MV_NO_SUCH == status)
  47144. + {
  47145. + winPrioIndex++;
  47146. + continue;
  47147. + }
  47148. + if (MV_OK != status)
  47149. + {
  47150. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  47151. + return MV_ERROR;
  47152. + }
  47153. +
  47154. + if (cpuAddrDecWin.enable == MV_TRUE)
  47155. + {
  47156. + sdmmcWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  47157. + sdmmcWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  47158. + sdmmcWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  47159. + sdmmcWin.enable = MV_TRUE;
  47160. + sdmmcWin.target = sdmmcAddrDecPrioTab[winPrioIndex];
  47161. +
  47162. + if(MV_OK != mvSdmmcWinSet(0/*dev*/, winNum, &sdmmcWin))
  47163. + {
  47164. + return MV_ERROR;
  47165. + }
  47166. + winNum++;
  47167. + }
  47168. + winPrioIndex++;
  47169. + }
  47170. + return MV_OK;
  47171. +}
  47172. +
  47173. +
  47174. +
  47175. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h
  47176. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h 1970-01-01 01:00:00.000000000 +0100
  47177. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h 2010-08-05 22:02:22.873729006 +0200
  47178. @@ -0,0 +1,125 @@
  47179. +
  47180. +/*******************************************************************************
  47181. +Copyright (C) Marvell International Ltd. and its affiliates
  47182. +
  47183. +This software file (the "File") is owned and distributed by Marvell
  47184. +International Ltd. and/or its affiliates ("Marvell") under the following
  47185. +alternative licensing terms. Once you have made an election to distribute the
  47186. +File under one of the following license alternatives, please (i) delete this
  47187. +introductory statement regarding license alternatives, (ii) delete the two
  47188. +license alternatives that you have not elected to use and (iii) preserve the
  47189. +Marvell copyright notice above.
  47190. +
  47191. +********************************************************************************
  47192. +Marvell Commercial License Option
  47193. +
  47194. +If you received this File from Marvell and you have entered into a commercial
  47195. +license agreement (a "Commercial License") with Marvell, the File is licensed
  47196. +to you under the terms of the applicable Commercial License.
  47197. +
  47198. +********************************************************************************
  47199. +Marvell GPL License Option
  47200. +
  47201. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47202. +modify this File in accordance with the terms and conditions of the General
  47203. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  47204. +available along with the File in the license.txt file or by writing to the Free
  47205. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  47206. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  47207. +
  47208. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  47209. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  47210. +DISCLAIMED. The GPL License provides additional details about this warranty
  47211. +disclaimer.
  47212. +********************************************************************************
  47213. +Marvell BSD License Option
  47214. +
  47215. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47216. +modify this File under the following licensing terms.
  47217. +Redistribution and use in source and binary forms, with or without modification,
  47218. +are permitted provided that the following conditions are met:
  47219. +
  47220. + * Redistributions of source code must retain the above copyright notice,
  47221. + this list of conditions and the following disclaimer.
  47222. +
  47223. + * Redistributions in binary form must reproduce the above copyright
  47224. + notice, this list of conditions and the following disclaimer in the
  47225. + documentation and/or other materials provided with the distribution.
  47226. +
  47227. + * Neither the name of Marvell nor the names of its contributors may be
  47228. + used to endorse or promote products derived from this software without
  47229. + specific prior written permission.
  47230. +
  47231. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  47232. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  47233. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  47234. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  47235. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  47236. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  47237. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  47238. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  47239. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  47240. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  47241. +
  47242. +*******************************************************************************/
  47243. +#ifndef __INCMVSysSdmmcAddrDech
  47244. +#define __INCMVSysSdmmcAddrDech
  47245. +
  47246. +#include "mvCommon.h"
  47247. +#include "ctrlEnv/mvCtrlEnvLib.h"
  47248. +#include "ctrlEnv/sys/mvCpuIf.h"
  47249. +
  47250. +
  47251. +#ifdef __cplusplus
  47252. +extern "C" {
  47253. +#endif
  47254. +
  47255. +typedef struct _mvSdmmcDecWin
  47256. +{
  47257. + MV_TARGET target;
  47258. + MV_ADDR_WIN addrWin; /* An address window*/
  47259. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  47260. +
  47261. +} MV_SDMMC_DEC_WIN;
  47262. +
  47263. +
  47264. +#define MV_SDMMC_MAX_ADDR_DECODE_WIN 4
  47265. +
  47266. +#define MV_SDMMC_WIN_CTRL_REG(dev, win) (MV_SDIO_REG_BASE + 0x108 + ((win)<<3))
  47267. +#define MV_SDMMC_WIN_BASE_REG(dev, win) (MV_SDIO_REG_BASE + 0x10c + ((win)<<3))
  47268. +
  47269. +
  47270. +/* BITs in Windows 0-3 Control and Base Registers */
  47271. +#define MV_SDMMC_WIN_ENABLE_BIT 0
  47272. +#define MV_SDMMC_WIN_ENABLE_MASK (1<<MV_SDMMC_WIN_ENABLE_BIT)
  47273. +
  47274. +#define MV_SDMMC_WIN_TARGET_OFFSET 4
  47275. +#define MV_SDMMC_WIN_TARGET_MASK (0xF<<MV_SDMMC_WIN_TARGET_OFFSET)
  47276. +
  47277. +#define MV_SDMMC_WIN_ATTR_OFFSET 8
  47278. +#define MV_SDMMC_WIN_ATTR_MASK (0xFF<<MV_SDMMC_WIN_ATTR_OFFSET)
  47279. +
  47280. +#define MV_SDMMC_WIN_SIZE_OFFSET 16
  47281. +#define MV_SDMMC_WIN_SIZE_MASK (0xFFFF<<MV_SDMMC_WIN_SIZE_OFFSET)
  47282. +
  47283. +#define MV_SDMMC_WIN_BASE_OFFSET 16
  47284. +#define MV_SDMMC_WIN_BASE_MASK (0xFFFF<<MV_SDMMC_WIN_BASE_OFFSET)
  47285. +
  47286. +MV_STATUS mvSdmmcWinGet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin);
  47287. +MV_STATUS mvSdmmcWinSet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin);
  47288. +MV_STATUS mvSdmmcWinByTargetGet(MV_TARGET target, MV_SDMMC_DEC_WIN *pAddrDecWin);
  47289. +MV_STATUS mvSdmmcWinInit(MV_VOID);
  47290. +MV_VOID mvSdmmcAddrDecShow(MV_VOID);
  47291. +
  47292. +
  47293. +#ifdef __cplusplus
  47294. +}
  47295. +#endif
  47296. +
  47297. +
  47298. +#endif
  47299. +
  47300. +
  47301. +
  47302. +
  47303. +
  47304. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c
  47305. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c 1970-01-01 01:00:00.000000000 +0100
  47306. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c 2010-08-05 22:02:22.923805489 +0200
  47307. @@ -0,0 +1,462 @@
  47308. +/*******************************************************************************
  47309. +Copyright (C) Marvell International Ltd. and its affiliates
  47310. +
  47311. +This software file (the "File") is owned and distributed by Marvell
  47312. +International Ltd. and/or its affiliates ("Marvell") under the following
  47313. +alternative licensing terms. Once you have made an election to distribute the
  47314. +File under one of the following license alternatives, please (i) delete this
  47315. +introductory statement regarding license alternatives, (ii) delete the two
  47316. +license alternatives that you have not elected to use and (iii) preserve the
  47317. +Marvell copyright notice above.
  47318. +
  47319. +********************************************************************************
  47320. +Marvell Commercial License Option
  47321. +
  47322. +If you received this File from Marvell and you have entered into a commercial
  47323. +license agreement (a "Commercial License") with Marvell, the File is licensed
  47324. +to you under the terms of the applicable Commercial License.
  47325. +
  47326. +********************************************************************************
  47327. +Marvell GPL License Option
  47328. +
  47329. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47330. +modify this File in accordance with the terms and conditions of the General
  47331. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  47332. +available along with the File in the license.txt file or by writing to the Free
  47333. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  47334. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  47335. +
  47336. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  47337. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  47338. +DISCLAIMED. The GPL License provides additional details about this warranty
  47339. +disclaimer.
  47340. +********************************************************************************
  47341. +Marvell BSD License Option
  47342. +
  47343. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47344. +modify this File under the following licensing terms.
  47345. +Redistribution and use in source and binary forms, with or without modification,
  47346. +are permitted provided that the following conditions are met:
  47347. +
  47348. + * Redistributions of source code must retain the above copyright notice,
  47349. + this list of conditions and the following disclaimer.
  47350. +
  47351. + * Redistributions in binary form must reproduce the above copyright
  47352. + notice, this list of conditions and the following disclaimer in the
  47353. + documentation and/or other materials provided with the distribution.
  47354. +
  47355. + * Neither the name of Marvell nor the names of its contributors may be
  47356. + used to endorse or promote products derived from this software without
  47357. + specific prior written permission.
  47358. +
  47359. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  47360. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  47361. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  47362. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  47363. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  47364. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  47365. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  47366. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  47367. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  47368. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  47369. +
  47370. +*******************************************************************************/
  47371. +
  47372. +#include "mvSysTdm.h"
  47373. +
  47374. +
  47375. +/* defines */
  47376. +#ifdef MV_DEBUG
  47377. + #define DB(x) x
  47378. +#else
  47379. + #define DB(x)
  47380. +#endif
  47381. +
  47382. +static MV_TARGET tdmAddrDecPrioTap[] =
  47383. +{
  47384. + PEX0_MEM,
  47385. + SDRAM_CS0,
  47386. + SDRAM_CS1,
  47387. + SDRAM_CS2,
  47388. + SDRAM_CS3,
  47389. + DEVICE_CS0,
  47390. + DEVICE_CS1,
  47391. + DEVICE_CS2,
  47392. + DEV_BOOCS,
  47393. + PEX0_IO,
  47394. + TBL_TERM
  47395. +};
  47396. +
  47397. +static MV_STATUS tdmWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
  47398. +
  47399. +/*******************************************************************************
  47400. +* mvTdmWinInit - Initialize TDM address decode windows
  47401. +*
  47402. +* DESCRIPTION:
  47403. +* This function initialize TDM window decode unit. It set the
  47404. +* default address decode
  47405. +* windows of the unit.
  47406. +*
  47407. +* INPUT:
  47408. +* None.
  47409. +*
  47410. +* OUTPUT:
  47411. +* None.
  47412. +*
  47413. +* RETURN:
  47414. +* MV_ERROR if setting fail.
  47415. +*******************************************************************************/
  47416. +
  47417. +MV_STATUS mvTdmWinInit(void)
  47418. +{
  47419. + MV_U32 winNum;
  47420. + MV_U32 winPrioIndex = 0;
  47421. + MV_CPU_DEC_WIN cpuAddrDecWin;
  47422. + MV_TDM_DEC_WIN tdmWin;
  47423. + MV_STATUS status;
  47424. +
  47425. + /*Disable all windows*/
  47426. + for (winNum = 0; winNum < TDM_MBUS_MAX_WIN; winNum++)
  47427. + {
  47428. + mvTdmWinEnable(winNum, MV_FALSE);
  47429. + }
  47430. +
  47431. + for (winNum = 0; ((tdmAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
  47432. + (winNum < TDM_MBUS_MAX_WIN)); )
  47433. + {
  47434. + status = mvCpuIfTargetWinGet(tdmAddrDecPrioTap[winPrioIndex],
  47435. + &cpuAddrDecWin);
  47436. + if (MV_NO_SUCH == status)
  47437. + {
  47438. + winPrioIndex++;
  47439. + continue;
  47440. + }
  47441. + if (MV_OK != status)
  47442. + {
  47443. + mvOsPrintf("mvTdmInit: ERR. mvCpuIfTargetWinGet failed\n");
  47444. + return MV_ERROR;
  47445. + }
  47446. +
  47447. + if (cpuAddrDecWin.enable == MV_TRUE)
  47448. + {
  47449. + tdmWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  47450. + tdmWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  47451. + tdmWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  47452. + tdmWin.enable = MV_TRUE;
  47453. + tdmWin.target = tdmAddrDecPrioTap[winPrioIndex];
  47454. + if (MV_OK != mvTdmWinSet(winNum, &tdmWin))
  47455. + {
  47456. + return MV_ERROR;
  47457. + }
  47458. + winNum++;
  47459. + }
  47460. + winPrioIndex++;
  47461. + }
  47462. + return MV_OK;
  47463. +}
  47464. +
  47465. +/*******************************************************************************
  47466. +* mvTdmWinSet - Set TDM target address window
  47467. +*
  47468. +* DESCRIPTION:
  47469. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  47470. +* address window, also known as address decode window.
  47471. +* After setting this target window, the TDM will be able to access the
  47472. +* target within the address window.
  47473. +*
  47474. +* INPUT:
  47475. +* winNum - TDM to target address decode window number.
  47476. +* pAddrDecWin - TDM target window data structure.
  47477. +*
  47478. +* OUTPUT:
  47479. +* None.
  47480. +*
  47481. +* RETURN:
  47482. +* MV_ERROR if address window overlapps with other address decode windows.
  47483. +* MV_BAD_PARAM if base address is invalid parameter or target is
  47484. +* unknown.
  47485. +*
  47486. +*******************************************************************************/
  47487. +
  47488. +MV_STATUS mvTdmWinSet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)
  47489. +{
  47490. + MV_TARGET_ATTRIB targetAttribs;
  47491. + MV_DEC_REGS decRegs;
  47492. + MV_U32 ctrlReg = 0;
  47493. +
  47494. + /* Parameter checking */
  47495. + if (winNum >= TDM_MBUS_MAX_WIN)
  47496. + {
  47497. + mvOsPrintf("mvTdmWinSet: ERR. Invalid win num %d\n",winNum);
  47498. + return MV_BAD_PARAM;
  47499. + }
  47500. +
  47501. + /* Check if the requested window overlapps with current windows */
  47502. + if (MV_TRUE == tdmWinOverlapDetect(winNum, &pAddrDecWin->addrWin))
  47503. + {
  47504. + mvOsPrintf("mvTdmWinSet: ERR. Window %d overlap\n", winNum);
  47505. + return MV_ERROR;
  47506. + }
  47507. +
  47508. + /* check if address is aligned to the size */
  47509. + if (MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  47510. + {
  47511. + mvOsPrintf("mvTdmWinSet: Error setting TDM window %d to "\
  47512. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  47513. + winNum,
  47514. + mvCtrlTargetNameGet(pAddrDecWin->target),
  47515. + pAddrDecWin->addrWin.baseLow,
  47516. + pAddrDecWin->addrWin.size);
  47517. + return MV_ERROR;
  47518. + }
  47519. +
  47520. + decRegs.baseReg = MV_REG_READ(TDM_WIN_BASE_REG(winNum));
  47521. + decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >> TDM_WIN_SIZE_OFFS;
  47522. +
  47523. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  47524. + {
  47525. + mvOsPrintf("mvTdmWinSet: mvCtrlAddrDecToReg Failed\n");
  47526. + return MV_ERROR;
  47527. + }
  47528. +
  47529. + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
  47530. +
  47531. + /* for the safe side we disable the window before writing the new
  47532. + values */
  47533. + mvTdmWinEnable(winNum, MV_FALSE);
  47534. +
  47535. + ctrlReg |= (targetAttribs.attrib << TDM_WIN_ATTRIB_OFFS);
  47536. + ctrlReg |= (targetAttribs.targetId << TDM_WIN_TARGET_OFFS);
  47537. + ctrlReg |= (decRegs.sizeReg & TDM_WIN_SIZE_MASK);
  47538. +
  47539. + /* Write to address base and control registers */
  47540. + MV_REG_WRITE(TDM_WIN_BASE_REG(winNum), decRegs.baseReg);
  47541. + MV_REG_WRITE(TDM_WIN_CTRL_REG(winNum), ctrlReg);
  47542. + /* Enable address decode target window */
  47543. + if (pAddrDecWin->enable == MV_TRUE)
  47544. + {
  47545. + mvTdmWinEnable(winNum, MV_TRUE);
  47546. + }
  47547. + return MV_OK;
  47548. +}
  47549. +
  47550. +/*******************************************************************************
  47551. +* mvTdmWinGet - Get peripheral target address window.
  47552. +*
  47553. +* DESCRIPTION:
  47554. +* Get TDM peripheral target address window.
  47555. +*
  47556. +* INPUT:
  47557. +* winNum - TDM to target address decode window number.
  47558. +*
  47559. +* OUTPUT:
  47560. +* pAddrDecWin - TDM target window data structure.
  47561. +*
  47562. +* RETURN:
  47563. +* MV_ERROR if register parameters are invalid.
  47564. +*
  47565. +*******************************************************************************/
  47566. +
  47567. +MV_STATUS mvTdmWinGet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)
  47568. +{
  47569. +
  47570. + MV_DEC_REGS decRegs;
  47571. + MV_TARGET_ATTRIB targetAttrib;
  47572. +
  47573. + /* Parameter checking */
  47574. + if (winNum >= TDM_MBUS_MAX_WIN)
  47575. + {
  47576. + mvOsPrintf("mvTdmWinGet: ERR. Invalid winNum %d\n", winNum);
  47577. + return MV_NOT_SUPPORTED;
  47578. + }
  47579. +
  47580. + decRegs.baseReg = MV_REG_READ(TDM_WIN_BASE_REG(winNum));
  47581. + decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >> TDM_WIN_SIZE_OFFS;
  47582. +
  47583. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  47584. + {
  47585. + mvOsPrintf("mvTdmWinGet: mvCtrlRegToAddrDec Failed \n");
  47586. + return MV_ERROR;
  47587. + }
  47588. +
  47589. + /* attrib and targetId */
  47590. + targetAttrib.attrib =
  47591. + (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ATTRIB_MASK) >> TDM_WIN_ATTRIB_OFFS;
  47592. + targetAttrib.targetId =
  47593. + (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_TARGET_MASK) >> TDM_WIN_TARGET_OFFS;
  47594. +
  47595. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  47596. +
  47597. + /* Check if window is enabled */
  47598. + if (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ENABLE_MASK)
  47599. + {
  47600. + pAddrDecWin->enable = MV_TRUE;
  47601. + }
  47602. + else
  47603. + {
  47604. + pAddrDecWin->enable = MV_FALSE;
  47605. + }
  47606. +
  47607. + return MV_OK;
  47608. +}
  47609. +
  47610. +/*******************************************************************************
  47611. +* mvTdmWinEnable - Enable/disable a TDM to target address window
  47612. +*
  47613. +* DESCRIPTION:
  47614. +* This function enable/disable a TDM to target address window.
  47615. +* According to parameter 'enable' the routine will enable the
  47616. +* window, thus enabling TDM accesses (before enabling the window it is
  47617. +* tested for overlapping). Otherwise, the window will be disabled.
  47618. +*
  47619. +* INPUT:
  47620. +* winNum - TDM to target address decode window number.
  47621. +* enable - Enable/disable parameter.
  47622. +*
  47623. +* OUTPUT:
  47624. +* N/A
  47625. +*
  47626. +* RETURN:
  47627. +* MV_ERROR if decode window number was wrong or enabled window overlapps.
  47628. +*
  47629. +*******************************************************************************/
  47630. +MV_STATUS mvTdmWinEnable(int winNum, MV_BOOL enable)
  47631. +{
  47632. + MV_TDM_DEC_WIN addrDecWin;
  47633. +
  47634. + if (MV_TRUE == enable)
  47635. + {
  47636. + if (winNum >= TDM_MBUS_MAX_WIN)
  47637. + {
  47638. + mvOsPrintf("mvTdmWinEnable:ERR. Invalid winNum%d\n",winNum);
  47639. + return MV_ERROR;
  47640. + }
  47641. +
  47642. + /* First check for overlap with other enabled windows */
  47643. + /* Get current window */
  47644. + if (MV_OK != mvTdmWinGet(winNum, &addrDecWin))
  47645. + {
  47646. + mvOsPrintf("mvTdmWinEnable:ERR. targetWinGet fail\n");
  47647. + return MV_ERROR;
  47648. + }
  47649. + /* Check for overlapping */
  47650. + if (MV_FALSE == tdmWinOverlapDetect(winNum, &(addrDecWin.addrWin)))
  47651. + {
  47652. + /* No Overlap. Enable address decode target window */
  47653. + MV_REG_BIT_SET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);
  47654. + }
  47655. + else
  47656. + { /* Overlap detected */
  47657. + mvOsPrintf("mvTdmWinEnable:ERR. Overlap detected\n");
  47658. + return MV_ERROR;
  47659. + }
  47660. + }
  47661. + else
  47662. + {
  47663. + MV_REG_BIT_RESET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);
  47664. + }
  47665. + return MV_OK;
  47666. +}
  47667. +
  47668. +
  47669. +/*******************************************************************************
  47670. +* tdmWinOverlapDetect - Detect TDM address windows overlapping
  47671. +*
  47672. +* DESCRIPTION:
  47673. +* An unpredicted behaviour is expected in case TDM address decode
  47674. +* windows overlapps.
  47675. +* This function detects TDM address decode windows overlapping of a
  47676. +* specified window. The function does not check the window itself for
  47677. +* overlapping. The function also skipps disabled address decode windows.
  47678. +*
  47679. +* INPUT:
  47680. +* winNum - address decode window number.
  47681. +* pAddrDecWin - An address decode window struct.
  47682. +*
  47683. +* OUTPUT:
  47684. +* None.
  47685. +*
  47686. +* RETURN:
  47687. +* MV_TRUE if the given address window overlap current address
  47688. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  47689. +* from registers.
  47690. +*
  47691. +*******************************************************************************/
  47692. +static MV_STATUS tdmWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  47693. +{
  47694. + MV_U32 winNumIndex;
  47695. + MV_TDM_DEC_WIN addrDecWin;
  47696. +
  47697. + for (winNumIndex = 0; winNumIndex < TDM_MBUS_MAX_WIN; winNumIndex++)
  47698. + {
  47699. + /* Do not check window itself */
  47700. + if (winNumIndex == winNum)
  47701. + {
  47702. + continue;
  47703. + }
  47704. + /* Do not check disabled windows */
  47705. + if (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ENABLE_MASK)
  47706. + {
  47707. + /* Get window parameters */
  47708. + if (MV_OK != mvTdmWinGet(winNumIndex, &addrDecWin))
  47709. + {
  47710. + DB(mvOsPrintf("dmaWinOverlapDetect: ERR. TargetWinGet failed\n"));
  47711. + return MV_ERROR;
  47712. + }
  47713. +
  47714. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  47715. + {
  47716. + return MV_TRUE;
  47717. + }
  47718. + }
  47719. + }
  47720. + return MV_FALSE;
  47721. +}
  47722. +
  47723. +/*******************************************************************************
  47724. +* mvTdmAddrDecShow - Print the TDM address decode map.
  47725. +*
  47726. +* DESCRIPTION:
  47727. +* This function print the TDM address decode map.
  47728. +*
  47729. +* INPUT:
  47730. +* None.
  47731. +*
  47732. +* OUTPUT:
  47733. +* None.
  47734. +*
  47735. +* RETURN:
  47736. +* None.
  47737. +*
  47738. +*******************************************************************************/
  47739. +MV_VOID mvTdmAddrDecShow(MV_VOID)
  47740. +{
  47741. + MV_TDM_DEC_WIN win;
  47742. + int i;
  47743. +
  47744. + mvOsOutput( "\n" );
  47745. + mvOsOutput( "TDM:\n" );
  47746. + mvOsOutput( "----\n" );
  47747. +
  47748. + for( i = 0; i < TDM_MBUS_MAX_WIN; i++ )
  47749. + {
  47750. + memset( &win, 0, sizeof(MV_TDM_DEC_WIN) );
  47751. +
  47752. + mvOsOutput( "win%d - ", i );
  47753. +
  47754. + if (mvTdmWinGet(i, &win ) == MV_OK )
  47755. + {
  47756. + if( win.enable )
  47757. + {
  47758. + mvOsOutput( "%s base %08x, ",
  47759. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow);
  47760. + mvOsOutput( "...." );
  47761. + mvSizePrint( win.addrWin.size );
  47762. + mvOsOutput( "\n" );
  47763. + }
  47764. + else
  47765. + mvOsOutput( "disable\n" );
  47766. + }
  47767. + }
  47768. +}
  47769. +
  47770. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h
  47771. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h 1970-01-01 01:00:00.000000000 +0100
  47772. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h 2010-08-05 22:02:22.964868565 +0200
  47773. @@ -0,0 +1,106 @@
  47774. +/*******************************************************************************
  47775. +Copyright (C) Marvell International Ltd. and its affiliates
  47776. +
  47777. +This software file (the "File") is owned and distributed by Marvell
  47778. +International Ltd. and/or its affiliates ("Marvell") under the following
  47779. +alternative licensing terms. Once you have made an election to distribute the
  47780. +File under one of the following license alternatives, please (i) delete this
  47781. +introductory statement regarding license alternatives, (ii) delete the two
  47782. +license alternatives that you have not elected to use and (iii) preserve the
  47783. +Marvell copyright notice above.
  47784. +
  47785. +********************************************************************************
  47786. +Marvell Commercial License Option
  47787. +
  47788. +If you received this File from Marvell and you have entered into a commercial
  47789. +license agreement (a "Commercial License") with Marvell, the File is licensed
  47790. +to you under the terms of the applicable Commercial License.
  47791. +
  47792. +********************************************************************************
  47793. +Marvell GPL License Option
  47794. +
  47795. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47796. +modify this File in accordance with the terms and conditions of the General
  47797. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  47798. +available along with the File in the license.txt file or by writing to the Free
  47799. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  47800. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  47801. +
  47802. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  47803. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  47804. +DISCLAIMED. The GPL License provides additional details about this warranty
  47805. +disclaimer.
  47806. +********************************************************************************
  47807. +Marvell BSD License Option
  47808. +
  47809. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47810. +modify this File under the following licensing terms.
  47811. +Redistribution and use in source and binary forms, with or without modification,
  47812. +are permitted provided that the following conditions are met:
  47813. +
  47814. + * Redistributions of source code must retain the above copyright notice,
  47815. + this list of conditions and the following disclaimer.
  47816. +
  47817. + * Redistributions in binary form must reproduce the above copyright
  47818. + notice, this list of conditions and the following disclaimer in the
  47819. + documentation and/or other materials provided with the distribution.
  47820. +
  47821. + * Neither the name of Marvell nor the names of its contributors may be
  47822. + used to endorse or promote products derived from this software without
  47823. + specific prior written permission.
  47824. +
  47825. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  47826. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  47827. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  47828. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  47829. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  47830. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  47831. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  47832. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  47833. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  47834. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  47835. +
  47836. +*******************************************************************************/
  47837. +
  47838. +#ifndef __INCmvSysTdmh
  47839. +#define __INCmvSysTdmh
  47840. +
  47841. +#include "ctrlEnv/sys/mvCpuIf.h"
  47842. +#include "ctrlEnv/mvCtrlEnvLib.h"
  47843. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  47844. +
  47845. +typedef struct _mvTdmDecWin
  47846. +{
  47847. + MV_TARGET target;
  47848. + MV_ADDR_WIN addrWin; /* An address window*/
  47849. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  47850. +} MV_TDM_DEC_WIN;
  47851. +
  47852. +MV_STATUS mvTdmWinInit(MV_VOID);
  47853. +MV_STATUS mvTdmWinSet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin);
  47854. +MV_STATUS mvTdmWinGet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin);
  47855. +MV_STATUS mvTdmWinEnable(int winNum, MV_BOOL enable);
  47856. +MV_VOID mvTdmAddrDecShow(MV_VOID);
  47857. +
  47858. +
  47859. +#define TDM_MBUS_MAX_WIN 4
  47860. +#define TDM_WIN_CTRL_REG(win) ((TDM_REG_BASE + 0x4030) + (win<<4))
  47861. +#define TDM_WIN_BASE_REG(win) ((TDM_REG_BASE +0x4034) + (win<<4))
  47862. +
  47863. +/* TDM_WIN_CTRL_REG bits */
  47864. +#define TDM_WIN_ENABLE_OFFS 0
  47865. +#define TDM_WIN_ENABLE_MASK (1<<TDM_WIN_ENABLE_OFFS)
  47866. +#define TDM_WIN_ENABLE 1
  47867. +#define TDM_WIN_TARGET_OFFS 4
  47868. +#define TDM_WIN_TARGET_MASK (0xf<<TDM_WIN_TARGET_OFFS)
  47869. +#define TDM_WIN_ATTRIB_OFFS 8
  47870. +#define TDM_WIN_ATTRIB_MASK (0xff<<TDM_WIN_ATTRIB_OFFS)
  47871. +#define TDM_WIN_SIZE_OFFS 16
  47872. +#define TDM_WIN_SIZE_MASK (0xffff<<TDM_WIN_SIZE_OFFS)
  47873. +
  47874. +/* TDM_WIN_BASE_REG bits */
  47875. +#define TDM_BASE_OFFS 16
  47876. +#define TDM_BASE_MASK (0xffff<<TDM_BASE_OFFS)
  47877. +
  47878. +#endif /*__INCmvSysTdmh*/
  47879. +
  47880. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c
  47881. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c 1970-01-01 01:00:00.000000000 +0100
  47882. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c 2010-08-05 22:02:23.004868159 +0200
  47883. @@ -0,0 +1,591 @@
  47884. +/*******************************************************************************
  47885. +Copyright (C) Marvell International Ltd. and its affiliates
  47886. +
  47887. +This software file (the "File") is owned and distributed by Marvell
  47888. +International Ltd. and/or its affiliates ("Marvell") under the following
  47889. +alternative licensing terms. Once you have made an election to distribute the
  47890. +File under one of the following license alternatives, please (i) delete this
  47891. +introductory statement regarding license alternatives, (ii) delete the two
  47892. +license alternatives that you have not elected to use and (iii) preserve the
  47893. +Marvell copyright notice above.
  47894. +
  47895. +********************************************************************************
  47896. +Marvell Commercial License Option
  47897. +
  47898. +If you received this File from Marvell and you have entered into a commercial
  47899. +license agreement (a "Commercial License") with Marvell, the File is licensed
  47900. +to you under the terms of the applicable Commercial License.
  47901. +
  47902. +********************************************************************************
  47903. +Marvell GPL License Option
  47904. +
  47905. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47906. +modify this File in accordance with the terms and conditions of the General
  47907. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  47908. +available along with the File in the license.txt file or by writing to the Free
  47909. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  47910. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  47911. +
  47912. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  47913. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  47914. +DISCLAIMED. The GPL License provides additional details about this warranty
  47915. +disclaimer.
  47916. +********************************************************************************
  47917. +Marvell BSD License Option
  47918. +
  47919. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47920. +modify this File under the following licensing terms.
  47921. +Redistribution and use in source and binary forms, with or without modification,
  47922. +are permitted provided that the following conditions are met:
  47923. +
  47924. + * Redistributions of source code must retain the above copyright notice,
  47925. + this list of conditions and the following disclaimer.
  47926. +
  47927. + * Redistributions in binary form must reproduce the above copyright
  47928. + notice, this list of conditions and the following disclaimer in the
  47929. + documentation and/or other materials provided with the distribution.
  47930. +
  47931. + * Neither the name of Marvell nor the names of its contributors may be
  47932. + used to endorse or promote products derived from this software without
  47933. + specific prior written permission.
  47934. +
  47935. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  47936. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  47937. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  47938. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  47939. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  47940. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  47941. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  47942. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  47943. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  47944. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  47945. +
  47946. +*******************************************************************************/
  47947. +
  47948. +
  47949. +#include "ctrlEnv/sys/mvSysTs.h"
  47950. +
  47951. +
  47952. +typedef struct _mvTsuDecWin
  47953. +{
  47954. + MV_TARGET target;
  47955. + MV_ADDR_WIN addrWin; /* An address window*/
  47956. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  47957. +
  47958. +}MV_TSU_DEC_WIN;
  47959. +
  47960. +
  47961. +MV_TARGET tsuAddrDecPrioTap[] =
  47962. +{
  47963. +#if defined(MV_INCLUDE_PEX)
  47964. + PEX0_MEM,
  47965. +#endif
  47966. +#if defined(MV_INCLUDE_PCI)
  47967. + PCI0_MEM,
  47968. +#endif
  47969. +#if defined(MV_INCLUDE_SDRAM_CS0)
  47970. + SDRAM_CS0,
  47971. +#endif
  47972. +#if defined(MV_INCLUDE_SDRAM_CS1)
  47973. + SDRAM_CS1,
  47974. +#endif
  47975. +#if defined(MV_INCLUDE_SDRAM_CS2)
  47976. + SDRAM_CS2,
  47977. +#endif
  47978. +#if defined(MV_INCLUDE_SDRAM_CS3)
  47979. + SDRAM_CS3,
  47980. +#endif
  47981. +#if defined(MV_INCLUDE_DEVICE_CS0)
  47982. + DEVICE_CS0,
  47983. +#endif
  47984. +#if defined(MV_INCLUDE_DEVICE_CS1)
  47985. + DEVICE_CS1,
  47986. +#endif
  47987. +#if defined(MV_INCLUDE_DEVICE_CS2)
  47988. + DEVICE_CS2,
  47989. +#endif
  47990. +#if defined(MV_INCLUDE_DEVICE_CS3)
  47991. + DEVICE_CS3,
  47992. +#endif
  47993. +#if defined(MV_INCLUDE_PEX)
  47994. + PEX0_IO,
  47995. +#endif
  47996. +#if defined(MV_INCLUDE_PCI)
  47997. + PCI0_IO,
  47998. +#endif
  47999. + TBL_TERM
  48000. +};
  48001. +
  48002. +static MV_STATUS tsuWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
  48003. +static MV_STATUS mvTsuWinSet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin);
  48004. +static MV_STATUS mvTsuWinGet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin);
  48005. +MV_STATUS mvTsuWinEnable(MV_U32 winNum,MV_BOOL enable);
  48006. +
  48007. +/*******************************************************************************
  48008. +* mvTsuWinInit
  48009. +*
  48010. +* DESCRIPTION:
  48011. +* Initialize the TSU unit address decode windows.
  48012. +*
  48013. +* INPUT:
  48014. +* None.
  48015. +* OUTPUT:
  48016. +* None.
  48017. +* RETURN:
  48018. +* MV_OK - on success,
  48019. +*
  48020. +*******************************************************************************/
  48021. +MV_STATUS mvTsuWinInit(void)
  48022. +{
  48023. + MV_U32 winNum, status, winPrioIndex=0;
  48024. + MV_TSU_DEC_WIN tsuWin;
  48025. + MV_CPU_DEC_WIN cpuAddrDecWin;
  48026. +
  48027. + /* First disable all address decode windows */
  48028. + for(winNum = 0; winNum < TSU_MAX_DECODE_WIN; winNum++)
  48029. + {
  48030. + MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum),
  48031. + TSU_WIN_CTRL_EN_MASK);
  48032. + }
  48033. +
  48034. + /* Go through all windows in user table until table terminator */
  48035. + for(winNum = 0; ((tsuAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
  48036. + (winNum < TSU_MAX_DECODE_WIN));)
  48037. + {
  48038. + /* first get attributes from CPU If */
  48039. + status = mvCpuIfTargetWinGet(tsuAddrDecPrioTap[winPrioIndex],
  48040. + &cpuAddrDecWin);
  48041. +
  48042. + if(MV_NO_SUCH == status)
  48043. + {
  48044. + winPrioIndex++;
  48045. + continue;
  48046. + }
  48047. + if(MV_OK != status)
  48048. + {
  48049. + mvOsPrintf("mvTsuWinInit: ERR. mvCpuIfTargetWinGet failed\n");
  48050. + return MV_ERROR;
  48051. + }
  48052. +
  48053. + if (cpuAddrDecWin.enable == MV_TRUE)
  48054. + {
  48055. + tsuWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  48056. + tsuWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  48057. + tsuWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  48058. + tsuWin.enable = MV_TRUE;
  48059. + tsuWin.target = tsuAddrDecPrioTap[winPrioIndex];
  48060. +
  48061. + if(MV_OK != mvTsuWinSet(winNum, &tsuWin))
  48062. + {
  48063. + mvOsPrintf("mvTsuWinInit: ERR. mvTsuWinSet failed winNum=%d\n",
  48064. + winNum);
  48065. + return MV_ERROR;
  48066. + }
  48067. + winNum++;
  48068. + }
  48069. + winPrioIndex ++;
  48070. + }
  48071. +
  48072. + return MV_OK;
  48073. +}
  48074. +
  48075. +
  48076. +/*******************************************************************************
  48077. +* mvTsuWinSet
  48078. +*
  48079. +* DESCRIPTION:
  48080. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  48081. +* address window, also known as address decode window.
  48082. +* After setting this target window, the TSU will be able to access the
  48083. +* target within the address window.
  48084. +*
  48085. +* INPUT:
  48086. +* winNum - TSU to target address decode window number.
  48087. +* pAddrDecWin - TSU target window data structure.
  48088. +*
  48089. +* OUTPUT:
  48090. +* None.
  48091. +*
  48092. +* RETURN:
  48093. +* MV_ERROR - if address window overlapps with other address decode
  48094. +* windows.
  48095. +* MV_BAD_PARAM - if base address is invalid parameter or target is
  48096. +* unknown.
  48097. +*
  48098. +*******************************************************************************/
  48099. +MV_STATUS mvTsuWinSet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin)
  48100. +{
  48101. + MV_TARGET_ATTRIB targetAttribs;
  48102. + MV_DEC_REGS decRegs;
  48103. +
  48104. + /* Parameter checking */
  48105. + if(winNum >= TSU_MAX_DECODE_WIN)
  48106. + {
  48107. + mvOsPrintf("mvTsuWinSet: ERR. Invalid win num %d\n",winNum);
  48108. + return MV_BAD_PARAM;
  48109. + }
  48110. +
  48111. + /* Check if the requested window overlapps with current windows */
  48112. + if(MV_TRUE == tsuWinOverlapDetect(winNum, &pAddrDecWin->addrWin))
  48113. + {
  48114. + mvOsPrintf("mvTsuWinSet: ERR. Window %d overlap\n", winNum);
  48115. + return MV_ERROR;
  48116. + }
  48117. +
  48118. + /* check if address is aligned to the size */
  48119. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow,pAddrDecWin->addrWin.size))
  48120. + {
  48121. + mvOsPrintf("mvTsuWinSet: Error setting TSU window %d to target "
  48122. + "%s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  48123. + winNum, mvCtrlTargetNameGet(pAddrDecWin->target),
  48124. + pAddrDecWin->addrWin.baseLow,
  48125. + pAddrDecWin->addrWin.size);
  48126. + return MV_ERROR;
  48127. + }
  48128. +
  48129. + decRegs.baseReg = MV_REG_READ(MV_TSU_WIN_BASE_REG(winNum));
  48130. + decRegs.sizeReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum));
  48131. +
  48132. + if(MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  48133. + {
  48134. + mvOsPrintf("mvTsuWinSet: mvCtrlAddrDecToReg Failed\n");
  48135. + return MV_ERROR;
  48136. + }
  48137. +
  48138. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  48139. +
  48140. + /* set attributes */
  48141. + decRegs.sizeReg &= ~TSU_WIN_CTRL_ATTR_MASK;
  48142. + decRegs.sizeReg |= targetAttribs.attrib << TSU_WIN_CTRL_ATTR_OFFS;
  48143. + /* set target ID */
  48144. + decRegs.sizeReg &= ~TSU_WIN_CTRL_TARGET_MASK;
  48145. + decRegs.sizeReg |= targetAttribs.targetId << TSU_WIN_CTRL_TARGET_OFFS;
  48146. +
  48147. + /* for the safe side we disable the window before writing the new */
  48148. + /* values */
  48149. + mvTsuWinEnable(winNum, MV_FALSE);
  48150. + MV_REG_WRITE(MV_TSU_WIN_CTRL_REG(winNum),decRegs.sizeReg);
  48151. +
  48152. + /* Write to address decode Size Register */
  48153. + MV_REG_WRITE(MV_TSU_WIN_BASE_REG(winNum), decRegs.baseReg);
  48154. +
  48155. + /* Enable address decode target window */
  48156. + if(pAddrDecWin->enable == MV_TRUE)
  48157. + {
  48158. + mvTsuWinEnable(winNum,MV_TRUE);
  48159. + }
  48160. +
  48161. + return MV_OK;
  48162. +}
  48163. +
  48164. +
  48165. +/*******************************************************************************
  48166. +* mvTsuWinGet
  48167. +*
  48168. +* DESCRIPTION:
  48169. +* Get TSU peripheral target address window.
  48170. +*
  48171. +* INPUT:
  48172. +* winNum - TSU to target address decode window number.
  48173. +*
  48174. +* OUTPUT:
  48175. +* pAddrDecWin - TSU target window data structure.
  48176. +*
  48177. +* RETURN:
  48178. +* MV_ERROR if register parameters are invalid.
  48179. +*
  48180. +*******************************************************************************/
  48181. +MV_STATUS mvTsuWinGet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin)
  48182. +{
  48183. + MV_DEC_REGS decRegs;
  48184. + MV_TARGET_ATTRIB targetAttrib;
  48185. +
  48186. + /* Parameter checking */
  48187. + if(winNum >= TSU_MAX_DECODE_WIN)
  48188. + {
  48189. + mvOsPrintf("mvTsuWinGet: ERR. Invalid winNum %d\n", winNum);
  48190. + return MV_NOT_SUPPORTED;
  48191. + }
  48192. +
  48193. + decRegs.baseReg = MV_REG_READ(MV_TSU_WIN_BASE_REG(winNum));
  48194. + decRegs.sizeReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum));
  48195. +
  48196. + if(MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  48197. + {
  48198. + mvOsPrintf("mvTsuWinGet: mvCtrlRegToAddrDec Failed \n");
  48199. + return MV_ERROR;
  48200. + }
  48201. +
  48202. + /* attrib and targetId */
  48203. + targetAttrib.attrib =
  48204. + (decRegs.sizeReg & TSU_WIN_CTRL_ATTR_MASK) >> TSU_WIN_CTRL_ATTR_OFFS;
  48205. + targetAttrib.targetId =
  48206. + (decRegs.sizeReg & TSU_WIN_CTRL_TARGET_MASK) >> TSU_WIN_CTRL_TARGET_OFFS;
  48207. +
  48208. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  48209. +
  48210. + /* Check if window is enabled */
  48211. + if((MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum)) & TSU_WIN_CTRL_EN_MASK))
  48212. + {
  48213. + pAddrDecWin->enable = MV_TRUE;
  48214. + }
  48215. + else
  48216. + {
  48217. + pAddrDecWin->enable = MV_FALSE;
  48218. + }
  48219. +
  48220. + return MV_OK;
  48221. +}
  48222. +
  48223. +
  48224. +/*******************************************************************************
  48225. +* mvTsuWinEnable
  48226. +*
  48227. +* DESCRIPTION:
  48228. +* This function enable/disable a TSU to target address window.
  48229. +* According to parameter 'enable' the routine will enable the
  48230. +* window, thus enabling TSU accesses (before enabling the window it is
  48231. +* tested for overlapping). Otherwise, the window will be disabled.
  48232. +*
  48233. +* INPUT:
  48234. +* winNum - TSU to target address decode window number.
  48235. +* enable - Enable / disable parameter.
  48236. +*
  48237. +* OUTPUT:
  48238. +* N/A
  48239. +*
  48240. +* RETURN:
  48241. +* MV_ERROR if decode window number was wrong or enabled window overlapps.
  48242. +*
  48243. +*******************************************************************************/
  48244. +MV_STATUS mvTsuWinEnable(MV_U32 winNum,MV_BOOL enable)
  48245. +{
  48246. + MV_TSU_DEC_WIN addrDecWin;
  48247. +
  48248. + /* Parameter checking */
  48249. + if(winNum >= TSU_MAX_DECODE_WIN)
  48250. + {
  48251. + mvOsPrintf("mvTsuWinEnable: ERR. Invalid winNum%d\n",winNum);
  48252. + return MV_ERROR;
  48253. + }
  48254. +
  48255. + if(enable == MV_TRUE)
  48256. + {
  48257. + /* First check for overlap with other enabled windows */
  48258. + /* Get current window. */
  48259. + if(MV_OK != mvTsuWinGet(winNum,&addrDecWin))
  48260. + {
  48261. + mvOsPrintf("mvTsuWinEnable: ERR. targetWinGet fail\n");
  48262. + return MV_ERROR;
  48263. + }
  48264. + /* Check for overlapping. */
  48265. + if(MV_FALSE == tsuWinOverlapDetect(winNum,&(addrDecWin.addrWin)))
  48266. + {
  48267. + /* No Overlap. Enable address decode target window */
  48268. + MV_REG_BIT_SET(MV_TSU_WIN_CTRL_REG(winNum),
  48269. + TSU_WIN_CTRL_EN_MASK);
  48270. + }
  48271. + else
  48272. + {
  48273. + /* Overlap detected */
  48274. + mvOsPrintf("mvTsuWinEnable: ERR. Overlap detected\n");
  48275. + return MV_ERROR;
  48276. + }
  48277. + }
  48278. + else
  48279. + {
  48280. + /* Disable address decode target window */
  48281. + MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum),
  48282. + TSU_WIN_CTRL_EN_MASK);
  48283. + }
  48284. + return MV_OK;
  48285. +}
  48286. +
  48287. +/*******************************************************************************
  48288. +* mvTsuWinTargetGet
  48289. +*
  48290. +* DESCRIPTION:
  48291. +* Get Window number associated with target
  48292. +*
  48293. +* INPUT:
  48294. +* target - Target ID to get the window number for.
  48295. +* OUTPUT:
  48296. +*
  48297. +* RETURN:
  48298. +* window number or 0xFFFFFFFF on error.
  48299. +*
  48300. +*******************************************************************************/
  48301. +MV_U32 mvTsuWinTargetGet(MV_TARGET target)
  48302. +{
  48303. + MV_TSU_DEC_WIN decWin;
  48304. + MV_U32 winNum;
  48305. +
  48306. + /* Check parameters */
  48307. + if(target >= MAX_TARGETS)
  48308. + {
  48309. + mvOsPrintf("mvTsuWinTargetGet: target %d is Illigal\n", target);
  48310. + return 0xffffffff;
  48311. + }
  48312. +
  48313. + for(winNum = 0; winNum < TSU_MAX_DECODE_WIN; winNum++)
  48314. + {
  48315. + if(mvTsuWinGet(winNum,&decWin) != MV_OK)
  48316. + {
  48317. + mvOsPrintf("mvTsuWinGet: window returned error\n");
  48318. + return 0xffffffff;
  48319. + }
  48320. +
  48321. + if (decWin.enable == MV_TRUE)
  48322. + {
  48323. + if(decWin.target == target)
  48324. + {
  48325. + return winNum;
  48326. + }
  48327. + }
  48328. + }
  48329. + return 0xFFFFFFFF;
  48330. +}
  48331. +
  48332. +
  48333. +/*******************************************************************************
  48334. +* tsuWinOverlapDetect
  48335. +*
  48336. +* DESCRIPTION:
  48337. +* Detect TSU address windows overlapping
  48338. +* An unpredicted behaviur is expected in case TSU address decode
  48339. +* windows overlapps.
  48340. +* This function detects TSU address decode windows overlapping of a
  48341. +* specified window. The function does not check the window itself for
  48342. +* overlapping. The function also skipps disabled address decode windows.
  48343. +*
  48344. +* INPUT:
  48345. +* winNum - address decode window number.
  48346. +* pAddrDecWin - An address decode window struct.
  48347. +*
  48348. +* OUTPUT:
  48349. +* None.
  48350. +*
  48351. +* RETURN:
  48352. +* MV_TRUE if the given address window overlap current address
  48353. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  48354. +* from registers.
  48355. +*
  48356. +*******************************************************************************/
  48357. +static MV_STATUS tsuWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  48358. +{
  48359. + MV_U32 ctrlReg;
  48360. + MV_U32 winNumIndex;
  48361. + MV_TSU_DEC_WIN addrDecWin;
  48362. +
  48363. + for(winNumIndex = 0; winNumIndex < TSU_MAX_DECODE_WIN; winNumIndex++)
  48364. + {
  48365. + /* Do not check window itself */
  48366. + if(winNumIndex == winNum)
  48367. + {
  48368. + continue;
  48369. + }
  48370. +
  48371. + /* Do not check disabled windows */
  48372. + ctrlReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNumIndex));
  48373. + if((ctrlReg & TSU_WIN_CTRL_EN_MASK) == 0)
  48374. + {
  48375. + continue;
  48376. + }
  48377. +
  48378. + /* Get window parameters */
  48379. + if (MV_OK != mvTsuWinGet(winNumIndex, &addrDecWin))
  48380. + {
  48381. + mvOsPrintf("tsuWinOverlapDetect: ERR. mvTsuWinGet failed\n");
  48382. + return MV_ERROR;
  48383. + }
  48384. +
  48385. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  48386. + {
  48387. + return MV_TRUE;
  48388. + }
  48389. + }
  48390. + return MV_FALSE;
  48391. +}
  48392. +
  48393. +
  48394. +/*******************************************************************************
  48395. +* mvTsuAddrDecShow
  48396. +*
  48397. +* DESCRIPTION:
  48398. +* Print the TSU address decode map.
  48399. +*
  48400. +* INPUT:
  48401. +* None.
  48402. +*
  48403. +* OUTPUT:
  48404. +* None.
  48405. +*
  48406. +* RETURN:
  48407. +* None.
  48408. +*
  48409. +*******************************************************************************/
  48410. +void mvTsuAddrDecShow(void)
  48411. +{
  48412. + MV_TSU_DEC_WIN win;
  48413. + int i;
  48414. +
  48415. + if (MV_FALSE == mvCtrlPwrClckGet(TS_UNIT_ID, 0))
  48416. + return;
  48417. +
  48418. + mvOsOutput( "\n" );
  48419. + mvOsOutput( "TSU:\n");
  48420. + mvOsOutput( "----\n" );
  48421. +
  48422. + for(i = 0; i < TSU_MAX_DECODE_WIN; i++)
  48423. + {
  48424. + memset(&win, 0, sizeof(TSU_MAX_DECODE_WIN));
  48425. + mvOsOutput( "win%d - ", i );
  48426. +
  48427. + if(mvTsuWinGet(i, &win ) == MV_OK )
  48428. + {
  48429. + if(win.enable == MV_TRUE)
  48430. + {
  48431. + mvOsOutput("%s base %08x, ",
  48432. + mvCtrlTargetNameGet(win.target),
  48433. + win.addrWin.baseLow);
  48434. + mvOsOutput( "...." );
  48435. + mvSizePrint(win.addrWin.size );
  48436. + mvOsOutput( "\n" );
  48437. + }
  48438. + else
  48439. + {
  48440. + mvOsOutput( "disable\n" );
  48441. + }
  48442. + }
  48443. + }
  48444. + return;
  48445. +}
  48446. +
  48447. +
  48448. +/*******************************************************************************
  48449. +* mvTsuInit
  48450. +*
  48451. +* DESCRIPTION:
  48452. +* Initialize the TSU unit, and get unit out of reset.
  48453. +*
  48454. +* INPUT:
  48455. +* coreClock - The core clock at which the TSU should operate.
  48456. +* mode - The mode on configure the unit into (serial/parallel).
  48457. +* memHandle - Memory handle used for memory allocations.
  48458. +* OUTPUT:
  48459. +* None.
  48460. +* RETURN:
  48461. +* MV_OK - on success,
  48462. +*
  48463. +*******************************************************************************/
  48464. +MV_STATUS mvTsuInit(MV_TSU_CORE_CLOCK coreClock, MV_TSU_PORTS_MODE mode,
  48465. + void *osHandle)
  48466. +{
  48467. + MV_STATUS status;
  48468. +
  48469. + status = mvTsuWinInit();
  48470. + if(status == MV_OK)
  48471. + status = mvTsuHalInit(coreClock,mode,osHandle);
  48472. +
  48473. + return status;
  48474. +}
  48475. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h
  48476. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h 1970-01-01 01:00:00.000000000 +0100
  48477. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h 2010-08-05 22:02:23.044868529 +0200
  48478. @@ -0,0 +1,110 @@
  48479. +/*******************************************************************************
  48480. +Copyright (C) Marvell International Ltd. and its affiliates
  48481. +
  48482. +This software file (the "File") is owned and distributed by Marvell
  48483. +International Ltd. and/or its affiliates ("Marvell") under the following
  48484. +alternative licensing terms. Once you have made an election to distribute the
  48485. +File under one of the following license alternatives, please (i) delete this
  48486. +introductory statement regarding license alternatives, (ii) delete the two
  48487. +license alternatives that you have not elected to use and (iii) preserve the
  48488. +Marvell copyright notice above.
  48489. +
  48490. +********************************************************************************
  48491. +Marvell Commercial License Option
  48492. +
  48493. +If you received this File from Marvell and you have entered into a commercial
  48494. +license agreement (a "Commercial License") with Marvell, the File is licensed
  48495. +to you under the terms of the applicable Commercial License.
  48496. +
  48497. +********************************************************************************
  48498. +Marvell GPL License Option
  48499. +
  48500. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48501. +modify this File in accordance with the terms and conditions of the General
  48502. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  48503. +available along with the File in the license.txt file or by writing to the Free
  48504. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  48505. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  48506. +
  48507. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  48508. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  48509. +DISCLAIMED. The GPL License provides additional details about this warranty
  48510. +disclaimer.
  48511. +********************************************************************************
  48512. +Marvell BSD License Option
  48513. +
  48514. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48515. +modify this File under the following licensing terms.
  48516. +Redistribution and use in source and binary forms, with or without modification,
  48517. +are permitted provided that the following conditions are met:
  48518. +
  48519. + * Redistributions of source code must retain the above copyright notice,
  48520. + this list of conditions and the following disclaimer.
  48521. +
  48522. + * Redistributions in binary form must reproduce the above copyright
  48523. + notice, this list of conditions and the following disclaimer in the
  48524. + documentation and/or other materials provided with the distribution.
  48525. +
  48526. + * Neither the name of Marvell nor the names of its contributors may be
  48527. + used to endorse or promote products derived from this software without
  48528. + specific prior written permission.
  48529. +
  48530. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  48531. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  48532. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  48533. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  48534. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  48535. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  48536. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  48537. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  48538. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  48539. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  48540. +
  48541. +*******************************************************************************/
  48542. +
  48543. +#ifndef __INCmvSysTsh
  48544. +#define __INCmvSysTsh
  48545. +
  48546. +#ifdef __cplusplus
  48547. +extern "C" {
  48548. +#endif /* __cplusplus */
  48549. +
  48550. +/* includes */
  48551. +#include "ts/mvTsu.h"
  48552. +#include "ctrlEnv/sys/mvCpuIf.h"
  48553. +#include "ctrlEnv/mvCtrlEnvLib.h"
  48554. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  48555. +
  48556. +#define TSU_MAX_DECODE_WIN 4
  48557. +
  48558. +
  48559. +/*******************************************/
  48560. +/* TSU Windows Registers */
  48561. +/*******************************************/
  48562. +#define MV_TSU_WIN_CTRL_REG(win) (TSU_GLOBAL_REG_BASE +0x30 + 0x10 * win)
  48563. +#define MV_TSU_WIN_BASE_REG(win) (TSU_GLOBAL_REG_BASE +0x34 + 0x10 * win)
  48564. +
  48565. +/* TSU windows control register. */
  48566. +#define TSU_WIN_CTRL_EN_MASK (0x1 << 0)
  48567. +#define TSU_WIN_CTRL_TARGET_OFFS 4
  48568. +#define TSU_WIN_CTRL_TARGET_MASK (0xF << TSU_WIN_CTRL_TARGET_OFFS)
  48569. +#define TSU_WIN_CTRL_ATTR_OFFS 8
  48570. +#define TSU_WIN_CTRL_ATTR_MASK (0xFF << TSU_WIN_CTRL_ATTR_OFFS)
  48571. +#define TSU_WIN_CTRL_SIZE_OFFS 16
  48572. +#define TSU_WIN_CTRL_SIZE_MASK (0xFFFF << TSU_WIN_CTRL_SIZE_OFFS)
  48573. +
  48574. +/* TSU windows base register. */
  48575. +#define TSU_WIN_BASE_OFFS 16
  48576. +#define TSU_WIN_BASE_MASK (0xFFFF << TSU_WIN_BASE_OFFS)
  48577. +
  48578. +MV_STATUS mvTsuWinInit(void);
  48579. +
  48580. +void mvTsuAddrDecShow(void);
  48581. +MV_STATUS mvTsuInit(MV_TSU_CORE_CLOCK coreClock, MV_TSU_PORTS_MODE mode,
  48582. + void *osHandle);
  48583. +
  48584. +#ifdef __cplusplus
  48585. +}
  48586. +#endif /* __cplusplus */
  48587. +
  48588. +#endif /* __INCmvTsh */
  48589. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c
  48590. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c 1970-01-01 01:00:00.000000000 +0100
  48591. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c 2010-08-05 22:02:23.084868030 +0200
  48592. @@ -0,0 +1,497 @@
  48593. +/*******************************************************************************
  48594. +Copyright (C) Marvell International Ltd. and its affiliates
  48595. +
  48596. +This software file (the "File") is owned and distributed by Marvell
  48597. +International Ltd. and/or its affiliates ("Marvell") under the following
  48598. +alternative licensing terms. Once you have made an election to distribute the
  48599. +File under one of the following license alternatives, please (i) delete this
  48600. +introductory statement regarding license alternatives, (ii) delete the two
  48601. +license alternatives that you have not elected to use and (iii) preserve the
  48602. +Marvell copyright notice above.
  48603. +
  48604. +********************************************************************************
  48605. +Marvell Commercial License Option
  48606. +
  48607. +If you received this File from Marvell and you have entered into a commercial
  48608. +license agreement (a "Commercial License") with Marvell, the File is licensed
  48609. +to you under the terms of the applicable Commercial License.
  48610. +
  48611. +********************************************************************************
  48612. +Marvell GPL License Option
  48613. +
  48614. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48615. +modify this File in accordance with the terms and conditions of the General
  48616. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  48617. +available along with the File in the license.txt file or by writing to the Free
  48618. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  48619. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  48620. +
  48621. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  48622. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  48623. +DISCLAIMED. The GPL License provides additional details about this warranty
  48624. +disclaimer.
  48625. +********************************************************************************
  48626. +Marvell BSD License Option
  48627. +
  48628. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48629. +modify this File under the following licensing terms.
  48630. +Redistribution and use in source and binary forms, with or without modification,
  48631. +are permitted provided that the following conditions are met:
  48632. +
  48633. + * Redistributions of source code must retain the above copyright notice,
  48634. + this list of conditions and the following disclaimer.
  48635. +
  48636. + * Redistributions in binary form must reproduce the above copyright
  48637. + notice, this list of conditions and the following disclaimer in the
  48638. + documentation and/or other materials provided with the distribution.
  48639. +
  48640. + * Neither the name of Marvell nor the names of its contributors may be
  48641. + used to endorse or promote products derived from this software without
  48642. + specific prior written permission.
  48643. +
  48644. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  48645. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  48646. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  48647. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  48648. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  48649. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  48650. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  48651. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  48652. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  48653. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  48654. +
  48655. +*******************************************************************************/
  48656. +
  48657. +#include "ctrlEnv/sys/mvSysUsb.h"
  48658. +
  48659. +MV_TARGET usbAddrDecPrioTab[] =
  48660. +{
  48661. +#if defined(MV_INCLUDE_SDRAM_CS0)
  48662. + SDRAM_CS0,
  48663. +#endif
  48664. +#if defined(MV_INCLUDE_SDRAM_CS1)
  48665. + SDRAM_CS1,
  48666. +#endif
  48667. +#if defined(MV_INCLUDE_SDRAM_CS2)
  48668. + SDRAM_CS2,
  48669. +#endif
  48670. +#if defined(MV_INCLUDE_SDRAM_CS3)
  48671. + SDRAM_CS3,
  48672. +#endif
  48673. +#if defined(MV_INCLUDE_CESA) && defined(USB_UNDERRUN_WA)
  48674. + CRYPT_ENG,
  48675. +#endif
  48676. +#if defined(MV_INCLUDE_PEX)
  48677. + PEX0_MEM,
  48678. +#endif
  48679. + TBL_TERM
  48680. +};
  48681. +
  48682. +
  48683. +
  48684. +MV_STATUS mvUsbInit(int dev, MV_BOOL isHost)
  48685. +{
  48686. + MV_STATUS status;
  48687. +
  48688. + status = mvUsbWinInit(dev);
  48689. + if(status != MV_OK)
  48690. + return status;
  48691. +
  48692. + return mvUsbHalInit(dev, isHost);
  48693. +}
  48694. +
  48695. +
  48696. +/*******************************************************************************
  48697. +* usbWinOverlapDetect - Detect USB address windows overlapping
  48698. +*
  48699. +* DESCRIPTION:
  48700. +* An unpredicted behaviur is expected in case USB address decode
  48701. +* windows overlapps.
  48702. +* This function detects USB address decode windows overlapping of a
  48703. +* specified window. The function does not check the window itself for
  48704. +* overlapping. The function also skipps disabled address decode windows.
  48705. +*
  48706. +* INPUT:
  48707. +* winNum - address decode window number.
  48708. +* pAddrDecWin - An address decode window struct.
  48709. +*
  48710. +* OUTPUT:
  48711. +* None.
  48712. +*
  48713. +* RETURN:
  48714. +* MV_TRUE if the given address window overlap current address
  48715. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  48716. +* from registers.
  48717. +*
  48718. +*******************************************************************************/
  48719. +static MV_STATUS usbWinOverlapDetect(int dev, MV_U32 winNum,
  48720. + MV_ADDR_WIN *pAddrWin)
  48721. +{
  48722. + MV_U32 winNumIndex;
  48723. + MV_DEC_WIN addrDecWin;
  48724. +
  48725. + for(winNumIndex=0; winNumIndex<MV_USB_MAX_ADDR_DECODE_WIN; winNumIndex++)
  48726. + {
  48727. + /* Do not check window itself */
  48728. + if (winNumIndex == winNum)
  48729. + {
  48730. + continue;
  48731. + }
  48732. +
  48733. + /* Get window parameters */
  48734. + if (MV_OK != mvUsbWinGet(dev, winNumIndex, &addrDecWin))
  48735. + {
  48736. + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
  48737. + return MV_ERROR;
  48738. + }
  48739. +
  48740. + /* Do not check disabled windows */
  48741. + if(addrDecWin.enable == MV_FALSE)
  48742. + {
  48743. + continue;
  48744. + }
  48745. +
  48746. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  48747. + {
  48748. + return MV_TRUE;
  48749. + }
  48750. + }
  48751. + return MV_FALSE;
  48752. +}
  48753. +
  48754. +/*******************************************************************************
  48755. +* mvUsbWinSet - Set USB target address window
  48756. +*
  48757. +* DESCRIPTION:
  48758. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  48759. +* address window, also known as address decode window.
  48760. +* After setting this target window, the USB will be able to access the
  48761. +* target within the address window.
  48762. +*
  48763. +* INPUT:
  48764. +* winNum - USB target address decode window number.
  48765. +* pAddrDecWin - USB target window data structure.
  48766. +*
  48767. +* OUTPUT:
  48768. +* None.
  48769. +*
  48770. +* RETURN:
  48771. +* MV_ERROR if address window overlapps with other address decode windows.
  48772. +* MV_BAD_PARAM if base address is invalid parameter or target is
  48773. +* unknown.
  48774. +*
  48775. +*******************************************************************************/
  48776. +MV_STATUS mvUsbWinSet(int dev, MV_U32 winNum, MV_DEC_WIN *pDecWin)
  48777. +{
  48778. + MV_DEC_WIN_PARAMS winParams;
  48779. + MV_U32 sizeReg, baseReg;
  48780. +
  48781. + /* Parameter checking */
  48782. + if (winNum >= MV_USB_MAX_ADDR_DECODE_WIN)
  48783. + {
  48784. + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
  48785. + return MV_BAD_PARAM;
  48786. + }
  48787. +
  48788. + /* Check if the requested window overlapps with current windows */
  48789. + if (MV_TRUE == usbWinOverlapDetect(dev, winNum, &pDecWin->addrWin))
  48790. + {
  48791. + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
  48792. + return MV_ERROR;
  48793. + }
  48794. +
  48795. + /* check if address is aligned to the size */
  48796. + if(MV_IS_NOT_ALIGN(pDecWin->addrWin.baseLow, pDecWin->addrWin.size))
  48797. + {
  48798. + mvOsPrintf("mvUsbWinSet:Error setting USB window %d to "\
  48799. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  48800. + winNum,
  48801. + mvCtrlTargetNameGet(pDecWin->target),
  48802. + pDecWin->addrWin.baseLow,
  48803. + pDecWin->addrWin.size);
  48804. + return MV_ERROR;
  48805. + }
  48806. +
  48807. + if(MV_OK != mvCtrlAddrDecToParams(pDecWin, &winParams))
  48808. + {
  48809. + mvOsPrintf("%s: mvCtrlAddrDecToParams Failed\n", __FUNCTION__);
  48810. + return MV_ERROR;
  48811. + }
  48812. +
  48813. + /* set Size, Attributes and TargetID */
  48814. + sizeReg = (((winParams.targetId << MV_USB_WIN_TARGET_OFFSET) & MV_USB_WIN_TARGET_MASK) |
  48815. + ((winParams.attrib << MV_USB_WIN_ATTR_OFFSET) & MV_USB_WIN_ATTR_MASK) |
  48816. + ((winParams.size << MV_USB_WIN_SIZE_OFFSET) & MV_USB_WIN_SIZE_MASK));
  48817. +
  48818. +#if defined(MV645xx) || defined(MV646xx)
  48819. + /* If window is DRAM with HW cache coherency, make sure bit2 is set */
  48820. + sizeReg &= ~MV_USB_WIN_BURST_WR_LIMIT_MASK;
  48821. +
  48822. + if((MV_TARGET_IS_DRAM(pDecWin->target)) &&
  48823. + (pDecWin->addrWinAttr.cachePolicy != NO_COHERENCY))
  48824. + {
  48825. + sizeReg |= MV_USB_WIN_BURST_WR_32BIT_LIMIT;
  48826. + }
  48827. + else
  48828. + {
  48829. + sizeReg |= MV_USB_WIN_BURST_WR_NO_LIMIT;
  48830. + }
  48831. +#endif /* MV645xx || MV646xx */
  48832. +
  48833. + if (pDecWin->enable == MV_TRUE)
  48834. + {
  48835. + sizeReg |= MV_USB_WIN_ENABLE_MASK;
  48836. + }
  48837. + else
  48838. + {
  48839. + sizeReg &= ~MV_USB_WIN_ENABLE_MASK;
  48840. + }
  48841. +
  48842. + /* Update Base value */
  48843. + baseReg = (winParams.baseAddr & MV_USB_WIN_BASE_MASK);
  48844. +
  48845. + MV_REG_WRITE( MV_USB_WIN_CTRL_REG(dev, winNum), sizeReg);
  48846. + MV_REG_WRITE( MV_USB_WIN_BASE_REG(dev, winNum), baseReg);
  48847. +
  48848. + return MV_OK;
  48849. +}
  48850. +
  48851. +/*******************************************************************************
  48852. +* mvUsbWinGet - Get USB peripheral target address window.
  48853. +*
  48854. +* DESCRIPTION:
  48855. +* Get USB peripheral target address window.
  48856. +*
  48857. +* INPUT:
  48858. +* winNum - USB target address decode window number.
  48859. +*
  48860. +* OUTPUT:
  48861. +* pDecWin - USB target window data structure.
  48862. +*
  48863. +* RETURN:
  48864. +* MV_ERROR if register parameters are invalid.
  48865. +*
  48866. +*******************************************************************************/
  48867. +MV_STATUS mvUsbWinGet(int dev, MV_U32 winNum, MV_DEC_WIN *pDecWin)
  48868. +{
  48869. + MV_DEC_WIN_PARAMS winParam;
  48870. + MV_U32 sizeReg, baseReg;
  48871. +
  48872. + /* Parameter checking */
  48873. + if (winNum >= MV_USB_MAX_ADDR_DECODE_WIN)
  48874. + {
  48875. + mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",
  48876. + __FUNCTION__, dev, winNum);
  48877. + return MV_NOT_SUPPORTED;
  48878. + }
  48879. +
  48880. + baseReg = MV_REG_READ( MV_USB_WIN_BASE_REG(dev, winNum) );
  48881. + sizeReg = MV_REG_READ( MV_USB_WIN_CTRL_REG(dev, winNum) );
  48882. +
  48883. + /* Check if window is enabled */
  48884. + if(sizeReg & MV_USB_WIN_ENABLE_MASK)
  48885. + {
  48886. + pDecWin->enable = MV_TRUE;
  48887. +
  48888. + /* Extract window parameters from registers */
  48889. + winParam.targetId = (sizeReg & MV_USB_WIN_TARGET_MASK) >> MV_USB_WIN_TARGET_OFFSET;
  48890. + winParam.attrib = (sizeReg & MV_USB_WIN_ATTR_MASK) >> MV_USB_WIN_ATTR_OFFSET;
  48891. + winParam.size = (sizeReg & MV_USB_WIN_SIZE_MASK) >> MV_USB_WIN_SIZE_OFFSET;
  48892. + winParam.baseAddr = (baseReg & MV_USB_WIN_BASE_MASK);
  48893. +
  48894. + /* Translate the decode window parameters to address decode struct */
  48895. + if (MV_OK != mvCtrlParamsToAddrDec(&winParam, pDecWin))
  48896. + {
  48897. + mvOsPrintf("Failed to translate register parameters to USB address" \
  48898. + " decode window structure\n");
  48899. + return MV_ERROR;
  48900. + }
  48901. + }
  48902. + else
  48903. + {
  48904. + pDecWin->enable = MV_FALSE;
  48905. + }
  48906. + return MV_OK;
  48907. +}
  48908. +
  48909. +/*******************************************************************************
  48910. +* mvUsbWinInit -
  48911. +*
  48912. +* INPUT:
  48913. +*
  48914. +* OUTPUT:
  48915. +*
  48916. +* RETURN:
  48917. +* MV_ERROR if register parameters are invalid.
  48918. +*
  48919. +*******************************************************************************/
  48920. +MV_STATUS mvUsbWinInit(int dev)
  48921. +{
  48922. + MV_STATUS status;
  48923. + MV_DEC_WIN usbWin;
  48924. + MV_CPU_DEC_WIN cpuAddrDecWin;
  48925. + int winNum;
  48926. + MV_U32 winPrioIndex = 0;
  48927. +
  48928. + /* First disable all address decode windows */
  48929. + for(winNum = 0; winNum < MV_USB_MAX_ADDR_DECODE_WIN; winNum++)
  48930. + {
  48931. + MV_REG_BIT_RESET(MV_USB_WIN_CTRL_REG(dev, winNum), MV_USB_WIN_ENABLE_MASK);
  48932. + }
  48933. +
  48934. + /* Go through all windows in user table until table terminator */
  48935. + winNum = 0;
  48936. + while( (usbAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
  48937. + (winNum < MV_USB_MAX_ADDR_DECODE_WIN) )
  48938. + {
  48939. + /* first get attributes from CPU If */
  48940. + status = mvCpuIfTargetWinGet(usbAddrDecPrioTab[winPrioIndex],
  48941. + &cpuAddrDecWin);
  48942. +
  48943. + if(MV_NO_SUCH == status)
  48944. + {
  48945. + winPrioIndex++;
  48946. + continue;
  48947. + }
  48948. + if (MV_OK != status)
  48949. + {
  48950. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  48951. + return MV_ERROR;
  48952. + }
  48953. +
  48954. + if (cpuAddrDecWin.enable == MV_TRUE)
  48955. + {
  48956. + usbWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  48957. + usbWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  48958. + usbWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  48959. + usbWin.enable = MV_TRUE;
  48960. + usbWin.target = usbAddrDecPrioTab[winPrioIndex];
  48961. +
  48962. +#if defined(MV645xx) || defined(MV646xx)
  48963. + /* Get the default attributes for that target window */
  48964. + mvCtrlDefAttribGet(usbWin.target, &usbWin.addrWinAttr);
  48965. +#endif /* MV645xx || MV646xx */
  48966. +
  48967. + if(MV_OK != mvUsbWinSet(dev, winNum, &usbWin))
  48968. + {
  48969. + return MV_ERROR;
  48970. + }
  48971. + winNum++;
  48972. + }
  48973. + winPrioIndex++;
  48974. + }
  48975. + return MV_OK;
  48976. +}
  48977. +
  48978. +/*******************************************************************************
  48979. +* mvUsbAddrDecShow - Print the USB address decode map.
  48980. +*
  48981. +* DESCRIPTION:
  48982. +* This function print the USB address decode map.
  48983. +*
  48984. +* INPUT:
  48985. +* None.
  48986. +*
  48987. +* OUTPUT:
  48988. +* None.
  48989. +*
  48990. +* RETURN:
  48991. +* None.
  48992. +*
  48993. +*******************************************************************************/
  48994. +MV_VOID mvUsbAddrDecShow(MV_VOID)
  48995. +{
  48996. + MV_DEC_WIN addrDecWin;
  48997. + int i, winNum;
  48998. +
  48999. + mvOsOutput( "\n" );
  49000. + mvOsOutput( "USB:\n" );
  49001. + mvOsOutput( "----\n" );
  49002. +
  49003. + for(i=0; i<mvCtrlUsbMaxGet(); i++)
  49004. + {
  49005. + mvOsOutput( "Device %d:\n", i);
  49006. +
  49007. + for(winNum = 0; winNum < MV_USB_MAX_ADDR_DECODE_WIN; winNum++)
  49008. + {
  49009. + memset(&addrDecWin, 0, sizeof(MV_DEC_WIN) );
  49010. +
  49011. + mvOsOutput( "win%d - ", winNum );
  49012. +
  49013. + if( mvUsbWinGet(i, winNum, &addrDecWin ) == MV_OK )
  49014. + {
  49015. + if( addrDecWin.enable )
  49016. + {
  49017. + mvOsOutput( "%s base %08x, ",
  49018. + mvCtrlTargetNameGet(addrDecWin.target), addrDecWin.addrWin.baseLow );
  49019. +
  49020. + mvSizePrint( addrDecWin.addrWin.size );
  49021. +
  49022. +#if defined(MV645xx) || defined(MV646xx)
  49023. + switch( addrDecWin.addrWinAttr.swapType)
  49024. + {
  49025. + case MV_BYTE_SWAP:
  49026. + mvOsOutput( "BYTE_SWAP, " );
  49027. + break;
  49028. + case MV_NO_SWAP:
  49029. + mvOsOutput( "NO_SWAP , " );
  49030. + break;
  49031. + case MV_BYTE_WORD_SWAP:
  49032. + mvOsOutput( "BYTE_WORD_SWAP, " );
  49033. + break;
  49034. + case MV_WORD_SWAP:
  49035. + mvOsOutput( "WORD_SWAP, " );
  49036. + break;
  49037. + default:
  49038. + mvOsOutput( "SWAP N/A , " );
  49039. + }
  49040. +
  49041. + switch( addrDecWin.addrWinAttr.cachePolicy )
  49042. + {
  49043. + case NO_COHERENCY:
  49044. + mvOsOutput( "NO_COHERENCY , " );
  49045. + break;
  49046. + case WT_COHERENCY:
  49047. + mvOsOutput( "WT_COHERENCY , " );
  49048. + break;
  49049. + case WB_COHERENCY:
  49050. + mvOsOutput( "WB_COHERENCY , " );
  49051. + break;
  49052. + default:
  49053. + mvOsOutput( "COHERENCY N/A, " );
  49054. + }
  49055. +
  49056. + switch( addrDecWin.addrWinAttr.pcixNoSnoop )
  49057. + {
  49058. + case 0:
  49059. + mvOsOutput( "PCI-X NS inactive, " );
  49060. + break;
  49061. + case 1:
  49062. + mvOsOutput( "PCI-X NS active , " );
  49063. + break;
  49064. + default:
  49065. + mvOsOutput( "PCI-X NS N/A , " );
  49066. + }
  49067. +
  49068. + switch( addrDecWin.addrWinAttr.p2pReq64 )
  49069. + {
  49070. + case 0:
  49071. + mvOsOutput( "REQ64 force" );
  49072. + break;
  49073. + case 1:
  49074. + mvOsOutput( "REQ64 detect" );
  49075. + break;
  49076. + default:
  49077. + mvOsOutput( "REQ64 N/A" );
  49078. + }
  49079. +#endif /* MV645xx || MV646xx */
  49080. + mvOsOutput( "\n" );
  49081. + }
  49082. + else
  49083. + mvOsOutput( "disable\n" );
  49084. + }
  49085. + }
  49086. + }
  49087. +}
  49088. +
  49089. +
  49090. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h
  49091. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h 1970-01-01 01:00:00.000000000 +0100
  49092. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h 2010-08-05 22:02:23.124868235 +0200
  49093. @@ -0,0 +1,125 @@
  49094. +/*******************************************************************************
  49095. +Copyright (C) Marvell International Ltd. and its affiliates
  49096. +
  49097. +This software file (the "File") is owned and distributed by Marvell
  49098. +International Ltd. and/or its affiliates ("Marvell") under the following
  49099. +alternative licensing terms. Once you have made an election to distribute the
  49100. +File under one of the following license alternatives, please (i) delete this
  49101. +introductory statement regarding license alternatives, (ii) delete the two
  49102. +license alternatives that you have not elected to use and (iii) preserve the
  49103. +Marvell copyright notice above.
  49104. +
  49105. +********************************************************************************
  49106. +Marvell Commercial License Option
  49107. +
  49108. +If you received this File from Marvell and you have entered into a commercial
  49109. +license agreement (a "Commercial License") with Marvell, the File is licensed
  49110. +to you under the terms of the applicable Commercial License.
  49111. +
  49112. +********************************************************************************
  49113. +Marvell GPL License Option
  49114. +
  49115. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49116. +modify this File in accordance with the terms and conditions of the General
  49117. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  49118. +available along with the File in the license.txt file or by writing to the Free
  49119. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  49120. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  49121. +
  49122. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  49123. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  49124. +DISCLAIMED. The GPL License provides additional details about this warranty
  49125. +disclaimer.
  49126. +********************************************************************************
  49127. +Marvell BSD License Option
  49128. +
  49129. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49130. +modify this File under the following licensing terms.
  49131. +Redistribution and use in source and binary forms, with or without modification,
  49132. +are permitted provided that the following conditions are met:
  49133. +
  49134. + * Redistributions of source code must retain the above copyright notice,
  49135. + this list of conditions and the following disclaimer.
  49136. +
  49137. + * Redistributions in binary form must reproduce the above copyright
  49138. + notice, this list of conditions and the following disclaimer in the
  49139. + documentation and/or other materials provided with the distribution.
  49140. +
  49141. + * Neither the name of Marvell nor the names of its contributors may be
  49142. + used to endorse or promote products derived from this software without
  49143. + specific prior written permission.
  49144. +
  49145. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  49146. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  49147. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  49148. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  49149. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  49150. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  49151. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  49152. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  49153. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  49154. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  49155. +
  49156. +*******************************************************************************/
  49157. +
  49158. +#ifndef __INCmvSysUsbh
  49159. +#define __INCmvSysUsbh
  49160. +
  49161. +#ifdef __cplusplus
  49162. +extern "C" {
  49163. +#endif /* __cplusplus */
  49164. +
  49165. +/* includes */
  49166. +#include "usb/mvUsb.h"
  49167. +#include "ctrlEnv/sys/mvCpuIf.h"
  49168. +#include "ctrlEnv/mvCtrlEnvLib.h"
  49169. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  49170. +
  49171. +#define MV_USB_MAX_ADDR_DECODE_WIN 4
  49172. +
  49173. +/*******************************************/
  49174. +/* USB Bridge Registers */
  49175. +/*******************************************/
  49176. +#define MV_USB_BRIDGE_CTRL_REG(dev) (USB_REG_BASE(dev) + 0x300)
  49177. +
  49178. +#define MV_USB_WIN_CTRL_REG(dev, win) (USB_REG_BASE(dev) + 0x320 + ((win)<<4))
  49179. +#define MV_USB_WIN_BASE_REG(dev, win) (USB_REG_BASE(dev) + 0x324 + ((win)<<4))
  49180. +
  49181. +/* BITs in Windows 0-3 Control and Base Registers */
  49182. +#define MV_USB_WIN_ENABLE_BIT 0
  49183. +#define MV_USB_WIN_ENABLE_MASK (1 << MV_USB_WIN_ENABLE_BIT)
  49184. +
  49185. +#define MV_USB_WIN_BURST_WR_LIMIT_BIT 1
  49186. +#define MV_USB_WIN_BURST_WR_LIMIT_MASK (1 << MV_USB_WIN_BURST_WR_LIMIT_BIT)
  49187. +#define MV_USB_WIN_BURST_WR_NO_LIMIT (0 << MV_USB_WIN_BURST_WR_LIMIT_BIT)
  49188. +#define MV_USB_WIN_BURST_WR_32BIT_LIMIT (1 << MV_USB_WIN_BURST_WR_LIMIT_BIT)
  49189. +
  49190. +#define MV_USB_WIN_TARGET_OFFSET 4
  49191. +#define MV_USB_WIN_TARGET_MASK (0xF << MV_USB_WIN_TARGET_OFFSET)
  49192. +
  49193. +#define MV_USB_WIN_ATTR_OFFSET 8
  49194. +#define MV_USB_WIN_ATTR_MASK (0xFF << MV_USB_WIN_ATTR_OFFSET)
  49195. +
  49196. +#define MV_USB_WIN_SIZE_OFFSET 16
  49197. +#define MV_USB_WIN_SIZE_MASK (0xFFFF << MV_USB_WIN_SIZE_OFFSET)
  49198. +
  49199. +#define MV_USB_WIN_BASE_OFFSET 16
  49200. +#define MV_USB_WIN_BASE_MASK (0xFFFF << MV_USB_WIN_BASE_OFFSET)
  49201. +
  49202. +
  49203. +#define MV_USB_BRIDGE_IPG_REG(dev) (USB_REG_BASE(dev) + 0x360)
  49204. +
  49205. +
  49206. +MV_STATUS mvUsbInit(int dev, MV_BOOL isHost);
  49207. +
  49208. +MV_STATUS mvUsbWinInit(int dev);
  49209. +MV_STATUS mvUsbWinSet(int dev, MV_U32 winNum, MV_DEC_WIN *pAddrWin);
  49210. +MV_STATUS mvUsbWinGet(int dev, MV_U32 winNum, MV_DEC_WIN *pAddrWin);
  49211. +
  49212. +void mvUsbAddrDecShow(void);
  49213. +
  49214. +#ifdef __cplusplus
  49215. +}
  49216. +#endif /* __cplusplus */
  49217. +
  49218. +#endif /* __INCmvUsbh */
  49219. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c
  49220. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c 1970-01-01 01:00:00.000000000 +0100
  49221. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c 2010-08-05 22:02:23.164868323 +0200
  49222. @@ -0,0 +1,662 @@
  49223. +/*******************************************************************************
  49224. +Copyright (C) Marvell International Ltd. and its affiliates
  49225. +
  49226. +This software file (the "File") is owned and distributed by Marvell
  49227. +International Ltd. and/or its affiliates ("Marvell") under the following
  49228. +alternative licensing terms. Once you have made an election to distribute the
  49229. +File under one of the following license alternatives, please (i) delete this
  49230. +introductory statement regarding license alternatives, (ii) delete the two
  49231. +license alternatives that you have not elected to use and (iii) preserve the
  49232. +Marvell copyright notice above.
  49233. +
  49234. +********************************************************************************
  49235. +Marvell Commercial License Option
  49236. +
  49237. +If you received this File from Marvell and you have entered into a commercial
  49238. +license agreement (a "Commercial License") with Marvell, the File is licensed
  49239. +to you under the terms of the applicable Commercial License.
  49240. +
  49241. +********************************************************************************
  49242. +Marvell GPL License Option
  49243. +
  49244. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49245. +modify this File in accordance with the terms and conditions of the General
  49246. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  49247. +available along with the File in the license.txt file or by writing to the Free
  49248. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  49249. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  49250. +
  49251. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  49252. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  49253. +DISCLAIMED. The GPL License provides additional details about this warranty
  49254. +disclaimer.
  49255. +********************************************************************************
  49256. +Marvell BSD License Option
  49257. +
  49258. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49259. +modify this File under the following licensing terms.
  49260. +Redistribution and use in source and binary forms, with or without modification,
  49261. +are permitted provided that the following conditions are met:
  49262. +
  49263. + * Redistributions of source code must retain the above copyright notice,
  49264. + this list of conditions and the following disclaimer.
  49265. +
  49266. + * Redistributions in binary form must reproduce the above copyright
  49267. + notice, this list of conditions and the following disclaimer in the
  49268. + documentation and/or other materials provided with the distribution.
  49269. +
  49270. + * Neither the name of Marvell nor the names of its contributors may be
  49271. + used to endorse or promote products derived from this software without
  49272. + specific prior written permission.
  49273. +
  49274. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  49275. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  49276. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  49277. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  49278. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  49279. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  49280. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  49281. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  49282. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  49283. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  49284. +
  49285. +*******************************************************************************/
  49286. +
  49287. +#include "xor/mvXor.h"
  49288. +#include "mvSysXor.h"
  49289. +
  49290. +/* defines */
  49291. +#ifdef MV_DEBUG
  49292. + #define DB(x) x
  49293. +#else
  49294. + #define DB(x)
  49295. +#endif
  49296. +
  49297. +
  49298. +static MV_STATUS xorWinOverlapDetect(MV_U32 unit,MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
  49299. +
  49300. +MV_TARGET xorAddrDecPrioTap[] =
  49301. +{
  49302. +#if defined(MV_INCLUDE_DEVICE_CS0)
  49303. + DEVICE_CS0,
  49304. +#endif
  49305. +#if defined(MV_INCLUDE_PEX)
  49306. + PEX0_MEM,
  49307. +#endif
  49308. +#if defined(MV_INCLUDE_SDRAM_CS0)
  49309. + SDRAM_CS0,
  49310. +#endif
  49311. +#if defined(MV_INCLUDE_SDRAM_CS1)
  49312. + SDRAM_CS1,
  49313. +#endif
  49314. +#if defined(MV_INCLUDE_SDRAM_CS2)
  49315. + SDRAM_CS2,
  49316. +#endif
  49317. +#if defined(MV_INCLUDE_SDRAM_CS3)
  49318. + SDRAM_CS3,
  49319. +#endif
  49320. +#if defined(MV_INCLUDE_DEVICE_CS1)
  49321. + DEVICE_CS1,
  49322. +#endif
  49323. +#if defined(MV_INCLUDE_CESA)
  49324. + CRYPT_ENG,
  49325. +#endif
  49326. + TBL_TERM
  49327. +};
  49328. +static MV_STATUS mvXorInitWinsUnit (MV_U32 unit)
  49329. +{
  49330. + MV_U32 winNum;
  49331. + MV_XOR_DEC_WIN addrDecWin;
  49332. + MV_CPU_DEC_WIN cpuAddrDecWin;
  49333. + MV_U32 status;
  49334. + MV_U32 winPrioIndex=0;
  49335. +
  49336. + /* Initiate XOR address decode */
  49337. +
  49338. + /* First disable all address decode windows */
  49339. + for(winNum = 0; winNum < XOR_MAX_ADDR_DEC_WIN; winNum++)
  49340. + {
  49341. + mvXorTargetWinEnable(unit,winNum, MV_FALSE);
  49342. + }
  49343. +
  49344. + /* Go through all windows in user table until table terminator */
  49345. + for (winNum = 0; ((xorAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
  49346. + (winNum < XOR_MAX_ADDR_DEC_WIN));)
  49347. + {
  49348. + /* first get attributes from CPU If */
  49349. + status = mvCpuIfTargetWinGet(xorAddrDecPrioTap[winPrioIndex],
  49350. + &cpuAddrDecWin);
  49351. +
  49352. + if(MV_NO_SUCH == status)
  49353. + {
  49354. + winPrioIndex++;
  49355. + continue;
  49356. + }
  49357. + if (MV_OK != status)
  49358. + {
  49359. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  49360. + return MV_ERROR;
  49361. + }
  49362. +
  49363. +
  49364. + if (cpuAddrDecWin.enable == MV_TRUE)
  49365. + {
  49366. +
  49367. + addrDecWin.target = xorAddrDecPrioTap[winPrioIndex];
  49368. + addrDecWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  49369. + addrDecWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  49370. + addrDecWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  49371. + addrDecWin.enable = MV_TRUE;
  49372. +
  49373. + if (MV_OK != mvXorTargetWinSet(unit,winNum, &addrDecWin))
  49374. + {
  49375. + DB(mvOsPrintf("mvXorInit: ERR. mvDmaTargetWinSet failed\n"));
  49376. + return MV_ERROR;
  49377. + }
  49378. + winNum++;
  49379. + }
  49380. + winPrioIndex++;
  49381. +
  49382. + }
  49383. +
  49384. + return MV_OK;
  49385. +}
  49386. +
  49387. +
  49388. +/*******************************************************************************
  49389. +* mvXorInit - Initialize XOR engine
  49390. +*
  49391. +* DESCRIPTION:
  49392. +* This function initialize XOR unit. It set the default address decode
  49393. +* windows of the unit.
  49394. +* Note that if the address window is disabled in xorAddrDecMap, the
  49395. +* window parameters will be set but the window will remain disabled.
  49396. +*
  49397. +* INPUT:
  49398. +* None.
  49399. +*
  49400. +* OUTPUT:
  49401. +* None.
  49402. +*
  49403. +* RETURN:
  49404. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  49405. +*******************************************************************************/
  49406. +MV_STATUS mvXorInit (MV_VOID)
  49407. +{
  49408. + MV_U32 i;
  49409. +
  49410. + /* Initiate XOR address decode */
  49411. + for(i = 0; i < MV_XOR_MAX_UNIT; i++)
  49412. + mvXorInitWinsUnit(i);
  49413. +
  49414. + mvXorHalInit(MV_XOR_MAX_CHAN);
  49415. +
  49416. + return MV_OK;
  49417. +}
  49418. +
  49419. +/*******************************************************************************
  49420. +* mvXorTargetWinSet - Set XOR target address window
  49421. +*
  49422. +* DESCRIPTION:
  49423. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  49424. +* address window. After setting this target window, the XOR will be
  49425. +* able to access the target within the address window.
  49426. +*
  49427. +* INPUT:
  49428. +* winNum - One of the possible XOR memory decode windows.
  49429. +* target - Peripheral target enumerator.
  49430. +* base - Window base address.
  49431. +* size - Window size.
  49432. +* enable - Window enable/disable.
  49433. +*
  49434. +* OUTPUT:
  49435. +* None.
  49436. +*
  49437. +* RETURN:
  49438. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  49439. +*
  49440. +*******************************************************************************/
  49441. +MV_STATUS mvXorTargetWinSet(MV_U32 unit, MV_U32 winNum, MV_XOR_DEC_WIN *pAddrDecWin)
  49442. +{
  49443. + MV_DEC_REGS xorDecRegs;
  49444. + MV_TARGET_ATTRIB targetAttribs;
  49445. + MV_U32 chan;
  49446. +
  49447. + /* Parameter checking */
  49448. + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
  49449. + {
  49450. + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum));
  49451. + return MV_BAD_PARAM;
  49452. + }
  49453. + if (pAddrDecWin == NULL)
  49454. + {
  49455. + DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __FUNCTION__ ));
  49456. + return MV_BAD_PTR;
  49457. + }
  49458. + /* Check if the requested window overlaps with current windows */
  49459. + if (MV_TRUE == xorWinOverlapDetect(unit, winNum, &pAddrDecWin->addrWin))
  49460. + {
  49461. + DB(mvOsPrintf("%s: ERR. Window %d overlap\n",__FUNCTION__,winNum));
  49462. + return MV_ERROR;
  49463. + }
  49464. +
  49465. + xorDecRegs.baseReg = MV_REG_READ(XOR_BASE_ADDR_REG(unit,winNum));
  49466. + xorDecRegs.sizeReg = MV_REG_READ(XOR_SIZE_MASK_REG(unit,winNum));
  49467. +
  49468. + /* Get Base Address and size registers values */
  49469. + if(MV_OK != mvCtrlAddrDecToReg(&pAddrDecWin->addrWin, &xorDecRegs))
  49470. + {
  49471. + DB(mvOsPrintf("%s: ERR. Invalid addr dec window\n",__FUNCTION__));
  49472. + return MV_BAD_PARAM;
  49473. + }
  49474. +
  49475. +
  49476. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  49477. +
  49478. + /* set attributes */
  49479. + xorDecRegs.baseReg &= ~XEBARX_ATTR_MASK;
  49480. + xorDecRegs.baseReg |= targetAttribs.attrib << XEBARX_ATTR_OFFS;
  49481. + /* set target ID */
  49482. + xorDecRegs.baseReg &= ~XEBARX_TARGET_MASK;
  49483. + xorDecRegs.baseReg |= targetAttribs.targetId << XEBARX_TARGET_OFFS;
  49484. +
  49485. +
  49486. + /* Write to address decode Base Address Register */
  49487. + MV_REG_WRITE(XOR_BASE_ADDR_REG(unit,winNum), xorDecRegs.baseReg);
  49488. +
  49489. + /* Write to Size Register */
  49490. + MV_REG_WRITE(XOR_SIZE_MASK_REG(unit,winNum), xorDecRegs.sizeReg);
  49491. +
  49492. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
  49493. + {
  49494. + if (pAddrDecWin->enable)
  49495. + {
  49496. + MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit,chan),
  49497. + XEXWCR_WIN_EN_MASK(winNum));
  49498. + }
  49499. + else
  49500. + {
  49501. + MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit,chan),
  49502. + XEXWCR_WIN_EN_MASK(winNum));
  49503. + }
  49504. + }
  49505. + return MV_OK;
  49506. +}
  49507. +
  49508. +/*******************************************************************************
  49509. +* mvXorTargetWinGet - Get xor peripheral target address window.
  49510. +*
  49511. +* DESCRIPTION:
  49512. +* Get xor peripheral target address window.
  49513. +*
  49514. +* INPUT:
  49515. +* winNum - One of the possible XOR memory decode windows.
  49516. +*
  49517. +* OUTPUT:
  49518. +* base - Window base address.
  49519. +* size - Window size.
  49520. +* enable - window enable/disable.
  49521. +*
  49522. +* RETURN:
  49523. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  49524. +*
  49525. +*******************************************************************************/
  49526. +MV_STATUS mvXorTargetWinGet(MV_U32 unit,MV_U32 winNum, MV_XOR_DEC_WIN *pAddrDecWin)
  49527. +{
  49528. + MV_DEC_REGS xorDecRegs;
  49529. + MV_TARGET_ATTRIB targetAttrib;
  49530. + MV_U32 chan=0,chanWinEn;
  49531. +
  49532. + /* Parameter checking */
  49533. + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
  49534. + {
  49535. + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__ , winNum));
  49536. + return MV_ERROR;
  49537. + }
  49538. +
  49539. + if (NULL == pAddrDecWin)
  49540. + {
  49541. + DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __FUNCTION__ ));
  49542. + return MV_BAD_PTR;
  49543. + }
  49544. +
  49545. + chanWinEn = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,0)) & XEXWCR_WIN_EN_MASK(winNum);
  49546. +
  49547. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++) /* we should scan here all channels per unit */
  49548. + {
  49549. + /* Check if enable bit is equal for all channels */
  49550. + if ((MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan)) &
  49551. + XEXWCR_WIN_EN_MASK(winNum)) != chanWinEn)
  49552. + {
  49553. + mvOsPrintf("%s: ERR. Window enable field must be equal in "
  49554. + "all channels(chan=%d)\n",__FUNCTION__, chan);
  49555. + return MV_ERROR;
  49556. + }
  49557. + }
  49558. +
  49559. +
  49560. +
  49561. + xorDecRegs.baseReg = MV_REG_READ(XOR_BASE_ADDR_REG(unit,winNum));
  49562. + xorDecRegs.sizeReg = MV_REG_READ(XOR_SIZE_MASK_REG(unit,winNum));
  49563. +
  49564. + if (MV_OK != mvCtrlRegToAddrDec(&xorDecRegs, &pAddrDecWin->addrWin))
  49565. + {
  49566. + mvOsPrintf("%s: ERR. mvCtrlRegToAddrDec failed\n", __FUNCTION__);
  49567. + return MV_ERROR;
  49568. + }
  49569. +
  49570. + /* attrib and targetId */
  49571. + targetAttrib.attrib =
  49572. + (xorDecRegs.baseReg & XEBARX_ATTR_MASK) >> XEBARX_ATTR_OFFS;
  49573. + targetAttrib.targetId =
  49574. + (xorDecRegs.baseReg & XEBARX_TARGET_MASK) >> XEBARX_TARGET_OFFS;
  49575. +
  49576. +
  49577. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  49578. +
  49579. + if(chanWinEn)
  49580. + {
  49581. + pAddrDecWin->enable = MV_TRUE;
  49582. + }
  49583. + else pAddrDecWin->enable = MV_FALSE;
  49584. +
  49585. + return MV_OK;
  49586. +}
  49587. +
  49588. +/*******************************************************************************
  49589. +* mvXorTargetWinEnable - Enable/disable a Xor address decode window
  49590. +*
  49591. +* DESCRIPTION:
  49592. +* This function enable/disable a XOR address decode window.
  49593. +* if parameter 'enable' == MV_TRUE the routine will enable the
  49594. +* window, thus enabling XOR accesses (before enabling the window it is
  49595. +* tested for overlapping). Otherwise, the window will be disabled.
  49596. +*
  49597. +* INPUT:
  49598. +* winNum - Decode window number.
  49599. +* enable - Enable/disable parameter.
  49600. +*
  49601. +* OUTPUT:
  49602. +* None.
  49603. +*
  49604. +* RETURN:
  49605. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  49606. +*
  49607. +*******************************************************************************/
  49608. +MV_STATUS mvXorTargetWinEnable(MV_U32 unit,MV_U32 winNum, MV_BOOL enable)
  49609. +{
  49610. + MV_XOR_DEC_WIN addrDecWin;
  49611. + MV_U32 chan;
  49612. +
  49613. + /* Parameter checking */
  49614. + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
  49615. + {
  49616. + DB(mvOsPrintf("%s: ERR. Invalid winNum%d\n", __FUNCTION__, winNum));
  49617. + return MV_ERROR;
  49618. + }
  49619. +
  49620. + if (enable == MV_TRUE)
  49621. + {
  49622. + /* Get current window */
  49623. + if (MV_OK != mvXorTargetWinGet(unit,winNum, &addrDecWin))
  49624. + {
  49625. + DB(mvOsPrintf("%s: ERR. targetWinGet fail\n", __FUNCTION__));
  49626. + return MV_ERROR;
  49627. + }
  49628. +
  49629. + /* Check for overlapping */
  49630. + if (MV_TRUE == xorWinOverlapDetect(unit,winNum, &(addrDecWin.addrWin)))
  49631. + {
  49632. + /* Overlap detected */
  49633. + DB(mvOsPrintf("%s: ERR. Overlap detected\n", __FUNCTION__));
  49634. + return MV_ERROR;
  49635. + }
  49636. +
  49637. + /* No Overlap. Enable address decode target window */
  49638. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
  49639. + {
  49640. + MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit,chan),
  49641. + XEXWCR_WIN_EN_MASK(winNum));
  49642. + }
  49643. +
  49644. + }
  49645. + else
  49646. + {
  49647. + /* Disable address decode target window */
  49648. +
  49649. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
  49650. + {
  49651. + MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit,chan),
  49652. + XEXWCR_WIN_EN_MASK(winNum));
  49653. + }
  49654. +
  49655. + }
  49656. +
  49657. + return MV_OK;
  49658. +}
  49659. +
  49660. +/*******************************************************************************
  49661. +* mvXorSetProtWinSet - Configure access attributes of a XOR engine
  49662. +* to one of the XOR memory windows.
  49663. +*
  49664. +* DESCRIPTION:
  49665. +* Each engine can be configured with access attributes for each of the
  49666. +* memory spaces. This function sets access attributes
  49667. +* to a given window for the given engine
  49668. +*
  49669. +* INPUTS:
  49670. +* chan - One of the possible engines.
  49671. +* winNum - One of the possible XOR memory spaces.
  49672. +* access - Protection access rights.
  49673. +* write - Write rights.
  49674. +*
  49675. +* OUTPUT:
  49676. +* None.
  49677. +*
  49678. +* RETURN:
  49679. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  49680. +*
  49681. +*******************************************************************************/
  49682. +MV_STATUS mvXorProtWinSet (MV_U32 unit,MV_U32 chan, MV_U32 winNum, MV_BOOL access,
  49683. + MV_BOOL write)
  49684. +{
  49685. + MV_U32 temp;
  49686. +
  49687. + /* Parameter checking */
  49688. + if (chan >= MV_XOR_MAX_CHAN_PER_UNIT)
  49689. + {
  49690. + DB(mvOsPrintf("%s: ERR. Invalid chan num %d\n", __FUNCTION__ , chan));
  49691. + return MV_BAD_PARAM;
  49692. + }
  49693. + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
  49694. + {
  49695. + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n", __FUNCTION__, winNum));
  49696. + return MV_BAD_PARAM;
  49697. + }
  49698. +
  49699. + temp = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan)) &
  49700. + (~XEXWCR_WIN_ACC_MASK(winNum));
  49701. +
  49702. + /* if access is disable */
  49703. + if (!access)
  49704. + {
  49705. + /* disable access */
  49706. + temp |= XEXWCR_WIN_ACC_NO_ACC(winNum);
  49707. + }
  49708. + /* if access is enable */
  49709. + else
  49710. + {
  49711. + /* if write is enable */
  49712. + if (write)
  49713. + {
  49714. + /* enable write */
  49715. + temp |= XEXWCR_WIN_ACC_RW(winNum);
  49716. + }
  49717. + /* if write is disable */
  49718. + else
  49719. + {
  49720. + /* disable write */
  49721. + temp |= XEXWCR_WIN_ACC_RO(winNum);
  49722. + }
  49723. + }
  49724. + MV_REG_WRITE(XOR_WINDOW_CTRL_REG(unit,chan),temp);
  49725. + return MV_OK;
  49726. +}
  49727. +
  49728. +/*******************************************************************************
  49729. +* mvXorPciRemap - Set XOR remap register for PCI address windows.
  49730. +*
  49731. +* DESCRIPTION:
  49732. +* only Windows 0-3 can be remapped.
  49733. +*
  49734. +* INPUT:
  49735. +* winNum - window number
  49736. +* pAddrDecWin - pointer to address space window structure
  49737. +* OUTPUT:
  49738. +* None.
  49739. +*
  49740. +* RETURN:
  49741. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  49742. +*
  49743. +*******************************************************************************/
  49744. +MV_STATUS mvXorPciRemap(MV_U32 unit,MV_U32 winNum, MV_U32 addrHigh)
  49745. +{
  49746. + /* Parameter checking */
  49747. + if (winNum >= XOR_MAX_REMAP_WIN)
  49748. + {
  49749. + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n", __FUNCTION__, winNum));
  49750. + return MV_BAD_PARAM;
  49751. + }
  49752. +
  49753. + MV_REG_WRITE(XOR_HIGH_ADDR_REMAP_REG(unit,winNum), addrHigh);
  49754. +
  49755. + return MV_OK;
  49756. +}
  49757. +
  49758. +/*******************************************************************************
  49759. +* xorWinOverlapDetect - Detect XOR address windows overlaping
  49760. +*
  49761. +* DESCRIPTION:
  49762. +* An unpredicted behaviour is expected in case XOR address decode
  49763. +* windows overlaps.
  49764. +* This function detects XOR address decode windows overlaping of a
  49765. +* specified window. The function does not check the window itself for
  49766. +* overlaping. The function also skipps disabled address decode windows.
  49767. +*
  49768. +* INPUT:
  49769. +* winNum - address decode window number.
  49770. +* pAddrDecWin - An address decode window struct.
  49771. +*
  49772. +* OUTPUT:
  49773. +* None.
  49774. +*
  49775. +* RETURN:
  49776. +* MV_TRUE if the given address window overlap current address
  49777. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  49778. +* from registers.
  49779. +*
  49780. +*******************************************************************************/
  49781. +static MV_STATUS xorWinOverlapDetect(MV_U32 unit,MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  49782. +{
  49783. + MV_U32 baseAddrEnableReg;
  49784. + MV_U32 winNumIndex,chan;
  49785. + MV_XOR_DEC_WIN addrDecWin;
  49786. +
  49787. + if (pAddrWin == NULL)
  49788. + {
  49789. + DB(mvOsPrintf("%s: ERR. pAddrWin is NULL pointer\n", __FUNCTION__ ));
  49790. + return MV_BAD_PTR;
  49791. + }
  49792. +
  49793. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
  49794. + {
  49795. + /* Read base address enable register. Do not check disabled windows */
  49796. + baseAddrEnableReg = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan));
  49797. +
  49798. + for (winNumIndex = 0; winNumIndex < XOR_MAX_ADDR_DEC_WIN; winNumIndex++)
  49799. + {
  49800. + /* Do not check window itself */
  49801. + if (winNumIndex == winNum)
  49802. + {
  49803. + continue;
  49804. + }
  49805. +
  49806. + /* Do not check disabled windows */
  49807. + if ((baseAddrEnableReg & XEXWCR_WIN_EN_MASK(winNumIndex)) == 0)
  49808. + {
  49809. + continue;
  49810. + }
  49811. +
  49812. + /* Get window parameters */
  49813. + if (MV_OK != mvXorTargetWinGet(unit,winNumIndex, &addrDecWin))
  49814. + {
  49815. + DB(mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__ ));
  49816. + return MV_ERROR;
  49817. + }
  49818. +
  49819. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  49820. + {
  49821. + return MV_TRUE;
  49822. + }
  49823. + }
  49824. + }
  49825. +
  49826. + return MV_FALSE;
  49827. +}
  49828. +
  49829. +static MV_VOID mvXorAddrDecShowUnit(MV_U32 unit)
  49830. +{
  49831. + MV_XOR_DEC_WIN win;
  49832. + int i;
  49833. +
  49834. + mvOsOutput( "\n" );
  49835. + mvOsOutput( "XOR %d:\n", unit );
  49836. + mvOsOutput( "----\n" );
  49837. +
  49838. + for( i = 0; i < XOR_MAX_ADDR_DEC_WIN; i++ )
  49839. + {
  49840. + memset( &win, 0, sizeof(MV_XOR_DEC_WIN) );
  49841. +
  49842. + mvOsOutput( "win%d - ", i );
  49843. +
  49844. + if( mvXorTargetWinGet(unit, i, &win ) == MV_OK )
  49845. + {
  49846. + if( win.enable )
  49847. + {
  49848. + mvOsOutput( "%s base %x, ",
  49849. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  49850. +
  49851. + mvSizePrint( win.addrWin.size );
  49852. +
  49853. + mvOsOutput( "\n" );
  49854. + }
  49855. + else
  49856. + mvOsOutput( "disable\n" );
  49857. + }
  49858. + }
  49859. +}
  49860. +
  49861. +/*******************************************************************************
  49862. +* mvXorAddrDecShow - Print the XOR address decode map.
  49863. +*
  49864. +* DESCRIPTION:
  49865. +* This function print the XOR address decode map.
  49866. +*
  49867. +* INPUT:
  49868. +* None.
  49869. +*
  49870. +* OUTPUT:
  49871. +* None.
  49872. +*
  49873. +* RETURN:
  49874. +* None.
  49875. +*
  49876. +*******************************************************************************/
  49877. +MV_VOID mvXorAddrDecShow(MV_VOID)
  49878. +{
  49879. + int i;
  49880. +
  49881. + for( i = 0; i < MV_XOR_MAX_UNIT; i++ )
  49882. + mvXorAddrDecShowUnit(i);
  49883. +
  49884. +}
  49885. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h
  49886. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h 1970-01-01 01:00:00.000000000 +0100
  49887. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h 2010-08-05 22:02:23.204868080 +0200
  49888. @@ -0,0 +1,140 @@
  49889. +/*******************************************************************************
  49890. +Copyright (C) Marvell International Ltd. and its affiliates
  49891. +
  49892. +This software file (the "File") is owned and distributed by Marvell
  49893. +International Ltd. and/or its affiliates ("Marvell") under the following
  49894. +alternative licensing terms. Once you have made an election to distribute the
  49895. +File under one of the following license alternatives, please (i) delete this
  49896. +introductory statement regarding license alternatives, (ii) delete the two
  49897. +license alternatives that you have not elected to use and (iii) preserve the
  49898. +Marvell copyright notice above.
  49899. +
  49900. +********************************************************************************
  49901. +Marvell Commercial License Option
  49902. +
  49903. +If you received this File from Marvell and you have entered into a commercial
  49904. +license agreement (a "Commercial License") with Marvell, the File is licensed
  49905. +to you under the terms of the applicable Commercial License.
  49906. +
  49907. +********************************************************************************
  49908. +Marvell GPL License Option
  49909. +
  49910. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49911. +modify this File in accordance with the terms and conditions of the General
  49912. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  49913. +available along with the File in the license.txt file or by writing to the Free
  49914. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  49915. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  49916. +
  49917. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  49918. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  49919. +DISCLAIMED. The GPL License provides additional details about this warranty
  49920. +disclaimer.
  49921. +********************************************************************************
  49922. +Marvell BSD License Option
  49923. +
  49924. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49925. +modify this File under the following licensing terms.
  49926. +Redistribution and use in source and binary forms, with or without modification,
  49927. +are permitted provided that the following conditions are met:
  49928. +
  49929. + * Redistributions of source code must retain the above copyright notice,
  49930. + this list of conditions and the following disclaimer.
  49931. +
  49932. + * Redistributions in binary form must reproduce the above copyright
  49933. + notice, this list of conditions and the following disclaimer in the
  49934. + documentation and/or other materials provided with the distribution.
  49935. +
  49936. + * Neither the name of Marvell nor the names of its contributors may be
  49937. + used to endorse or promote products derived from this software without
  49938. + specific prior written permission.
  49939. +
  49940. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  49941. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  49942. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  49943. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  49944. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  49945. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  49946. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  49947. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  49948. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  49949. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  49950. +
  49951. +*******************************************************************************/
  49952. +
  49953. +#ifndef __INCMVSysXorh
  49954. +#define __INCMVSysXorh
  49955. +
  49956. +
  49957. +#ifdef __cplusplus
  49958. +extern "C" {
  49959. +#endif
  49960. +
  49961. +#include "ctrlEnv/sys/mvCpuIf.h"
  49962. +
  49963. +#include "ctrlEnv/mvCtrlEnvLib.h"
  49964. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  49965. +
  49966. +#define XOR_MAX_ADDR_DEC_WIN 8 /* Maximum address decode windows */
  49967. +#define XOR_MAX_REMAP_WIN 4 /* Maximum address arbiter windows */
  49968. +
  49969. +/* XOR Engine Address Decoding Register Map */
  49970. +#define XOR_WINDOW_CTRL_REG(unit,chan) (XOR_UNIT_BASE(unit)+(0x240 + ((chan) * 4)))
  49971. +#define XOR_BASE_ADDR_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x250 + ((winNum) * 4)))
  49972. +#define XOR_SIZE_MASK_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x270 + ((winNum) * 4)))
  49973. +#define XOR_HIGH_ADDR_REMAP_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x290 + ((winNum) * 4)))
  49974. +
  49975. +/* XOR Engine [0..1] Window Control Registers (XExWCR) */
  49976. +#define XEXWCR_WIN_EN_OFFS(winNum) (winNum)
  49977. +#define XEXWCR_WIN_EN_MASK(winNum) (1 << (XEXWCR_WIN_EN_OFFS(winNum)))
  49978. +#define XEXWCR_WIN_EN_ENABLE(winNum) (1 << (XEXWCR_WIN_EN_OFFS(winNum)))
  49979. +#define XEXWCR_WIN_EN_DISABLE(winNum) (0 << (XEXWCR_WIN_EN_OFFS(winNum)))
  49980. +
  49981. +#define XEXWCR_WIN_ACC_OFFS(winNum) ((2 * winNum) + 16)
  49982. +#define XEXWCR_WIN_ACC_MASK(winNum) (3 << (XEXWCR_WIN_ACC_OFFS(winNum)))
  49983. +#define XEXWCR_WIN_ACC_NO_ACC(winNum) (0 << (XEXWCR_WIN_ACC_OFFS(winNum)))
  49984. +#define XEXWCR_WIN_ACC_RO(winNum) (1 << (XEXWCR_WIN_ACC_OFFS(winNum)))
  49985. +#define XEXWCR_WIN_ACC_RW(winNum) (3 << (XEXWCR_WIN_ACC_OFFS(winNum)))
  49986. +
  49987. +/* XOR Engine Base Address Registers (XEBARx) */
  49988. +#define XEBARX_TARGET_OFFS (0)
  49989. +#define XEBARX_TARGET_MASK (0xF << XEBARX_TARGET_OFFS)
  49990. +#define XEBARX_ATTR_OFFS (8)
  49991. +#define XEBARX_ATTR_MASK (0xFF << XEBARX_ATTR_OFFS)
  49992. +#define XEBARX_BASE_OFFS (16)
  49993. +#define XEBARX_BASE_MASK (0xFFFF << XEBARX_BASE_OFFS)
  49994. +
  49995. +/* XOR Engine Size Mask Registers (XESMRx) */
  49996. +#define XESMRX_SIZE_MASK_OFFS (16)
  49997. +#define XESMRX_SIZE_MASK_MASK (0xFFFF << XESMRX_SIZE_MASK_OFFS)
  49998. +
  49999. +/* XOR Engine High Address Remap Register (XEHARRx1) */
  50000. +#define XEHARRX_REMAP_OFFS (0)
  50001. +#define XEHARRX_REMAP_MASK (0xFFFFFFFF << XEHARRX_REMAP_OFFS)
  50002. +
  50003. +typedef struct _mvXorDecWin
  50004. +{
  50005. + MV_TARGET target;
  50006. + MV_ADDR_WIN addrWin; /* An address window*/
  50007. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  50008. +
  50009. +}MV_XOR_DEC_WIN;
  50010. +
  50011. +MV_STATUS mvXorInit (MV_VOID);
  50012. +MV_STATUS mvXorTargetWinSet(MV_U32 unit, MV_U32 winNum,
  50013. + MV_XOR_DEC_WIN *pAddrDecWin);
  50014. +MV_STATUS mvXorTargetWinGet(MV_U32 unit, MV_U32 winNum,
  50015. + MV_XOR_DEC_WIN *pAddrDecWin);
  50016. +MV_STATUS mvXorTargetWinEnable(MV_U32 unit,
  50017. + MV_U32 winNum, MV_BOOL enable);
  50018. +MV_STATUS mvXorProtWinSet (MV_U32 unit,MV_U32 chan, MV_U32 winNum, MV_BOOL access,
  50019. + MV_BOOL write);
  50020. +MV_STATUS mvXorPciRemap(MV_U32 unit, MV_U32 winNum, MV_U32 addrHigh);
  50021. +
  50022. +MV_VOID mvXorAddrDecShow(MV_VOID);
  50023. +
  50024. +#ifdef __cplusplus
  50025. +}
  50026. +#endif
  50027. +
  50028. +#endif
  50029. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c
  50030. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c 1970-01-01 01:00:00.000000000 +0100
  50031. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c 2010-08-05 22:02:23.244867956 +0200
  50032. @@ -0,0 +1,75 @@
  50033. +/*******************************************************************************
  50034. +Copyright (C) Marvell International Ltd. and its affiliates
  50035. +
  50036. +This software file (the "File") is owned and distributed by Marvell
  50037. +International Ltd. and/or its affiliates ("Marvell") under the following
  50038. +alternative licensing terms. Once you have made an election to distribute the
  50039. +File under one of the following license alternatives, please (i) delete this
  50040. +introductory statement regarding license alternatives, (ii) delete the two
  50041. +license alternatives that you have not elected to use and (iii) preserve the
  50042. +Marvell copyright notice above.
  50043. +
  50044. +********************************************************************************
  50045. +Marvell Commercial License Option
  50046. +
  50047. +If you received this File from Marvell and you have entered into a commercial
  50048. +license agreement (a "Commercial License") with Marvell, the File is licensed
  50049. +to you under the terms of the applicable Commercial License.
  50050. +
  50051. +********************************************************************************
  50052. +Marvell GPL License Option
  50053. +
  50054. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50055. +modify this File in accordance with the terms and conditions of the General
  50056. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  50057. +available along with the File in the license.txt file or by writing to the Free
  50058. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  50059. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  50060. +
  50061. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  50062. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  50063. +DISCLAIMED. The GPL License provides additional details about this warranty
  50064. +disclaimer.
  50065. +********************************************************************************
  50066. +Marvell BSD License Option
  50067. +
  50068. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50069. +modify this File under the following licensing terms.
  50070. +Redistribution and use in source and binary forms, with or without modification,
  50071. +are permitted provided that the following conditions are met:
  50072. +
  50073. + * Redistributions of source code must retain the above copyright notice,
  50074. + this list of conditions and the following disclaimer.
  50075. +
  50076. + * Redistributions in binary form must reproduce the above copyright
  50077. + notice, this list of conditions and the following disclaimer in the
  50078. + documentation and/or other materials provided with the distribution.
  50079. +
  50080. + * Neither the name of Marvell nor the names of its contributors may be
  50081. + used to endorse or promote products derived from this software without
  50082. + specific prior written permission.
  50083. +
  50084. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  50085. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  50086. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  50087. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  50088. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  50089. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  50090. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  50091. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  50092. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  50093. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50094. +
  50095. +*******************************************************************************/
  50096. +
  50097. +#include "device/mvDevice.h"
  50098. +
  50099. +/* defines */
  50100. +#ifdef MV_DEBUG
  50101. + #define DB(x) x
  50102. +#else
  50103. + #define DB(x)
  50104. +#endif
  50105. +
  50106. +
  50107. +
  50108. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h
  50109. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h 1970-01-01 01:00:00.000000000 +0100
  50110. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h 2010-08-05 22:02:23.294149171 +0200
  50111. @@ -0,0 +1,74 @@
  50112. +/*******************************************************************************
  50113. +Copyright (C) Marvell International Ltd. and its affiliates
  50114. +
  50115. +This software file (the "File") is owned and distributed by Marvell
  50116. +International Ltd. and/or its affiliates ("Marvell") under the following
  50117. +alternative licensing terms. Once you have made an election to distribute the
  50118. +File under one of the following license alternatives, please (i) delete this
  50119. +introductory statement regarding license alternatives, (ii) delete the two
  50120. +license alternatives that you have not elected to use and (iii) preserve the
  50121. +Marvell copyright notice above.
  50122. +
  50123. +********************************************************************************
  50124. +Marvell Commercial License Option
  50125. +
  50126. +If you received this File from Marvell and you have entered into a commercial
  50127. +license agreement (a "Commercial License") with Marvell, the File is licensed
  50128. +to you under the terms of the applicable Commercial License.
  50129. +
  50130. +********************************************************************************
  50131. +Marvell GPL License Option
  50132. +
  50133. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50134. +modify this File in accordance with the terms and conditions of the General
  50135. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  50136. +available along with the File in the license.txt file or by writing to the Free
  50137. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  50138. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  50139. +
  50140. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  50141. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  50142. +DISCLAIMED. The GPL License provides additional details about this warranty
  50143. +disclaimer.
  50144. +********************************************************************************
  50145. +Marvell BSD License Option
  50146. +
  50147. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50148. +modify this File under the following licensing terms.
  50149. +Redistribution and use in source and binary forms, with or without modification,
  50150. +are permitted provided that the following conditions are met:
  50151. +
  50152. + * Redistributions of source code must retain the above copyright notice,
  50153. + this list of conditions and the following disclaimer.
  50154. +
  50155. + * Redistributions in binary form must reproduce the above copyright
  50156. + notice, this list of conditions and the following disclaimer in the
  50157. + documentation and/or other materials provided with the distribution.
  50158. +
  50159. + * Neither the name of Marvell nor the names of its contributors may be
  50160. + used to endorse or promote products derived from this software without
  50161. + specific prior written permission.
  50162. +
  50163. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  50164. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  50165. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  50166. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  50167. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  50168. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  50169. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  50170. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  50171. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  50172. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50173. +
  50174. +*******************************************************************************/
  50175. +
  50176. +#ifndef __INCmvDeviceH
  50177. +#define __INCmvDeviceH
  50178. +
  50179. +#include "mvCommon.h"
  50180. +#include "mvOs.h"
  50181. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  50182. +#include "device/mvDeviceRegs.h"
  50183. +
  50184. +
  50185. +#endif /* #ifndef __INCmvDeviceH */
  50186. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h
  50187. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h 1970-01-01 01:00:00.000000000 +0100
  50188. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h 2010-08-05 22:02:23.344059995 +0200
  50189. @@ -0,0 +1,101 @@
  50190. +/*******************************************************************************
  50191. +Copyright (C) Marvell International Ltd. and its affiliates
  50192. +
  50193. +This software file (the "File") is owned and distributed by Marvell
  50194. +International Ltd. and/or its affiliates ("Marvell") under the following
  50195. +alternative licensing terms. Once you have made an election to distribute the
  50196. +File under one of the following license alternatives, please (i) delete this
  50197. +introductory statement regarding license alternatives, (ii) delete the two
  50198. +license alternatives that you have not elected to use and (iii) preserve the
  50199. +Marvell copyright notice above.
  50200. +
  50201. +********************************************************************************
  50202. +Marvell Commercial License Option
  50203. +
  50204. +If you received this File from Marvell and you have entered into a commercial
  50205. +license agreement (a "Commercial License") with Marvell, the File is licensed
  50206. +to you under the terms of the applicable Commercial License.
  50207. +
  50208. +********************************************************************************
  50209. +Marvell GPL License Option
  50210. +
  50211. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50212. +modify this File in accordance with the terms and conditions of the General
  50213. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  50214. +available along with the File in the license.txt file or by writing to the Free
  50215. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  50216. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  50217. +
  50218. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  50219. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  50220. +DISCLAIMED. The GPL License provides additional details about this warranty
  50221. +disclaimer.
  50222. +********************************************************************************
  50223. +Marvell BSD License Option
  50224. +
  50225. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50226. +modify this File under the following licensing terms.
  50227. +Redistribution and use in source and binary forms, with or without modification,
  50228. +are permitted provided that the following conditions are met:
  50229. +
  50230. + * Redistributions of source code must retain the above copyright notice,
  50231. + this list of conditions and the following disclaimer.
  50232. +
  50233. + * Redistributions in binary form must reproduce the above copyright
  50234. + notice, this list of conditions and the following disclaimer in the
  50235. + documentation and/or other materials provided with the distribution.
  50236. +
  50237. + * Neither the name of Marvell nor the names of its contributors may be
  50238. + used to endorse or promote products derived from this software without
  50239. + specific prior written permission.
  50240. +
  50241. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  50242. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  50243. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  50244. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  50245. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  50246. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  50247. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  50248. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  50249. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  50250. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50251. +
  50252. +*******************************************************************************/
  50253. +
  50254. +#ifndef __INCmvDeviceRegsH
  50255. +#define __INCmvDeviceRegsH
  50256. +
  50257. +#ifndef MV_ASMLANGUAGE
  50258. +#include "ctrlEnv/mvCtrlEnvLib.h"
  50259. +/* This enumerator describes the Marvell controller possible devices that */
  50260. +/* can be connected to its device interface. */
  50261. +typedef enum _mvDevice
  50262. +{
  50263. +#if defined(MV_INCLUDE_DEVICE_CS0)
  50264. + DEV_CS0 = 0, /* Device connected to dev CS[0] */
  50265. +#endif
  50266. +#if defined(MV_INCLUDE_DEVICE_CS1)
  50267. + DEV_CS1 = 1, /* Device connected to dev CS[1] */
  50268. +#endif
  50269. +#if defined(MV_INCLUDE_DEVICE_CS2)
  50270. + DEV_CS2 = 2, /* Device connected to dev CS[2] */
  50271. +#endif
  50272. +#if defined(MV_INCLUDE_DEVICE_CS3)
  50273. + DEV_CS3 = 3, /* Device connected to dev CS[2] */
  50274. +#endif
  50275. +#if defined(MV_INCLUDE_DEVICE_CS4)
  50276. + DEV_CS4 = 4, /* Device connected to BOOT dev */
  50277. +#endif
  50278. + MV_DEV_MAX_CS = MV_DEVICE_MAX_CS
  50279. +}MV_DEVICE;
  50280. +
  50281. +
  50282. +#endif /* MV_ASMLANGUAGE */
  50283. +
  50284. +
  50285. +#define NAND_CTRL_REG 0x10470
  50286. +
  50287. +#define NAND_ACTCEBOOT_BIT BIT1
  50288. +
  50289. +
  50290. +#endif /* #ifndef __INCmvDeviceRegsH */
  50291. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c
  50292. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c 1970-01-01 01:00:00.000000000 +0100
  50293. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c 2010-08-05 22:02:23.384506949 +0200
  50294. @@ -0,0 +1,211 @@
  50295. +/*******************************************************************************
  50296. +Copyright (C) Marvell International Ltd. and its affiliates
  50297. +
  50298. +This software file (the "File") is owned and distributed by Marvell
  50299. +International Ltd. and/or its affiliates ("Marvell") under the following
  50300. +alternative licensing terms. Once you have made an election to distribute the
  50301. +File under one of the following license alternatives, please (i) delete this
  50302. +introductory statement regarding license alternatives, (ii) delete the two
  50303. +license alternatives that you have not elected to use and (iii) preserve the
  50304. +Marvell copyright notice above.
  50305. +
  50306. +
  50307. +********************************************************************************
  50308. +Marvell GPL License Option
  50309. +
  50310. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50311. +modify this File in accordance with the terms and conditions of the General
  50312. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  50313. +available along with the File in the license.txt file or by writing to the Free
  50314. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  50315. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  50316. +
  50317. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  50318. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  50319. +DISCLAIMED. The GPL License provides additional details about this warranty
  50320. +disclaimer.
  50321. +*******************************************************************************/
  50322. +/*******************************************************************************
  50323. +* mvOsCpuArchLib.c - Marvell CPU architecture library
  50324. +*
  50325. +* DESCRIPTION:
  50326. +* This library introduce Marvell API for OS dependent CPU architecture
  50327. +* APIs. This library introduce single CPU architecture services APKI
  50328. +* cross OS.
  50329. +*
  50330. +* DEPENDENCIES:
  50331. +* None.
  50332. +*
  50333. +*******************************************************************************/
  50334. +
  50335. +/* includes */
  50336. +#include <asm/processor.h>
  50337. +#include "mvOs.h"
  50338. +
  50339. +static MV_U32 read_p15_c0 (void);
  50340. +
  50341. +/* defines */
  50342. +#define ARM_ID_REVISION_OFFS 0
  50343. +#define ARM_ID_REVISION_MASK (0xf << ARM_ID_REVISION_OFFS)
  50344. +
  50345. +#define ARM_ID_PART_NUM_OFFS 4
  50346. +#define ARM_ID_PART_NUM_MASK (0xfff << ARM_ID_PART_NUM_OFFS)
  50347. +
  50348. +#define ARM_ID_ARCH_OFFS 16
  50349. +#define ARM_ID_ARCH_MASK (0xf << ARM_ID_ARCH_OFFS)
  50350. +
  50351. +#define ARM_ID_VAR_OFFS 20
  50352. +#define ARM_ID_VAR_MASK (0xf << ARM_ID_VAR_OFFS)
  50353. +
  50354. +#define ARM_ID_ASCII_OFFS 24
  50355. +#define ARM_ID_ASCII_MASK (0xff << ARM_ID_ASCII_OFFS)
  50356. +
  50357. +
  50358. +
  50359. +void* mvOsIoCachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr,
  50360. + MV_U32 *memHandle)
  50361. +{
  50362. + void *p = kmalloc( size, GFP_KERNEL );
  50363. + *pPhyAddr = pci_map_single( osHandle, p, 0, PCI_DMA_BIDIRECTIONAL );
  50364. + return p;
  50365. +}
  50366. +void* mvOsIoUncachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr,
  50367. + MV_U32 *memHandle)
  50368. +{
  50369. + return pci_alloc_consistent( osHandle, size, (dma_addr_t *)pPhyAddr );
  50370. +}
  50371. +
  50372. +void mvOsIoUncachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr,
  50373. + MV_U32 memHandle)
  50374. +{
  50375. + return pci_free_consistent( osHandle, size, pVirtAddr, (dma_addr_t)phyAddr );
  50376. +}
  50377. +
  50378. +void mvOsIoCachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr,
  50379. + MV_U32 memHandle )
  50380. +{
  50381. + return kfree( pVirtAddr );
  50382. +}
  50383. +
  50384. +int mvOsRand(void)
  50385. +{
  50386. + int rand;
  50387. + get_random_bytes(&rand, sizeof(rand) );
  50388. + return rand;
  50389. +}
  50390. +
  50391. +/*******************************************************************************
  50392. +* mvOsCpuVerGet() -
  50393. +*
  50394. +* DESCRIPTION:
  50395. +*
  50396. +* INPUT:
  50397. +* None.
  50398. +*
  50399. +* OUTPUT:
  50400. +* None.
  50401. +*
  50402. +* RETURN:
  50403. +* 32bit CPU Revision
  50404. +*
  50405. +*******************************************************************************/
  50406. +MV_U32 mvOsCpuRevGet( MV_VOID )
  50407. +{
  50408. + return ((read_p15_c0() & ARM_ID_REVISION_MASK ) >> ARM_ID_REVISION_OFFS);
  50409. +}
  50410. +/*******************************************************************************
  50411. +* mvOsCpuPartGet() -
  50412. +*
  50413. +* DESCRIPTION:
  50414. +*
  50415. +* INPUT:
  50416. +* None.
  50417. +*
  50418. +* OUTPUT:
  50419. +* None.
  50420. +*
  50421. +* RETURN:
  50422. +* 32bit CPU Part number
  50423. +*
  50424. +*******************************************************************************/
  50425. +MV_U32 mvOsCpuPartGet( MV_VOID )
  50426. +{
  50427. + return ((read_p15_c0() & ARM_ID_PART_NUM_MASK ) >> ARM_ID_PART_NUM_OFFS);
  50428. +}
  50429. +/*******************************************************************************
  50430. +* mvOsCpuArchGet() -
  50431. +*
  50432. +* DESCRIPTION:
  50433. +*
  50434. +* INPUT:
  50435. +* None.
  50436. +*
  50437. +* OUTPUT:
  50438. +* None.
  50439. +*
  50440. +* RETURN:
  50441. +* 32bit CPU Architicture number
  50442. +*
  50443. +*******************************************************************************/
  50444. +MV_U32 mvOsCpuArchGet( MV_VOID )
  50445. +{
  50446. + return ((read_p15_c0() & ARM_ID_ARCH_MASK ) >> ARM_ID_ARCH_OFFS);
  50447. +}
  50448. +/*******************************************************************************
  50449. +* mvOsCpuVarGet() -
  50450. +*
  50451. +* DESCRIPTION:
  50452. +*
  50453. +* INPUT:
  50454. +* None.
  50455. +*
  50456. +* OUTPUT:
  50457. +* None.
  50458. +*
  50459. +* RETURN:
  50460. +* 32bit CPU Variant number
  50461. +*
  50462. +*******************************************************************************/
  50463. +MV_U32 mvOsCpuVarGet( MV_VOID )
  50464. +{
  50465. + return ((read_p15_c0() & ARM_ID_VAR_MASK ) >> ARM_ID_VAR_OFFS);
  50466. +}
  50467. +/*******************************************************************************
  50468. +* mvOsCpuAsciiGet() -
  50469. +*
  50470. +* DESCRIPTION:
  50471. +*
  50472. +* INPUT:
  50473. +* None.
  50474. +*
  50475. +* OUTPUT:
  50476. +* None.
  50477. +*
  50478. +* RETURN:
  50479. +* 32bit CPU Variant number
  50480. +*
  50481. +*******************************************************************************/
  50482. +MV_U32 mvOsCpuAsciiGet( MV_VOID )
  50483. +{
  50484. + return ((read_p15_c0() & ARM_ID_ASCII_MASK ) >> ARM_ID_ASCII_OFFS);
  50485. +}
  50486. +
  50487. +
  50488. +
  50489. +/*
  50490. +static unsigned long read_p15_c0 (void)
  50491. +*/
  50492. +/* read co-processor 15, register #0 (ID register) */
  50493. +static MV_U32 read_p15_c0 (void)
  50494. +{
  50495. + MV_U32 value;
  50496. +
  50497. + __asm__ __volatile__(
  50498. + "mrc p15, 0, %0, c0, c0, 0 @ read control reg\n"
  50499. + : "=r" (value)
  50500. + :
  50501. + : "memory");
  50502. +
  50503. + return value;
  50504. +}
  50505. +
  50506. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h
  50507. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h 1970-01-01 01:00:00.000000000 +0100
  50508. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h 2010-08-05 22:02:23.414867923 +0200
  50509. @@ -0,0 +1,423 @@
  50510. +/*******************************************************************************
  50511. +Copyright (C) Marvell International Ltd. and its affiliates
  50512. +
  50513. +This software file (the "File") is owned and distributed by Marvell
  50514. +International Ltd. and/or its affiliates ("Marvell") under the following
  50515. +alternative licensing terms. Once you have made an election to distribute the
  50516. +File under one of the following license alternatives, please (i) delete this
  50517. +introductory statement regarding license alternatives, (ii) delete the two
  50518. +license alternatives that you have not elected to use and (iii) preserve the
  50519. +Marvell copyright notice above.
  50520. +
  50521. +
  50522. +********************************************************************************
  50523. +Marvell GPL License Option
  50524. +
  50525. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50526. +modify this File in accordance with the terms and conditions of the General
  50527. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  50528. +available along with the File in the license.txt file or by writing to the Free
  50529. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  50530. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  50531. +
  50532. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  50533. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  50534. +DISCLAIMED. The GPL License provides additional details about this warranty
  50535. +disclaimer.
  50536. +*******************************************************************************/
  50537. +#ifndef _MV_OS_LNX_H_
  50538. +#define _MV_OS_LNX_H_
  50539. +
  50540. +
  50541. +#ifdef __KERNEL__
  50542. +/* for kernel space */
  50543. +#include <linux/autoconf.h>
  50544. +#include <linux/interrupt.h>
  50545. +#include <linux/stddef.h>
  50546. +#include <linux/kernel.h>
  50547. +#include <linux/init.h>
  50548. +#include <linux/errno.h>
  50549. +#include <linux/reboot.h>
  50550. +#include <linux/pci.h>
  50551. +#include <linux/kdev_t.h>
  50552. +#include <linux/major.h>
  50553. +#include <linux/blkdev.h>
  50554. +#include <linux/console.h>
  50555. +#include <linux/delay.h>
  50556. +#include <linux/seq_file.h>
  50557. +#include <linux/string.h>
  50558. +#include <linux/slab.h>
  50559. +#include <linux/kernel.h>
  50560. +#include <linux/string.h>
  50561. +#include <linux/slab.h>
  50562. +#include <linux/mm.h>
  50563. +
  50564. +#include <asm/system.h>
  50565. +#include <asm/pgtable.h>
  50566. +#include <asm/page.h>
  50567. +#include <asm/hardirq.h>
  50568. +#include <asm/dma.h>
  50569. +#include <asm/io.h>
  50570. +
  50571. +#include <linux/random.h>
  50572. +
  50573. +#include "dbg-trace.h"
  50574. +
  50575. +extern void mv_early_printk(char *fmt,...);
  50576. +
  50577. +#define MV_ASM __asm__ __volatile__
  50578. +#define INLINE inline
  50579. +#define MV_TRC_REC TRC_REC
  50580. +#define mvOsPrintf printk
  50581. +#define mvOsEarlyPrintf mv_early_printk
  50582. +#define mvOsOutput printk
  50583. +#define mvOsSPrintf sprintf
  50584. +#define mvOsMalloc(_size_) kmalloc(_size_,GFP_ATOMIC)
  50585. +#define mvOsFree kfree
  50586. +#define mvOsMemcpy memcpy
  50587. +#define mvOsSleep(_mils_) mdelay(_mils_)
  50588. +#define mvOsTaskLock()
  50589. +#define mvOsTaskUnlock()
  50590. +#define strtol simple_strtoul
  50591. +#define mvOsDelay(x) mdelay(x)
  50592. +#define mvOsUDelay(x) udelay(x)
  50593. +#define mvCopyFromOs copy_from_user
  50594. +#define mvCopyToOs copy_to_user
  50595. +
  50596. +
  50597. +#include "mvTypes.h"
  50598. +#include "mvCommon.h"
  50599. +
  50600. +#ifdef MV_NDEBUG
  50601. +#define mvOsAssert(cond)
  50602. +#else
  50603. +#define mvOsAssert(cond) { do { if(!(cond)) { BUG(); } }while(0); }
  50604. +#endif /* MV_NDEBUG */
  50605. +
  50606. +#else /* __KERNEL__ */
  50607. +
  50608. +/* for user space applications */
  50609. +#include <stdlib.h>
  50610. +#include <stdio.h>
  50611. +#include <assert.h>
  50612. +#include <string.h>
  50613. +
  50614. +#define INLINE inline
  50615. +#define mvOsPrintf printf
  50616. +#define mvOsOutput printf
  50617. +#define mvOsMalloc(_size_) malloc(_size_)
  50618. +#define mvOsFree free
  50619. +#define mvOsAssert(cond) assert(cond)
  50620. +
  50621. +#endif /* __KERNEL__ */
  50622. +#define mvOsIoVirtToPhy(pDev, pVirtAddr) \
  50623. + pci_map_single( (pDev), (pVirtAddr), 0, PCI_DMA_BIDIRECTIONAL )
  50624. +
  50625. +#define mvOsCacheClear(pDev, p, size ) \
  50626. + pci_map_single( (pDev), (p), (size), PCI_DMA_BIDIRECTIONAL)
  50627. +
  50628. +#define mvOsCacheFlush(pDev, p, size ) \
  50629. + pci_map_single( (pDev), (p), (size), PCI_DMA_TODEVICE)
  50630. +
  50631. +#define mvOsCacheInvalidate(pDev, p, size) \
  50632. + pci_map_single( (pDev), (p), (size), PCI_DMA_FROMDEVICE )
  50633. +
  50634. +#define mvOsCacheUnmap(pDev, phys, size) \
  50635. + pci_unmap_single( (pDev), (dma_addr_t)(phys), (size), PCI_DMA_FROMDEVICE )
  50636. +
  50637. +
  50638. +#define CPU_PHY_MEM(x) (MV_U32)x
  50639. +#define CPU_MEMIO_CACHED_ADDR(x) (void*)x
  50640. +#define CPU_MEMIO_UNCACHED_ADDR(x) (void*)x
  50641. +
  50642. +
  50643. +/* CPU architecture dependent 32, 16, 8 bit read/write IO addresses */
  50644. +#define MV_MEMIO32_WRITE(addr, data) \
  50645. + ((*((volatile unsigned int*)(addr))) = ((unsigned int)(data)))
  50646. +
  50647. +#define MV_MEMIO32_READ(addr) \
  50648. + ((*((volatile unsigned int*)(addr))))
  50649. +
  50650. +#define MV_MEMIO16_WRITE(addr, data) \
  50651. + ((*((volatile unsigned short*)(addr))) = ((unsigned short)(data)))
  50652. +
  50653. +#define MV_MEMIO16_READ(addr) \
  50654. + ((*((volatile unsigned short*)(addr))))
  50655. +
  50656. +#define MV_MEMIO8_WRITE(addr, data) \
  50657. + ((*((volatile unsigned char*)(addr))) = ((unsigned char)(data)))
  50658. +
  50659. +#define MV_MEMIO8_READ(addr) \
  50660. + ((*((volatile unsigned char*)(addr))))
  50661. +
  50662. +
  50663. +/* No Fast Swap implementation (in assembler) for ARM */
  50664. +#define MV_32BIT_LE_FAST(val) MV_32BIT_LE(val)
  50665. +#define MV_16BIT_LE_FAST(val) MV_16BIT_LE(val)
  50666. +#define MV_32BIT_BE_FAST(val) MV_32BIT_BE(val)
  50667. +#define MV_16BIT_BE_FAST(val) MV_16BIT_BE(val)
  50668. +
  50669. +/* 32 and 16 bit read/write in big/little endian mode */
  50670. +
  50671. +/* 16bit write in little endian mode */
  50672. +#define MV_MEMIO_LE16_WRITE(addr, data) \
  50673. + MV_MEMIO16_WRITE(addr, MV_16BIT_LE_FAST(data))
  50674. +
  50675. +/* 16bit read in little endian mode */
  50676. +static __inline MV_U16 MV_MEMIO_LE16_READ(MV_U32 addr)
  50677. +{
  50678. + MV_U16 data;
  50679. +
  50680. + data= (MV_U16)MV_MEMIO16_READ(addr);
  50681. +
  50682. + return (MV_U16)MV_16BIT_LE_FAST(data);
  50683. +}
  50684. +
  50685. +/* 32bit write in little endian mode */
  50686. +#define MV_MEMIO_LE32_WRITE(addr, data) \
  50687. + MV_MEMIO32_WRITE(addr, MV_32BIT_LE_FAST(data))
  50688. +
  50689. +/* 32bit read in little endian mode */
  50690. +static __inline MV_U32 MV_MEMIO_LE32_READ(MV_U32 addr)
  50691. +{
  50692. + MV_U32 data;
  50693. +
  50694. + data= (MV_U32)MV_MEMIO32_READ(addr);
  50695. +
  50696. + return (MV_U32)MV_32BIT_LE_FAST(data);
  50697. +}
  50698. +
  50699. +static __inline void mvOsBCopy(char* srcAddr, char* dstAddr, int byteCount)
  50700. +{
  50701. + while(byteCount != 0)
  50702. + {
  50703. + *dstAddr = *srcAddr;
  50704. + dstAddr++;
  50705. + srcAddr++;
  50706. + byteCount--;
  50707. + }
  50708. +}
  50709. +
  50710. +static INLINE MV_U64 mvOsDivMod64(MV_U64 divided, MV_U64 divisor, MV_U64* modulu)
  50711. +{
  50712. + MV_U64 division = 0;
  50713. +
  50714. + if(divisor == 1)
  50715. + return divided;
  50716. +
  50717. + while(divided >= divisor)
  50718. + {
  50719. + division++;
  50720. + divided -= divisor;
  50721. + }
  50722. + if (modulu != NULL)
  50723. + *modulu = divided;
  50724. +
  50725. + return division;
  50726. +}
  50727. +
  50728. +#if defined(MV_BRIDGE_SYNC_REORDER)
  50729. +extern MV_U32 *mvUncachedParam;
  50730. +
  50731. +static __inline void mvOsBridgeReorderWA(void)
  50732. +{
  50733. + volatile MV_U32 val = 0;
  50734. +
  50735. + val = mvUncachedParam[0];
  50736. +}
  50737. +#endif
  50738. +
  50739. +
  50740. +/* Flash APIs */
  50741. +#define MV_FL_8_READ MV_MEMIO8_READ
  50742. +#define MV_FL_16_READ MV_MEMIO_LE16_READ
  50743. +#define MV_FL_32_READ MV_MEMIO_LE32_READ
  50744. +#define MV_FL_8_DATA_READ MV_MEMIO8_READ
  50745. +#define MV_FL_16_DATA_READ MV_MEMIO16_READ
  50746. +#define MV_FL_32_DATA_READ MV_MEMIO32_READ
  50747. +#define MV_FL_8_WRITE MV_MEMIO8_WRITE
  50748. +#define MV_FL_16_WRITE MV_MEMIO_LE16_WRITE
  50749. +#define MV_FL_32_WRITE MV_MEMIO_LE32_WRITE
  50750. +#define MV_FL_8_DATA_WRITE MV_MEMIO8_WRITE
  50751. +#define MV_FL_16_DATA_WRITE MV_MEMIO16_WRITE
  50752. +#define MV_FL_32_DATA_WRITE MV_MEMIO32_WRITE
  50753. +
  50754. +
  50755. +/* CPU cache information */
  50756. +#define CPU_I_CACHE_LINE_SIZE 32 /* 2do: replace 32 with linux core macro */
  50757. +#define CPU_D_CACHE_LINE_SIZE 32 /* 2do: replace 32 with linux core macro */
  50758. +
  50759. +#ifdef CONFIG_L2_CACHE_ENABLE
  50760. +/* Data cache flush one line */
  50761. +#define mvOsCacheLineFlushInv(handle, addr) \
  50762. +{ \
  50763. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c14, 1" : : "r" (addr));\
  50764. + __asm__ __volatile__ ("mcr p15, 1, %0, c15, c10, 1" : : "r" (addr));\
  50765. + __asm__ __volatile__ ("mcr p15, 0, r0, c7, c10, 4"); \
  50766. +}
  50767. +
  50768. +#else
  50769. +
  50770. +/* Data cache flush one line */
  50771. +#define mvOsCacheLineFlushInv(handle, addr) \
  50772. +{ \
  50773. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c14, 1" : : "r" (addr));\
  50774. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" : : "r" (addr)); \
  50775. +}
  50776. +#endif
  50777. +
  50778. +#ifdef CONFIG_L2_CACHE_ENABLE
  50779. +#define mvOsCacheLineInv(handle,addr) \
  50780. +{ \
  50781. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c6, 1" : : "r" (addr)); \
  50782. + __asm__ __volatile__ ("mcr p15, 1, %0, c15, c11, 1" : : "r" (addr)); \
  50783. +}
  50784. +#else
  50785. +#define mvOsCacheLineInv(handle,addr) \
  50786. +{ \
  50787. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c6, 1" : : "r" (addr)); \
  50788. +}
  50789. +#endif
  50790. +
  50791. +#ifdef CONFIG_L2_CACHE_ENABLE
  50792. +/* Data cache flush one line */
  50793. +#define mvOsCacheLineFlush(handle, addr) \
  50794. +{ \
  50795. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 1" : : "r" (addr));\
  50796. + __asm__ __volatile__ ("mcr p15, 1, %0, c15, c9, 1" : : "r" (addr));\
  50797. + __asm__ __volatile__ ("mcr p15, 0, r0, c7, c10, 4"); \
  50798. +}
  50799. +
  50800. +#else
  50801. +/* Data cache flush one line */
  50802. +#define mvOsCacheLineFlush(handle, addr) \
  50803. +{ \
  50804. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 1" : : "r" (addr));\
  50805. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" : : "r" (addr)); \
  50806. +}
  50807. +#endif
  50808. +
  50809. +static __inline void mvOsPrefetch(const void *ptr)
  50810. +{
  50811. +#ifdef CONFIG_USE_DSP
  50812. + __asm__ __volatile__(
  50813. + "pld\t%0"
  50814. + :
  50815. + : "o" (*(char *)ptr)
  50816. + : "cc");
  50817. +#else
  50818. + return;
  50819. +#endif
  50820. +}
  50821. +
  50822. +
  50823. +/* Flush CPU pipe */
  50824. +#define CPU_PIPE_FLUSH
  50825. +
  50826. +
  50827. +
  50828. +
  50829. +
  50830. +/* register manipulations */
  50831. +
  50832. +/******************************************************************************
  50833. +* This debug function enable the write of each register that u-boot access to
  50834. +* to an array in the DRAM, the function record only MV_REG_WRITE access.
  50835. +* The function could not be operate when booting from flash.
  50836. +* In order to print the array we use the printreg command.
  50837. +******************************************************************************/
  50838. +/* #define REG_DEBUG */
  50839. +#if defined(REG_DEBUG)
  50840. +extern int reg_arry[2048][2];
  50841. +extern int reg_arry_index;
  50842. +#endif
  50843. +
  50844. +/* Marvell controller register read/write macros */
  50845. +#define MV_REG_VALUE(offset) \
  50846. + (MV_MEMIO32_READ((INTER_REGS_BASE | (offset))))
  50847. +
  50848. +#define MV_REG_READ(offset) \
  50849. + (MV_MEMIO_LE32_READ(INTER_REGS_BASE | (offset)))
  50850. +
  50851. +#if defined(REG_DEBUG)
  50852. +#define MV_REG_WRITE(offset, val) \
  50853. + MV_MEMIO_LE32_WRITE((INTER_REGS_BASE | (offset)), (val)); \
  50854. + { \
  50855. + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
  50856. + reg_arry[reg_arry_index][1] = (val);\
  50857. + reg_arry_index++;\
  50858. + }
  50859. +#else
  50860. +#define MV_REG_WRITE(offset, val) \
  50861. + MV_MEMIO_LE32_WRITE((INTER_REGS_BASE | (offset)), (val));
  50862. +#endif
  50863. +
  50864. +#define MV_REG_BYTE_READ(offset) \
  50865. + (MV_MEMIO8_READ((INTER_REGS_BASE | (offset))))
  50866. +
  50867. +#if defined(REG_DEBUG)
  50868. +#define MV_REG_BYTE_WRITE(offset, val) \
  50869. + MV_MEMIO8_WRITE((INTER_REGS_BASE | (offset)), (val)); \
  50870. + { \
  50871. + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
  50872. + reg_arry[reg_arry_index][1] = (val);\
  50873. + reg_arry_index++;\
  50874. + }
  50875. +#else
  50876. +#define MV_REG_BYTE_WRITE(offset, val) \
  50877. + MV_MEMIO8_WRITE((INTER_REGS_BASE | (offset)), (val))
  50878. +#endif
  50879. +
  50880. +#if defined(REG_DEBUG)
  50881. +#define MV_REG_BIT_SET(offset, bitMask) \
  50882. + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
  50883. + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) | \
  50884. + MV_32BIT_LE_FAST(bitMask)))); \
  50885. + { \
  50886. + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
  50887. + reg_arry[reg_arry_index][1] = (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)));\
  50888. + reg_arry_index++;\
  50889. + }
  50890. +#else
  50891. +#define MV_REG_BIT_SET(offset, bitMask) \
  50892. + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
  50893. + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) | \
  50894. + MV_32BIT_LE_FAST(bitMask))))
  50895. +#endif
  50896. +
  50897. +#if defined(REG_DEBUG)
  50898. +#define MV_REG_BIT_RESET(offset,bitMask) \
  50899. + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
  50900. + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) & \
  50901. + MV_32BIT_LE_FAST(~bitMask)))); \
  50902. + { \
  50903. + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
  50904. + reg_arry[reg_arry_index][1] = (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)));\
  50905. + reg_arry_index++;\
  50906. + }
  50907. +#else
  50908. +#define MV_REG_BIT_RESET(offset,bitMask) \
  50909. + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
  50910. + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) & \
  50911. + MV_32BIT_LE_FAST(~bitMask))))
  50912. +#endif
  50913. +
  50914. +
  50915. +
  50916. +/* ARM architecture APIs */
  50917. +MV_U32 mvOsCpuRevGet (MV_VOID);
  50918. +MV_U32 mvOsCpuPartGet (MV_VOID);
  50919. +MV_U32 mvOsCpuArchGet (MV_VOID);
  50920. +MV_U32 mvOsCpuVarGet (MV_VOID);
  50921. +MV_U32 mvOsCpuAsciiGet (MV_VOID);
  50922. +
  50923. +/* Other APIs */
  50924. +void* mvOsIoCachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr, MV_U32 *memHandle);
  50925. +void* mvOsIoUncachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr, MV_U32 *memHandle );
  50926. +void mvOsIoUncachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr, MV_U32 memHandle );
  50927. +void mvOsIoCachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr, MV_U32 memHandle );
  50928. +int mvOsRand(void);
  50929. +
  50930. +#endif /* _MV_OS_LNX_H_ */
  50931. +
  50932. +
  50933. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h
  50934. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h 1970-01-01 01:00:00.000000000 +0100
  50935. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h 2010-08-05 22:02:23.454867934 +0200
  50936. @@ -0,0 +1,158 @@
  50937. +/*******************************************************************************
  50938. +Copyright (C) Marvell International Ltd. and its affiliates
  50939. +
  50940. +This software file (the "File") is owned and distributed by Marvell
  50941. +International Ltd. and/or its affiliates ("Marvell") under the following
  50942. +alternative licensing terms. Once you have made an election to distribute the
  50943. +File under one of the following license alternatives, please (i) delete this
  50944. +introductory statement regarding license alternatives, (ii) delete the two
  50945. +license alternatives that you have not elected to use and (iii) preserve the
  50946. +Marvell copyright notice above.
  50947. +
  50948. +
  50949. +********************************************************************************
  50950. +Marvell GPL License Option
  50951. +
  50952. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50953. +modify this File in accordance with the terms and conditions of the General
  50954. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  50955. +available along with the File in the license.txt file or by writing to the Free
  50956. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  50957. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  50958. +
  50959. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  50960. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  50961. +DISCLAIMED. The GPL License provides additional details about this warranty
  50962. +disclaimer.
  50963. +*******************************************************************************/
  50964. +/*******************************************************************************
  50965. +* mvOsLinux.h - O.S. interface header file for Linux
  50966. +*
  50967. +* DESCRIPTION:
  50968. +* This header file contains OS dependent definition under Linux
  50969. +*
  50970. +* DEPENDENCIES:
  50971. +* Linux kernel header files.
  50972. +*
  50973. +* FILE REVISION NUMBER:
  50974. +* $Revision: 1.1 $
  50975. +*******************************************************************************/
  50976. +
  50977. +#ifndef __INCmvOsLinuxh
  50978. +#define __INCmvOsLinuxh
  50979. +
  50980. +/* Includes */
  50981. +#include <linux/autoconf.h>
  50982. +#include <linux/module.h>
  50983. +#include <linux/types.h>
  50984. +#include <linux/string.h>
  50985. +#include <linux/kernel.h>
  50986. +#include <linux/timer.h>
  50987. +#include <linux/mm.h>
  50988. +#include <linux/interrupt.h>
  50989. +#include <linux/major.h>
  50990. +#include <linux/errno.h>
  50991. +#include <linux/genhd.h>
  50992. +#include <linux/slab.h>
  50993. +#include <linux/delay.h>
  50994. +#include <linux/ide.h>
  50995. +#include <linux/pci.h>
  50996. +
  50997. +#include <asm/byteorder.h>
  50998. +#include <asm/irq.h>
  50999. +#include <asm/uaccess.h>
  51000. +#include <asm/io.h>
  51001. +#include "mvOs.h"
  51002. +
  51003. +
  51004. +/* Definitions */
  51005. +#define MV_DEFAULT_QUEUE_DEPTH 2
  51006. +#define MV_SATA_SUPPORT_EDMA_SINGLE_DATA_REGION
  51007. +#define MV_SATA_SUPPORT_GEN2E_128_QUEUE_LEN
  51008. +
  51009. +#ifdef CONFIG_MV88F6082
  51010. + #define MV_SATA_OVERRIDE_SW_QUEUE_SIZE
  51011. + #define MV_SATA_REQUESTED_SW_QUEUE_SIZE 2
  51012. + #undef MV_SATA_SUPPORT_GEN2E_128_QUEUE_LEN
  51013. +#endif
  51014. +
  51015. +/* System dependent macro for flushing CPU write cache */
  51016. +#if defined (MV_BRIDGE_SYNC_REORDER)
  51017. +#define MV_CPU_WRITE_BUFFER_FLUSH() do { \
  51018. + wmb(); \
  51019. + mvOsBridgeReorderWA(); \
  51020. + } while (0)
  51021. +#else
  51022. +#define MV_CPU_WRITE_BUFFER_FLUSH() wmb()
  51023. +#endif /* CONFIG_MV78XX0 */
  51024. +
  51025. +/* System dependent little endian from / to CPU conversions */
  51026. +#define MV_CPU_TO_LE16(x) cpu_to_le16(x)
  51027. +#define MV_CPU_TO_LE32(x) cpu_to_le32(x)
  51028. +
  51029. +#define MV_LE16_TO_CPU(x) le16_to_cpu(x)
  51030. +#define MV_LE32_TO_CPU(x) le32_to_cpu(x)
  51031. +
  51032. +#ifdef __BIG_ENDIAN_BITFIELD
  51033. +#define MV_BIG_ENDIAN_BITFIELD
  51034. +#endif
  51035. +
  51036. +/* System dependent register read / write in byte/word/dword variants */
  51037. +#define MV_REG_WRITE_BYTE(base, offset, val) writeb(val, base + offset)
  51038. +#define MV_REG_WRITE_WORD(base, offset, val) writew(val, base + offset)
  51039. +#define MV_REG_WRITE_DWORD(base, offset, val) writel(val, base + offset)
  51040. +#define MV_REG_READ_BYTE(base, offset) readb(base + offset)
  51041. +#define MV_REG_READ_WORD(base, offset) readw(base + offset)
  51042. +#define MV_REG_READ_DWORD(base, offset) readl(base + offset)
  51043. +
  51044. +
  51045. +/* Typedefs */
  51046. +
  51047. +/* System dependant typedefs */
  51048. +typedef void *MV_VOID_PTR;
  51049. +typedef u32 *MV_U32_PTR;
  51050. +typedef u16 *MV_U16_PTR;
  51051. +typedef u8 *MV_U8_PTR;
  51052. +typedef char *MV_CHAR_PTR;
  51053. +typedef void *MV_BUS_ADDR_T;
  51054. +typedef unsigned long MV_CPU_FLAGS;
  51055. +
  51056. +
  51057. +/* Structures */
  51058. +/* System dependent structure */
  51059. +typedef struct mvOsSemaphore
  51060. +{
  51061. + int notUsed;
  51062. +} MV_OS_SEMAPHORE;
  51063. +
  51064. +
  51065. +/* Functions (User implemented)*/
  51066. +
  51067. +/* Semaphore init, take and release */
  51068. +#define mvOsSemInit(x) MV_TRUE
  51069. +#define mvOsSemTake(x)
  51070. +#define mvOsSemRelease(x)
  51071. +
  51072. +/* Interrupt masking and unmasking functions */
  51073. +MV_CPU_FLAGS mvOsSaveFlagsAndMaskCPUInterrupts(MV_VOID);
  51074. +MV_VOID mvOsRestoreFlags(MV_CPU_FLAGS);
  51075. +
  51076. +/* Delay function in micro seconds resolution */
  51077. +void mvMicroSecondsDelay(MV_VOID_PTR, MV_U32);
  51078. +
  51079. +/* Typedefs */
  51080. +typedef enum mvBoolean
  51081. +{
  51082. + MV_SFALSE, MV_STRUE
  51083. +} MV_BOOLEAN;
  51084. +
  51085. +/* System logging function */
  51086. +#include "mvLog.h"
  51087. +/* Enable READ/WRITE Long SCSI command only when driver is compiled for debugging */
  51088. +#ifdef MV_LOGGER
  51089. +#define MV_SATA_SUPPORT_READ_WRITE_LONG
  51090. +#endif
  51091. +
  51092. +#define MV_IAL_LOG_ID 3
  51093. +
  51094. +#endif /* __INCmvOsLinuxh */
  51095. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c
  51096. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c 1970-01-01 01:00:00.000000000 +0100
  51097. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c 2010-08-05 22:02:23.504867996 +0200
  51098. @@ -0,0 +1,376 @@
  51099. +/*******************************************************************************
  51100. +Copyright (C) Marvell International Ltd. and its affiliates
  51101. +
  51102. +This software file (the "File") is owned and distributed by Marvell
  51103. +International Ltd. and/or its affiliates ("Marvell") under the following
  51104. +alternative licensing terms. Once you have made an election to distribute the
  51105. +File under one of the following license alternatives, please (i) delete this
  51106. +introductory statement regarding license alternatives, (ii) delete the two
  51107. +license alternatives that you have not elected to use and (iii) preserve the
  51108. +Marvell copyright notice above.
  51109. +
  51110. +********************************************************************************
  51111. +Marvell Commercial License Option
  51112. +
  51113. +If you received this File from Marvell and you have entered into a commercial
  51114. +license agreement (a "Commercial License") with Marvell, the File is licensed
  51115. +to you under the terms of the applicable Commercial License.
  51116. +
  51117. +********************************************************************************
  51118. +Marvell GPL License Option
  51119. +
  51120. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51121. +modify this File in accordance with the terms and conditions of the General
  51122. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51123. +available along with the File in the license.txt file or by writing to the Free
  51124. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51125. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51126. +
  51127. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51128. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51129. +DISCLAIMED. The GPL License provides additional details about this warranty
  51130. +disclaimer.
  51131. +********************************************************************************
  51132. +Marvell BSD License Option
  51133. +
  51134. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51135. +modify this File under the following licensing terms.
  51136. +Redistribution and use in source and binary forms, with or without modification,
  51137. +are permitted provided that the following conditions are met:
  51138. +
  51139. + * Redistributions of source code must retain the above copyright notice,
  51140. + this list of conditions and the following disclaimer.
  51141. +
  51142. + * Redistributions in binary form must reproduce the above copyright
  51143. + notice, this list of conditions and the following disclaimer in the
  51144. + documentation and/or other materials provided with the distribution.
  51145. +
  51146. + * Neither the name of Marvell nor the names of its contributors may be
  51147. + used to endorse or promote products derived from this software without
  51148. + specific prior written permission.
  51149. +
  51150. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  51151. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  51152. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  51153. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  51154. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  51155. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  51156. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  51157. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  51158. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  51159. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  51160. +
  51161. +*******************************************************************************/
  51162. +
  51163. +#include "mvCntmr.h"
  51164. +#include "cpu/mvCpu.h"
  51165. +
  51166. +/* defines */
  51167. +#ifdef MV_DEBUG
  51168. + #define DB(x) x
  51169. +#else
  51170. + #define DB(x)
  51171. +#endif
  51172. +
  51173. +extern unsigned int whoAmI(void);
  51174. +
  51175. +/*******************************************************************************
  51176. +* mvCntmrLoad -
  51177. +*
  51178. +* DESCRIPTION:
  51179. +* Load an init Value to a given counter/timer
  51180. +*
  51181. +* INPUT:
  51182. +* countNum - counter number
  51183. +* value - value to be loaded
  51184. +*
  51185. +* OUTPUT:
  51186. +* None.
  51187. +*
  51188. +* RETURN:
  51189. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  51190. +*******************************************************************************/
  51191. +MV_STATUS mvCntmrLoad(MV_U32 countNum, MV_U32 value)
  51192. +{
  51193. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  51194. + {
  51195. +
  51196. + mvOsPrintf(("mvCntmrLoad: Err. Illigal counter number \n"));
  51197. + return MV_BAD_PARAM;;
  51198. +
  51199. + }
  51200. +
  51201. + MV_REG_WRITE(CNTMR_RELOAD_REG(countNum),value);
  51202. + MV_REG_WRITE(CNTMR_VAL_REG(countNum),value);
  51203. +
  51204. + return MV_OK;
  51205. +}
  51206. +
  51207. +/*******************************************************************************
  51208. +* mvCntmrRead -
  51209. +*
  51210. +* DESCRIPTION:
  51211. +* Returns the value of the given Counter/Timer
  51212. +*
  51213. +* INPUT:
  51214. +* countNum - counter number
  51215. +*
  51216. +* OUTPUT:
  51217. +* None.
  51218. +*
  51219. +* RETURN:
  51220. +* MV_U32 counter value
  51221. +*******************************************************************************/
  51222. +MV_U32 mvCntmrRead(MV_U32 countNum)
  51223. +{
  51224. + return MV_REG_READ(CNTMR_VAL_REG(countNum));
  51225. +}
  51226. +
  51227. +/*******************************************************************************
  51228. +* mvCntmrWrite -
  51229. +*
  51230. +* DESCRIPTION:
  51231. +* Returns the value of the given Counter/Timer
  51232. +*
  51233. +* INPUT:
  51234. +* countNum - counter number
  51235. +* countVal - value to write
  51236. +*
  51237. +* OUTPUT:
  51238. +* None.
  51239. +*
  51240. +* RETURN:
  51241. +* None
  51242. +*******************************************************************************/
  51243. +void mvCntmrWrite(MV_U32 countNum,MV_U32 countVal)
  51244. +{
  51245. + MV_REG_WRITE(CNTMR_VAL_REG(countNum),countVal);
  51246. +}
  51247. +
  51248. +/*******************************************************************************
  51249. +* mvCntmrCtrlSet -
  51250. +*
  51251. +* DESCRIPTION:
  51252. +* Set the Control to a given counter/timer
  51253. +*
  51254. +* INPUT:
  51255. +* countNum - counter number
  51256. +* pCtrl - pointer to MV_CNTMR_CTRL structure
  51257. +*
  51258. +* OUTPUT:
  51259. +* None.
  51260. +*
  51261. +* RETURN:
  51262. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  51263. +*******************************************************************************/
  51264. +MV_STATUS mvCntmrCtrlSet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl)
  51265. +{
  51266. + MV_U32 cntmrCtrl;
  51267. +
  51268. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  51269. + {
  51270. +
  51271. + DB(mvOsPrintf(("mvCntmrCtrlSet: Err. Illigal counter number \n")));
  51272. + return MV_BAD_PARAM;;
  51273. +
  51274. + }
  51275. +
  51276. + /* read control register */
  51277. + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
  51278. +
  51279. +
  51280. + if (pCtrl->enable) /* enable counter\timer */
  51281. + {
  51282. + cntmrCtrl |= CTCR_ARM_TIMER_EN(countNum);
  51283. + }
  51284. + else /* disable counter\timer */
  51285. + {
  51286. + cntmrCtrl &= ~CTCR_ARM_TIMER_EN(countNum);
  51287. + }
  51288. +
  51289. + if ( pCtrl->autoEnable ) /* Auto mode */
  51290. + {
  51291. + cntmrCtrl |= CTCR_ARM_TIMER_AUTO_EN(countNum);
  51292. +
  51293. + }
  51294. + else /* no auto mode */
  51295. + {
  51296. + cntmrCtrl &= ~CTCR_ARM_TIMER_AUTO_EN(countNum);
  51297. + }
  51298. +
  51299. + MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);
  51300. +
  51301. + return MV_OK;
  51302. +
  51303. +}
  51304. +
  51305. +/*******************************************************************************
  51306. +* mvCntmrCtrlGet -
  51307. +*
  51308. +* DESCRIPTION:
  51309. +* Get the Control value of a given counter/timer
  51310. +*
  51311. +* INPUT:
  51312. +* countNum - counter number
  51313. +* pCtrl - pointer to MV_CNTMR_CTRL structure
  51314. +*
  51315. +* OUTPUT:
  51316. +* Counter\Timer control value
  51317. +*
  51318. +* RETURN:
  51319. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  51320. +*******************************************************************************/
  51321. +MV_STATUS mvCntmrCtrlGet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl)
  51322. +{
  51323. + MV_U32 cntmrCtrl;
  51324. +
  51325. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  51326. + {
  51327. + DB(mvOsPrintf(("mvCntmrCtrlGet: Err. Illigal counter number \n")));
  51328. + return MV_BAD_PARAM;;
  51329. + }
  51330. +
  51331. + /* read control register */
  51332. + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
  51333. +
  51334. + /* enable counter\timer */
  51335. + if (cntmrCtrl & CTCR_ARM_TIMER_EN(countNum))
  51336. + {
  51337. + pCtrl->enable = MV_TRUE;
  51338. + }
  51339. + else
  51340. + {
  51341. + pCtrl->enable = MV_FALSE;
  51342. + }
  51343. +
  51344. + /* counter mode */
  51345. + if (cntmrCtrl & CTCR_ARM_TIMER_AUTO_EN(countNum))
  51346. + {
  51347. + pCtrl->autoEnable = MV_TRUE;
  51348. + }
  51349. + else
  51350. + {
  51351. + pCtrl->autoEnable = MV_FALSE;
  51352. + }
  51353. +
  51354. + return MV_OK;
  51355. +}
  51356. +
  51357. +/*******************************************************************************
  51358. +* mvCntmrEnable -
  51359. +*
  51360. +* DESCRIPTION:
  51361. +* Set the Enable-Bit to logic '1' ==> starting the counter
  51362. +*
  51363. +* INPUT:
  51364. +* countNum - counter number
  51365. +*
  51366. +* OUTPUT:
  51367. +* None.
  51368. +*
  51369. +* RETURN:
  51370. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  51371. +*******************************************************************************/
  51372. +MV_STATUS mvCntmrEnable(MV_U32 countNum)
  51373. +{
  51374. + MV_U32 cntmrCtrl;
  51375. +
  51376. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  51377. + {
  51378. +
  51379. + DB(mvOsPrintf(("mvCntmrEnable: Err. Illigal counter number \n")));
  51380. + return MV_BAD_PARAM;;
  51381. +
  51382. + }
  51383. +
  51384. + /* read control register */
  51385. + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
  51386. +
  51387. + /* enable counter\timer */
  51388. + cntmrCtrl |= CTCR_ARM_TIMER_EN(countNum);
  51389. +
  51390. +
  51391. + MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);
  51392. +
  51393. + return MV_OK;
  51394. +}
  51395. +
  51396. +/*******************************************************************************
  51397. +* mvCntmrDisable -
  51398. +*
  51399. +* DESCRIPTION:
  51400. +* Stop the counter/timer running, and returns its Value
  51401. +*
  51402. +* INPUT:
  51403. +* countNum - counter number
  51404. +*
  51405. +* OUTPUT:
  51406. +* None.
  51407. +*
  51408. +* RETURN:
  51409. +* MV_U32 counter\timer value
  51410. +*******************************************************************************/
  51411. +MV_STATUS mvCntmrDisable(MV_U32 countNum)
  51412. +{
  51413. + MV_U32 cntmrCtrl;
  51414. +
  51415. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  51416. + {
  51417. +
  51418. + DB(mvOsPrintf(("mvCntmrDisable: Err. Illigal counter number \n")));
  51419. + return MV_BAD_PARAM;;
  51420. +
  51421. + }
  51422. +
  51423. + /* read control register */
  51424. + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
  51425. +
  51426. + /* disable counter\timer */
  51427. + cntmrCtrl &= ~CTCR_ARM_TIMER_EN(countNum);
  51428. +
  51429. + MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);
  51430. +
  51431. + return MV_OK;
  51432. +}
  51433. +
  51434. +/*******************************************************************************
  51435. +* mvCntmrStart -
  51436. +*
  51437. +* DESCRIPTION:
  51438. +* Combined all the sub-operations above to one function: Load,setMode,Enable
  51439. +*
  51440. +* INPUT:
  51441. +* countNum - counter number
  51442. +* value - value of the counter\timer to be set
  51443. +* pCtrl - pointer to MV_CNTMR_CTRL structure
  51444. +*
  51445. +* OUTPUT:
  51446. +* None.
  51447. +*
  51448. +* RETURN:
  51449. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  51450. +*******************************************************************************/
  51451. +MV_STATUS mvCntmrStart(MV_U32 countNum, MV_U32 value,
  51452. + MV_CNTMR_CTRL *pCtrl)
  51453. +{
  51454. +
  51455. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  51456. + {
  51457. +
  51458. + mvOsPrintf(("mvCntmrDisable: Err. Illigal counter number \n"));
  51459. + return MV_BAD_PARAM;;
  51460. +
  51461. + }
  51462. +
  51463. + /* load value onto counter\timer */
  51464. + mvCntmrLoad(countNum,value);
  51465. +
  51466. + /* set the counter to load in the first time */
  51467. + mvCntmrWrite(countNum,value);
  51468. +
  51469. + /* set control for timer \ cunter and enable */
  51470. + mvCntmrCtrlSet(countNum,pCtrl);
  51471. +
  51472. + return MV_OK;
  51473. +}
  51474. +
  51475. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h
  51476. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h 1970-01-01 01:00:00.000000000 +0100
  51477. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h 2010-08-05 22:02:23.694867951 +0200
  51478. @@ -0,0 +1,121 @@
  51479. +/*******************************************************************************
  51480. +Copyright (C) Marvell International Ltd. and its affiliates
  51481. +
  51482. +This software file (the "File") is owned and distributed by Marvell
  51483. +International Ltd. and/or its affiliates ("Marvell") under the following
  51484. +alternative licensing terms. Once you have made an election to distribute the
  51485. +File under one of the following license alternatives, please (i) delete this
  51486. +introductory statement regarding license alternatives, (ii) delete the two
  51487. +license alternatives that you have not elected to use and (iii) preserve the
  51488. +Marvell copyright notice above.
  51489. +
  51490. +********************************************************************************
  51491. +Marvell Commercial License Option
  51492. +
  51493. +If you received this File from Marvell and you have entered into a commercial
  51494. +license agreement (a "Commercial License") with Marvell, the File is licensed
  51495. +to you under the terms of the applicable Commercial License.
  51496. +
  51497. +********************************************************************************
  51498. +Marvell GPL License Option
  51499. +
  51500. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51501. +modify this File in accordance with the terms and conditions of the General
  51502. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51503. +available along with the File in the license.txt file or by writing to the Free
  51504. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51505. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51506. +
  51507. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51508. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51509. +DISCLAIMED. The GPL License provides additional details about this warranty
  51510. +disclaimer.
  51511. +********************************************************************************
  51512. +Marvell BSD License Option
  51513. +
  51514. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51515. +modify this File under the following licensing terms.
  51516. +Redistribution and use in source and binary forms, with or without modification,
  51517. +are permitted provided that the following conditions are met:
  51518. +
  51519. + * Redistributions of source code must retain the above copyright notice,
  51520. + this list of conditions and the following disclaimer.
  51521. +
  51522. + * Redistributions in binary form must reproduce the above copyright
  51523. + notice, this list of conditions and the following disclaimer in the
  51524. + documentation and/or other materials provided with the distribution.
  51525. +
  51526. + * Neither the name of Marvell nor the names of its contributors may be
  51527. + used to endorse or promote products derived from this software without
  51528. + specific prior written permission.
  51529. +
  51530. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  51531. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  51532. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  51533. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  51534. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  51535. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  51536. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  51537. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  51538. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  51539. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  51540. +
  51541. +*******************************************************************************/
  51542. +
  51543. +#ifndef __INCmvTmrWtdgh
  51544. +#define __INCmvTmrWtdgh
  51545. +
  51546. +/* includes */
  51547. +#include "mvCommon.h"
  51548. +#include "mvOs.h"
  51549. +#include "cntmr/mvCntmrRegs.h"
  51550. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  51551. +
  51552. +
  51553. +/* This enumerator describe counters\watchdog numbers */
  51554. +typedef enum _mvCntmrID
  51555. +{
  51556. + TIMER0 = 0,
  51557. + TIMER1,
  51558. + WATCHDOG,
  51559. + TIMER2,
  51560. + TIMER3,
  51561. +}MV_CNTMR_ID;
  51562. +
  51563. +
  51564. +/* Counter / Timer control structure */
  51565. +typedef struct _mvCntmrCtrl
  51566. +{
  51567. + MV_BOOL enable; /* enable */
  51568. + MV_BOOL autoEnable; /* counter/Timer */
  51569. +}MV_CNTMR_CTRL;
  51570. +
  51571. +
  51572. +/* Functions */
  51573. +
  51574. +/* Load an init Value to a given counter/timer */
  51575. +MV_STATUS mvCntmrLoad(MV_U32 countNum, MV_U32 value);
  51576. +
  51577. +/* Returns the value of the given Counter/Timer */
  51578. +MV_U32 mvCntmrRead(MV_U32 countNum);
  51579. +
  51580. +/* Write a value of the given Counter/Timer */
  51581. +void mvCntmrWrite(MV_U32 countNum,MV_U32 countVal);
  51582. +
  51583. +/* Set the Control to a given counter/timer */
  51584. +MV_STATUS mvCntmrCtrlSet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl);
  51585. +
  51586. +/* Get the value of a given counter/timer */
  51587. +MV_STATUS mvCntmrCtrlGet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl);
  51588. +
  51589. +/* Set the Enable-Bit to logic '1' ==> starting the counter. */
  51590. +MV_STATUS mvCntmrEnable(MV_U32 countNum);
  51591. +
  51592. +/* Stop the counter/timer running, and returns its Value. */
  51593. +MV_STATUS mvCntmrDisable(MV_U32 countNum);
  51594. +
  51595. +/* Combined all the sub-operations above to one function: Load,setMode,Enable */
  51596. +MV_STATUS mvCntmrStart(MV_U32 countNum, MV_U32 value,
  51597. + MV_CNTMR_CTRL *pCtrl);
  51598. +
  51599. +#endif /* __INCmvTmrWtdgh */
  51600. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h
  51601. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h 1970-01-01 01:00:00.000000000 +0100
  51602. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h 2010-08-05 22:02:23.744868285 +0200
  51603. @@ -0,0 +1,121 @@
  51604. +/*******************************************************************************
  51605. +Copyright (C) Marvell International Ltd. and its affiliates
  51606. +
  51607. +This software file (the "File") is owned and distributed by Marvell
  51608. +International Ltd. and/or its affiliates ("Marvell") under the following
  51609. +alternative licensing terms. Once you have made an election to distribute the
  51610. +File under one of the following license alternatives, please (i) delete this
  51611. +introductory statement regarding license alternatives, (ii) delete the two
  51612. +license alternatives that you have not elected to use and (iii) preserve the
  51613. +Marvell copyright notice above.
  51614. +
  51615. +********************************************************************************
  51616. +Marvell Commercial License Option
  51617. +
  51618. +If you received this File from Marvell and you have entered into a commercial
  51619. +license agreement (a "Commercial License") with Marvell, the File is licensed
  51620. +to you under the terms of the applicable Commercial License.
  51621. +
  51622. +********************************************************************************
  51623. +Marvell GPL License Option
  51624. +
  51625. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51626. +modify this File in accordance with the terms and conditions of the General
  51627. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51628. +available along with the File in the license.txt file or by writing to the Free
  51629. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51630. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51631. +
  51632. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51633. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51634. +DISCLAIMED. The GPL License provides additional details about this warranty
  51635. +disclaimer.
  51636. +********************************************************************************
  51637. +Marvell BSD License Option
  51638. +
  51639. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51640. +modify this File under the following licensing terms.
  51641. +Redistribution and use in source and binary forms, with or without modification,
  51642. +are permitted provided that the following conditions are met:
  51643. +
  51644. + * Redistributions of source code must retain the above copyright notice,
  51645. + this list of conditions and the following disclaimer.
  51646. +
  51647. + * Redistributions in binary form must reproduce the above copyright
  51648. + notice, this list of conditions and the following disclaimer in the
  51649. + documentation and/or other materials provided with the distribution.
  51650. +
  51651. + * Neither the name of Marvell nor the names of its contributors may be
  51652. + used to endorse or promote products derived from this software without
  51653. + specific prior written permission.
  51654. +
  51655. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  51656. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  51657. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  51658. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  51659. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  51660. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  51661. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  51662. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  51663. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  51664. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  51665. +
  51666. +*******************************************************************************/
  51667. +
  51668. +#ifndef __INCmvTmrwtdgRegsh
  51669. +#define __INCmvTmrwtdgRegsh
  51670. +
  51671. +/*******************************************/
  51672. +/* ARM Timers Registers Map */
  51673. +/*******************************************/
  51674. +
  51675. +#define CNTMR_RELOAD_REG(tmrNum) (CNTMR_BASE + 0x10 + (tmrNum)*8 + \
  51676. + (((tmrNum) <= 3)?0:8))
  51677. +#define CNTMR_VAL_REG(tmrNum) (CNTMR_BASE + 0x14 + (tmrNum)*8 + \
  51678. + (((tmrNum) <= 3)?0:8))
  51679. +#define CNTMR_CTRL_REG (CNTMR_BASE)
  51680. +
  51681. +/*For MV78XX0*/
  51682. +#define CNTMR_CAUSE_REG (CPU_AHB_MBUS_CAUSE_INT_REG(whoAmI()))
  51683. +#define CNTMR_MASK_REG (CPU_AHB_MBUS_MASK_INT_REG(whoAmI()))
  51684. +
  51685. +/* ARM Timers Registers Map */
  51686. +/*******************************************/
  51687. +
  51688. +
  51689. +/* ARM Timers Control Register */
  51690. +/* CPU_TIMERS_CTRL_REG (CTCR) */
  51691. +
  51692. +#define TIMER0_NUM 0
  51693. +#define TIMER1_NUM 1
  51694. +#define WATCHDOG_NUM 2
  51695. +#define TIMER2_NUM 3
  51696. +#define TIMER3_NUM 4
  51697. +
  51698. +#define CTCR_ARM_TIMER_EN_OFFS(cntr) (cntr * 2)
  51699. +#define CTCR_ARM_TIMER_EN_MASK(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS)
  51700. +#define CTCR_ARM_TIMER_EN(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS(cntr))
  51701. +#define CTCR_ARM_TIMER_DIS(cntr) (0 << CTCR_ARM_TIMER_EN_OFFS(cntr))
  51702. +
  51703. +#define CTCR_ARM_TIMER_AUTO_OFFS(cntr) ((cntr * 2) + 1)
  51704. +#define CTCR_ARM_TIMER_AUTO_MASK(cntr) BIT1
  51705. +#define CTCR_ARM_TIMER_AUTO_EN(cntr) (1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
  51706. +#define CTCR_ARM_TIMER_AUTO_DIS(cntr) (0 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
  51707. +
  51708. +
  51709. +/* ARM Timer\Watchdog Reload Register */
  51710. +/* CNTMR_RELOAD_REG (TRR) */
  51711. +
  51712. +#define TRG_ARM_TIMER_REL_OFFS 0
  51713. +#define TRG_ARM_TIMER_REL_MASK 0xffffffff
  51714. +
  51715. +/* ARM Timer\Watchdog Register */
  51716. +/* CNTMR_VAL_REG (TVRG) */
  51717. +
  51718. +#define TVR_ARM_TIMER_OFFS 0
  51719. +#define TVR_ARM_TIMER_MASK 0xffffffff
  51720. +#define TVR_ARM_TIMER_MAX 0xffffffff
  51721. +
  51722. +
  51723. +
  51724. +#endif /* __INCmvTmrwtdgRegsh */
  51725. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c
  51726. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c 1970-01-01 01:00:00.000000000 +0100
  51727. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c 2010-08-05 22:02:23.784868241 +0200
  51728. @@ -0,0 +1,207 @@
  51729. +/*
  51730. + * This program is free software; you can redistribute it and/or modify
  51731. + * it under the terms of the GNU General Public License as published by
  51732. + * the Free Software Foundation; either version 2 of the License, or
  51733. + * (at your option) any later version.
  51734. + *
  51735. + * This program is distributed in the hope that it will be useful,
  51736. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  51737. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  51738. + * GNU General Public License for more details.
  51739. + *
  51740. + * You should have received a copy of the GNU General Public License
  51741. + * along with this program; if not, write to the Free Software
  51742. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  51743. + */
  51744. +
  51745. +#include "mvOs.h"
  51746. +#include "mvCpuCntrs.h"
  51747. +
  51748. +
  51749. +const static MV_CPU_CNTRS_OPS mvCpuCntrsOpsTbl[MV_CPU_CNTRS_NUM][MV_CPU_CNTRS_OPS_NUM] =
  51750. +{
  51751. + /*0*/
  51752. + {
  51753. + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_DCACHE_READ_HIT, MV_CPU_CNTRS_DCACHE_READ_MISS,
  51754. + MV_CPU_CNTRS_DCACHE_WRITE_HIT, MV_CPU_CNTRS_DCACHE_WRITE_MISS, MV_CPU_CNTRS_INSTRUCTIONS,
  51755. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  51756. + MV_CPU_CNTRS_MMU_READ_LATENCY, MV_CPU_CNTRS_ICACHE_READ_LATENCY, MV_CPU_CNTRS_WB_WRITE_LATENCY,
  51757. + MV_CPU_CNTRS_LDM_STM_HOLD, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  51758. + MV_CPU_CNTRS_DATA_WRITE_ACCESS, MV_CPU_CNTRS_DATA_READ_ACCESS, MV_CPU_CNTRS_INVALID,
  51759. + MV_CPU_CNTRS_BRANCH_PREDICT_COUNT,
  51760. + },
  51761. + /*1*/
  51762. + {
  51763. + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_ICACHE_READ_MISS, MV_CPU_CNTRS_DCACHE_READ_MISS,
  51764. + MV_CPU_CNTRS_DCACHE_WRITE_MISS, MV_CPU_CNTRS_ITLB_MISS, MV_CPU_CNTRS_SINGLE_ISSUE,
  51765. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BRANCH_RETIRED, MV_CPU_CNTRS_INVALID,
  51766. + MV_CPU_CNTRS_MMU_READ_BEAT, MV_CPU_CNTRS_ICACHE_READ_LATENCY, MV_CPU_CNTRS_WB_WRITE_BEAT,
  51767. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_IS_HOLD, MV_CPU_CNTRS_DATA_READ_ACCESS,
  51768. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  51769. + MV_CPU_CNTRS_INVALID,
  51770. + },
  51771. + /*2*/
  51772. + {
  51773. + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DCACHE_ACCESS,
  51774. + MV_CPU_CNTRS_DTLB_MISS, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  51775. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BRANCH_PREDICT_MISS, MV_CPU_CNTRS_WB_WRITE_BEAT,
  51776. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DCACHE_READ_LATENCY, MV_CPU_CNTRS_DCACHE_WRITE_LATENCY,
  51777. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BIU_SIMULT_ACCESS,
  51778. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  51779. + MV_CPU_CNTRS_INVALID,
  51780. + },
  51781. + /*3*/
  51782. + {
  51783. + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_DCACHE_READ_MISS, MV_CPU_CNTRS_DCACHE_WRITE_MISS,
  51784. + MV_CPU_CNTRS_TLB_MISS, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  51785. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BRANCH_TAKEN, MV_CPU_CNTRS_WB_FULL_CYCLES,
  51786. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DCACHE_READ_BEAT, MV_CPU_CNTRS_DCACHE_WRITE_BEAT,
  51787. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BIU_ANY_ACCESS,
  51788. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DATA_WRITE_ACCESS,
  51789. + MV_CPU_CNTRS_INVALID,
  51790. + }
  51791. +};
  51792. +
  51793. +MV_CPU_CNTRS_ENTRY mvCpuCntrsTbl[MV_CPU_CNTRS_NUM];
  51794. +
  51795. +MV_CPU_CNTRS_EVENT* mvCpuCntrsEventTbl[128];
  51796. +
  51797. +void mvCpuCntrsReset(void)
  51798. +{
  51799. + MV_U32 reg = 0;
  51800. +
  51801. + MV_ASM ("mcr p15, 0, %0, c15, c13, 0" : : "r" (reg));
  51802. + MV_ASM ("mcr p15, 0, %0, c15, c13, 1" : : "r" (reg));
  51803. + MV_ASM ("mcr p15, 0, %0, c15, c13, 2" : : "r" (reg));
  51804. + MV_ASM ("mcr p15, 0, %0, c15, c13, 3" : : "r" (reg));
  51805. + MV_ASM ("mcr p15, 0, %0, c15, c13, 4" : : "r" (reg));
  51806. + MV_ASM ("mcr p15, 0, %0, c15, c13, 5" : : "r" (reg));
  51807. + MV_ASM ("mcr p15, 0, %0, c15, c13, 6" : : "r" (reg));
  51808. + MV_ASM ("mcr p15, 0, %0, c15, c13, 7" : : "r" (reg));
  51809. +}
  51810. +
  51811. +void program_counter(int counter, int op)
  51812. +{
  51813. + MV_U32 reg = (1 << op) | 0x1; /*enable*/
  51814. +
  51815. + switch(counter)
  51816. + {
  51817. + case 0:
  51818. + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 0" : : "r" (reg));
  51819. + return;
  51820. +
  51821. + case 1:
  51822. + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 1" : : "r" (reg));
  51823. + return;
  51824. +
  51825. + case 2:
  51826. + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 2" : : "r" (reg));
  51827. + return;
  51828. +
  51829. + case 3:
  51830. + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 3" : : "r" (reg));
  51831. + return;
  51832. +
  51833. + default:
  51834. + mvOsPrintf("error in program_counter: bad counter number (%d)\n", counter);
  51835. + }
  51836. + return;
  51837. +}
  51838. +
  51839. +void mvCpuCntrsEventClear(MV_CPU_CNTRS_EVENT* pEvent)
  51840. +{
  51841. + int i;
  51842. +
  51843. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  51844. + {
  51845. + pEvent->counters_sum[i] = 0;
  51846. + }
  51847. + pEvent->num_of_measurements = 0;
  51848. +}
  51849. +
  51850. +
  51851. +MV_CPU_CNTRS_EVENT* mvCpuCntrsEventCreate(char* name, MV_U32 print_threshold)
  51852. +{
  51853. + int i;
  51854. + MV_CPU_CNTRS_EVENT* event = mvOsMalloc(sizeof(MV_CPU_CNTRS_EVENT));
  51855. +
  51856. + if(event)
  51857. + {
  51858. + strncpy(event->name, name, sizeof(event->name));
  51859. + event->num_of_measurements = 0;
  51860. + event->avg_sample_count = print_threshold;
  51861. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  51862. + {
  51863. + event->counters_before[i] = 0;
  51864. + event->counters_after[i] = 0;
  51865. + event->counters_sum[i] = 0;
  51866. + }
  51867. + }
  51868. + return event;
  51869. +}
  51870. +
  51871. +void mvCpuCntrsEventDelete(MV_CPU_CNTRS_EVENT* event)
  51872. +{
  51873. + if(event != NULL)
  51874. + mvOsFree(event);
  51875. +}
  51876. +
  51877. +
  51878. +MV_STATUS mvCpuCntrsProgram(int counter, MV_CPU_CNTRS_OPS op,
  51879. + char* name, MV_U32 overhead)
  51880. +{
  51881. + int i;
  51882. +
  51883. + /* Find required operations */
  51884. + for(i=0; i<MV_CPU_CNTRS_OPS_NUM; i++)
  51885. + {
  51886. + if( mvCpuCntrsOpsTbl[counter][i] == op)
  51887. + {
  51888. + strncpy(mvCpuCntrsTbl[counter].name, name, sizeof(mvCpuCntrsTbl[counter].name));
  51889. + mvCpuCntrsTbl[counter].operation = op;
  51890. + mvCpuCntrsTbl[counter].opIdx = i+1;
  51891. + mvCpuCntrsTbl[counter].overhead = overhead;
  51892. + program_counter(counter, mvCpuCntrsTbl[counter].opIdx);
  51893. + mvOsPrintf("Counter=%d, opIdx=%d, overhead=%d\n",
  51894. + counter, mvCpuCntrsTbl[counter].opIdx, mvCpuCntrsTbl[counter].overhead);
  51895. + return MV_OK;
  51896. + }
  51897. + }
  51898. + return MV_NOT_FOUND;
  51899. +}
  51900. +
  51901. +void mvCpuCntrsShow(MV_CPU_CNTRS_EVENT* pEvent)
  51902. +{
  51903. + int i;
  51904. + MV_U64 counters_avg;
  51905. +
  51906. + if(pEvent->num_of_measurements < pEvent->avg_sample_count)
  51907. + return;
  51908. +
  51909. + mvOsPrintf("%16s: ", pEvent->name);
  51910. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  51911. + {
  51912. + counters_avg = mvOsDivMod64(pEvent->counters_sum[i],
  51913. + pEvent->num_of_measurements, NULL);
  51914. + if(counters_avg >= mvCpuCntrsTbl[i].overhead)
  51915. + counters_avg -= mvCpuCntrsTbl[i].overhead;
  51916. + else
  51917. + counters_avg = 0;
  51918. +
  51919. + mvOsPrintf("%s=%5llu, ", mvCpuCntrsTbl[i].name, counters_avg);
  51920. + }
  51921. + mvOsPrintf("\n");
  51922. + mvCpuCntrsEventClear(pEvent);
  51923. + mvCpuCntrsReset();
  51924. +}
  51925. +
  51926. +void mvCpuCntrsStatus(void)
  51927. +{
  51928. + int i;
  51929. +
  51930. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  51931. + {
  51932. + mvOsPrintf("#%d: %s, overhead=%d\n",
  51933. + i, mvCpuCntrsTbl[i].name, mvCpuCntrsTbl[i].overhead);
  51934. + }
  51935. +}
  51936. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h
  51937. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h 1970-01-01 01:00:00.000000000 +0100
  51938. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h 2010-08-05 22:02:23.834868231 +0200
  51939. @@ -0,0 +1,213 @@
  51940. +/*******************************************************************************
  51941. +Copyright (C) Marvell International Ltd. and its affiliates
  51942. +
  51943. +This software file (the "File") is owned and distributed by Marvell
  51944. +International Ltd. and/or its affiliates ("Marvell") under the following
  51945. +alternative licensing terms. Once you have made an election to distribute the
  51946. +File under one of the following license alternatives, please (i) delete this
  51947. +introductory statement regarding license alternatives, (ii) delete the two
  51948. +license alternatives that you have not elected to use and (iii) preserve the
  51949. +Marvell copyright notice above.
  51950. +
  51951. +
  51952. +********************************************************************************
  51953. +Marvell GPL License Option
  51954. +
  51955. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51956. +modify this File in accordance with the terms and conditions of the General
  51957. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51958. +available along with the File in the license.txt file or by writing to the Free
  51959. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51960. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51961. +
  51962. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51963. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51964. +DISCLAIMED. The GPL License provides additional details about this warranty
  51965. +disclaimer.
  51966. +*******************************************************************************/
  51967. +#ifndef __mvCpuCntrs_h__
  51968. +#define __mvCpuCntrs_h__
  51969. +
  51970. +#include "mvTypes.h"
  51971. +#include "mvOs.h"
  51972. +
  51973. +
  51974. +#define MV_CPU_CNTRS_NUM 4
  51975. +#define MV_CPU_CNTRS_OPS_NUM 32
  51976. +
  51977. +typedef enum
  51978. +{
  51979. + MV_CPU_CNTRS_INVALID = 0,
  51980. + MV_CPU_CNTRS_CYCLES,
  51981. + MV_CPU_CNTRS_ICACHE_READ_MISS,
  51982. + MV_CPU_CNTRS_DCACHE_ACCESS,
  51983. + MV_CPU_CNTRS_DCACHE_READ_MISS,
  51984. + MV_CPU_CNTRS_DCACHE_READ_HIT,
  51985. + MV_CPU_CNTRS_DCACHE_WRITE_MISS,
  51986. + MV_CPU_CNTRS_DCACHE_WRITE_HIT,
  51987. + MV_CPU_CNTRS_DTLB_MISS,
  51988. + MV_CPU_CNTRS_TLB_MISS,
  51989. + MV_CPU_CNTRS_ITLB_MISS,
  51990. + MV_CPU_CNTRS_INSTRUCTIONS,
  51991. + MV_CPU_CNTRS_SINGLE_ISSUE,
  51992. + MV_CPU_CNTRS_MMU_READ_LATENCY,
  51993. + MV_CPU_CNTRS_MMU_READ_BEAT,
  51994. + MV_CPU_CNTRS_BRANCH_RETIRED,
  51995. + MV_CPU_CNTRS_BRANCH_TAKEN,
  51996. + MV_CPU_CNTRS_BRANCH_PREDICT_MISS,
  51997. + MV_CPU_CNTRS_BRANCH_PREDICT_COUNT,
  51998. + MV_CPU_CNTRS_WB_FULL_CYCLES,
  51999. + MV_CPU_CNTRS_WB_WRITE_LATENCY,
  52000. + MV_CPU_CNTRS_WB_WRITE_BEAT,
  52001. + MV_CPU_CNTRS_ICACHE_READ_LATENCY,
  52002. + MV_CPU_CNTRS_ICACHE_READ_BEAT,
  52003. + MV_CPU_CNTRS_DCACHE_READ_LATENCY,
  52004. + MV_CPU_CNTRS_DCACHE_READ_BEAT,
  52005. + MV_CPU_CNTRS_DCACHE_WRITE_LATENCY,
  52006. + MV_CPU_CNTRS_DCACHE_WRITE_BEAT,
  52007. + MV_CPU_CNTRS_LDM_STM_HOLD,
  52008. + MV_CPU_CNTRS_IS_HOLD,
  52009. + MV_CPU_CNTRS_DATA_WRITE_ACCESS,
  52010. + MV_CPU_CNTRS_DATA_READ_ACCESS,
  52011. + MV_CPU_CNTRS_BIU_SIMULT_ACCESS,
  52012. + MV_CPU_CNTRS_BIU_ANY_ACCESS,
  52013. +
  52014. +} MV_CPU_CNTRS_OPS;
  52015. +
  52016. +typedef struct
  52017. +{
  52018. + char name[16];
  52019. + MV_CPU_CNTRS_OPS operation;
  52020. + int opIdx;
  52021. + MV_U32 overhead;
  52022. +
  52023. +} MV_CPU_CNTRS_ENTRY;
  52024. +
  52025. +
  52026. +typedef struct
  52027. +{
  52028. + char name[16];
  52029. + MV_U32 num_of_measurements;
  52030. + MV_U32 avg_sample_count;
  52031. + MV_U64 counters_before[MV_CPU_CNTRS_NUM];
  52032. + MV_U64 counters_after[MV_CPU_CNTRS_NUM];
  52033. + MV_U64 counters_sum[MV_CPU_CNTRS_NUM];
  52034. +
  52035. +} MV_CPU_CNTRS_EVENT;
  52036. +
  52037. +extern MV_CPU_CNTRS_ENTRY mvCpuCntrsTbl[MV_CPU_CNTRS_NUM];
  52038. +
  52039. +
  52040. +MV_STATUS mvCpuCntrsProgram(int counter, MV_CPU_CNTRS_OPS op,
  52041. + char* name, MV_U32 overhead);
  52042. +void mvCpuCntrsInit(void);
  52043. +MV_CPU_CNTRS_EVENT* mvCpuCntrsEventCreate(char* name, MV_U32 print_threshold);
  52044. +void mvCpuCntrsEventDelete(MV_CPU_CNTRS_EVENT* event);
  52045. +void mvCpuCntrsReset(void);
  52046. +void mvCpuCntrsShow(MV_CPU_CNTRS_EVENT* pEvent);
  52047. +void mvCpuCntrsEventClear(MV_CPU_CNTRS_EVENT* pEvent);
  52048. +
  52049. +/* internal */
  52050. +void program_counter(int counter, int op);
  52051. +
  52052. +static INLINE MV_U64 mvCpuCntrsRead(const int counter)
  52053. +{
  52054. + MV_U32 low = 0, high = 0;
  52055. + MV_U32 ll = 0;
  52056. +
  52057. + switch(counter)
  52058. + {
  52059. + case 0:
  52060. + MV_ASM ("mcr p15, 0, %0, c15, c12, 0" : : "r" (ll));
  52061. + MV_ASM ("mrc p15, 0, %0, c15, c13, 0" : "=r" (low));
  52062. + MV_ASM ("mrc p15, 0, %0, c15, c13, 1" : "=r" (high));
  52063. + break;
  52064. +
  52065. + case 1:
  52066. + MV_ASM ("mcr p15, 0, %0, c15, c12, 1" : : "r" (ll));
  52067. + MV_ASM ("mrc p15, 0, %0, c15, c13, 2" : "=r" (low));
  52068. + MV_ASM ("mrc p15, 0, %0, c15, c13, 3" : "=r" (high));
  52069. + break;
  52070. +
  52071. + case 2:
  52072. + MV_ASM ("mcr p15, 0, %0, c15, c12, 2" : : "r" (ll));
  52073. + MV_ASM ("mrc p15, 0, %0, c15, c13, 4" : "=r" (low));
  52074. + MV_ASM ("mrc p15, 0, %0, c15, c13, 5" : "=r" (high));
  52075. + break;
  52076. +
  52077. + case 3:
  52078. + MV_ASM ("mcr p15, 0, %0, c15, c12, 3" : : "r" (ll));
  52079. + MV_ASM ("mrc p15, 0, %0, c15, c13, 6" : "=r" (low));
  52080. + MV_ASM ("mrc p15, 0, %0, c15, c13, 7" : "=r" (high));
  52081. + break;
  52082. +
  52083. + default:
  52084. + mvOsPrintf("mv_cpu_cntrs_read: bad counter number (%d)\n", counter);
  52085. + }
  52086. + program_counter(counter, mvCpuCntrsTbl[counter].opIdx);
  52087. + return (((MV_U64)high << 32 ) | low);
  52088. +
  52089. +}
  52090. +
  52091. +
  52092. +static INLINE void mvCpuCntrsReadBefore(MV_CPU_CNTRS_EVENT* pEvent)
  52093. +{
  52094. +#if 0
  52095. + int i;
  52096. +
  52097. + /* order is important - we want to measure the cycle count last here! */
  52098. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  52099. + pEvent->counters_before[i] = mvCpuCntrsRead(i);
  52100. +#else
  52101. + pEvent->counters_before[1] = mvCpuCntrsRead(1);
  52102. + pEvent->counters_before[3] = mvCpuCntrsRead(3);
  52103. + pEvent->counters_before[0] = mvCpuCntrsRead(0);
  52104. + pEvent->counters_before[2] = mvCpuCntrsRead(2);
  52105. +#endif
  52106. +}
  52107. +
  52108. +static INLINE void mvCpuCntrsReadAfter(MV_CPU_CNTRS_EVENT* pEvent)
  52109. +{
  52110. + int i;
  52111. +
  52112. +#if 0
  52113. + /* order is important - we want to measure the cycle count first here! */
  52114. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  52115. + pEvent->counters_after[i] = mvCpuCntrsRead(i);
  52116. +#else
  52117. + pEvent->counters_after[2] = mvCpuCntrsRead(2);
  52118. + pEvent->counters_after[0] = mvCpuCntrsRead(0);
  52119. + pEvent->counters_after[3] = mvCpuCntrsRead(3);
  52120. + pEvent->counters_after[1] = mvCpuCntrsRead(1);
  52121. +#endif
  52122. +
  52123. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  52124. + {
  52125. + pEvent->counters_sum[i] += (pEvent->counters_after[i] - pEvent->counters_before[i]);
  52126. + }
  52127. + pEvent->num_of_measurements++;
  52128. +}
  52129. +
  52130. +
  52131. +#ifdef CONFIG_MV_CPU_PERF_CNTRS
  52132. +
  52133. +#define MV_CPU_CNTRS_READ(counter) mvCpuCntrsRead(counter)
  52134. +
  52135. +#define MV_CPU_CNTRS_START(event) mvCpuCntrsReadBefore(event)
  52136. +
  52137. +#define MV_CPU_CNTRS_STOP(event) mvCpuCntrsReadAfter(event)
  52138. +
  52139. +#define MV_CPU_CNTRS_SHOW(event) mvCpuCntrsShow(event)
  52140. +
  52141. +#else
  52142. +
  52143. +#define MV_CPU_CNTRS_READ(counter)
  52144. +#define MV_CPU_CNTRS_START(event)
  52145. +#define MV_CPU_CNTRS_STOP(event)
  52146. +#define MV_CPU_CNTRS_SHOW(event)
  52147. +
  52148. +#endif /* CONFIG_MV_CPU_PERF_CNTRS */
  52149. +
  52150. +
  52151. +#endif /* __mvCpuCntrs_h__ */
  52152. +
  52153. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c
  52154. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c 1970-01-01 01:00:00.000000000 +0100
  52155. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c 2010-08-05 22:02:23.884301932 +0200
  52156. @@ -0,0 +1,143 @@
  52157. +/*
  52158. + * This program is free software; you can redistribute it and/or modify
  52159. + * it under the terms of the GNU General Public License as published by
  52160. + * the Free Software Foundation; either version 2 of the License, or
  52161. + * (at your option) any later version.
  52162. + *
  52163. + * This program is distributed in the hope that it will be useful,
  52164. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  52165. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  52166. + * GNU General Public License for more details.
  52167. + *
  52168. + * You should have received a copy of the GNU General Public License
  52169. + * along with this program; if not, write to the Free Software
  52170. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  52171. + */
  52172. +
  52173. +#include "mvOs.h"
  52174. +#include "mvCpuL2Cntrs.h"
  52175. +
  52176. +
  52177. +
  52178. +MV_CPU_L2_CNTRS_ENTRY mvCpuL2CntrsTbl[MV_CPU_L2_CNTRS_NUM];
  52179. +
  52180. +MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventTbl[128];
  52181. +
  52182. +void mvCpuL2CntrsReset(void)
  52183. +{
  52184. + MV_U32 reg = 0;
  52185. +
  52186. + MV_ASM ("mcr p15, 6, %0, c15, c13, 0" : : "r" (reg));
  52187. + MV_ASM ("mcr p15, 6, %0, c15, c13, 1" : : "r" (reg));
  52188. + MV_ASM ("mcr p15, 6, %0, c15, c13, 2" : : "r" (reg));
  52189. + MV_ASM ("mcr p15, 6, %0, c15, c13, 3" : : "r" (reg));
  52190. +}
  52191. +
  52192. +static void mvCpuL2CntrConfig(int counter, int op)
  52193. +{
  52194. + MV_U32 reg = (1 << op) | 0x1; /*enable*/
  52195. +
  52196. + switch(counter)
  52197. + {
  52198. + case 0:
  52199. + MV_ASM ("mcr p15, 6, %0, c15, c12, 0" : : "r" (reg));
  52200. + return;
  52201. +
  52202. + case 1:
  52203. + MV_ASM ("mcr p15, 6, %0, c15, c12, 1" : : "r" (reg));
  52204. + return;
  52205. +
  52206. + default:
  52207. + mvOsPrintf("mvCpuL2CntrConfig: bad counter number (%d)\n", counter);
  52208. + }
  52209. + return;
  52210. +}
  52211. +
  52212. +void mvCpuL2CntrsEventClear(MV_CPU_L2_CNTRS_EVENT* pEvent)
  52213. +{
  52214. + int i;
  52215. +
  52216. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  52217. + {
  52218. + pEvent->counters_sum[i] = 0;
  52219. + }
  52220. + pEvent->num_of_measurements = 0;
  52221. +}
  52222. +
  52223. +
  52224. +MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventCreate(char* name, MV_U32 print_threshold)
  52225. +{
  52226. + int i;
  52227. + MV_CPU_L2_CNTRS_EVENT* event = mvOsMalloc(sizeof(MV_CPU_L2_CNTRS_EVENT));
  52228. +
  52229. + if(event)
  52230. + {
  52231. + strncpy(event->name, name, sizeof(event->name));
  52232. + event->num_of_measurements = 0;
  52233. + event->avg_sample_count = print_threshold;
  52234. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  52235. + {
  52236. + event->counters_before[i] = 0;
  52237. + event->counters_after[i] = 0;
  52238. + event->counters_sum[i] = 0;
  52239. + }
  52240. + }
  52241. + return event;
  52242. +}
  52243. +
  52244. +void mvCpuL2CntrsEventDelete(MV_CPU_L2_CNTRS_EVENT* event)
  52245. +{
  52246. + if(event != NULL)
  52247. + mvOsFree(event);
  52248. +}
  52249. +
  52250. +
  52251. +MV_STATUS mvCpuL2CntrsProgram(int counter, MV_CPU_L2_CNTRS_OPS op,
  52252. + char* name, MV_U32 overhead)
  52253. +{
  52254. + strncpy(mvCpuL2CntrsTbl[counter].name, name, sizeof(mvCpuL2CntrsTbl[counter].name));
  52255. + mvCpuL2CntrsTbl[counter].operation = op;
  52256. + mvCpuL2CntrsTbl[counter].opIdx = op;
  52257. + mvCpuL2CntrsTbl[counter].overhead = overhead;
  52258. + mvCpuL2CntrConfig(counter, op);
  52259. + mvOsPrintf("CPU L2 Counter %d: operation=%d, overhead=%d\n",
  52260. + counter, op, overhead);
  52261. + return MV_OK;
  52262. +}
  52263. +
  52264. +void mvCpuL2CntrsShow(MV_CPU_L2_CNTRS_EVENT* pEvent)
  52265. +{
  52266. + int i;
  52267. + MV_U64 counters_avg;
  52268. +
  52269. + if(pEvent->num_of_measurements < pEvent->avg_sample_count)
  52270. + return;
  52271. +
  52272. + mvOsPrintf("%16s: ", pEvent->name);
  52273. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  52274. + {
  52275. + counters_avg = mvOsDivMod64(pEvent->counters_sum[i],
  52276. + pEvent->num_of_measurements, NULL);
  52277. +
  52278. + if(counters_avg >= mvCpuL2CntrsTbl[i].overhead)
  52279. + counters_avg -= mvCpuL2CntrsTbl[i].overhead;
  52280. + else
  52281. + counters_avg = 0;
  52282. +
  52283. + mvOsPrintf("%s=%5llu, ", mvCpuL2CntrsTbl[i].name, counters_avg);
  52284. + }
  52285. + mvOsPrintf("\n");
  52286. + mvCpuL2CntrsEventClear(pEvent);
  52287. + mvCpuL2CntrsReset();
  52288. +}
  52289. +
  52290. +void mvCpuL2CntrsStatus(void)
  52291. +{
  52292. + int i;
  52293. +
  52294. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  52295. + {
  52296. + mvOsPrintf("#%d: %s, overhead=%d\n",
  52297. + i, mvCpuL2CntrsTbl[i].name, mvCpuL2CntrsTbl[i].overhead);
  52298. + }
  52299. +}
  52300. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h
  52301. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h 1970-01-01 01:00:00.000000000 +0100
  52302. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h 2010-08-05 22:02:23.934314260 +0200
  52303. @@ -0,0 +1,151 @@
  52304. +/*******************************************************************************
  52305. +Copyright (C) Marvell International Ltd. and its affiliates
  52306. +
  52307. +This software file (the "File") is owned and distributed by Marvell
  52308. +International Ltd. and/or its affiliates ("Marvell") under the following
  52309. +alternative licensing terms. Once you have made an election to distribute the
  52310. +File under one of the following license alternatives, please (i) delete this
  52311. +introductory statement regarding license alternatives, (ii) delete the two
  52312. +license alternatives that you have not elected to use and (iii) preserve the
  52313. +Marvell copyright notice above.
  52314. +
  52315. +
  52316. +********************************************************************************
  52317. +Marvell GPL License Option
  52318. +
  52319. +If you received this File from Marvell, you may opt to use, redistribute and/or
  52320. +modify this File in accordance with the terms and conditions of the General
  52321. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  52322. +available along with the File in the license.txt file or by writing to the Free
  52323. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  52324. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  52325. +
  52326. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  52327. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  52328. +DISCLAIMED. The GPL License provides additional details about this warranty
  52329. +disclaimer.
  52330. +*******************************************************************************/
  52331. +#ifndef __mvCpuL2Cntrs_h__
  52332. +#define __mvCpuL2Cntrs_h__
  52333. +
  52334. +#include "mvTypes.h"
  52335. +#include "mvOs.h"
  52336. +
  52337. +
  52338. +#define MV_CPU_L2_CNTRS_NUM 2
  52339. +
  52340. +typedef enum
  52341. +{
  52342. + MV_CPU_L2_CNTRS_ENABLE = 0,
  52343. + MV_CPU_L2_CNTRS_DATA_REQ,
  52344. + MV_CPU_L2_CNTRS_DATA_MISS_REQ,
  52345. + MV_CPU_L2_CNTRS_INST_REQ,
  52346. + MV_CPU_L2_CNTRS_INST_MISS_REQ,
  52347. + MV_CPU_L2_CNTRS_DATA_READ_REQ,
  52348. + MV_CPU_L2_CNTRS_DATA_READ_MISS_REQ,
  52349. + MV_CPU_L2_CNTRS_DATA_WRITE_REQ,
  52350. + MV_CPU_L2_CNTRS_DATA_WRITE_MISS_REQ,
  52351. + MV_CPU_L2_CNTRS_RESERVED,
  52352. + MV_CPU_L2_CNTRS_DIRTY_EVICT_REQ,
  52353. + MV_CPU_L2_CNTRS_EVICT_BUFF_STALL,
  52354. + MV_CPU_L2_CNTRS_ACTIVE_CYCLES,
  52355. +
  52356. +} MV_CPU_L2_CNTRS_OPS;
  52357. +
  52358. +typedef struct
  52359. +{
  52360. + char name[16];
  52361. + MV_CPU_L2_CNTRS_OPS operation;
  52362. + int opIdx;
  52363. + MV_U32 overhead;
  52364. +
  52365. +} MV_CPU_L2_CNTRS_ENTRY;
  52366. +
  52367. +
  52368. +typedef struct
  52369. +{
  52370. + char name[16];
  52371. + MV_U32 num_of_measurements;
  52372. + MV_U32 avg_sample_count;
  52373. + MV_U64 counters_before[MV_CPU_L2_CNTRS_NUM];
  52374. + MV_U64 counters_after[MV_CPU_L2_CNTRS_NUM];
  52375. + MV_U64 counters_sum[MV_CPU_L2_CNTRS_NUM];
  52376. +
  52377. +} MV_CPU_L2_CNTRS_EVENT;
  52378. +
  52379. +
  52380. +MV_STATUS mvCpuL2CntrsProgram(int counter, MV_CPU_L2_CNTRS_OPS op,
  52381. + char* name, MV_U32 overhead);
  52382. +void mvCpuL2CntrsInit(void);
  52383. +MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventCreate(char* name, MV_U32 print_threshold);
  52384. +void mvCpuL2CntrsEventDelete(MV_CPU_L2_CNTRS_EVENT* event);
  52385. +void mvCpuL2CntrsReset(void);
  52386. +void mvCpuL2CntrsShow(MV_CPU_L2_CNTRS_EVENT* pEvent);
  52387. +void mvCpuL2CntrsEventClear(MV_CPU_L2_CNTRS_EVENT* pEvent);
  52388. +
  52389. +static INLINE MV_U64 mvCpuL2CntrsRead(const int counter)
  52390. +{
  52391. + MV_U32 low = 0, high = 0;
  52392. +
  52393. + switch(counter)
  52394. + {
  52395. + case 0:
  52396. + MV_ASM ("mrc p15, 6, %0, c15, c13, 0" : "=r" (low));
  52397. + MV_ASM ("mrc p15, 6, %0, c15, c13, 1" : "=r" (high));
  52398. + break;
  52399. +
  52400. + case 1:
  52401. + MV_ASM ("mrc p15, 6, %0, c15, c13, 2" : "=r" (low));
  52402. + MV_ASM ("mrc p15, 6, %0, c15, c13, 3" : "=r" (high));
  52403. + break;
  52404. +
  52405. + default:
  52406. + mvOsPrintf("mvCpuL2CntrsRead: bad counter number (%d)\n", counter);
  52407. + }
  52408. + return (((MV_U64)high << 32 ) | low);
  52409. +
  52410. +}
  52411. +
  52412. +static INLINE void mvCpuL2CntrsReadBefore(MV_CPU_L2_CNTRS_EVENT* pEvent)
  52413. +{
  52414. + int i;
  52415. +
  52416. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  52417. + pEvent->counters_before[i] = mvCpuL2CntrsRead(i);
  52418. +}
  52419. +
  52420. +static INLINE void mvCpuL2CntrsReadAfter(MV_CPU_L2_CNTRS_EVENT* pEvent)
  52421. +{
  52422. + int i;
  52423. +
  52424. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  52425. + {
  52426. + pEvent->counters_after[i] = mvCpuL2CntrsRead(i);
  52427. + pEvent->counters_sum[i] += (pEvent->counters_after[i] - pEvent->counters_before[i]);
  52428. + }
  52429. + pEvent->num_of_measurements++;
  52430. +}
  52431. +
  52432. +
  52433. +#ifdef CONFIG_MV_CPU_L2_PERF_CNTRS
  52434. +
  52435. +#define MV_CPU_L2_CNTRS_READ(counter) mvCpuL2CntrsRead(counter)
  52436. +
  52437. +#define MV_CPU_L2_CNTRS_START(event) mvCpuL2CntrsReadBefore(event)
  52438. +
  52439. +#define MV_CPU_L2_CNTRS_STOP(event) mvCpuL2CntrsReadAfter(event)
  52440. +
  52441. +#define MV_CPU_L2_CNTRS_SHOW(event) mvCpuL2CntrsShow(event)
  52442. +
  52443. +#else
  52444. +
  52445. +#define MV_CPU_L2_CNTRS_READ(counter)
  52446. +#define MV_CPU_L2_CNTRS_START(event)
  52447. +#define MV_CPU_L2_CNTRS_STOP(event)
  52448. +#define MV_CPU_L2_CNTRS_SHOW(event)
  52449. +
  52450. +#endif /* CONFIG_MV_CPU_L2_PERF_CNTRS */
  52451. +
  52452. +
  52453. +#endif /* __mvCpuL2Cntrs_h__ */
  52454. +
  52455. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c
  52456. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c 1970-01-01 01:00:00.000000000 +0100
  52457. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c 2010-08-05 22:02:23.984868200 +0200
  52458. @@ -0,0 +1,1479 @@
  52459. +/*******************************************************************************
  52460. +Copyright (C) Marvell International Ltd. and its affiliates
  52461. +
  52462. +This software file (the "File") is owned and distributed by Marvell
  52463. +International Ltd. and/or its affiliates ("Marvell") under the following
  52464. +alternative licensing terms. Once you have made an election to distribute the
  52465. +File under one of the following license alternatives, please (i) delete this
  52466. +introductory statement regarding license alternatives, (ii) delete the two
  52467. +license alternatives that you have not elected to use and (iii) preserve the
  52468. +Marvell copyright notice above.
  52469. +
  52470. +********************************************************************************
  52471. +Marvell Commercial License Option
  52472. +
  52473. +If you received this File from Marvell and you have entered into a commercial
  52474. +license agreement (a "Commercial License") with Marvell, the File is licensed
  52475. +to you under the terms of the applicable Commercial License.
  52476. +
  52477. +********************************************************************************
  52478. +Marvell GPL License Option
  52479. +
  52480. +If you received this File from Marvell, you may opt to use, redistribute and/or
  52481. +modify this File in accordance with the terms and conditions of the General
  52482. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  52483. +available along with the File in the license.txt file or by writing to the Free
  52484. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  52485. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  52486. +
  52487. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  52488. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  52489. +DISCLAIMED. The GPL License provides additional details about this warranty
  52490. +disclaimer.
  52491. +********************************************************************************
  52492. +Marvell BSD License Option
  52493. +
  52494. +If you received this File from Marvell, you may opt to use, redistribute and/or
  52495. +modify this File under the following licensing terms.
  52496. +Redistribution and use in source and binary forms, with or without modification,
  52497. +are permitted provided that the following conditions are met:
  52498. +
  52499. + * Redistributions of source code must retain the above copyright notice,
  52500. + this list of conditions and the following disclaimer.
  52501. +
  52502. + * Redistributions in binary form must reproduce the above copyright
  52503. + notice, this list of conditions and the following disclaimer in the
  52504. + documentation and/or other materials provided with the distribution.
  52505. +
  52506. + * Neither the name of Marvell nor the names of its contributors may be
  52507. + used to endorse or promote products derived from this software without
  52508. + specific prior written permission.
  52509. +
  52510. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  52511. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  52512. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  52513. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  52514. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  52515. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  52516. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  52517. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  52518. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  52519. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  52520. +
  52521. +*******************************************************************************/
  52522. +
  52523. +#include "ddr1_2/mvDram.h"
  52524. +#include "boardEnv/mvBoardEnvLib.h"
  52525. +
  52526. +#undef MV_DEBUG
  52527. +#ifdef MV_DEBUG
  52528. +#define DB(x) x
  52529. +#else
  52530. +#define DB(x)
  52531. +#endif
  52532. +
  52533. +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
  52534. + MV_DRAM_BANK_INFO *pBankInfo);
  52535. +static MV_U32 cas2ps(MV_U8 spd_byte);
  52536. +/*******************************************************************************
  52537. +* mvDramBankGet - Get the DRAM bank paramters.
  52538. +*
  52539. +* DESCRIPTION:
  52540. +* This function retrieves DRAM bank parameters as described in
  52541. +* DRAM_BANK_INFO struct to the controller DRAM unit. In case the board
  52542. +* has its DRAM on DIMMs it will use its EEPROM to extract SPD data
  52543. +* from it. Otherwise, if the DRAM is soldered on board, the function
  52544. +* should insert its bank information into MV_DRAM_BANK_INFO struct.
  52545. +*
  52546. +* INPUT:
  52547. +* bankNum - Board DRAM bank number.
  52548. +*
  52549. +* OUTPUT:
  52550. +* pBankInfo - DRAM bank information struct.
  52551. +*
  52552. +* RETURN:
  52553. +* MV_FAIL - Bank parameters could not be read.
  52554. +*
  52555. +*******************************************************************************/
  52556. +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo)
  52557. +{
  52558. + MV_DIMM_INFO dimmInfo;
  52559. +
  52560. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bank %d\n", bankNum));
  52561. + /* zero pBankInfo structure */
  52562. + memset(pBankInfo, 0, sizeof(*pBankInfo));
  52563. +
  52564. + if((NULL == pBankInfo) || (bankNum >= MV_DRAM_MAX_CS ))
  52565. + {
  52566. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
  52567. + return MV_BAD_PARAM;
  52568. + }
  52569. + if( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
  52570. + {
  52571. + DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
  52572. + return MV_FAIL;
  52573. + }
  52574. + if((dimmInfo.numOfModuleBanks == 1) && ((bankNum % 2) == 1))
  52575. + {
  52576. + DB(mvOsPrintf("Dram: ERR dimmSpdGet. Can't find DIMM bank 2 \n"));
  52577. + return MV_FAIL;
  52578. + }
  52579. +
  52580. + /* convert Dimm info to Bank info */
  52581. + cpyDimm2BankInfo(&dimmInfo, pBankInfo);
  52582. +
  52583. + return MV_OK;
  52584. +}
  52585. +
  52586. +/*******************************************************************************
  52587. +* cpyDimm2BankInfo - Convert a Dimm info struct into a bank info struct.
  52588. +*
  52589. +* DESCRIPTION:
  52590. +* Convert a Dimm info struct into a bank info struct.
  52591. +*
  52592. +* INPUT:
  52593. +* pDimmInfo - DIMM information structure.
  52594. +*
  52595. +* OUTPUT:
  52596. +* pBankInfo - DRAM bank information struct.
  52597. +*
  52598. +* RETURN:
  52599. +* None.
  52600. +*
  52601. +*******************************************************************************/
  52602. +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
  52603. + MV_DRAM_BANK_INFO *pBankInfo)
  52604. +{
  52605. + pBankInfo->memoryType = pDimmInfo->memoryType;
  52606. +
  52607. + /* DIMM dimensions */
  52608. + pBankInfo->numOfRowAddr = pDimmInfo->numOfRowAddr;
  52609. + pBankInfo->numOfColAddr = pDimmInfo->numOfColAddr;
  52610. + pBankInfo->dataWidth = pDimmInfo->dataWidth;
  52611. + pBankInfo->errorCheckType = pDimmInfo->errorCheckType;
  52612. + pBankInfo->sdramWidth = pDimmInfo->sdramWidth;
  52613. + pBankInfo->errorCheckDataWidth = pDimmInfo->errorCheckDataWidth;
  52614. + pBankInfo->numOfBanksOnEachDevice = pDimmInfo->numOfBanksOnEachDevice;
  52615. + pBankInfo->suportedCasLatencies = pDimmInfo->suportedCasLatencies;
  52616. + pBankInfo->refreshInterval = pDimmInfo->refreshInterval;
  52617. +
  52618. + /* DIMM timing parameters */
  52619. + pBankInfo->minCycleTimeAtMaxCasLatPs = pDimmInfo->minCycleTimeAtMaxCasLatPs;
  52620. + pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps =
  52621. + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps;
  52622. + pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps =
  52623. + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps;
  52624. +
  52625. + pBankInfo->minRowPrechargeTime = pDimmInfo->minRowPrechargeTime;
  52626. + pBankInfo->minRowActiveToRowActive = pDimmInfo->minRowActiveToRowActive;
  52627. + pBankInfo->minRasToCasDelay = pDimmInfo->minRasToCasDelay;
  52628. + pBankInfo->minRasPulseWidth = pDimmInfo->minRasPulseWidth;
  52629. + pBankInfo->minWriteRecoveryTime = pDimmInfo->minWriteRecoveryTime;
  52630. + pBankInfo->minWriteToReadCmdDelay = pDimmInfo->minWriteToReadCmdDelay;
  52631. + pBankInfo->minReadToPrechCmdDelay = pDimmInfo->minReadToPrechCmdDelay;
  52632. + pBankInfo->minRefreshToActiveCmd = pDimmInfo->minRefreshToActiveCmd;
  52633. +
  52634. + /* Parameters calculated from the extracted DIMM information */
  52635. + pBankInfo->size = pDimmInfo->size/pDimmInfo->numOfModuleBanks;
  52636. + pBankInfo->deviceDensity = pDimmInfo->deviceDensity;
  52637. + pBankInfo->numberOfDevices = pDimmInfo->numberOfDevices /
  52638. + pDimmInfo->numOfModuleBanks;
  52639. +
  52640. + /* DIMM attributes (MV_TRUE for yes) */
  52641. +
  52642. + if ((pDimmInfo->memoryType == MEM_TYPE_SDRAM) ||
  52643. + (pDimmInfo->memoryType == MEM_TYPE_DDR1) )
  52644. + {
  52645. + if (pDimmInfo->dimmAttributes & BIT1)
  52646. + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
  52647. + else
  52648. + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
  52649. + }
  52650. + else /* pDimmInfo->memoryType == MEM_TYPE_DDR2 */
  52651. + {
  52652. + if (pDimmInfo->dimmTypeInfo & (BIT0 | BIT4))
  52653. + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
  52654. + else
  52655. + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
  52656. + }
  52657. +
  52658. + return;
  52659. +}
  52660. +
  52661. +/*******************************************************************************
  52662. +* dimmSpdCpy - Cpy SPD parameters from dimm 0 to dimm 1.
  52663. +*
  52664. +* DESCRIPTION:
  52665. +* Read the DIMM SPD parameters from dimm 0 into dimm 1 SPD.
  52666. +*
  52667. +* INPUT:
  52668. +* None.
  52669. +*
  52670. +* OUTPUT:
  52671. +* None.
  52672. +*
  52673. +* RETURN:
  52674. +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
  52675. +*
  52676. +*******************************************************************************/
  52677. +MV_STATUS dimmSpdCpy(MV_VOID)
  52678. +{
  52679. + MV_U32 i;
  52680. + MV_U32 spdChecksum;
  52681. +
  52682. + MV_TWSI_SLAVE twsiSlave;
  52683. + MV_U8 data[SPD_SIZE];
  52684. +
  52685. + /* zero dimmInfo structure */
  52686. + memset(data, 0, SPD_SIZE);
  52687. +
  52688. + /* read the dimm eeprom */
  52689. + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
  52690. + twsiSlave.slaveAddr.address = MV_BOARD_DIMM0_I2C_ADDR;
  52691. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  52692. + twsiSlave.validOffset = MV_TRUE;
  52693. + twsiSlave.offset = 0;
  52694. + twsiSlave.moreThen256 = MV_FALSE;
  52695. +
  52696. + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL,
  52697. + &twsiSlave, data, SPD_SIZE) )
  52698. + {
  52699. + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 0\n"));
  52700. + return MV_FAIL;
  52701. + }
  52702. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  52703. +
  52704. + /* calculate SPD checksum */
  52705. + spdChecksum = 0;
  52706. +
  52707. + for(i = 0 ; i <= 62 ; i++)
  52708. + {
  52709. + spdChecksum += data[i];
  52710. + }
  52711. +
  52712. + if ((spdChecksum & 0xff) != data[63])
  52713. + {
  52714. + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
  52715. + (MV_U32)(spdChecksum & 0xff), data[63]));
  52716. + }
  52717. + else
  52718. + {
  52719. + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
  52720. + }
  52721. +
  52722. + /* copy the SPD content 1:1 into the DIMM 1 SPD */
  52723. + twsiSlave.slaveAddr.address = MV_BOARD_DIMM1_I2C_ADDR;
  52724. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  52725. + twsiSlave.validOffset = MV_TRUE;
  52726. + twsiSlave.offset = 0;
  52727. + twsiSlave.moreThen256 = MV_FALSE;
  52728. +
  52729. + for(i = 0 ; i < SPD_SIZE ; i++)
  52730. + {
  52731. + twsiSlave.offset = i;
  52732. + if( MV_OK != mvTwsiWrite (MV_BOARD_DIMM_I2C_CHANNEL,
  52733. + &twsiSlave, &data[i], 1) )
  52734. + {
  52735. + mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 1 byte %d \n",i);
  52736. + return MV_FAIL;
  52737. + }
  52738. + mvOsDelay(5);
  52739. + }
  52740. +
  52741. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  52742. + return MV_OK;
  52743. +}
  52744. +
  52745. +/*******************************************************************************
  52746. +* dimmSpdGet - Get the SPD parameters.
  52747. +*
  52748. +* DESCRIPTION:
  52749. +* Read the DIMM SPD parameters into given struct parameter.
  52750. +*
  52751. +* INPUT:
  52752. +* dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
  52753. +*
  52754. +* OUTPUT:
  52755. +* pDimmInfo - DIMM information structure.
  52756. +*
  52757. +* RETURN:
  52758. +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
  52759. +*
  52760. +*******************************************************************************/
  52761. +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo)
  52762. +{
  52763. + MV_U32 i;
  52764. + MV_U32 density = 1;
  52765. + MV_U32 spdChecksum;
  52766. +
  52767. + MV_TWSI_SLAVE twsiSlave;
  52768. + MV_U8 data[SPD_SIZE];
  52769. +
  52770. + if((NULL == pDimmInfo)|| (dimmNum >= MAX_DIMM_NUM))
  52771. + {
  52772. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
  52773. + return MV_BAD_PARAM;
  52774. + }
  52775. +
  52776. + /* zero dimmInfo structure */
  52777. + memset(data, 0, SPD_SIZE);
  52778. +
  52779. + /* read the dimm eeprom */
  52780. + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
  52781. + twsiSlave.slaveAddr.address = (dimmNum == 0) ?
  52782. + MV_BOARD_DIMM0_I2C_ADDR : MV_BOARD_DIMM1_I2C_ADDR;
  52783. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  52784. + twsiSlave.validOffset = MV_TRUE;
  52785. + twsiSlave.offset = 0;
  52786. + twsiSlave.moreThen256 = MV_FALSE;
  52787. +
  52788. + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL,
  52789. + &twsiSlave, data, SPD_SIZE) )
  52790. + {
  52791. + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum %d \n", dimmNum));
  52792. + return MV_FAIL;
  52793. + }
  52794. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  52795. +
  52796. + /* calculate SPD checksum */
  52797. + spdChecksum = 0;
  52798. +
  52799. + for(i = 0 ; i <= 62 ; i++)
  52800. + {
  52801. + spdChecksum += data[i];
  52802. + }
  52803. +
  52804. + if ((spdChecksum & 0xff) != data[63])
  52805. + {
  52806. + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
  52807. + (MV_U32)(spdChecksum & 0xff), data[63]));
  52808. + }
  52809. + else
  52810. + {
  52811. + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
  52812. + }
  52813. +
  52814. + /* copy the SPD content 1:1 into the dimmInfo structure*/
  52815. + for(i = 0 ; i < SPD_SIZE ; i++)
  52816. + {
  52817. + pDimmInfo->spdRawData[i] = data[i];
  52818. + DB(mvOsPrintf("SPD-EEPROM Byte %3d = %3x (%3d)\n",i, data[i], data[i]));
  52819. + }
  52820. +
  52821. + DB(mvOsPrintf("DRAM SPD Information:\n"));
  52822. +
  52823. + /* Memory type (DDR / SDRAM) */
  52824. + switch (data[DIMM_MEM_TYPE])
  52825. + {
  52826. + case (DIMM_MEM_TYPE_SDRAM):
  52827. + pDimmInfo->memoryType = MEM_TYPE_SDRAM;
  52828. + DB(mvOsPrintf("DRAM Memeory type SDRAM\n"));
  52829. + break;
  52830. + case (DIMM_MEM_TYPE_DDR1):
  52831. + pDimmInfo->memoryType = MEM_TYPE_DDR1;
  52832. + DB(mvOsPrintf("DRAM Memeory type DDR1\n"));
  52833. + break;
  52834. + case (DIMM_MEM_TYPE_DDR2):
  52835. + pDimmInfo->memoryType = MEM_TYPE_DDR2;
  52836. + DB(mvOsPrintf("DRAM Memeory type DDR2\n"));
  52837. + break;
  52838. + default:
  52839. + mvOsPrintf("ERROR: Undefined memory type!\n");
  52840. + return MV_ERROR;
  52841. + }
  52842. +
  52843. +
  52844. + /* Number Of Row Addresses */
  52845. + pDimmInfo->numOfRowAddr = data[DIMM_ROW_NUM];
  52846. + DB(mvOsPrintf("DRAM numOfRowAddr[3] %d\n",pDimmInfo->numOfRowAddr));
  52847. +
  52848. + /* Number Of Column Addresses */
  52849. + pDimmInfo->numOfColAddr = data[DIMM_COL_NUM];
  52850. + DB(mvOsPrintf("DRAM numOfColAddr[4] %d\n",pDimmInfo->numOfColAddr));
  52851. +
  52852. + /* Number Of Module Banks */
  52853. + pDimmInfo->numOfModuleBanks = data[DIMM_MODULE_BANK_NUM];
  52854. + DB(mvOsPrintf("DRAM numOfModuleBanks[5] 0x%x\n",
  52855. + pDimmInfo->numOfModuleBanks));
  52856. +
  52857. + /* Number of module banks encoded differently for DDR2 */
  52858. + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
  52859. + pDimmInfo->numOfModuleBanks = (pDimmInfo->numOfModuleBanks & 0x7)+1;
  52860. +
  52861. + /* Data Width */
  52862. + pDimmInfo->dataWidth = data[DIMM_DATA_WIDTH];
  52863. + DB(mvOsPrintf("DRAM dataWidth[6] 0x%x\n", pDimmInfo->dataWidth));
  52864. +
  52865. + /* Minimum Cycle Time At Max CasLatancy */
  52866. + pDimmInfo->minCycleTimeAtMaxCasLatPs = cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS]);
  52867. +
  52868. + /* Error Check Type */
  52869. + pDimmInfo->errorCheckType = data[DIMM_ERR_CHECK_TYPE];
  52870. + DB(mvOsPrintf("DRAM errorCheckType[11] 0x%x\n",
  52871. + pDimmInfo->errorCheckType));
  52872. +
  52873. + /* Refresh Interval */
  52874. + pDimmInfo->refreshInterval = data[DIMM_REFRESH_INTERVAL];
  52875. + DB(mvOsPrintf("DRAM refreshInterval[12] 0x%x\n",
  52876. + pDimmInfo->refreshInterval));
  52877. +
  52878. + /* Sdram Width */
  52879. + pDimmInfo->sdramWidth = data[DIMM_SDRAM_WIDTH];
  52880. + DB(mvOsPrintf("DRAM sdramWidth[13] 0x%x\n",pDimmInfo->sdramWidth));
  52881. +
  52882. + /* Error Check Data Width */
  52883. + pDimmInfo->errorCheckDataWidth = data[DIMM_ERR_CHECK_DATA_WIDTH];
  52884. + DB(mvOsPrintf("DRAM errorCheckDataWidth[14] 0x%x\n",
  52885. + pDimmInfo->errorCheckDataWidth));
  52886. +
  52887. + /* Burst Length Supported */
  52888. + /* SDRAM/DDR1:
  52889. + *******-******-******-******-******-******-******-*******
  52890. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  52891. + *******-******-******-******-******-******-******-*******
  52892. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
  52893. + *********************************************************/
  52894. + /* DDR2:
  52895. + *******-******-******-******-******-******-******-*******
  52896. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  52897. + *******-******-******-******-******-******-******-*******
  52898. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
  52899. + *********************************************************/
  52900. +
  52901. + pDimmInfo->burstLengthSupported = data[DIMM_BURST_LEN_SUP];
  52902. + DB(mvOsPrintf("DRAM burstLengthSupported[16] 0x%x\n",
  52903. + pDimmInfo->burstLengthSupported));
  52904. +
  52905. + /* Number Of Banks On Each Device */
  52906. + pDimmInfo->numOfBanksOnEachDevice = data[DIMM_DEV_BANK_NUM];
  52907. + DB(mvOsPrintf("DRAM numOfBanksOnEachDevice[17] 0x%x\n",
  52908. + pDimmInfo->numOfBanksOnEachDevice));
  52909. +
  52910. + /* Suported Cas Latencies */
  52911. +
  52912. + /* SDRAM:
  52913. + *******-******-******-******-******-******-******-*******
  52914. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  52915. + *******-******-******-******-******-******-******-*******
  52916. + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
  52917. + ********************************************************/
  52918. +
  52919. + /* DDR 1:
  52920. + *******-******-******-******-******-******-******-*******
  52921. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  52922. + *******-******-******-******-******-******-******-*******
  52923. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  52924. + *********************************************************/
  52925. +
  52926. + /* DDR 2:
  52927. + *******-******-******-******-******-******-******-*******
  52928. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  52929. + *******-******-******-******-******-******-******-*******
  52930. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  52931. + *********************************************************/
  52932. +
  52933. + pDimmInfo->suportedCasLatencies = data[DIMM_SUP_CAL];
  52934. + DB(mvOsPrintf("DRAM suportedCasLatencies[18] 0x%x\n",
  52935. + pDimmInfo->suportedCasLatencies));
  52936. +
  52937. + /* For DDR2 only, get the DIMM type information */
  52938. + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
  52939. + {
  52940. + pDimmInfo->dimmTypeInfo = data[DIMM_DDR2_TYPE_INFORMATION];
  52941. + DB(mvOsPrintf("DRAM dimmTypeInfo[20] (DDR2) 0x%x\n",
  52942. + pDimmInfo->dimmTypeInfo));
  52943. + }
  52944. +
  52945. + /* SDRAM Modules Attributes */
  52946. + pDimmInfo->dimmAttributes = data[DIMM_BUF_ADDR_CONT_IN];
  52947. + DB(mvOsPrintf("DRAM dimmAttributes[21] 0x%x\n",
  52948. + pDimmInfo->dimmAttributes));
  52949. +
  52950. + /* Minimum Cycle Time At Max CasLatancy Minus 1*/
  52951. + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps =
  52952. + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS1]);
  52953. +
  52954. + /* Minimum Cycle Time At Max CasLatancy Minus 2*/
  52955. + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps =
  52956. + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS2]);
  52957. +
  52958. + pDimmInfo->minRowPrechargeTime = data[DIMM_MIN_ROW_PRECHARGE_TIME];
  52959. + DB(mvOsPrintf("DRAM minRowPrechargeTime[27] 0x%x\n",
  52960. + pDimmInfo->minRowPrechargeTime));
  52961. + pDimmInfo->minRowActiveToRowActive = data[DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE];
  52962. + DB(mvOsPrintf("DRAM minRowActiveToRowActive[28] 0x%x\n",
  52963. + pDimmInfo->minRowActiveToRowActive));
  52964. + pDimmInfo->minRasToCasDelay = data[DIMM_MIN_RAS_TO_CAS_DELAY];
  52965. + DB(mvOsPrintf("DRAM minRasToCasDelay[29] 0x%x\n",
  52966. + pDimmInfo->minRasToCasDelay));
  52967. + pDimmInfo->minRasPulseWidth = data[DIMM_MIN_RAS_PULSE_WIDTH];
  52968. + DB(mvOsPrintf("DRAM minRasPulseWidth[30] 0x%x\n",
  52969. + pDimmInfo->minRasPulseWidth));
  52970. +
  52971. + /* DIMM Bank Density */
  52972. + pDimmInfo->dimmBankDensity = data[DIMM_BANK_DENSITY];
  52973. + DB(mvOsPrintf("DRAM dimmBankDensity[31] 0x%x\n",
  52974. + pDimmInfo->dimmBankDensity));
  52975. +
  52976. + /* Only DDR2 includes Write Recovery Time field. Other SDRAM ignore */
  52977. + pDimmInfo->minWriteRecoveryTime = data[DIMM_MIN_WRITE_RECOVERY_TIME];
  52978. + DB(mvOsPrintf("DRAM minWriteRecoveryTime[36] 0x%x\n",
  52979. + pDimmInfo->minWriteRecoveryTime));
  52980. +
  52981. + /* Only DDR2 includes Internal Write To Read Command Delay field. */
  52982. + pDimmInfo->minWriteToReadCmdDelay = data[DIMM_MIN_WRITE_TO_READ_CMD_DELAY];
  52983. + DB(mvOsPrintf("DRAM minWriteToReadCmdDelay[37] 0x%x\n",
  52984. + pDimmInfo->minWriteToReadCmdDelay));
  52985. +
  52986. + /* Only DDR2 includes Internal Read To Precharge Command Delay field. */
  52987. + pDimmInfo->minReadToPrechCmdDelay = data[DIMM_MIN_READ_TO_PRECH_CMD_DELAY];
  52988. + DB(mvOsPrintf("DRAM minReadToPrechCmdDelay[38] 0x%x\n",
  52989. + pDimmInfo->minReadToPrechCmdDelay));
  52990. +
  52991. + /* Only DDR2 includes Minimum Refresh to Activate/Refresh Command field */
  52992. + pDimmInfo->minRefreshToActiveCmd = data[DIMM_MIN_REFRESH_TO_ACTIVATE_CMD];
  52993. + DB(mvOsPrintf("DRAM minRefreshToActiveCmd[42] 0x%x\n",
  52994. + pDimmInfo->minRefreshToActiveCmd));
  52995. +
  52996. + /* calculating the sdram density. Representing device density from */
  52997. + /* bit 20 to allow representation of 4GB and above. */
  52998. + /* For example, if density is 512Mbit 0x20000000, will be represent in */
  52999. + /* deviceDensity by 0x20000000 >> 16 --> 0x00000200. Another example */
  53000. + /* is density 8GB 0x200000000 >> 16 --> 0x00002000. */
  53001. + density = (1 << ((pDimmInfo->numOfRowAddr + pDimmInfo->numOfColAddr) - 20));
  53002. + pDimmInfo->deviceDensity = density *
  53003. + pDimmInfo->numOfBanksOnEachDevice *
  53004. + pDimmInfo->sdramWidth;
  53005. + DB(mvOsPrintf("DRAM deviceDensity %d\n",pDimmInfo->deviceDensity));
  53006. +
  53007. + /* Number of devices includeing Error correction */
  53008. + pDimmInfo->numberOfDevices = (pDimmInfo->dataWidth/pDimmInfo->sdramWidth) *
  53009. + pDimmInfo->numOfModuleBanks;
  53010. + DB(mvOsPrintf("DRAM numberOfDevices %d\n",
  53011. + pDimmInfo->numberOfDevices));
  53012. +
  53013. + pDimmInfo->size = 0;
  53014. +
  53015. + /* Note that pDimmInfo->size is in MB units */
  53016. + if (pDimmInfo->memoryType == MEM_TYPE_SDRAM)
  53017. + {
  53018. + if (pDimmInfo->dimmBankDensity & BIT0)
  53019. + pDimmInfo->size += 1024; /* Equal to 1GB */
  53020. + else if (pDimmInfo->dimmBankDensity & BIT1)
  53021. + pDimmInfo->size += 8; /* Equal to 8MB */
  53022. + else if (pDimmInfo->dimmBankDensity & BIT2)
  53023. + pDimmInfo->size += 16; /* Equal to 16MB */
  53024. + else if (pDimmInfo->dimmBankDensity & BIT3)
  53025. + pDimmInfo->size += 32; /* Equal to 32MB */
  53026. + else if (pDimmInfo->dimmBankDensity & BIT4)
  53027. + pDimmInfo->size += 64; /* Equal to 64MB */
  53028. + else if (pDimmInfo->dimmBankDensity & BIT5)
  53029. + pDimmInfo->size += 128; /* Equal to 128MB */
  53030. + else if (pDimmInfo->dimmBankDensity & BIT6)
  53031. + pDimmInfo->size += 256; /* Equal to 256MB */
  53032. + else if (pDimmInfo->dimmBankDensity & BIT7)
  53033. + pDimmInfo->size += 512; /* Equal to 512MB */
  53034. + }
  53035. + else if (pDimmInfo->memoryType == MEM_TYPE_DDR1)
  53036. + {
  53037. + if (pDimmInfo->dimmBankDensity & BIT0)
  53038. + pDimmInfo->size += 1024; /* Equal to 1GB */
  53039. + else if (pDimmInfo->dimmBankDensity & BIT1)
  53040. + pDimmInfo->size += 2048; /* Equal to 2GB */
  53041. + else if (pDimmInfo->dimmBankDensity & BIT2)
  53042. + pDimmInfo->size += 16; /* Equal to 16MB */
  53043. + else if (pDimmInfo->dimmBankDensity & BIT3)
  53044. + pDimmInfo->size += 32; /* Equal to 32MB */
  53045. + else if (pDimmInfo->dimmBankDensity & BIT4)
  53046. + pDimmInfo->size += 64; /* Equal to 64MB */
  53047. + else if (pDimmInfo->dimmBankDensity & BIT5)
  53048. + pDimmInfo->size += 128; /* Equal to 128MB */
  53049. + else if (pDimmInfo->dimmBankDensity & BIT6)
  53050. + pDimmInfo->size += 256; /* Equal to 256MB */
  53051. + else if (pDimmInfo->dimmBankDensity & BIT7)
  53052. + pDimmInfo->size += 512; /* Equal to 512MB */
  53053. + }
  53054. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  53055. + {
  53056. + if (pDimmInfo->dimmBankDensity & BIT0)
  53057. + pDimmInfo->size += 1024; /* Equal to 1GB */
  53058. + else if (pDimmInfo->dimmBankDensity & BIT1)
  53059. + pDimmInfo->size += 2048; /* Equal to 2GB */
  53060. + else if (pDimmInfo->dimmBankDensity & BIT2)
  53061. + pDimmInfo->size += 4096; /* Equal to 4GB */
  53062. + else if (pDimmInfo->dimmBankDensity & BIT3)
  53063. + pDimmInfo->size += 8192; /* Equal to 8GB */
  53064. + else if (pDimmInfo->dimmBankDensity & BIT4)
  53065. + pDimmInfo->size += 16384; /* Equal to 16GB */
  53066. + else if (pDimmInfo->dimmBankDensity & BIT5)
  53067. + pDimmInfo->size += 128; /* Equal to 128MB */
  53068. + else if (pDimmInfo->dimmBankDensity & BIT6)
  53069. + pDimmInfo->size += 256; /* Equal to 256MB */
  53070. + else if (pDimmInfo->dimmBankDensity & BIT7)
  53071. + pDimmInfo->size += 512; /* Equal to 512MB */
  53072. + }
  53073. +
  53074. + pDimmInfo->size *= pDimmInfo->numOfModuleBanks;
  53075. +
  53076. + DB(mvOsPrintf("Dram: dimm size %dMB \n",pDimmInfo->size));
  53077. +
  53078. + return MV_OK;
  53079. +}
  53080. +
  53081. +/*******************************************************************************
  53082. +* dimmSpdPrint - Print the SPD parameters.
  53083. +*
  53084. +* DESCRIPTION:
  53085. +* Print the Dimm SPD parameters.
  53086. +*
  53087. +* INPUT:
  53088. +* pDimmInfo - DIMM information structure.
  53089. +*
  53090. +* OUTPUT:
  53091. +* None.
  53092. +*
  53093. +* RETURN:
  53094. +* None.
  53095. +*
  53096. +*******************************************************************************/
  53097. +MV_VOID dimmSpdPrint(MV_U32 dimmNum)
  53098. +{
  53099. + MV_DIMM_INFO dimmInfo;
  53100. + MV_U32 i, temp = 0;
  53101. + MV_U32 k, maskLeftOfPoint = 0, maskRightOfPoint = 0;
  53102. + MV_U32 rightOfPoint = 0,leftOfPoint = 0, div, time_tmp, shift;
  53103. + MV_U32 busClkPs;
  53104. + MV_U8 trp_clocks=0, trcd_clocks, tras_clocks, trrd_clocks,
  53105. + temp_buf[40], *spdRawData;
  53106. +
  53107. + busClkPs = 1000000000 / (mvBoardSysClkGet() / 100); /* in 10 ps units */
  53108. +
  53109. + spdRawData = dimmInfo.spdRawData;
  53110. +
  53111. + if(MV_OK != dimmSpdGet(dimmNum, &dimmInfo))
  53112. + {
  53113. + mvOsOutput("ERROR: Could not read SPD information!\n");
  53114. + return;
  53115. + }
  53116. +
  53117. + /* find Manufactura of Dimm Module */
  53118. + mvOsOutput("\nManufacturer's JEDEC ID Code: ");
  53119. + for(i = 0 ; i < DIMM_MODULE_MANU_SIZE ; i++)
  53120. + {
  53121. + mvOsOutput("%x",spdRawData[DIMM_MODULE_MANU_OFFS + i]);
  53122. + }
  53123. + mvOsOutput("\n");
  53124. +
  53125. + /* Manufacturer's Specific Data */
  53126. + for(i = 0 ; i < DIMM_MODULE_ID_SIZE ; i++)
  53127. + {
  53128. + temp_buf[i] = spdRawData[DIMM_MODULE_ID_OFFS + i];
  53129. + }
  53130. + mvOsOutput("Manufacturer's Specific Data: %s\n", temp_buf);
  53131. +
  53132. + /* Module Part Number */
  53133. + for(i = 0 ; i < DIMM_MODULE_VEN_SIZE ; i++)
  53134. + {
  53135. + temp_buf[i] = spdRawData[DIMM_MODULE_VEN_OFFS + i];
  53136. + }
  53137. + mvOsOutput("Module Part Number: %s\n", temp_buf);
  53138. +
  53139. + /* Module Serial Number */
  53140. + for(i = 0; i < sizeof(MV_U32); i++)
  53141. + {
  53142. + temp |= spdRawData[95+i] << 8*i;
  53143. + }
  53144. + mvOsOutput("DIMM Serial No. %ld (%lx)\n", (long)temp,
  53145. + (long)temp);
  53146. +
  53147. + /* find Manufac-Data of Dimm Module */
  53148. + mvOsOutput("Manufactoring Date: Year 20%d%d/ ww %d%d\n",
  53149. + ((spdRawData[93] & 0xf0) >> 4), (spdRawData[93] & 0xf),
  53150. + ((spdRawData[94] & 0xf0) >> 4), (spdRawData[94] & 0xf));
  53151. + /* find modul_revision of Dimm Module */
  53152. + mvOsOutput("Module Revision: %d.%d\n",
  53153. + spdRawData[91], spdRawData[92]);
  53154. +
  53155. + /* find manufac_place of Dimm Module */
  53156. + mvOsOutput("manufac_place: %d\n", spdRawData[72]);
  53157. +
  53158. + /* go over the first 35 I2C data bytes */
  53159. + for(i = 2 ; i <= 35 ; i++)
  53160. + switch(i)
  53161. + {
  53162. + case 2: /* Memory type (DDR1/2 / SDRAM) */
  53163. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53164. + mvOsOutput("Dram Type is: SDRAM\n");
  53165. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  53166. + mvOsOutput("Dram Type is: SDRAM DDR1\n");
  53167. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  53168. + mvOsOutput("Dram Type is: SDRAM DDR2\n");
  53169. + else
  53170. + mvOsOutput("Dram Type unknown\n");
  53171. + break;
  53172. +/*----------------------------------------------------------------------------*/
  53173. +
  53174. + case 3: /* Number Of Row Addresses */
  53175. + mvOsOutput("Module Number of row addresses: %d\n",
  53176. + dimmInfo.numOfRowAddr);
  53177. + break;
  53178. +/*----------------------------------------------------------------------------*/
  53179. +
  53180. + case 4: /* Number Of Column Addresses */
  53181. + mvOsOutput("Module Number of col addresses: %d\n",
  53182. + dimmInfo.numOfColAddr);
  53183. + break;
  53184. +/*----------------------------------------------------------------------------*/
  53185. +
  53186. + case 5: /* Number Of Module Banks */
  53187. + mvOsOutput("Number of Banks on Mod.: %d\n",
  53188. + dimmInfo.numOfModuleBanks);
  53189. + break;
  53190. +/*----------------------------------------------------------------------------*/
  53191. +
  53192. + case 6: /* Data Width */
  53193. + mvOsOutput("Module Data Width: %d bit\n",
  53194. + dimmInfo.dataWidth);
  53195. + break;
  53196. +/*----------------------------------------------------------------------------*/
  53197. +
  53198. + case 8: /* Voltage Interface */
  53199. + switch(spdRawData[i])
  53200. + {
  53201. + case 0x0:
  53202. + mvOsOutput("Module is TTL_5V_TOLERANT\n");
  53203. + break;
  53204. + case 0x1:
  53205. + mvOsOutput("Module is LVTTL\n");
  53206. + break;
  53207. + case 0x2:
  53208. + mvOsOutput("Module is HSTL_1_5V\n");
  53209. + break;
  53210. + case 0x3:
  53211. + mvOsOutput("Module is SSTL_3_3V\n");
  53212. + break;
  53213. + case 0x4:
  53214. + mvOsOutput("Module is SSTL_2_5V\n");
  53215. + break;
  53216. + case 0x5:
  53217. + if (dimmInfo.memoryType != MEM_TYPE_SDRAM)
  53218. + {
  53219. + mvOsOutput("Module is SSTL_1_8V\n");
  53220. + break;
  53221. + }
  53222. + default:
  53223. + mvOsOutput("Module is VOLTAGE_UNKNOWN\n");
  53224. + break;
  53225. + }
  53226. + break;
  53227. +/*----------------------------------------------------------------------------*/
  53228. +
  53229. + case 9: /* Minimum Cycle Time At Max CasLatancy */
  53230. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  53231. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  53232. +
  53233. + /* DDR2 addition of right of point */
  53234. + if ((spdRawData[i] & 0x0f) == 0xA)
  53235. + {
  53236. + rightOfPoint = 25;
  53237. + }
  53238. + if ((spdRawData[i] & 0x0f) == 0xB)
  53239. + {
  53240. + rightOfPoint = 33;
  53241. + }
  53242. + if ((spdRawData[i] & 0x0f) == 0xC)
  53243. + {
  53244. + rightOfPoint = 66;
  53245. + }
  53246. + if ((spdRawData[i] & 0x0f) == 0xD)
  53247. + {
  53248. + rightOfPoint = 75;
  53249. + }
  53250. + mvOsOutput("Minimum Cycle Time At Max CL: %d.%d [ns]\n",
  53251. + leftOfPoint, rightOfPoint);
  53252. + break;
  53253. +/*----------------------------------------------------------------------------*/
  53254. +
  53255. + case 10: /* Clock To Data Out */
  53256. + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 10:100;
  53257. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  53258. + ((spdRawData[i] & 0x0f));
  53259. + leftOfPoint = time_tmp / div;
  53260. + rightOfPoint = time_tmp % div;
  53261. + mvOsOutput("Clock To Data Out: %d.%d [ns]\n",
  53262. + leftOfPoint, rightOfPoint);
  53263. + break;
  53264. +/*----------------------------------------------------------------------------*/
  53265. +
  53266. + case 11: /* Error Check Type */
  53267. + mvOsOutput("Error Check Type (0=NONE): %d\n",
  53268. + dimmInfo.errorCheckType);
  53269. + break;
  53270. +/*----------------------------------------------------------------------------*/
  53271. +
  53272. + case 12: /* Refresh Interval */
  53273. + mvOsOutput("Refresh Rate: %x\n",
  53274. + dimmInfo.refreshInterval);
  53275. + break;
  53276. +/*----------------------------------------------------------------------------*/
  53277. +
  53278. + case 13: /* Sdram Width */
  53279. + mvOsOutput("Sdram Width: %d bits\n",
  53280. + dimmInfo.sdramWidth);
  53281. + break;
  53282. +/*----------------------------------------------------------------------------*/
  53283. +
  53284. + case 14: /* Error Check Data Width */
  53285. + mvOsOutput("Error Check Data Width: %d bits\n",
  53286. + dimmInfo.errorCheckDataWidth);
  53287. + break;
  53288. +/*----------------------------------------------------------------------------*/
  53289. +
  53290. + case 15: /* Minimum Clock Delay is unsupported */
  53291. + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
  53292. + (dimmInfo.memoryType == MEM_TYPE_DDR1))
  53293. + {
  53294. + mvOsOutput("Minimum Clk Delay back to back: %d\n",
  53295. + spdRawData[i]);
  53296. + }
  53297. + break;
  53298. +/*----------------------------------------------------------------------------*/
  53299. +
  53300. + case 16: /* Burst Length Supported */
  53301. + /* SDRAM/DDR1:
  53302. + *******-******-******-******-******-******-******-*******
  53303. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  53304. + *******-******-******-******-******-******-******-*******
  53305. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
  53306. + *********************************************************/
  53307. + /* DDR2:
  53308. + *******-******-******-******-******-******-******-*******
  53309. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  53310. + *******-******-******-******-******-******-******-*******
  53311. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
  53312. + *********************************************************/
  53313. + mvOsOutput("Burst Length Supported: ");
  53314. + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
  53315. + (dimmInfo.memoryType == MEM_TYPE_DDR1))
  53316. + {
  53317. + if (dimmInfo.burstLengthSupported & BIT0)
  53318. + mvOsOutput("1, ");
  53319. + if (dimmInfo.burstLengthSupported & BIT1)
  53320. + mvOsOutput("2, ");
  53321. + }
  53322. + if (dimmInfo.burstLengthSupported & BIT2)
  53323. + mvOsOutput("4, ");
  53324. + if (dimmInfo.burstLengthSupported & BIT3)
  53325. + mvOsOutput("8, ");
  53326. +
  53327. + mvOsOutput(" Bit \n");
  53328. + break;
  53329. +/*----------------------------------------------------------------------------*/
  53330. +
  53331. + case 17: /* Number Of Banks On Each Device */
  53332. + mvOsOutput("Number Of Banks On Each Chip: %d\n",
  53333. + dimmInfo.numOfBanksOnEachDevice);
  53334. + break;
  53335. +/*----------------------------------------------------------------------------*/
  53336. +
  53337. + case 18: /* Suported Cas Latencies */
  53338. +
  53339. + /* SDRAM:
  53340. + *******-******-******-******-******-******-******-*******
  53341. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  53342. + *******-******-******-******-******-******-******-*******
  53343. + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
  53344. + ********************************************************/
  53345. +
  53346. + /* DDR 1:
  53347. + *******-******-******-******-******-******-******-*******
  53348. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  53349. + *******-******-******-******-******-******-******-*******
  53350. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  53351. + *********************************************************/
  53352. +
  53353. + /* DDR 2:
  53354. + *******-******-******-******-******-******-******-*******
  53355. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  53356. + *******-******-******-******-******-******-******-*******
  53357. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  53358. + *********************************************************/
  53359. +
  53360. + mvOsOutput("Suported Cas Latencies: (CL) ");
  53361. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53362. + {
  53363. + for (k = 0; k <=7; k++)
  53364. + {
  53365. + if (dimmInfo.suportedCasLatencies & (1 << k))
  53366. + mvOsOutput("%d, ", k+1);
  53367. + }
  53368. + }
  53369. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  53370. + {
  53371. + if (dimmInfo.suportedCasLatencies & BIT0)
  53372. + mvOsOutput("1, ");
  53373. + if (dimmInfo.suportedCasLatencies & BIT1)
  53374. + mvOsOutput("1.5, ");
  53375. + if (dimmInfo.suportedCasLatencies & BIT2)
  53376. + mvOsOutput("2, ");
  53377. + if (dimmInfo.suportedCasLatencies & BIT3)
  53378. + mvOsOutput("2.5, ");
  53379. + if (dimmInfo.suportedCasLatencies & BIT4)
  53380. + mvOsOutput("3, ");
  53381. + if (dimmInfo.suportedCasLatencies & BIT5)
  53382. + mvOsOutput("3.5, ");
  53383. + }
  53384. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  53385. + {
  53386. + if (dimmInfo.suportedCasLatencies & BIT2)
  53387. + mvOsOutput("2, ");
  53388. + if (dimmInfo.suportedCasLatencies & BIT3)
  53389. + mvOsOutput("3, ");
  53390. + if (dimmInfo.suportedCasLatencies & BIT4)
  53391. + mvOsOutput("4, ");
  53392. + if (dimmInfo.suportedCasLatencies & BIT5)
  53393. + mvOsOutput("5, ");
  53394. + }
  53395. + else
  53396. + mvOsOutput("?.?, ");
  53397. + mvOsOutput("\n");
  53398. + break;
  53399. +/*----------------------------------------------------------------------------*/
  53400. +
  53401. + case 20: /* DDR2 DIMM type info */
  53402. + if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  53403. + {
  53404. + if (dimmInfo.dimmTypeInfo & (BIT0 | BIT4))
  53405. + mvOsOutput("Registered DIMM (RDIMM)\n");
  53406. + else if (dimmInfo.dimmTypeInfo & (BIT1 | BIT5))
  53407. + mvOsOutput("Unbuffered DIMM (UDIMM)\n");
  53408. + else
  53409. + mvOsOutput("Unknown DIMM type.\n");
  53410. + }
  53411. +
  53412. + break;
  53413. +/*----------------------------------------------------------------------------*/
  53414. +
  53415. + case 21: /* SDRAM Modules Attributes */
  53416. + mvOsOutput("\nModule Attributes (SPD Byte 21): \n");
  53417. +
  53418. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53419. + {
  53420. + if (dimmInfo.dimmAttributes & BIT0)
  53421. + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
  53422. + else
  53423. + mvOsOutput(" Buffered Addr/Control Input: No\n");
  53424. +
  53425. + if (dimmInfo.dimmAttributes & BIT1)
  53426. + mvOsOutput(" Registered Addr/Control Input: Yes\n");
  53427. + else
  53428. + mvOsOutput(" Registered Addr/Control Input: No\n");
  53429. +
  53430. + if (dimmInfo.dimmAttributes & BIT2)
  53431. + mvOsOutput(" On-Card PLL (clock): Yes \n");
  53432. + else
  53433. + mvOsOutput(" On-Card PLL (clock): No \n");
  53434. +
  53435. + if (dimmInfo.dimmAttributes & BIT3)
  53436. + mvOsOutput(" Bufferd DQMB Input: Yes \n");
  53437. + else
  53438. + mvOsOutput(" Bufferd DQMB Inputs: No \n");
  53439. +
  53440. + if (dimmInfo.dimmAttributes & BIT4)
  53441. + mvOsOutput(" Registered DQMB Inputs: Yes \n");
  53442. + else
  53443. + mvOsOutput(" Registered DQMB Inputs: No \n");
  53444. +
  53445. + if (dimmInfo.dimmAttributes & BIT5)
  53446. + mvOsOutput(" Differential Clock Input: Yes \n");
  53447. + else
  53448. + mvOsOutput(" Differential Clock Input: No \n");
  53449. +
  53450. + if (dimmInfo.dimmAttributes & BIT6)
  53451. + mvOsOutput(" redundant Row Addressing: Yes \n");
  53452. + else
  53453. + mvOsOutput(" redundant Row Addressing: No \n");
  53454. + }
  53455. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  53456. + {
  53457. + if (dimmInfo.dimmAttributes & BIT0)
  53458. + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
  53459. + else
  53460. + mvOsOutput(" Buffered Addr/Control Input: No\n");
  53461. +
  53462. + if (dimmInfo.dimmAttributes & BIT1)
  53463. + mvOsOutput(" Registered Addr/Control Input: Yes\n");
  53464. + else
  53465. + mvOsOutput(" Registered Addr/Control Input: No\n");
  53466. +
  53467. + if (dimmInfo.dimmAttributes & BIT2)
  53468. + mvOsOutput(" On-Card PLL (clock): Yes \n");
  53469. + else
  53470. + mvOsOutput(" On-Card PLL (clock): No \n");
  53471. +
  53472. + if (dimmInfo.dimmAttributes & BIT3)
  53473. + mvOsOutput(" FET Switch On-Card Enabled: Yes \n");
  53474. + else
  53475. + mvOsOutput(" FET Switch On-Card Enabled: No \n");
  53476. +
  53477. + if (dimmInfo.dimmAttributes & BIT4)
  53478. + mvOsOutput(" FET Switch External Enabled: Yes \n");
  53479. + else
  53480. + mvOsOutput(" FET Switch External Enabled: No \n");
  53481. +
  53482. + if (dimmInfo.dimmAttributes & BIT5)
  53483. + mvOsOutput(" Differential Clock Input: Yes \n");
  53484. + else
  53485. + mvOsOutput(" Differential Clock Input: No \n");
  53486. + }
  53487. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  53488. + {
  53489. + mvOsOutput(" Number of Active Registers on the DIMM: %d\n",
  53490. + (dimmInfo.dimmAttributes & 0x3) + 1);
  53491. +
  53492. + mvOsOutput(" Number of PLLs on the DIMM: %d\n",
  53493. + ((dimmInfo.dimmAttributes) >> 2) & 0x3);
  53494. +
  53495. + if (dimmInfo.dimmAttributes & BIT4)
  53496. + mvOsOutput(" FET Switch External Enabled: Yes \n");
  53497. + else
  53498. + mvOsOutput(" FET Switch External Enabled: No \n");
  53499. +
  53500. + if (dimmInfo.dimmAttributes & BIT6)
  53501. + mvOsOutput(" Analysis probe installed: Yes \n");
  53502. + else
  53503. + mvOsOutput(" Analysis probe installed: No \n");
  53504. + }
  53505. +
  53506. + break;
  53507. +/*----------------------------------------------------------------------------*/
  53508. +
  53509. + case 22: /* Suported AutoPreCharge */
  53510. + mvOsOutput("\nModul Attributes (SPD Byte 22): \n");
  53511. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53512. + {
  53513. + if ( spdRawData[i] & BIT0 )
  53514. + mvOsOutput(" Early Ras Precharge: Yes \n");
  53515. + else
  53516. + mvOsOutput(" Early Ras Precharge: No \n");
  53517. +
  53518. + if ( spdRawData[i] & BIT1 )
  53519. + mvOsOutput(" AutoPreCharge: Yes \n");
  53520. + else
  53521. + mvOsOutput(" AutoPreCharge: No \n");
  53522. +
  53523. + if ( spdRawData[i] & BIT2 )
  53524. + mvOsOutput(" Precharge All: Yes \n");
  53525. + else
  53526. + mvOsOutput(" Precharge All: No \n");
  53527. +
  53528. + if ( spdRawData[i] & BIT3 )
  53529. + mvOsOutput(" Write 1/ReadBurst: Yes \n");
  53530. + else
  53531. + mvOsOutput(" Write 1/ReadBurst: No \n");
  53532. +
  53533. + if ( spdRawData[i] & BIT4 )
  53534. + mvOsOutput(" lower VCC tolerance: 5%%\n");
  53535. + else
  53536. + mvOsOutput(" lower VCC tolerance: 10%%\n");
  53537. +
  53538. + if ( spdRawData[i] & BIT5 )
  53539. + mvOsOutput(" upper VCC tolerance: 5%%\n");
  53540. + else
  53541. + mvOsOutput(" upper VCC tolerance: 10%%\n");
  53542. + }
  53543. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  53544. + {
  53545. + if ( spdRawData[i] & BIT0 )
  53546. + mvOsOutput(" Supports Weak Driver: Yes \n");
  53547. + else
  53548. + mvOsOutput(" Supports Weak Driver: No \n");
  53549. +
  53550. + if ( !(spdRawData[i] & BIT4) )
  53551. + mvOsOutput(" lower VCC tolerance: 0.2V\n");
  53552. +
  53553. + if ( !(spdRawData[i] & BIT5) )
  53554. + mvOsOutput(" upper VCC tolerance: 0.2V\n");
  53555. +
  53556. + if ( spdRawData[i] & BIT6 )
  53557. + mvOsOutput(" Concurrent Auto Preharge: Yes \n");
  53558. + else
  53559. + mvOsOutput(" Concurrent Auto Preharge: No \n");
  53560. +
  53561. + if ( spdRawData[i] & BIT7 )
  53562. + mvOsOutput(" Supports Fast AP: Yes \n");
  53563. + else
  53564. + mvOsOutput(" Supports Fast AP: No \n");
  53565. + }
  53566. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  53567. + {
  53568. + if ( spdRawData[i] & BIT0 )
  53569. + mvOsOutput(" Supports Weak Driver: Yes \n");
  53570. + else
  53571. + mvOsOutput(" Supports Weak Driver: No \n");
  53572. + }
  53573. + break;
  53574. +/*----------------------------------------------------------------------------*/
  53575. +
  53576. + case 23:
  53577. + /* Minimum Cycle Time At Maximum Cas Latancy Minus 1 (2nd highest CL) */
  53578. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  53579. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  53580. +
  53581. + /* DDR2 addition of right of point */
  53582. + if ((spdRawData[i] & 0x0f) == 0xA)
  53583. + {
  53584. + rightOfPoint = 25;
  53585. + }
  53586. + if ((spdRawData[i] & 0x0f) == 0xB)
  53587. + {
  53588. + rightOfPoint = 33;
  53589. + }
  53590. + if ((spdRawData[i] & 0x0f) == 0xC)
  53591. + {
  53592. + rightOfPoint = 66;
  53593. + }
  53594. + if ((spdRawData[i] & 0x0f) == 0xD)
  53595. + {
  53596. + rightOfPoint = 75;
  53597. + }
  53598. +
  53599. + mvOsOutput("Minimum Cycle Time At 2nd highest CasLatancy"
  53600. + "(0 = Not supported): %d.%d [ns]\n",
  53601. + leftOfPoint, rightOfPoint );
  53602. + break;
  53603. +/*----------------------------------------------------------------------------*/
  53604. +
  53605. + case 24: /* Clock To Data Out 2nd highest Cas Latency Value*/
  53606. + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 10:100;
  53607. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  53608. + ((spdRawData[i] & 0x0f));
  53609. + leftOfPoint = time_tmp / div;
  53610. + rightOfPoint = time_tmp % div;
  53611. + mvOsOutput("Clock To Data Out (2nd CL value): %d.%d [ns]\n",
  53612. + leftOfPoint, rightOfPoint);
  53613. + break;
  53614. +/*----------------------------------------------------------------------------*/
  53615. +
  53616. + case 25:
  53617. + /* Minimum Cycle Time At Maximum Cas Latancy Minus 2 (3rd highest CL) */
  53618. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53619. + {
  53620. + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
  53621. + rightOfPoint = (spdRawData[i] & 0x3) * 25;
  53622. + }
  53623. + else /* DDR1 or DDR2 */
  53624. + {
  53625. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  53626. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  53627. +
  53628. + /* DDR2 addition of right of point */
  53629. + if ((spdRawData[i] & 0x0f) == 0xA)
  53630. + {
  53631. + rightOfPoint = 25;
  53632. + }
  53633. + if ((spdRawData[i] & 0x0f) == 0xB)
  53634. + {
  53635. + rightOfPoint = 33;
  53636. + }
  53637. + if ((spdRawData[i] & 0x0f) == 0xC)
  53638. + {
  53639. + rightOfPoint = 66;
  53640. + }
  53641. + if ((spdRawData[i] & 0x0f) == 0xD)
  53642. + {
  53643. + rightOfPoint = 75;
  53644. + }
  53645. + }
  53646. + mvOsOutput("Minimum Cycle Time At 3rd highest CasLatancy"
  53647. + "(0 = Not supported): %d.%d [ns]\n",
  53648. + leftOfPoint, rightOfPoint );
  53649. + break;
  53650. +/*----------------------------------------------------------------------------*/
  53651. +
  53652. + case 26: /* Clock To Data Out 3rd highest Cas Latency Value*/
  53653. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53654. + {
  53655. + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
  53656. + rightOfPoint = (spdRawData[i] & 0x3) * 25;
  53657. + }
  53658. + else /* DDR1 or DDR2 */
  53659. + {
  53660. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  53661. + ((spdRawData[i] & 0x0f));
  53662. + leftOfPoint = 0;
  53663. + rightOfPoint = time_tmp;
  53664. + }
  53665. + mvOsOutput("Clock To Data Out (3rd CL value): %d.%2d[ns]\n",
  53666. + leftOfPoint, rightOfPoint );
  53667. + break;
  53668. +/*----------------------------------------------------------------------------*/
  53669. +
  53670. + case 27: /* Minimum Row Precharge Time */
  53671. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  53672. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  53673. + 0xff : 0xfc;
  53674. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  53675. + 0x00 : 0x03;
  53676. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  53677. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  53678. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 10ps Intervals*/
  53679. + trp_clocks = (temp + (busClkPs-1)) / busClkPs;
  53680. + mvOsOutput("Minimum Row Precharge Time [ns]: %d.%d = "
  53681. + "in Clk cycles %d\n",
  53682. + leftOfPoint, rightOfPoint, trp_clocks);
  53683. + break;
  53684. +/*----------------------------------------------------------------------------*/
  53685. +
  53686. + case 28: /* Minimum Row Active to Row Active Time */
  53687. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  53688. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  53689. + 0xff : 0xfc;
  53690. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  53691. + 0x00 : 0x03;
  53692. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  53693. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  53694. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
  53695. + trrd_clocks = (temp + (busClkPs-1)) / busClkPs;
  53696. + mvOsOutput("Minimum Row Active -To- Row Active Delay [ns]: "
  53697. + "%d.%d = in Clk cycles %d\n",
  53698. + leftOfPoint, rightOfPoint, trp_clocks);
  53699. + break;
  53700. +/*----------------------------------------------------------------------------*/
  53701. +
  53702. + case 29: /* Minimum Ras-To-Cas Delay */
  53703. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  53704. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  53705. + 0xff : 0xfc;
  53706. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  53707. + 0x00 : 0x03;
  53708. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  53709. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  53710. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
  53711. + trcd_clocks = (temp + (busClkPs-1) )/ busClkPs;
  53712. + mvOsOutput("Minimum Ras-To-Cas Delay [ns]: %d.%d = "
  53713. + "in Clk cycles %d\n",
  53714. + leftOfPoint, rightOfPoint, trp_clocks);
  53715. + break;
  53716. +/*----------------------------------------------------------------------------*/
  53717. +
  53718. + case 30: /* Minimum Ras Pulse Width */
  53719. + tras_clocks = (cas2ps(spdRawData[i])+(busClkPs-1)) / busClkPs;
  53720. + mvOsOutput("Minimum Ras Pulse Width [ns]: %d = "
  53721. + "in Clk cycles %d\n", spdRawData[i], tras_clocks);
  53722. + break;
  53723. +/*----------------------------------------------------------------------------*/
  53724. +
  53725. + case 31: /* Module Bank Density */
  53726. + mvOsOutput("Module Bank Density (more than 1= Multisize-Module):");
  53727. +
  53728. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53729. + {
  53730. + if (dimmInfo.dimmBankDensity & BIT0)
  53731. + mvOsOutput("1GB, ");
  53732. + if (dimmInfo.dimmBankDensity & BIT1)
  53733. + mvOsOutput("8MB, ");
  53734. + if (dimmInfo.dimmBankDensity & BIT2)
  53735. + mvOsOutput("16MB, ");
  53736. + if (dimmInfo.dimmBankDensity & BIT3)
  53737. + mvOsOutput("32MB, ");
  53738. + if (dimmInfo.dimmBankDensity & BIT4)
  53739. + mvOsOutput("64MB, ");
  53740. + if (dimmInfo.dimmBankDensity & BIT5)
  53741. + mvOsOutput("128MB, ");
  53742. + if (dimmInfo.dimmBankDensity & BIT6)
  53743. + mvOsOutput("256MB, ");
  53744. + if (dimmInfo.dimmBankDensity & BIT7)
  53745. + mvOsOutput("512MB, ");
  53746. + }
  53747. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  53748. + {
  53749. + if (dimmInfo.dimmBankDensity & BIT0)
  53750. + mvOsOutput("1GB, ");
  53751. + if (dimmInfo.dimmBankDensity & BIT1)
  53752. + mvOsOutput("2GB, ");
  53753. + if (dimmInfo.dimmBankDensity & BIT2)
  53754. + mvOsOutput("16MB, ");
  53755. + if (dimmInfo.dimmBankDensity & BIT3)
  53756. + mvOsOutput("32MB, ");
  53757. + if (dimmInfo.dimmBankDensity & BIT4)
  53758. + mvOsOutput("64MB, ");
  53759. + if (dimmInfo.dimmBankDensity & BIT5)
  53760. + mvOsOutput("128MB, ");
  53761. + if (dimmInfo.dimmBankDensity & BIT6)
  53762. + mvOsOutput("256MB, ");
  53763. + if (dimmInfo.dimmBankDensity & BIT7)
  53764. + mvOsOutput("512MB, ");
  53765. + }
  53766. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  53767. + {
  53768. + if (dimmInfo.dimmBankDensity & BIT0)
  53769. + mvOsOutput("1GB, ");
  53770. + if (dimmInfo.dimmBankDensity & BIT1)
  53771. + mvOsOutput("2GB, ");
  53772. + if (dimmInfo.dimmBankDensity & BIT2)
  53773. + mvOsOutput("4GB, ");
  53774. + if (dimmInfo.dimmBankDensity & BIT3)
  53775. + mvOsOutput("8GB, ");
  53776. + if (dimmInfo.dimmBankDensity & BIT4)
  53777. + mvOsOutput("16GB, ");
  53778. + if (dimmInfo.dimmBankDensity & BIT5)
  53779. + mvOsOutput("128MB, ");
  53780. + if (dimmInfo.dimmBankDensity & BIT6)
  53781. + mvOsOutput("256MB, ");
  53782. + if (dimmInfo.dimmBankDensity & BIT7)
  53783. + mvOsOutput("512MB, ");
  53784. + }
  53785. + mvOsOutput("\n");
  53786. + break;
  53787. +/*----------------------------------------------------------------------------*/
  53788. +
  53789. + case 32: /* Address And Command Setup Time (measured in ns/1000) */
  53790. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53791. + {
  53792. + rightOfPoint = (spdRawData[i] & 0x0f);
  53793. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  53794. + if(leftOfPoint > 7)
  53795. + {
  53796. + leftOfPoint *= -1;
  53797. + }
  53798. + }
  53799. + else /* DDR1 or DDR2 */
  53800. + {
  53801. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  53802. + ((spdRawData[i] & 0x0f));
  53803. + leftOfPoint = time_tmp / 100;
  53804. + rightOfPoint = time_tmp % 100;
  53805. + }
  53806. + mvOsOutput("Address And Command Setup Time [ns]: %d.%d\n",
  53807. + leftOfPoint, rightOfPoint);
  53808. + break;
  53809. +/*----------------------------------------------------------------------------*/
  53810. +
  53811. + case 33: /* Address And Command Hold Time */
  53812. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53813. + {
  53814. + rightOfPoint = (spdRawData[i] & 0x0f);
  53815. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  53816. + if(leftOfPoint > 7)
  53817. + {
  53818. + leftOfPoint *= -1;
  53819. + }
  53820. + }
  53821. + else /* DDR1 or DDR2 */
  53822. + {
  53823. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  53824. + ((spdRawData[i] & 0x0f));
  53825. + leftOfPoint = time_tmp / 100;
  53826. + rightOfPoint = time_tmp % 100;
  53827. + }
  53828. + mvOsOutput("Address And Command Hold Time [ns]: %d.%d\n",
  53829. + leftOfPoint, rightOfPoint);
  53830. + break;
  53831. +/*----------------------------------------------------------------------------*/
  53832. +
  53833. + case 34: /* Data Input Setup Time */
  53834. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53835. + {
  53836. + rightOfPoint = (spdRawData[i] & 0x0f);
  53837. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  53838. + if(leftOfPoint > 7)
  53839. + {
  53840. + leftOfPoint *= -1;
  53841. + }
  53842. + }
  53843. + else /* DDR1 or DDR2 */
  53844. + {
  53845. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  53846. + ((spdRawData[i] & 0x0f));
  53847. + leftOfPoint = time_tmp / 100;
  53848. + rightOfPoint = time_tmp % 100;
  53849. + }
  53850. + mvOsOutput("Data Input Setup Time [ns]: %d.%d\n",
  53851. + leftOfPoint, rightOfPoint);
  53852. + break;
  53853. +/*----------------------------------------------------------------------------*/
  53854. +
  53855. + case 35: /* Data Input Hold Time */
  53856. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  53857. + {
  53858. + rightOfPoint = (spdRawData[i] & 0x0f);
  53859. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  53860. + if(leftOfPoint > 7)
  53861. + {
  53862. + leftOfPoint *= -1;
  53863. + }
  53864. + }
  53865. + else /* DDR1 or DDR2 */
  53866. + {
  53867. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  53868. + ((spdRawData[i] & 0x0f));
  53869. + leftOfPoint = time_tmp / 100;
  53870. + rightOfPoint = time_tmp % 100;
  53871. + }
  53872. + mvOsOutput("Data Input Hold Time [ns]: %d.%d\n\n",
  53873. + leftOfPoint, rightOfPoint);
  53874. + break;
  53875. +/*----------------------------------------------------------------------------*/
  53876. +
  53877. + case 36: /* Relevant for DDR2 only: Write Recovery Time */
  53878. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> 2);
  53879. + rightOfPoint = (spdRawData[i] & maskRightOfPoint) * 25;
  53880. + mvOsOutput("Write Recovery Time [ns]: %d.%d\n",
  53881. + leftOfPoint, rightOfPoint);
  53882. + break;
  53883. +/*----------------------------------------------------------------------------*/
  53884. + }
  53885. +
  53886. +}
  53887. +
  53888. +
  53889. +/*
  53890. + * translate ns.ns/10 coding of SPD timing values
  53891. + * into ps unit values
  53892. + */
  53893. +/*******************************************************************************
  53894. +* cas2ps - Translate x.y ns parameter to pico-seconds values
  53895. +*
  53896. +* DESCRIPTION:
  53897. +* This function translates x.y nano seconds to its value in pico seconds.
  53898. +* For example 3.75ns will return 3750.
  53899. +*
  53900. +* INPUT:
  53901. +* spd_byte - DIMM SPD byte.
  53902. +*
  53903. +* OUTPUT:
  53904. +* None.
  53905. +*
  53906. +* RETURN:
  53907. +* value in pico seconds.
  53908. +*
  53909. +*******************************************************************************/
  53910. +static MV_U32 cas2ps(MV_U8 spd_byte)
  53911. +{
  53912. + MV_U32 ns, ns10;
  53913. +
  53914. + /* isolate upper nibble */
  53915. + ns = (spd_byte >> 4) & 0x0F;
  53916. + /* isolate lower nibble */
  53917. + ns10 = (spd_byte & 0x0F);
  53918. +
  53919. + if( ns10 < 10 ) {
  53920. + ns10 *= 10;
  53921. + }
  53922. + else if( ns10 == 10 )
  53923. + ns10 = 25;
  53924. + else if( ns10 == 11 )
  53925. + ns10 = 33;
  53926. + else if( ns10 == 12 )
  53927. + ns10 = 66;
  53928. + else if( ns10 == 13 )
  53929. + ns10 = 75;
  53930. + else
  53931. + {
  53932. + mvOsOutput("cas2ps Err. unsupported cycle time.\n");
  53933. + }
  53934. +
  53935. + return (ns*1000 + ns10*10);
  53936. +}
  53937. +
  53938. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h
  53939. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h 1970-01-01 01:00:00.000000000 +0100
  53940. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h 2010-08-05 22:02:24.034868021 +0200
  53941. @@ -0,0 +1,191 @@
  53942. +/*******************************************************************************
  53943. +Copyright (C) Marvell International Ltd. and its affiliates
  53944. +
  53945. +This software file (the "File") is owned and distributed by Marvell
  53946. +International Ltd. and/or its affiliates ("Marvell") under the following
  53947. +alternative licensing terms. Once you have made an election to distribute the
  53948. +File under one of the following license alternatives, please (i) delete this
  53949. +introductory statement regarding license alternatives, (ii) delete the two
  53950. +license alternatives that you have not elected to use and (iii) preserve the
  53951. +Marvell copyright notice above.
  53952. +
  53953. +********************************************************************************
  53954. +Marvell Commercial License Option
  53955. +
  53956. +If you received this File from Marvell and you have entered into a commercial
  53957. +license agreement (a "Commercial License") with Marvell, the File is licensed
  53958. +to you under the terms of the applicable Commercial License.
  53959. +
  53960. +********************************************************************************
  53961. +Marvell GPL License Option
  53962. +
  53963. +If you received this File from Marvell, you may opt to use, redistribute and/or
  53964. +modify this File in accordance with the terms and conditions of the General
  53965. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  53966. +available along with the File in the license.txt file or by writing to the Free
  53967. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  53968. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  53969. +
  53970. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  53971. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  53972. +DISCLAIMED. The GPL License provides additional details about this warranty
  53973. +disclaimer.
  53974. +********************************************************************************
  53975. +Marvell BSD License Option
  53976. +
  53977. +If you received this File from Marvell, you may opt to use, redistribute and/or
  53978. +modify this File under the following licensing terms.
  53979. +Redistribution and use in source and binary forms, with or without modification,
  53980. +are permitted provided that the following conditions are met:
  53981. +
  53982. + * Redistributions of source code must retain the above copyright notice,
  53983. + this list of conditions and the following disclaimer.
  53984. +
  53985. + * Redistributions in binary form must reproduce the above copyright
  53986. + notice, this list of conditions and the following disclaimer in the
  53987. + documentation and/or other materials provided with the distribution.
  53988. +
  53989. + * Neither the name of Marvell nor the names of its contributors may be
  53990. + used to endorse or promote products derived from this software without
  53991. + specific prior written permission.
  53992. +
  53993. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  53994. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  53995. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  53996. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  53997. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  53998. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  53999. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  54000. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  54001. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  54002. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  54003. +
  54004. +*******************************************************************************/
  54005. +
  54006. +#ifndef __INCmvDram
  54007. +#define __INCmvDram
  54008. +
  54009. +#include "ddr1_2/mvDramIf.h"
  54010. +#include "twsi/mvTwsi.h"
  54011. +
  54012. +#define MAX_DIMM_NUM 2
  54013. +#define SPD_SIZE 128
  54014. +
  54015. +/* Dimm spd offsets */
  54016. +#define DIMM_MEM_TYPE 2
  54017. +#define DIMM_ROW_NUM 3
  54018. +#define DIMM_COL_NUM 4
  54019. +#define DIMM_MODULE_BANK_NUM 5
  54020. +#define DIMM_DATA_WIDTH 6
  54021. +#define DIMM_VOLT_IF 8
  54022. +#define DIMM_MIN_CC_AT_MAX_CAS 9
  54023. +#define DIMM_ERR_CHECK_TYPE 11
  54024. +#define DIMM_REFRESH_INTERVAL 12
  54025. +#define DIMM_SDRAM_WIDTH 13
  54026. +#define DIMM_ERR_CHECK_DATA_WIDTH 14
  54027. +#define DIMM_MIN_CLK_DEL 15
  54028. +#define DIMM_BURST_LEN_SUP 16
  54029. +#define DIMM_DEV_BANK_NUM 17
  54030. +#define DIMM_SUP_CAL 18
  54031. +#define DIMM_DDR2_TYPE_INFORMATION 20 /* DDR2 only */
  54032. +#define DIMM_BUF_ADDR_CONT_IN 21
  54033. +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS1 23
  54034. +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS2 25
  54035. +#define DIMM_MIN_ROW_PRECHARGE_TIME 27
  54036. +#define DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE 28
  54037. +#define DIMM_MIN_RAS_TO_CAS_DELAY 29
  54038. +#define DIMM_MIN_RAS_PULSE_WIDTH 30
  54039. +#define DIMM_BANK_DENSITY 31
  54040. +#define DIMM_MIN_WRITE_RECOVERY_TIME 36
  54041. +#define DIMM_MIN_WRITE_TO_READ_CMD_DELAY 37
  54042. +#define DIMM_MIN_READ_TO_PRECH_CMD_DELAY 38
  54043. +#define DIMM_MIN_REFRESH_TO_ACTIVATE_CMD 42
  54044. +
  54045. +/* Dimm Memory Type values */
  54046. +#define DIMM_MEM_TYPE_SDRAM 0x4
  54047. +#define DIMM_MEM_TYPE_DDR1 0x7
  54048. +#define DIMM_MEM_TYPE_DDR2 0x8
  54049. +
  54050. +#define DIMM_MODULE_MANU_OFFS 64
  54051. +#define DIMM_MODULE_MANU_SIZE 8
  54052. +#define DIMM_MODULE_VEN_OFFS 73
  54053. +#define DIMM_MODULE_VEN_SIZE 25
  54054. +#define DIMM_MODULE_ID_OFFS 99
  54055. +#define DIMM_MODULE_ID_SIZE 18
  54056. +
  54057. +/* enumeration for voltage levels. */
  54058. +typedef enum _mvDimmVoltageIf
  54059. +{
  54060. + TTL_5V_TOLERANT,
  54061. + LVTTL,
  54062. + HSTL_1_5V,
  54063. + SSTL_3_3V,
  54064. + SSTL_2_5V,
  54065. + VOLTAGE_UNKNOWN,
  54066. +} MV_DIMM_VOLTAGE_IF;
  54067. +
  54068. +
  54069. +/* enumaration for SDRAM CAS Latencies. */
  54070. +typedef enum _mvDimmSdramCas
  54071. +{
  54072. + SD_CL_1 =1,
  54073. + SD_CL_2,
  54074. + SD_CL_3,
  54075. + SD_CL_4,
  54076. + SD_CL_5,
  54077. + SD_CL_6,
  54078. + SD_CL_7,
  54079. + SD_FAULT
  54080. +}MV_DIMM_SDRAM_CAS;
  54081. +
  54082. +
  54083. +/* DIMM information structure */
  54084. +typedef struct _mvDimmInfo
  54085. +{
  54086. + MV_MEMORY_TYPE memoryType; /* DDR or SDRAM */
  54087. +
  54088. + MV_U8 spdRawData[SPD_SIZE]; /* Content of SPD-EEPROM copied 1:1 */
  54089. +
  54090. + /* DIMM dimensions */
  54091. + MV_U32 numOfRowAddr;
  54092. + MV_U32 numOfColAddr;
  54093. + MV_U32 numOfModuleBanks;
  54094. + MV_U32 dataWidth;
  54095. + MV_U32 errorCheckType; /* ECC , PARITY..*/
  54096. + MV_U32 sdramWidth; /* 4,8,16 or 32 */
  54097. + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
  54098. + MV_U32 burstLengthSupported;
  54099. + MV_U32 numOfBanksOnEachDevice;
  54100. + MV_U32 suportedCasLatencies;
  54101. + MV_U32 refreshInterval;
  54102. + MV_U32 dimmBankDensity;
  54103. + MV_U32 dimmTypeInfo; /* DDR2 only */
  54104. + MV_U32 dimmAttributes;
  54105. +
  54106. + /* DIMM timing parameters */
  54107. + MV_U32 minCycleTimeAtMaxCasLatPs;
  54108. + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
  54109. + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
  54110. + MV_U32 minRowPrechargeTime;
  54111. + MV_U32 minRowActiveToRowActive;
  54112. + MV_U32 minRasToCasDelay;
  54113. + MV_U32 minRasPulseWidth;
  54114. + MV_U32 minWriteRecoveryTime; /* DDR2 only */
  54115. + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
  54116. + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
  54117. + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
  54118. +
  54119. + /* Parameters calculated from the extracted DIMM information */
  54120. + MV_U32 size; /* 16,64,128,256 or 512 MByte in MB units */
  54121. + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit in MB units */
  54122. + MV_U32 numberOfDevices;
  54123. +
  54124. +} MV_DIMM_INFO;
  54125. +
  54126. +
  54127. +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo);
  54128. +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo);
  54129. +MV_VOID dimmSpdPrint(MV_U32 dimmNum);
  54130. +MV_STATUS dimmSpdCpy(MV_VOID);
  54131. +
  54132. +#endif /* __INCmvDram */
  54133. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c
  54134. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c 1970-01-01 01:00:00.000000000 +0100
  54135. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c 2010-08-05 22:02:24.074868141 +0200
  54136. @@ -0,0 +1,1599 @@
  54137. +/*******************************************************************************
  54138. +Copyright (C) Marvell International Ltd. and its affiliates
  54139. +
  54140. +This software file (the "File") is owned and distributed by Marvell
  54141. +International Ltd. and/or its affiliates ("Marvell") under the following
  54142. +alternative licensing terms. Once you have made an election to distribute the
  54143. +File under one of the following license alternatives, please (i) delete this
  54144. +introductory statement regarding license alternatives, (ii) delete the two
  54145. +license alternatives that you have not elected to use and (iii) preserve the
  54146. +Marvell copyright notice above.
  54147. +
  54148. +********************************************************************************
  54149. +Marvell Commercial License Option
  54150. +
  54151. +If you received this File from Marvell and you have entered into a commercial
  54152. +license agreement (a "Commercial License") with Marvell, the File is licensed
  54153. +to you under the terms of the applicable Commercial License.
  54154. +
  54155. +********************************************************************************
  54156. +Marvell GPL License Option
  54157. +
  54158. +If you received this File from Marvell, you may opt to use, redistribute and/or
  54159. +modify this File in accordance with the terms and conditions of the General
  54160. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  54161. +available along with the File in the license.txt file or by writing to the Free
  54162. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  54163. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  54164. +
  54165. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  54166. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  54167. +DISCLAIMED. The GPL License provides additional details about this warranty
  54168. +disclaimer.
  54169. +********************************************************************************
  54170. +Marvell BSD License Option
  54171. +
  54172. +If you received this File from Marvell, you may opt to use, redistribute and/or
  54173. +modify this File under the following licensing terms.
  54174. +Redistribution and use in source and binary forms, with or without modification,
  54175. +are permitted provided that the following conditions are met:
  54176. +
  54177. + * Redistributions of source code must retain the above copyright notice,
  54178. + this list of conditions and the following disclaimer.
  54179. +
  54180. + * Redistributions in binary form must reproduce the above copyright
  54181. + notice, this list of conditions and the following disclaimer in the
  54182. + documentation and/or other materials provided with the distribution.
  54183. +
  54184. + * Neither the name of Marvell nor the names of its contributors may be
  54185. + used to endorse or promote products derived from this software without
  54186. + specific prior written permission.
  54187. +
  54188. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  54189. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  54190. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  54191. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  54192. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  54193. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  54194. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  54195. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  54196. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  54197. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  54198. +
  54199. +*******************************************************************************/
  54200. +
  54201. +
  54202. +/* includes */
  54203. +#include "ddr1_2/mvDramIf.h"
  54204. +#include "ctrlEnv/sys/mvCpuIf.h"
  54205. +
  54206. +
  54207. +
  54208. +#ifdef MV_DEBUG
  54209. +#define DB(x) x
  54210. +#else
  54211. +#define DB(x)
  54212. +#endif
  54213. +
  54214. +/* DRAM bank presence encoding */
  54215. +#define BANK_PRESENT_CS0 0x1
  54216. +#define BANK_PRESENT_CS0_CS1 0x3
  54217. +#define BANK_PRESENT_CS0_CS2 0x5
  54218. +#define BANK_PRESENT_CS0_CS1_CS2 0x7
  54219. +#define BANK_PRESENT_CS0_CS2_CS3 0xd
  54220. +#define BANK_PRESENT_CS0_CS2_CS3_CS4 0xf
  54221. +
  54222. +/* locals */
  54223. +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
  54224. +#if defined(MV_INC_BOARD_DDIM)
  54225. +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo);
  54226. +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas);
  54227. +static MV_U32 sdramModeRegCalc(MV_U32 minCas);
  54228. +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo);
  54229. +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo);
  54230. +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
  54231. +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk,
  54232. + MV_U32 forcedCl);
  54233. +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
  54234. + MV_U32 minCas, MV_U32 busClk);
  54235. +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
  54236. + MV_U32 busClk);
  54237. +
  54238. +/*******************************************************************************
  54239. +* mvDramIfDetect - Prepare DRAM interface configuration values.
  54240. +*
  54241. +* DESCRIPTION:
  54242. +* This function implements the full DRAM detection and timing
  54243. +* configuration for best system performance.
  54244. +* Since this routine runs from a ROM device (Boot Flash), its stack
  54245. +* resides on RAM, that might be the system DRAM. Changing DRAM
  54246. +* configuration values while keeping vital data in DRAM is risky. That
  54247. +* is why the function does not preform the configuration setting but
  54248. +* prepare those in predefined 32bit registers (in this case IDMA
  54249. +* registers are used) for other routine to perform the settings.
  54250. +* The function will call for board DRAM SPD information for each DRAM
  54251. +* chip select. The function will then analyze those SPD parameters of
  54252. +* all DRAM banks in order to decide on DRAM configuration compatible
  54253. +* for all DRAM banks.
  54254. +* The function will set the CPU DRAM address decode registers.
  54255. +* Note: This routine prepares values that will overide configuration of
  54256. +* mvDramBasicAsmInit().
  54257. +*
  54258. +* INPUT:
  54259. +* forcedCl - Forced CAL Latency. If equal to zero, do not force.
  54260. +*
  54261. +* OUTPUT:
  54262. +* None.
  54263. +*
  54264. +* RETURN:
  54265. +* None.
  54266. +*
  54267. +*******************************************************************************/
  54268. +MV_STATUS mvDramIfDetect(MV_U32 forcedCl)
  54269. +{
  54270. + MV_U32 retVal = MV_OK; /* return value */
  54271. + MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
  54272. + MV_U32 busClk, size, base = 0, i, temp, deviceW, dimmW;
  54273. + MV_U8 minCas;
  54274. + MV_DRAM_DEC_WIN dramDecWin;
  54275. +
  54276. + dramDecWin.addrWin.baseHigh = 0;
  54277. +
  54278. + busClk = mvBoardSysClkGet();
  54279. +
  54280. + if (0 == busClk)
  54281. + {
  54282. + mvOsPrintf("Dram: ERR. Can't detect system clock! \n");
  54283. + return MV_ERROR;
  54284. + }
  54285. +
  54286. + /* Close DRAM banks except bank 0 (in case code is excecuting from it...) */
  54287. +#if defined(MV_INCLUDE_SDRAM_CS1)
  54288. + for(i= SDRAM_CS1; i < MV_DRAM_MAX_CS; i++)
  54289. + mvCpuIfTargetWinEnable(i, MV_FALSE);
  54290. +#endif
  54291. +
  54292. + /* we will use bank 0 as the representative of the all the DRAM banks, */
  54293. + /* since bank 0 must exist. */
  54294. + for(i = 0; i < MV_DRAM_MAX_CS; i++)
  54295. + {
  54296. + /* if Bank exist */
  54297. + if(MV_OK == mvDramBankInfoGet(i, &bankInfo[i]))
  54298. + {
  54299. + /* check it isn't SDRAM */
  54300. + if(bankInfo[i].memoryType == MEM_TYPE_SDRAM)
  54301. + {
  54302. + mvOsPrintf("Dram: ERR. SDRAM type not supported !!!\n");
  54303. + return MV_ERROR;
  54304. + }
  54305. + /* All banks must support registry in order to activate it */
  54306. + if(bankInfo[i].registeredAddrAndControlInputs !=
  54307. + bankInfo[0].registeredAddrAndControlInputs)
  54308. + {
  54309. + mvOsPrintf("Dram: ERR. different Registered settings !!!\n");
  54310. + return MV_ERROR;
  54311. + }
  54312. +
  54313. + /* Init the CPU window decode */
  54314. + /* Note that the size in Bank info is in MB units */
  54315. + /* Note that the Dimm width might be different then the device DRAM width */
  54316. + temp = MV_REG_READ(SDRAM_CONFIG_REG);
  54317. +
  54318. + deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_16BIT )? 16 : 32;
  54319. + dimmW = bankInfo[0].dataWidth - (bankInfo[0].dataWidth % 16);
  54320. + size = ((bankInfo[i].size << 20) / (dimmW/deviceW));
  54321. +
  54322. + /* We can not change DRAM window settings while excecuting */
  54323. + /* code from it. That is why we skip the DRAM CS[0], saving */
  54324. + /* it to the ROM configuration routine */
  54325. + if(i == SDRAM_CS0)
  54326. + {
  54327. + MV_U32 sizeToReg;
  54328. +
  54329. + /* Translate the given window size to register format */
  54330. + sizeToReg = ctrlSizeToReg(size, SCSR_SIZE_ALIGNMENT);
  54331. +
  54332. + /* Size parameter validity check. */
  54333. + if (-1 == sizeToReg)
  54334. + {
  54335. + mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n"
  54336. + ,i);
  54337. + return MV_BAD_PARAM;
  54338. + }
  54339. +
  54340. + /* Size is located at upper 16 bits */
  54341. + sizeToReg <<= SCSR_SIZE_OFFS;
  54342. +
  54343. + /* enable it */
  54344. + sizeToReg |= SCSR_WIN_EN;
  54345. +
  54346. + MV_REG_WRITE(DRAM_BUF_REG0, sizeToReg);
  54347. + }
  54348. + else
  54349. + {
  54350. + dramDecWin.addrWin.baseLow = base;
  54351. + dramDecWin.addrWin.size = size;
  54352. + dramDecWin.enable = MV_TRUE;
  54353. +
  54354. + if (MV_OK != mvDramIfWinSet(SDRAM_CS0 + i, &dramDecWin))
  54355. + {
  54356. + mvOsPrintf("Dram: ERR. Fail to set bank %d!!!\n",
  54357. + SDRAM_CS0 + i);
  54358. + return MV_ERROR;
  54359. + }
  54360. + }
  54361. +
  54362. + base += size;
  54363. +
  54364. + /* update the suportedCasLatencies mask */
  54365. + bankInfo[0].suportedCasLatencies &= bankInfo[i].suportedCasLatencies;
  54366. +
  54367. + }
  54368. + else
  54369. + {
  54370. + if( i == 0 ) /* bank 0 doesn't exist */
  54371. + {
  54372. + mvOsPrintf("Dram: ERR. Fail to detect bank 0 !!!\n");
  54373. + return MV_ERROR;
  54374. + }
  54375. + else
  54376. + {
  54377. + DB(mvOsPrintf("Dram: Could not find bank %d\n", i));
  54378. + bankInfo[i].size = 0; /* Mark this bank as non exist */
  54379. + }
  54380. + }
  54381. + }
  54382. +
  54383. + /* calculate minimum CAS */
  54384. + minCas = minCasCalc(&bankInfo[0], busClk, forcedCl);
  54385. + if (0 == minCas)
  54386. + {
  54387. + mvOsOutput("Dram: Warn: Could not find CAS compatible to SysClk %dMhz\n",
  54388. + (busClk / 1000000));
  54389. +
  54390. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  54391. + {
  54392. + minCas = DDR2_CL_4; /* Continue with this CAS */
  54393. + mvOsPrintf("Set default CAS latency 4\n");
  54394. + }
  54395. + else
  54396. + {
  54397. + minCas = DDR1_CL_3; /* Continue with this CAS */
  54398. + mvOsPrintf("Set default CAS latency 3\n");
  54399. + }
  54400. + }
  54401. +
  54402. + /* calc SDRAM_CONFIG_REG and save it to temp register */
  54403. + temp = sdramConfigRegCalc(&bankInfo[0], busClk);
  54404. + if(-1 == temp)
  54405. + {
  54406. + mvOsPrintf("Dram: ERR. sdramConfigRegCalc failed !!!\n");
  54407. + return MV_ERROR;
  54408. + }
  54409. + MV_REG_WRITE(DRAM_BUF_REG1, temp);
  54410. +
  54411. + /* calc SDRAM_MODE_REG and save it to temp register */
  54412. + temp = sdramModeRegCalc(minCas);
  54413. + if(-1 == temp)
  54414. + {
  54415. + mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n");
  54416. + return MV_ERROR;
  54417. + }
  54418. + MV_REG_WRITE(DRAM_BUF_REG2, temp);
  54419. +
  54420. + /* calc SDRAM_EXTENDED_MODE_REG and save it to temp register */
  54421. + temp = sdramExtModeRegCalc(&bankInfo[0]);
  54422. + if(-1 == temp)
  54423. + {
  54424. + mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n");
  54425. + return MV_ERROR;
  54426. + }
  54427. + MV_REG_WRITE(DRAM_BUF_REG10, temp);
  54428. +
  54429. + /* calc D_UNIT_CONTROL_LOW and save it to temp register */
  54430. + temp = dunitCtrlLowRegCalc(&bankInfo[0], minCas);
  54431. + if(-1 == temp)
  54432. + {
  54433. + mvOsPrintf("Dram: ERR. dunitCtrlLowRegCalc failed !!!\n");
  54434. + return MV_ERROR;
  54435. + }
  54436. + MV_REG_WRITE(DRAM_BUF_REG3, temp);
  54437. +
  54438. + /* calc SDRAM_ADDR_CTRL_REG and save it to temp register */
  54439. + temp = sdramAddrCtrlRegCalc(&bankInfo[0]);
  54440. + if(-1 == temp)
  54441. + {
  54442. + mvOsPrintf("Dram: ERR. sdramAddrCtrlRegCalc failed !!!\n");
  54443. + return MV_ERROR;
  54444. + }
  54445. + MV_REG_WRITE(DRAM_BUF_REG4, temp);
  54446. +
  54447. + /* calc SDRAM_TIMING_CTRL_LOW_REG and save it to temp register */
  54448. + temp = sdramTimeCtrlLowRegCalc(&bankInfo[0], minCas, busClk);
  54449. + if(-1 == temp)
  54450. + {
  54451. + mvOsPrintf("Dram: ERR. sdramTimeCtrlLowRegCalc failed !!!\n");
  54452. + return MV_ERROR;
  54453. + }
  54454. + MV_REG_WRITE(DRAM_BUF_REG5, temp);
  54455. +
  54456. + /* calc SDRAM_TIMING_CTRL_HIGH_REG and save it to temp register */
  54457. + temp = sdramTimeCtrlHighRegCalc(&bankInfo[0], busClk);
  54458. + if(-1 == temp)
  54459. + {
  54460. + mvOsPrintf("Dram: ERR. sdramTimeCtrlHighRegCalc failed !!!\n");
  54461. + return MV_ERROR;
  54462. + }
  54463. + MV_REG_WRITE(DRAM_BUF_REG6, temp);
  54464. +
  54465. + /* Config DDR2 On Die Termination (ODT) registers */
  54466. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  54467. + {
  54468. + sdramDDr2OdtConfig(bankInfo);
  54469. + }
  54470. +
  54471. + /* Note that DDR SDRAM Address/Control and Data pad calibration */
  54472. + /* settings is done in mvSdramIfConfig.s */
  54473. +
  54474. + return retVal;
  54475. +}
  54476. +
  54477. +/*******************************************************************************
  54478. +* minCasCalc - Calculate the Minimum CAS latency which can be used.
  54479. +*
  54480. +* DESCRIPTION:
  54481. +* Calculate the minimum CAS latency that can be used, base on the DRAM
  54482. +* parameters and the SDRAM bus Clock freq.
  54483. +*
  54484. +* INPUT:
  54485. +* busClk - the DRAM bus Clock.
  54486. +* pBankInfo - bank info parameters.
  54487. +*
  54488. +* OUTPUT:
  54489. +* None
  54490. +*
  54491. +* RETURN:
  54492. +* The minimum CAS Latency. The function returns 0 if max CAS latency
  54493. +* supported by banks is incompatible with system bus clock frequancy.
  54494. +*
  54495. +*******************************************************************************/
  54496. +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk,
  54497. + MV_U32 forcedCl)
  54498. +{
  54499. + MV_U32 count = 1, j;
  54500. + MV_U32 busClkPs = 1000000000 / (busClk / 1000); /* in ps units */
  54501. + MV_U32 startBit, stopBit;
  54502. +
  54503. + /* DDR 1:
  54504. + *******-******-******-******-******-******-******-*******
  54505. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54506. + *******-******-******-******-******-******-******-*******
  54507. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  54508. + *********************************************************/
  54509. +
  54510. + /* DDR 2:
  54511. + *******-******-******-******-******-******-******-*******
  54512. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54513. + *******-******-******-******-******-******-******-*******
  54514. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  54515. + *********************************************************/
  54516. +
  54517. +
  54518. + /* If we are asked to use the forced CAL */
  54519. + if (forcedCl)
  54520. + {
  54521. + mvOsPrintf("DRAM: Using forced CL %d.%d\n", (forcedCl / 10),
  54522. + (forcedCl % 10));
  54523. +
  54524. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  54525. + {
  54526. + if (forcedCl == 30)
  54527. + pBankInfo->suportedCasLatencies = 0x08;
  54528. + else if (forcedCl == 40)
  54529. + pBankInfo->suportedCasLatencies = 0x10;
  54530. + else
  54531. + {
  54532. + mvOsPrintf("Forced CL %d.%d not supported. Set default CL 4\n",
  54533. + (forcedCl / 10), (forcedCl % 10));
  54534. + pBankInfo->suportedCasLatencies = 0x10;
  54535. + }
  54536. + }
  54537. + else
  54538. + {
  54539. + if (forcedCl == 15)
  54540. + pBankInfo->suportedCasLatencies = 0x02;
  54541. + else if (forcedCl == 20)
  54542. + pBankInfo->suportedCasLatencies = 0x04;
  54543. + else if (forcedCl == 25)
  54544. + pBankInfo->suportedCasLatencies = 0x08;
  54545. + else if (forcedCl == 30)
  54546. + pBankInfo->suportedCasLatencies = 0x10;
  54547. + else if (forcedCl == 40)
  54548. + pBankInfo->suportedCasLatencies = 0x40;
  54549. + else
  54550. + {
  54551. + mvOsPrintf("Forced CL %d.%d not supported. Set default CL 3\n",
  54552. + (forcedCl / 10), (forcedCl % 10));
  54553. + pBankInfo->suportedCasLatencies = 0x10;
  54554. + }
  54555. + }
  54556. +
  54557. + return pBankInfo->suportedCasLatencies;
  54558. + }
  54559. +
  54560. + /* go over the supported cas mask from Max Cas down and check if the */
  54561. + /* SysClk stands in its time requirments. */
  54562. +
  54563. +
  54564. + DB(mvOsPrintf("Dram: minCasCalc supported mask = %x busClkPs = %x \n",
  54565. + pBankInfo->suportedCasLatencies,busClkPs ));
  54566. + for(j = 7; j > 0; j--)
  54567. + {
  54568. + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
  54569. + {
  54570. + /* Reset the bits for CL incompatible for the sysClk */
  54571. + switch (count)
  54572. + {
  54573. + case 1:
  54574. + if (pBankInfo->minCycleTimeAtMaxCasLatPs > busClkPs)
  54575. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  54576. + count++;
  54577. + break;
  54578. + case 2:
  54579. + if (pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
  54580. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  54581. + count++;
  54582. + break;
  54583. + case 3:
  54584. + if (pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
  54585. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  54586. + count++;
  54587. + break;
  54588. + default:
  54589. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  54590. + break;
  54591. + }
  54592. + }
  54593. + }
  54594. +
  54595. + DB(mvOsPrintf("Dram: minCasCalc support = %x (after SysCC calc)\n",
  54596. + pBankInfo->suportedCasLatencies ));
  54597. +
  54598. + /* SDRAM DDR1 controller supports CL 1.5 to 3.5 */
  54599. + /* SDRAM DDR2 controller supports CL 3 to 5 */
  54600. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  54601. + {
  54602. + startBit = 3; /* DDR2 support CL start with CL3 (bit 3) */
  54603. + stopBit = 5; /* DDR2 support CL stops with CL5 (bit 5) */
  54604. + }
  54605. + else
  54606. + {
  54607. + startBit = 1; /* DDR1 support CL start with CL1.5 (bit 3) */
  54608. + stopBit = 4; /* DDR1 support CL stops with CL3 (bit 4) */
  54609. + }
  54610. +
  54611. + for(j = startBit; j <= stopBit ; j++)
  54612. + {
  54613. + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
  54614. + {
  54615. + DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
  54616. + return (BIT0 << j);
  54617. + }
  54618. + }
  54619. +
  54620. + return 0;
  54621. +}
  54622. +
  54623. +/*******************************************************************************
  54624. +* sdramConfigRegCalc - Calculate sdram config register
  54625. +*
  54626. +* DESCRIPTION: Calculate sdram config register optimized value based
  54627. +* on the bank info parameters.
  54628. +*
  54629. +* INPUT:
  54630. +* pBankInfo - sdram bank parameters
  54631. +*
  54632. +* OUTPUT:
  54633. +* None
  54634. +*
  54635. +* RETURN:
  54636. +* sdram config reg value.
  54637. +*
  54638. +*******************************************************************************/
  54639. +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
  54640. +{
  54641. + MV_U32 sdramConfig = 0;
  54642. + MV_U32 refreshPeriod;
  54643. +
  54644. + busClk /= 1000000; /* we work with busClk in MHz */
  54645. +
  54646. + sdramConfig = MV_REG_READ(SDRAM_CONFIG_REG);
  54647. +
  54648. + /* figure out the memory refresh internal */
  54649. + switch (pBankInfo->refreshInterval & 0xf)
  54650. + {
  54651. + case 0x0: /* refresh period is 15.625 usec */
  54652. + refreshPeriod = 15625;
  54653. + break;
  54654. + case 0x1: /* refresh period is 3.9 usec */
  54655. + refreshPeriod = 3900;
  54656. + break;
  54657. + case 0x2: /* refresh period is 7.8 usec */
  54658. + refreshPeriod = 7800;
  54659. + break;
  54660. + case 0x3: /* refresh period is 31.3 usec */
  54661. + refreshPeriod = 31300;
  54662. + break;
  54663. + case 0x4: /* refresh period is 62.5 usec */
  54664. + refreshPeriod = 62500;
  54665. + break;
  54666. + case 0x5: /* refresh period is 125 usec */
  54667. + refreshPeriod = 125000;
  54668. + break;
  54669. + default: /* refresh period undefined */
  54670. + mvOsPrintf("Dram: ERR. DRAM refresh period is unknown!\n");
  54671. + return -1;
  54672. + }
  54673. +
  54674. + /* Now the refreshPeriod is in register format value */
  54675. + refreshPeriod = (busClk * refreshPeriod) / 1000;
  54676. +
  54677. + DB(mvOsPrintf("Dram: sdramConfigRegCalc calculated refresh interval %0x\n",
  54678. + refreshPeriod));
  54679. +
  54680. + /* make sure the refresh value is only 14 bits */
  54681. + if(refreshPeriod > SDRAM_REFRESH_MAX)
  54682. + {
  54683. + refreshPeriod = SDRAM_REFRESH_MAX;
  54684. + DB(mvOsPrintf("Dram: sdramConfigRegCalc adjusted refresh interval %0x\n",
  54685. + refreshPeriod));
  54686. + }
  54687. +
  54688. + /* Clear the refresh field */
  54689. + sdramConfig &= ~SDRAM_REFRESH_MASK;
  54690. +
  54691. + /* Set new value to refresh field */
  54692. + sdramConfig |= (refreshPeriod & SDRAM_REFRESH_MASK);
  54693. +
  54694. + /* registered DRAM ? */
  54695. + if ( pBankInfo->registeredAddrAndControlInputs )
  54696. + {
  54697. + /* it's registered DRAM, so set the reg. DRAM bit */
  54698. + sdramConfig |= SDRAM_REGISTERED;
  54699. + mvOsPrintf("DRAM Attribute: Registered address and control inputs.\n");
  54700. + }
  54701. +
  54702. + /* set DDR SDRAM devices configuration */
  54703. + sdramConfig &= ~SDRAM_DCFG_MASK; /* Clear Dcfg field */
  54704. +
  54705. + switch (pBankInfo->sdramWidth)
  54706. + {
  54707. + case 8: /* memory is x8 */
  54708. + sdramConfig |= SDRAM_DCFG_X8_DEV;
  54709. + DB(mvOsPrintf("Dram: sdramConfigRegCalc SDRAM device width x8\n"));
  54710. + break;
  54711. + case 16:
  54712. + sdramConfig |= SDRAM_DCFG_X16_DEV;
  54713. + DB(mvOsPrintf("Dram: sdramConfigRegCalc SDRAM device width x16\n"));
  54714. + break;
  54715. + default: /* memory width unsupported */
  54716. + mvOsPrintf("Dram: ERR. DRAM chip width is unknown!\n");
  54717. + return -1;
  54718. + }
  54719. +
  54720. + /* Set static default settings */
  54721. + sdramConfig |= SDRAM_CONFIG_DV;
  54722. +
  54723. + DB(mvOsPrintf("Dram: sdramConfigRegCalc set sdramConfig to 0x%x\n",
  54724. + sdramConfig));
  54725. +
  54726. + return sdramConfig;
  54727. +}
  54728. +
  54729. +/*******************************************************************************
  54730. +* sdramModeRegCalc - Calculate sdram mode register
  54731. +*
  54732. +* DESCRIPTION: Calculate sdram mode register optimized value based
  54733. +* on the bank info parameters and the minCas.
  54734. +*
  54735. +* INPUT:
  54736. +* minCas - minimum CAS supported.
  54737. +*
  54738. +* OUTPUT:
  54739. +* None
  54740. +*
  54741. +* RETURN:
  54742. +* sdram mode reg value.
  54743. +*
  54744. +*******************************************************************************/
  54745. +static MV_U32 sdramModeRegCalc(MV_U32 minCas)
  54746. +{
  54747. + MV_U32 sdramMode;
  54748. +
  54749. + sdramMode = MV_REG_READ(SDRAM_MODE_REG);
  54750. +
  54751. + /* Clear CAS Latency field */
  54752. + sdramMode &= ~SDRAM_CL_MASK;
  54753. +
  54754. + mvOsPrintf("DRAM CAS Latency ");
  54755. +
  54756. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  54757. + {
  54758. + switch (minCas)
  54759. + {
  54760. + case DDR2_CL_3:
  54761. + sdramMode |= SDRAM_DDR2_CL_3;
  54762. + mvOsPrintf("3.\n");
  54763. + break;
  54764. + case DDR2_CL_4:
  54765. + sdramMode |= SDRAM_DDR2_CL_4;
  54766. + mvOsPrintf("4.\n");
  54767. + break;
  54768. + case DDR2_CL_5:
  54769. + sdramMode |= SDRAM_DDR2_CL_5;
  54770. + mvOsPrintf("5.\n");
  54771. + break;
  54772. + default:
  54773. + mvOsPrintf("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
  54774. + return -1;
  54775. + }
  54776. + sdramMode |= DDR2_MODE_REG_DV;
  54777. + }
  54778. + else /* DDR1 */
  54779. + {
  54780. + switch (minCas)
  54781. + {
  54782. + case DDR1_CL_1_5:
  54783. + sdramMode |= SDRAM_DDR1_CL_1_5;
  54784. + mvOsPrintf("1.5\n");
  54785. + break;
  54786. + case DDR1_CL_2:
  54787. + sdramMode |= SDRAM_DDR1_CL_2;
  54788. + mvOsPrintf("2\n");
  54789. + break;
  54790. + case DDR1_CL_2_5:
  54791. + sdramMode |= SDRAM_DDR1_CL_2_5;
  54792. + mvOsPrintf("2.5\n");
  54793. + break;
  54794. + case DDR1_CL_3:
  54795. + sdramMode |= SDRAM_DDR1_CL_3;
  54796. + mvOsPrintf("3\n");
  54797. + break;
  54798. + case DDR1_CL_4:
  54799. + sdramMode |= SDRAM_DDR1_CL_4;
  54800. + mvOsPrintf("4\n");
  54801. + break;
  54802. + default:
  54803. + mvOsPrintf("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
  54804. + return -1;
  54805. + }
  54806. + sdramMode |= DDR1_MODE_REG_DV;
  54807. + }
  54808. +
  54809. + DB(mvOsPrintf("nsdramModeRegCalc register 0x%x\n", sdramMode ));
  54810. +
  54811. + return sdramMode;
  54812. +}
  54813. +
  54814. +/*******************************************************************************
  54815. +* sdramExtModeRegCalc - Calculate sdram Extended mode register
  54816. +*
  54817. +* DESCRIPTION:
  54818. +* Return sdram Extended mode register value based
  54819. +* on the bank info parameters and bank presence.
  54820. +*
  54821. +* INPUT:
  54822. +* pBankInfo - sdram bank parameters
  54823. +*
  54824. +* OUTPUT:
  54825. +* None
  54826. +*
  54827. +* RETURN:
  54828. +* sdram Extended mode reg value.
  54829. +*
  54830. +*******************************************************************************/
  54831. +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo)
  54832. +{
  54833. + MV_U32 populateBanks = 0;
  54834. + int bankNum;
  54835. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  54836. + {
  54837. + /* Represent the populate banks in binary form */
  54838. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  54839. + {
  54840. + if (0 != pBankInfo[bankNum].size)
  54841. + {
  54842. + populateBanks |= (1 << bankNum);
  54843. + }
  54844. + }
  54845. +
  54846. + switch(populateBanks)
  54847. + {
  54848. + case(BANK_PRESENT_CS0):
  54849. + return DDR_SDRAM_EXT_MODE_CS0_DV;
  54850. +
  54851. + case(BANK_PRESENT_CS0_CS1):
  54852. + return DDR_SDRAM_EXT_MODE_CS0_DV;
  54853. +
  54854. + case(BANK_PRESENT_CS0_CS2):
  54855. + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
  54856. +
  54857. + case(BANK_PRESENT_CS0_CS1_CS2):
  54858. + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
  54859. +
  54860. + case(BANK_PRESENT_CS0_CS2_CS3):
  54861. + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
  54862. +
  54863. + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
  54864. + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
  54865. +
  54866. + default:
  54867. + mvOsPrintf("sdramExtModeRegCalc: Invalid DRAM bank presence\n");
  54868. + return -1;
  54869. + }
  54870. + }
  54871. + return 0;
  54872. +}
  54873. +
  54874. +/*******************************************************************************
  54875. +* dunitCtrlLowRegCalc - Calculate sdram dunit control low register
  54876. +*
  54877. +* DESCRIPTION: Calculate sdram dunit control low register optimized value based
  54878. +* on the bank info parameters and the minCas.
  54879. +*
  54880. +* INPUT:
  54881. +* pBankInfo - sdram bank parameters
  54882. +* minCas - minimum CAS supported.
  54883. +*
  54884. +* OUTPUT:
  54885. +* None
  54886. +*
  54887. +* RETURN:
  54888. +* sdram dunit control low reg value.
  54889. +*
  54890. +*******************************************************************************/
  54891. +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas)
  54892. +{
  54893. + MV_U32 dunitCtrlLow;
  54894. +
  54895. + dunitCtrlLow = MV_REG_READ(SDRAM_DUNIT_CTRL_REG);
  54896. +
  54897. + /* Clear StBurstDel field */
  54898. + dunitCtrlLow &= ~SDRAM_ST_BURST_DEL_MASK;
  54899. +
  54900. +#ifdef MV_88W8660
  54901. + /* Clear address/control output timing field */
  54902. + dunitCtrlLow &= ~SDRAM_CTRL_POS_RISE;
  54903. +#endif /* MV_88W8660 */
  54904. +
  54905. + DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc\n"));
  54906. +
  54907. + /* For proper sample of read data set the Dunit Control register's */
  54908. + /* stBurstDel bits [27:24] */
  54909. + /********-********-********-********-********-*********
  54910. + * CL=1.5 | CL=2 | CL=2.5 | CL=3 | CL=4 | CL=5 *
  54911. + *********-********-********-********-********-*********
  54912. +Not Reg. * 0011 | 0011 | 0100 | 0100 | 0101 | TBD *
  54913. + *********-********-********-********-********-*********
  54914. +Registered * 0100 | 0100 | 0101 | 0101 | 0110 | TBD *
  54915. + *********-********-********-********-********-*********/
  54916. +
  54917. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  54918. + {
  54919. + switch (minCas)
  54920. + {
  54921. + case DDR2_CL_3:
  54922. + /* registerd DDR SDRAM? */
  54923. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  54924. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  54925. + else
  54926. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  54927. + break;
  54928. + case DDR2_CL_4:
  54929. + /* registerd DDR SDRAM? */
  54930. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  54931. + dunitCtrlLow |= 0x6 << SDRAM_ST_BURST_DEL_OFFS;
  54932. + else
  54933. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  54934. + break;
  54935. + default:
  54936. + mvOsPrintf("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n",
  54937. + minCas);
  54938. + return -1;
  54939. + }
  54940. + }
  54941. + else /* DDR1 */
  54942. + {
  54943. + switch (minCas)
  54944. + {
  54945. + case DDR1_CL_1_5:
  54946. + /* registerd DDR SDRAM? */
  54947. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  54948. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  54949. + else
  54950. + dunitCtrlLow |= 0x3 << SDRAM_ST_BURST_DEL_OFFS;
  54951. + break;
  54952. + case DDR1_CL_2:
  54953. + /* registerd DDR SDRAM? */
  54954. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  54955. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  54956. + else
  54957. + dunitCtrlLow |= 0x3 << SDRAM_ST_BURST_DEL_OFFS;
  54958. + break;
  54959. + case DDR1_CL_2_5:
  54960. + /* registerd DDR SDRAM? */
  54961. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  54962. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  54963. + else
  54964. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  54965. + break;
  54966. + case DDR1_CL_3:
  54967. + /* registerd DDR SDRAM? */
  54968. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  54969. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  54970. + else
  54971. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  54972. + break;
  54973. + case DDR1_CL_4:
  54974. + /* registerd DDR SDRAM? */
  54975. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  54976. + dunitCtrlLow |= 0x6 << SDRAM_ST_BURST_DEL_OFFS;
  54977. + else
  54978. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  54979. + break;
  54980. + default:
  54981. + mvOsPrintf("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n",
  54982. + minCas);
  54983. + return -1;
  54984. + }
  54985. +
  54986. + }
  54987. + DB(mvOsPrintf("Dram: Reg dunit control low = %x\n", dunitCtrlLow ));
  54988. +
  54989. + return dunitCtrlLow;
  54990. +}
  54991. +
  54992. +/*******************************************************************************
  54993. +* sdramAddrCtrlRegCalc - Calculate sdram address control register
  54994. +*
  54995. +* DESCRIPTION: Calculate sdram address control register optimized value based
  54996. +* on the bank info parameters and the minCas.
  54997. +*
  54998. +* INPUT:
  54999. +* pBankInfo - sdram bank parameters
  55000. +*
  55001. +* OUTPUT:
  55002. +* None
  55003. +*
  55004. +* RETURN:
  55005. +* sdram address control reg value.
  55006. +*
  55007. +*******************************************************************************/
  55008. +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo)
  55009. +{
  55010. + MV_U32 addrCtrl = 0;
  55011. +
  55012. + /* Set Address Control register static configuration bits */
  55013. + addrCtrl = MV_REG_READ(SDRAM_ADDR_CTRL_REG);
  55014. +
  55015. + /* Set address control default value */
  55016. + addrCtrl |= SDRAM_ADDR_CTRL_DV;
  55017. +
  55018. + /* Clear DSize field */
  55019. + addrCtrl &= ~SDRAM_DSIZE_MASK;
  55020. +
  55021. + /* Note that density is in MB units */
  55022. + switch (pBankInfo->deviceDensity)
  55023. + {
  55024. + case 128: /* 128 Mbit */
  55025. + DB(mvOsPrintf("DRAM Device Density 128Mbit\n"));
  55026. + addrCtrl |= SDRAM_DSIZE_128Mb;
  55027. + break;
  55028. + case 256: /* 256 Mbit */
  55029. + DB(mvOsPrintf("DRAM Device Density 256Mbit\n"));
  55030. + addrCtrl |= SDRAM_DSIZE_256Mb;
  55031. + break;
  55032. + case 512: /* 512 Mbit */
  55033. + DB(mvOsPrintf("DRAM Device Density 512Mbit\n"));
  55034. + addrCtrl |= SDRAM_DSIZE_512Mb;
  55035. + break;
  55036. + default:
  55037. + mvOsPrintf("Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
  55038. + pBankInfo->deviceDensity);
  55039. + return -1;
  55040. + }
  55041. +
  55042. + /* SDRAM address control */
  55043. + DB(mvOsPrintf("Dram: setting sdram address control with: %x \n", addrCtrl));
  55044. +
  55045. + return addrCtrl;
  55046. +}
  55047. +
  55048. +/*******************************************************************************
  55049. +* sdramTimeCtrlLowRegCalc - Calculate sdram timing control low register
  55050. +*
  55051. +* DESCRIPTION:
  55052. +* This function calculates sdram timing control low register
  55053. +* optimized value based on the bank info parameters and the minCas.
  55054. +*
  55055. +* INPUT:
  55056. +* pBankInfo - sdram bank parameters
  55057. +* busClk - Bus clock
  55058. +*
  55059. +* OUTPUT:
  55060. +* None
  55061. +*
  55062. +* RETURN:
  55063. +* sdram timinf control low reg value.
  55064. +*
  55065. +*******************************************************************************/
  55066. +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
  55067. + MV_U32 minCas, MV_U32 busClk)
  55068. +{
  55069. + MV_U32 tRp = 0;
  55070. + MV_U32 tRrd = 0;
  55071. + MV_U32 tRcd = 0;
  55072. + MV_U32 tRas = 0;
  55073. + MV_U32 tWr = 0;
  55074. + MV_U32 tWtr = 0;
  55075. + MV_U32 tRtp = 0;
  55076. +
  55077. + MV_U32 bankNum;
  55078. +
  55079. + busClk = busClk / 1000000; /* In MHz */
  55080. +
  55081. + /* Scan all DRAM banks to find maximum timing values */
  55082. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  55083. + {
  55084. + tRp = MV_MAX(tRp, pBankInfo[bankNum].minRowPrechargeTime);
  55085. + tRrd = MV_MAX(tRrd, pBankInfo[bankNum].minRowActiveToRowActive);
  55086. + tRcd = MV_MAX(tRcd, pBankInfo[bankNum].minRasToCasDelay);
  55087. + tRas = MV_MAX(tRas, pBankInfo[bankNum].minRasPulseWidth);
  55088. + }
  55089. +
  55090. + /* Extract timing (in ns) from SPD value. We ignore the tenth ns part. */
  55091. + /* by shifting the data two bits right. */
  55092. + tRp = tRp >> 2; /* For example 0x50 -> 20ns */
  55093. + tRrd = tRrd >> 2;
  55094. + tRcd = tRcd >> 2;
  55095. +
  55096. + /* Extract clock cycles from time parameter. We need to round up */
  55097. + tRp = ((busClk * tRp) / 1000) + (((busClk * tRp) % 1000) ? 1 : 0);
  55098. + /* Micron work around for 133MHz */
  55099. + if (busClk == 133)
  55100. + tRp += 1;
  55101. + DB(mvOsPrintf("Dram Timing Low: tRp = %d ", tRp));
  55102. + tRrd = ((busClk * tRrd) / 1000) + (((busClk * tRrd) % 1000) ? 1 : 0);
  55103. + /* JEDEC min reqeirments tRrd = 2 */
  55104. + if (tRrd < 2)
  55105. + tRrd = 2;
  55106. + DB(mvOsPrintf("tRrd = %d ", tRrd));
  55107. + tRcd = ((busClk * tRcd) / 1000) + (((busClk * tRcd) % 1000) ? 1 : 0);
  55108. + DB(mvOsPrintf("tRcd = %d ", tRcd));
  55109. + tRas = ((busClk * tRas) / 1000) + (((busClk * tRas) % 1000) ? 1 : 0);
  55110. + DB(mvOsPrintf("tRas = %d ", tRas));
  55111. +
  55112. + /* tWr and tWtr is different for DDR1 and DDR2. tRtp is only for DDR2 */
  55113. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  55114. + {
  55115. + /* Scan all DRAM banks to find maximum timing values */
  55116. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  55117. + {
  55118. + tWr = MV_MAX(tWr, pBankInfo[bankNum].minWriteRecoveryTime);
  55119. + tWtr = MV_MAX(tWtr, pBankInfo[bankNum].minWriteToReadCmdDelay);
  55120. + tRtp = MV_MAX(tRtp, pBankInfo[bankNum].minReadToPrechCmdDelay);
  55121. + }
  55122. +
  55123. + /* Extract timing (in ns) from SPD value. We ignore the tenth ns */
  55124. + /* part by shifting the data two bits right. */
  55125. + tWr = tWr >> 2; /* For example 0x50 -> 20ns */
  55126. + tWtr = tWtr >> 2;
  55127. + tRtp = tRtp >> 2;
  55128. +
  55129. + /* Extract clock cycles from time parameter. We need to round up */
  55130. + tWr = ((busClk * tWr) / 1000) + (((busClk * tWr) % 1000) ? 1 : 0);
  55131. + DB(mvOsPrintf("tWr = %d ", tWr));
  55132. + tWtr = ((busClk * tWtr) / 1000) + (((busClk * tWtr) % 1000) ? 1 : 0);
  55133. + /* JEDEC min reqeirments tWtr = 2 */
  55134. + if (tWtr < 2)
  55135. + tWtr = 2;
  55136. + DB(mvOsPrintf("tWtr = %d ", tWtr));
  55137. + tRtp = ((busClk * tRtp) / 1000) + (((busClk * tRtp) % 1000) ? 1 : 0);
  55138. + /* JEDEC min reqeirments tRtp = 2 */
  55139. + if (tRtp < 2)
  55140. + tRtp = 2;
  55141. + DB(mvOsPrintf("tRtp = %d ", tRtp));
  55142. + }
  55143. + else
  55144. + {
  55145. + tWr = ((busClk*SDRAM_TWR) / 1000) + (((busClk*SDRAM_TWR) % 1000)?1:0);
  55146. +
  55147. + if ((200 == busClk) || ((100 == busClk) && (DDR1_CL_1_5 == minCas)))
  55148. + {
  55149. + tWtr = 2;
  55150. + }
  55151. + else
  55152. + {
  55153. + tWtr = 1;
  55154. + }
  55155. +
  55156. + tRtp = 2; /* Must be set to 0x1 (two cycles) when using DDR1 */
  55157. + }
  55158. +
  55159. + DB(mvOsPrintf("tWtr = %d\n", tWtr));
  55160. +
  55161. + /* Note: value of 0 in register means one cycle, 1 means two and so on */
  55162. + return (((tRp - 1) << SDRAM_TRP_OFFS) |
  55163. + ((tRrd - 1) << SDRAM_TRRD_OFFS) |
  55164. + ((tRcd - 1) << SDRAM_TRCD_OFFS) |
  55165. + ((tRas - 1) << SDRAM_TRAS_OFFS) |
  55166. + ((tWr - 1) << SDRAM_TWR_OFFS) |
  55167. + ((tWtr - 1) << SDRAM_TWTR_OFFS) |
  55168. + ((tRtp - 1) << SDRAM_TRTP_OFFS));
  55169. +}
  55170. +
  55171. +/*******************************************************************************
  55172. +* sdramTimeCtrlHighRegCalc - Calculate sdram timing control high register
  55173. +*
  55174. +* DESCRIPTION:
  55175. +* This function calculates sdram timing control high register
  55176. +* optimized value based on the bank info parameters and the bus clock.
  55177. +*
  55178. +* INPUT:
  55179. +* pBankInfo - sdram bank parameters
  55180. +* busClk - Bus clock
  55181. +*
  55182. +* OUTPUT:
  55183. +* None
  55184. +*
  55185. +* RETURN:
  55186. +* sdram timinf control high reg value.
  55187. +*
  55188. +*******************************************************************************/
  55189. +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
  55190. + MV_U32 busClk)
  55191. +{
  55192. + MV_U32 tRfc;
  55193. + MV_U32 timeNs = 0;
  55194. + int bankNum;
  55195. + MV_U32 sdramTw2wCyc = 0;
  55196. +
  55197. + busClk = busClk / 1000000; /* In MHz */
  55198. +
  55199. + /* tRfc is different for DDR1 and DDR2. */
  55200. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  55201. + {
  55202. + MV_U32 bankNum;
  55203. +
  55204. + /* Scan all DRAM banks to find maximum timing values */
  55205. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  55206. + timeNs = MV_MAX(timeNs, pBankInfo[bankNum].minRefreshToActiveCmd);
  55207. + }
  55208. + else
  55209. + {
  55210. + if (pBankInfo[0].deviceDensity == _1G)
  55211. + {
  55212. + timeNs = SDRAM_TRFC_1G;
  55213. + }
  55214. + else
  55215. + {
  55216. + if (200 == busClk)
  55217. + {
  55218. + timeNs = SDRAM_TRFC_64_512M_AT_200MHZ;
  55219. + }
  55220. + else
  55221. + {
  55222. + timeNs = SDRAM_TRFC_64_512M;
  55223. + }
  55224. + }
  55225. + }
  55226. +
  55227. + tRfc = ((busClk * timeNs) / 1000) + (((busClk * timeNs) % 1000) ? 1 : 0);
  55228. +
  55229. + DB(mvOsPrintf("Dram Timing High: tRfc = %d\n", tRfc));
  55230. +
  55231. +
  55232. + /* Represent the populate banks in binary form */
  55233. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  55234. + {
  55235. + if (0 != pBankInfo[bankNum].size)
  55236. + sdramTw2wCyc++;
  55237. + }
  55238. +
  55239. + /* If we have more the 1 bank then we need the TW2W in 1 for ODT switch */
  55240. + if (sdramTw2wCyc > 1)
  55241. + sdramTw2wCyc = 1;
  55242. + else
  55243. + sdramTw2wCyc = 0;
  55244. +
  55245. + /* Note: value of 0 in register means one cycle, 1 means two and so on */
  55246. + return ((((tRfc - 1) & SDRAM_TRFC_MASK) << SDRAM_TRFC_OFFS) |
  55247. + ((SDRAM_TR2R_CYC - 1) << SDRAM_TR2R_OFFS) |
  55248. + ((SDRAM_TR2WW2R_CYC - 1) << SDRAM_TR2W_W2R_OFFS) |
  55249. + (((tRfc - 1) >> 4) << SDRAM_TRFC_EXT_OFFS) |
  55250. + (sdramTw2wCyc << SDRAM_TW2W_OFFS));
  55251. +
  55252. +}
  55253. +
  55254. +/*******************************************************************************
  55255. +* sdramDDr2OdtConfig - Set DRAM DDR2 On Die Termination registers.
  55256. +*
  55257. +* DESCRIPTION:
  55258. +* This function config DDR2 On Die Termination (ODT) registers.
  55259. +* ODT configuration is done according to DIMM presence:
  55260. +*
  55261. +* Presence Ctrl Low Ctrl High Dunit Ctrl Ext Mode
  55262. +* CS0 0x84210000 0x00000000 0x0000780F 0x00000440
  55263. +* CS0+CS1 0x84210000 0x00000000 0x0000780F 0x00000440
  55264. +* CS0+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404
  55265. +* CS0+CS1+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404
  55266. +* CS0+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404
  55267. +* CS0+CS1+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404
  55268. +*
  55269. +* INPUT:
  55270. +* pBankInfo - bank info parameters.
  55271. +*
  55272. +* OUTPUT:
  55273. +* None
  55274. +*
  55275. +* RETURN:
  55276. +* None
  55277. +*******************************************************************************/
  55278. +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo)
  55279. +{
  55280. + MV_U32 populateBanks = 0;
  55281. + MV_U32 odtCtrlLow, odtCtrlHigh, dunitOdtCtrl;
  55282. + int bankNum;
  55283. +
  55284. + /* Represent the populate banks in binary form */
  55285. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  55286. + {
  55287. + if (0 != pBankInfo[bankNum].size)
  55288. + {
  55289. + populateBanks |= (1 << bankNum);
  55290. + }
  55291. + }
  55292. +
  55293. + switch(populateBanks)
  55294. + {
  55295. + case(BANK_PRESENT_CS0):
  55296. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_DV;
  55297. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_DV;
  55298. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_DV;
  55299. + break;
  55300. + case(BANK_PRESENT_CS0_CS1):
  55301. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_DV;
  55302. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_DV;
  55303. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_DV;
  55304. + break;
  55305. + case(BANK_PRESENT_CS0_CS2):
  55306. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
  55307. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
  55308. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
  55309. + break;
  55310. + case(BANK_PRESENT_CS0_CS1_CS2):
  55311. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
  55312. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
  55313. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
  55314. + break;
  55315. + case(BANK_PRESENT_CS0_CS2_CS3):
  55316. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
  55317. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
  55318. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
  55319. + break;
  55320. + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
  55321. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
  55322. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
  55323. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
  55324. + break;
  55325. + default:
  55326. + mvOsPrintf("sdramDDr2OdtConfig: Invalid DRAM bank presence\n");
  55327. + return;
  55328. + }
  55329. + MV_REG_WRITE(DRAM_BUF_REG7, odtCtrlLow);
  55330. + MV_REG_WRITE(DRAM_BUF_REG8, odtCtrlHigh);
  55331. + MV_REG_WRITE(DRAM_BUF_REG9, dunitOdtCtrl);
  55332. + return;
  55333. +}
  55334. +#endif /* defined(MV_INC_BOARD_DDIM) */
  55335. +
  55336. +/*******************************************************************************
  55337. +* mvDramIfWinSet - Set DRAM interface address decode window
  55338. +*
  55339. +* DESCRIPTION:
  55340. +* This function sets DRAM interface address decode window.
  55341. +*
  55342. +* INPUT:
  55343. +* target - System target. Use only SDRAM targets.
  55344. +* pAddrDecWin - SDRAM address window structure.
  55345. +*
  55346. +* OUTPUT:
  55347. +* None
  55348. +*
  55349. +* RETURN:
  55350. +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
  55351. +* otherwise.
  55352. +*******************************************************************************/
  55353. +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
  55354. +{
  55355. + MV_U32 baseReg=0,sizeReg=0;
  55356. + MV_U32 baseToReg=0 , sizeToReg=0;
  55357. +
  55358. + /* Check parameters */
  55359. + if (!MV_TARGET_IS_DRAM(target))
  55360. + {
  55361. + mvOsPrintf("mvDramIfWinSet: target %d is not SDRAM\n", target);
  55362. + return MV_BAD_PARAM;
  55363. + }
  55364. +
  55365. + /* Check if the requested window overlaps with current enabled windows */
  55366. + if (MV_TRUE == sdramIfWinOverlap(target, &pAddrDecWin->addrWin))
  55367. + {
  55368. + mvOsPrintf("mvDramIfWinSet: ERR. Target %d overlaps\n", target);
  55369. + return MV_BAD_PARAM;
  55370. + }
  55371. +
  55372. + /* check if address is aligned to the size */
  55373. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  55374. + {
  55375. + mvOsPrintf("mvDramIfWinSet:Error setting DRAM interface window %d."\
  55376. + "\nAddress 0x%08x is unaligned to size 0x%x.\n",
  55377. + target,
  55378. + pAddrDecWin->addrWin.baseLow,
  55379. + pAddrDecWin->addrWin.size);
  55380. + return MV_ERROR;
  55381. + }
  55382. +
  55383. + /* read base register*/
  55384. + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(target));
  55385. +
  55386. + /* read size register */
  55387. + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(target));
  55388. +
  55389. + /* BaseLow[31:16] => base register [31:16] */
  55390. + baseToReg = pAddrDecWin->addrWin.baseLow & SCBAR_BASE_MASK;
  55391. +
  55392. + /* Write to address decode Base Address Register */
  55393. + baseReg &= ~SCBAR_BASE_MASK;
  55394. + baseReg |= baseToReg;
  55395. +
  55396. + /* Translate the given window size to register format */
  55397. + sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, SCSR_SIZE_ALIGNMENT);
  55398. +
  55399. + /* Size parameter validity check. */
  55400. + if (-1 == sizeToReg)
  55401. + {
  55402. + mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n",target);
  55403. + return MV_BAD_PARAM;
  55404. + }
  55405. +
  55406. + /* set size */
  55407. + sizeReg &= ~SCSR_SIZE_MASK;
  55408. + /* Size is located at upper 16 bits */
  55409. + sizeReg |= (sizeToReg << SCSR_SIZE_OFFS);
  55410. +
  55411. + /* enable/Disable */
  55412. + if (MV_TRUE == pAddrDecWin->enable)
  55413. + {
  55414. + sizeReg |= SCSR_WIN_EN;
  55415. + }
  55416. + else
  55417. + {
  55418. + sizeReg &= ~SCSR_WIN_EN;
  55419. + }
  55420. +
  55421. + /* 3) Write to address decode Base Address Register */
  55422. + MV_REG_WRITE(SDRAM_BASE_ADDR_REG(target), baseReg);
  55423. +
  55424. + /* Write to address decode Size Register */
  55425. + MV_REG_WRITE(SDRAM_SIZE_REG(target), sizeReg);
  55426. +
  55427. + return MV_OK;
  55428. +}
  55429. +/*******************************************************************************
  55430. +* mvDramIfWinGet - Get DRAM interface address decode window
  55431. +*
  55432. +* DESCRIPTION:
  55433. +* This function gets DRAM interface address decode window.
  55434. +*
  55435. +* INPUT:
  55436. +* target - System target. Use only SDRAM targets.
  55437. +*
  55438. +* OUTPUT:
  55439. +* pAddrDecWin - SDRAM address window structure.
  55440. +*
  55441. +* RETURN:
  55442. +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
  55443. +* otherwise.
  55444. +*******************************************************************************/
  55445. +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
  55446. +{
  55447. + MV_U32 baseReg,sizeReg;
  55448. + MV_U32 sizeRegVal;
  55449. +
  55450. + /* Check parameters */
  55451. + if (!MV_TARGET_IS_DRAM(target))
  55452. + {
  55453. + mvOsPrintf("mvDramIfWinGet: target %d is Illigal\n", target);
  55454. + return MV_ERROR;
  55455. + }
  55456. +
  55457. + /* Read base and size registers */
  55458. + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(target));
  55459. + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(target));
  55460. +
  55461. + sizeRegVal = (sizeReg & SCSR_SIZE_MASK) >> SCSR_SIZE_OFFS;
  55462. +
  55463. + pAddrDecWin->addrWin.size = ctrlRegToSize(sizeRegVal,
  55464. + SCSR_SIZE_ALIGNMENT);
  55465. +
  55466. + /* Check if ctrlRegToSize returned OK */
  55467. + if (-1 == pAddrDecWin->addrWin.size)
  55468. + {
  55469. + mvOsPrintf("mvDramIfWinGet: size of target %d is Illigal\n", target);
  55470. + return MV_ERROR;
  55471. + }
  55472. +
  55473. + /* Extract base address */
  55474. + /* Base register [31:16] ==> baseLow[31:16] */
  55475. + pAddrDecWin->addrWin.baseLow = baseReg & SCBAR_BASE_MASK;
  55476. +
  55477. + pAddrDecWin->addrWin.baseHigh = 0;
  55478. +
  55479. +
  55480. + if (sizeReg & SCSR_WIN_EN)
  55481. + {
  55482. + pAddrDecWin->enable = MV_TRUE;
  55483. + }
  55484. + else
  55485. + {
  55486. + pAddrDecWin->enable = MV_FALSE;
  55487. + }
  55488. +
  55489. + return MV_OK;
  55490. +}
  55491. +/*******************************************************************************
  55492. +* mvDramIfWinEnable - Enable/Disable SDRAM address decode window
  55493. +*
  55494. +* DESCRIPTION:
  55495. +* This function enable/Disable SDRAM address decode window.
  55496. +*
  55497. +* INPUT:
  55498. +* target - System target. Use only SDRAM targets.
  55499. +*
  55500. +* OUTPUT:
  55501. +* None.
  55502. +*
  55503. +* RETURN:
  55504. +* MV_ERROR in case function parameter are invalid, MV_OK otherewise.
  55505. +*
  55506. +*******************************************************************************/
  55507. +MV_STATUS mvDramIfWinEnable(MV_TARGET target,MV_BOOL enable)
  55508. +{
  55509. + MV_DRAM_DEC_WIN addrDecWin;
  55510. +
  55511. + /* Check parameters */
  55512. + if (!MV_TARGET_IS_DRAM(target))
  55513. + {
  55514. + mvOsPrintf("mvDramIfWinEnable: target %d is Illigal\n", target);
  55515. + return MV_ERROR;
  55516. + }
  55517. +
  55518. + if (enable == MV_TRUE)
  55519. + { /* First check for overlap with other enabled windows */
  55520. + if (MV_OK != mvDramIfWinGet(target, &addrDecWin))
  55521. + {
  55522. + mvOsPrintf("mvDramIfWinEnable:ERR. Getting target %d failed.\n",
  55523. + target);
  55524. + return MV_ERROR;
  55525. + }
  55526. + /* Check for overlapping */
  55527. + if (MV_FALSE == sdramIfWinOverlap(target, &(addrDecWin.addrWin)))
  55528. + {
  55529. + /* No Overlap. Enable address decode winNum window */
  55530. + MV_REG_BIT_SET(SDRAM_SIZE_REG(target), SCSR_WIN_EN);
  55531. + }
  55532. + else
  55533. + { /* Overlap detected */
  55534. + mvOsPrintf("mvDramIfWinEnable: ERR. Target %d overlap detect\n",
  55535. + target);
  55536. + return MV_ERROR;
  55537. + }
  55538. + }
  55539. + else
  55540. + { /* Disable address decode winNum window */
  55541. + MV_REG_BIT_RESET(SDRAM_SIZE_REG(target), SCSR_WIN_EN);
  55542. + }
  55543. +
  55544. + return MV_OK;
  55545. +}
  55546. +
  55547. +/*******************************************************************************
  55548. +* sdramIfWinOverlap - Check if an address window overlap an SDRAM address window
  55549. +*
  55550. +* DESCRIPTION:
  55551. +* This function scan each SDRAM address decode window to test if it
  55552. +* overlapps the given address windoow
  55553. +*
  55554. +* INPUT:
  55555. +* target - SDRAM target where the function skips checking.
  55556. +* pAddrDecWin - The tested address window for overlapping with
  55557. +* SDRAM windows.
  55558. +*
  55559. +* OUTPUT:
  55560. +* None.
  55561. +*
  55562. +* RETURN:
  55563. +* MV_TRUE if the given address window overlaps any enabled address
  55564. +* decode map, MV_FALSE otherwise.
  55565. +*
  55566. +*******************************************************************************/
  55567. +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
  55568. +{
  55569. + MV_TARGET targetNum;
  55570. + MV_DRAM_DEC_WIN addrDecWin;
  55571. +
  55572. + for(targetNum = SDRAM_CS0; targetNum < MV_DRAM_MAX_CS ; targetNum++)
  55573. + {
  55574. + /* don't check our winNum or illegal targets */
  55575. + if (targetNum == target)
  55576. + {
  55577. + continue;
  55578. + }
  55579. +
  55580. + /* Get window parameters */
  55581. + if (MV_OK != mvDramIfWinGet(targetNum, &addrDecWin))
  55582. + {
  55583. + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
  55584. + return MV_ERROR;
  55585. + }
  55586. +
  55587. + /* Do not check disabled windows */
  55588. + if (MV_FALSE == addrDecWin.enable)
  55589. + {
  55590. + continue;
  55591. + }
  55592. +
  55593. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
  55594. + {
  55595. + mvOsPrintf(
  55596. + "sdramIfWinOverlap: Required target %d overlap winNum %d\n",
  55597. + target, targetNum);
  55598. + return MV_TRUE;
  55599. + }
  55600. + }
  55601. +
  55602. + return MV_FALSE;
  55603. +}
  55604. +
  55605. +/*******************************************************************************
  55606. +* mvDramIfBankSizeGet - Get DRAM interface bank size.
  55607. +*
  55608. +* DESCRIPTION:
  55609. +* This function returns the size of a given DRAM bank.
  55610. +*
  55611. +* INPUT:
  55612. +* bankNum - Bank number.
  55613. +*
  55614. +* OUTPUT:
  55615. +* None.
  55616. +*
  55617. +* RETURN:
  55618. +* DRAM bank size. If bank is disabled the function return '0'. In case
  55619. +* or paramter is invalid, the function returns -1.
  55620. +*
  55621. +*******************************************************************************/
  55622. +MV_32 mvDramIfBankSizeGet(MV_U32 bankNum)
  55623. +{
  55624. + MV_DRAM_DEC_WIN addrDecWin;
  55625. +
  55626. + /* Check parameters */
  55627. + if (!MV_TARGET_IS_DRAM(bankNum))
  55628. + {
  55629. + mvOsPrintf("mvDramIfBankBaseGet: bankNum %d is invalid\n", bankNum);
  55630. + return -1;
  55631. + }
  55632. + /* Get window parameters */
  55633. + if (MV_OK != mvDramIfWinGet(bankNum, &addrDecWin))
  55634. + {
  55635. + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
  55636. + return -1;
  55637. + }
  55638. +
  55639. + if (MV_TRUE == addrDecWin.enable)
  55640. + {
  55641. + return addrDecWin.addrWin.size;
  55642. + }
  55643. + else
  55644. + {
  55645. + return 0;
  55646. + }
  55647. +}
  55648. +
  55649. +
  55650. +/*******************************************************************************
  55651. +* mvDramIfSizeGet - Get DRAM interface total size.
  55652. +*
  55653. +* DESCRIPTION:
  55654. +* This function get the DRAM total size.
  55655. +*
  55656. +* INPUT:
  55657. +* None.
  55658. +*
  55659. +* OUTPUT:
  55660. +* None.
  55661. +*
  55662. +* RETURN:
  55663. +* DRAM total size. In case or paramter is invalid, the function
  55664. +* returns -1.
  55665. +*
  55666. +*******************************************************************************/
  55667. +MV_32 mvDramIfSizeGet(MV_VOID)
  55668. +{
  55669. + MV_U32 totalSize = 0, bankSize = 0, bankNum;
  55670. +
  55671. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  55672. + {
  55673. + bankSize = mvDramIfBankSizeGet(bankNum);
  55674. +
  55675. + if (-1 == bankSize)
  55676. + {
  55677. + mvOsPrintf("Dram: mvDramIfSizeGet error with bank %d \n",bankNum);
  55678. + return -1;
  55679. + }
  55680. + else
  55681. + {
  55682. + totalSize += bankSize;
  55683. + }
  55684. + }
  55685. +
  55686. + DB(mvOsPrintf("Dram: Total DRAM size is 0x%x \n",totalSize));
  55687. +
  55688. + return totalSize;
  55689. +}
  55690. +
  55691. +/*******************************************************************************
  55692. +* mvDramIfBankBaseGet - Get DRAM interface bank base.
  55693. +*
  55694. +* DESCRIPTION:
  55695. +* This function returns the 32 bit base address of a given DRAM bank.
  55696. +*
  55697. +* INPUT:
  55698. +* bankNum - Bank number.
  55699. +*
  55700. +* OUTPUT:
  55701. +* None.
  55702. +*
  55703. +* RETURN:
  55704. +* DRAM bank size. If bank is disabled or paramter is invalid, the
  55705. +* function returns -1.
  55706. +*
  55707. +*******************************************************************************/
  55708. +MV_32 mvDramIfBankBaseGet(MV_U32 bankNum)
  55709. +{
  55710. + MV_DRAM_DEC_WIN addrDecWin;
  55711. +
  55712. + /* Check parameters */
  55713. + if (!MV_TARGET_IS_DRAM(bankNum))
  55714. + {
  55715. + mvOsPrintf("mvDramIfBankBaseGet: bankNum %d is invalid\n", bankNum);
  55716. + return -1;
  55717. + }
  55718. + /* Get window parameters */
  55719. + if (MV_OK != mvDramIfWinGet(bankNum, &addrDecWin))
  55720. + {
  55721. + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
  55722. + return -1;
  55723. + }
  55724. +
  55725. + if (MV_TRUE == addrDecWin.enable)
  55726. + {
  55727. + return addrDecWin.addrWin.baseLow;
  55728. + }
  55729. + else
  55730. + {
  55731. + return -1;
  55732. + }
  55733. +}
  55734. +
  55735. +
  55736. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h
  55737. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h 1970-01-01 01:00:00.000000000 +0100
  55738. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h 2010-08-05 22:02:24.124868029 +0200
  55739. @@ -0,0 +1,192 @@
  55740. +/*******************************************************************************
  55741. +Copyright (C) Marvell International Ltd. and its affiliates
  55742. +
  55743. +This software file (the "File") is owned and distributed by Marvell
  55744. +International Ltd. and/or its affiliates ("Marvell") under the following
  55745. +alternative licensing terms. Once you have made an election to distribute the
  55746. +File under one of the following license alternatives, please (i) delete this
  55747. +introductory statement regarding license alternatives, (ii) delete the two
  55748. +license alternatives that you have not elected to use and (iii) preserve the
  55749. +Marvell copyright notice above.
  55750. +
  55751. +********************************************************************************
  55752. +Marvell Commercial License Option
  55753. +
  55754. +If you received this File from Marvell and you have entered into a commercial
  55755. +license agreement (a "Commercial License") with Marvell, the File is licensed
  55756. +to you under the terms of the applicable Commercial License.
  55757. +
  55758. +********************************************************************************
  55759. +Marvell GPL License Option
  55760. +
  55761. +If you received this File from Marvell, you may opt to use, redistribute and/or
  55762. +modify this File in accordance with the terms and conditions of the General
  55763. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  55764. +available along with the File in the license.txt file or by writing to the Free
  55765. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  55766. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  55767. +
  55768. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  55769. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  55770. +DISCLAIMED. The GPL License provides additional details about this warranty
  55771. +disclaimer.
  55772. +********************************************************************************
  55773. +Marvell BSD License Option
  55774. +
  55775. +If you received this File from Marvell, you may opt to use, redistribute and/or
  55776. +modify this File under the following licensing terms.
  55777. +Redistribution and use in source and binary forms, with or without modification,
  55778. +are permitted provided that the following conditions are met:
  55779. +
  55780. + * Redistributions of source code must retain the above copyright notice,
  55781. + this list of conditions and the following disclaimer.
  55782. +
  55783. + * Redistributions in binary form must reproduce the above copyright
  55784. + notice, this list of conditions and the following disclaimer in the
  55785. + documentation and/or other materials provided with the distribution.
  55786. +
  55787. + * Neither the name of Marvell nor the names of its contributors may be
  55788. + used to endorse or promote products derived from this software without
  55789. + specific prior written permission.
  55790. +
  55791. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  55792. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  55793. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  55794. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  55795. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  55796. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  55797. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  55798. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  55799. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  55800. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  55801. +
  55802. +*******************************************************************************/
  55803. +
  55804. +
  55805. +#ifndef __INCmvDramIfConfigh
  55806. +#define __INCmvDramIfConfigh
  55807. +
  55808. +/* includes */
  55809. +
  55810. +/* defines */
  55811. +
  55812. +/* registers defaults values */
  55813. +
  55814. +#define SDRAM_CONFIG_DV \
  55815. + (SDRAM_PERR_WRITE | \
  55816. + SDRAM_SRMODE | \
  55817. + SDRAM_SRCLK_GATED)
  55818. +
  55819. +#define SDRAM_DUNIT_CTRL_LOW_DV \
  55820. + (SDRAM_CTRL_POS_RISE | \
  55821. + SDRAM_CLK1DRV_NORMAL | \
  55822. + SDRAM_LOCKEN_ENABLE)
  55823. +
  55824. +#define SDRAM_ADDR_CTRL_DV 0
  55825. +
  55826. +#define SDRAM_TIMING_CTRL_LOW_REG_DV \
  55827. + ((0x2 << SDRAM_TRCD_OFFS) | \
  55828. + (0x2 << SDRAM_TRP_OFFS) | \
  55829. + (0x1 << SDRAM_TWR_OFFS) | \
  55830. + (0x0 << SDRAM_TWTR_OFFS) | \
  55831. + (0x5 << SDRAM_TRAS_OFFS) | \
  55832. + (0x1 << SDRAM_TRRD_OFFS))
  55833. +/* TRFC 0x27, TW2W 0x1 */
  55834. +#define SDRAM_TIMING_CTRL_HIGH_REG_DV (( 0x7 << SDRAM_TRFC_OFFS ) |\
  55835. + ( 0x2 << SDRAM_TRFC_EXT_OFFS) |\
  55836. + ( 0x1 << SDRAM_TW2W_OFFS))
  55837. +
  55838. +#define SDRAM_OPEN_PAGES_CTRL_REG_DV SDRAM_OPEN_PAGE_EN
  55839. +
  55840. +/* DDR2 ODT default register values */
  55841. +
  55842. +/* Presence Ctrl Low Ctrl High Dunit Ctrl Ext Mode */
  55843. +/* CS0 0x84210000 0x00000000 0x0000780F 0x00000440 */
  55844. +/* CS0+CS1 0x84210000 0x00000000 0x0000780F 0x00000440 */
  55845. +/* CS0+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  55846. +/* CS0+CS1+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  55847. +/* CS0+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  55848. +/* CS0+CS1+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  55849. +
  55850. +#define DDR2_ODT_CTRL_LOW_CS0_DV 0x84210000
  55851. +#define DDR2_ODT_CTRL_HIGH_CS0_DV 0x00000000
  55852. +#define DDR2_DUNIT_ODT_CTRL_CS0_DV 0x0000780F
  55853. +#define DDR_SDRAM_EXT_MODE_CS0_DV 0x00000440
  55854. +
  55855. +#define DDR2_ODT_CTRL_LOW_CS0_CS2_DV 0x030C030C
  55856. +#define DDR2_ODT_CTRL_HIGH_CS0_CS2_DV 0x00000000
  55857. +#define DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV 0x0000740F
  55858. +#define DDR_SDRAM_EXT_MODE_CS0_CS2_DV 0x00000404
  55859. +
  55860. +
  55861. +/* DDR SDRAM Adderss/Control and Data Pads Calibration default values */
  55862. +#define DDR1_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV \
  55863. + (1 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  55864. +#define DDR2_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV \
  55865. + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  55866. +
  55867. +
  55868. +#define DDR1_DATA_PAD_STRENGTH_TYPICAL_DV \
  55869. + (1 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  55870. +#define DDR2_DATA_PAD_STRENGTH_TYPICAL_DV \
  55871. + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  55872. +
  55873. +/* DDR SDRAM Mode Register default value */
  55874. +#define DDR1_MODE_REG_DV 0x00000000
  55875. +#define DDR2_MODE_REG_DV 0x00000400
  55876. +
  55877. +/* DDR SDRAM Timing parameter default values */
  55878. +#define DDR1_TIMING_LOW_DV 0x11602220
  55879. +#define DDR1_TIMING_HIGH_DV 0x0000000d
  55880. +
  55881. +#define DDR2_TIMING_LOW_DV 0x11812220
  55882. +#define DDR2_TIMING_HIGH_DV 0x0000030f
  55883. +
  55884. +/* For Guideline (GL# MEM-4) DQS Reference Delay Tuning */
  55885. +#define FTDLL_DDR1_166MHZ ((0x1 << 0) | \
  55886. + (0x7F<< 12) | \
  55887. + (0x1 << 22))
  55888. +
  55889. +#define FTDLL_DDR1_133MHZ FTDLL_DDR1_166MHZ
  55890. +
  55891. +#define FTDLL_DDR1_200MHZ ((0x1 << 0) | \
  55892. + (0x1 << 12) | \
  55893. + (0x3 << 14) | \
  55894. + (0x1 << 18) | \
  55895. + (0x1 << 22))
  55896. +
  55897. +
  55898. +#define FTDLL_DDR2_166MHZ ((0x1 << 0) | \
  55899. + (0x1 << 12) | \
  55900. + (0x1 << 14) | \
  55901. + (0x1 << 16) | \
  55902. + (0x1 << 19) | \
  55903. + (0xF << 20))
  55904. +
  55905. +#define FTDLL_DDR2_133MHZ FTDLL_DDR2_166MHZ
  55906. +
  55907. +#define FTDLL_DDR2_200MHZ ((0x1 << 0) | \
  55908. + (0x1 << 12) | \
  55909. + (0x1 << 14) | \
  55910. + (0x1 << 16) | \
  55911. + (0x1 << 19) | \
  55912. + (0xF << 20))
  55913. +
  55914. +#define FTDLL_DDR2_250MHZ 0x445001
  55915. +
  55916. +/* Orion 1 B1 and above */
  55917. +#define FTDLL_DDR1_166MHZ_5181_B1 0x45D001
  55918. +
  55919. +/* Orion nas */
  55920. +#define FTDLL_DDR2_166MHZ_5182 0x597001
  55921. +
  55922. +/* Orion 2 D0 and above */
  55923. +#define FTDLL_DDR1_166MHZ_5281_D0 0x8D0001
  55924. +#define FTDLL_DDR1_200MHZ_5281_D0 0x8D0001
  55925. +#define FTDLL_DDR2_166MHZ_5281_D0 0x485001
  55926. +#define FTDLL_DDR2_200MHZ_5281_D0 0x485001
  55927. +#define FTDLL_DDR2_250MHZ_5281_D0 0x445001
  55928. +#define FTDLL_DDR2_200MHZ_5281_D1 0x995001
  55929. +#define FTDLL_DDR2_250MHZ_5281_D1 0x984801
  55930. +
  55931. +#endif /* __INCmvDramIfh */
  55932. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h
  55933. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h 1970-01-01 01:00:00.000000000 +0100
  55934. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h 2010-08-05 22:02:24.164868025 +0200
  55935. @@ -0,0 +1,179 @@
  55936. +/*******************************************************************************
  55937. +Copyright (C) Marvell International Ltd. and its affiliates
  55938. +
  55939. +This software file (the "File") is owned and distributed by Marvell
  55940. +International Ltd. and/or its affiliates ("Marvell") under the following
  55941. +alternative licensing terms. Once you have made an election to distribute the
  55942. +File under one of the following license alternatives, please (i) delete this
  55943. +introductory statement regarding license alternatives, (ii) delete the two
  55944. +license alternatives that you have not elected to use and (iii) preserve the
  55945. +Marvell copyright notice above.
  55946. +
  55947. +********************************************************************************
  55948. +Marvell Commercial License Option
  55949. +
  55950. +If you received this File from Marvell and you have entered into a commercial
  55951. +license agreement (a "Commercial License") with Marvell, the File is licensed
  55952. +to you under the terms of the applicable Commercial License.
  55953. +
  55954. +********************************************************************************
  55955. +Marvell GPL License Option
  55956. +
  55957. +If you received this File from Marvell, you may opt to use, redistribute and/or
  55958. +modify this File in accordance with the terms and conditions of the General
  55959. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  55960. +available along with the File in the license.txt file or by writing to the Free
  55961. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  55962. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  55963. +
  55964. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  55965. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  55966. +DISCLAIMED. The GPL License provides additional details about this warranty
  55967. +disclaimer.
  55968. +********************************************************************************
  55969. +Marvell BSD License Option
  55970. +
  55971. +If you received this File from Marvell, you may opt to use, redistribute and/or
  55972. +modify this File under the following licensing terms.
  55973. +Redistribution and use in source and binary forms, with or without modification,
  55974. +are permitted provided that the following conditions are met:
  55975. +
  55976. + * Redistributions of source code must retain the above copyright notice,
  55977. + this list of conditions and the following disclaimer.
  55978. +
  55979. + * Redistributions in binary form must reproduce the above copyright
  55980. + notice, this list of conditions and the following disclaimer in the
  55981. + documentation and/or other materials provided with the distribution.
  55982. +
  55983. + * Neither the name of Marvell nor the names of its contributors may be
  55984. + used to endorse or promote products derived from this software without
  55985. + specific prior written permission.
  55986. +
  55987. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  55988. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  55989. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  55990. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  55991. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  55992. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  55993. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  55994. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  55995. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  55996. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  55997. +
  55998. +*******************************************************************************/
  55999. +
  56000. +
  56001. +#ifndef __INCmvDramIfh
  56002. +#define __INCmvDramIfh
  56003. +
  56004. +/* includes */
  56005. +#include "ddr1_2/mvDramIfRegs.h"
  56006. +#include "ddr1_2/mvDramIfConfig.h"
  56007. +#include "ctrlEnv/mvCtrlEnvLib.h"
  56008. +
  56009. +/* defines */
  56010. +/* DRAM Timing parameters */
  56011. +#define SDRAM_TWR 15 /* ns tWr */
  56012. +#define SDRAM_TRFC_64_512M_AT_200MHZ 70 /* ns tRfc for dens 64-512 @ 200MHz */
  56013. +#define SDRAM_TRFC_64_512M 75 /* ns tRfc for dens 64-512 */
  56014. +#define SDRAM_TRFC_1G 120 /* ns tRfc for dens 1GB */
  56015. +#define SDRAM_TR2R_CYC 1 /* cycle for tR2r */
  56016. +#define SDRAM_TR2WW2R_CYC 1 /* cycle for tR2wW2r */
  56017. +
  56018. +/* typedefs */
  56019. +
  56020. +/* enumeration for memory types */
  56021. +typedef enum _mvMemoryType
  56022. +{
  56023. + MEM_TYPE_SDRAM,
  56024. + MEM_TYPE_DDR1,
  56025. + MEM_TYPE_DDR2
  56026. +}MV_MEMORY_TYPE;
  56027. +
  56028. +/* enumeration for DDR1 supported CAS Latencies */
  56029. +typedef enum _mvDimmDdr1Cas
  56030. +{
  56031. + DDR1_CL_1_5 = 0x02,
  56032. + DDR1_CL_2 = 0x04,
  56033. + DDR1_CL_2_5 = 0x08,
  56034. + DDR1_CL_3 = 0x10,
  56035. + DDR1_CL_4 = 0x40,
  56036. + DDR1_CL_FAULT
  56037. +} MV_DIMM_DDR1_CAS;
  56038. +
  56039. +/* enumeration for DDR2 supported CAS Latencies */
  56040. +typedef enum _mvDimmDdr2Cas
  56041. +{
  56042. + DDR2_CL_3 = 0x08,
  56043. + DDR2_CL_4 = 0x10,
  56044. + DDR2_CL_5 = 0x20,
  56045. + DDR2_CL_FAULT
  56046. +} MV_DIMM_DDR2_CAS;
  56047. +
  56048. +
  56049. +typedef struct _mvDramBankInfo
  56050. +{
  56051. + MV_MEMORY_TYPE memoryType; /* DDR1, DDR2 or SDRAM */
  56052. +
  56053. + /* DIMM dimensions */
  56054. + MV_U32 numOfRowAddr;
  56055. + MV_U32 numOfColAddr;
  56056. + MV_U32 dataWidth;
  56057. + MV_U32 errorCheckType; /* ECC , PARITY..*/
  56058. + MV_U32 sdramWidth; /* 4,8,16 or 32 */
  56059. + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
  56060. + MV_U32 burstLengthSupported;
  56061. + MV_U32 numOfBanksOnEachDevice;
  56062. + MV_U32 suportedCasLatencies;
  56063. + MV_U32 refreshInterval;
  56064. +
  56065. + /* DIMM timing parameters */
  56066. + MV_U32 minCycleTimeAtMaxCasLatPs;
  56067. + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
  56068. + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
  56069. + MV_U32 minRowPrechargeTime;
  56070. + MV_U32 minRowActiveToRowActive;
  56071. + MV_U32 minRasToCasDelay;
  56072. + MV_U32 minRasPulseWidth;
  56073. + MV_U32 minWriteRecoveryTime; /* DDR2 only */
  56074. + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
  56075. + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
  56076. + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
  56077. +
  56078. + /* Parameters calculated from the extracted DIMM information */
  56079. + MV_U32 size;
  56080. + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit */
  56081. + MV_U32 numberOfDevices;
  56082. +
  56083. + /* DIMM attributes (MV_TRUE for yes) */
  56084. + MV_BOOL registeredAddrAndControlInputs;
  56085. +
  56086. +}MV_DRAM_BANK_INFO;
  56087. +
  56088. +/* This structure describes CPU interface address decode window */
  56089. +typedef struct _mvDramIfDecWin
  56090. +{
  56091. + MV_ADDR_WIN addrWin; /* An address window*/
  56092. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  56093. +}MV_DRAM_DEC_WIN;
  56094. +
  56095. +#include "ddr1_2/mvDram.h"
  56096. +
  56097. +/* mvDramIf.h API list */
  56098. +MV_VOID mvDramIfBasicAsmInit(MV_VOID);
  56099. +MV_STATUS mvDramIfDetect(MV_U32 forcedCl);
  56100. +MV_VOID _mvDramIfConfig(MV_VOID);
  56101. +
  56102. +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
  56103. +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
  56104. +MV_STATUS mvDramIfWinEnable(MV_TARGET target,MV_BOOL enable);
  56105. +MV_32 mvDramIfBankSizeGet(MV_U32 bankNum);
  56106. +MV_32 mvDramIfBankBaseGet(MV_U32 bankNum);
  56107. +MV_32 mvDramIfSizeGet(MV_VOID);
  56108. +
  56109. +#if 0
  56110. +MV_STATUS mvDramIfMbusCtrlSet(MV_XBAR_TARGET *pPizzaArbArray);
  56111. +MV_STATUS mvDramIfMbusToutSet(MV_U32 timeout, MV_BOOL enable);
  56112. +#endif
  56113. +
  56114. +#endif /* __INCmvDramIfh */
  56115. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h
  56116. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h 1970-01-01 01:00:00.000000000 +0100
  56117. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h 2010-08-05 22:02:24.214868327 +0200
  56118. @@ -0,0 +1,306 @@
  56119. +/*******************************************************************************
  56120. +Copyright (C) Marvell International Ltd. and its affiliates
  56121. +
  56122. +This software file (the "File") is owned and distributed by Marvell
  56123. +International Ltd. and/or its affiliates ("Marvell") under the following
  56124. +alternative licensing terms. Once you have made an election to distribute the
  56125. +File under one of the following license alternatives, please (i) delete this
  56126. +introductory statement regarding license alternatives, (ii) delete the two
  56127. +license alternatives that you have not elected to use and (iii) preserve the
  56128. +Marvell copyright notice above.
  56129. +
  56130. +********************************************************************************
  56131. +Marvell Commercial License Option
  56132. +
  56133. +If you received this File from Marvell and you have entered into a commercial
  56134. +license agreement (a "Commercial License") with Marvell, the File is licensed
  56135. +to you under the terms of the applicable Commercial License.
  56136. +
  56137. +********************************************************************************
  56138. +Marvell GPL License Option
  56139. +
  56140. +If you received this File from Marvell, you may opt to use, redistribute and/or
  56141. +modify this File in accordance with the terms and conditions of the General
  56142. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  56143. +available along with the File in the license.txt file or by writing to the Free
  56144. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  56145. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  56146. +
  56147. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  56148. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  56149. +DISCLAIMED. The GPL License provides additional details about this warranty
  56150. +disclaimer.
  56151. +********************************************************************************
  56152. +Marvell BSD License Option
  56153. +
  56154. +If you received this File from Marvell, you may opt to use, redistribute and/or
  56155. +modify this File under the following licensing terms.
  56156. +Redistribution and use in source and binary forms, with or without modification,
  56157. +are permitted provided that the following conditions are met:
  56158. +
  56159. + * Redistributions of source code must retain the above copyright notice,
  56160. + this list of conditions and the following disclaimer.
  56161. +
  56162. + * Redistributions in binary form must reproduce the above copyright
  56163. + notice, this list of conditions and the following disclaimer in the
  56164. + documentation and/or other materials provided with the distribution.
  56165. +
  56166. + * Neither the name of Marvell nor the names of its contributors may be
  56167. + used to endorse or promote products derived from this software without
  56168. + specific prior written permission.
  56169. +
  56170. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  56171. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  56172. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  56173. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  56174. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  56175. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  56176. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  56177. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  56178. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  56179. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  56180. +
  56181. +*******************************************************************************/
  56182. +
  56183. +#ifndef __INCmvDramIfRegsh
  56184. +#define __INCmvDramIfRegsh
  56185. +
  56186. +
  56187. +/* DDR SDRAM Controller Address Decode Registers */
  56188. +/* SDRAM CSn Base Address Register (SCBAR) */
  56189. +#define SDRAM_BASE_ADDR_REG(csNum) (0x1500 + (csNum * 8))
  56190. +#define SCBAR_BASE_OFFS 16
  56191. +#define SCBAR_BASE_MASK (0xffff << SCBAR_BASE_OFFS)
  56192. +#define SCBAR_BASE_ALIGNMENT 0x10000
  56193. +
  56194. +/* SDRAM CSn Size Register (SCSR) */
  56195. +#define SDRAM_SIZE_REG(csNum) (0x1504 + (csNum * 8))
  56196. +#define SCSR_WIN_EN BIT0
  56197. +#define SCSR_SIZE_OFFS 16
  56198. +#define SCSR_SIZE_MASK (0xffff << SCSR_SIZE_OFFS)
  56199. +#define SCSR_SIZE_ALIGNMENT 0x10000
  56200. +
  56201. +/* configuration register */
  56202. +#define SDRAM_CONFIG_REG 0x1400
  56203. +#define SDRAM_REFRESH_OFFS 0
  56204. +#define SDRAM_REFRESH_MAX 0x3000
  56205. +#define SDRAM_REFRESH_MASK (SDRAM_REFRESH_MAX << SDRAM_REFRESH_OFFS)
  56206. +#define SDRAM_DWIDTH_OFFS 14
  56207. +#define SDRAM_DWIDTH_MASK (3 << SDRAM_DWIDTH_OFFS)
  56208. +#define SDRAM_DWIDTH_16BIT (1 << SDRAM_DWIDTH_OFFS)
  56209. +#define SDRAM_DWIDTH_32BIT (2 << SDRAM_DWIDTH_OFFS)
  56210. +#define SDRAM_DTYPE_OFFS 16
  56211. +#define SDRAM_DTYPE_MASK (1 << SDRAM_DTYPE_OFFS)
  56212. +#define SDRAM_DTYPE_DDR1 (0 << SDRAM_DTYPE_OFFS)
  56213. +#define SDRAM_DTYPE_DDR2 (1 << SDRAM_DTYPE_OFFS)
  56214. +#define SDRAM_REGISTERED (1 << 17)
  56215. +#define SDRAM_PERR_OFFS 18
  56216. +#define SDRAM_PERR_MASK (1 << SDRAM_PERR_OFFS)
  56217. +#define SDRAM_PERR_NO_WRITE (0 << SDRAM_PERR_OFFS)
  56218. +#define SDRAM_PERR_WRITE (1 << SDRAM_PERR_OFFS)
  56219. +#define SDRAM_DCFG_OFFS 20
  56220. +#define SDRAM_DCFG_MASK (0x3 << SDRAM_DCFG_OFFS)
  56221. +#define SDRAM_DCFG_X16_DEV (1 << SDRAM_DCFG_OFFS)
  56222. +#define SDRAM_DCFG_X8_DEV (2 << SDRAM_DCFG_OFFS)
  56223. +#define SDRAM_SRMODE (1 << 24)
  56224. +#define SDRAM_SRCLK_OFFS 25
  56225. +#define SDRAM_SRCLK_MASK (1 << SDRAM_SRCLK_OFFS)
  56226. +#define SDRAM_SRCLK_KEPT (0 << SDRAM_SRCLK_OFFS)
  56227. +#define SDRAM_SRCLK_GATED (1 << SDRAM_SRCLK_OFFS)
  56228. +#define SDRAM_CATTH_OFFS 26
  56229. +#define SDRAM_CATTHR_EN (1 << SDRAM_CATTH_OFFS)
  56230. +
  56231. +
  56232. +/* dunit control register */
  56233. +#define SDRAM_DUNIT_CTRL_REG 0x1404
  56234. +#define SDRAM_CTRL_POS_OFFS 6
  56235. +#define SDRAM_CTRL_POS_FALL (0 << SDRAM_CTRL_POS_OFFS)
  56236. +#define SDRAM_CTRL_POS_RISE (1 << SDRAM_CTRL_POS_OFFS)
  56237. +#define SDRAM_CLK1DRV_OFFS 12
  56238. +#define SDRAM_CLK1DRV_MASK (1 << SDRAM_CLK1DRV_OFFS)
  56239. +#define SDRAM_CLK1DRV_HIGH_Z (0 << SDRAM_CLK1DRV_OFFS)
  56240. +#define SDRAM_CLK1DRV_NORMAL (1 << SDRAM_CLK1DRV_OFFS)
  56241. +#define SDRAM_LOCKEN_OFFS 18
  56242. +#define SDRAM_LOCKEN_MASK (1 << SDRAM_LOCKEN_OFFS)
  56243. +#define SDRAM_LOCKEN_DISABLE (0 << SDRAM_LOCKEN_OFFS)
  56244. +#define SDRAM_LOCKEN_ENABLE (1 << SDRAM_LOCKEN_OFFS)
  56245. +#define SDRAM_ST_BURST_DEL_OFFS 24
  56246. +#define SDRAM_ST_BURST_DEL_MAX 0xf
  56247. +#define SDRAM_ST_BURST_DEL_MASK (SDRAM_ST_BURST_DEL_MAX<<SDRAM_ST_BURST_DEL_OFFS)
  56248. +
  56249. +/* sdram timing control low register */
  56250. +#define SDRAM_TIMING_CTRL_LOW_REG 0x1408
  56251. +#define SDRAM_TRCD_OFFS 4
  56252. +#define SDRAM_TRCD_MASK (0xF << SDRAM_TRCD_OFFS)
  56253. +#define SDRAM_TRP_OFFS 8
  56254. +#define SDRAM_TRP_MASK (0xF << SDRAM_TRP_OFFS)
  56255. +#define SDRAM_TWR_OFFS 12
  56256. +#define SDRAM_TWR_MASK (0xF << SDRAM_TWR_OFFS)
  56257. +#define SDRAM_TWTR_OFFS 16
  56258. +#define SDRAM_TWTR_MASK (0xF << SDRAM_TWTR_OFFS)
  56259. +#define SDRAM_TRAS_OFFS 20
  56260. +#define SDRAM_TRAS_MASK (0xF << SDRAM_TRAS_OFFS)
  56261. +#define SDRAM_TRRD_OFFS 24
  56262. +#define SDRAM_TRRD_MASK (0xF << SDRAM_TRRD_OFFS)
  56263. +#define SDRAM_TRTP_OFFS 28
  56264. +#define SDRAM_TRTP_MASK (0xF << SDRAM_TRTP_OFFS)
  56265. +
  56266. +/* sdram timing control high register */
  56267. +#define SDRAM_TIMING_CTRL_HIGH_REG 0x140c
  56268. +#define SDRAM_TRFC_OFFS 0
  56269. +#define SDRAM_TRFC_MASK (0xF << SDRAM_TRFC_OFFS)
  56270. +#define SDRAM_TR2R_OFFS 4
  56271. +#define SDRAM_TR2R_MASK (0x3 << SDRAM_TR2R_OFFS)
  56272. +#define SDRAM_TR2W_W2R_OFFS 6
  56273. +#define SDRAM_TR2W_W2R_MASK (0x3 << SDRAM_TR2W_W2R_OFFS)
  56274. +#define SDRAM_TRFC_EXT_OFFS 8
  56275. +#define SDRAM_TRFC_EXT_MASK (0x1 << SDRAM_TRFC_EXT_OFFS)
  56276. +#define SDRAM_TW2W_OFFS 10
  56277. +#define SDRAM_TW2W_MASK (0x1 << SDRAM_TW2W_OFFS)
  56278. +
  56279. +/* address control register */
  56280. +#define SDRAM_ADDR_CTRL_REG 0x1410
  56281. +#define SDRAM_DSIZE_OFFS 4
  56282. +#define SDRAM_DSIZE_MASK (0x3 << SDRAM_DSIZE_OFFS)
  56283. +#define SDRAM_DSIZE_128Mb (0x0 << SDRAM_DSIZE_OFFS)
  56284. +#define SDRAM_DSIZE_256Mb (0x1 << SDRAM_DSIZE_OFFS)
  56285. +#define SDRAM_DSIZE_512Mb (0x2 << SDRAM_DSIZE_OFFS)
  56286. +
  56287. +/* SDRAM Open Pages Control registers */
  56288. +#define SDRAM_OPEN_PAGE_CTRL_REG 0x1414
  56289. +#define SDRAM_OPEN_PAGE_EN (0 << 0)
  56290. +#define SDRAM_OPEN_PAGE_DIS (1 << 0)
  56291. +
  56292. +/* sdram opertion register */
  56293. +#define SDRAM_OPERATION_REG 0x1418
  56294. +#define SDRAM_CMD_OFFS 0
  56295. +#define SDRAM_CMD_MASK (0x7 << SDRAM_CMD_OFFS)
  56296. +#define SDRAM_CMD_NORMAL (0x0 << SDRAM_CMD_OFFS)
  56297. +#define SDRAM_CMD_PRECHARGE_ALL (0x1 << SDRAM_CMD_OFFS)
  56298. +#define SDRAM_CMD_REFRESH_ALL (0x2 << SDRAM_CMD_OFFS)
  56299. +#define SDRAM_CMD_REG_SET_CMD (0x3 << SDRAM_CMD_OFFS)
  56300. +#define SDRAM_CMD_EXT_MODE_SET (0x4 << SDRAM_CMD_OFFS)
  56301. +#define SDRAM_CMD_NOP (0x5 << SDRAM_CMD_OFFS)
  56302. +#define SDRAM_CMD_SLF_RFRSH (0x7 << SDRAM_CMD_OFFS)
  56303. +#define SDRAM_CMD_EMRS2_CMD (0x8 << SDRAM_CMD_OFFS)
  56304. +#define SDRAM_CMD_EMRS3_CMD (0x9 << SDRAM_CMD_OFFS)
  56305. +
  56306. +/* sdram mode register */
  56307. +#define SDRAM_MODE_REG 0x141c
  56308. +#define SDRAM_BURST_LEN_OFFS 0
  56309. +#define SDRAM_BURST_LEN_MASK (0x7 << SDRAM_BURST_LEN_OFFS)
  56310. +#define SDRAM_BURST_LEN_4 (0x2 << SDRAM_BURST_LEN_OFFS)
  56311. +#define SDRAM_CL_OFFS 4
  56312. +#define SDRAM_CL_MASK (0x7 << SDRAM_CL_OFFS)
  56313. +#define SDRAM_DDR1_CL_2 (0x2 << SDRAM_CL_OFFS)
  56314. +#define SDRAM_DDR1_CL_3 (0x3 << SDRAM_CL_OFFS)
  56315. +#define SDRAM_DDR1_CL_4 (0x4 << SDRAM_CL_OFFS)
  56316. +#define SDRAM_DDR1_CL_1_5 (0x5 << SDRAM_CL_OFFS)
  56317. +#define SDRAM_DDR1_CL_2_5 (0x6 << SDRAM_CL_OFFS)
  56318. +#define SDRAM_DDR2_CL_3 (0x3 << SDRAM_CL_OFFS)
  56319. +#define SDRAM_DDR2_CL_4 (0x4 << SDRAM_CL_OFFS)
  56320. +#define SDRAM_DDR2_CL_5 (0x5 << SDRAM_CL_OFFS)
  56321. +#define SDRAM_TM_OFFS 7
  56322. +#define SDRAM_TM_MASK (1 << SDRAM_TM_OFFS)
  56323. +#define SDRAM_TM_NORMAL (0 << SDRAM_TM_OFFS)
  56324. +#define SDRAM_TM_TEST_MODE (1 << SDRAM_TM_OFFS)
  56325. +#define SDRAM_DLL_OFFS 8
  56326. +#define SDRAM_DLL_MASK (1 << SDRAM_DLL_OFFS)
  56327. +#define SDRAM_DLL_NORMAL (0 << SDRAM_DLL_OFFS)
  56328. +#define SDRAM_DLL_RESET (1 << SDRAM_DLL_OFFS)
  56329. +#define SDRAM_WR_OFFS 11
  56330. +#define SDRAM_WR_MAX 7
  56331. +#define SDRAM_WR_MASK (SDRAM_WR_MAX << SDRAM_WR_OFFS)
  56332. +#define SDRAM_PD_OFFS 12
  56333. +#define SDRAM_PD_MASK (1 << SDRAM_PD_OFFS)
  56334. +#define SDRAM_PD_FAST_EXIT (0 << SDRAM_PD_OFFS)
  56335. +#define SDRAM_PD_SLOW_EXIT (1 << SDRAM_PD_OFFS)
  56336. +
  56337. +/* DDR SDRAM Extended Mode register (DSEMR) */
  56338. +#define SDRAM_EXTENDED_MODE_REG 0x1420
  56339. +#define DSEMR_DLL_ENABLE (1 << 0)
  56340. +#define DSEMR_DS_OFFS 1
  56341. +#define DSEMR_DS_MASK (1 << DSEMR_DS_OFFS)
  56342. +#define DSEMR_DS_NORMAL (0 << DSEMR_DS_OFFS)
  56343. +#define DSEMR_DS_REDUCED (1 << DSEMR_DS_OFFS)
  56344. +#define DSEMR_RTT0_OFFS 2
  56345. +#define DSEMR_RTT1_OFFS 6
  56346. +#define DSEMR_RTT_ODT_DISABLE ((0 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
  56347. +#define DSEMR_RTT_ODT_75_OHM ((1 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
  56348. +#define DSEMR_RTT_ODT_150_OHM ((0 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))
  56349. +#define DSEMR_OCD_OFFS 7
  56350. +#define DSEMR_OCD_MASK (0x7 << DSEMR_OCD_OFFS)
  56351. +#define DSEMR_OCD_EXIT_CALIB (0 << DSEMR_OCD_OFFS)
  56352. +#define DSEMR_OCD_DRIVE1 (1 << DSEMR_OCD_OFFS)
  56353. +#define DSEMR_OCD_DRIVE0 (2 << DSEMR_OCD_OFFS)
  56354. +#define DSEMR_OCD_ADJUST_MODE (4 << DSEMR_OCD_OFFS)
  56355. +#define DSEMR_OCD_CALIB_DEFAULT (7 << DSEMR_OCD_OFFS)
  56356. +#define DSEMR_DQS_OFFS 10
  56357. +#define DSEMR_DQS_MASK (1 << DSEMR_DQS_OFFS)
  56358. +#define DSEMR_DQS_DIFFERENTIAL (0 << DSEMR_DQS_OFFS)
  56359. +#define DSEMR_DQS_SINGLE_ENDED (0 << DSEMR_DQS_OFFS)
  56360. +#define DSEMR_RDQS_ENABLE (1 << 11)
  56361. +#define DSEMR_QOFF_OUTPUT_BUFF_EN (1 << 12)
  56362. +
  56363. +/* DDR SDRAM Operation Control Register */
  56364. +#define SDRAM_OPERATION_CTRL_REG 0x142c
  56365. +
  56366. +/* Dunit FTDLL Configuration Register */
  56367. +#define SDRAM_FTDLL_CONFIG_REG 0x1484
  56368. +
  56369. +/* Pads Calibration register */
  56370. +#define SDRAM_ADDR_CTRL_PADS_CAL_REG 0x14c0
  56371. +#define SDRAM_DATA_PADS_CAL_REG 0x14c4
  56372. +#define SDRAM_DRVN_OFFS 0
  56373. +#define SDRAM_DRVN_MASK (0x3F << SDRAM_DRVN_OFFS)
  56374. +#define SDRAM_DRVP_OFFS 6
  56375. +#define SDRAM_DRVP_MASK (0x3F << SDRAM_DRVP_OFFS)
  56376. +#define SDRAM_PRE_DRIVER_STRENGTH_OFFS 12
  56377. +#define SDRAM_PRE_DRIVER_STRENGTH_MASK (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  56378. +#define SDRAM_TUNE_EN BIT16
  56379. +#define SDRAM_LOCK_OFFS 17
  56380. +#define SDRAM_LOCK_MAKS (0x1F << SDRAM_LOCK_OFFS)
  56381. +#define SDRAM_LOCKN_OFFS 17
  56382. +#define SDRAM_LOCKN_MAKS (0x3F << SDRAM_LOCKN_OFFS)
  56383. +#define SDRAM_LOCKP_OFFS 23
  56384. +#define SDRAM_LOCKP_MAKS (0x3F << SDRAM_LOCKP_OFFS)
  56385. +#define SDRAM_WR_EN (1 << 31)
  56386. +
  56387. +/* DDR2 SDRAM ODT Control (Low) Register (DSOCLR) */
  56388. +#define DDR2_SDRAM_ODT_CTRL_LOW_REG 0x1494
  56389. +#define DSOCLR_ODT_RD_OFFS(odtNum) (odtNum * 4)
  56390. +#define DSOCLR_ODT_RD_MASK(odtNum) (0xf << DSOCLR_ODT_RD_OFFS(odtNum))
  56391. +#define DSOCLR_ODT_RD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_RD_OFFS(odtNum))
  56392. +#define DSOCLR_ODT_WR_OFFS(odtNum) (16 + (odtNum * 4))
  56393. +#define DSOCLR_ODT_WR_MASK(odtNum) (0xf << DSOCLR_ODT_WR_OFFS(odtNum))
  56394. +#define DSOCLR_ODT_WD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_WR_OFFS(odtNum))
  56395. +
  56396. +/* DDR2 SDRAM ODT Control (High) Register (DSOCHR) */
  56397. +#define DDR2_SDRAM_ODT_CTRL_HIGH_REG 0x1498
  56398. +/* Optional control values to DSOCHR_ODT_EN macro */
  56399. +#define DDR2_ODT_CTRL_DUNIT 0
  56400. +#define DDR2_ODT_CTRL_NEVER 1
  56401. +#define DDR2_ODT_CTRL_ALWAYS 3
  56402. +#define DSOCHR_ODT_EN_OFFS(odtNum) (odtNum * 2)
  56403. +#define DSOCHR_ODT_EN_MASK(odtNum) (0x3 << DSOCHR_ODT_EN_OFFS(odtNum))
  56404. +#define DSOCHR_ODT_EN(odtNum, ctrl) ((1 << ctrl) << DSOCHR_ODT_RD_OFFS(odtNum))
  56405. +
  56406. +/* DDR2 Dunit ODT Control Register (DDOCR)*/
  56407. +#define DDR2_DUNIT_ODT_CONTROL_REG 0x149c
  56408. +#define DDOCR_ODT_RD_OFFS 0
  56409. +#define DDOCR_ODT_RD_MASK (0xf << DDOCR_ODT_RD_OFFS)
  56410. +#define DDOCR_ODT_RD(bank) ((1 << bank) << DDOCR_ODT_RD_OFFS)
  56411. +#define DDOCR_ODT_WR_OFFS 4
  56412. +#define DDOCR_ODT_WR_MASK (0xf << DDOCR_ODT_WR_OFFS)
  56413. +#define DDOCR_ODT_WR(bank) ((1 << bank) << DDOCR_ODT_WR_OFFS)
  56414. +#define DSOCR_ODT_EN_OFFS 8
  56415. +#define DSOCR_ODT_EN_MASK (0x3 << DSOCR_ODT_EN_OFFS)
  56416. +#define DSOCR_ODT_EN(ctrl) ((1 << ctrl) << DSOCR_ODT_EN_OFFS)
  56417. +#define DSOCR_ODT_SEL_OFFS 10
  56418. +#define DSOCR_ODT_SEL_MASK (0x3 << DSOCR_ODT_SEL_OFFS)
  56419. +
  56420. +/* DDR SDRAM Initialization Control Register (DSICR) */
  56421. +#define DDR_SDRAM_INIT_CTRL_REG 0x1480
  56422. +#define DSICR_INIT_EN (1 << 0)
  56423. +
  56424. +#endif /* __INCmvDramIfRegsh */
  56425. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c
  56426. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c 1970-01-01 01:00:00.000000000 +0100
  56427. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c 2010-08-05 22:02:24.254867983 +0200
  56428. @@ -0,0 +1,1855 @@
  56429. +/*******************************************************************************
  56430. +Copyright (C) Marvell International Ltd. and its affiliates
  56431. +
  56432. +This software file (the "File") is owned and distributed by Marvell
  56433. +International Ltd. and/or its affiliates ("Marvell") under the following
  56434. +alternative licensing terms. Once you have made an election to distribute the
  56435. +File under one of the following license alternatives, please (i) delete this
  56436. +introductory statement regarding license alternatives, (ii) delete the two
  56437. +license alternatives that you have not elected to use and (iii) preserve the
  56438. +Marvell copyright notice above.
  56439. +
  56440. +********************************************************************************
  56441. +Marvell Commercial License Option
  56442. +
  56443. +If you received this File from Marvell and you have entered into a commercial
  56444. +license agreement (a "Commercial License") with Marvell, the File is licensed
  56445. +to you under the terms of the applicable Commercial License.
  56446. +
  56447. +********************************************************************************
  56448. +Marvell GPL License Option
  56449. +
  56450. +If you received this File from Marvell, you may opt to use, redistribute and/or
  56451. +modify this File in accordance with the terms and conditions of the General
  56452. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  56453. +available along with the File in the license.txt file or by writing to the Free
  56454. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  56455. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  56456. +
  56457. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  56458. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  56459. +DISCLAIMED. The GPL License provides additional details about this warranty
  56460. +disclaimer.
  56461. +********************************************************************************
  56462. +Marvell BSD License Option
  56463. +
  56464. +If you received this File from Marvell, you may opt to use, redistribute and/or
  56465. +modify this File under the following licensing terms.
  56466. +Redistribution and use in source and binary forms, with or without modification,
  56467. +are permitted provided that the following conditions are met:
  56468. +
  56469. + * Redistributions of source code must retain the above copyright notice,
  56470. + this list of conditions and the following disclaimer.
  56471. +
  56472. + * Redistributions in binary form must reproduce the above copyright
  56473. + notice, this list of conditions and the following disclaimer in the
  56474. + documentation and/or other materials provided with the distribution.
  56475. +
  56476. + * Neither the name of Marvell nor the names of its contributors may be
  56477. + used to endorse or promote products derived from this software without
  56478. + specific prior written permission.
  56479. +
  56480. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  56481. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  56482. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  56483. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  56484. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  56485. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  56486. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  56487. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  56488. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  56489. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  56490. +
  56491. +*******************************************************************************/
  56492. +
  56493. +
  56494. +/* includes */
  56495. +#include "ddr2/mvDramIf.h"
  56496. +#include "ctrlEnv/sys/mvCpuIf.h"
  56497. +
  56498. +#include "ddr2/mvDramIfStaticInit.h"
  56499. +
  56500. +/* #define MV_DEBUG */
  56501. +#ifdef MV_DEBUG
  56502. +#define DB(x) x
  56503. +#else
  56504. +#define DB(x)
  56505. +#endif
  56506. +
  56507. +/* DRAM bank presence encoding */
  56508. +#define BANK_PRESENT_CS0 0x1
  56509. +#define BANK_PRESENT_CS0_CS1 0x3
  56510. +#define BANK_PRESENT_CS0_CS2 0x5
  56511. +#define BANK_PRESENT_CS0_CS1_CS2 0x7
  56512. +#define BANK_PRESENT_CS0_CS2_CS3 0xd
  56513. +#define BANK_PRESENT_CS0_CS2_CS3_CS4 0xf
  56514. +
  56515. +/* locals */
  56516. +#ifndef MV_STATIC_DRAM_ON_BOARD
  56517. +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo);
  56518. +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk, MV_STATUS TTmode );
  56519. +static MV_U32 dunitCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
  56520. +static MV_U32 sdramModeRegCalc(MV_U32 minCas);
  56521. +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
  56522. +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfoDIMM1);
  56523. +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk);
  56524. +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk, MV_U32 forcedCl);
  56525. +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk);
  56526. +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
  56527. +static MV_U32 sdramDdr2TimeLoRegCalc(MV_U32 minCas);
  56528. +static MV_U32 sdramDdr2TimeHiRegCalc(MV_U32 minCas);
  56529. +#endif
  56530. +MV_32 DRAM_CS_Order[MV_DRAM_MAX_CS] = {N_A
  56531. +
  56532. +#ifdef MV_INCLUDE_SDRAM_CS1
  56533. + ,N_A
  56534. +#endif
  56535. +#ifdef MV_INCLUDE_SDRAM_CS2
  56536. + ,N_A
  56537. +#endif
  56538. +#ifdef MV_INCLUDE_SDRAM_CS3
  56539. + ,N_A
  56540. +#endif
  56541. + };
  56542. +/* Get DRAM size of CS num */
  56543. +MV_U32 mvDramCsSizeGet(MV_U32 csNum)
  56544. +{
  56545. + MV_DRAM_BANK_INFO bankInfo;
  56546. + MV_U32 size, deviceW, dimmW;
  56547. +#ifdef MV78XX0
  56548. + MV_U32 temp;
  56549. +#endif
  56550. +
  56551. + if(MV_OK == mvDramBankInfoGet(csNum, &bankInfo))
  56552. + {
  56553. + if (0 == bankInfo.size)
  56554. + return 0;
  56555. +
  56556. + /* Note that the Dimm width might be different then the device DRAM width */
  56557. +#ifdef MV78XX0
  56558. + temp = MV_REG_READ(SDRAM_CONFIG_REG);
  56559. + deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_32BIT )? 32 : 64;
  56560. +#else
  56561. + deviceW = 16 /* KW family */;
  56562. +#endif
  56563. + dimmW = bankInfo.dataWidth - (bankInfo.dataWidth % 16);
  56564. + size = ((bankInfo.size << 20) / (dimmW/deviceW));
  56565. + return size;
  56566. + }
  56567. + else
  56568. + return 0;
  56569. +}
  56570. +/*******************************************************************************
  56571. +* mvDramIfDetect - Prepare DRAM interface configuration values.
  56572. +*
  56573. +* DESCRIPTION:
  56574. +* This function implements the full DRAM detection and timing
  56575. +* configuration for best system performance.
  56576. +* Since this routine runs from a ROM device (Boot Flash), its stack
  56577. +* resides on RAM, that might be the system DRAM. Changing DRAM
  56578. +* configuration values while keeping vital data in DRAM is risky. That
  56579. +* is why the function does not preform the configuration setting but
  56580. +* prepare those in predefined 32bit registers (in this case IDMA
  56581. +* registers are used) for other routine to perform the settings.
  56582. +* The function will call for board DRAM SPD information for each DRAM
  56583. +* chip select. The function will then analyze those SPD parameters of
  56584. +* all DRAM banks in order to decide on DRAM configuration compatible
  56585. +* for all DRAM banks.
  56586. +* The function will set the CPU DRAM address decode registers.
  56587. +* Note: This routine prepares values that will overide configuration of
  56588. +* mvDramBasicAsmInit().
  56589. +*
  56590. +* INPUT:
  56591. +* forcedCl - Forced CAL Latency. If equal to zero, do not force.
  56592. +* eccDisable - Force down the ECC.
  56593. +*
  56594. +* OUTPUT:
  56595. +* None.
  56596. +*
  56597. +* RETURN:
  56598. +* None.
  56599. +*
  56600. +*******************************************************************************/
  56601. +MV_STATUS mvDramIfDetect(MV_U32 forcedCl, MV_BOOL eccDisable)
  56602. +{
  56603. + MV_32 MV_DRAM_CS_order[MV_DRAM_MAX_CS] = {
  56604. + SDRAM_CS0
  56605. +#ifdef MV_INCLUDE_SDRAM_CS1
  56606. + ,SDRAM_CS1
  56607. +#endif
  56608. +#ifdef MV_INCLUDE_SDRAM_CS2
  56609. + ,SDRAM_CS2
  56610. +#endif
  56611. +#ifdef MV_INCLUDE_SDRAM_CS3
  56612. + ,SDRAM_CS3
  56613. +#endif
  56614. + };
  56615. + MV_U32 busClk, deviceW, dimmW;
  56616. + MV_U32 numOfAllDevices = 0;
  56617. + MV_STATUS TTMode;
  56618. +#ifndef MV_STATIC_DRAM_ON_BOARD
  56619. + MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
  56620. + MV_U32 size, base = 0, i, j, temp, busClkPs;
  56621. + MV_U8 minCas;
  56622. + MV_CPU_DEC_WIN dramDecWin;
  56623. + dramDecWin.addrWin.baseHigh = 0;
  56624. +#endif
  56625. +
  56626. + busClk = mvBoardSysClkGet();
  56627. +
  56628. + if (0 == busClk)
  56629. + {
  56630. + mvOsPrintf("Dram: ERR. Can't detect system clock! \n");
  56631. + return MV_ERROR;
  56632. + }
  56633. +
  56634. +#ifndef MV_STATIC_DRAM_ON_BOARD
  56635. +
  56636. + busClkPs = 1000000000 / (busClk / 1000); /* in ps units */
  56637. + /* we will use bank 0 as the representative of the all the DRAM banks, */
  56638. + /* since bank 0 must exist. */
  56639. + for(i = 0; i < MV_DRAM_MAX_CS; i++)
  56640. + {
  56641. + /* if Bank exist */
  56642. + if(MV_OK == mvDramBankInfoGet(i, &bankInfo[i]))
  56643. + {
  56644. + DB(mvOsPrintf("Dram: Find bank %d\n", i));
  56645. + /* check it isn't SDRAM */
  56646. + if(bankInfo[i].memoryType != MEM_TYPE_DDR2)
  56647. + {
  56648. + mvOsOutput("Dram: ERR. SDRAM type not supported !!!\n");
  56649. + return MV_ERROR;
  56650. + }
  56651. +
  56652. + /* All banks must support the Mclk freqency */
  56653. + if(bankInfo[i].minCycleTimeAtMaxCasLatPs > busClkPs)
  56654. + {
  56655. + mvOsOutput("Dram: ERR. Bank %d doesn't support memory clock!!!\n", i);
  56656. + return MV_ERROR;
  56657. + }
  56658. +
  56659. + /* All banks must support registry in order to activate it */
  56660. + if(bankInfo[i].registeredAddrAndControlInputs !=
  56661. + bankInfo[0].registeredAddrAndControlInputs)
  56662. + {
  56663. + mvOsOutput("Dram: ERR. different Registered settings !!!\n");
  56664. + return MV_ERROR;
  56665. + }
  56666. +
  56667. + /* All banks must support same ECC mode */
  56668. + if(bankInfo[i].errorCheckType !=
  56669. + bankInfo[0].errorCheckType)
  56670. + {
  56671. + mvOsOutput("Dram: ERR. different ECC settings !!!\n");
  56672. + return MV_ERROR;
  56673. + }
  56674. +
  56675. + }
  56676. + else
  56677. + {
  56678. + if( i == 0 ) /* bank 0 doesn't exist */
  56679. + {
  56680. + mvOsOutput("Dram: ERR. Fail to detect bank 0 !!!\n");
  56681. + return MV_ERROR;
  56682. + }
  56683. + else
  56684. + {
  56685. + DB(mvOsPrintf("Dram: Could not find bank %d\n", i));
  56686. + bankInfo[i].size = 0; /* Mark this bank as non exist */
  56687. + }
  56688. + }
  56689. + }
  56690. +
  56691. +#ifdef MV_INCLUDE_SDRAM_CS2
  56692. + if (bankInfo[SDRAM_CS0].size < bankInfo[SDRAM_CS2].size)
  56693. + {
  56694. + MV_DRAM_CS_order[0] = SDRAM_CS2;
  56695. + MV_DRAM_CS_order[1] = SDRAM_CS3;
  56696. + MV_DRAM_CS_order[2] = SDRAM_CS0;
  56697. + MV_DRAM_CS_order[3] = SDRAM_CS1;
  56698. + DRAM_CS_Order[0] = SDRAM_CS2;
  56699. + DRAM_CS_Order[1] = SDRAM_CS3;
  56700. + DRAM_CS_Order[2] = SDRAM_CS0;
  56701. + DRAM_CS_Order[3] = SDRAM_CS1;
  56702. +
  56703. + }
  56704. + else
  56705. +#endif
  56706. + {
  56707. + MV_DRAM_CS_order[0] = SDRAM_CS0;
  56708. + MV_DRAM_CS_order[1] = SDRAM_CS1;
  56709. + DRAM_CS_Order[0] = SDRAM_CS0;
  56710. + DRAM_CS_Order[1] = SDRAM_CS1;
  56711. +#ifdef MV_INCLUDE_SDRAM_CS2
  56712. + MV_DRAM_CS_order[2] = SDRAM_CS2;
  56713. + MV_DRAM_CS_order[3] = SDRAM_CS3;
  56714. + DRAM_CS_Order[2] = SDRAM_CS2;
  56715. + DRAM_CS_Order[3] = SDRAM_CS3;
  56716. +#endif
  56717. + }
  56718. +
  56719. + for(j = 0; j < MV_DRAM_MAX_CS; j++)
  56720. + {
  56721. + i = MV_DRAM_CS_order[j];
  56722. +
  56723. + if (0 == bankInfo[i].size)
  56724. + continue;
  56725. +
  56726. + /* Init the CPU window decode */
  56727. + /* Note that the Dimm width might be different then the device DRAM width */
  56728. +#ifdef MV78XX0
  56729. + temp = MV_REG_READ(SDRAM_CONFIG_REG);
  56730. + deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_32BIT )? 32 : 64;
  56731. +#else
  56732. + deviceW = 16 /* KW family */;
  56733. +#endif
  56734. + dimmW = bankInfo[0].dataWidth - (bankInfo[0].dataWidth % 16);
  56735. + size = ((bankInfo[i].size << 20) / (dimmW/deviceW));
  56736. +
  56737. + /* We can not change DRAM window settings while excecuting */
  56738. + /* code from it. That is why we skip the DRAM CS[0], saving */
  56739. + /* it to the ROM configuration routine */
  56740. +
  56741. + numOfAllDevices += bankInfo[i].numberOfDevices;
  56742. + if (i == MV_DRAM_CS_order[0])
  56743. + {
  56744. + MV_U32 sizeToReg;
  56745. + /* Translate the given window size to register format */
  56746. + sizeToReg = ctrlSizeToReg(size, SCSR_SIZE_ALIGNMENT);
  56747. + /* Size parameter validity check. */
  56748. + if (-1 == sizeToReg)
  56749. + {
  56750. + mvOsOutput("DRAM: mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n"
  56751. + ,i);
  56752. + return MV_BAD_PARAM;
  56753. + }
  56754. +
  56755. + DB(mvOsPrintf("Dram: Bank 0 Size - %x\n",sizeToReg);)
  56756. + sizeToReg = (sizeToReg << SCSR_SIZE_OFFS);
  56757. + sizeToReg |= SCSR_WIN_EN;
  56758. + MV_REG_WRITE(DRAM_BUF_REG0, sizeToReg);
  56759. + }
  56760. + else
  56761. + {
  56762. + dramDecWin.addrWin.baseLow = base;
  56763. + dramDecWin.addrWin.size = size;
  56764. + dramDecWin.enable = MV_TRUE;
  56765. + DB(mvOsPrintf("Dram: Enable window %d base 0x%x, size=0x%x\n",i, base, size));
  56766. +
  56767. + /* Check if the DRAM size is more then 3GByte */
  56768. + if (base < 0xC0000000)
  56769. + {
  56770. + DB(mvOsPrintf("Dram: Enable window %d base 0x%x, size=0x%x\n",i, base, size));
  56771. + if (MV_OK != mvCpuIfTargetWinSet(i, &dramDecWin))
  56772. + {
  56773. + mvOsPrintf("Dram: ERR. Fail to set bank %d!!!\n", SDRAM_CS0 + i);
  56774. + return MV_ERROR;
  56775. + }
  56776. + }
  56777. + }
  56778. +
  56779. + base += size;
  56780. +
  56781. + /* update the suportedCasLatencies mask */
  56782. + bankInfo[0].suportedCasLatencies &= bankInfo[i].suportedCasLatencies;
  56783. + }
  56784. +
  56785. + /* calculate minimum CAS */
  56786. + minCas = minCasCalc(&bankInfo[0], &bankInfo[2], busClk, forcedCl);
  56787. + if (0 == minCas)
  56788. + {
  56789. + mvOsOutput("Dram: Warn: Could not find CAS compatible to SysClk %dMhz\n",
  56790. + (busClk / 1000000));
  56791. +
  56792. + minCas = DDR2_CL_4; /* Continue with this CAS */
  56793. + mvOsOutput("Set default CAS latency 4\n");
  56794. + }
  56795. +
  56796. + /* calc SDRAM_CONFIG_REG and save it to temp register */
  56797. + temp = sdramConfigRegCalc(&bankInfo[0],&bankInfo[2], busClk);
  56798. + if(-1 == temp)
  56799. + {
  56800. + mvOsOutput("Dram: ERR. sdramConfigRegCalc failed !!!\n");
  56801. + return MV_ERROR;
  56802. + }
  56803. +
  56804. + /* check if ECC is enabled by the user */
  56805. + if(eccDisable)
  56806. + {
  56807. + /* turn off ECC*/
  56808. + temp &= ~BIT18;
  56809. + }
  56810. + DB(mvOsPrintf("Dram: sdramConfigRegCalc - %x\n",temp);)
  56811. + MV_REG_WRITE(DRAM_BUF_REG1, temp);
  56812. +
  56813. + /* calc SDRAM_MODE_REG and save it to temp register */
  56814. + temp = sdramModeRegCalc(minCas);
  56815. + if(-1 == temp)
  56816. + {
  56817. + mvOsOutput("Dram: ERR. sdramModeRegCalc failed !!!\n");
  56818. + return MV_ERROR;
  56819. + }
  56820. + DB(mvOsPrintf("Dram: sdramModeRegCalc - %x\n",temp);)
  56821. + MV_REG_WRITE(DRAM_BUF_REG2, temp);
  56822. +
  56823. + /* calc SDRAM_EXTENDED_MODE_REG and save it to temp register */
  56824. + temp = sdramExtModeRegCalc(&bankInfo[0], busClk);
  56825. + if(-1 == temp)
  56826. + {
  56827. + mvOsOutput("Dram: ERR. sdramExtModeRegCalc failed !!!\n");
  56828. + return MV_ERROR;
  56829. + }
  56830. + DB(mvOsPrintf("Dram: sdramExtModeRegCalc - %x\n",temp);)
  56831. + MV_REG_WRITE(DRAM_BUF_REG10, temp);
  56832. +
  56833. + /* calc D_UNIT_CONTROL_LOW and save it to temp register */
  56834. + TTMode = MV_FALSE;
  56835. + DB(mvOsPrintf("Dram: numOfAllDevices = %x\n",numOfAllDevices);)
  56836. + if( (numOfAllDevices > 9) && (bankInfo[0].registeredAddrAndControlInputs == MV_FALSE) )
  56837. + {
  56838. + if ( ( (numOfAllDevices > 9) && (busClk > MV_BOARD_SYSCLK_200MHZ) ) ||
  56839. + (numOfAllDevices > 18) )
  56840. + {
  56841. + mvOsOutput("Enable 2T ");
  56842. + TTMode = MV_TRUE;
  56843. + }
  56844. + }
  56845. +
  56846. + temp = dunitCtrlLowRegCalc(&bankInfo[0], minCas, busClk, TTMode );
  56847. + if(-1 == temp)
  56848. + {
  56849. + mvOsOutput("Dram: ERR. dunitCtrlLowRegCalc failed !!!\n");
  56850. + return MV_ERROR;
  56851. + }
  56852. + DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc - %x\n",temp);)
  56853. + MV_REG_WRITE(DRAM_BUF_REG3, temp);
  56854. +
  56855. + /* calc D_UNIT_CONTROL_HIGH and save it to temp register */
  56856. + temp = dunitCtrlHighRegCalc(&bankInfo[0], busClk);
  56857. + if(-1 == temp)
  56858. + {
  56859. + mvOsOutput("Dram: ERR. dunitCtrlHighRegCalc failed !!!\n");
  56860. + return MV_ERROR;
  56861. + }
  56862. + DB(mvOsPrintf("Dram: dunitCtrlHighRegCalc - %x\n",temp);)
  56863. + /* check if ECC is enabled by the user */
  56864. + if(eccDisable)
  56865. + {
  56866. + /* turn off sample stage if no ecc */
  56867. + temp &= ~SDRAM__D2P_EN;;
  56868. + }
  56869. + MV_REG_WRITE(DRAM_BUF_REG13, temp);
  56870. +
  56871. + /* calc SDRAM_ADDR_CTRL_REG and save it to temp register */
  56872. + temp = sdramAddrCtrlRegCalc(&bankInfo[0],&bankInfo[2]);
  56873. + if(-1 == temp)
  56874. + {
  56875. + mvOsOutput("Dram: ERR. sdramAddrCtrlRegCalc failed !!!\n");
  56876. + return MV_ERROR;
  56877. + }
  56878. + DB(mvOsPrintf("Dram: sdramAddrCtrlRegCalc - %x\n",temp);)
  56879. + MV_REG_WRITE(DRAM_BUF_REG4, temp);
  56880. +
  56881. + /* calc SDRAM_TIMING_CTRL_LOW_REG and save it to temp register */
  56882. + temp = sdramTimeCtrlLowRegCalc(&bankInfo[0], minCas, busClk);
  56883. + if(-1 == temp)
  56884. + {
  56885. + mvOsOutput("Dram: ERR. sdramTimeCtrlLowRegCalc failed !!!\n");
  56886. + return MV_ERROR;
  56887. + }
  56888. + DB(mvOsPrintf("Dram: sdramTimeCtrlLowRegCalc - %x\n",temp);)
  56889. + MV_REG_WRITE(DRAM_BUF_REG5, temp);
  56890. +
  56891. + /* calc SDRAM_TIMING_CTRL_HIGH_REG and save it to temp register */
  56892. + temp = sdramTimeCtrlHighRegCalc(&bankInfo[0], busClk);
  56893. + if(-1 == temp)
  56894. + {
  56895. + mvOsOutput("Dram: ERR. sdramTimeCtrlHighRegCalc failed !!!\n");
  56896. + return MV_ERROR;
  56897. + }
  56898. + DB(mvOsPrintf("Dram: sdramTimeCtrlHighRegCalc - %x\n",temp);)
  56899. + MV_REG_WRITE(DRAM_BUF_REG6, temp);
  56900. +
  56901. + sdramDDr2OdtConfig(bankInfo);
  56902. +
  56903. + /* calc DDR2_SDRAM_TIMING_LOW_REG and save it to temp register */
  56904. + temp = sdramDdr2TimeLoRegCalc(minCas);
  56905. + if(-1 == temp)
  56906. + {
  56907. + mvOsOutput("Dram: ERR. sdramDdr2TimeLoRegCalc failed !!!\n");
  56908. + return MV_ERROR;
  56909. + }
  56910. + DB(mvOsPrintf("Dram: sdramDdr2TimeLoRegCalc - %x\n",temp);)
  56911. + MV_REG_WRITE(DRAM_BUF_REG11, temp);
  56912. +
  56913. + /* calc DDR2_SDRAM_TIMING_HIGH_REG and save it to temp register */
  56914. + temp = sdramDdr2TimeHiRegCalc(minCas);
  56915. + if(-1 == temp)
  56916. + {
  56917. + mvOsOutput("Dram: ERR. sdramDdr2TimeHiRegCalc failed !!!\n");
  56918. + return MV_ERROR;
  56919. + }
  56920. + DB(mvOsPrintf("Dram: sdramDdr2TimeHiRegCalc - %x\n",temp);)
  56921. + MV_REG_WRITE(DRAM_BUF_REG12, temp);
  56922. +#endif
  56923. +
  56924. + /* Note that DDR SDRAM Address/Control and Data pad calibration */
  56925. + /* settings is done in mvSdramIfConfig.s */
  56926. +
  56927. + return MV_OK;
  56928. +}
  56929. +
  56930. +
  56931. +/*******************************************************************************
  56932. +* mvDramIfBankBaseGet - Get DRAM interface bank base.
  56933. +*
  56934. +* DESCRIPTION:
  56935. +* This function returns the 32 bit base address of a given DRAM bank.
  56936. +*
  56937. +* INPUT:
  56938. +* bankNum - Bank number.
  56939. +*
  56940. +* OUTPUT:
  56941. +* None.
  56942. +*
  56943. +* RETURN:
  56944. +* DRAM bank size. If bank is disabled or paramter is invalid, the
  56945. +* function returns -1.
  56946. +*
  56947. +*******************************************************************************/
  56948. +MV_U32 mvDramIfBankBaseGet(MV_U32 bankNum)
  56949. +{
  56950. + DB(mvOsPrintf("Dram: mvDramIfBankBaseGet Bank %d base addr is %x \n",
  56951. + bankNum, mvCpuIfTargetWinBaseLowGet(SDRAM_CS0 + bankNum)));
  56952. + return mvCpuIfTargetWinBaseLowGet(SDRAM_CS0 + bankNum);
  56953. +}
  56954. +
  56955. +/*******************************************************************************
  56956. +* mvDramIfBankSizeGet - Get DRAM interface bank size.
  56957. +*
  56958. +* DESCRIPTION:
  56959. +* This function returns the size of a given DRAM bank.
  56960. +*
  56961. +* INPUT:
  56962. +* bankNum - Bank number.
  56963. +*
  56964. +* OUTPUT:
  56965. +* None.
  56966. +*
  56967. +* RETURN:
  56968. +* DRAM bank size. If bank is disabled the function return '0'. In case
  56969. +* or paramter is invalid, the function returns -1.
  56970. +*
  56971. +*******************************************************************************/
  56972. +MV_U32 mvDramIfBankSizeGet(MV_U32 bankNum)
  56973. +{
  56974. + DB(mvOsPrintf("Dram: mvDramIfBankSizeGet Bank %d size is %x \n",
  56975. + bankNum, mvCpuIfTargetWinSizeGet(SDRAM_CS0 + bankNum)));
  56976. + return mvCpuIfTargetWinSizeGet(SDRAM_CS0 + bankNum);
  56977. +}
  56978. +
  56979. +
  56980. +/*******************************************************************************
  56981. +* mvDramIfSizeGet - Get DRAM interface total size.
  56982. +*
  56983. +* DESCRIPTION:
  56984. +* This function get the DRAM total size.
  56985. +*
  56986. +* INPUT:
  56987. +* None.
  56988. +*
  56989. +* OUTPUT:
  56990. +* None.
  56991. +*
  56992. +* RETURN:
  56993. +* DRAM total size. In case or paramter is invalid, the function
  56994. +* returns -1.
  56995. +*
  56996. +*******************************************************************************/
  56997. +MV_U32 mvDramIfSizeGet(MV_VOID)
  56998. +{
  56999. + MV_U32 size = 0, i;
  57000. +
  57001. + for(i = 0; i < MV_DRAM_MAX_CS; i++)
  57002. + size += mvDramIfBankSizeGet(i);
  57003. +
  57004. + DB(mvOsPrintf("Dram: mvDramIfSizeGet size is %x \n",size));
  57005. + return size;
  57006. +}
  57007. +
  57008. +/*******************************************************************************
  57009. +* mvDramIfSingleBitErrThresholdSet - Set single bit ECC threshold.
  57010. +*
  57011. +* DESCRIPTION:
  57012. +* The ECC single bit error threshold is the number of single bit
  57013. +* errors to happen before the Dunit generates an interrupt.
  57014. +* This function set single bit ECC threshold.
  57015. +*
  57016. +* INPUT:
  57017. +* threshold - threshold.
  57018. +*
  57019. +* OUTPUT:
  57020. +* None.
  57021. +*
  57022. +* RETURN:
  57023. +* MV_BAD_PARAM if threshold is to big, MV_OK otherwise.
  57024. +*
  57025. +*******************************************************************************/
  57026. +MV_STATUS mvDramIfSingleBitErrThresholdSet(MV_U32 threshold)
  57027. +{
  57028. + MV_U32 regVal;
  57029. +
  57030. + if (threshold > SECR_THRECC_MAX)
  57031. + {
  57032. + return MV_BAD_PARAM;
  57033. + }
  57034. +
  57035. + regVal = MV_REG_READ(SDRAM_ECC_CONTROL_REG);
  57036. + regVal &= ~SECR_THRECC_MASK;
  57037. + regVal |= ((SECR_THRECC(threshold) & SECR_THRECC_MASK));
  57038. + MV_REG_WRITE(SDRAM_ECC_CONTROL_REG, regVal);
  57039. +
  57040. + return MV_OK;
  57041. +}
  57042. +
  57043. +#ifndef MV_STATIC_DRAM_ON_BOARD
  57044. +/*******************************************************************************
  57045. +* minCasCalc - Calculate the Minimum CAS latency which can be used.
  57046. +*
  57047. +* DESCRIPTION:
  57048. +* Calculate the minimum CAS latency that can be used, base on the DRAM
  57049. +* parameters and the SDRAM bus Clock freq.
  57050. +*
  57051. +* INPUT:
  57052. +* busClk - the DRAM bus Clock.
  57053. +* pBankInfo - bank info parameters.
  57054. +* forcedCl - Forced CAS Latency multiplied by 10. If equal to zero, do not force.
  57055. +*
  57056. +* OUTPUT:
  57057. +* None
  57058. +*
  57059. +* RETURN:
  57060. +* The minimum CAS Latency. The function returns 0 if max CAS latency
  57061. +* supported by banks is incompatible with system bus clock frequancy.
  57062. +*
  57063. +*******************************************************************************/
  57064. +
  57065. +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk, MV_U32 forcedCl)
  57066. +{
  57067. + MV_U32 count = 1, j;
  57068. + MV_U32 busClkPs = 1000000000 / (busClk / 1000); /* in ps units */
  57069. + MV_U32 startBit, stopBit;
  57070. + MV_U32 minCas0 = 0, minCas2 = 0;
  57071. +
  57072. +
  57073. + /* DDR 2:
  57074. + *******-******-******-******-******-******-******-*******
  57075. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  57076. + *******-******-******-******-******-******-******-*******
  57077. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  57078. + Disco VI= * TBD | TBD | 5 | 4 | 3 | TBD | TBD | TBD *
  57079. + Disco Duo= * TBD | 6 | 5 | 4 | 3 | TBD | TBD | TBD *
  57080. + *********************************************************/
  57081. +
  57082. +
  57083. + /* If we are asked to use the forced CAL we change the suported CAL to be forcedCl only */
  57084. + if (forcedCl)
  57085. + {
  57086. + mvOsOutput("DRAM: Using forced CL %d.%d\n", (forcedCl / 10), (forcedCl % 10));
  57087. +
  57088. + if (forcedCl == 30)
  57089. + pBankInfo->suportedCasLatencies = 0x08;
  57090. + else if (forcedCl == 40)
  57091. + pBankInfo->suportedCasLatencies = 0x10;
  57092. + else if (forcedCl == 50)
  57093. + pBankInfo->suportedCasLatencies = 0x20;
  57094. + else if (forcedCl == 60)
  57095. + pBankInfo->suportedCasLatencies = 0x40;
  57096. + else
  57097. + {
  57098. + mvOsPrintf("Forced CL %d.%d not supported. Set default CL 4\n",
  57099. + (forcedCl / 10), (forcedCl % 10));
  57100. + pBankInfo->suportedCasLatencies = 0x10;
  57101. + }
  57102. +
  57103. + return pBankInfo->suportedCasLatencies;
  57104. + }
  57105. +
  57106. + /* go over the supported cas mask from Max Cas down and check if the */
  57107. + /* SysClk stands in its time requirments. */
  57108. +
  57109. + DB(mvOsPrintf("Dram: minCasCalc supported mask = %x busClkPs = %x \n",
  57110. + pBankInfo->suportedCasLatencies,busClkPs ));
  57111. + count = 1;
  57112. + for(j = 7; j > 0; j--)
  57113. + {
  57114. + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
  57115. + {
  57116. + /* Reset the bits for CL incompatible for the sysClk */
  57117. + switch (count)
  57118. + {
  57119. + case 1:
  57120. + if (pBankInfo->minCycleTimeAtMaxCasLatPs > busClkPs)
  57121. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  57122. + count++;
  57123. + break;
  57124. + case 2:
  57125. + if (pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
  57126. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  57127. + count++;
  57128. + break;
  57129. + case 3:
  57130. + if (pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
  57131. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  57132. + count++;
  57133. + break;
  57134. + default:
  57135. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  57136. + break;
  57137. + }
  57138. + }
  57139. + }
  57140. +
  57141. + DB(mvOsPrintf("Dram: minCasCalc support = %x (after SysCC calc)\n",
  57142. + pBankInfo->suportedCasLatencies ));
  57143. +
  57144. + count = 1;
  57145. + DB(mvOsPrintf("Dram2: minCasCalc supported mask = %x busClkPs = %x \n",
  57146. + pBankInfo2->suportedCasLatencies,busClkPs ));
  57147. + for(j = 7; j > 0; j--)
  57148. + {
  57149. + if((pBankInfo2->suportedCasLatencies >> j) & BIT0 )
  57150. + {
  57151. + /* Reset the bits for CL incompatible for the sysClk */
  57152. + switch (count)
  57153. + {
  57154. + case 1:
  57155. + if (pBankInfo2->minCycleTimeAtMaxCasLatPs > busClkPs)
  57156. + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
  57157. + count++;
  57158. + break;
  57159. + case 2:
  57160. + if (pBankInfo2->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
  57161. + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
  57162. + count++;
  57163. + break;
  57164. + case 3:
  57165. + if (pBankInfo2->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
  57166. + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
  57167. + count++;
  57168. + break;
  57169. + default:
  57170. + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
  57171. + break;
  57172. + }
  57173. + }
  57174. + }
  57175. +
  57176. + DB(mvOsPrintf("Dram2: minCasCalc support = %x (after SysCC calc)\n",
  57177. + pBankInfo2->suportedCasLatencies ));
  57178. +
  57179. + startBit = 3; /* DDR2 support CL start with CL3 (bit 3) */
  57180. + stopBit = 6; /* DDR2 support CL stops with CL6 (bit 6) */
  57181. +
  57182. + for(j = startBit; j <= stopBit ; j++)
  57183. + {
  57184. + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
  57185. + {
  57186. + DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
  57187. + minCas0 = (BIT0 << j);
  57188. + break;
  57189. + }
  57190. + }
  57191. +
  57192. + for(j = startBit; j <= stopBit ; j++)
  57193. + {
  57194. + if((pBankInfo2->suportedCasLatencies >> j) & BIT0 )
  57195. + {
  57196. + DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
  57197. + minCas2 = (BIT0 << j);
  57198. + break;
  57199. + }
  57200. + }
  57201. +
  57202. + if (minCas2 > minCas0)
  57203. + return minCas2;
  57204. + else
  57205. + return minCas0;
  57206. +
  57207. + return 0;
  57208. +}
  57209. +
  57210. +/*******************************************************************************
  57211. +* sdramConfigRegCalc - Calculate sdram config register
  57212. +*
  57213. +* DESCRIPTION: Calculate sdram config register optimized value based
  57214. +* on the bank info parameters.
  57215. +*
  57216. +* INPUT:
  57217. +* busClk - the DRAM bus Clock.
  57218. +* pBankInfo - sdram bank parameters
  57219. +*
  57220. +* OUTPUT:
  57221. +* None
  57222. +*
  57223. +* RETURN:
  57224. +* sdram config reg value.
  57225. +*
  57226. +*******************************************************************************/
  57227. +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk)
  57228. +{
  57229. + MV_U32 sdramConfig = 0;
  57230. + MV_U32 refreshPeriod;
  57231. +
  57232. + busClk /= 1000000; /* we work with busClk in MHz */
  57233. +
  57234. + sdramConfig = MV_REG_READ(SDRAM_CONFIG_REG);
  57235. +
  57236. + /* figure out the memory refresh internal */
  57237. + switch (pBankInfo->refreshInterval & 0xf)
  57238. + {
  57239. + case 0x0: /* refresh period is 15.625 usec */
  57240. + refreshPeriod = 15625;
  57241. + break;
  57242. + case 0x1: /* refresh period is 3.9 usec */
  57243. + refreshPeriod = 3900;
  57244. + break;
  57245. + case 0x2: /* refresh period is 7.8 usec */
  57246. + refreshPeriod = 7800;
  57247. + break;
  57248. + case 0x3: /* refresh period is 31.3 usec */
  57249. + refreshPeriod = 31300;
  57250. + break;
  57251. + case 0x4: /* refresh period is 62.5 usec */
  57252. + refreshPeriod = 62500;
  57253. + break;
  57254. + case 0x5: /* refresh period is 125 usec */
  57255. + refreshPeriod = 125000;
  57256. + break;
  57257. + default: /* refresh period undefined */
  57258. + mvOsPrintf("Dram: ERR. DRAM refresh period is unknown!\n");
  57259. + return -1;
  57260. + }
  57261. +
  57262. + /* Now the refreshPeriod is in register format value */
  57263. + refreshPeriod = (busClk * refreshPeriod) / 1000;
  57264. +
  57265. + DB(mvOsPrintf("Dram: sdramConfigRegCalc calculated refresh interval %0x\n",
  57266. + refreshPeriod));
  57267. +
  57268. + /* make sure the refresh value is only 14 bits */
  57269. + if(refreshPeriod > SDRAM_REFRESH_MAX)
  57270. + {
  57271. + refreshPeriod = SDRAM_REFRESH_MAX;
  57272. + DB(mvOsPrintf("Dram: sdramConfigRegCalc adjusted refresh interval %0x\n",
  57273. + refreshPeriod));
  57274. + }
  57275. +
  57276. + /* Clear the refresh field */
  57277. + sdramConfig &= ~SDRAM_REFRESH_MASK;
  57278. +
  57279. + /* Set new value to refresh field */
  57280. + sdramConfig |= (refreshPeriod & SDRAM_REFRESH_MASK);
  57281. +
  57282. + /* registered DRAM ? */
  57283. + if ( pBankInfo->registeredAddrAndControlInputs )
  57284. + {
  57285. + /* it's registered DRAM, so set the reg. DRAM bit */
  57286. + sdramConfig |= SDRAM_REGISTERED;
  57287. + DB(mvOsPrintf("DRAM Attribute: Registered address and control inputs.\n");)
  57288. + }
  57289. +
  57290. + /* ECC and IERR support */
  57291. + sdramConfig &= ~SDRAM_ECC_MASK; /* Clear ECC field */
  57292. + sdramConfig &= ~SDRAM_IERR_MASK; /* Clear IErr field */
  57293. +
  57294. + if ( pBankInfo->errorCheckType )
  57295. + {
  57296. + sdramConfig |= SDRAM_ECC_EN;
  57297. + sdramConfig |= SDRAM_IERR_REPORTE;
  57298. + DB(mvOsPrintf("Dram: mvDramIfDetect Enabling ECC\n"));
  57299. + }
  57300. + else
  57301. + {
  57302. + sdramConfig |= SDRAM_ECC_DIS;
  57303. + sdramConfig |= SDRAM_IERR_IGNORE;
  57304. + DB(mvOsPrintf("Dram: mvDramIfDetect Disabling ECC!\n"));
  57305. + }
  57306. + /* Set static default settings */
  57307. + sdramConfig |= SDRAM_CONFIG_DV;
  57308. +
  57309. + DB(mvOsPrintf("Dram: sdramConfigRegCalc set sdramConfig to 0x%x\n",
  57310. + sdramConfig));
  57311. +
  57312. + return sdramConfig;
  57313. +}
  57314. +
  57315. +/*******************************************************************************
  57316. +* sdramModeRegCalc - Calculate sdram mode register
  57317. +*
  57318. +* DESCRIPTION: Calculate sdram mode register optimized value based
  57319. +* on the bank info parameters and the minCas.
  57320. +*
  57321. +* INPUT:
  57322. +* minCas - minimum CAS supported.
  57323. +*
  57324. +* OUTPUT:
  57325. +* None
  57326. +*
  57327. +* RETURN:
  57328. +* sdram mode reg value.
  57329. +*
  57330. +*******************************************************************************/
  57331. +static MV_U32 sdramModeRegCalc(MV_U32 minCas)
  57332. +{
  57333. + MV_U32 sdramMode;
  57334. +
  57335. + sdramMode = MV_REG_READ(SDRAM_MODE_REG);
  57336. +
  57337. + /* Clear CAS Latency field */
  57338. + sdramMode &= ~SDRAM_CL_MASK;
  57339. +
  57340. + DB(mvOsPrintf("DRAM CAS Latency ");)
  57341. +
  57342. + switch (minCas)
  57343. + {
  57344. + case DDR2_CL_3:
  57345. + sdramMode |= SDRAM_DDR2_CL_3;
  57346. + DB(mvOsPrintf("3.\n");)
  57347. + break;
  57348. + case DDR2_CL_4:
  57349. + sdramMode |= SDRAM_DDR2_CL_4;
  57350. + DB(mvOsPrintf("4.\n");)
  57351. + break;
  57352. + case DDR2_CL_5:
  57353. + sdramMode |= SDRAM_DDR2_CL_5;
  57354. + DB(mvOsPrintf("5.\n");)
  57355. + break;
  57356. + case DDR2_CL_6:
  57357. + sdramMode |= SDRAM_DDR2_CL_6;
  57358. + DB(mvOsPrintf("6.\n");)
  57359. + break;
  57360. + default:
  57361. + mvOsOutput("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
  57362. + return -1;
  57363. + }
  57364. +
  57365. + DB(mvOsPrintf("\nsdramModeRegCalc register 0x%x\n", sdramMode ));
  57366. +
  57367. + return sdramMode;
  57368. +}
  57369. +/*******************************************************************************
  57370. +* sdramExtModeRegCalc - Calculate sdram Extended mode register
  57371. +*
  57372. +* DESCRIPTION:
  57373. +* Return sdram Extended mode register value based
  57374. +* on the bank info parameters and bank presence.
  57375. +*
  57376. +* INPUT:
  57377. +* pBankInfo - sdram bank parameters
  57378. +* busClk - DRAM frequency
  57379. +*
  57380. +* OUTPUT:
  57381. +* None
  57382. +*
  57383. +* RETURN:
  57384. +* sdram Extended mode reg value.
  57385. +*
  57386. +*******************************************************************************/
  57387. +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
  57388. +{
  57389. + MV_U32 populateBanks = 0;
  57390. + int bankNum;
  57391. +
  57392. + /* Represent the populate banks in binary form */
  57393. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  57394. + {
  57395. + if (0 != pBankInfo[bankNum].size)
  57396. + {
  57397. + populateBanks |= (1 << bankNum);
  57398. + }
  57399. + }
  57400. +
  57401. + switch(populateBanks)
  57402. + {
  57403. + case(BANK_PRESENT_CS0):
  57404. + case(BANK_PRESENT_CS0_CS1):
  57405. + return DDR_SDRAM_EXT_MODE_CS0_CS1_DV;
  57406. +
  57407. + case(BANK_PRESENT_CS0_CS2):
  57408. + case(BANK_PRESENT_CS0_CS1_CS2):
  57409. + case(BANK_PRESENT_CS0_CS2_CS3):
  57410. + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
  57411. + if (busClk >= MV_BOARD_SYSCLK_267MHZ)
  57412. + return DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV;
  57413. + else
  57414. + return DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV;
  57415. +
  57416. + default:
  57417. + mvOsOutput("sdramExtModeRegCalc: Invalid DRAM bank presence\n");
  57418. + return -1;
  57419. + }
  57420. + return 0;
  57421. +}
  57422. +
  57423. +/*******************************************************************************
  57424. +* dunitCtrlLowRegCalc - Calculate sdram dunit control low register
  57425. +*
  57426. +* DESCRIPTION: Calculate sdram dunit control low register optimized value based
  57427. +* on the bank info parameters and the minCas.
  57428. +*
  57429. +* INPUT:
  57430. +* pBankInfo - sdram bank parameters
  57431. +* minCas - minimum CAS supported.
  57432. +*
  57433. +* OUTPUT:
  57434. +* None
  57435. +*
  57436. +* RETURN:
  57437. +* sdram dunit control low reg value.
  57438. +*
  57439. +*******************************************************************************/
  57440. +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk, MV_STATUS TTMode)
  57441. +{
  57442. + MV_U32 dunitCtrlLow, cl;
  57443. + MV_U32 sbOutR[4]={3,5,7,9} ;
  57444. + MV_U32 sbOutU[4]={1,3,5,7} ;
  57445. +
  57446. + dunitCtrlLow = MV_REG_READ(SDRAM_DUNIT_CTRL_REG);
  57447. +
  57448. + DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc\n"));
  57449. +
  57450. + /* Clear StBurstOutDel field */
  57451. + dunitCtrlLow &= ~SDRAM_SB_OUT_MASK;
  57452. +
  57453. + /* Clear StBurstInDel field */
  57454. + dunitCtrlLow &= ~SDRAM_SB_IN_MASK;
  57455. +
  57456. + /* Clear CtrlPos field */
  57457. + dunitCtrlLow &= ~SDRAM_CTRL_POS_MASK;
  57458. +
  57459. + /* Clear 2T field */
  57460. + dunitCtrlLow &= ~SDRAM_2T_MASK;
  57461. + if (TTMode == MV_TRUE)
  57462. + {
  57463. + dunitCtrlLow |= SDRAM_2T_MODE;
  57464. + }
  57465. +
  57466. + /* For proper sample of read data set the Dunit Control register's */
  57467. + /* stBurstInDel bits [27:24] */
  57468. + /* 200MHz - 267MHz None reg = CL + 1 */
  57469. + /* 200MHz - 267MHz reg = CL + 2 */
  57470. + /* > 267MHz None reg = CL + 2 */
  57471. + /* > 267MHz reg = CL + 3 */
  57472. +
  57473. + /* For proper sample of read data set the Dunit Control register's */
  57474. + /* stBurstOutDel bits [23:20] */
  57475. + /********-********-********-********-
  57476. + * CL=3 | CL=4 | CL=5 | CL=6 |
  57477. + *********-********-********-********-
  57478. + Not Reg. * 0001 | 0011 | 0101 | 0111 |
  57479. + *********-********-********-********-
  57480. + Registered * 0011 | 0101 | 0111 | 1001 |
  57481. + *********-********-********-********/
  57482. +
  57483. + /* Set Dunit Control low default value */
  57484. + dunitCtrlLow |= SDRAM_DUNIT_CTRL_LOW_DDR2_DV;
  57485. +
  57486. + switch (minCas)
  57487. + {
  57488. + case DDR2_CL_3: cl = 3; break;
  57489. + case DDR2_CL_4: cl = 4; break;
  57490. + case DDR2_CL_5: cl = 5; break;
  57491. + case DDR2_CL_6: cl = 6; break;
  57492. + default:
  57493. + mvOsOutput("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n", minCas);
  57494. + return -1;
  57495. + }
  57496. +
  57497. + /* registerd DDR SDRAM? */
  57498. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  57499. + {
  57500. + dunitCtrlLow |= (sbOutR[cl-3]) << SDRAM_SB_OUT_DEL_OFFS;
  57501. + }
  57502. + else
  57503. + {
  57504. + dunitCtrlLow |= (sbOutU[cl-3]) << SDRAM_SB_OUT_DEL_OFFS;
  57505. + }
  57506. +
  57507. + DB(mvOsPrintf("\n\ndunitCtrlLowRegCalc: CL = %d, frequencies=%d\n", cl, busClk));
  57508. +
  57509. + if (busClk <= MV_BOARD_SYSCLK_267MHZ)
  57510. + {
  57511. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  57512. + cl = cl + 2;
  57513. + else
  57514. + cl = cl + 1;
  57515. + }
  57516. + else
  57517. + {
  57518. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  57519. + cl = cl + 3;
  57520. + else
  57521. + cl = cl + 2;
  57522. + }
  57523. +
  57524. + DB(mvOsPrintf("dunitCtrlLowRegCalc: SDRAM_SB_IN_DEL_OFFS = %d \n", cl));
  57525. + dunitCtrlLow |= cl << SDRAM_SB_IN_DEL_OFFS;
  57526. +
  57527. + DB(mvOsPrintf("Dram: Reg dunit control low = %x\n", dunitCtrlLow ));
  57528. +
  57529. + return dunitCtrlLow;
  57530. +}
  57531. +
  57532. +/*******************************************************************************
  57533. +* dunitCtrlHighRegCalc - Calculate sdram dunit control high register
  57534. +*
  57535. +* DESCRIPTION: Calculate sdram dunit control high register optimized value based
  57536. +* on the bus clock.
  57537. +*
  57538. +* INPUT:
  57539. +* busClk - DRAM frequency.
  57540. +*
  57541. +* OUTPUT:
  57542. +* None
  57543. +*
  57544. +* RETURN:
  57545. +* sdram dunit control high reg value.
  57546. +*
  57547. +*******************************************************************************/
  57548. +static MV_U32 dunitCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
  57549. +{
  57550. + MV_U32 dunitCtrlHigh;
  57551. + dunitCtrlHigh = MV_REG_READ(SDRAM_DUNIT_CTRL_HI_REG);
  57552. + if(busClk > MV_BOARD_SYSCLK_300MHZ)
  57553. + dunitCtrlHigh |= SDRAM__P2D_EN;
  57554. + else
  57555. + dunitCtrlHigh &= ~SDRAM__P2D_EN;
  57556. +
  57557. + if(busClk > MV_BOARD_SYSCLK_267MHZ)
  57558. + dunitCtrlHigh |= (SDRAM__WR_MESH_DELAY_EN | SDRAM__PUP_ZERO_SKEW_EN | SDRAM__ADD_HALF_FCC_EN);
  57559. +
  57560. + /* If ECC support we turn on D2P sample */
  57561. + dunitCtrlHigh &= ~SDRAM__D2P_EN; /* Clear D2P bit */
  57562. + if (( pBankInfo->errorCheckType ) && (busClk > MV_BOARD_SYSCLK_267MHZ))
  57563. + dunitCtrlHigh |= SDRAM__D2P_EN;
  57564. +
  57565. + return dunitCtrlHigh;
  57566. +}
  57567. +
  57568. +/*******************************************************************************
  57569. +* sdramAddrCtrlRegCalc - Calculate sdram address control register
  57570. +*
  57571. +* DESCRIPTION: Calculate sdram address control register optimized value based
  57572. +* on the bank info parameters and the minCas.
  57573. +*
  57574. +* INPUT:
  57575. +* pBankInfo - sdram bank parameters
  57576. +*
  57577. +* OUTPUT:
  57578. +* None
  57579. +*
  57580. +* RETURN:
  57581. +* sdram address control reg value.
  57582. +*
  57583. +*******************************************************************************/
  57584. +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfoDIMM1)
  57585. +{
  57586. + MV_U32 addrCtrl = 0;
  57587. +
  57588. + if (pBankInfoDIMM1->size)
  57589. + {
  57590. + switch (pBankInfoDIMM1->sdramWidth)
  57591. + {
  57592. + case 4: /* memory is x4 */
  57593. + mvOsOutput("sdramAddrCtrlRegCalc: Error - x4 not supported!\n");
  57594. + return -1;
  57595. + break;
  57596. + case 8: /* memory is x8 */
  57597. + addrCtrl |= SDRAM_ADDRSEL_X8(2) | SDRAM_ADDRSEL_X8(3);
  57598. + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device DIMM2 width x8\n"));
  57599. + break;
  57600. + case 16:
  57601. + addrCtrl |= SDRAM_ADDRSEL_X16(2) | SDRAM_ADDRSEL_X16(3);
  57602. + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device DIMM2 width x16\n"));
  57603. + break;
  57604. + default: /* memory width unsupported */
  57605. + mvOsOutput("sdramAddrCtrlRegCalc: ERR. DRAM chip width is unknown!\n");
  57606. + return -1;
  57607. + }
  57608. + }
  57609. +
  57610. + switch (pBankInfo->sdramWidth)
  57611. + {
  57612. + case 4: /* memory is x4 */
  57613. + mvOsOutput("sdramAddrCtrlRegCalc: Error - x4 not supported!\n");
  57614. + return -1;
  57615. + break;
  57616. + case 8: /* memory is x8 */
  57617. + addrCtrl |= SDRAM_ADDRSEL_X8(0) | SDRAM_ADDRSEL_X8(1);
  57618. + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device width x8\n"));
  57619. + break;
  57620. + case 16:
  57621. + addrCtrl |= SDRAM_ADDRSEL_X16(0) | SDRAM_ADDRSEL_X16(1);
  57622. + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device width x16\n"));
  57623. + break;
  57624. + default: /* memory width unsupported */
  57625. + mvOsOutput("sdramAddrCtrlRegCalc: ERR. DRAM chip width is unknown!\n");
  57626. + return -1;
  57627. + }
  57628. +
  57629. + /* Note that density is in MB units */
  57630. + switch (pBankInfo->deviceDensity)
  57631. + {
  57632. + case 256: /* 256 Mbit */
  57633. + DB(mvOsPrintf("DRAM Device Density 256Mbit\n"));
  57634. + addrCtrl |= SDRAM_DSIZE_256Mb(0) | SDRAM_DSIZE_256Mb(1);
  57635. + break;
  57636. + case 512: /* 512 Mbit */
  57637. + DB(mvOsPrintf("DRAM Device Density 512Mbit\n"));
  57638. + addrCtrl |= SDRAM_DSIZE_512Mb(0) | SDRAM_DSIZE_512Mb(1);
  57639. + break;
  57640. + case 1024: /* 1 Gbit */
  57641. + DB(mvOsPrintf("DRAM Device Density 1Gbit\n"));
  57642. + addrCtrl |= SDRAM_DSIZE_1Gb(0) | SDRAM_DSIZE_1Gb(1);
  57643. + break;
  57644. + case 2048: /* 2 Gbit */
  57645. + DB(mvOsPrintf("DRAM Device Density 2Gbit\n"));
  57646. + addrCtrl |= SDRAM_DSIZE_2Gb(0) | SDRAM_DSIZE_2Gb(1);
  57647. + break;
  57648. + default:
  57649. + mvOsOutput("Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
  57650. + pBankInfo->deviceDensity);
  57651. + return -1;
  57652. + }
  57653. +
  57654. + if (pBankInfoDIMM1->size)
  57655. + {
  57656. + switch (pBankInfoDIMM1->deviceDensity)
  57657. + {
  57658. + case 256: /* 256 Mbit */
  57659. + DB(mvOsPrintf("DIMM2: DRAM Device Density 256Mbit\n"));
  57660. + addrCtrl |= SDRAM_DSIZE_256Mb(2) | SDRAM_DSIZE_256Mb(3);
  57661. + break;
  57662. + case 512: /* 512 Mbit */
  57663. + DB(mvOsPrintf("DIMM2: DRAM Device Density 512Mbit\n"));
  57664. + addrCtrl |= SDRAM_DSIZE_512Mb(2) | SDRAM_DSIZE_512Mb(3);
  57665. + break;
  57666. + case 1024: /* 1 Gbit */
  57667. + DB(mvOsPrintf("DIMM2: DRAM Device Density 1Gbit\n"));
  57668. + addrCtrl |= SDRAM_DSIZE_1Gb(2) | SDRAM_DSIZE_1Gb(3);
  57669. + break;
  57670. + case 2048: /* 2 Gbit */
  57671. + DB(mvOsPrintf("DIMM2: DRAM Device Density 2Gbit\n"));
  57672. + addrCtrl |= SDRAM_DSIZE_2Gb(2) | SDRAM_DSIZE_2Gb(3);
  57673. + break;
  57674. + default:
  57675. + mvOsOutput("DIMM2: Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
  57676. + pBankInfoDIMM1->deviceDensity);
  57677. + return -1;
  57678. + }
  57679. + }
  57680. + /* SDRAM address control */
  57681. + DB(mvOsPrintf("Dram: setting sdram address control with: %x \n", addrCtrl));
  57682. +
  57683. + return addrCtrl;
  57684. +}
  57685. +
  57686. +/*******************************************************************************
  57687. +* sdramTimeCtrlLowRegCalc - Calculate sdram timing control low register
  57688. +*
  57689. +* DESCRIPTION:
  57690. +* This function calculates sdram timing control low register
  57691. +* optimized value based on the bank info parameters and the minCas.
  57692. +*
  57693. +* INPUT:
  57694. +* pBankInfo - sdram bank parameters
  57695. +* minCas - minimum CAS supported.
  57696. +* busClk - Bus clock
  57697. +*
  57698. +* OUTPUT:
  57699. +* None
  57700. +*
  57701. +* RETURN:
  57702. +* sdram timing control low reg value.
  57703. +*
  57704. +*******************************************************************************/
  57705. +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk)
  57706. +{
  57707. + MV_U32 tRp = 0;
  57708. + MV_U32 tRrd = 0;
  57709. + MV_U32 tRcd = 0;
  57710. + MV_U32 tRas = 0;
  57711. + MV_U32 tWr = 0;
  57712. + MV_U32 tWtr = 0;
  57713. + MV_U32 tRtp = 0;
  57714. + MV_U32 timeCtrlLow = 0;
  57715. +
  57716. + MV_U32 bankNum;
  57717. +
  57718. + busClk = busClk / 1000000; /* In MHz */
  57719. +
  57720. + /* Scan all DRAM banks to find maximum timing values */
  57721. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  57722. + {
  57723. + tRp = MV_MAX(tRp, pBankInfo[bankNum].minRowPrechargeTime);
  57724. + tRrd = MV_MAX(tRrd, pBankInfo[bankNum].minRowActiveToRowActive);
  57725. + tRcd = MV_MAX(tRcd, pBankInfo[bankNum].minRasToCasDelay);
  57726. + tRas = MV_MAX(tRas, pBankInfo[bankNum].minRasPulseWidth);
  57727. + }
  57728. +
  57729. + /* Extract timing (in ns) from SPD value. We ignore the tenth ns part. */
  57730. + /* by shifting the data two bits right. */
  57731. + tRp = tRp >> 2; /* For example 0x50 -> 20ns */
  57732. + tRrd = tRrd >> 2;
  57733. + tRcd = tRcd >> 2;
  57734. +
  57735. + /* Extract clock cycles from time parameter. We need to round up */
  57736. + tRp = ((busClk * tRp) / 1000) + (((busClk * tRp) % 1000) ? 1 : 0);
  57737. + DB(mvOsPrintf("Dram Timing Low: tRp = %d ", tRp));
  57738. + tRrd = ((busClk * tRrd) / 1000) + (((busClk * tRrd) % 1000) ? 1 : 0);
  57739. + /* JEDEC min reqeirments tRrd = 2 */
  57740. + if (tRrd < 2)
  57741. + tRrd = 2;
  57742. + DB(mvOsPrintf("tRrd = %d ", tRrd));
  57743. + tRcd = ((busClk * tRcd) / 1000) + (((busClk * tRcd) % 1000) ? 1 : 0);
  57744. + DB(mvOsPrintf("tRcd = %d ", tRcd));
  57745. + tRas = ((busClk * tRas) / 1000) + (((busClk * tRas) % 1000) ? 1 : 0);
  57746. + DB(mvOsPrintf("tRas = %d ", tRas));
  57747. +
  57748. + /* tWr and tWtr is different for DDR1 and DDR2. tRtp is only for DDR2 */
  57749. + /* Scan all DRAM banks to find maximum timing values */
  57750. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  57751. + {
  57752. + tWr = MV_MAX(tWr, pBankInfo[bankNum].minWriteRecoveryTime);
  57753. + tWtr = MV_MAX(tWtr, pBankInfo[bankNum].minWriteToReadCmdDelay);
  57754. + tRtp = MV_MAX(tRtp, pBankInfo[bankNum].minReadToPrechCmdDelay);
  57755. + }
  57756. +
  57757. + /* Extract timing (in ns) from SPD value. We ignore the tenth ns */
  57758. + /* part by shifting the data two bits right. */
  57759. + tWr = tWr >> 2; /* For example 0x50 -> 20ns */
  57760. + tWtr = tWtr >> 2;
  57761. + tRtp = tRtp >> 2;
  57762. + /* Extract clock cycles from time parameter. We need to round up */
  57763. + tWr = ((busClk * tWr) / 1000) + (((busClk * tWr) % 1000) ? 1 : 0);
  57764. + DB(mvOsPrintf("tWr = %d ", tWr));
  57765. + tWtr = ((busClk * tWtr) / 1000) + (((busClk * tWtr) % 1000) ? 1 : 0);
  57766. + /* JEDEC min reqeirments tWtr = 2 */
  57767. + if (tWtr < 2)
  57768. + tWtr = 2;
  57769. + DB(mvOsPrintf("tWtr = %d ", tWtr));
  57770. + tRtp = ((busClk * tRtp) / 1000) + (((busClk * tRtp) % 1000) ? 1 : 0);
  57771. + /* JEDEC min reqeirments tRtp = 2 */
  57772. + if (tRtp < 2)
  57773. + tRtp = 2;
  57774. + DB(mvOsPrintf("tRtp = %d ", tRtp));
  57775. +
  57776. + /* Note: value of 0 in register means one cycle, 1 means two and so on */
  57777. + timeCtrlLow = (((tRp - 1) << SDRAM_TRP_OFFS) |
  57778. + ((tRrd - 1) << SDRAM_TRRD_OFFS) |
  57779. + ((tRcd - 1) << SDRAM_TRCD_OFFS) |
  57780. + (((tRas - 1) << SDRAM_TRAS_OFFS) & SDRAM_TRAS_MASK)|
  57781. + ((tWr - 1) << SDRAM_TWR_OFFS) |
  57782. + ((tWtr - 1) << SDRAM_TWTR_OFFS) |
  57783. + ((tRtp - 1) << SDRAM_TRTP_OFFS));
  57784. +
  57785. + /* Check extended tRas bit */
  57786. + if ((tRas - 1) & BIT4)
  57787. + timeCtrlLow |= (1 << SDRAM_EXT_TRAS_OFFS);
  57788. +
  57789. + return timeCtrlLow;
  57790. +}
  57791. +
  57792. +/*******************************************************************************
  57793. +* sdramTimeCtrlHighRegCalc - Calculate sdram timing control high register
  57794. +*
  57795. +* DESCRIPTION:
  57796. +* This function calculates sdram timing control high register
  57797. +* optimized value based on the bank info parameters and the bus clock.
  57798. +*
  57799. +* INPUT:
  57800. +* pBankInfo - sdram bank parameters
  57801. +* busClk - Bus clock
  57802. +*
  57803. +* OUTPUT:
  57804. +* None
  57805. +*
  57806. +* RETURN:
  57807. +* sdram timing control high reg value.
  57808. +*
  57809. +*******************************************************************************/
  57810. +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
  57811. +{
  57812. + MV_U32 tRfc;
  57813. + MV_U32 timingHigh;
  57814. + MV_U32 timeNs = 0;
  57815. + MV_U32 bankNum;
  57816. +
  57817. + busClk = busClk / 1000000; /* In MHz */
  57818. +
  57819. + /* Set DDR timing high register static configuration bits */
  57820. + timingHigh = MV_REG_READ(SDRAM_TIMING_CTRL_HIGH_REG);
  57821. +
  57822. + /* Set DDR timing high register default value */
  57823. + timingHigh |= SDRAM_TIMING_CTRL_HIGH_REG_DV;
  57824. +
  57825. + /* Clear tRfc field */
  57826. + timingHigh &= ~SDRAM_TRFC_MASK;
  57827. +
  57828. + /* Scan all DRAM banks to find maximum timing values */
  57829. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  57830. + {
  57831. + timeNs = MV_MAX(timeNs, pBankInfo[bankNum].minRefreshToActiveCmd);
  57832. + DB(mvOsPrintf("Dram: Timing High: minRefreshToActiveCmd = %d\n",
  57833. + pBankInfo[bankNum].minRefreshToActiveCmd));
  57834. + }
  57835. + if(busClk >= 333 && mvCtrlModelGet() == MV_78XX0_A1_REV)
  57836. + {
  57837. + timingHigh |= 0x1 << SDRAM_TR2W_W2R_OFFS;
  57838. + }
  57839. +
  57840. + tRfc = ((busClk * timeNs) / 1000) + (((busClk * timeNs) % 1000) ? 1 : 0);
  57841. + /* Note: value of 0 in register means one cycle, 1 means two and so on */
  57842. + DB(mvOsPrintf("Dram: Timing High: tRfc = %d\n", tRfc));
  57843. + timingHigh |= (((tRfc - 1) & SDRAM_TRFC_MASK) << SDRAM_TRFC_OFFS);
  57844. + DB(mvOsPrintf("Dram: Timing High: tRfc = %d\n", tRfc));
  57845. +
  57846. + /* SDRAM timing high */
  57847. + DB(mvOsPrintf("Dram: setting timing high with: %x \n", timingHigh));
  57848. +
  57849. + return timingHigh;
  57850. +}
  57851. +/*******************************************************************************
  57852. +* sdramDDr2OdtConfig - Set DRAM DDR2 On Die Termination registers.
  57853. +*
  57854. +* DESCRIPTION:
  57855. +* This function config DDR2 On Die Termination (ODT) registers.
  57856. +*
  57857. +* INPUT:
  57858. +* pBankInfo - bank info parameters.
  57859. +*
  57860. +* OUTPUT:
  57861. +* None
  57862. +*
  57863. +* RETURN:
  57864. +* None
  57865. +*******************************************************************************/
  57866. +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo)
  57867. +{
  57868. + MV_U32 populateBanks = 0;
  57869. + MV_U32 odtCtrlLow, odtCtrlHigh, dunitOdtCtrl;
  57870. + int bankNum;
  57871. +
  57872. + /* Represent the populate banks in binary form */
  57873. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  57874. + {
  57875. + if (0 != pBankInfo[bankNum].size)
  57876. + {
  57877. + populateBanks |= (1 << bankNum);
  57878. + }
  57879. + }
  57880. +
  57881. + switch(populateBanks)
  57882. + {
  57883. + case(BANK_PRESENT_CS0):
  57884. + case(BANK_PRESENT_CS0_CS1):
  57885. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS1_DV;
  57886. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS1_DV;
  57887. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS1_DV;
  57888. + break;
  57889. + case(BANK_PRESENT_CS0_CS2):
  57890. + case(BANK_PRESENT_CS0_CS1_CS2):
  57891. + case(BANK_PRESENT_CS0_CS2_CS3):
  57892. + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
  57893. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS1_CS2_CS3_DV;
  57894. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS1_CS2_CS3_DV;
  57895. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS1_CS2_CS3_DV;
  57896. + break;
  57897. + default:
  57898. + DB(mvOsPrintf("sdramDDr2OdtConfig: Invalid DRAM bank presence\n"));
  57899. + return;
  57900. + }
  57901. + /* DDR2 SDRAM ODT ctrl low */
  57902. + DB(mvOsPrintf("Dram: DDR2 setting ODT ctrl low with: %x \n", odtCtrlLow));
  57903. + MV_REG_WRITE(DRAM_BUF_REG7, odtCtrlLow);
  57904. +
  57905. + /* DDR2 SDRAM ODT ctrl high */
  57906. + DB(mvOsPrintf("Dram: DDR2 setting ODT ctrl high with: %x \n", odtCtrlHigh));
  57907. + MV_REG_WRITE(DRAM_BUF_REG8, odtCtrlHigh);
  57908. +
  57909. + /* DDR2 DUNIT ODT ctrl */
  57910. + if ( ((mvCtrlModelGet() == MV_78XX0_DEV_ID) && (mvCtrlRevGet() == MV_78XX0_Y0_REV)) ||
  57911. + (mvCtrlModelGet() == MV_76100_DEV_ID) ||
  57912. + (mvCtrlModelGet() == MV_78100_DEV_ID) ||
  57913. + (mvCtrlModelGet() == MV_78200_DEV_ID) )
  57914. + dunitOdtCtrl &= ~(BIT9|BIT8); /* Clear ODT always on */
  57915. +
  57916. + DB(mvOsPrintf("DUNIT: DDR2 setting ODT ctrl with: %x \n", dunitOdtCtrl));
  57917. + MV_REG_WRITE(DRAM_BUF_REG9, dunitOdtCtrl);
  57918. + return;
  57919. +}
  57920. +/*******************************************************************************
  57921. +* sdramDdr2TimeLoRegCalc - Set DDR2 DRAM Timing Low registers.
  57922. +*
  57923. +* DESCRIPTION:
  57924. +* This function config DDR2 DRAM Timing low registers.
  57925. +*
  57926. +* INPUT:
  57927. +* minCas - minimum CAS supported.
  57928. +*
  57929. +* OUTPUT:
  57930. +* None
  57931. +*
  57932. +* RETURN:
  57933. +* DDR2 sdram timing low reg value.
  57934. +*******************************************************************************/
  57935. +static MV_U32 sdramDdr2TimeLoRegCalc(MV_U32 minCas)
  57936. +{
  57937. + MV_U8 cl = -1;
  57938. + MV_U32 ddr2TimeLoReg;
  57939. +
  57940. + /* read and clear the feilds we are going to set */
  57941. + ddr2TimeLoReg = MV_REG_READ(SDRAM_DDR2_TIMING_LO_REG);
  57942. + ddr2TimeLoReg &= ~(SD2TLR_TODT_ON_RD_MASK |
  57943. + SD2TLR_TODT_OFF_RD_MASK |
  57944. + SD2TLR_TODT_ON_CTRL_RD_MASK |
  57945. + SD2TLR_TODT_OFF_CTRL_RD_MASK);
  57946. +
  57947. + if( minCas == DDR2_CL_3 )
  57948. + {
  57949. + cl = 3;
  57950. + }
  57951. + else if( minCas == DDR2_CL_4 )
  57952. + {
  57953. + cl = 4;
  57954. + }
  57955. + else if( minCas == DDR2_CL_5 )
  57956. + {
  57957. + cl = 5;
  57958. + }
  57959. + else if( minCas == DDR2_CL_6 )
  57960. + {
  57961. + cl = 6;
  57962. + }
  57963. + else
  57964. + {
  57965. + DB(mvOsPrintf("sdramDdr2TimeLoRegCalc: CAS latency %d unsupported. using CAS latency 4\n",
  57966. + minCas));
  57967. + cl = 4;
  57968. + }
  57969. +
  57970. + ddr2TimeLoReg |= ((cl-3) << SD2TLR_TODT_ON_RD_OFFS);
  57971. + ddr2TimeLoReg |= ( cl << SD2TLR_TODT_OFF_RD_OFFS);
  57972. + ddr2TimeLoReg |= ( cl << SD2TLR_TODT_ON_CTRL_RD_OFFS);
  57973. + ddr2TimeLoReg |= ((cl+3) << SD2TLR_TODT_OFF_CTRL_RD_OFFS);
  57974. +
  57975. + /* DDR2 SDRAM timing low */
  57976. + DB(mvOsPrintf("Dram: DDR2 setting timing low with: %x \n", ddr2TimeLoReg));
  57977. +
  57978. + return ddr2TimeLoReg;
  57979. +}
  57980. +
  57981. +/*******************************************************************************
  57982. +* sdramDdr2TimeHiRegCalc - Set DDR2 DRAM Timing High registers.
  57983. +*
  57984. +* DESCRIPTION:
  57985. +* This function config DDR2 DRAM Timing high registers.
  57986. +*
  57987. +* INPUT:
  57988. +* minCas - minimum CAS supported.
  57989. +*
  57990. +* OUTPUT:
  57991. +* None
  57992. +*
  57993. +* RETURN:
  57994. +* DDR2 sdram timing high reg value.
  57995. +*******************************************************************************/
  57996. +static MV_U32 sdramDdr2TimeHiRegCalc(MV_U32 minCas)
  57997. +{
  57998. + MV_U8 cl = -1;
  57999. + MV_U32 ddr2TimeHiReg;
  58000. +
  58001. + /* read and clear the feilds we are going to set */
  58002. + ddr2TimeHiReg = MV_REG_READ(SDRAM_DDR2_TIMING_HI_REG);
  58003. + ddr2TimeHiReg &= ~(SD2THR_TODT_ON_WR_MASK |
  58004. + SD2THR_TODT_OFF_WR_MASK |
  58005. + SD2THR_TODT_ON_CTRL_WR_MASK |
  58006. + SD2THR_TODT_OFF_CTRL_WR_MASK);
  58007. +
  58008. + if( minCas == DDR2_CL_3 )
  58009. + {
  58010. + cl = 3;
  58011. + }
  58012. + else if( minCas == DDR2_CL_4 )
  58013. + {
  58014. + cl = 4;
  58015. + }
  58016. + else if( minCas == DDR2_CL_5 )
  58017. + {
  58018. + cl = 5;
  58019. + }
  58020. + else if( minCas == DDR2_CL_6 )
  58021. + {
  58022. + cl = 6;
  58023. + }
  58024. + else
  58025. + {
  58026. + mvOsOutput("sdramDdr2TimeHiRegCalc: CAS latency %d unsupported. using CAS latency 4\n",
  58027. + minCas);
  58028. + cl = 4;
  58029. + }
  58030. +
  58031. + ddr2TimeHiReg |= ((cl-3) << SD2THR_TODT_ON_WR_OFFS);
  58032. + ddr2TimeHiReg |= ( cl << SD2THR_TODT_OFF_WR_OFFS);
  58033. + ddr2TimeHiReg |= ( cl << SD2THR_TODT_ON_CTRL_WR_OFFS);
  58034. + ddr2TimeHiReg |= ((cl+3) << SD2THR_TODT_OFF_CTRL_WR_OFFS);
  58035. +
  58036. + /* DDR2 SDRAM timin high */
  58037. + DB(mvOsPrintf("Dram: DDR2 setting timing high with: %x \n", ddr2TimeHiReg));
  58038. +
  58039. + return ddr2TimeHiReg;
  58040. +}
  58041. +#endif
  58042. +
  58043. +/*******************************************************************************
  58044. +* mvDramIfCalGet - Get CAS Latency
  58045. +*
  58046. +* DESCRIPTION:
  58047. +* This function get the CAS Latency.
  58048. +*
  58049. +* INPUT:
  58050. +* None
  58051. +*
  58052. +* OUTPUT:
  58053. +* None
  58054. +*
  58055. +* RETURN:
  58056. +* CAS latency times 10 (to avoid using floating point).
  58057. +*
  58058. +*******************************************************************************/
  58059. +MV_U32 mvDramIfCalGet(void)
  58060. +{
  58061. + MV_U32 sdramCasLat, casLatMask;
  58062. +
  58063. + casLatMask = (MV_REG_READ(SDRAM_MODE_REG) & SDRAM_CL_MASK);
  58064. +
  58065. + switch (casLatMask)
  58066. + {
  58067. + case SDRAM_DDR2_CL_3:
  58068. + sdramCasLat = 30;
  58069. + break;
  58070. + case SDRAM_DDR2_CL_4:
  58071. + sdramCasLat = 40;
  58072. + break;
  58073. + case SDRAM_DDR2_CL_5:
  58074. + sdramCasLat = 50;
  58075. + break;
  58076. + case SDRAM_DDR2_CL_6:
  58077. + sdramCasLat = 60;
  58078. + break;
  58079. + default:
  58080. + mvOsOutput("mvDramIfCalGet: Err, unknown DDR2 CAL\n");
  58081. + return -1;
  58082. + }
  58083. +
  58084. + return sdramCasLat;
  58085. +}
  58086. +
  58087. +
  58088. +/*******************************************************************************
  58089. +* mvDramIfSelfRefreshSet - Put the dram in self refresh mode -
  58090. +*
  58091. +* DESCRIPTION:
  58092. +* add support in power management.
  58093. +*
  58094. +*
  58095. +* INPUT:
  58096. +* None
  58097. +*
  58098. +* OUTPUT:
  58099. +* None
  58100. +*
  58101. +* RETURN:
  58102. +* None
  58103. +*
  58104. +*******************************************************************************/
  58105. +
  58106. +MV_VOID mvDramIfSelfRefreshSet()
  58107. +{
  58108. + MV_U32 operReg;
  58109. +
  58110. + operReg = MV_REG_READ(SDRAM_OPERATION_REG);
  58111. + MV_REG_WRITE(SDRAM_OPERATION_REG ,operReg |SDRAM_CMD_SLF_RFRSH);
  58112. + /* Read until register is reset to 0 */
  58113. + while(MV_REG_READ(SDRAM_OPERATION_REG));
  58114. +}
  58115. +/*******************************************************************************
  58116. +* mvDramIfDimGetSPDversion - return DIMM SPD version.
  58117. +*
  58118. +* DESCRIPTION:
  58119. +* This function prints the DRAM controller information.
  58120. +*
  58121. +* INPUT:
  58122. +* None.
  58123. +*
  58124. +* OUTPUT:
  58125. +* None.
  58126. +*
  58127. +* RETURN:
  58128. +* None.
  58129. +*
  58130. +*******************************************************************************/
  58131. +static void mvDramIfDimGetSPDversion(MV_U32 *pMajor, MV_U32 *pMinor, MV_U32 bankNum)
  58132. +{
  58133. + MV_DIMM_INFO dimmInfo;
  58134. + if (bankNum >= MV_DRAM_MAX_CS )
  58135. + {
  58136. + DB(mvOsPrintf("Dram: mvDramIfDimGetSPDversion bad params \n"));
  58137. + return ;
  58138. + }
  58139. + memset(&dimmInfo,0,sizeof(dimmInfo));
  58140. + if ( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
  58141. + {
  58142. + DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
  58143. + return ;
  58144. + }
  58145. + *pMajor = dimmInfo.spdRawData[DIMM_SPD_VERSION]/10;
  58146. + *pMinor = dimmInfo.spdRawData[DIMM_SPD_VERSION]%10;
  58147. +}
  58148. +/*******************************************************************************
  58149. +* mvDramIfShow - Show DRAM controller information.
  58150. +*
  58151. +* DESCRIPTION:
  58152. +* This function prints the DRAM controller information.
  58153. +*
  58154. +* INPUT:
  58155. +* None.
  58156. +*
  58157. +* OUTPUT:
  58158. +* None.
  58159. +*
  58160. +* RETURN:
  58161. +* None.
  58162. +*
  58163. +*******************************************************************************/
  58164. +void mvDramIfShow(void)
  58165. +{
  58166. + int i, sdramCasLat, sdramCsSize;
  58167. + MV_U32 Major=0, Minor=0;
  58168. +
  58169. + mvOsOutput("DRAM Controller info:\n");
  58170. +
  58171. + mvOsOutput("Total DRAM ");
  58172. + mvSizePrint(mvDramIfSizeGet());
  58173. + mvOsOutput("\n");
  58174. +
  58175. + for(i = 0; i < MV_DRAM_MAX_CS; i++)
  58176. + {
  58177. + sdramCsSize = mvDramIfBankSizeGet(i);
  58178. + if (sdramCsSize)
  58179. + {
  58180. + if (0 == (i & 1))
  58181. + {
  58182. + mvDramIfDimGetSPDversion(&Major, &Minor,i);
  58183. + mvOsOutput("DIMM %d version %d.%d\n", i/2, Major, Minor);
  58184. + }
  58185. + mvOsOutput("\tDRAM CS[%d] ", i);
  58186. + mvSizePrint(sdramCsSize);
  58187. + mvOsOutput("\n");
  58188. + }
  58189. + }
  58190. + sdramCasLat = mvDramIfCalGet();
  58191. +
  58192. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_ECC_EN)
  58193. + {
  58194. + mvOsOutput("ECC enabled, ");
  58195. + }
  58196. + else
  58197. + {
  58198. + mvOsOutput("ECC Disabled, ");
  58199. + }
  58200. +
  58201. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_REGISTERED)
  58202. + {
  58203. + mvOsOutput("Registered DIMM\n");
  58204. + }
  58205. + else
  58206. + {
  58207. + mvOsOutput("Non registered DIMM\n");
  58208. + }
  58209. +
  58210. + mvOsOutput("Configured CAS Latency %d.%d\n", sdramCasLat/10, sdramCasLat%10);
  58211. +}
  58212. +/*******************************************************************************
  58213. +* mvDramIfGetFirstCS - find the DRAM bank on the lower address
  58214. +*
  58215. +*
  58216. +* DESCRIPTION:
  58217. +* This function return the fisrt CS on address 0
  58218. +*
  58219. +* INPUT:
  58220. +* None.
  58221. +*
  58222. +* OUTPUT:
  58223. +* None.
  58224. +*
  58225. +* RETURN:
  58226. +* SDRAM_CS0 or SDRAM_CS2
  58227. +*
  58228. +*******************************************************************************/
  58229. +MV_U32 mvDramIfGetFirstCS(void)
  58230. +{
  58231. + MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
  58232. +
  58233. + if (DRAM_CS_Order[0] == N_A)
  58234. + {
  58235. + mvDramBankInfoGet(SDRAM_CS0, &bankInfo[SDRAM_CS0]);
  58236. +#ifdef MV_INCLUDE_SDRAM_CS2
  58237. + mvDramBankInfoGet(SDRAM_CS2, &bankInfo[SDRAM_CS2]);
  58238. +#endif
  58239. +
  58240. +#ifdef MV_INCLUDE_SDRAM_CS2
  58241. + if (bankInfo[SDRAM_CS0].size < bankInfo[SDRAM_CS2].size)
  58242. + {
  58243. + DRAM_CS_Order[0] = SDRAM_CS2;
  58244. + DRAM_CS_Order[1] = SDRAM_CS3;
  58245. + DRAM_CS_Order[2] = SDRAM_CS0;
  58246. + DRAM_CS_Order[3] = SDRAM_CS1;
  58247. +
  58248. + return SDRAM_CS2;
  58249. + }
  58250. +#endif
  58251. + DRAM_CS_Order[0] = SDRAM_CS0;
  58252. + DRAM_CS_Order[1] = SDRAM_CS1;
  58253. +#ifdef MV_INCLUDE_SDRAM_CS2
  58254. + DRAM_CS_Order[2] = SDRAM_CS2;
  58255. + DRAM_CS_Order[3] = SDRAM_CS3;
  58256. +#endif
  58257. + return SDRAM_CS0;
  58258. + }
  58259. + return DRAM_CS_Order[0];
  58260. +}
  58261. +/*******************************************************************************
  58262. +* mvDramIfGetCSorder -
  58263. +*
  58264. +*
  58265. +* DESCRIPTION:
  58266. +* This function return the fisrt CS on address 0
  58267. +*
  58268. +* INPUT:
  58269. +* CS number.
  58270. +*
  58271. +* OUTPUT:
  58272. +* CS order.
  58273. +*
  58274. +* RETURN:
  58275. +* SDRAM_CS0 or SDRAM_CS2
  58276. +*
  58277. +* NOTE: mvDramIfGetFirstCS must be caled before this subroutine
  58278. +*******************************************************************************/
  58279. +MV_U32 mvDramIfGetCSorder(MV_U32 csOrder )
  58280. +{
  58281. + return DRAM_CS_Order[csOrder];
  58282. +}
  58283. +
  58284. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h
  58285. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h 1970-01-01 01:00:00.000000000 +0100
  58286. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h 2010-08-05 22:02:24.324868447 +0200
  58287. @@ -0,0 +1,157 @@
  58288. +/*******************************************************************************
  58289. +Copyright (C) Marvell International Ltd. and its affiliates
  58290. +
  58291. +This software file (the "File") is owned and distributed by Marvell
  58292. +International Ltd. and/or its affiliates ("Marvell") under the following
  58293. +alternative licensing terms. Once you have made an election to distribute the
  58294. +File under one of the following license alternatives, please (i) delete this
  58295. +introductory statement regarding license alternatives, (ii) delete the two
  58296. +license alternatives that you have not elected to use and (iii) preserve the
  58297. +Marvell copyright notice above.
  58298. +
  58299. +********************************************************************************
  58300. +Marvell Commercial License Option
  58301. +
  58302. +If you received this File from Marvell and you have entered into a commercial
  58303. +license agreement (a "Commercial License") with Marvell, the File is licensed
  58304. +to you under the terms of the applicable Commercial License.
  58305. +
  58306. +********************************************************************************
  58307. +Marvell GPL License Option
  58308. +
  58309. +If you received this File from Marvell, you may opt to use, redistribute and/or
  58310. +modify this File in accordance with the terms and conditions of the General
  58311. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  58312. +available along with the File in the license.txt file or by writing to the Free
  58313. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  58314. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  58315. +
  58316. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  58317. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  58318. +DISCLAIMED. The GPL License provides additional details about this warranty
  58319. +disclaimer.
  58320. +********************************************************************************
  58321. +Marvell BSD License Option
  58322. +
  58323. +If you received this File from Marvell, you may opt to use, redistribute and/or
  58324. +modify this File under the following licensing terms.
  58325. +Redistribution and use in source and binary forms, with or without modification,
  58326. +are permitted provided that the following conditions are met:
  58327. +
  58328. + * Redistributions of source code must retain the above copyright notice,
  58329. + this list of conditions and the following disclaimer.
  58330. +
  58331. + * Redistributions in binary form must reproduce the above copyright
  58332. + notice, this list of conditions and the following disclaimer in the
  58333. + documentation and/or other materials provided with the distribution.
  58334. +
  58335. + * Neither the name of Marvell nor the names of its contributors may be
  58336. + used to endorse or promote products derived from this software without
  58337. + specific prior written permission.
  58338. +
  58339. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  58340. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  58341. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  58342. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  58343. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  58344. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  58345. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  58346. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  58347. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  58348. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  58349. +
  58350. +*******************************************************************************/
  58351. +
  58352. +
  58353. +#ifndef __INCmvDramIfConfigh
  58354. +#define __INCmvDramIfConfigh
  58355. +
  58356. +#ifdef __cplusplus
  58357. +extern "C" {
  58358. +#endif /* __cplusplus */
  58359. +
  58360. +/* includes */
  58361. +
  58362. +/* defines */
  58363. +
  58364. +/* registers defaults values */
  58365. +
  58366. +#define SDRAM_CONFIG_DV (SDRAM_SRMODE_DRAM | BIT25 | BIT30)
  58367. +
  58368. +#define SDRAM_DUNIT_CTRL_LOW_DDR2_DV \
  58369. + (SDRAM_SRCLK_KEPT | \
  58370. + SDRAM_CLK1DRV_NORMAL | \
  58371. + (BIT28 | BIT29))
  58372. +
  58373. +#define SDRAM_ADDR_CTRL_DV 2
  58374. +
  58375. +#define SDRAM_TIMING_CTRL_LOW_REG_DV \
  58376. + ((0x2 << SDRAM_TRCD_OFFS) | \
  58377. + (0x2 << SDRAM_TRP_OFFS) | \
  58378. + (0x1 << SDRAM_TWR_OFFS) | \
  58379. + (0x0 << SDRAM_TWTR_OFFS) | \
  58380. + (0x5 << SDRAM_TRAS_OFFS) | \
  58381. + (0x1 << SDRAM_TRRD_OFFS))
  58382. +
  58383. +/* Note: value of 0 in register means one cycle, 1 means two and so on */
  58384. +#define SDRAM_TIMING_CTRL_HIGH_REG_DV \
  58385. + ((0x0 << SDRAM_TR2R_OFFS) | \
  58386. + (0x0 << SDRAM_TR2W_W2R_OFFS) | \
  58387. + (0x1 << SDRAM_TW2W_OFFS))
  58388. +
  58389. +#define SDRAM_OPEN_PAGES_CTRL_REG_DV SDRAM_OPEN_PAGE_EN
  58390. +
  58391. +/* Presence Ctrl Low Ctrl High Dunit Ctrl Ext Mode */
  58392. +/* CS0 0x84210000 0x00000000 0x0000780F 0x00000440 */
  58393. +/* CS0+CS1 0x84210000 0x00000000 0x0000780F 0x00000440 */
  58394. +/* CS0+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  58395. +/* CS0+CS1+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  58396. +/* CS0+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  58397. +/* CS0+CS1+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  58398. +
  58399. +#define DDR2_ODT_CTRL_LOW_CS0_CS1_DV 0x84210000
  58400. +#define DDR2_ODT_CTRL_HIGH_CS0_CS1_DV 0x00000000
  58401. +#define DDR2_DUNIT_ODT_CTRL_CS0_CS1_DV 0x0000E80F
  58402. +#ifdef MV78XX0
  58403. +#define DDR_SDRAM_EXT_MODE_CS0_CS1_DV 0x00000040
  58404. +#else
  58405. +#define DDR_SDRAM_EXT_MODE_CS0_CS1_DV 0x00000440
  58406. +#endif
  58407. +
  58408. +#define DDR2_ODT_CTRL_LOW_CS0_CS1_CS2_CS3_DV 0x030C030C
  58409. +#define DDR2_ODT_CTRL_HIGH_CS0_CS1_CS2_CS3_DV 0x00000000
  58410. +#define DDR2_DUNIT_ODT_CTRL_CS0_CS1_CS2_CS3_DV 0x0000F40F
  58411. +#ifdef MV78XX0
  58412. +#define DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV 0x00000004
  58413. +#define DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV 0x00000044
  58414. +#else
  58415. +#define DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV 0x00000404
  58416. +#define DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV 0x00000444
  58417. +#endif
  58418. +
  58419. +/* DDR SDRAM Adderss/Control and Data Pads Calibration default values */
  58420. +#define DDR2_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV \
  58421. + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  58422. +
  58423. +#define DDR2_DATA_PAD_STRENGTH_TYPICAL_DV \
  58424. + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  58425. +
  58426. +/* DDR SDRAM Mode Register default value */
  58427. +#define DDR2_MODE_REG_DV (SDRAM_BURST_LEN_4 | SDRAM_WR_3_CYC)
  58428. +/* DDR SDRAM Timing parameter default values */
  58429. +#define SDRAM_TIMING_CTRL_LOW_REG_DEFAULT 0x33136552
  58430. +#define SDRAM_TRFC_DEFAULT_VALUE 0x34
  58431. +#define SDRAM_TRFC_DEFAULT SDRAM_TRFC_DEFAULT_VALUE
  58432. +#define SDRAM_TW2W_DEFALT (0x1 << SDRAM_TW2W_OFFS)
  58433. +
  58434. +#define SDRAM_TIMING_CTRL_HIGH_REG_DEFAULT (SDRAM_TRFC_DEFAULT | SDRAM_TW2W_DEFALT)
  58435. +
  58436. +#define SDRAM_FTDLL_REG_DEFAULT_LEFT 0x88C800
  58437. +#define SDRAM_FTDLL_REG_DEFAULT_RIGHT 0x88C800
  58438. +#define SDRAM_FTDLL_REG_DEFAULT_UP 0x88C800
  58439. +
  58440. +#ifdef __cplusplus
  58441. +}
  58442. +#endif /* __cplusplus */
  58443. +
  58444. +#endif /* __INCmvDramIfh */
  58445. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h
  58446. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h 1970-01-01 01:00:00.000000000 +0100
  58447. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h 2010-08-05 22:02:24.364867961 +0200
  58448. @@ -0,0 +1,172 @@
  58449. +/*******************************************************************************
  58450. +Copyright (C) Marvell International Ltd. and its affiliates
  58451. +
  58452. +This software file (the "File") is owned and distributed by Marvell
  58453. +International Ltd. and/or its affiliates ("Marvell") under the following
  58454. +alternative licensing terms. Once you have made an election to distribute the
  58455. +File under one of the following license alternatives, please (i) delete this
  58456. +introductory statement regarding license alternatives, (ii) delete the two
  58457. +license alternatives that you have not elected to use and (iii) preserve the
  58458. +Marvell copyright notice above.
  58459. +
  58460. +********************************************************************************
  58461. +Marvell Commercial License Option
  58462. +
  58463. +If you received this File from Marvell and you have entered into a commercial
  58464. +license agreement (a "Commercial License") with Marvell, the File is licensed
  58465. +to you under the terms of the applicable Commercial License.
  58466. +
  58467. +********************************************************************************
  58468. +Marvell GPL License Option
  58469. +
  58470. +If you received this File from Marvell, you may opt to use, redistribute and/or
  58471. +modify this File in accordance with the terms and conditions of the General
  58472. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  58473. +available along with the File in the license.txt file or by writing to the Free
  58474. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  58475. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  58476. +
  58477. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  58478. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  58479. +DISCLAIMED. The GPL License provides additional details about this warranty
  58480. +disclaimer.
  58481. +********************************************************************************
  58482. +Marvell BSD License Option
  58483. +
  58484. +If you received this File from Marvell, you may opt to use, redistribute and/or
  58485. +modify this File under the following licensing terms.
  58486. +Redistribution and use in source and binary forms, with or without modification,
  58487. +are permitted provided that the following conditions are met:
  58488. +
  58489. + * Redistributions of source code must retain the above copyright notice,
  58490. + this list of conditions and the following disclaimer.
  58491. +
  58492. + * Redistributions in binary form must reproduce the above copyright
  58493. + notice, this list of conditions and the following disclaimer in the
  58494. + documentation and/or other materials provided with the distribution.
  58495. +
  58496. + * Neither the name of Marvell nor the names of its contributors may be
  58497. + used to endorse or promote products derived from this software without
  58498. + specific prior written permission.
  58499. +
  58500. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  58501. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  58502. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  58503. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  58504. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  58505. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  58506. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  58507. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  58508. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  58509. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  58510. +
  58511. +*******************************************************************************/
  58512. +
  58513. +
  58514. +#ifndef __INCmvDramIfh
  58515. +#define __INCmvDramIfh
  58516. +
  58517. +#ifdef __cplusplus
  58518. +extern "C" {
  58519. +#endif /* __cplusplus */
  58520. +
  58521. +/* includes */
  58522. +#include "ddr2/mvDramIfRegs.h"
  58523. +#include "ddr2/mvDramIfConfig.h"
  58524. +#include "ctrlEnv/mvCtrlEnvLib.h"
  58525. +
  58526. +/* defines */
  58527. +/* DRAM Timing parameters */
  58528. +#define SDRAM_TWR 15 /* ns tWr */
  58529. +#define SDRAM_TRFC_64_512M_AT_200MHZ 70 /* ns tRfc for dens 64-512 @ 200MHz */
  58530. +#define SDRAM_TRFC_64_512M 75 /* ns tRfc for dens 64-512 */
  58531. +#define SDRAM_TRFC_1G 120 /* ns tRfc for dens 1GB */
  58532. +#define SDRAM_TR2R_CYC 1 /* cycle for tR2r */
  58533. +
  58534. +#define CAL_AUTO_DETECT 0 /* Do not force CAS latancy (mvDramIfDetect) */
  58535. +#define ECC_DISABLE 1 /* Force ECC to Disable */
  58536. +#define ECC_ENABLE 0 /* Force ECC to ENABLE */
  58537. +/* typedefs */
  58538. +
  58539. +/* enumeration for memory types */
  58540. +typedef enum _mvMemoryType
  58541. +{
  58542. + MEM_TYPE_SDRAM,
  58543. + MEM_TYPE_DDR1,
  58544. + MEM_TYPE_DDR2
  58545. +}MV_MEMORY_TYPE;
  58546. +
  58547. +/* enumeration for DDR2 supported CAS Latencies */
  58548. +typedef enum _mvDimmDdr2Cas
  58549. +{
  58550. + DDR2_CL_3 = 0x08,
  58551. + DDR2_CL_4 = 0x10,
  58552. + DDR2_CL_5 = 0x20,
  58553. + DDR2_CL_6 = 0x40,
  58554. + DDR2_CL_FAULT
  58555. +} MV_DIMM_DDR2_CAS;
  58556. +
  58557. +
  58558. +typedef struct _mvDramBankInfo
  58559. +{
  58560. + MV_MEMORY_TYPE memoryType; /* DDR1, DDR2 or SDRAM */
  58561. +
  58562. + /* DIMM dimensions */
  58563. + MV_U32 numOfRowAddr;
  58564. + MV_U32 numOfColAddr;
  58565. + MV_U32 dataWidth;
  58566. + MV_U32 errorCheckType; /* ECC , PARITY..*/
  58567. + MV_U32 sdramWidth; /* 4,8,16 or 32 */
  58568. + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
  58569. + MV_U32 burstLengthSupported;
  58570. + MV_U32 numOfBanksOnEachDevice;
  58571. + MV_U32 suportedCasLatencies;
  58572. + MV_U32 refreshInterval;
  58573. +
  58574. + /* DIMM timing parameters */
  58575. + MV_U32 minCycleTimeAtMaxCasLatPs;
  58576. + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
  58577. + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
  58578. + MV_U32 minRowPrechargeTime;
  58579. + MV_U32 minRowActiveToRowActive;
  58580. + MV_U32 minRasToCasDelay;
  58581. + MV_U32 minRasPulseWidth;
  58582. + MV_U32 minWriteRecoveryTime; /* DDR2 only */
  58583. + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
  58584. + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
  58585. + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
  58586. +
  58587. + /* Parameters calculated from the extracted DIMM information */
  58588. + MV_U32 size;
  58589. + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit */
  58590. + MV_U32 numberOfDevices;
  58591. +
  58592. + /* DIMM attributes (MV_TRUE for yes) */
  58593. + MV_BOOL registeredAddrAndControlInputs;
  58594. + MV_BOOL registeredDQMBinputs;
  58595. +
  58596. +}MV_DRAM_BANK_INFO;
  58597. +
  58598. +#include "ddr2/spd/mvSpd.h"
  58599. +
  58600. +/* mvDramIf.h API list */
  58601. +MV_VOID mvDramIfBasicAsmInit(MV_VOID);
  58602. +MV_STATUS mvDramIfDetect(MV_U32 forcedCl, MV_BOOL eccDisable);
  58603. +MV_VOID _mvDramIfConfig(int entryNum);
  58604. +
  58605. +MV_U32 mvDramIfBankSizeGet(MV_U32 bankNum);
  58606. +MV_U32 mvDramIfBankBaseGet(MV_U32 bankNum);
  58607. +MV_U32 mvDramIfSizeGet(MV_VOID);
  58608. +MV_U32 mvDramIfCalGet(void);
  58609. +MV_STATUS mvDramIfSingleBitErrThresholdSet(MV_U32 threshold);
  58610. +MV_VOID mvDramIfSelfRefreshSet(void);
  58611. +void mvDramIfShow(void);
  58612. +MV_U32 mvDramIfGetFirstCS(void);
  58613. +MV_U32 mvDramIfGetCSorder(MV_U32 csOrder );
  58614. +MV_U32 mvDramCsSizeGet(MV_U32 csNum);
  58615. +
  58616. +#ifdef __cplusplus
  58617. +}
  58618. +#endif /* __cplusplus */
  58619. +
  58620. +#endif /* __INCmvDramIfh */
  58621. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h
  58622. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h 1970-01-01 01:00:00.000000000 +0100
  58623. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h 2010-08-05 22:02:24.404867958 +0200
  58624. @@ -0,0 +1,423 @@
  58625. +/*******************************************************************************
  58626. +Copyright (C) Marvell International Ltd. and its affiliates
  58627. +
  58628. +This software file (the "File") is owned and distributed by Marvell
  58629. +International Ltd. and/or its affiliates ("Marvell") under the following
  58630. +alternative licensing terms. Once you have made an election to distribute the
  58631. +File under one of the following license alternatives, please (i) delete this
  58632. +introductory statement regarding license alternatives, (ii) delete the two
  58633. +license alternatives that you have not elected to use and (iii) preserve the
  58634. +Marvell copyright notice above.
  58635. +
  58636. +********************************************************************************
  58637. +Marvell Commercial License Option
  58638. +
  58639. +If you received this File from Marvell and you have entered into a commercial
  58640. +license agreement (a "Commercial License") with Marvell, the File is licensed
  58641. +to you under the terms of the applicable Commercial License.
  58642. +
  58643. +********************************************************************************
  58644. +Marvell GPL License Option
  58645. +
  58646. +If you received this File from Marvell, you may opt to use, redistribute and/or
  58647. +modify this File in accordance with the terms and conditions of the General
  58648. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  58649. +available along with the File in the license.txt file or by writing to the Free
  58650. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  58651. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  58652. +
  58653. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  58654. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  58655. +DISCLAIMED. The GPL License provides additional details about this warranty
  58656. +disclaimer.
  58657. +********************************************************************************
  58658. +Marvell BSD License Option
  58659. +
  58660. +If you received this File from Marvell, you may opt to use, redistribute and/or
  58661. +modify this File under the following licensing terms.
  58662. +Redistribution and use in source and binary forms, with or without modification,
  58663. +are permitted provided that the following conditions are met:
  58664. +
  58665. + * Redistributions of source code must retain the above copyright notice,
  58666. + this list of conditions and the following disclaimer.
  58667. +
  58668. + * Redistributions in binary form must reproduce the above copyright
  58669. + notice, this list of conditions and the following disclaimer in the
  58670. + documentation and/or other materials provided with the distribution.
  58671. +
  58672. + * Neither the name of Marvell nor the names of its contributors may be
  58673. + used to endorse or promote products derived from this software without
  58674. + specific prior written permission.
  58675. +
  58676. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  58677. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  58678. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  58679. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  58680. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  58681. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  58682. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  58683. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  58684. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  58685. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  58686. +
  58687. +*******************************************************************************/
  58688. +
  58689. +#ifndef __INCmvDramIfRegsh
  58690. +#define __INCmvDramIfRegsh
  58691. +
  58692. +#ifdef __cplusplus
  58693. +extern "C" {
  58694. +#endif /* __cplusplus */
  58695. +
  58696. +/* DDR SDRAM Controller Address Decode Registers */
  58697. + /* SDRAM CSn Base Address Register (SCBAR) */
  58698. +#define SDRAM_BASE_ADDR_REG(cpu,csNum) (0x1500 + ((csNum) * 8) + ((cpu) * 0x70))
  58699. +#define SCBAR_BASE_OFFS 16
  58700. +#define SCBAR_BASE_MASK (0xffff << SCBAR_BASE_OFFS)
  58701. +#define SCBAR_BASE_ALIGNMENT 0x10000
  58702. +
  58703. +/* SDRAM CSn Size Register (SCSR) */
  58704. +#define SDRAM_SIZE_REG(cpu,csNum) (0x1504 + ((csNum) * 8) + ((cpu) * 0x70))
  58705. +#define SCSR_SIZE_OFFS 24
  58706. +#define SCSR_SIZE_MASK (0xff << SCSR_SIZE_OFFS)
  58707. +#define SCSR_SIZE_ALIGNMENT 0x1000000
  58708. +#define SCSR_WIN_EN BIT0
  58709. +
  58710. +/* configuration register */
  58711. +#define SDRAM_CONFIG_REG (DRAM_BASE + 0x1400)
  58712. +#define SDRAM_REFRESH_OFFS 0
  58713. +#define SDRAM_REFRESH_MAX 0x3FFF
  58714. +#define SDRAM_REFRESH_MASK (SDRAM_REFRESH_MAX << SDRAM_REFRESH_OFFS)
  58715. +#define SDRAM_DWIDTH_OFFS 15
  58716. +#define SDRAM_DWIDTH_MASK (1 << SDRAM_DWIDTH_OFFS)
  58717. +#define SDRAM_DWIDTH_32BIT (0 << SDRAM_DWIDTH_OFFS)
  58718. +#define SDRAM_DWIDTH_64BIT (1 << SDRAM_DWIDTH_OFFS)
  58719. +#define SDRAM_REGISTERED (1 << 17)
  58720. +#define SDRAM_ECC_OFFS 18
  58721. +#define SDRAM_ECC_MASK (1 << SDRAM_ECC_OFFS)
  58722. +#define SDRAM_ECC_DIS (0 << SDRAM_ECC_OFFS)
  58723. +#define SDRAM_ECC_EN (1 << SDRAM_ECC_OFFS)
  58724. +#define SDRAM_IERR_OFFS 19
  58725. +#define SDRAM_IERR_MASK (1 << SDRAM_IERR_OFFS)
  58726. +#define SDRAM_IERR_REPORTE (0 << SDRAM_IERR_OFFS)
  58727. +#define SDRAM_IERR_IGNORE (1 << SDRAM_IERR_OFFS)
  58728. +#define SDRAM_SRMODE_OFFS 24
  58729. +#define SDRAM_SRMODE_MASK (1 << SDRAM_SRMODE_OFFS)
  58730. +#define SDRAM_SRMODE_POWER (0 << SDRAM_SRMODE_OFFS)
  58731. +#define SDRAM_SRMODE_DRAM (1 << SDRAM_SRMODE_OFFS)
  58732. +
  58733. +/* dunit control low register */
  58734. +#define SDRAM_DUNIT_CTRL_REG (DRAM_BASE + 0x1404)
  58735. +#define SDRAM_2T_OFFS 4
  58736. +#define SDRAM_2T_MASK (1 << SDRAM_2T_OFFS)
  58737. +#define SDRAM_2T_MODE (1 << SDRAM_2T_OFFS)
  58738. +
  58739. +#define SDRAM_SRCLK_OFFS 5
  58740. +#define SDRAM_SRCLK_MASK (1 << SDRAM_SRCLK_OFFS)
  58741. +#define SDRAM_SRCLK_KEPT (0 << SDRAM_SRCLK_OFFS)
  58742. +#define SDRAM_SRCLK_GATED (1 << SDRAM_SRCLK_OFFS)
  58743. +#define SDRAM_CTRL_POS_OFFS 6
  58744. +#define SDRAM_CTRL_POS_MASK (1 << SDRAM_CTRL_POS_OFFS)
  58745. +#define SDRAM_CTRL_POS_FALL (0 << SDRAM_CTRL_POS_OFFS)
  58746. +#define SDRAM_CTRL_POS_RISE (1 << SDRAM_CTRL_POS_OFFS)
  58747. +#define SDRAM_CLK1DRV_OFFS 12
  58748. +#define SDRAM_CLK1DRV_MASK (1 << SDRAM_CLK1DRV_OFFS)
  58749. +#define SDRAM_CLK1DRV_HIGH_Z (0 << SDRAM_CLK1DRV_OFFS)
  58750. +#define SDRAM_CLK1DRV_NORMAL (1 << SDRAM_CLK1DRV_OFFS)
  58751. +#define SDRAM_CLK2DRV_OFFS 13
  58752. +#define SDRAM_CLK2DRV_MASK (1 << SDRAM_CLK2DRV_OFFS)
  58753. +#define SDRAM_CLK2DRV_HIGH_Z (0 << SDRAM_CLK2DRV_OFFS)
  58754. +#define SDRAM_CLK2DRV_NORMAL (1 << SDRAM_CLK2DRV_OFFS)
  58755. +#define SDRAM_SB_OUT_DEL_OFFS 20
  58756. +#define SDRAM_SB_OUT_DEL_MAX 0xf
  58757. +#define SDRAM_SB_OUT_MASK (SDRAM_SB_OUT_DEL_MAX<<SDRAM_SB_OUT_DEL_OFFS)
  58758. +#define SDRAM_SB_IN_DEL_OFFS 24
  58759. +#define SDRAM_SB_IN_DEL_MAX 0xf
  58760. +#define SDRAM_SB_IN_MASK (SDRAM_SB_IN_DEL_MAX<<SDRAM_SB_IN_DEL_OFFS)
  58761. +
  58762. +/* dunit control hight register */
  58763. +#define SDRAM_DUNIT_CTRL_HI_REG (DRAM_BASE + 0x1424)
  58764. +#define SDRAM__D2P_OFFS 7
  58765. +#define SDRAM__D2P_EN (1 << SDRAM__D2P_OFFS)
  58766. +#define SDRAM__P2D_OFFS 8
  58767. +#define SDRAM__P2D_EN (1 << SDRAM__P2D_OFFS)
  58768. +#define SDRAM__ADD_HALF_FCC_OFFS 9
  58769. +#define SDRAM__ADD_HALF_FCC_EN (1 << SDRAM__ADD_HALF_FCC_OFFS)
  58770. +#define SDRAM__PUP_ZERO_SKEW_OFFS 10
  58771. +#define SDRAM__PUP_ZERO_SKEW_EN (1 << SDRAM__PUP_ZERO_SKEW_OFFS)
  58772. +#define SDRAM__WR_MESH_DELAY_OFFS 11
  58773. +#define SDRAM__WR_MESH_DELAY_EN (1 << SDRAM__WR_MESH_DELAY_OFFS)
  58774. +
  58775. +/* sdram timing control low register */
  58776. +#define SDRAM_TIMING_CTRL_LOW_REG (DRAM_BASE + 0x1408)
  58777. +#define SDRAM_TRCD_OFFS 4
  58778. +#define SDRAM_TRCD_MASK (0xF << SDRAM_TRCD_OFFS)
  58779. +#define SDRAM_TRP_OFFS 8
  58780. +#define SDRAM_TRP_MASK (0xF << SDRAM_TRP_OFFS)
  58781. +#define SDRAM_TWR_OFFS 12
  58782. +#define SDRAM_TWR_MASK (0xF << SDRAM_TWR_OFFS)
  58783. +#define SDRAM_TWTR_OFFS 16
  58784. +#define SDRAM_TWTR_MASK (0xF << SDRAM_TWTR_OFFS)
  58785. +#define SDRAM_TRAS_OFFS 0
  58786. +#define SDRAM_TRAS_MASK (0xF << SDRAM_TRAS_OFFS)
  58787. +#define SDRAM_EXT_TRAS_OFFS 20
  58788. +#define SDRAM_EXT_TRAS_MASK (0x1 << SDRAM_EXT_TRAS_OFFS)
  58789. +#define SDRAM_TRRD_OFFS 24
  58790. +#define SDRAM_TRRD_MASK (0xF << SDRAM_TRRD_OFFS)
  58791. +#define SDRAM_TRTP_OFFS 28
  58792. +#define SDRAM_TRTP_MASK (0xF << SDRAM_TRTP_OFFS)
  58793. +#define SDRAM_TRTP_DDR1 (0x1 << SDRAM_TRTP_OFFS)
  58794. +
  58795. +/* sdram timing control high register */
  58796. +#define SDRAM_TIMING_CTRL_HIGH_REG (DRAM_BASE + 0x140c)
  58797. +#define SDRAM_TRFC_OFFS 0
  58798. +#define SDRAM_TRFC_MASK (0x3F << SDRAM_TRFC_OFFS)
  58799. +#define SDRAM_TR2R_OFFS 7
  58800. +#define SDRAM_TR2R_MASK (0x3 << SDRAM_TR2R_OFFS)
  58801. +#define SDRAM_TR2W_W2R_OFFS 9
  58802. +#define SDRAM_TR2W_W2R_MASK (0x3 << SDRAM_TR2W_W2R_OFFS)
  58803. +#define SDRAM_TW2W_OFFS 11
  58804. +#define SDRAM_TW2W_MASK (0x3 << SDRAM_TW2W_OFFS)
  58805. +
  58806. +/* sdram DDR2 timing low register (SD2TLR) */
  58807. +#define SDRAM_DDR2_TIMING_LO_REG (DRAM_BASE + 0x1428)
  58808. +#define SD2TLR_TODT_ON_RD_OFFS 4
  58809. +#define SD2TLR_TODT_ON_RD_MASK (0xF << SD2TLR_TODT_ON_RD_OFFS)
  58810. +#define SD2TLR_TODT_OFF_RD_OFFS 8
  58811. +#define SD2TLR_TODT_OFF_RD_MASK (0xF << SD2TLR_TODT_OFF_RD_OFFS)
  58812. +#define SD2TLR_TODT_ON_CTRL_RD_OFFS 12
  58813. +#define SD2TLR_TODT_ON_CTRL_RD_MASK (0xF << SD2TLR_TODT_ON_CTRL_RD_OFFS)
  58814. +#define SD2TLR_TODT_OFF_CTRL_RD_OFFS 16
  58815. +#define SD2TLR_TODT_OFF_CTRL_RD_MASK (0xF << SD2TLR_TODT_OFF_CTRL_RD_OFFS)
  58816. +
  58817. +/* sdram DDR2 timing high register (SD2TLR) */
  58818. +#define SDRAM_DDR2_TIMING_HI_REG (DRAM_BASE + 0x147C)
  58819. +#define SD2THR_TODT_ON_WR_OFFS 0
  58820. +#define SD2THR_TODT_ON_WR_MASK (0xF << SD2THR_TODT_ON_WR_OFFS)
  58821. +#define SD2THR_TODT_OFF_WR_OFFS 4
  58822. +#define SD2THR_TODT_OFF_WR_MASK (0xF << SD2THR_TODT_OFF_WR_OFFS)
  58823. +#define SD2THR_TODT_ON_CTRL_WR_OFFS 8
  58824. +#define SD2THR_TODT_ON_CTRL_WR_MASK (0xF << SD2THR_TODT_ON_CTRL_WR_OFFS)
  58825. +#define SD2THR_TODT_OFF_CTRL_WR_OFFS 12
  58826. +#define SD2THR_TODT_OFF_CTRL_WR_MASK (0xF << SD2THR_TODT_OFF_CTRL_WR_OFFS)
  58827. +
  58828. +/* address control register */
  58829. +#define SDRAM_ADDR_CTRL_REG (DRAM_BASE + 0x1410)
  58830. +#define SDRAM_ADDRSEL_OFFS(cs) (4 * (cs))
  58831. +#define SDRAM_ADDRSEL_MASK(cs) (0x3 << SDRAM_ADDRSEL_OFFS(cs))
  58832. +#define SDRAM_ADDRSEL_X8(cs) (0x0 << SDRAM_ADDRSEL_OFFS(cs))
  58833. +#define SDRAM_ADDRSEL_X16(cs) (0x1 << SDRAM_ADDRSEL_OFFS(cs))
  58834. +#define SDRAM_DSIZE_OFFS(cs) (2 + 4 * (cs))
  58835. +#define SDRAM_DSIZE_MASK(cs) (0x3 << SDRAM_DSIZE_OFFS(cs))
  58836. +#define SDRAM_DSIZE_256Mb(cs) (0x1 << SDRAM_DSIZE_OFFS(cs))
  58837. +#define SDRAM_DSIZE_512Mb(cs) (0x2 << SDRAM_DSIZE_OFFS(cs))
  58838. +#define SDRAM_DSIZE_1Gb(cs) (0x3 << SDRAM_DSIZE_OFFS(cs))
  58839. +#define SDRAM_DSIZE_2Gb(cs) (0x0 << SDRAM_DSIZE_OFFS(cs))
  58840. +
  58841. +/* SDRAM Open Pages Control registers */
  58842. +#define SDRAM_OPEN_PAGE_CTRL_REG (DRAM_BASE + 0x1414)
  58843. +#define SDRAM_OPEN_PAGE_EN (0 << 0)
  58844. +#define SDRAM_OPEN_PAGE_DIS (1 << 0)
  58845. +
  58846. +/* sdram opertion register */
  58847. +#define SDRAM_OPERATION_REG (DRAM_BASE + 0x1418)
  58848. +#define SDRAM_CMD_OFFS 0
  58849. +#define SDRAM_CMD_MASK (0xF << SDRAM_CMD_OFFS)
  58850. +#define SDRAM_CMD_NORMAL (0x0 << SDRAM_CMD_OFFS)
  58851. +#define SDRAM_CMD_PRECHARGE_ALL (0x1 << SDRAM_CMD_OFFS)
  58852. +#define SDRAM_CMD_REFRESH_ALL (0x2 << SDRAM_CMD_OFFS)
  58853. +#define SDRAM_CMD_REG_SET_CMD (0x3 << SDRAM_CMD_OFFS)
  58854. +#define SDRAM_CMD_EXT_MODE_SET (0x4 << SDRAM_CMD_OFFS)
  58855. +#define SDRAM_CMD_NOP (0x5 << SDRAM_CMD_OFFS)
  58856. +#define SDRAM_CMD_SLF_RFRSH (0x7 << SDRAM_CMD_OFFS)
  58857. +#define SDRAM_CMD_EMRS2_CMD (0x8 << SDRAM_CMD_OFFS)
  58858. +#define SDRAM_CMD_EMRS3_CMD (0x9 << SDRAM_CMD_OFFS)
  58859. +
  58860. +/* sdram mode register */
  58861. +#define SDRAM_MODE_REG (DRAM_BASE + 0x141c)
  58862. +#define SDRAM_BURST_LEN_OFFS 0
  58863. +#define SDRAM_BURST_LEN_MASK (0x7 << SDRAM_BURST_LEN_OFFS)
  58864. +#define SDRAM_BURST_LEN_4 (0x2 << SDRAM_BURST_LEN_OFFS)
  58865. +#define SDRAM_CL_OFFS 4
  58866. +#define SDRAM_CL_MASK (0x7 << SDRAM_CL_OFFS)
  58867. +#define SDRAM_DDR2_CL_3 (0x3 << SDRAM_CL_OFFS)
  58868. +#define SDRAM_DDR2_CL_4 (0x4 << SDRAM_CL_OFFS)
  58869. +#define SDRAM_DDR2_CL_5 (0x5 << SDRAM_CL_OFFS)
  58870. +#define SDRAM_DDR2_CL_6 (0x6 << SDRAM_CL_OFFS)
  58871. +
  58872. +#define SDRAM_TM_OFFS 7
  58873. +#define SDRAM_TM_MASK (1 << SDRAM_TM_OFFS)
  58874. +#define SDRAM_TM_NORMAL (0 << SDRAM_TM_OFFS)
  58875. +#define SDRAM_TM_TEST_MODE (1 << SDRAM_TM_OFFS)
  58876. +#define SDRAM_DLL_OFFS 8
  58877. +#define SDRAM_DLL_MASK (1 << SDRAM_DLL_OFFS)
  58878. +#define SDRAM_DLL_NORMAL (0 << SDRAM_DLL_OFFS)
  58879. +#define SDRAM_DLL_RESET (1 << SDRAM_DLL_OFFS)
  58880. +#define SDRAM_WR_OFFS 9
  58881. +#define SDRAM_WR_MAX 7
  58882. +#define SDRAM_WR_MASK (SDRAM_WR_MAX << SDRAM_WR_OFFS)
  58883. +#define SDRAM_WR_2_CYC (1 << SDRAM_WR_OFFS)
  58884. +#define SDRAM_WR_3_CYC (2 << SDRAM_WR_OFFS)
  58885. +#define SDRAM_WR_4_CYC (3 << SDRAM_WR_OFFS)
  58886. +#define SDRAM_WR_5_CYC (4 << SDRAM_WR_OFFS)
  58887. +#define SDRAM_WR_6_CYC (5 << SDRAM_WR_OFFS)
  58888. +#define SDRAM_PD_OFFS 12
  58889. +#define SDRAM_PD_MASK (1 << SDRAM_PD_OFFS)
  58890. +#define SDRAM_PD_FAST_EXIT (0 << SDRAM_PD_OFFS)
  58891. +#define SDRAM_PD_SLOW_EXIT (1 << SDRAM_PD_OFFS)
  58892. +
  58893. +/* DDR SDRAM Extended Mode register (DSEMR) */
  58894. +#define SDRAM_EXTENDED_MODE_REG (DRAM_BASE + 0x1420)
  58895. +#define DSEMR_DLL_ENABLE 0
  58896. +#define DSEMR_DLL_DISABLE 1
  58897. +#define DSEMR_DS_OFFS 1
  58898. +#define DSEMR_DS_MASK (1 << DSEMR_DS_OFFS)
  58899. +#define DSEMR_DS_NORMAL (0 << DSEMR_DS_OFFS)
  58900. +#define DSEMR_DS_REDUCED (1 << DSEMR_DS_OFFS)
  58901. +#define DSEMR_QOFF_OUTPUT_BUFF_EN (0 << 12)
  58902. +#define DSEMR_RTT0_OFFS 2
  58903. +#define DSEMR_RTT1_OFFS 6
  58904. +#define DSEMR_RTT_ODT_DISABLE ((0 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
  58905. +#define DSEMR_RTT_ODT_75_OHM ((1 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
  58906. +#define DSEMR_RTT_ODT_150_OHM ((0 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))
  58907. +#define DSEMR_RTT_ODT_50_OHM ((1 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))
  58908. +#define DSEMR_DQS_OFFS 10
  58909. +#define DSEMR_DQS_MASK (1 << DSEMR_DQS_OFFS)
  58910. +#define DSEMR_DQS_DIFFERENTIAL (0 << DSEMR_DQS_OFFS)
  58911. +#define DSEMR_DQS_SINGLE_ENDED (1 << DSEMR_DQS_OFFS)
  58912. +#define DSEMR_RDQS_ENABLE (1 << 11)
  58913. +#define DSEMR_QOFF_OUTPUT_BUFF_EN (0 << 12)
  58914. +#define DSEMR_QOFF_OUTPUT_BUFF_DIS (1 << 12)
  58915. +
  58916. +/* DDR SDRAM Operation Control Register */
  58917. +#define SDRAM_OPERATION_CTRL_REG (DRAM_BASE + 0x142c)
  58918. +
  58919. +/* Dunit FTDLL Configuration Register */
  58920. +#define SDRAM_FTDLL_CONFIG_LEFT_REG (DRAM_BASE + 0x1484)
  58921. +#define SDRAM_FTDLL_CONFIG_RIGHT_REG (DRAM_BASE + 0x161C)
  58922. +#define SDRAM_FTDLL_CONFIG_UP_REG (DRAM_BASE + 0x1620)
  58923. +
  58924. +/* Pads Calibration register */
  58925. +#define SDRAM_ADDR_CTRL_PADS_CAL_REG (DRAM_BASE + 0x14c0)
  58926. +#define SDRAM_DATA_PADS_CAL_REG (DRAM_BASE + 0x14c4)
  58927. +#define SDRAM_DRVN_OFFS 0
  58928. +#define SDRAM_DRVN_MASK (0x3F << SDRAM_DRVN_OFFS)
  58929. +#define SDRAM_DRVP_OFFS 6
  58930. +#define SDRAM_DRVP_MASK (0x3F << SDRAM_DRVP_OFFS)
  58931. +#define SDRAM_PRE_DRIVER_STRENGTH_OFFS 12
  58932. +#define SDRAM_PRE_DRIVER_STRENGTH_MASK (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  58933. +#define SDRAM_TUNE_EN BIT16
  58934. +#define SDRAM_LOCKN_OFFS 17
  58935. +#define SDRAM_LOCKN_MAKS (0x3F << SDRAM_LOCKN_OFFS)
  58936. +#define SDRAM_LOCKP_OFFS 23
  58937. +#define SDRAM_LOCKP_MAKS (0x3F << SDRAM_LOCKP_OFFS)
  58938. +#define SDRAM_WR_EN (1 << 31)
  58939. +
  58940. +/* DDR2 SDRAM ODT Control (Low) Register (DSOCLR) */
  58941. +#define DDR2_SDRAM_ODT_CTRL_LOW_REG (DRAM_BASE + 0x1494)
  58942. +#define DSOCLR_ODT_RD_OFFS(odtNum) (odtNum * 4)
  58943. +#define DSOCLR_ODT_RD_MASK(odtNum) (0xf << DSOCLR_ODT_RD_OFFS(odtNum))
  58944. +#define DSOCLR_ODT_RD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_RD_OFFS(odtNum))
  58945. +#define DSOCLR_ODT_WR_OFFS(odtNum) (16 + (odtNum * 4))
  58946. +#define DSOCLR_ODT_WR_MASK(odtNum) (0xf << DSOCLR_ODT_WR_OFFS(odtNum))
  58947. +#define DSOCLR_ODT_WR(odtNum, bank) ((1 << bank) << DSOCLR_ODT_WR_OFFS(odtNum))
  58948. +
  58949. +/* DDR2 SDRAM ODT Control (High) Register (DSOCHR) */
  58950. +#define DDR2_SDRAM_ODT_CTRL_HIGH_REG (DRAM_BASE + 0x1498)
  58951. +/* Optional control values to DSOCHR_ODT_EN macro */
  58952. +#define DDR2_ODT_CTRL_DUNIT 0
  58953. +#define DDR2_ODT_CTRL_NEVER 1
  58954. +#define DDR2_ODT_CTRL_ALWAYS 3
  58955. +#define DSOCHR_ODT_EN_OFFS(odtNum) (odtNum * 2)
  58956. +#define DSOCHR_ODT_EN_MASK(odtNum) (0x3 << DSOCHR_ODT_EN_OFFS(odtNum))
  58957. +#define DSOCHR_ODT_EN(odtNum, ctrl) (ctrl << DSOCHR_ODT_EN_OFFS(odtNum))
  58958. +
  58959. +/* DDR2 Dunit ODT Control Register (DDOCR)*/
  58960. +#define DDR2_DUNIT_ODT_CONTROL_REG (DRAM_BASE + 0x149c)
  58961. +#define DDOCR_ODT_RD_OFFS 0
  58962. +#define DDOCR_ODT_RD_MASK (0xf << DDOCR_ODT_RD_OFFS)
  58963. +#define DDOCR_ODT_RD(bank) ((1 << bank) << DDOCR_ODT_RD_OFFS)
  58964. +#define DDOCR_ODT_WR_OFFS 4
  58965. +#define DDOCR_ODT_WR_MASK (0xf << DDOCR_ODT_WR_OFFS)
  58966. +#define DDOCR_ODT_WR(bank) ((1 << bank) << DDOCR_ODT_WR_OFFS)
  58967. +#define DSOCR_ODT_EN_OFFS 8
  58968. +#define DSOCR_ODT_EN_MASK (0x3 << DSOCR_ODT_EN_OFFS)
  58969. +/* For ctrl parameters see DDR2 SDRAM ODT Control (High) Register (0x1498) above. */
  58970. +#define DSOCR_ODT_EN(ctrl) (ctrl << DSOCR_ODT_EN_OFFS)
  58971. +#define DSOCR_ODT_SEL_DISABLE 0
  58972. +#define DSOCR_ODT_SEL_75_OHM 2
  58973. +#define DSOCR_ODT_SEL_150_OHM 1
  58974. +#define DSOCR_ODT_SEL_50_OHM 3
  58975. +#define DSOCR_DQ_ODT_SEL_OFFS 10
  58976. +#define DSOCR_DQ_ODT_SEL_MASK (0x3 << DSOCR_DQ_ODT_SEL_OFFS)
  58977. +#define DSOCR_DQ_ODT_SEL(odtSel) (odtSel << DSOCR_DQ_ODT_SEL_OFFS)
  58978. +#define DSOCR_ST_ODT_SEL_OFFS 12
  58979. +#define DSOCR_ST_ODT_SEL_MASK (0x3 << DSOCR_ST_ODT_SEL_OFFS)
  58980. +#define DSOCR_ST_ODT_SEL(odtSel) (odtSel << DSOCR_ST_ODT_SEL_OFFS)
  58981. +#define DSOCR_ST_ODT_EN (1 << 14)
  58982. +
  58983. +/* DDR SDRAM Initialization Control Register (DSICR) */
  58984. +#define DDR_SDRAM_INIT_CTRL_REG (DRAM_BASE + 0x1480)
  58985. +#define DSICR_INIT_EN (1 << 0)
  58986. +#define DSICR_T200_SET (1 << 8)
  58987. +
  58988. +/* sdram extended mode2 register (SEM2R) */
  58989. +#define SDRAM_EXTENDED_MODE2_REG (DRAM_BASE + 0x148C)
  58990. +#define SEM2R_EMRS2_DDR2_OFFS 0
  58991. +#define SEM2R_EMRS2_DDR2_MASK (0x7FFF << SEM2R_EMRS2_DDR2_OFFS)
  58992. +
  58993. +/* sdram extended mode3 register (SEM3R) */
  58994. +#define SDRAM_EXTENDED_MODE3_REG (DRAM_BASE + 0x1490)
  58995. +#define SEM3R_EMRS3_DDR2_OFFS 0
  58996. +#define SEM3R_EMRS3_DDR2_MASK (0x7FFF << SEM3R_EMRS3_DDR2_OFFS)
  58997. +
  58998. +/* sdram error registers */
  58999. +#define SDRAM_ERROR_CAUSE_REG (DRAM_BASE + 0x14d0)
  59000. +#define SDRAM_ERROR_MASK_REG (DRAM_BASE + 0x14d4)
  59001. +#define SDRAM_ERROR_DATA_LOW_REG (DRAM_BASE + 0x1444)
  59002. +#define SDRAM_ERROR_DATA_HIGH_REG (DRAM_BASE + 0x1440)
  59003. +#define SDRAM_ERROR_ADDR_REG (DRAM_BASE + 0x1450)
  59004. +#define SDRAM_ERROR_ECC_REG (DRAM_BASE + 0x1448)
  59005. +#define SDRAM_CALC_ECC_REG (DRAM_BASE + 0x144c)
  59006. +#define SDRAM_ECC_CONTROL_REG (DRAM_BASE + 0x1454)
  59007. +#define SDRAM_SINGLE_BIT_ERR_CNTR_REG (DRAM_BASE + 0x1458)
  59008. +#define SDRAM_DOUBLE_BIT_ERR_CNTR_REG (DRAM_BASE + 0x145c)
  59009. +
  59010. +/* SDRAM Error Cause Register (SECR) */
  59011. +#define SECR_SINGLE_BIT_ERR BIT0
  59012. +#define SECR_DOUBLE_BIT_ERR BIT1
  59013. +#define SECR_DATA_PATH_PARITY_ERR BIT2
  59014. +/* SDRAM Error Address Register (SEAR) */
  59015. +#define SEAR_ERR_TYPE_OFFS 0
  59016. +#define SEAR_ERR_TYPE_MASK (1 << SEAR_ERR_TYPE_OFFS)
  59017. +#define SEAR_ERR_TYPE_SINGLE 0
  59018. +#define SEAR_ERR_TYPE_DOUBLE (1 << SEAR_ERR_TYPE_OFFS)
  59019. +#define SEAR_ERR_CS_OFFS 1
  59020. +#define SEAR_ERR_CS_MASK (3 << SEAR_ERR_CS_OFFS)
  59021. +#define SEAR_ERR_CS(csNum) (csNum << SEAR_ERR_CS_OFFS)
  59022. +#define SEAR_ERR_ADDR_OFFS 3
  59023. +#define SEAR_ERR_ADDR_MASK (0x1FFFFFFF << SEAR_ERR_ADDR_OFFS)
  59024. +
  59025. +/* SDRAM ECC Control Register (SECR) */
  59026. +#define SECR_FORCEECC_OFFS 0
  59027. +#define SECR_FORCEECC_MASK (0xFF << SECR_FORCEECC_OFFS)
  59028. +#define SECR_FORCEEN_OFFS 8
  59029. +#define SECR_FORCEEN_MASK (1 << SECR_FORCEEN_OFFS)
  59030. +#define SECR_ECC_CALC_MASK (0 << SECR_FORCEEN_OFFS)
  59031. +#define SECR_ECC_USER_MASK (1 << SECR_FORCEEN_OFFS)
  59032. +#define SECR_PERRPROP_EN BIT9
  59033. +#define SECR_CNTMODE_OFFS 10
  59034. +#define SECR_CNTMODE_MASK (1 << SECR_CNTMODE_OFFS)
  59035. +#define SECR_ALL_IN_CS0 (0 << SECR_CNTMODE_OFFS)
  59036. +#define SECR_NORMAL_COUNTER (1 << SECR_CNTMODE_OFFS)
  59037. +#define SECR_THRECC_OFFS 16
  59038. +#define SECR_THRECC_MAX 0xFF
  59039. +#define SECR_THRECC_MASK (SECR_THRECC_MAX << SECR_THRECC_OFFS)
  59040. +#define SECR_THRECC(threshold) (threshold << SECR_THRECC_OFFS)
  59041. +
  59042. +
  59043. +#ifdef __cplusplus
  59044. +}
  59045. +#endif /* __cplusplus */
  59046. +
  59047. +#endif /* __INCmvDramIfRegsh */
  59048. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h
  59049. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h 1970-01-01 01:00:00.000000000 +0100
  59050. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h 2010-08-05 22:02:24.444868303 +0200
  59051. @@ -0,0 +1,179 @@
  59052. +/*******************************************************************************
  59053. +Copyright (C) Marvell International Ltd. and its affiliates
  59054. +
  59055. +This software file (the "File") is owned and distributed by Marvell
  59056. +International Ltd. and/or its affiliates ("Marvell") under the following
  59057. +alternative licensing terms. Once you have made an election to distribute the
  59058. +File under one of the following license alternatives, please (i) delete this
  59059. +introductory statement regarding license alternatives, (ii) delete the two
  59060. +license alternatives that you have not elected to use and (iii) preserve the
  59061. +Marvell copyright notice above.
  59062. +
  59063. +********************************************************************************
  59064. +Marvell Commercial License Option
  59065. +
  59066. +If you received this File from Marvell and you have entered into a commercial
  59067. +license agreement (a "Commercial License") with Marvell, the File is licensed
  59068. +to you under the terms of the applicable Commercial License.
  59069. +
  59070. +********************************************************************************
  59071. +Marvell GPL License Option
  59072. +
  59073. +If you received this File from Marvell, you may opt to use, redistribute and/or
  59074. +modify this File in accordance with the terms and conditions of the General
  59075. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  59076. +available along with the File in the license.txt file or by writing to the Free
  59077. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  59078. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  59079. +
  59080. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  59081. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  59082. +DISCLAIMED. The GPL License provides additional details about this warranty
  59083. +disclaimer.
  59084. +********************************************************************************
  59085. +Marvell BSD License Option
  59086. +
  59087. +If you received this File from Marvell, you may opt to use, redistribute and/or
  59088. +modify this File under the following licensing terms.
  59089. +Redistribution and use in source and binary forms, with or without modification,
  59090. +are permitted provided that the following conditions are met:
  59091. +
  59092. + * Redistributions of source code must retain the above copyright notice,
  59093. + this list of conditions and the following disclaimer.
  59094. +
  59095. + * Redistributions in binary form must reproduce the above copyright
  59096. + notice, this list of conditions and the following disclaimer in the
  59097. + documentation and/or other materials provided with the distribution.
  59098. +
  59099. + * Neither the name of Marvell nor the names of its contributors may be
  59100. + used to endorse or promote products derived from this software without
  59101. + specific prior written permission.
  59102. +
  59103. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  59104. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  59105. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  59106. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  59107. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  59108. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  59109. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  59110. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  59111. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  59112. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  59113. +
  59114. +*******************************************************************************/
  59115. +
  59116. +
  59117. +#ifndef __INCmvDramIfStaticInith
  59118. +#define __INCmvDramIfStaticInith
  59119. +
  59120. +#ifdef MV_STATIC_DRAM_ON_BOARD
  59121. +#define STATIC_DRAM_BANK_1
  59122. +#undef STATIC_DRAM_BANK_2
  59123. +#undef STATIC_DRAM_BANK_3
  59124. +#undef STATIC_DRAM_BANK_4
  59125. +
  59126. +
  59127. +#ifdef MV_DIMM_TS256MLQ72V5U
  59128. +#define STATIC_DRAM_BANK_2
  59129. +#define STATIC_DRAM_BANK_3
  59130. +#undef STATIC_DRAM_BANK_4
  59131. +
  59132. +#define STATIC_SDRAM_CONFIG_REG 0x4724481A /* offset 0x1400 - DMA reg-0xf1000814 */
  59133. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0x37707450 /* offset 0x1404 - DMA reg-0xf100081c */
  59134. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x11A13330 /* offset 0x1408 - DMA reg-0xf1000824 */
  59135. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000601 /* offset 0x140c - DMA reg-0xf1000828 */
  59136. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00001CB2 /* offset 0x1410 - DMA reg-0xf1000820 */
  59137. +#define STATIC_SDRAM_MODE_REG 0x00000642 /* offset 0x141c - DMA reg-0xf1000818 */
  59138. +#define STATIC_SDRAM_ODT_CTRL_LOW 0x030C030C /* 0x1494 */
  59139. +#define STATIC_SDRAM_ODT_CTRL_HI 0x00000000 /* 0x1498 */
  59140. +#define STATIC_SDRAM_DUNIT_ODT_CTRL 0x0000740F /* 0x149c */
  59141. +#define STATIC_SDRAM_EXT_MODE 0x00000404 /* 0x1420 */
  59142. +#define STATIC_SDRAM_DDR2_TIMING_LO 0x00074410 /* 0x1428 */
  59143. +#define STATIC_SDRAM_DDR2_TIMING_HI 0x00007441 /* 0x147C */
  59144. +
  59145. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x3FFF /* size bank0 dimm0 - DMA reg-0xf1000810 */
  59146. +#define STATIC_SDRAM_RANK1_SIZE_DIMM0 0x3FFF /* size bank1 dimm0 */
  59147. +#define STATIC_SDRAM_RANK0_SIZE_DIMM1 0x3FFF /* size bank0 dimm1 */
  59148. +#define STATIC_SDRAM_RANK1_SIZE_DIMM1 0x0 /* size bank1 dimm1 */
  59149. +
  59150. +#endif /* TS256MLQ72V5U */
  59151. +
  59152. +
  59153. +#ifdef MV_MT9VDDT3272AG
  59154. +/* one DIMM 256M */
  59155. +#define STATIC_SDRAM_CONFIG_REG 0x5820040d /* offset 0x1400 - DMA reg-0xf1000814 */
  59156. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xC4000540 /* offset 0x1404 - DMA reg-0xf100081c */
  59157. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x01602220 /* offset 0x1408 - DMA reg-0xf1000824 */
  59158. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x0000000b /* offset 0x140c - DMA reg-0xf1000828 */
  59159. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000012 /* offset 0x1410 - DMA reg-0xf1000820 */
  59160. +#define STATIC_SDRAM_MODE_REG 0x00000062 /* offset 0x141c - DMA reg-0xf1000818 */
  59161. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x0fff /* size bank0 dimm0 - DMA reg-0xf1000810 */
  59162. +#define STATIC_SDRAM_RANK0_SIZE_DIMM1 0x0 /* size bank0 dimm1 */
  59163. +
  59164. +#endif /* MV_MT9VDDT3272AG */
  59165. +
  59166. +
  59167. +
  59168. +#ifdef MV_D27RB12P
  59169. +/*
  59170. +Two DIMM 512M + ECC enabled, Registered DIMM CAS Latency 2.5
  59171. +*/
  59172. +
  59173. +#define STATIC_SDRAM_CONFIG_REG 0x6826081E /* offset 0x1400 - DMA reg-0xf1000814 */
  59174. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xC5000540 /* offset 0x1404 - DMA reg-0xf100081c */
  59175. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x01501220 /* offset 0x1408 - DMA reg-0xf1000824 */
  59176. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000009 /* offset 0x140c - DMA reg-0xf1000828 */
  59177. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000012 /* offset 0x1410 - DMA reg-0xf1000820 */
  59178. +#define STATIC_SDRAM_MODE_REG 0x00000062 /* offset 0x141c - DMA reg-0xf1000818 */
  59179. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x0FFF /* size bank0 dimm0 - DMA reg-0xf1000810 */
  59180. +#define STATIC_SDRAM_RANK0_SIZE_DIMM1 0x0FFF /* size bank0 dimm1 */
  59181. +
  59182. +#define STATIC_DRAM_BANK_2
  59183. +
  59184. +#define STATIC_DRAM_BANK_3
  59185. +#define STATIC_DRAM_BANK_4
  59186. +
  59187. +#endif /* mv_D27RB12P */
  59188. +
  59189. +#ifdef RD_MV645XX
  59190. +
  59191. +#define STATIC_MEM_TYPE MEM_TYPE_DDR2
  59192. +#define STATIC_DIMM_INFO_BANK0_SIZE 256
  59193. +/* DDR2 boards 256 MB*/
  59194. +
  59195. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x00000fff /* size bank0 dimm0 - DMA reg-0xf1000810 */
  59196. +#define STATIC_SDRAM_CONFIG_REG 0x07190618
  59197. +#define STATIC_SDRAM_MODE_REG 0x00000432
  59198. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xf4a03440
  59199. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000022
  59200. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x11712220
  59201. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000504
  59202. +#define STATIC_SDRAM_ODT_CTRL_LOW 0x84210000
  59203. +#define STATIC_SDRAM_ODT_CTRL_HI 0x00000000
  59204. +#define STATIC_SDRAM_DUNIT_ODT_CTRL 0x0000780f
  59205. +#define STATIC_SDRAM_EXT_MODE 0x00000440
  59206. +#define STATIC_SDRAM_DDR2_TIMING_LO 0x00063300
  59207. +#define STATIC_SDRAM_DDR2_TIMING_HI 0x00006330
  59208. +#endif /* RD_MV645XX */
  59209. +
  59210. +#if MV_DIMM_M3783354CZ3_CE6
  59211. +
  59212. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x00000FFF /* 0x2010 size bank0 dimm0 - DMA reg-0xf1000810 */
  59213. +#define STATIC_SDRAM_CONFIG_REG 0x07190618 /* 0x1400 */
  59214. +#define STATIC_SDRAM_MODE_REG 0x00000432 /* 0x141c */
  59215. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xf4a03440 /* 0x1404 */
  59216. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000022 /* 0x1410 */
  59217. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x11712220 /* 0x1408 */
  59218. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000504 /* 0x140c */
  59219. +#define STATIC_SDRAM_ODT_CTRL_LOW 0x84210000 /* 0x1494 */
  59220. +#define STATIC_SDRAM_ODT_CTRL_HI 0x00000000 /* 0x1498 */
  59221. +#define STATIC_SDRAM_DUNIT_ODT_CTRL 0x0000780f /* 0x149c */
  59222. +#define STATIC_SDRAM_EXT_MODE 0x00000440 /* 0x1420 */
  59223. +#define STATIC_SDRAM_DDR2_TIMING_LO 0x00063300 /* 0x1428 */
  59224. +#define STATIC_SDRAM_DDR2_TIMING_HI 0x00006330 /* 0x147C */
  59225. +
  59226. +#endif /* MV_DIMM_M3783354CZ3_CE6 */
  59227. +
  59228. +#endif /* MV_STATIC_DRAM_ON_BOARD */
  59229. +#endif /* __INCmvDramIfStaticInith */
  59230. +
  59231. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c
  59232. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c 1970-01-01 01:00:00.000000000 +0100
  59233. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c 2010-08-05 22:02:24.474867944 +0200
  59234. @@ -0,0 +1,1474 @@
  59235. +/*******************************************************************************
  59236. +Copyright (C) Marvell International Ltd. and its affiliates
  59237. +
  59238. +This software file (the "File") is owned and distributed by Marvell
  59239. +International Ltd. and/or its affiliates ("Marvell") under the following
  59240. +alternative licensing terms. Once you have made an election to distribute the
  59241. +File under one of the following license alternatives, please (i) delete this
  59242. +introductory statement regarding license alternatives, (ii) delete the two
  59243. +license alternatives that you have not elected to use and (iii) preserve the
  59244. +Marvell copyright notice above.
  59245. +
  59246. +********************************************************************************
  59247. +Marvell Commercial License Option
  59248. +
  59249. +If you received this File from Marvell and you have entered into a commercial
  59250. +license agreement (a "Commercial License") with Marvell, the File is licensed
  59251. +to you under the terms of the applicable Commercial License.
  59252. +
  59253. +********************************************************************************
  59254. +Marvell GPL License Option
  59255. +
  59256. +If you received this File from Marvell, you may opt to use, redistribute and/or
  59257. +modify this File in accordance with the terms and conditions of the General
  59258. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  59259. +available along with the File in the license.txt file or by writing to the Free
  59260. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  59261. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  59262. +
  59263. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  59264. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  59265. +DISCLAIMED. The GPL License provides additional details about this warranty
  59266. +disclaimer.
  59267. +********************************************************************************
  59268. +Marvell BSD License Option
  59269. +
  59270. +If you received this File from Marvell, you may opt to use, redistribute and/or
  59271. +modify this File under the following licensing terms.
  59272. +Redistribution and use in source and binary forms, with or without modification,
  59273. +are permitted provided that the following conditions are met:
  59274. +
  59275. + * Redistributions of source code must retain the above copyright notice,
  59276. + this list of conditions and the following disclaimer.
  59277. +
  59278. + * Redistributions in binary form must reproduce the above copyright
  59279. + notice, this list of conditions and the following disclaimer in the
  59280. + documentation and/or other materials provided with the distribution.
  59281. +
  59282. + * Neither the name of Marvell nor the names of its contributors may be
  59283. + used to endorse or promote products derived from this software without
  59284. + specific prior written permission.
  59285. +
  59286. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  59287. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  59288. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  59289. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  59290. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  59291. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  59292. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  59293. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  59294. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  59295. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  59296. +
  59297. +*******************************************************************************/
  59298. +
  59299. +#include "ddr2/spd/mvSpd.h"
  59300. +#include "boardEnv/mvBoardEnvLib.h"
  59301. +
  59302. +/* #define MV_DEBUG */
  59303. +#ifdef MV_DEBUG
  59304. +#define DB(x) x
  59305. +#else
  59306. +#define DB(x)
  59307. +#endif
  59308. +
  59309. +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
  59310. + MV_DRAM_BANK_INFO *pBankInfo);
  59311. +static MV_U32 cas2ps(MV_U8 spd_byte);
  59312. +/*******************************************************************************
  59313. +* mvDramBankGet - Get the DRAM bank paramters.
  59314. +*
  59315. +* DESCRIPTION:
  59316. +* This function retrieves DRAM bank parameters as described in
  59317. +* DRAM_BANK_INFO struct to the controller DRAM unit. In case the board
  59318. +* has its DRAM on DIMMs it will use its EEPROM to extract SPD data
  59319. +* from it. Otherwise, if the DRAM is soldered on board, the function
  59320. +* should insert its bank information into MV_DRAM_BANK_INFO struct.
  59321. +*
  59322. +* INPUT:
  59323. +* bankNum - Board DRAM bank number.
  59324. +*
  59325. +* OUTPUT:
  59326. +* pBankInfo - DRAM bank information struct.
  59327. +*
  59328. +* RETURN:
  59329. +* MV_FAIL - Bank parameters could not be read.
  59330. +*
  59331. +*******************************************************************************/
  59332. +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo)
  59333. +{
  59334. + MV_DIMM_INFO dimmInfo;
  59335. +
  59336. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bank %d\n", bankNum));
  59337. + /* zero pBankInfo structure */
  59338. +
  59339. + if((NULL == pBankInfo) || (bankNum >= MV_DRAM_MAX_CS ))
  59340. + {
  59341. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
  59342. + return MV_BAD_PARAM;
  59343. + }
  59344. + memset(pBankInfo, 0, sizeof(*pBankInfo));
  59345. +
  59346. + if ( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
  59347. + {
  59348. + DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
  59349. + return MV_FAIL;
  59350. + }
  59351. + if ((dimmInfo.numOfModuleBanks == 1) && ((bankNum % 2) == 1))
  59352. + {
  59353. + DB(mvOsPrintf("Dram: ERR dimmSpdGet. Can't find DIMM bank 2 \n"));
  59354. + return MV_FAIL;
  59355. + }
  59356. + /* convert Dimm info to Bank info */
  59357. + cpyDimm2BankInfo(&dimmInfo, pBankInfo);
  59358. + return MV_OK;
  59359. +}
  59360. +
  59361. +/*******************************************************************************
  59362. +* cpyDimm2BankInfo - Convert a Dimm info struct into a bank info struct.
  59363. +*
  59364. +* DESCRIPTION:
  59365. +* Convert a Dimm info struct into a bank info struct.
  59366. +*
  59367. +* INPUT:
  59368. +* pDimmInfo - DIMM information structure.
  59369. +*
  59370. +* OUTPUT:
  59371. +* pBankInfo - DRAM bank information struct.
  59372. +*
  59373. +* RETURN:
  59374. +* None.
  59375. +*
  59376. +*******************************************************************************/
  59377. +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
  59378. + MV_DRAM_BANK_INFO *pBankInfo)
  59379. +{
  59380. + pBankInfo->memoryType = pDimmInfo->memoryType;
  59381. +
  59382. + /* DIMM dimensions */
  59383. + pBankInfo->numOfRowAddr = pDimmInfo->numOfRowAddr;
  59384. + pBankInfo->numOfColAddr = pDimmInfo->numOfColAddr;
  59385. + pBankInfo->dataWidth = pDimmInfo->dataWidth;
  59386. + pBankInfo->errorCheckType = pDimmInfo->errorCheckType;
  59387. + pBankInfo->sdramWidth = pDimmInfo->sdramWidth;
  59388. + pBankInfo->errorCheckDataWidth = pDimmInfo->errorCheckDataWidth;
  59389. + pBankInfo->numOfBanksOnEachDevice = pDimmInfo->numOfBanksOnEachDevice;
  59390. + pBankInfo->suportedCasLatencies = pDimmInfo->suportedCasLatencies;
  59391. + pBankInfo->refreshInterval = pDimmInfo->refreshInterval;
  59392. +
  59393. + /* DIMM timing parameters */
  59394. + pBankInfo->minCycleTimeAtMaxCasLatPs = pDimmInfo->minCycleTimeAtMaxCasLatPs;
  59395. + pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps =
  59396. + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps;
  59397. + pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps =
  59398. + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps;
  59399. +
  59400. + pBankInfo->minRowPrechargeTime = pDimmInfo->minRowPrechargeTime;
  59401. + pBankInfo->minRowActiveToRowActive = pDimmInfo->minRowActiveToRowActive;
  59402. + pBankInfo->minRasToCasDelay = pDimmInfo->minRasToCasDelay;
  59403. + pBankInfo->minRasPulseWidth = pDimmInfo->minRasPulseWidth;
  59404. + pBankInfo->minWriteRecoveryTime = pDimmInfo->minWriteRecoveryTime;
  59405. + pBankInfo->minWriteToReadCmdDelay = pDimmInfo->minWriteToReadCmdDelay;
  59406. + pBankInfo->minReadToPrechCmdDelay = pDimmInfo->minReadToPrechCmdDelay;
  59407. + pBankInfo->minRefreshToActiveCmd = pDimmInfo->minRefreshToActiveCmd;
  59408. +
  59409. + /* Parameters calculated from the extracted DIMM information */
  59410. + pBankInfo->size = pDimmInfo->size/pDimmInfo->numOfModuleBanks;
  59411. + pBankInfo->deviceDensity = pDimmInfo->deviceDensity;
  59412. + pBankInfo->numberOfDevices = pDimmInfo->numberOfDevices /
  59413. + pDimmInfo->numOfModuleBanks;
  59414. +
  59415. + /* DIMM attributes (MV_TRUE for yes) */
  59416. +
  59417. + if ((pDimmInfo->memoryType == MEM_TYPE_SDRAM) ||
  59418. + (pDimmInfo->memoryType == MEM_TYPE_DDR1) )
  59419. + {
  59420. + if (pDimmInfo->dimmAttributes & BIT1)
  59421. + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
  59422. + else
  59423. + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
  59424. + }
  59425. + else /* pDimmInfo->memoryType == MEM_TYPE_DDR2 */
  59426. + {
  59427. + if (pDimmInfo->dimmTypeInfo & (BIT0 | BIT4))
  59428. + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
  59429. + else
  59430. + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
  59431. + }
  59432. +
  59433. + return;
  59434. +}
  59435. +/*******************************************************************************
  59436. +* dimmSpdCpy - Cpy SPD parameters from dimm 0 to dimm 1.
  59437. +*
  59438. +* DESCRIPTION:
  59439. +* Read the DIMM SPD parameters from dimm 0 into dimm 1 SPD.
  59440. +*
  59441. +* INPUT:
  59442. +* None.
  59443. +*
  59444. +* OUTPUT:
  59445. +* None.
  59446. +*
  59447. +* RETURN:
  59448. +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
  59449. +*
  59450. +*******************************************************************************/
  59451. +MV_STATUS dimmSpdCpy(MV_VOID)
  59452. +{
  59453. + MV_U32 i;
  59454. + MV_U32 spdChecksum;
  59455. +
  59456. + MV_TWSI_SLAVE twsiSlave;
  59457. + MV_U8 data[SPD_SIZE];
  59458. +
  59459. + /* zero dimmInfo structure */
  59460. + memset(data, 0, SPD_SIZE);
  59461. +
  59462. + /* read the dimm eeprom */
  59463. + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
  59464. + twsiSlave.slaveAddr.address = MV_BOARD_DIMM0_I2C_ADDR;
  59465. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  59466. + twsiSlave.validOffset = MV_TRUE;
  59467. + twsiSlave.offset = 0;
  59468. + twsiSlave.moreThen256 = MV_FALSE;
  59469. +
  59470. + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, data, SPD_SIZE) )
  59471. + {
  59472. + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 0\n"));
  59473. + return MV_FAIL;
  59474. + }
  59475. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  59476. +
  59477. + /* calculate SPD checksum */
  59478. + spdChecksum = 0;
  59479. +
  59480. + for(i = 0 ; i <= 62 ; i++)
  59481. + {
  59482. + spdChecksum += data[i];
  59483. + }
  59484. +
  59485. + if ((spdChecksum & 0xff) != data[63])
  59486. + {
  59487. + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
  59488. + (MV_U32)(spdChecksum & 0xff), data[63]));
  59489. + }
  59490. + else
  59491. + {
  59492. + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
  59493. + }
  59494. +
  59495. + /* copy the SPD content 1:1 into the DIMM 1 SPD */
  59496. + twsiSlave.slaveAddr.address = MV_BOARD_DIMM1_I2C_ADDR;
  59497. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  59498. + twsiSlave.validOffset = MV_TRUE;
  59499. + twsiSlave.offset = 0;
  59500. + twsiSlave.moreThen256 = MV_FALSE;
  59501. +
  59502. + for(i = 0 ; i < SPD_SIZE ; i++)
  59503. + {
  59504. + twsiSlave.offset = i;
  59505. + if( MV_OK != mvTwsiWrite (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, &data[i], 1) )
  59506. + {
  59507. + mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 1 byte %d \n",i);
  59508. + return MV_FAIL;
  59509. + }
  59510. + mvOsDelay(5);
  59511. + }
  59512. +
  59513. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  59514. + return MV_OK;
  59515. +}
  59516. +
  59517. +/*******************************************************************************
  59518. +* dimmSpdGet - Get the SPD parameters.
  59519. +*
  59520. +* DESCRIPTION:
  59521. +* Read the DIMM SPD parameters into given struct parameter.
  59522. +*
  59523. +* INPUT:
  59524. +* dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
  59525. +*
  59526. +* OUTPUT:
  59527. +* pDimmInfo - DIMM information structure.
  59528. +*
  59529. +* RETURN:
  59530. +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
  59531. +*
  59532. +*******************************************************************************/
  59533. +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo)
  59534. +{
  59535. + MV_U32 i;
  59536. + MV_U32 density = 1;
  59537. + MV_U32 spdChecksum;
  59538. +
  59539. + MV_TWSI_SLAVE twsiSlave;
  59540. + MV_U8 data[SPD_SIZE];
  59541. +
  59542. + if((NULL == pDimmInfo)|| (dimmNum >= MAX_DIMM_NUM))
  59543. + {
  59544. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
  59545. + return MV_BAD_PARAM;
  59546. + }
  59547. +
  59548. + /* zero dimmInfo structure */
  59549. + memset(data, 0, SPD_SIZE);
  59550. +
  59551. + /* read the dimm eeprom */
  59552. + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
  59553. + twsiSlave.slaveAddr.address = (dimmNum == 0) ?
  59554. + MV_BOARD_DIMM0_I2C_ADDR : MV_BOARD_DIMM1_I2C_ADDR;
  59555. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  59556. + twsiSlave.validOffset = MV_TRUE;
  59557. + twsiSlave.offset = 0;
  59558. + twsiSlave.moreThen256 = MV_FALSE;
  59559. +
  59560. + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, data, SPD_SIZE) )
  59561. + {
  59562. + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum %d \n", dimmNum));
  59563. + return MV_FAIL;
  59564. + }
  59565. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  59566. +
  59567. + /* calculate SPD checksum */
  59568. + spdChecksum = 0;
  59569. +
  59570. + for(i = 0 ; i <= 62 ; i++)
  59571. + {
  59572. + spdChecksum += data[i];
  59573. + }
  59574. +
  59575. + if ((spdChecksum & 0xff) != data[63])
  59576. + {
  59577. + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
  59578. + (MV_U32)(spdChecksum & 0xff), data[63]));
  59579. + }
  59580. + else
  59581. + {
  59582. + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
  59583. + }
  59584. +
  59585. + /* copy the SPD content 1:1 into the dimmInfo structure*/
  59586. + for(i = 0 ; i < SPD_SIZE ; i++)
  59587. + {
  59588. + pDimmInfo->spdRawData[i] = data[i];
  59589. + DB(mvOsPrintf("SPD-EEPROM Byte %3d = %3x (%3d)\n",i, data[i], data[i]));
  59590. + }
  59591. +
  59592. + DB(mvOsPrintf("DRAM SPD Information:\n"));
  59593. +
  59594. + /* Memory type (DDR / SDRAM) */
  59595. + switch (data[DIMM_MEM_TYPE])
  59596. + {
  59597. + case (DIMM_MEM_TYPE_SDRAM):
  59598. + pDimmInfo->memoryType = MEM_TYPE_SDRAM;
  59599. + DB(mvOsPrintf("DRAM Memeory type SDRAM\n"));
  59600. + break;
  59601. + case (DIMM_MEM_TYPE_DDR1):
  59602. + pDimmInfo->memoryType = MEM_TYPE_DDR1;
  59603. + DB(mvOsPrintf("DRAM Memeory type DDR1\n"));
  59604. + break;
  59605. + case (DIMM_MEM_TYPE_DDR2):
  59606. + pDimmInfo->memoryType = MEM_TYPE_DDR2;
  59607. + DB(mvOsPrintf("DRAM Memeory type DDR2\n"));
  59608. + break;
  59609. + default:
  59610. + mvOsPrintf("ERROR: Undefined memory type!\n");
  59611. + return MV_ERROR;
  59612. + }
  59613. +
  59614. +
  59615. + /* Number Of Row Addresses */
  59616. + pDimmInfo->numOfRowAddr = data[DIMM_ROW_NUM];
  59617. + DB(mvOsPrintf("DRAM numOfRowAddr[3] %d\n",pDimmInfo->numOfRowAddr));
  59618. +
  59619. + /* Number Of Column Addresses */
  59620. + pDimmInfo->numOfColAddr = data[DIMM_COL_NUM];
  59621. + DB(mvOsPrintf("DRAM numOfColAddr[4] %d\n",pDimmInfo->numOfColAddr));
  59622. +
  59623. + /* Number Of Module Banks */
  59624. + pDimmInfo->numOfModuleBanks = data[DIMM_MODULE_BANK_NUM];
  59625. + DB(mvOsPrintf("DRAM numOfModuleBanks[5] 0x%x\n",
  59626. + pDimmInfo->numOfModuleBanks));
  59627. +
  59628. + /* Number of module banks encoded differently for DDR2 */
  59629. + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
  59630. + pDimmInfo->numOfModuleBanks = (pDimmInfo->numOfModuleBanks & 0x7)+1;
  59631. +
  59632. + /* Data Width */
  59633. + pDimmInfo->dataWidth = data[DIMM_DATA_WIDTH];
  59634. + DB(mvOsPrintf("DRAM dataWidth[6] 0x%x\n", pDimmInfo->dataWidth));
  59635. +
  59636. + /* Minimum Cycle Time At Max CasLatancy */
  59637. + pDimmInfo->minCycleTimeAtMaxCasLatPs = cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS]);
  59638. +
  59639. + /* Error Check Type */
  59640. + pDimmInfo->errorCheckType = data[DIMM_ERR_CHECK_TYPE];
  59641. + DB(mvOsPrintf("DRAM errorCheckType[11] 0x%x\n",
  59642. + pDimmInfo->errorCheckType));
  59643. +
  59644. + /* Refresh Interval */
  59645. + pDimmInfo->refreshInterval = data[DIMM_REFRESH_INTERVAL];
  59646. + DB(mvOsPrintf("DRAM refreshInterval[12] 0x%x\n",
  59647. + pDimmInfo->refreshInterval));
  59648. +
  59649. + /* Sdram Width */
  59650. + pDimmInfo->sdramWidth = data[DIMM_SDRAM_WIDTH];
  59651. + DB(mvOsPrintf("DRAM sdramWidth[13] 0x%x\n",pDimmInfo->sdramWidth));
  59652. +
  59653. + /* Error Check Data Width */
  59654. + pDimmInfo->errorCheckDataWidth = data[DIMM_ERR_CHECK_DATA_WIDTH];
  59655. + DB(mvOsPrintf("DRAM errorCheckDataWidth[14] 0x%x\n",
  59656. + pDimmInfo->errorCheckDataWidth));
  59657. +
  59658. + /* Burst Length Supported */
  59659. + /* SDRAM/DDR1:
  59660. + *******-******-******-******-******-******-******-*******
  59661. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  59662. + *******-******-******-******-******-******-******-*******
  59663. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
  59664. + *********************************************************/
  59665. + /* DDR2:
  59666. + *******-******-******-******-******-******-******-*******
  59667. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  59668. + *******-******-******-******-******-******-******-*******
  59669. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
  59670. + *********************************************************/
  59671. +
  59672. + pDimmInfo->burstLengthSupported = data[DIMM_BURST_LEN_SUP];
  59673. + DB(mvOsPrintf("DRAM burstLengthSupported[16] 0x%x\n",
  59674. + pDimmInfo->burstLengthSupported));
  59675. +
  59676. + /* Number Of Banks On Each Device */
  59677. + pDimmInfo->numOfBanksOnEachDevice = data[DIMM_DEV_BANK_NUM];
  59678. + DB(mvOsPrintf("DRAM numOfBanksOnEachDevice[17] 0x%x\n",
  59679. + pDimmInfo->numOfBanksOnEachDevice));
  59680. +
  59681. + /* Suported Cas Latencies */
  59682. +
  59683. + /* SDRAM:
  59684. + *******-******-******-******-******-******-******-*******
  59685. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  59686. + *******-******-******-******-******-******-******-*******
  59687. + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
  59688. + ********************************************************/
  59689. +
  59690. + /* DDR 1:
  59691. + *******-******-******-******-******-******-******-*******
  59692. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  59693. + *******-******-******-******-******-******-******-*******
  59694. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  59695. + *********************************************************/
  59696. +
  59697. + /* DDR 2:
  59698. + *******-******-******-******-******-******-******-*******
  59699. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  59700. + *******-******-******-******-******-******-******-*******
  59701. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  59702. + *********************************************************/
  59703. +
  59704. + pDimmInfo->suportedCasLatencies = data[DIMM_SUP_CAL];
  59705. + DB(mvOsPrintf("DRAM suportedCasLatencies[18] 0x%x\n",
  59706. + pDimmInfo->suportedCasLatencies));
  59707. +
  59708. + /* For DDR2 only, get the DIMM type information */
  59709. + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
  59710. + {
  59711. + pDimmInfo->dimmTypeInfo = data[DIMM_DDR2_TYPE_INFORMATION];
  59712. + DB(mvOsPrintf("DRAM dimmTypeInfo[20] (DDR2) 0x%x\n",
  59713. + pDimmInfo->dimmTypeInfo));
  59714. + }
  59715. +
  59716. + /* SDRAM Modules Attributes */
  59717. + pDimmInfo->dimmAttributes = data[DIMM_BUF_ADDR_CONT_IN];
  59718. + DB(mvOsPrintf("DRAM dimmAttributes[21] 0x%x\n",
  59719. + pDimmInfo->dimmAttributes));
  59720. +
  59721. + /* Minimum Cycle Time At Max CasLatancy Minus 1*/
  59722. + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps =
  59723. + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS1]);
  59724. +
  59725. + /* Minimum Cycle Time At Max CasLatancy Minus 2*/
  59726. + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps =
  59727. + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS2]);
  59728. +
  59729. + pDimmInfo->minRowPrechargeTime = data[DIMM_MIN_ROW_PRECHARGE_TIME];
  59730. + DB(mvOsPrintf("DRAM minRowPrechargeTime[27] 0x%x\n",
  59731. + pDimmInfo->minRowPrechargeTime));
  59732. + pDimmInfo->minRowActiveToRowActive = data[DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE];
  59733. + DB(mvOsPrintf("DRAM minRowActiveToRowActive[28] 0x%x\n",
  59734. + pDimmInfo->minRowActiveToRowActive));
  59735. + pDimmInfo->minRasToCasDelay = data[DIMM_MIN_RAS_TO_CAS_DELAY];
  59736. + DB(mvOsPrintf("DRAM minRasToCasDelay[29] 0x%x\n",
  59737. + pDimmInfo->minRasToCasDelay));
  59738. + pDimmInfo->minRasPulseWidth = data[DIMM_MIN_RAS_PULSE_WIDTH];
  59739. + DB(mvOsPrintf("DRAM minRasPulseWidth[30] 0x%x\n",
  59740. + pDimmInfo->minRasPulseWidth));
  59741. +
  59742. + /* DIMM Bank Density */
  59743. + pDimmInfo->dimmBankDensity = data[DIMM_BANK_DENSITY];
  59744. + DB(mvOsPrintf("DRAM dimmBankDensity[31] 0x%x\n",
  59745. + pDimmInfo->dimmBankDensity));
  59746. +
  59747. + /* Only DDR2 includes Write Recovery Time field. Other SDRAM ignore */
  59748. + pDimmInfo->minWriteRecoveryTime = data[DIMM_MIN_WRITE_RECOVERY_TIME];
  59749. + DB(mvOsPrintf("DRAM minWriteRecoveryTime[36] 0x%x\n",
  59750. + pDimmInfo->minWriteRecoveryTime));
  59751. +
  59752. + /* Only DDR2 includes Internal Write To Read Command Delay field. */
  59753. + pDimmInfo->minWriteToReadCmdDelay = data[DIMM_MIN_WRITE_TO_READ_CMD_DELAY];
  59754. + DB(mvOsPrintf("DRAM minWriteToReadCmdDelay[37] 0x%x\n",
  59755. + pDimmInfo->minWriteToReadCmdDelay));
  59756. +
  59757. + /* Only DDR2 includes Internal Read To Precharge Command Delay field. */
  59758. + pDimmInfo->minReadToPrechCmdDelay = data[DIMM_MIN_READ_TO_PRECH_CMD_DELAY];
  59759. + DB(mvOsPrintf("DRAM minReadToPrechCmdDelay[38] 0x%x\n",
  59760. + pDimmInfo->minReadToPrechCmdDelay));
  59761. +
  59762. + /* Only DDR2 includes Minimum Refresh to Activate/Refresh Command field */
  59763. + pDimmInfo->minRefreshToActiveCmd = data[DIMM_MIN_REFRESH_TO_ACTIVATE_CMD];
  59764. + DB(mvOsPrintf("DRAM minRefreshToActiveCmd[42] 0x%x\n",
  59765. + pDimmInfo->minRefreshToActiveCmd));
  59766. +
  59767. + /* calculating the sdram density. Representing device density from */
  59768. + /* bit 20 to allow representation of 4GB and above. */
  59769. + /* For example, if density is 512Mbit 0x20000000, will be represent in */
  59770. + /* deviceDensity by 0x20000000 >> 16 --> 0x00000200. Another example */
  59771. + /* is density 8GB 0x200000000 >> 16 --> 0x00002000. */
  59772. + density = (1 << ((pDimmInfo->numOfRowAddr + pDimmInfo->numOfColAddr) - 20));
  59773. + pDimmInfo->deviceDensity = density *
  59774. + pDimmInfo->numOfBanksOnEachDevice *
  59775. + pDimmInfo->sdramWidth;
  59776. + DB(mvOsPrintf("DRAM deviceDensity %d\n",pDimmInfo->deviceDensity));
  59777. +
  59778. + /* Number of devices includeing Error correction */
  59779. + pDimmInfo->numberOfDevices = (pDimmInfo->dataWidth/pDimmInfo->sdramWidth) *
  59780. + pDimmInfo->numOfModuleBanks;
  59781. + DB(mvOsPrintf("DRAM numberOfDevices %d\n",
  59782. + pDimmInfo->numberOfDevices));
  59783. +
  59784. + pDimmInfo->size = 0;
  59785. +
  59786. + /* Note that pDimmInfo->size is in MB units */
  59787. + if (pDimmInfo->memoryType == MEM_TYPE_SDRAM)
  59788. + {
  59789. + if (pDimmInfo->dimmBankDensity & BIT0)
  59790. + pDimmInfo->size += 1024; /* Equal to 1GB */
  59791. + else if (pDimmInfo->dimmBankDensity & BIT1)
  59792. + pDimmInfo->size += 8; /* Equal to 8MB */
  59793. + else if (pDimmInfo->dimmBankDensity & BIT2)
  59794. + pDimmInfo->size += 16; /* Equal to 16MB */
  59795. + else if (pDimmInfo->dimmBankDensity & BIT3)
  59796. + pDimmInfo->size += 32; /* Equal to 32MB */
  59797. + else if (pDimmInfo->dimmBankDensity & BIT4)
  59798. + pDimmInfo->size += 64; /* Equal to 64MB */
  59799. + else if (pDimmInfo->dimmBankDensity & BIT5)
  59800. + pDimmInfo->size += 128; /* Equal to 128MB */
  59801. + else if (pDimmInfo->dimmBankDensity & BIT6)
  59802. + pDimmInfo->size += 256; /* Equal to 256MB */
  59803. + else if (pDimmInfo->dimmBankDensity & BIT7)
  59804. + pDimmInfo->size += 512; /* Equal to 512MB */
  59805. + }
  59806. + else if (pDimmInfo->memoryType == MEM_TYPE_DDR1)
  59807. + {
  59808. + if (pDimmInfo->dimmBankDensity & BIT0)
  59809. + pDimmInfo->size += 1024; /* Equal to 1GB */
  59810. + else if (pDimmInfo->dimmBankDensity & BIT1)
  59811. + pDimmInfo->size += 2048; /* Equal to 2GB */
  59812. + else if (pDimmInfo->dimmBankDensity & BIT2)
  59813. + pDimmInfo->size += 16; /* Equal to 16MB */
  59814. + else if (pDimmInfo->dimmBankDensity & BIT3)
  59815. + pDimmInfo->size += 32; /* Equal to 32MB */
  59816. + else if (pDimmInfo->dimmBankDensity & BIT4)
  59817. + pDimmInfo->size += 64; /* Equal to 64MB */
  59818. + else if (pDimmInfo->dimmBankDensity & BIT5)
  59819. + pDimmInfo->size += 128; /* Equal to 128MB */
  59820. + else if (pDimmInfo->dimmBankDensity & BIT6)
  59821. + pDimmInfo->size += 256; /* Equal to 256MB */
  59822. + else if (pDimmInfo->dimmBankDensity & BIT7)
  59823. + pDimmInfo->size += 512; /* Equal to 512MB */
  59824. + }
  59825. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  59826. + {
  59827. + if (pDimmInfo->dimmBankDensity & BIT0)
  59828. + pDimmInfo->size += 1024; /* Equal to 1GB */
  59829. + else if (pDimmInfo->dimmBankDensity & BIT1)
  59830. + pDimmInfo->size += 2048; /* Equal to 2GB */
  59831. + else if (pDimmInfo->dimmBankDensity & BIT2)
  59832. + pDimmInfo->size += 4096; /* Equal to 4GB */
  59833. + else if (pDimmInfo->dimmBankDensity & BIT3)
  59834. + pDimmInfo->size += 8192; /* Equal to 8GB */
  59835. + else if (pDimmInfo->dimmBankDensity & BIT4)
  59836. + pDimmInfo->size += 16384; /* Equal to 16GB */
  59837. + else if (pDimmInfo->dimmBankDensity & BIT5)
  59838. + pDimmInfo->size += 128; /* Equal to 128MB */
  59839. + else if (pDimmInfo->dimmBankDensity & BIT6)
  59840. + pDimmInfo->size += 256; /* Equal to 256MB */
  59841. + else if (pDimmInfo->dimmBankDensity & BIT7)
  59842. + pDimmInfo->size += 512; /* Equal to 512MB */
  59843. + }
  59844. +
  59845. + pDimmInfo->size *= pDimmInfo->numOfModuleBanks;
  59846. +
  59847. + DB(mvOsPrintf("Dram: dimm size %dMB \n",pDimmInfo->size));
  59848. +
  59849. + return MV_OK;
  59850. +}
  59851. +
  59852. +/*******************************************************************************
  59853. +* dimmSpdPrint - Print the SPD parameters.
  59854. +*
  59855. +* DESCRIPTION:
  59856. +* Print the Dimm SPD parameters.
  59857. +*
  59858. +* INPUT:
  59859. +* pDimmInfo - DIMM information structure.
  59860. +*
  59861. +* OUTPUT:
  59862. +* None.
  59863. +*
  59864. +* RETURN:
  59865. +* None.
  59866. +*
  59867. +*******************************************************************************/
  59868. +MV_VOID dimmSpdPrint(MV_U32 dimmNum)
  59869. +{
  59870. + MV_DIMM_INFO dimmInfo;
  59871. + MV_U32 i, temp = 0;
  59872. + MV_U32 k, maskLeftOfPoint = 0, maskRightOfPoint = 0;
  59873. + MV_U32 rightOfPoint = 0,leftOfPoint = 0, div, time_tmp, shift;
  59874. + MV_U32 busClkPs;
  59875. + MV_U8 trp_clocks=0, trcd_clocks, tras_clocks, trrd_clocks,
  59876. + temp_buf[40], *spdRawData;
  59877. +
  59878. + busClkPs = 1000000000 / (mvBoardSysClkGet() / 100); /* in 10 ps units */
  59879. +
  59880. + spdRawData = dimmInfo.spdRawData;
  59881. +
  59882. + if(MV_OK != dimmSpdGet(dimmNum, &dimmInfo))
  59883. + {
  59884. + mvOsOutput("ERROR: Could not read SPD information!\n");
  59885. + return;
  59886. + }
  59887. +
  59888. + /* find Manufactura of Dimm Module */
  59889. + mvOsOutput("\nManufacturer's JEDEC ID Code: ");
  59890. + for(i = 0 ; i < DIMM_MODULE_MANU_SIZE ; i++)
  59891. + {
  59892. + mvOsOutput("%x",spdRawData[DIMM_MODULE_MANU_OFFS + i]);
  59893. + }
  59894. + mvOsOutput("\n");
  59895. +
  59896. + /* Manufacturer's Specific Data */
  59897. + for(i = 0 ; i < DIMM_MODULE_ID_SIZE ; i++)
  59898. + {
  59899. + temp_buf[i] = spdRawData[DIMM_MODULE_ID_OFFS + i];
  59900. + }
  59901. + mvOsOutput("Manufacturer's Specific Data: %s\n", temp_buf);
  59902. +
  59903. + /* Module Part Number */
  59904. + for(i = 0 ; i < DIMM_MODULE_VEN_SIZE ; i++)
  59905. + {
  59906. + temp_buf[i] = spdRawData[DIMM_MODULE_VEN_OFFS + i];
  59907. + }
  59908. + mvOsOutput("Module Part Number: %s\n", temp_buf);
  59909. +
  59910. + /* Module Serial Number */
  59911. + for(i = 0; i < sizeof(MV_U32); i++)
  59912. + {
  59913. + temp |= spdRawData[95+i] << 8*i;
  59914. + }
  59915. + mvOsOutput("DIMM Serial No. %ld (%lx)\n", (long)temp,
  59916. + (long)temp);
  59917. +
  59918. + /* find Manufac-Data of Dimm Module */
  59919. + mvOsOutput("Manufactoring Date: Year 20%d%d/ ww %d%d\n",
  59920. + ((spdRawData[93] & 0xf0) >> 4), (spdRawData[93] & 0xf),
  59921. + ((spdRawData[94] & 0xf0) >> 4), (spdRawData[94] & 0xf));
  59922. + /* find modul_revision of Dimm Module */
  59923. + mvOsOutput("Module Revision: %d.%d\n",
  59924. + spdRawData[62]/10, spdRawData[62]%10);
  59925. +
  59926. + /* find manufac_place of Dimm Module */
  59927. + mvOsOutput("manufac_place: %d\n", spdRawData[72]);
  59928. +
  59929. + /* go over the first 35 I2C data bytes */
  59930. + for(i = 2 ; i <= 35 ; i++)
  59931. + switch(i)
  59932. + {
  59933. + case 2: /* Memory type (DDR1/2 / SDRAM) */
  59934. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  59935. + mvOsOutput("Dram Type is: SDRAM\n");
  59936. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  59937. + mvOsOutput("Dram Type is: SDRAM DDR1\n");
  59938. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  59939. + mvOsOutput("Dram Type is: SDRAM DDR2\n");
  59940. + else
  59941. + mvOsOutput("Dram Type unknown\n");
  59942. + break;
  59943. +/*----------------------------------------------------------------------------*/
  59944. +
  59945. + case 3: /* Number Of Row Addresses */
  59946. + mvOsOutput("Module Number of row addresses: %d\n",
  59947. + dimmInfo.numOfRowAddr);
  59948. + break;
  59949. +/*----------------------------------------------------------------------------*/
  59950. +
  59951. + case 4: /* Number Of Column Addresses */
  59952. + mvOsOutput("Module Number of col addresses: %d\n",
  59953. + dimmInfo.numOfColAddr);
  59954. + break;
  59955. +/*----------------------------------------------------------------------------*/
  59956. +
  59957. + case 5: /* Number Of Module Banks */
  59958. + mvOsOutput("Number of Banks on Mod.: %d\n",
  59959. + dimmInfo.numOfModuleBanks);
  59960. + break;
  59961. +/*----------------------------------------------------------------------------*/
  59962. +
  59963. + case 6: /* Data Width */
  59964. + mvOsOutput("Module Data Width: %d bit\n",
  59965. + dimmInfo.dataWidth);
  59966. + break;
  59967. +/*----------------------------------------------------------------------------*/
  59968. +
  59969. + case 8: /* Voltage Interface */
  59970. + switch(spdRawData[i])
  59971. + {
  59972. + case 0x0:
  59973. + mvOsOutput("Module is TTL_5V_TOLERANT\n");
  59974. + break;
  59975. + case 0x1:
  59976. + mvOsOutput("Module is LVTTL\n");
  59977. + break;
  59978. + case 0x2:
  59979. + mvOsOutput("Module is HSTL_1_5V\n");
  59980. + break;
  59981. + case 0x3:
  59982. + mvOsOutput("Module is SSTL_3_3V\n");
  59983. + break;
  59984. + case 0x4:
  59985. + mvOsOutput("Module is SSTL_2_5V\n");
  59986. + break;
  59987. + case 0x5:
  59988. + if (dimmInfo.memoryType != MEM_TYPE_SDRAM)
  59989. + {
  59990. + mvOsOutput("Module is SSTL_1_8V\n");
  59991. + break;
  59992. + }
  59993. + default:
  59994. + mvOsOutput("Module is VOLTAGE_UNKNOWN\n");
  59995. + break;
  59996. + }
  59997. + break;
  59998. +/*----------------------------------------------------------------------------*/
  59999. +
  60000. + case 9: /* Minimum Cycle Time At Max CasLatancy */
  60001. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  60002. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  60003. +
  60004. + /* DDR2 addition of right of point */
  60005. + if ((spdRawData[i] & 0x0f) == 0xA)
  60006. + {
  60007. + rightOfPoint = 25;
  60008. + }
  60009. + if ((spdRawData[i] & 0x0f) == 0xB)
  60010. + {
  60011. + rightOfPoint = 33;
  60012. + }
  60013. + if ((spdRawData[i] & 0x0f) == 0xC)
  60014. + {
  60015. + rightOfPoint = 66;
  60016. + }
  60017. + if ((spdRawData[i] & 0x0f) == 0xD)
  60018. + {
  60019. + rightOfPoint = 75;
  60020. + }
  60021. + mvOsOutput("Minimum Cycle Time At Max CL: %d.%d [ns]\n",
  60022. + leftOfPoint, rightOfPoint);
  60023. + break;
  60024. +/*----------------------------------------------------------------------------*/
  60025. +
  60026. + case 10: /* Clock To Data Out */
  60027. + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 10:100;
  60028. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  60029. + ((spdRawData[i] & 0x0f));
  60030. + leftOfPoint = time_tmp / div;
  60031. + rightOfPoint = time_tmp % div;
  60032. + mvOsOutput("Clock To Data Out: %d.%d [ns]\n",
  60033. + leftOfPoint, rightOfPoint);
  60034. + break;
  60035. +/*----------------------------------------------------------------------------*/
  60036. +
  60037. + case 11: /* Error Check Type */
  60038. + mvOsOutput("Error Check Type (0=NONE): %d\n",
  60039. + dimmInfo.errorCheckType);
  60040. + break;
  60041. +/*----------------------------------------------------------------------------*/
  60042. +
  60043. + case 12: /* Refresh Interval */
  60044. + mvOsOutput("Refresh Rate: %x\n",
  60045. + dimmInfo.refreshInterval);
  60046. + break;
  60047. +/*----------------------------------------------------------------------------*/
  60048. +
  60049. + case 13: /* Sdram Width */
  60050. + mvOsOutput("Sdram Width: %d bits\n",
  60051. + dimmInfo.sdramWidth);
  60052. + break;
  60053. +/*----------------------------------------------------------------------------*/
  60054. +
  60055. + case 14: /* Error Check Data Width */
  60056. + mvOsOutput("Error Check Data Width: %d bits\n",
  60057. + dimmInfo.errorCheckDataWidth);
  60058. + break;
  60059. +/*----------------------------------------------------------------------------*/
  60060. +
  60061. + case 15: /* Minimum Clock Delay is unsupported */
  60062. + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
  60063. + (dimmInfo.memoryType == MEM_TYPE_DDR1))
  60064. + {
  60065. + mvOsOutput("Minimum Clk Delay back to back: %d\n",
  60066. + spdRawData[i]);
  60067. + }
  60068. + break;
  60069. +/*----------------------------------------------------------------------------*/
  60070. +
  60071. + case 16: /* Burst Length Supported */
  60072. + /* SDRAM/DDR1:
  60073. + *******-******-******-******-******-******-******-*******
  60074. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  60075. + *******-******-******-******-******-******-******-*******
  60076. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
  60077. + *********************************************************/
  60078. + /* DDR2:
  60079. + *******-******-******-******-******-******-******-*******
  60080. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  60081. + *******-******-******-******-******-******-******-*******
  60082. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
  60083. + *********************************************************/
  60084. + mvOsOutput("Burst Length Supported: ");
  60085. + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
  60086. + (dimmInfo.memoryType == MEM_TYPE_DDR1))
  60087. + {
  60088. + if (dimmInfo.burstLengthSupported & BIT0)
  60089. + mvOsOutput("1, ");
  60090. + if (dimmInfo.burstLengthSupported & BIT1)
  60091. + mvOsOutput("2, ");
  60092. + }
  60093. + if (dimmInfo.burstLengthSupported & BIT2)
  60094. + mvOsOutput("4, ");
  60095. + if (dimmInfo.burstLengthSupported & BIT3)
  60096. + mvOsOutput("8, ");
  60097. +
  60098. + mvOsOutput(" Bit \n");
  60099. + break;
  60100. +/*----------------------------------------------------------------------------*/
  60101. +
  60102. + case 17: /* Number Of Banks On Each Device */
  60103. + mvOsOutput("Number Of Banks On Each Chip: %d\n",
  60104. + dimmInfo.numOfBanksOnEachDevice);
  60105. + break;
  60106. +/*----------------------------------------------------------------------------*/
  60107. +
  60108. + case 18: /* Suported Cas Latencies */
  60109. +
  60110. + /* SDRAM:
  60111. + *******-******-******-******-******-******-******-*******
  60112. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  60113. + *******-******-******-******-******-******-******-*******
  60114. + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
  60115. + ********************************************************/
  60116. +
  60117. + /* DDR 1:
  60118. + *******-******-******-******-******-******-******-*******
  60119. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  60120. + *******-******-******-******-******-******-******-*******
  60121. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  60122. + *********************************************************/
  60123. +
  60124. + /* DDR 2:
  60125. + *******-******-******-******-******-******-******-*******
  60126. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  60127. + *******-******-******-******-******-******-******-*******
  60128. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  60129. + *********************************************************/
  60130. +
  60131. + mvOsOutput("Suported Cas Latencies: (CL) ");
  60132. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60133. + {
  60134. + for (k = 0; k <=7; k++)
  60135. + {
  60136. + if (dimmInfo.suportedCasLatencies & (1 << k))
  60137. + mvOsOutput("%d, ", k+1);
  60138. + }
  60139. + }
  60140. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  60141. + {
  60142. + if (dimmInfo.suportedCasLatencies & BIT0)
  60143. + mvOsOutput("1, ");
  60144. + if (dimmInfo.suportedCasLatencies & BIT1)
  60145. + mvOsOutput("1.5, ");
  60146. + if (dimmInfo.suportedCasLatencies & BIT2)
  60147. + mvOsOutput("2, ");
  60148. + if (dimmInfo.suportedCasLatencies & BIT3)
  60149. + mvOsOutput("2.5, ");
  60150. + if (dimmInfo.suportedCasLatencies & BIT4)
  60151. + mvOsOutput("3, ");
  60152. + if (dimmInfo.suportedCasLatencies & BIT5)
  60153. + mvOsOutput("3.5, ");
  60154. + }
  60155. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  60156. + {
  60157. + if (dimmInfo.suportedCasLatencies & BIT2)
  60158. + mvOsOutput("2, ");
  60159. + if (dimmInfo.suportedCasLatencies & BIT3)
  60160. + mvOsOutput("3, ");
  60161. + if (dimmInfo.suportedCasLatencies & BIT4)
  60162. + mvOsOutput("4, ");
  60163. + if (dimmInfo.suportedCasLatencies & BIT5)
  60164. + mvOsOutput("5, ");
  60165. + }
  60166. + else
  60167. + mvOsOutput("?.?, ");
  60168. + mvOsOutput("\n");
  60169. + break;
  60170. +/*----------------------------------------------------------------------------*/
  60171. +
  60172. + case 20: /* DDR2 DIMM type info */
  60173. + if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  60174. + {
  60175. + if (dimmInfo.dimmTypeInfo & (BIT0 | BIT4))
  60176. + mvOsOutput("Registered DIMM (RDIMM)\n");
  60177. + else if (dimmInfo.dimmTypeInfo & (BIT1 | BIT5))
  60178. + mvOsOutput("Unbuffered DIMM (UDIMM)\n");
  60179. + else
  60180. + mvOsOutput("Unknown DIMM type.\n");
  60181. + }
  60182. +
  60183. + break;
  60184. +/*----------------------------------------------------------------------------*/
  60185. +
  60186. + case 21: /* SDRAM Modules Attributes */
  60187. + mvOsOutput("\nModule Attributes (SPD Byte 21): \n");
  60188. +
  60189. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60190. + {
  60191. + if (dimmInfo.dimmAttributes & BIT0)
  60192. + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
  60193. + else
  60194. + mvOsOutput(" Buffered Addr/Control Input: No\n");
  60195. +
  60196. + if (dimmInfo.dimmAttributes & BIT1)
  60197. + mvOsOutput(" Registered Addr/Control Input: Yes\n");
  60198. + else
  60199. + mvOsOutput(" Registered Addr/Control Input: No\n");
  60200. +
  60201. + if (dimmInfo.dimmAttributes & BIT2)
  60202. + mvOsOutput(" On-Card PLL (clock): Yes \n");
  60203. + else
  60204. + mvOsOutput(" On-Card PLL (clock): No \n");
  60205. +
  60206. + if (dimmInfo.dimmAttributes & BIT3)
  60207. + mvOsOutput(" Bufferd DQMB Input: Yes \n");
  60208. + else
  60209. + mvOsOutput(" Bufferd DQMB Inputs: No \n");
  60210. +
  60211. + if (dimmInfo.dimmAttributes & BIT4)
  60212. + mvOsOutput(" Registered DQMB Inputs: Yes \n");
  60213. + else
  60214. + mvOsOutput(" Registered DQMB Inputs: No \n");
  60215. +
  60216. + if (dimmInfo.dimmAttributes & BIT5)
  60217. + mvOsOutput(" Differential Clock Input: Yes \n");
  60218. + else
  60219. + mvOsOutput(" Differential Clock Input: No \n");
  60220. +
  60221. + if (dimmInfo.dimmAttributes & BIT6)
  60222. + mvOsOutput(" redundant Row Addressing: Yes \n");
  60223. + else
  60224. + mvOsOutput(" redundant Row Addressing: No \n");
  60225. + }
  60226. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  60227. + {
  60228. + if (dimmInfo.dimmAttributes & BIT0)
  60229. + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
  60230. + else
  60231. + mvOsOutput(" Buffered Addr/Control Input: No\n");
  60232. +
  60233. + if (dimmInfo.dimmAttributes & BIT1)
  60234. + mvOsOutput(" Registered Addr/Control Input: Yes\n");
  60235. + else
  60236. + mvOsOutput(" Registered Addr/Control Input: No\n");
  60237. +
  60238. + if (dimmInfo.dimmAttributes & BIT2)
  60239. + mvOsOutput(" On-Card PLL (clock): Yes \n");
  60240. + else
  60241. + mvOsOutput(" On-Card PLL (clock): No \n");
  60242. +
  60243. + if (dimmInfo.dimmAttributes & BIT3)
  60244. + mvOsOutput(" FET Switch On-Card Enabled: Yes \n");
  60245. + else
  60246. + mvOsOutput(" FET Switch On-Card Enabled: No \n");
  60247. +
  60248. + if (dimmInfo.dimmAttributes & BIT4)
  60249. + mvOsOutput(" FET Switch External Enabled: Yes \n");
  60250. + else
  60251. + mvOsOutput(" FET Switch External Enabled: No \n");
  60252. +
  60253. + if (dimmInfo.dimmAttributes & BIT5)
  60254. + mvOsOutput(" Differential Clock Input: Yes \n");
  60255. + else
  60256. + mvOsOutput(" Differential Clock Input: No \n");
  60257. + }
  60258. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  60259. + {
  60260. + mvOsOutput(" Number of Active Registers on the DIMM: %d\n",
  60261. + (dimmInfo.dimmAttributes & 0x3) + 1);
  60262. +
  60263. + mvOsOutput(" Number of PLLs on the DIMM: %d\n",
  60264. + ((dimmInfo.dimmAttributes) >> 2) & 0x3);
  60265. +
  60266. + if (dimmInfo.dimmAttributes & BIT4)
  60267. + mvOsOutput(" FET Switch External Enabled: Yes \n");
  60268. + else
  60269. + mvOsOutput(" FET Switch External Enabled: No \n");
  60270. +
  60271. + if (dimmInfo.dimmAttributes & BIT6)
  60272. + mvOsOutput(" Analysis probe installed: Yes \n");
  60273. + else
  60274. + mvOsOutput(" Analysis probe installed: No \n");
  60275. + }
  60276. +
  60277. + break;
  60278. +/*----------------------------------------------------------------------------*/
  60279. +
  60280. + case 22: /* Suported AutoPreCharge */
  60281. + mvOsOutput("\nModul Attributes (SPD Byte 22): \n");
  60282. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60283. + {
  60284. + if ( spdRawData[i] & BIT0 )
  60285. + mvOsOutput(" Early Ras Precharge: Yes \n");
  60286. + else
  60287. + mvOsOutput(" Early Ras Precharge: No \n");
  60288. +
  60289. + if ( spdRawData[i] & BIT1 )
  60290. + mvOsOutput(" AutoPreCharge: Yes \n");
  60291. + else
  60292. + mvOsOutput(" AutoPreCharge: No \n");
  60293. +
  60294. + if ( spdRawData[i] & BIT2 )
  60295. + mvOsOutput(" Precharge All: Yes \n");
  60296. + else
  60297. + mvOsOutput(" Precharge All: No \n");
  60298. +
  60299. + if ( spdRawData[i] & BIT3 )
  60300. + mvOsOutput(" Write 1/ReadBurst: Yes \n");
  60301. + else
  60302. + mvOsOutput(" Write 1/ReadBurst: No \n");
  60303. +
  60304. + if ( spdRawData[i] & BIT4 )
  60305. + mvOsOutput(" lower VCC tolerance: 5%%\n");
  60306. + else
  60307. + mvOsOutput(" lower VCC tolerance: 10%%\n");
  60308. +
  60309. + if ( spdRawData[i] & BIT5 )
  60310. + mvOsOutput(" upper VCC tolerance: 5%%\n");
  60311. + else
  60312. + mvOsOutput(" upper VCC tolerance: 10%%\n");
  60313. + }
  60314. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  60315. + {
  60316. + if ( spdRawData[i] & BIT0 )
  60317. + mvOsOutput(" Supports Weak Driver: Yes \n");
  60318. + else
  60319. + mvOsOutput(" Supports Weak Driver: No \n");
  60320. +
  60321. + if ( !(spdRawData[i] & BIT4) )
  60322. + mvOsOutput(" lower VCC tolerance: 0.2V\n");
  60323. +
  60324. + if ( !(spdRawData[i] & BIT5) )
  60325. + mvOsOutput(" upper VCC tolerance: 0.2V\n");
  60326. +
  60327. + if ( spdRawData[i] & BIT6 )
  60328. + mvOsOutput(" Concurrent Auto Preharge: Yes \n");
  60329. + else
  60330. + mvOsOutput(" Concurrent Auto Preharge: No \n");
  60331. +
  60332. + if ( spdRawData[i] & BIT7 )
  60333. + mvOsOutput(" Supports Fast AP: Yes \n");
  60334. + else
  60335. + mvOsOutput(" Supports Fast AP: No \n");
  60336. + }
  60337. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  60338. + {
  60339. + if ( spdRawData[i] & BIT0 )
  60340. + mvOsOutput(" Supports Weak Driver: Yes \n");
  60341. + else
  60342. + mvOsOutput(" Supports Weak Driver: No \n");
  60343. + }
  60344. + break;
  60345. +/*----------------------------------------------------------------------------*/
  60346. +
  60347. + case 23:
  60348. + /* Minimum Cycle Time At Maximum Cas Latancy Minus 1 (2nd highest CL) */
  60349. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  60350. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  60351. +
  60352. + /* DDR2 addition of right of point */
  60353. + if ((spdRawData[i] & 0x0f) == 0xA)
  60354. + {
  60355. + rightOfPoint = 25;
  60356. + }
  60357. + if ((spdRawData[i] & 0x0f) == 0xB)
  60358. + {
  60359. + rightOfPoint = 33;
  60360. + }
  60361. + if ((spdRawData[i] & 0x0f) == 0xC)
  60362. + {
  60363. + rightOfPoint = 66;
  60364. + }
  60365. + if ((spdRawData[i] & 0x0f) == 0xD)
  60366. + {
  60367. + rightOfPoint = 75;
  60368. + }
  60369. +
  60370. + mvOsOutput("Minimum Cycle Time At 2nd highest CasLatancy"
  60371. + "(0 = Not supported): %d.%d [ns]\n",
  60372. + leftOfPoint, rightOfPoint );
  60373. + break;
  60374. +/*----------------------------------------------------------------------------*/
  60375. +
  60376. + case 24: /* Clock To Data Out 2nd highest Cas Latency Value*/
  60377. + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 10:100;
  60378. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  60379. + ((spdRawData[i] & 0x0f));
  60380. + leftOfPoint = time_tmp / div;
  60381. + rightOfPoint = time_tmp % div;
  60382. + mvOsOutput("Clock To Data Out (2nd CL value): %d.%d [ns]\n",
  60383. + leftOfPoint, rightOfPoint);
  60384. + break;
  60385. +/*----------------------------------------------------------------------------*/
  60386. +
  60387. + case 25:
  60388. + /* Minimum Cycle Time At Maximum Cas Latancy Minus 2 (3rd highest CL) */
  60389. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60390. + {
  60391. + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
  60392. + rightOfPoint = (spdRawData[i] & 0x3) * 25;
  60393. + }
  60394. + else /* DDR1 or DDR2 */
  60395. + {
  60396. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  60397. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  60398. +
  60399. + /* DDR2 addition of right of point */
  60400. + if ((spdRawData[i] & 0x0f) == 0xA)
  60401. + {
  60402. + rightOfPoint = 25;
  60403. + }
  60404. + if ((spdRawData[i] & 0x0f) == 0xB)
  60405. + {
  60406. + rightOfPoint = 33;
  60407. + }
  60408. + if ((spdRawData[i] & 0x0f) == 0xC)
  60409. + {
  60410. + rightOfPoint = 66;
  60411. + }
  60412. + if ((spdRawData[i] & 0x0f) == 0xD)
  60413. + {
  60414. + rightOfPoint = 75;
  60415. + }
  60416. + }
  60417. + mvOsOutput("Minimum Cycle Time At 3rd highest CasLatancy"
  60418. + "(0 = Not supported): %d.%d [ns]\n",
  60419. + leftOfPoint, rightOfPoint );
  60420. + break;
  60421. +/*----------------------------------------------------------------------------*/
  60422. +
  60423. + case 26: /* Clock To Data Out 3rd highest Cas Latency Value*/
  60424. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60425. + {
  60426. + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
  60427. + rightOfPoint = (spdRawData[i] & 0x3) * 25;
  60428. + }
  60429. + else /* DDR1 or DDR2 */
  60430. + {
  60431. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  60432. + ((spdRawData[i] & 0x0f));
  60433. + leftOfPoint = 0;
  60434. + rightOfPoint = time_tmp;
  60435. + }
  60436. + mvOsOutput("Clock To Data Out (3rd CL value): %d.%2d[ns]\n",
  60437. + leftOfPoint, rightOfPoint );
  60438. + break;
  60439. +/*----------------------------------------------------------------------------*/
  60440. +
  60441. + case 27: /* Minimum Row Precharge Time */
  60442. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  60443. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  60444. + 0xff : 0xfc;
  60445. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  60446. + 0x00 : 0x03;
  60447. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  60448. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  60449. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 10ps Intervals*/
  60450. + trp_clocks = (temp + (busClkPs-1)) / busClkPs;
  60451. + mvOsOutput("Minimum Row Precharge Time [ns]: %d.%d = "
  60452. + "in Clk cycles %d\n",
  60453. + leftOfPoint, rightOfPoint, trp_clocks);
  60454. + break;
  60455. +/*----------------------------------------------------------------------------*/
  60456. +
  60457. + case 28: /* Minimum Row Active to Row Active Time */
  60458. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  60459. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  60460. + 0xff : 0xfc;
  60461. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  60462. + 0x00 : 0x03;
  60463. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  60464. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  60465. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
  60466. + trrd_clocks = (temp + (busClkPs-1)) / busClkPs;
  60467. + mvOsOutput("Minimum Row Active -To- Row Active Delay [ns]: "
  60468. + "%d.%d = in Clk cycles %d\n",
  60469. + leftOfPoint, rightOfPoint, trp_clocks);
  60470. + break;
  60471. +/*----------------------------------------------------------------------------*/
  60472. +
  60473. + case 29: /* Minimum Ras-To-Cas Delay */
  60474. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  60475. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  60476. + 0xff : 0xfc;
  60477. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  60478. + 0x00 : 0x03;
  60479. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  60480. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  60481. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
  60482. + trcd_clocks = (temp + (busClkPs-1) )/ busClkPs;
  60483. + mvOsOutput("Minimum Ras-To-Cas Delay [ns]: %d.%d = "
  60484. + "in Clk cycles %d\n",
  60485. + leftOfPoint, rightOfPoint, trp_clocks);
  60486. + break;
  60487. +/*----------------------------------------------------------------------------*/
  60488. +
  60489. + case 30: /* Minimum Ras Pulse Width */
  60490. + tras_clocks = (cas2ps(spdRawData[i])+(busClkPs-1)) / busClkPs;
  60491. + mvOsOutput("Minimum Ras Pulse Width [ns]: %d = "
  60492. + "in Clk cycles %d\n", spdRawData[i], tras_clocks);
  60493. + break;
  60494. +/*----------------------------------------------------------------------------*/
  60495. +
  60496. + case 31: /* Module Bank Density */
  60497. + mvOsOutput("Module Bank Density (more than 1= Multisize-Module):");
  60498. +
  60499. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60500. + {
  60501. + if (dimmInfo.dimmBankDensity & BIT0)
  60502. + mvOsOutput("1GB, ");
  60503. + if (dimmInfo.dimmBankDensity & BIT1)
  60504. + mvOsOutput("8MB, ");
  60505. + if (dimmInfo.dimmBankDensity & BIT2)
  60506. + mvOsOutput("16MB, ");
  60507. + if (dimmInfo.dimmBankDensity & BIT3)
  60508. + mvOsOutput("32MB, ");
  60509. + if (dimmInfo.dimmBankDensity & BIT4)
  60510. + mvOsOutput("64MB, ");
  60511. + if (dimmInfo.dimmBankDensity & BIT5)
  60512. + mvOsOutput("128MB, ");
  60513. + if (dimmInfo.dimmBankDensity & BIT6)
  60514. + mvOsOutput("256MB, ");
  60515. + if (dimmInfo.dimmBankDensity & BIT7)
  60516. + mvOsOutput("512MB, ");
  60517. + }
  60518. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  60519. + {
  60520. + if (dimmInfo.dimmBankDensity & BIT0)
  60521. + mvOsOutput("1GB, ");
  60522. + if (dimmInfo.dimmBankDensity & BIT1)
  60523. + mvOsOutput("2GB, ");
  60524. + if (dimmInfo.dimmBankDensity & BIT2)
  60525. + mvOsOutput("16MB, ");
  60526. + if (dimmInfo.dimmBankDensity & BIT3)
  60527. + mvOsOutput("32MB, ");
  60528. + if (dimmInfo.dimmBankDensity & BIT4)
  60529. + mvOsOutput("64MB, ");
  60530. + if (dimmInfo.dimmBankDensity & BIT5)
  60531. + mvOsOutput("128MB, ");
  60532. + if (dimmInfo.dimmBankDensity & BIT6)
  60533. + mvOsOutput("256MB, ");
  60534. + if (dimmInfo.dimmBankDensity & BIT7)
  60535. + mvOsOutput("512MB, ");
  60536. + }
  60537. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  60538. + {
  60539. + if (dimmInfo.dimmBankDensity & BIT0)
  60540. + mvOsOutput("1GB, ");
  60541. + if (dimmInfo.dimmBankDensity & BIT1)
  60542. + mvOsOutput("2GB, ");
  60543. + if (dimmInfo.dimmBankDensity & BIT2)
  60544. + mvOsOutput("4GB, ");
  60545. + if (dimmInfo.dimmBankDensity & BIT3)
  60546. + mvOsOutput("8GB, ");
  60547. + if (dimmInfo.dimmBankDensity & BIT4)
  60548. + mvOsOutput("16GB, ");
  60549. + if (dimmInfo.dimmBankDensity & BIT5)
  60550. + mvOsOutput("128MB, ");
  60551. + if (dimmInfo.dimmBankDensity & BIT6)
  60552. + mvOsOutput("256MB, ");
  60553. + if (dimmInfo.dimmBankDensity & BIT7)
  60554. + mvOsOutput("512MB, ");
  60555. + }
  60556. + mvOsOutput("\n");
  60557. + break;
  60558. +/*----------------------------------------------------------------------------*/
  60559. +
  60560. + case 32: /* Address And Command Setup Time (measured in ns/1000) */
  60561. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60562. + {
  60563. + rightOfPoint = (spdRawData[i] & 0x0f);
  60564. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  60565. + if(leftOfPoint > 7)
  60566. + {
  60567. + leftOfPoint *= -1;
  60568. + }
  60569. + }
  60570. + else /* DDR1 or DDR2 */
  60571. + {
  60572. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  60573. + ((spdRawData[i] & 0x0f));
  60574. + leftOfPoint = time_tmp / 100;
  60575. + rightOfPoint = time_tmp % 100;
  60576. + }
  60577. + mvOsOutput("Address And Command Setup Time [ns]: %d.%d\n",
  60578. + leftOfPoint, rightOfPoint);
  60579. + break;
  60580. +/*----------------------------------------------------------------------------*/
  60581. +
  60582. + case 33: /* Address And Command Hold Time */
  60583. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60584. + {
  60585. + rightOfPoint = (spdRawData[i] & 0x0f);
  60586. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  60587. + if(leftOfPoint > 7)
  60588. + {
  60589. + leftOfPoint *= -1;
  60590. + }
  60591. + }
  60592. + else /* DDR1 or DDR2 */
  60593. + {
  60594. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  60595. + ((spdRawData[i] & 0x0f));
  60596. + leftOfPoint = time_tmp / 100;
  60597. + rightOfPoint = time_tmp % 100;
  60598. + }
  60599. + mvOsOutput("Address And Command Hold Time [ns]: %d.%d\n",
  60600. + leftOfPoint, rightOfPoint);
  60601. + break;
  60602. +/*----------------------------------------------------------------------------*/
  60603. +
  60604. + case 34: /* Data Input Setup Time */
  60605. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60606. + {
  60607. + rightOfPoint = (spdRawData[i] & 0x0f);
  60608. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  60609. + if(leftOfPoint > 7)
  60610. + {
  60611. + leftOfPoint *= -1;
  60612. + }
  60613. + }
  60614. + else /* DDR1 or DDR2 */
  60615. + {
  60616. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  60617. + ((spdRawData[i] & 0x0f));
  60618. + leftOfPoint = time_tmp / 100;
  60619. + rightOfPoint = time_tmp % 100;
  60620. + }
  60621. + mvOsOutput("Data Input Setup Time [ns]: %d.%d\n",
  60622. + leftOfPoint, rightOfPoint);
  60623. + break;
  60624. +/*----------------------------------------------------------------------------*/
  60625. +
  60626. + case 35: /* Data Input Hold Time */
  60627. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  60628. + {
  60629. + rightOfPoint = (spdRawData[i] & 0x0f);
  60630. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  60631. + if(leftOfPoint > 7)
  60632. + {
  60633. + leftOfPoint *= -1;
  60634. + }
  60635. + }
  60636. + else /* DDR1 or DDR2 */
  60637. + {
  60638. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  60639. + ((spdRawData[i] & 0x0f));
  60640. + leftOfPoint = time_tmp / 100;
  60641. + rightOfPoint = time_tmp % 100;
  60642. + }
  60643. + mvOsOutput("Data Input Hold Time [ns]: %d.%d\n\n",
  60644. + leftOfPoint, rightOfPoint);
  60645. + break;
  60646. +/*----------------------------------------------------------------------------*/
  60647. +
  60648. + case 36: /* Relevant for DDR2 only: Write Recovery Time */
  60649. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> 2);
  60650. + rightOfPoint = (spdRawData[i] & maskRightOfPoint) * 25;
  60651. + mvOsOutput("Write Recovery Time [ns]: %d.%d\n",
  60652. + leftOfPoint, rightOfPoint);
  60653. + break;
  60654. +/*----------------------------------------------------------------------------*/
  60655. + }
  60656. +
  60657. +}
  60658. +
  60659. +
  60660. +/*
  60661. + * translate ns.ns/10 coding of SPD timing values
  60662. + * into ps unit values
  60663. + */
  60664. +/*******************************************************************************
  60665. +* cas2ps - Translate x.y ns parameter to pico-seconds values
  60666. +*
  60667. +* DESCRIPTION:
  60668. +* This function translates x.y nano seconds to its value in pico seconds.
  60669. +* For example 3.75ns will return 3750.
  60670. +*
  60671. +* INPUT:
  60672. +* spd_byte - DIMM SPD byte.
  60673. +*
  60674. +* OUTPUT:
  60675. +* None.
  60676. +*
  60677. +* RETURN:
  60678. +* value in pico seconds.
  60679. +*
  60680. +*******************************************************************************/
  60681. +static MV_U32 cas2ps(MV_U8 spd_byte)
  60682. +{
  60683. + MV_U32 ns, ns10;
  60684. +
  60685. + /* isolate upper nibble */
  60686. + ns = (spd_byte >> 4) & 0x0F;
  60687. + /* isolate lower nibble */
  60688. + ns10 = (spd_byte & 0x0F);
  60689. +
  60690. + if( ns10 < 10 ) {
  60691. + ns10 *= 10;
  60692. + }
  60693. + else if( ns10 == 10 )
  60694. + ns10 = 25;
  60695. + else if( ns10 == 11 )
  60696. + ns10 = 33;
  60697. + else if( ns10 == 12 )
  60698. + ns10 = 66;
  60699. + else if( ns10 == 13 )
  60700. + ns10 = 75;
  60701. + else
  60702. + {
  60703. + mvOsOutput("cas2ps Err. unsupported cycle time.\n");
  60704. + }
  60705. +
  60706. + return (ns*1000 + ns10*10);
  60707. +}
  60708. +
  60709. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h
  60710. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h 1970-01-01 01:00:00.000000000 +0100
  60711. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h 2010-08-05 22:02:24.504868405 +0200
  60712. @@ -0,0 +1,192 @@
  60713. +/*******************************************************************************
  60714. +Copyright (C) Marvell International Ltd. and its affiliates
  60715. +
  60716. +This software file (the "File") is owned and distributed by Marvell
  60717. +International Ltd. and/or its affiliates ("Marvell") under the following
  60718. +alternative licensing terms. Once you have made an election to distribute the
  60719. +File under one of the following license alternatives, please (i) delete this
  60720. +introductory statement regarding license alternatives, (ii) delete the two
  60721. +license alternatives that you have not elected to use and (iii) preserve the
  60722. +Marvell copyright notice above.
  60723. +
  60724. +********************************************************************************
  60725. +Marvell Commercial License Option
  60726. +
  60727. +If you received this File from Marvell and you have entered into a commercial
  60728. +license agreement (a "Commercial License") with Marvell, the File is licensed
  60729. +to you under the terms of the applicable Commercial License.
  60730. +
  60731. +********************************************************************************
  60732. +Marvell GPL License Option
  60733. +
  60734. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60735. +modify this File in accordance with the terms and conditions of the General
  60736. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  60737. +available along with the File in the license.txt file or by writing to the Free
  60738. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  60739. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  60740. +
  60741. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  60742. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  60743. +DISCLAIMED. The GPL License provides additional details about this warranty
  60744. +disclaimer.
  60745. +********************************************************************************
  60746. +Marvell BSD License Option
  60747. +
  60748. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60749. +modify this File under the following licensing terms.
  60750. +Redistribution and use in source and binary forms, with or without modification,
  60751. +are permitted provided that the following conditions are met:
  60752. +
  60753. + * Redistributions of source code must retain the above copyright notice,
  60754. + this list of conditions and the following disclaimer.
  60755. +
  60756. + * Redistributions in binary form must reproduce the above copyright
  60757. + notice, this list of conditions and the following disclaimer in the
  60758. + documentation and/or other materials provided with the distribution.
  60759. +
  60760. + * Neither the name of Marvell nor the names of its contributors may be
  60761. + used to endorse or promote products derived from this software without
  60762. + specific prior written permission.
  60763. +
  60764. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  60765. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  60766. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  60767. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  60768. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  60769. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  60770. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  60771. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  60772. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  60773. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  60774. +
  60775. +*******************************************************************************/
  60776. +
  60777. +#ifndef __INCmvDram
  60778. +#define __INCmvDram
  60779. +
  60780. +#include "ddr2/mvDramIf.h"
  60781. +#include "twsi/mvTwsi.h"
  60782. +
  60783. +#define MAX_DIMM_NUM 2
  60784. +#define SPD_SIZE 128
  60785. +
  60786. +/* Dimm spd offsets */
  60787. +#define DIMM_MEM_TYPE 2
  60788. +#define DIMM_ROW_NUM 3
  60789. +#define DIMM_COL_NUM 4
  60790. +#define DIMM_MODULE_BANK_NUM 5
  60791. +#define DIMM_DATA_WIDTH 6
  60792. +#define DIMM_VOLT_IF 8
  60793. +#define DIMM_MIN_CC_AT_MAX_CAS 9
  60794. +#define DIMM_ERR_CHECK_TYPE 11
  60795. +#define DIMM_REFRESH_INTERVAL 12
  60796. +#define DIMM_SDRAM_WIDTH 13
  60797. +#define DIMM_ERR_CHECK_DATA_WIDTH 14
  60798. +#define DIMM_MIN_CLK_DEL 15
  60799. +#define DIMM_BURST_LEN_SUP 16
  60800. +#define DIMM_DEV_BANK_NUM 17
  60801. +#define DIMM_SUP_CAL 18
  60802. +#define DIMM_DDR2_TYPE_INFORMATION 20 /* DDR2 only */
  60803. +#define DIMM_BUF_ADDR_CONT_IN 21
  60804. +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS1 23
  60805. +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS2 25
  60806. +#define DIMM_MIN_ROW_PRECHARGE_TIME 27
  60807. +#define DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE 28
  60808. +#define DIMM_MIN_RAS_TO_CAS_DELAY 29
  60809. +#define DIMM_MIN_RAS_PULSE_WIDTH 30
  60810. +#define DIMM_BANK_DENSITY 31
  60811. +#define DIMM_MIN_WRITE_RECOVERY_TIME 36
  60812. +#define DIMM_MIN_WRITE_TO_READ_CMD_DELAY 37
  60813. +#define DIMM_MIN_READ_TO_PRECH_CMD_DELAY 38
  60814. +#define DIMM_MIN_REFRESH_TO_ACTIVATE_CMD 42
  60815. +#define DIMM_SPD_VERSION 62
  60816. +
  60817. +/* Dimm Memory Type values */
  60818. +#define DIMM_MEM_TYPE_SDRAM 0x4
  60819. +#define DIMM_MEM_TYPE_DDR1 0x7
  60820. +#define DIMM_MEM_TYPE_DDR2 0x8
  60821. +
  60822. +#define DIMM_MODULE_MANU_OFFS 64
  60823. +#define DIMM_MODULE_MANU_SIZE 8
  60824. +#define DIMM_MODULE_VEN_OFFS 73
  60825. +#define DIMM_MODULE_VEN_SIZE 25
  60826. +#define DIMM_MODULE_ID_OFFS 99
  60827. +#define DIMM_MODULE_ID_SIZE 18
  60828. +
  60829. +/* enumeration for voltage levels. */
  60830. +typedef enum _mvDimmVoltageIf
  60831. +{
  60832. + TTL_5V_TOLERANT,
  60833. + LVTTL,
  60834. + HSTL_1_5V,
  60835. + SSTL_3_3V,
  60836. + SSTL_2_5V,
  60837. + VOLTAGE_UNKNOWN,
  60838. +} MV_DIMM_VOLTAGE_IF;
  60839. +
  60840. +
  60841. +/* enumaration for SDRAM CAS Latencies. */
  60842. +typedef enum _mvDimmSdramCas
  60843. +{
  60844. + SD_CL_1 =1,
  60845. + SD_CL_2,
  60846. + SD_CL_3,
  60847. + SD_CL_4,
  60848. + SD_CL_5,
  60849. + SD_CL_6,
  60850. + SD_CL_7,
  60851. + SD_FAULT
  60852. +}MV_DIMM_SDRAM_CAS;
  60853. +
  60854. +
  60855. +/* DIMM information structure */
  60856. +typedef struct _mvDimmInfo
  60857. +{
  60858. + MV_MEMORY_TYPE memoryType; /* DDR or SDRAM */
  60859. +
  60860. + MV_U8 spdRawData[SPD_SIZE]; /* Content of SPD-EEPROM copied 1:1 */
  60861. +
  60862. + /* DIMM dimensions */
  60863. + MV_U32 numOfRowAddr;
  60864. + MV_U32 numOfColAddr;
  60865. + MV_U32 numOfModuleBanks;
  60866. + MV_U32 dataWidth;
  60867. + MV_U32 errorCheckType; /* ECC , PARITY..*/
  60868. + MV_U32 sdramWidth; /* 4,8,16 or 32 */
  60869. + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
  60870. + MV_U32 burstLengthSupported;
  60871. + MV_U32 numOfBanksOnEachDevice;
  60872. + MV_U32 suportedCasLatencies;
  60873. + MV_U32 refreshInterval;
  60874. + MV_U32 dimmBankDensity;
  60875. + MV_U32 dimmTypeInfo; /* DDR2 only */
  60876. + MV_U32 dimmAttributes;
  60877. +
  60878. + /* DIMM timing parameters */
  60879. + MV_U32 minCycleTimeAtMaxCasLatPs;
  60880. + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
  60881. + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
  60882. + MV_U32 minRowPrechargeTime;
  60883. + MV_U32 minRowActiveToRowActive;
  60884. + MV_U32 minRasToCasDelay;
  60885. + MV_U32 minRasPulseWidth;
  60886. + MV_U32 minWriteRecoveryTime; /* DDR2 only */
  60887. + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
  60888. + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
  60889. + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
  60890. +
  60891. + /* Parameters calculated from the extracted DIMM information */
  60892. + MV_U32 size; /* 16,64,128,256 or 512 MByte in MB units */
  60893. + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit in MB units */
  60894. + MV_U32 numberOfDevices;
  60895. +
  60896. +} MV_DIMM_INFO;
  60897. +
  60898. +
  60899. +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo);
  60900. +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo);
  60901. +MV_VOID dimmSpdPrint(MV_U32 dimmNum);
  60902. +MV_STATUS dimmSpdCpy(MV_VOID);
  60903. +
  60904. +#endif /* __INCmvDram */
  60905. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c
  60906. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c 1970-01-01 01:00:00.000000000 +0100
  60907. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c 2010-08-05 22:02:24.544868113 +0200
  60908. @@ -0,0 +1,2952 @@
  60909. +/*******************************************************************************
  60910. +Copyright (C) Marvell International Ltd. and its affiliates
  60911. +
  60912. +This software file (the "File") is owned and distributed by Marvell
  60913. +International Ltd. and/or its affiliates ("Marvell") under the following
  60914. +alternative licensing terms. Once you have made an election to distribute the
  60915. +File under one of the following license alternatives, please (i) delete this
  60916. +introductory statement regarding license alternatives, (ii) delete the two
  60917. +license alternatives that you have not elected to use and (iii) preserve the
  60918. +Marvell copyright notice above.
  60919. +
  60920. +********************************************************************************
  60921. +Marvell Commercial License Option
  60922. +
  60923. +If you received this File from Marvell and you have entered into a commercial
  60924. +license agreement (a "Commercial License") with Marvell, the File is licensed
  60925. +to you under the terms of the applicable Commercial License.
  60926. +
  60927. +********************************************************************************
  60928. +Marvell GPL License Option
  60929. +
  60930. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60931. +modify this File in accordance with the terms and conditions of the General
  60932. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  60933. +available along with the File in the license.txt file or by writing to the Free
  60934. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  60935. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  60936. +
  60937. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  60938. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  60939. +DISCLAIMED. The GPL License provides additional details about this warranty
  60940. +disclaimer.
  60941. +********************************************************************************
  60942. +Marvell BSD License Option
  60943. +
  60944. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60945. +modify this File under the following licensing terms.
  60946. +Redistribution and use in source and binary forms, with or without modification,
  60947. +are permitted provided that the following conditions are met:
  60948. +
  60949. + * Redistributions of source code must retain the above copyright notice,
  60950. + this list of conditions and the following disclaimer.
  60951. +
  60952. + * Redistributions in binary form must reproduce the above copyright
  60953. + notice, this list of conditions and the following disclaimer in the
  60954. + documentation and/or other materials provided with the distribution.
  60955. +
  60956. + * Neither the name of Marvell nor the names of its contributors may be
  60957. + used to endorse or promote products derived from this software without
  60958. + specific prior written permission.
  60959. +
  60960. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  60961. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  60962. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  60963. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  60964. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  60965. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  60966. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  60967. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  60968. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  60969. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  60970. +
  60971. +*******************************************************************************/
  60972. +
  60973. +/*******************************************************************************
  60974. +* mvEth.c - Marvell's Gigabit Ethernet controller low level driver
  60975. +*
  60976. +* DESCRIPTION:
  60977. +* This file introduce OS independent APIs to Marvell's Gigabit Ethernet
  60978. +* controller. This Gigabit Ethernet Controller driver API controls
  60979. +* 1) Operations (i.e. port Init, Finish, Up, Down, PhyReset etc').
  60980. +* 2) Data flow (i.e. port Send, Receive etc').
  60981. +* 3) MAC Filtering functions (ethSetMcastAddr, ethSetRxFilterMode, etc.)
  60982. +* 4) MIB counters support (ethReadMibCounter)
  60983. +* 5) Debug functions (ethPortRegs, ethPortCounters, ethPortQueues, etc.)
  60984. +* Each Gigabit Ethernet port is controlled via ETH_PORT_CTRL struct.
  60985. +* This struct includes configuration information as well as driver
  60986. +* internal data needed for its operations.
  60987. +*
  60988. +* Supported Features:
  60989. +* - OS independent. All required OS services are implemented via external
  60990. +* OS dependent components (like osLayer or ethOsg)
  60991. +* - The user is free from Rx/Tx queue managing.
  60992. +* - Simple Gigabit Ethernet port operation API.
  60993. +* - Simple Gigabit Ethernet port data flow API.
  60994. +* - Data flow and operation API support per queue functionality.
  60995. +* - Support cached descriptors for better performance.
  60996. +* - PHY access and control API.
  60997. +* - Port Configuration API.
  60998. +* - Full control over Special and Other Multicast MAC tables.
  60999. +*
  61000. +*******************************************************************************/
  61001. +/* includes */
  61002. +#include "mvTypes.h"
  61003. +#include "mv802_3.h"
  61004. +#include "mvDebug.h"
  61005. +#include "mvCommon.h"
  61006. +#include "mvOs.h"
  61007. +#include "ctrlEnv/mvCtrlEnvLib.h"
  61008. +#include "eth-phy/mvEthPhy.h"
  61009. +#include "eth/mvEth.h"
  61010. +#include "eth/gbe/mvEthGbe.h"
  61011. +#include "cpu/mvCpu.h"
  61012. +
  61013. +#ifdef INCLUDE_SYNC_BARR
  61014. +#include "sys/mvCpuIf.h"
  61015. +#endif
  61016. +
  61017. +#ifdef MV_RT_DEBUG
  61018. +# define ETH_DEBUG
  61019. +#endif
  61020. +
  61021. +
  61022. +/* locals */
  61023. +MV_BOOL ethDescInSram;
  61024. +MV_BOOL ethDescSwCoher;
  61025. +
  61026. +/* This array holds the control structure of each port */
  61027. +ETH_PORT_CTRL* ethPortCtrl[MV_ETH_MAX_PORTS];
  61028. +
  61029. +/* Ethernet Port Local routines */
  61030. +
  61031. +static void ethInitRxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue);
  61032. +
  61033. +static void ethInitTxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue);
  61034. +
  61035. +static void ethSetUcastTable(int portNo, int queue);
  61036. +
  61037. +static MV_BOOL ethSetUcastAddr (int ethPortNum, MV_U8 lastNibble, int queue);
  61038. +static MV_BOOL ethSetSpecialMcastAddr(int ethPortNum, MV_U8 lastByte, int queue);
  61039. +static MV_BOOL ethSetOtherMcastAddr(int ethPortNum, MV_U8 crc8, int queue);
  61040. +
  61041. +static void ethFreeDescrMemory(ETH_PORT_CTRL* pEthPortCtrl, MV_BUF_INFO* pDescBuf);
  61042. +static MV_U8* ethAllocDescrMemory(ETH_PORT_CTRL* pEthPortCtrl, int size,
  61043. + MV_ULONG* pPhysAddr, MV_U32 *memHandle);
  61044. +
  61045. +static MV_U32 mvEthMruGet(MV_U32 maxRxPktSize);
  61046. +
  61047. +static void mvEthPortSgmiiConfig(int port);
  61048. +
  61049. +
  61050. +
  61051. +/******************************************************************************/
  61052. +/* EthDrv Initialization functions */
  61053. +/******************************************************************************/
  61054. +
  61055. +/*******************************************************************************
  61056. +* mvEthHalInit - Initialize the Giga Ethernet unit
  61057. +*
  61058. +* DESCRIPTION:
  61059. +* This function initialize the Giga Ethernet unit.
  61060. +* 1) Configure Address decode windows of the unit
  61061. +* 2) Set registers to HW default values.
  61062. +* 3) Clear and Disable interrupts
  61063. +*
  61064. +* INPUT: NONE
  61065. +*
  61066. +* RETURN: NONE
  61067. +*
  61068. +* NOTE: this function is called once in the boot process.
  61069. +*******************************************************************************/
  61070. +void mvEthHalInit(void)
  61071. +{
  61072. + int port;
  61073. +
  61074. + /* Init static data structures */
  61075. + for (port=0; port<MV_ETH_MAX_PORTS; port++)
  61076. + {
  61077. + ethPortCtrl[port] = NULL;
  61078. + }
  61079. + /* Power down all existing ports */
  61080. + for(port=0; port<mvCtrlEthMaxPortGet(); port++)
  61081. + {
  61082. +
  61083. +#if defined (MV78200)
  61084. + /* Skip ports mapped to another CPU*/
  61085. + if (MV_FALSE == mvSocUnitIsMappedToThisCpu(GIGA0+port))
  61086. + {
  61087. + continue;
  61088. + }
  61089. +#endif
  61090. +
  61091. + /* Skip power down ports */
  61092. + if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port)) continue;
  61093. +
  61094. + /* Disable Giga Ethernet Unit interrupts */
  61095. + MV_REG_WRITE(ETH_UNIT_INTR_MASK_REG(port), 0);
  61096. +
  61097. + /* Clear ETH_UNIT_INTR_CAUSE_REG register */
  61098. + MV_REG_WRITE(ETH_UNIT_INTR_CAUSE_REG(port), 0);
  61099. +
  61100. + }
  61101. +
  61102. + mvEthMemAttrGet(&ethDescInSram, &ethDescSwCoher);
  61103. +
  61104. +#if defined(ETH_DESCR_IN_SRAM)
  61105. + if(ethDescInSram == MV_FALSE)
  61106. + {
  61107. + mvOsPrintf("ethDrv: WARNING! Descriptors will be allocated in DRAM instead of SRAM.\n");
  61108. + }
  61109. +#endif /* ETH_DESCR_IN_SRAM */
  61110. +}
  61111. +
  61112. +/*******************************************************************************
  61113. +* mvEthMemAttrGet - Define properties (SRAM/DRAM, SW_COHER / HW_COHER / UNCACHED)
  61114. +* of of memory location for RX and TX descriptors.
  61115. +*
  61116. +* DESCRIPTION:
  61117. +* This function allocates memory for RX and TX descriptors.
  61118. +* - If ETH_DESCR_IN_SRAM defined, allocate from SRAM memory.
  61119. +* - If ETH_DESCR_IN_SDRAM defined, allocate from SDRAM memory.
  61120. +*
  61121. +* INPUT:
  61122. +* MV_BOOL* pIsSram - place of descriptors:
  61123. +* MV_TRUE - in SRAM
  61124. +* MV_FALSE - in DRAM
  61125. +* MV_BOOL* pIsSwCoher - cache coherency of descriptors:
  61126. +* MV_TRUE - driver is responsible for cache coherency
  61127. +* MV_FALSE - driver is not responsible for cache coherency
  61128. +*
  61129. +* RETURN:
  61130. +*
  61131. +*******************************************************************************/
  61132. +void mvEthMemAttrGet(MV_BOOL* pIsSram, MV_BOOL* pIsSwCoher)
  61133. +{
  61134. + MV_BOOL isSram, isSwCoher;
  61135. +
  61136. + isSram = MV_FALSE;
  61137. +#if (ETHER_DRAM_COHER == MV_CACHE_COHER_SW)
  61138. + isSwCoher = MV_TRUE;
  61139. +#else
  61140. + isSwCoher = MV_FALSE;
  61141. +#endif
  61142. +
  61143. +#if defined(ETH_DESCR_IN_SRAM)
  61144. + if( mvCtrlSramSizeGet() > 0)
  61145. + {
  61146. + isSram = MV_TRUE;
  61147. + #if (INTEG_SRAM_COHER == MV_CACHE_COHER_SW)
  61148. + isSwCoher = MV_TRUE;
  61149. + #else
  61150. + isSwCoher = MV_FALSE;
  61151. + #endif
  61152. + }
  61153. +#endif /* ETH_DESCR_IN_SRAM */
  61154. +
  61155. + if(pIsSram != NULL)
  61156. + *pIsSram = isSram;
  61157. +
  61158. + if(pIsSwCoher != NULL)
  61159. + *pIsSwCoher = isSwCoher;
  61160. +}
  61161. +
  61162. +
  61163. +
  61164. +/******************************************************************************/
  61165. +/* Port Initialization functions */
  61166. +/******************************************************************************/
  61167. +
  61168. +/*******************************************************************************
  61169. +* mvEthPortInit - Initialize the Ethernet port driver
  61170. +*
  61171. +* DESCRIPTION:
  61172. +* This function initialize the ethernet port.
  61173. +* 1) Allocate and initialize internal port Control structure.
  61174. +* 2) Create RX and TX descriptor rings for default RX and TX queues
  61175. +* 3) Disable RX and TX operations, clear cause registers and
  61176. +* mask all interrupts.
  61177. +* 4) Set all registers to default values and clean all MAC tables.
  61178. +*
  61179. +* INPUT:
  61180. +* int portNo - Ethernet port number
  61181. +* ETH_PORT_INIT *pEthPortInit - Ethernet port init structure
  61182. +*
  61183. +* RETURN:
  61184. +* void* - ethernet port handler, that should be passed to the most other
  61185. +* functions dealing with this port.
  61186. +*
  61187. +* NOTE: This function is called once per port when loading the eth module.
  61188. +*******************************************************************************/
  61189. +void* mvEthPortInit(int portNo, MV_ETH_PORT_INIT *pEthPortInit)
  61190. +{
  61191. + int queue, descSize;
  61192. + ETH_PORT_CTRL* pPortCtrl;
  61193. +
  61194. + /* Check validity of parameters */
  61195. + if( (portNo >= (int)mvCtrlEthMaxPortGet()) ||
  61196. + (pEthPortInit->rxDefQ >= MV_ETH_RX_Q_NUM) ||
  61197. + (pEthPortInit->maxRxPktSize < 1518) )
  61198. + {
  61199. + mvOsPrintf("EthPort #%d: Bad initialization parameters\n", portNo);
  61200. + return NULL;
  61201. + }
  61202. + if( (pEthPortInit->rxDescrNum[pEthPortInit->rxDefQ]) == 0)
  61203. + {
  61204. + mvOsPrintf("EthPort #%d: rxDefQ (%d) must be created\n",
  61205. + portNo, pEthPortInit->rxDefQ);
  61206. + return NULL;
  61207. + }
  61208. +
  61209. + pPortCtrl = (ETH_PORT_CTRL*)mvOsMalloc( sizeof(ETH_PORT_CTRL) );
  61210. + if(pPortCtrl == NULL)
  61211. + {
  61212. + mvOsPrintf("EthDrv: Can't allocate %dB for port #%d control structure!\n",
  61213. + (int)sizeof(ETH_PORT_CTRL), portNo);
  61214. + return NULL;
  61215. + }
  61216. +
  61217. + memset(pPortCtrl, 0, sizeof(ETH_PORT_CTRL) );
  61218. + ethPortCtrl[portNo] = pPortCtrl;
  61219. +
  61220. + pPortCtrl->portState = MV_UNDEFINED_STATE;
  61221. +
  61222. + pPortCtrl->portNo = portNo;
  61223. +
  61224. + pPortCtrl->osHandle = pEthPortInit->osHandle;
  61225. +
  61226. + /* Copy Configuration parameters */
  61227. + pPortCtrl->portConfig.maxRxPktSize = pEthPortInit->maxRxPktSize;
  61228. + pPortCtrl->portConfig.rxDefQ = pEthPortInit->rxDefQ;
  61229. + pPortCtrl->portConfig.ejpMode = 0;
  61230. +
  61231. + for( queue=0; queue<MV_ETH_RX_Q_NUM; queue++ )
  61232. + {
  61233. + pPortCtrl->rxQueueConfig[queue].descrNum = pEthPortInit->rxDescrNum[queue];
  61234. + }
  61235. + for( queue=0; queue<MV_ETH_TX_Q_NUM; queue++ )
  61236. + {
  61237. + pPortCtrl->txQueueConfig[queue].descrNum = pEthPortInit->txDescrNum[queue];
  61238. + }
  61239. +
  61240. + mvEthPortDisable(pPortCtrl);
  61241. +
  61242. + /* Set the board information regarding PHY address */
  61243. + mvEthPhyAddrSet(pPortCtrl, mvBoardPhyAddrGet(portNo) );
  61244. +
  61245. + /* Create all requested RX queues */
  61246. + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
  61247. + {
  61248. + if(pPortCtrl->rxQueueConfig[queue].descrNum == 0)
  61249. + continue;
  61250. +
  61251. + /* Allocate memory for RX descriptors */
  61252. + descSize = ((pPortCtrl->rxQueueConfig[queue].descrNum * ETH_RX_DESC_ALIGNED_SIZE) +
  61253. + CPU_D_CACHE_LINE_SIZE);
  61254. +
  61255. + pPortCtrl->rxQueue[queue].descBuf.bufVirtPtr =
  61256. + ethAllocDescrMemory(pPortCtrl, descSize,
  61257. + &pPortCtrl->rxQueue[queue].descBuf.bufPhysAddr,
  61258. + &pPortCtrl->rxQueue[queue].descBuf.memHandle);
  61259. + pPortCtrl->rxQueue[queue].descBuf.bufSize = descSize;
  61260. + if(pPortCtrl->rxQueue[queue].descBuf.bufVirtPtr == NULL)
  61261. + {
  61262. + mvOsPrintf("EthPort #%d, rxQ=%d: Can't allocate %d bytes in %s for %d RX descr\n",
  61263. + pPortCtrl->portNo, queue, descSize,
  61264. + ethDescInSram ? "SRAM" : "DRAM",
  61265. + pPortCtrl->rxQueueConfig[queue].descrNum);
  61266. + return NULL;
  61267. + }
  61268. +
  61269. + ethInitRxDescRing(pPortCtrl, queue);
  61270. + }
  61271. + /* Create TX queues */
  61272. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  61273. + {
  61274. + if(pPortCtrl->txQueueConfig[queue].descrNum == 0)
  61275. + continue;
  61276. +
  61277. + /* Allocate memory for TX descriptors */
  61278. + descSize = ((pPortCtrl->txQueueConfig[queue].descrNum * ETH_TX_DESC_ALIGNED_SIZE) +
  61279. + CPU_D_CACHE_LINE_SIZE);
  61280. +
  61281. + pPortCtrl->txQueue[queue].descBuf.bufVirtPtr =
  61282. + ethAllocDescrMemory(pPortCtrl, descSize,
  61283. + &pPortCtrl->txQueue[queue].descBuf.bufPhysAddr,
  61284. + &pPortCtrl->txQueue[queue].descBuf.memHandle);
  61285. + pPortCtrl->txQueue[queue].descBuf.bufSize = descSize;
  61286. + if(pPortCtrl->txQueue[queue].descBuf.bufVirtPtr == NULL)
  61287. + {
  61288. + mvOsPrintf("EthPort #%d, txQ=%d: Can't allocate %d bytes in %s for %d TX descr\n",
  61289. + pPortCtrl->portNo, queue, descSize, ethDescInSram ? "SRAM" : "DRAM",
  61290. + pPortCtrl->txQueueConfig[queue].descrNum);
  61291. + return NULL;
  61292. + }
  61293. +
  61294. + ethInitTxDescRing(pPortCtrl, queue);
  61295. + }
  61296. + mvEthDefaultsSet(pPortCtrl);
  61297. +
  61298. + pPortCtrl->portState = MV_IDLE;
  61299. + return pPortCtrl;
  61300. +}
  61301. +
  61302. +/*******************************************************************************
  61303. +* ethPortFinish - Finish the Ethernet port driver
  61304. +*
  61305. +* DESCRIPTION:
  61306. +* This function finish the ethernet port.
  61307. +* 1) Down ethernet port if needed.
  61308. +* 2) Delete RX and TX descriptor rings for all created RX and TX queues
  61309. +* 3) Free internal port Control structure.
  61310. +*
  61311. +* INPUT:
  61312. +* void* pEthPortHndl - Ethernet port handler
  61313. +*
  61314. +* RETURN: NONE.
  61315. +*
  61316. +*******************************************************************************/
  61317. +void mvEthPortFinish(void* pPortHndl)
  61318. +{
  61319. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  61320. + int queue, portNo = pPortCtrl->portNo;
  61321. +
  61322. + if(pPortCtrl->portState == MV_ACTIVE)
  61323. + {
  61324. + mvOsPrintf("ethPort #%d: Warning !!! Finish port in Active state\n",
  61325. + portNo);
  61326. + mvEthPortDisable(pPortHndl);
  61327. + }
  61328. +
  61329. + /* Free all allocated RX queues */
  61330. + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
  61331. + {
  61332. + ethFreeDescrMemory(pPortCtrl, &pPortCtrl->rxQueue[queue].descBuf);
  61333. + }
  61334. +
  61335. + /* Free all allocated TX queues */
  61336. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  61337. + {
  61338. + ethFreeDescrMemory(pPortCtrl, &pPortCtrl->txQueue[queue].descBuf);
  61339. + }
  61340. +
  61341. + /* Free port control structure */
  61342. + mvOsFree(pPortCtrl);
  61343. +
  61344. + ethPortCtrl[portNo] = NULL;
  61345. +}
  61346. +
  61347. +/*******************************************************************************
  61348. +* mvEthDefaultsSet - Set defaults to the ethernet port
  61349. +*
  61350. +* DESCRIPTION:
  61351. +* This function set default values to the ethernet port.
  61352. +* 1) Clear Cause registers and Mask all interrupts
  61353. +* 2) Clear all MAC tables
  61354. +* 3) Set defaults to all registers
  61355. +* 4) Reset all created RX and TX descriptors ring
  61356. +* 5) Reset PHY
  61357. +*
  61358. +* INPUT:
  61359. +* void* pEthPortHndl - Ethernet port handler
  61360. +*
  61361. +* RETURN: MV_STATUS
  61362. +* MV_OK - Success, Others - Failure
  61363. +* NOTE:
  61364. +* This function update all the port configuration except those set
  61365. +* Initialy by the OsGlue by MV_ETH_PORT_INIT.
  61366. +* This function can be called after portDown to return the port setting
  61367. +* to defaults.
  61368. +*******************************************************************************/
  61369. +MV_STATUS mvEthDefaultsSet(void* pPortHndl)
  61370. +{
  61371. + int ethPortNo, queue;
  61372. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  61373. + ETH_QUEUE_CTRL* pQueueCtrl;
  61374. + MV_U32 txPrio;
  61375. + MV_U32 portCfgReg, portCfgExtReg, portSerialCtrlReg, portSerialCtrl1Reg, portSdmaCfgReg;
  61376. + MV_BOARD_MAC_SPEED boardMacCfg;
  61377. +
  61378. + ethPortNo = pPortCtrl->portNo;
  61379. +
  61380. + /* Clear Cause registers */
  61381. + MV_REG_WRITE(ETH_INTR_CAUSE_REG(ethPortNo),0);
  61382. + MV_REG_WRITE(ETH_INTR_CAUSE_EXT_REG(ethPortNo),0);
  61383. +
  61384. + /* Mask all interrupts */
  61385. + MV_REG_WRITE(ETH_INTR_MASK_REG(ethPortNo),0);
  61386. + MV_REG_WRITE(ETH_INTR_MASK_EXT_REG(ethPortNo),0);
  61387. +
  61388. + portCfgReg = PORT_CONFIG_VALUE;
  61389. + portCfgExtReg = PORT_CONFIG_EXTEND_VALUE;
  61390. +
  61391. + boardMacCfg = mvBoardMacSpeedGet(ethPortNo);
  61392. +
  61393. + if(boardMacCfg == BOARD_MAC_SPEED_100M)
  61394. + {
  61395. + portSerialCtrlReg = PORT_SERIAL_CONTROL_100MB_FORCE_VALUE;
  61396. + }
  61397. + else if(boardMacCfg == BOARD_MAC_SPEED_1000M)
  61398. + {
  61399. + portSerialCtrlReg = PORT_SERIAL_CONTROL_1000MB_FORCE_VALUE;
  61400. + }
  61401. + else
  61402. + {
  61403. + portSerialCtrlReg = PORT_SERIAL_CONTROL_VALUE;
  61404. + }
  61405. +
  61406. + /* build PORT_SDMA_CONFIG_REG */
  61407. + portSdmaCfgReg = ETH_TX_INTR_COAL_MASK(0);
  61408. + portSdmaCfgReg |= ETH_TX_BURST_SIZE_MASK(ETH_BURST_SIZE_16_64BIT_VALUE);
  61409. +
  61410. +#if ( (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WB) || \
  61411. + (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WT) )
  61412. + /* some devices have restricted RX burst size when using HW coherency */
  61413. + portSdmaCfgReg |= ETH_RX_BURST_SIZE_MASK(ETH_BURST_SIZE_4_64BIT_VALUE);
  61414. +#else
  61415. + portSdmaCfgReg |= ETH_RX_BURST_SIZE_MASK(ETH_BURST_SIZE_16_64BIT_VALUE);
  61416. +#endif
  61417. +
  61418. +#if defined(MV_CPU_BE)
  61419. + /* big endian */
  61420. +# if defined(MV_ARM)
  61421. + portSdmaCfgReg |= (ETH_RX_NO_DATA_SWAP_MASK |
  61422. + ETH_TX_NO_DATA_SWAP_MASK |
  61423. + ETH_DESC_SWAP_MASK);
  61424. +# elif defined(MV_PPC)
  61425. + portSdmaCfgReg |= (ETH_RX_DATA_SWAP_MASK |
  61426. + ETH_TX_DATA_SWAP_MASK |
  61427. + ETH_NO_DESC_SWAP_MASK);
  61428. +# else
  61429. +# error "Giga Ethernet Swap policy is not defined for the CPU_ARCH"
  61430. +# endif /* MV_ARM / MV_PPC */
  61431. +
  61432. +#else /* MV_CPU_LE */
  61433. + /* little endian */
  61434. + portSdmaCfgReg |= (ETH_RX_NO_DATA_SWAP_MASK |
  61435. + ETH_TX_NO_DATA_SWAP_MASK |
  61436. + ETH_NO_DESC_SWAP_MASK);
  61437. +#endif /* MV_CPU_BE / MV_CPU_LE */
  61438. +
  61439. + pPortCtrl->portRxQueueCmdReg = 0;
  61440. + pPortCtrl->portTxQueueCmdReg = 0;
  61441. +
  61442. +#if (MV_ETH_VERSION >= 4)
  61443. + if(pPortCtrl->portConfig.ejpMode == MV_TRUE)
  61444. + {
  61445. + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(ethPortNo), ETH_TX_EJP_ENABLE_MASK);
  61446. + }
  61447. + else
  61448. + {
  61449. + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(ethPortNo), 0)
  61450. + }
  61451. +#endif /* (MV_ETH_VERSION >= 4) */
  61452. +
  61453. + ethSetUcastTable(ethPortNo, -1);
  61454. + mvEthSetSpecialMcastTable(ethPortNo, -1);
  61455. + mvEthSetOtherMcastTable(ethPortNo, -1);
  61456. +
  61457. + portSerialCtrlReg &= ~ETH_MAX_RX_PACKET_SIZE_MASK;
  61458. +
  61459. + portSerialCtrlReg |= mvEthMruGet(pPortCtrl->portConfig.maxRxPktSize);
  61460. +
  61461. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNo), portSerialCtrlReg);
  61462. +
  61463. + /* Update value of PortConfig register accordingly with all RxQueue types */
  61464. + pPortCtrl->portConfig.rxArpQ = pPortCtrl->portConfig.rxDefQ;
  61465. + pPortCtrl->portConfig.rxBpduQ = pPortCtrl->portConfig.rxDefQ;
  61466. + pPortCtrl->portConfig.rxTcpQ = pPortCtrl->portConfig.rxDefQ;
  61467. + pPortCtrl->portConfig.rxUdpQ = pPortCtrl->portConfig.rxDefQ;
  61468. +
  61469. + portCfgReg &= ~ETH_DEF_RX_QUEUE_ALL_MASK;
  61470. + portCfgReg |= ETH_DEF_RX_QUEUE_MASK(pPortCtrl->portConfig.rxDefQ);
  61471. +
  61472. + portCfgReg &= ~ETH_DEF_RX_ARP_QUEUE_ALL_MASK;
  61473. + portCfgReg |= ETH_DEF_RX_ARP_QUEUE_MASK(pPortCtrl->portConfig.rxArpQ);
  61474. +
  61475. + portCfgReg &= ~ETH_DEF_RX_BPDU_QUEUE_ALL_MASK;
  61476. + portCfgReg |= ETH_DEF_RX_BPDU_QUEUE_MASK(pPortCtrl->portConfig.rxBpduQ);
  61477. +
  61478. + portCfgReg &= ~ETH_DEF_RX_TCP_QUEUE_ALL_MASK;
  61479. + portCfgReg |= ETH_DEF_RX_TCP_QUEUE_MASK(pPortCtrl->portConfig.rxTcpQ);
  61480. +
  61481. + portCfgReg &= ~ETH_DEF_RX_UDP_QUEUE_ALL_MASK;
  61482. + portCfgReg |= ETH_DEF_RX_UDP_QUEUE_MASK(pPortCtrl->portConfig.rxUdpQ);
  61483. +
  61484. + /* Assignment of Tx CTRP of given queue */
  61485. + txPrio = 0;
  61486. +
  61487. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  61488. + {
  61489. + pQueueCtrl = &pPortCtrl->txQueue[queue];
  61490. +
  61491. + if(pQueueCtrl->pFirstDescr != NULL)
  61492. + {
  61493. + ethResetTxDescRing(pPortCtrl, queue);
  61494. +
  61495. + MV_REG_WRITE(ETH_TXQ_TOKEN_COUNT_REG(ethPortNo, queue),
  61496. + 0x3fffffff);
  61497. + MV_REG_WRITE(ETH_TXQ_TOKEN_CFG_REG(ethPortNo, queue),
  61498. + 0x03ffffff);
  61499. + }
  61500. + else
  61501. + {
  61502. + MV_REG_WRITE(ETH_TXQ_TOKEN_COUNT_REG(ethPortNo, queue), 0x0);
  61503. + MV_REG_WRITE(ETH_TXQ_TOKEN_CFG_REG(ethPortNo, queue), 0x0);
  61504. + }
  61505. + }
  61506. +
  61507. + /* Assignment of Rx CRDP of given queue */
  61508. + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
  61509. + {
  61510. + ethResetRxDescRing(pPortCtrl, queue);
  61511. + }
  61512. +
  61513. + /* Allow receiving packes with odd number of preamble nibbles */
  61514. + portSerialCtrl1Reg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(ethPortNo));
  61515. + portSerialCtrl1Reg |= ETH_EN_MII_ODD_PRE_MASK;
  61516. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(ethPortNo), portSerialCtrl1Reg);
  61517. +
  61518. + /* Assign port configuration and command. */
  61519. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(ethPortNo), portCfgReg);
  61520. +
  61521. + MV_REG_WRITE(ETH_PORT_CONFIG_EXTEND_REG(ethPortNo), portCfgExtReg);
  61522. +
  61523. + /* Assign port SDMA configuration */
  61524. + MV_REG_WRITE(ETH_SDMA_CONFIG_REG(ethPortNo), portSdmaCfgReg);
  61525. +
  61526. + /* Turn off the port/queue bandwidth limitation */
  61527. + MV_REG_WRITE(ETH_MAX_TRANSMIT_UNIT_REG(ethPortNo), 0x0);
  61528. +
  61529. + return MV_OK;
  61530. +}
  61531. +
  61532. +/*******************************************************************************
  61533. +* ethPortUp - Start the Ethernet port RX and TX activity.
  61534. +*
  61535. +* DESCRIPTION:
  61536. +* This routine start Rx and Tx activity:
  61537. +*
  61538. +* Note: Each Rx and Tx queue descriptor's list must be initialized prior
  61539. +* to calling this function (use etherInitTxDescRing for Tx queues and
  61540. +* etherInitRxDescRing for Rx queues).
  61541. +*
  61542. +* INPUT:
  61543. +* void* pEthPortHndl - Ethernet port handler
  61544. +*
  61545. +* RETURN: MV_STATUS
  61546. +* MV_OK - Success, Others - Failure.
  61547. +*
  61548. +* NOTE : used for port link up.
  61549. +*******************************************************************************/
  61550. +MV_STATUS mvEthPortUp(void* pEthPortHndl)
  61551. +{
  61552. + int ethPortNo;
  61553. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  61554. +
  61555. + ethPortNo = pPortCtrl->portNo;
  61556. +
  61557. + if( (pPortCtrl->portState != MV_ACTIVE) &&
  61558. + (pPortCtrl->portState != MV_PAUSED) )
  61559. + {
  61560. + mvOsPrintf("ethDrv port%d: Unexpected port state %d\n",
  61561. + ethPortNo, pPortCtrl->portState);
  61562. + return MV_BAD_STATE;
  61563. + }
  61564. +
  61565. + ethPortNo = pPortCtrl->portNo;
  61566. +
  61567. + /* Enable port RX. */
  61568. + MV_REG_WRITE(ETH_RX_QUEUE_COMMAND_REG(ethPortNo), pPortCtrl->portRxQueueCmdReg);
  61569. +
  61570. + /* Enable port TX. */
  61571. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(ethPortNo)) = pPortCtrl->portTxQueueCmdReg;
  61572. +
  61573. + pPortCtrl->portState = MV_ACTIVE;
  61574. +
  61575. + return MV_OK;
  61576. +}
  61577. +
  61578. +/*******************************************************************************
  61579. +* ethPortDown - Stop the Ethernet port activity.
  61580. +*
  61581. +* DESCRIPTION:
  61582. +*
  61583. +* INPUT:
  61584. +* void* pEthPortHndl - Ethernet port handler
  61585. +*
  61586. +* RETURN: MV_STATUS
  61587. +* MV_OK - Success, Others - Failure.
  61588. +*
  61589. +* NOTE : used for port link down.
  61590. +*******************************************************************************/
  61591. +MV_STATUS mvEthPortDown(void* pEthPortHndl)
  61592. +{
  61593. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  61594. + int ethPortNum = pPortCtrl->portNo;
  61595. + unsigned int regData;
  61596. + volatile int uDelay, mDelay;
  61597. +
  61598. + /* Stop Rx port activity. Check port Rx activity. */
  61599. + regData = (MV_REG_READ(ETH_RX_QUEUE_COMMAND_REG(ethPortNum))) & ETH_RXQ_ENABLE_MASK;
  61600. + if(regData != 0)
  61601. + {
  61602. + /* Issue stop command for active channels only */
  61603. + MV_REG_WRITE(ETH_RX_QUEUE_COMMAND_REG(ethPortNum), (regData << ETH_RXQ_DISABLE_OFFSET));
  61604. + }
  61605. +
  61606. + /* Stop Tx port activity. Check port Tx activity. */
  61607. + regData = (MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(ethPortNum))) & ETH_TXQ_ENABLE_MASK;
  61608. + if(regData != 0)
  61609. + {
  61610. + /* Issue stop command for active channels only */
  61611. + MV_REG_WRITE(ETH_TX_QUEUE_COMMAND_REG(ethPortNum),
  61612. + (regData << ETH_TXQ_DISABLE_OFFSET) );
  61613. + }
  61614. +
  61615. + /* Force link down */
  61616. +/*
  61617. + regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));
  61618. + regData &= ~(ETH_DO_NOT_FORCE_LINK_FAIL_MASK);
  61619. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);
  61620. +*/
  61621. + /* Wait for all Rx activity to terminate. */
  61622. + mDelay = 0;
  61623. + do
  61624. + {
  61625. + if(mDelay >= RX_DISABLE_TIMEOUT_MSEC)
  61626. + {
  61627. + mvOsPrintf("ethPort_%d: TIMEOUT for RX stopped !!! rxQueueCmd - 0x08%x\n",
  61628. + ethPortNum, regData);
  61629. + break;
  61630. + }
  61631. + mvOsDelay(1);
  61632. + mDelay++;
  61633. +
  61634. + /* Check port RX Command register that all Rx queues are stopped */
  61635. + regData = MV_REG_READ(ETH_RX_QUEUE_COMMAND_REG(ethPortNum));
  61636. + }
  61637. + while(regData & 0xFF);
  61638. +
  61639. + /* Wait for all Tx activity to terminate. */
  61640. + mDelay = 0;
  61641. + do
  61642. + {
  61643. + if(mDelay >= TX_DISABLE_TIMEOUT_MSEC)
  61644. + {
  61645. + mvOsPrintf("ethPort_%d: TIMEOUT for TX stoped !!! txQueueCmd - 0x08%x\n",
  61646. + ethPortNum, regData);
  61647. + break;
  61648. + }
  61649. + mvOsDelay(1);
  61650. + mDelay++;
  61651. +
  61652. + /* Check port TX Command register that all Tx queues are stopped */
  61653. + regData = MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(ethPortNum));
  61654. + }
  61655. + while(regData & 0xFF);
  61656. +
  61657. + /* Double check to Verify that TX FIFO is Empty */
  61658. + mDelay = 0;
  61659. + while(MV_TRUE)
  61660. + {
  61661. + do
  61662. + {
  61663. + if(mDelay >= TX_FIFO_EMPTY_TIMEOUT_MSEC)
  61664. + {
  61665. + mvOsPrintf("\n ethPort_%d: TIMEOUT for TX FIFO empty !!! portStatus - 0x08%x\n",
  61666. + ethPortNum, regData);
  61667. + break;
  61668. + }
  61669. + mvOsDelay(1);
  61670. + mDelay++;
  61671. +
  61672. + regData = MV_REG_READ(ETH_PORT_STATUS_REG(ethPortNum));
  61673. + }
  61674. + while( ((regData & ETH_TX_FIFO_EMPTY_MASK) == 0) ||
  61675. + ((regData & ETH_TX_IN_PROGRESS_MASK) != 0) );
  61676. +
  61677. + if(mDelay >= TX_FIFO_EMPTY_TIMEOUT_MSEC)
  61678. + break;
  61679. +
  61680. + /* Double check */
  61681. + regData = MV_REG_READ(ETH_PORT_STATUS_REG(ethPortNum));
  61682. + if( ((regData & ETH_TX_FIFO_EMPTY_MASK) != 0) &&
  61683. + ((regData & ETH_TX_IN_PROGRESS_MASK) == 0) )
  61684. + {
  61685. + break;
  61686. + }
  61687. + else
  61688. + mvOsPrintf("ethPort_%d: TX FIFO Empty double check failed. %d msec, portStatus=0x%x\n",
  61689. + ethPortNum, mDelay, regData);
  61690. + }
  61691. +
  61692. + /* Do NOT force link down */
  61693. +/*
  61694. + regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));
  61695. + regData |= (ETH_DO_NOT_FORCE_LINK_FAIL_MASK);
  61696. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);
  61697. +*/
  61698. + /* Wait about 2500 tclk cycles */
  61699. + uDelay = (PORT_DISABLE_WAIT_TCLOCKS/(mvBoardTclkGet()/1000000));
  61700. + mvOsUDelay(uDelay);
  61701. +
  61702. + pPortCtrl->portState = MV_PAUSED;
  61703. +
  61704. + return MV_OK;
  61705. +}
  61706. +
  61707. +
  61708. +/*******************************************************************************
  61709. +* ethPortEnable - Enable the Ethernet port and Start RX and TX.
  61710. +*
  61711. +* DESCRIPTION:
  61712. +* This routine enable the Ethernet port and Rx and Tx activity:
  61713. +*
  61714. +* Note: Each Rx and Tx queue descriptor's list must be initialized prior
  61715. +* to calling this function (use etherInitTxDescRing for Tx queues and
  61716. +* etherInitRxDescRing for Rx queues).
  61717. +*
  61718. +* INPUT:
  61719. +* void* pEthPortHndl - Ethernet port handler
  61720. +*
  61721. +* RETURN: MV_STATUS
  61722. +* MV_OK - Success, Others - Failure.
  61723. +*
  61724. +* NOTE: main usage is to enable the port after ifconfig up.
  61725. +*******************************************************************************/
  61726. +MV_STATUS mvEthPortEnable(void* pEthPortHndl)
  61727. +{
  61728. + int ethPortNo;
  61729. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  61730. + MV_U32 portSerialCtrlReg;
  61731. +
  61732. + ethPortNo = pPortCtrl->portNo;
  61733. +
  61734. + /* Enable port */
  61735. + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNo));
  61736. + portSerialCtrlReg |= (ETH_DO_NOT_FORCE_LINK_FAIL_MASK | ETH_PORT_ENABLE_MASK);
  61737. +
  61738. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNo), portSerialCtrlReg);
  61739. +
  61740. + mvEthMibCountersClear(pEthPortHndl);
  61741. +
  61742. + pPortCtrl->portState = MV_PAUSED;
  61743. +
  61744. + /* If Link is UP, Start RX and TX traffic */
  61745. + if( MV_REG_READ( ETH_PORT_STATUS_REG(ethPortNo) ) & ETH_LINK_UP_MASK)
  61746. + return( mvEthPortUp(pEthPortHndl) );
  61747. +
  61748. + return MV_NOT_READY;
  61749. +}
  61750. +
  61751. +
  61752. +/*******************************************************************************
  61753. +* mvEthPortDisable - Stop RX and TX activities and Disable the Ethernet port.
  61754. +*
  61755. +* DESCRIPTION:
  61756. +*
  61757. +* INPUT:
  61758. +* void* pEthPortHndl - Ethernet port handler
  61759. +*
  61760. +* RETURN: MV_STATUS
  61761. +* MV_OK - Success, Others - Failure.
  61762. +*
  61763. +* NOTE: main usage is to disable the port after ifconfig down.
  61764. +*******************************************************************************/
  61765. +MV_STATUS mvEthPortDisable(void* pEthPortHndl)
  61766. +{
  61767. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  61768. + int ethPortNum = pPortCtrl->portNo;
  61769. + unsigned int regData;
  61770. + volatile int mvDelay;
  61771. +
  61772. + if(pPortCtrl->portState == MV_ACTIVE)
  61773. + {
  61774. + /* Stop RX and TX activities */
  61775. + mvEthPortDown(pEthPortHndl);
  61776. + }
  61777. +
  61778. + /* Reset the Enable bit in the Serial Control Register */
  61779. + regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));
  61780. + regData &= ~(ETH_PORT_ENABLE_MASK);
  61781. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);
  61782. +
  61783. + /* Wait about 2500 tclk cycles */
  61784. + mvDelay = (PORT_DISABLE_WAIT_TCLOCKS*(mvCpuPclkGet()/mvBoardTclkGet()));
  61785. + for(mvDelay; mvDelay>0; mvDelay--);
  61786. +
  61787. + pPortCtrl->portState = MV_IDLE;
  61788. + return MV_OK;
  61789. +}
  61790. +
  61791. +/*******************************************************************************
  61792. +* mvEthPortForceTxDone - Get next buffer from TX queue in spite of buffer ownership.
  61793. +*
  61794. +* DESCRIPTION:
  61795. +* This routine used to free buffers attached to the Tx ring and should
  61796. +* be called only when Giga Ethernet port is Down
  61797. +*
  61798. +* INPUT:
  61799. +* void* pEthPortHndl - Ethernet Port handler.
  61800. +* int txQueue - Number of TX queue.
  61801. +*
  61802. +* OUTPUT:
  61803. +* MV_PKT_INFO *pPktInfo - Pointer to packet was sent.
  61804. +*
  61805. +* RETURN:
  61806. +* MV_EMPTY - There is no more buffers in this queue.
  61807. +* MV_OK - Buffer detached from the queue and pPktInfo structure
  61808. +* filled with relevant information.
  61809. +*
  61810. +*******************************************************************************/
  61811. +MV_PKT_INFO* mvEthPortForceTxDone(void* pEthPortHndl, int txQueue)
  61812. +{
  61813. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  61814. + ETH_QUEUE_CTRL* pQueueCtrl;
  61815. + MV_PKT_INFO* pPktInfo;
  61816. + ETH_TX_DESC* pTxDesc;
  61817. + int port = pPortCtrl->portNo;
  61818. +
  61819. + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  61820. +
  61821. + while( (pQueueCtrl->pUsedDescr != pQueueCtrl->pCurrentDescr) ||
  61822. + (pQueueCtrl->resource == 0) )
  61823. + {
  61824. + /* Free next descriptor */
  61825. + pQueueCtrl->resource++;
  61826. + pTxDesc = (ETH_TX_DESC*)pQueueCtrl->pUsedDescr;
  61827. +
  61828. + /* pPktInfo is available only in descriptors which are last descriptors */
  61829. + pPktInfo = (MV_PKT_INFO*)pTxDesc->returnInfo;
  61830. + if (pPktInfo)
  61831. + pPktInfo->status = pTxDesc->cmdSts;
  61832. +
  61833. + pTxDesc->cmdSts = 0x0;
  61834. + pTxDesc->returnInfo = 0x0;
  61835. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxDesc);
  61836. +
  61837. + pQueueCtrl->pUsedDescr = TX_NEXT_DESC_PTR(pTxDesc, pQueueCtrl);
  61838. +
  61839. + if (pPktInfo)
  61840. + if (pPktInfo->status & ETH_TX_LAST_DESC_MASK)
  61841. + return pPktInfo;
  61842. + }
  61843. + MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(port, txQueue),
  61844. + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
  61845. + return NULL;
  61846. +}
  61847. +
  61848. +
  61849. +
  61850. +/*******************************************************************************
  61851. +* mvEthPortForceRx - Get next buffer from RX queue in spite of buffer ownership.
  61852. +*
  61853. +* DESCRIPTION:
  61854. +* This routine used to free buffers attached to the Rx ring and should
  61855. +* be called only when Giga Ethernet port is Down
  61856. +*
  61857. +* INPUT:
  61858. +* void* pEthPortHndl - Ethernet Port handler.
  61859. +* int rxQueue - Number of Rx queue.
  61860. +*
  61861. +* OUTPUT:
  61862. +* MV_PKT_INFO *pPktInfo - Pointer to received packet.
  61863. +*
  61864. +* RETURN:
  61865. +* MV_EMPTY - There is no more buffers in this queue.
  61866. +* MV_OK - Buffer detached from the queue and pBufInfo structure
  61867. +* filled with relevant information.
  61868. +*
  61869. +*******************************************************************************/
  61870. +MV_PKT_INFO* mvEthPortForceRx(void* pEthPortHndl, int rxQueue)
  61871. +{
  61872. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  61873. + ETH_QUEUE_CTRL* pQueueCtrl;
  61874. + ETH_RX_DESC* pRxDesc;
  61875. + MV_PKT_INFO* pPktInfo;
  61876. + int port = pPortCtrl->portNo;
  61877. +
  61878. + pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];
  61879. +
  61880. + if(pQueueCtrl->resource == 0)
  61881. + {
  61882. + MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(port, rxQueue),
  61883. + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
  61884. +
  61885. + return NULL;
  61886. + }
  61887. + /* Free next descriptor */
  61888. + pQueueCtrl->resource--;
  61889. + pRxDesc = (ETH_RX_DESC*)pQueueCtrl->pCurrentDescr;
  61890. + pPktInfo = (MV_PKT_INFO*)pRxDesc->returnInfo;
  61891. +
  61892. + pPktInfo->status = pRxDesc->cmdSts;
  61893. + pRxDesc->cmdSts = 0x0;
  61894. + pRxDesc->returnInfo = 0x0;
  61895. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxDesc);
  61896. +
  61897. + pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxDesc, pQueueCtrl);
  61898. + return pPktInfo;
  61899. +}
  61900. +
  61901. +
  61902. +/******************************************************************************/
  61903. +/* Port Configuration functions */
  61904. +/******************************************************************************/
  61905. +/*******************************************************************************
  61906. +* mvEthMruGet - Get MRU configuration for Max Rx packet size.
  61907. +*
  61908. +* INPUT:
  61909. +* MV_U32 maxRxPktSize - max packet size.
  61910. +*
  61911. +* RETURN: MV_U32 - MRU configuration.
  61912. +*
  61913. +*******************************************************************************/
  61914. +static MV_U32 mvEthMruGet(MV_U32 maxRxPktSize)
  61915. +{
  61916. + MV_U32 portSerialCtrlReg = 0;
  61917. +
  61918. + if(maxRxPktSize > 9192)
  61919. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_9700BYTE;
  61920. + else if(maxRxPktSize > 9022)
  61921. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_9192BYTE;
  61922. + else if(maxRxPktSize > 1552)
  61923. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_9022BYTE;
  61924. + else if(maxRxPktSize > 1522)
  61925. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_1552BYTE;
  61926. + else if(maxRxPktSize > 1518)
  61927. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_1522BYTE;
  61928. + else
  61929. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_1518BYTE;
  61930. +
  61931. + return portSerialCtrlReg;
  61932. +}
  61933. +
  61934. +/*******************************************************************************
  61935. +* mvEthRxCoalSet - Sets coalescing interrupt mechanism on RX path
  61936. +*
  61937. +* DESCRIPTION:
  61938. +* This routine sets the RX coalescing interrupt mechanism parameter.
  61939. +* This parameter is a timeout counter, that counts in 64 tClk
  61940. +* chunks, that when timeout event occurs a maskable interrupt occurs.
  61941. +* The parameter is calculated using the tCLK frequency of the
  61942. +* MV-64xxx chip, and the required number is in micro seconds.
  61943. +*
  61944. +* INPUT:
  61945. +* void* pPortHndl - Ethernet Port handler.
  61946. +* MV_U32 uSec - Number of micro seconds between
  61947. +* RX interrupts
  61948. +*
  61949. +* RETURN:
  61950. +* None.
  61951. +*
  61952. +* COMMENT:
  61953. +* 1 sec - TCLK_RATE clocks
  61954. +* 1 uSec - TCLK_RATE / 1,000,000 clocks
  61955. +*
  61956. +* Register Value for N micro seconds - ((N * ( (TCLK_RATE / 1,000,000)) / 64)
  61957. +*
  61958. +* RETURN:
  61959. +* None.
  61960. +*
  61961. +*******************************************************************************/
  61962. +MV_U32 mvEthRxCoalSet (void* pPortHndl, MV_U32 uSec)
  61963. +{
  61964. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  61965. + MV_U32 coal = ((uSec * (mvBoardTclkGet() / 1000000)) / 64);
  61966. + MV_U32 portSdmaCfgReg;
  61967. +
  61968. + portSdmaCfgReg = MV_REG_READ(ETH_SDMA_CONFIG_REG(pPortCtrl->portNo));
  61969. + portSdmaCfgReg &= ~ETH_RX_INTR_COAL_ALL_MASK;
  61970. +
  61971. + portSdmaCfgReg |= ETH_RX_INTR_COAL_MASK(coal);
  61972. +
  61973. +#if (MV_ETH_VERSION >= 2)
  61974. + /* Set additional bit if needed ETH_RX_INTR_COAL_MSB_BIT (25) */
  61975. + if(ETH_RX_INTR_COAL_MASK(coal) > ETH_RX_INTR_COAL_ALL_MASK)
  61976. + portSdmaCfgReg |= ETH_RX_INTR_COAL_MSB_MASK;
  61977. +#endif /* MV_ETH_VERSION >= 2 */
  61978. +
  61979. + MV_REG_WRITE (ETH_SDMA_CONFIG_REG(pPortCtrl->portNo), portSdmaCfgReg);
  61980. + return coal;
  61981. +}
  61982. +
  61983. +/*******************************************************************************
  61984. +* mvEthTxCoalSet - Sets coalescing interrupt mechanism on TX path
  61985. +*
  61986. +* DESCRIPTION:
  61987. +* This routine sets the TX coalescing interrupt mechanism parameter.
  61988. +* This parameter is a timeout counter, that counts in 64 tClk
  61989. +* chunks, that when timeout event occurs a maskable interrupt
  61990. +* occurs.
  61991. +* The parameter is calculated using the tCLK frequency of the
  61992. +* MV-64xxx chip, and the required number is in micro seconds.
  61993. +*
  61994. +* INPUT:
  61995. +* void* pPortHndl - Ethernet Port handler.
  61996. +* MV_U32 uSec - Number of micro seconds between
  61997. +* RX interrupts
  61998. +*
  61999. +* RETURN:
  62000. +* None.
  62001. +*
  62002. +* COMMENT:
  62003. +* 1 sec - TCLK_RATE clocks
  62004. +* 1 uSec - TCLK_RATE / 1,000,000 clocks
  62005. +*
  62006. +* Register Value for N micro seconds - ((N * ( (TCLK_RATE / 1,000,000)) / 64)
  62007. +*
  62008. +*******************************************************************************/
  62009. +MV_U32 mvEthTxCoalSet(void* pPortHndl, MV_U32 uSec)
  62010. +{
  62011. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  62012. + MV_U32 coal = ((uSec * (mvBoardTclkGet() / 1000000)) / 64);
  62013. + MV_U32 regVal;
  62014. +
  62015. + regVal = MV_REG_READ(ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo));
  62016. + regVal &= ~ETH_TX_INTR_COAL_ALL_MASK;
  62017. + regVal |= ETH_TX_INTR_COAL_MASK(coal);
  62018. +
  62019. + /* Set TX Coalescing mechanism */
  62020. + MV_REG_WRITE (ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo), regVal);
  62021. + return coal;
  62022. +}
  62023. +
  62024. +/*******************************************************************************
  62025. +* mvEthCoalGet - Gets RX and TX coalescing values in micro seconds
  62026. +*
  62027. +* DESCRIPTION:
  62028. +* This routine gets the RX and TX coalescing interrupt values.
  62029. +* The parameter is calculated using the tCLK frequency of the
  62030. +* MV-64xxx chip, and the returned numbers are in micro seconds.
  62031. +*
  62032. +* INPUTs:
  62033. +* void* pPortHndl - Ethernet Port handler.
  62034. +*
  62035. +* OUTPUTs:
  62036. +* MV_U32* pRxCoal - Number of micro seconds between RX interrupts
  62037. +* MV_U32* pTxCoal - Number of micro seconds between TX interrupts
  62038. +*
  62039. +* RETURN:
  62040. +* MV_STATUS MV_OK - success
  62041. +* Others - failure.
  62042. +*
  62043. +* COMMENT:
  62044. +* 1 sec - TCLK_RATE clocks
  62045. +* 1 uSec - TCLK_RATE / 1,000,000 clocks
  62046. +*
  62047. +* Register Value for N micro seconds - ((N * ( (TCLK_RATE / 1,000,000)) / 64)
  62048. +*
  62049. +*******************************************************************************/
  62050. +MV_STATUS mvEthCoalGet(void* pPortHndl, MV_U32* pRxCoal, MV_U32* pTxCoal)
  62051. +{
  62052. + MV_U32 regVal, coal, usec;
  62053. +
  62054. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  62055. +
  62056. + /* get TX Coalescing */
  62057. + regVal = MV_REG_READ (ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo));
  62058. + coal = ((regVal & ETH_TX_INTR_COAL_ALL_MASK) >> ETH_TX_INTR_COAL_OFFSET);
  62059. +
  62060. + usec = (coal * 64) / (mvBoardTclkGet() / 1000000);
  62061. + if(pTxCoal != NULL)
  62062. + *pTxCoal = usec;
  62063. +
  62064. + /* Get RX Coalescing */
  62065. + regVal = MV_REG_READ(ETH_SDMA_CONFIG_REG(pPortCtrl->portNo));
  62066. + coal = ((regVal & ETH_RX_INTR_COAL_ALL_MASK) >> ETH_RX_INTR_COAL_OFFSET);
  62067. +
  62068. +#if (MV_ETH_VERSION >= 2)
  62069. + if(regVal & ETH_RX_INTR_COAL_MSB_MASK)
  62070. + {
  62071. + /* Add MSB */
  62072. + coal |= (ETH_RX_INTR_COAL_ALL_MASK + 1);
  62073. + }
  62074. +#endif /* MV_ETH_VERSION >= 2 */
  62075. +
  62076. + usec = (coal * 64) / (mvBoardTclkGet() / 1000000);
  62077. + if(pRxCoal != NULL)
  62078. + *pRxCoal = usec;
  62079. +
  62080. + return MV_OK;
  62081. +}
  62082. +
  62083. +/*******************************************************************************
  62084. +* mvEthMaxRxSizeSet -
  62085. +*
  62086. +* DESCRIPTION:
  62087. +* Change maximum receive size of the port. This configuration will take place
  62088. +* after next call of ethPortSetDefaults() function.
  62089. +*
  62090. +* INPUT:
  62091. +*
  62092. +* RETURN:
  62093. +*******************************************************************************/
  62094. +MV_STATUS mvEthMaxRxSizeSet(void* pPortHndl, int maxRxSize)
  62095. +{
  62096. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  62097. + MV_U32 portSerialCtrlReg;
  62098. +
  62099. + if((maxRxSize < 1518) || (maxRxSize & ~ETH_RX_BUFFER_MASK))
  62100. + return MV_BAD_PARAM;
  62101. +
  62102. + pPortCtrl->portConfig.maxRxPktSize = maxRxSize;
  62103. +
  62104. + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(pPortCtrl->portNo));
  62105. + portSerialCtrlReg &= ~ETH_MAX_RX_PACKET_SIZE_MASK;
  62106. + portSerialCtrlReg |= mvEthMruGet(pPortCtrl->portConfig.maxRxPktSize);
  62107. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(pPortCtrl->portNo), portSerialCtrlReg);
  62108. +
  62109. + return MV_OK;
  62110. +}
  62111. +
  62112. +
  62113. +/******************************************************************************/
  62114. +/* MAC Filtering functions */
  62115. +/******************************************************************************/
  62116. +
  62117. +/*******************************************************************************
  62118. +* mvEthRxFilterModeSet - Configure Fitering mode of Ethernet port
  62119. +*
  62120. +* DESCRIPTION:
  62121. +* This routine used to free buffers attached to the Rx ring and should
  62122. +* be called only when Giga Ethernet port is Down
  62123. +*
  62124. +* INPUT:
  62125. +* void* pEthPortHndl - Ethernet Port handler.
  62126. +* MV_BOOL isPromisc - Promiscous mode
  62127. +* MV_TRUE - accept all Broadcast, Multicast
  62128. +* and Unicast packets
  62129. +* MV_FALSE - accept all Broadcast,
  62130. +* specially added Multicast and
  62131. +* single Unicast packets
  62132. +*
  62133. +* RETURN: MV_STATUS MV_OK - Success, Other - Failure
  62134. +*
  62135. +*******************************************************************************/
  62136. +MV_STATUS mvEthRxFilterModeSet(void* pEthPortHndl, MV_BOOL isPromisc)
  62137. +{
  62138. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  62139. + int queue;
  62140. + MV_U32 portCfgReg;
  62141. +
  62142. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  62143. + /* Set / Clear UPM bit in port configuration register */
  62144. + if(isPromisc)
  62145. + {
  62146. + /* Accept all multicast packets to RX default queue */
  62147. + queue = pPortCtrl->portConfig.rxDefQ;
  62148. + portCfgReg |= ETH_UNICAST_PROMISCUOUS_MODE_MASK;
  62149. + memset(pPortCtrl->mcastCount, 1, sizeof(pPortCtrl->mcastCount));
  62150. + MV_REG_WRITE(ETH_MAC_ADDR_LOW_REG(pPortCtrl->portNo),0xFFFF);
  62151. + MV_REG_WRITE(ETH_MAC_ADDR_HIGH_REG(pPortCtrl->portNo),0xFFFFFFFF);
  62152. + }
  62153. + else
  62154. + {
  62155. + /* Reject all Multicast addresses */
  62156. + queue = -1;
  62157. + portCfgReg &= ~ETH_UNICAST_PROMISCUOUS_MODE_MASK;
  62158. + /* Clear all mcastCount */
  62159. + memset(pPortCtrl->mcastCount, 0, sizeof(pPortCtrl->mcastCount));
  62160. + }
  62161. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  62162. +
  62163. + /* Set Special Multicast and Other Multicast tables */
  62164. + mvEthSetSpecialMcastTable(pPortCtrl->portNo, queue);
  62165. + mvEthSetOtherMcastTable(pPortCtrl->portNo, queue);
  62166. + ethSetUcastTable(pPortCtrl->portNo, queue);
  62167. +
  62168. + return MV_OK;
  62169. +}
  62170. +
  62171. +/*******************************************************************************
  62172. +* mvEthMacAddrSet - This function Set the port Unicast address.
  62173. +*
  62174. +* DESCRIPTION:
  62175. +* This function Set the port Ethernet MAC address. This address
  62176. +* will be used to send Pause frames if enabled. Packets with this
  62177. +* address will be accepted and dispatched to default RX queue
  62178. +*
  62179. +* INPUT:
  62180. +* void* pEthPortHndl - Ethernet port handler.
  62181. +* char* pAddr - Address to be set
  62182. +*
  62183. +* RETURN: MV_STATUS
  62184. +* MV_OK - Success, Other - Faulure
  62185. +*
  62186. +*******************************************************************************/
  62187. +MV_STATUS mvEthMacAddrSet(void* pPortHndl, unsigned char *pAddr, int queue)
  62188. +{
  62189. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  62190. + unsigned int macH;
  62191. + unsigned int macL;
  62192. +
  62193. + if(queue >= MV_ETH_RX_Q_NUM)
  62194. + {
  62195. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", queue);
  62196. + return MV_BAD_PARAM;
  62197. + }
  62198. +
  62199. + if(queue != -1)
  62200. + {
  62201. + macL = (pAddr[4] << 8) | (pAddr[5]);
  62202. + macH = (pAddr[0] << 24)| (pAddr[1] << 16) |
  62203. + (pAddr[2] << 8) | (pAddr[3] << 0);
  62204. +
  62205. + MV_REG_WRITE(ETH_MAC_ADDR_LOW_REG(pPortCtrl->portNo), macL);
  62206. + MV_REG_WRITE(ETH_MAC_ADDR_HIGH_REG(pPortCtrl->portNo), macH);
  62207. + }
  62208. +
  62209. + /* Accept frames of this address */
  62210. + ethSetUcastAddr(pPortCtrl->portNo, pAddr[5], queue);
  62211. +
  62212. + return MV_OK;
  62213. +}
  62214. +
  62215. +/*******************************************************************************
  62216. +* mvEthMacAddrGet - This function returns the port Unicast address.
  62217. +*
  62218. +* DESCRIPTION:
  62219. +* This function returns the port Ethernet MAC address.
  62220. +*
  62221. +* INPUT:
  62222. +* int portNo - Ethernet port number.
  62223. +* char* pAddr - Pointer where address will be written to
  62224. +*
  62225. +* RETURN: MV_STATUS
  62226. +* MV_OK - Success, Other - Faulure
  62227. +*
  62228. +*******************************************************************************/
  62229. +MV_STATUS mvEthMacAddrGet(int portNo, unsigned char *pAddr)
  62230. +{
  62231. + unsigned int macH;
  62232. + unsigned int macL;
  62233. +
  62234. + if(pAddr == NULL)
  62235. + {
  62236. + mvOsPrintf("mvEthMacAddrGet: NULL pointer.\n");
  62237. + return MV_BAD_PARAM;
  62238. + }
  62239. +
  62240. + macH = MV_REG_READ(ETH_MAC_ADDR_HIGH_REG(portNo));
  62241. + macL = MV_REG_READ(ETH_MAC_ADDR_LOW_REG(portNo));
  62242. + pAddr[0] = (macH >> 24) & 0xff;
  62243. + pAddr[1] = (macH >> 16) & 0xff;
  62244. + pAddr[2] = (macH >> 8) & 0xff;
  62245. + pAddr[3] = macH & 0xff;
  62246. + pAddr[4] = (macL >> 8) & 0xff;
  62247. + pAddr[5] = macL & 0xff;
  62248. +
  62249. + return MV_OK;
  62250. +}
  62251. +
  62252. +/*******************************************************************************
  62253. +* mvEthMcastCrc8Get - Calculate CRC8 of MAC address.
  62254. +*
  62255. +* DESCRIPTION:
  62256. +*
  62257. +* INPUT:
  62258. +* MV_U8* pAddr - Address to calculate CRC-8
  62259. +*
  62260. +* RETURN: MV_U8 - CRC-8 of this MAC address
  62261. +*
  62262. +*******************************************************************************/
  62263. +MV_U8 mvEthMcastCrc8Get(MV_U8* pAddr)
  62264. +{
  62265. + unsigned int macH;
  62266. + unsigned int macL;
  62267. + int macArray[48];
  62268. + int crc[8];
  62269. + int i;
  62270. + unsigned char crcResult = 0;
  62271. +
  62272. + /* Calculate CRC-8 out of the given address */
  62273. + macH = (pAddr[0] << 8) | (pAddr[1]);
  62274. + macL = (pAddr[2] << 24)| (pAddr[3] << 16) |
  62275. + (pAddr[4] << 8) | (pAddr[5] << 0);
  62276. +
  62277. + for(i=0; i<32; i++)
  62278. + macArray[i] = (macL >> i) & 0x1;
  62279. +
  62280. + for(i=32; i<48; i++)
  62281. + macArray[i] = (macH >> (i - 32)) & 0x1;
  62282. +
  62283. + crc[0] = macArray[45] ^ macArray[43] ^ macArray[40] ^ macArray[39] ^
  62284. + macArray[35] ^ macArray[34] ^ macArray[31] ^ macArray[30] ^
  62285. + macArray[28] ^ macArray[23] ^ macArray[21] ^ macArray[19] ^
  62286. + macArray[18] ^ macArray[16] ^ macArray[14] ^ macArray[12] ^
  62287. + macArray[8] ^ macArray[7] ^ macArray[6] ^ macArray[0];
  62288. +
  62289. + crc[1] = macArray[46] ^ macArray[45] ^ macArray[44] ^ macArray[43] ^
  62290. + macArray[41] ^ macArray[39] ^ macArray[36] ^ macArray[34] ^
  62291. + macArray[32] ^ macArray[30] ^ macArray[29] ^ macArray[28] ^
  62292. + macArray[24] ^ macArray[23] ^ macArray[22] ^ macArray[21] ^
  62293. + macArray[20] ^ macArray[18] ^ macArray[17] ^ macArray[16] ^
  62294. + macArray[15] ^ macArray[14] ^ macArray[13] ^ macArray[12] ^
  62295. + macArray[9] ^ macArray[6] ^ macArray[1] ^ macArray[0];
  62296. +
  62297. + crc[2] = macArray[47] ^ macArray[46] ^ macArray[44] ^ macArray[43] ^
  62298. + macArray[42] ^ macArray[39] ^ macArray[37] ^ macArray[34] ^
  62299. + macArray[33] ^ macArray[29] ^ macArray[28] ^ macArray[25] ^
  62300. + macArray[24] ^ macArray[22] ^ macArray[17] ^ macArray[15] ^
  62301. + macArray[13] ^ macArray[12] ^ macArray[10] ^ macArray[8] ^
  62302. + macArray[6] ^ macArray[2] ^ macArray[1] ^ macArray[0];
  62303. +
  62304. + crc[3] = macArray[47] ^ macArray[45] ^ macArray[44] ^ macArray[43] ^
  62305. + macArray[40] ^ macArray[38] ^ macArray[35] ^ macArray[34] ^
  62306. + macArray[30] ^ macArray[29] ^ macArray[26] ^ macArray[25] ^
  62307. + macArray[23] ^ macArray[18] ^ macArray[16] ^ macArray[14] ^
  62308. + macArray[13] ^ macArray[11] ^ macArray[9] ^ macArray[7] ^
  62309. + macArray[3] ^ macArray[2] ^ macArray[1];
  62310. +
  62311. + crc[4] = macArray[46] ^ macArray[45] ^ macArray[44] ^ macArray[41] ^
  62312. + macArray[39] ^ macArray[36] ^ macArray[35] ^ macArray[31] ^
  62313. + macArray[30] ^ macArray[27] ^ macArray[26] ^ macArray[24] ^
  62314. + macArray[19] ^ macArray[17] ^ macArray[15] ^ macArray[14] ^
  62315. + macArray[12] ^ macArray[10] ^ macArray[8] ^ macArray[4] ^
  62316. + macArray[3] ^ macArray[2];
  62317. +
  62318. + crc[5] = macArray[47] ^ macArray[46] ^ macArray[45] ^ macArray[42] ^
  62319. + macArray[40] ^ macArray[37] ^ macArray[36] ^ macArray[32] ^
  62320. + macArray[31] ^ macArray[28] ^ macArray[27] ^ macArray[25] ^
  62321. + macArray[20] ^ macArray[18] ^ macArray[16] ^ macArray[15] ^
  62322. + macArray[13] ^ macArray[11] ^ macArray[9] ^ macArray[5] ^
  62323. + macArray[4] ^ macArray[3];
  62324. +
  62325. + crc[6] = macArray[47] ^ macArray[46] ^ macArray[43] ^ macArray[41] ^
  62326. + macArray[38] ^ macArray[37] ^ macArray[33] ^ macArray[32] ^
  62327. + macArray[29] ^ macArray[28] ^ macArray[26] ^ macArray[21] ^
  62328. + macArray[19] ^ macArray[17] ^ macArray[16] ^ macArray[14] ^
  62329. + macArray[12] ^ macArray[10] ^ macArray[6] ^ macArray[5] ^
  62330. + macArray[4];
  62331. +
  62332. + crc[7] = macArray[47] ^ macArray[44] ^ macArray[42] ^ macArray[39] ^
  62333. + macArray[38] ^ macArray[34] ^ macArray[33] ^ macArray[30] ^
  62334. + macArray[29] ^ macArray[27] ^ macArray[22] ^ macArray[20] ^
  62335. + macArray[18] ^ macArray[17] ^ macArray[15] ^ macArray[13] ^
  62336. + macArray[11] ^ macArray[7] ^ macArray[6] ^ macArray[5];
  62337. +
  62338. + for(i=0; i<8; i++)
  62339. + crcResult = crcResult | (crc[i] << i);
  62340. +
  62341. + return crcResult;
  62342. +}
  62343. +/*******************************************************************************
  62344. +* mvEthMcastAddrSet - Multicast address settings.
  62345. +*
  62346. +* DESCRIPTION:
  62347. +* This API controls the MV device MAC multicast support.
  62348. +* The MV device supports multicast using two tables:
  62349. +* 1) Special Multicast Table for MAC addresses of the form
  62350. +* 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0xFF).
  62351. +* The MAC DA[7:0] bits are used as a pointer to the Special Multicast
  62352. +* Table entries in the DA-Filter table.
  62353. +* In this case, the function calls ethPortSmcAddr() routine to set the
  62354. +* Special Multicast Table.
  62355. +* 2) Other Multicast Table for multicast of another type. A CRC-8bit
  62356. +* is used as an index to the Other Multicast Table entries in the
  62357. +* DA-Filter table.
  62358. +* In this case, the function calculates the CRC-8bit value and calls
  62359. +* ethPortOmcAddr() routine to set the Other Multicast Table.
  62360. +*
  62361. +* INPUT:
  62362. +* void* pEthPortHndl - Ethernet port handler.
  62363. +* MV_U8* pAddr - Address to be set
  62364. +* int queue - RX queue to capture all packets with this
  62365. +* Multicast MAC address.
  62366. +* -1 means delete this Multicast address.
  62367. +*
  62368. +* RETURN: MV_STATUS
  62369. +* MV_TRUE - Success, Other - Failure
  62370. +*
  62371. +*******************************************************************************/
  62372. +MV_STATUS mvEthMcastAddrSet(void* pPortHndl, MV_U8 *pAddr, int queue)
  62373. +{
  62374. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  62375. + unsigned char crcResult = 0;
  62376. +
  62377. + if(queue >= MV_ETH_RX_Q_NUM)
  62378. + {
  62379. + mvOsPrintf("ethPort %d: RX queue #%d is out of range\n",
  62380. + pPortCtrl->portNo, queue);
  62381. + return MV_BAD_PARAM;
  62382. + }
  62383. +
  62384. + if((pAddr[0] == 0x01) &&
  62385. + (pAddr[1] == 0x00) &&
  62386. + (pAddr[2] == 0x5E) &&
  62387. + (pAddr[3] == 0x00) &&
  62388. + (pAddr[4] == 0x00))
  62389. + {
  62390. + ethSetSpecialMcastAddr(pPortCtrl->portNo, pAddr[5], queue);
  62391. + }
  62392. + else
  62393. + {
  62394. + crcResult = mvEthMcastCrc8Get(pAddr);
  62395. +
  62396. + /* Check Add counter for this CRC value */
  62397. + if(queue == -1)
  62398. + {
  62399. + if(pPortCtrl->mcastCount[crcResult] == 0)
  62400. + {
  62401. + mvOsPrintf("ethPort #%d: No valid Mcast for crc8=0x%02x\n",
  62402. + pPortCtrl->portNo, (unsigned)crcResult);
  62403. + return MV_NO_SUCH;
  62404. + }
  62405. +
  62406. + pPortCtrl->mcastCount[crcResult]--;
  62407. + if(pPortCtrl->mcastCount[crcResult] != 0)
  62408. + {
  62409. + mvOsPrintf("ethPort #%d: After delete there are %d valid Mcast for crc8=0x%02x\n",
  62410. + pPortCtrl->portNo, pPortCtrl->mcastCount[crcResult],
  62411. + (unsigned)crcResult);
  62412. + return MV_NO_CHANGE;
  62413. + }
  62414. + }
  62415. + else
  62416. + {
  62417. + pPortCtrl->mcastCount[crcResult]++;
  62418. + if(pPortCtrl->mcastCount[crcResult] > 1)
  62419. + {
  62420. + mvOsPrintf("ethPort #%d: Valid Mcast for crc8=0x%02x already exists\n",
  62421. + pPortCtrl->portNo, (unsigned)crcResult);
  62422. + return MV_NO_CHANGE;
  62423. + }
  62424. + }
  62425. + ethSetOtherMcastAddr(pPortCtrl->portNo, crcResult, queue);
  62426. + }
  62427. + return MV_OK;
  62428. +}
  62429. +
  62430. +/*******************************************************************************
  62431. +* ethSetUcastTable - Unicast address settings.
  62432. +*
  62433. +* DESCRIPTION:
  62434. +* Set all entries in the Unicast MAC Table queue==-1 means reject all
  62435. +* INPUT:
  62436. +*
  62437. +* RETURN:
  62438. +*
  62439. +*******************************************************************************/
  62440. +static void ethSetUcastTable(int portNo, int queue)
  62441. +{
  62442. + int offset;
  62443. + MV_U32 regValue;
  62444. +
  62445. + if(queue == -1)
  62446. + {
  62447. + regValue = 0;
  62448. + }
  62449. + else
  62450. + {
  62451. + regValue = (((0x01 | (queue<<1)) << 0) |
  62452. + ((0x01 | (queue<<1)) << 8) |
  62453. + ((0x01 | (queue<<1)) << 16) |
  62454. + ((0x01 | (queue<<1)) << 24));
  62455. + }
  62456. +
  62457. + for (offset=0; offset<=0xC; offset+=4)
  62458. + MV_REG_WRITE((ETH_DA_FILTER_UCAST_BASE(portNo) + offset), regValue);
  62459. +}
  62460. +
  62461. +/*******************************************************************************
  62462. +* mvEthSetSpecialMcastTable - Special Multicast address settings.
  62463. +*
  62464. +* DESCRIPTION:
  62465. +* Set all entries to the Special Multicast MAC Table. queue==-1 means reject all
  62466. +* INPUT:
  62467. +*
  62468. +* RETURN:
  62469. +*
  62470. +*******************************************************************************/
  62471. +MV_VOID mvEthSetSpecialMcastTable(int portNo, int queue)
  62472. +{
  62473. + int offset;
  62474. + MV_U32 regValue;
  62475. +
  62476. + if(queue == -1)
  62477. + {
  62478. + regValue = 0;
  62479. + }
  62480. + else
  62481. + {
  62482. + regValue = (((0x01 | (queue<<1)) << 0) |
  62483. + ((0x01 | (queue<<1)) << 8) |
  62484. + ((0x01 | (queue<<1)) << 16) |
  62485. + ((0x01 | (queue<<1)) << 24));
  62486. + }
  62487. +
  62488. + for (offset=0; offset<=0xFC; offset+=4)
  62489. + {
  62490. + MV_REG_WRITE((ETH_DA_FILTER_SPEC_MCAST_BASE(portNo) +
  62491. + offset), regValue);
  62492. + }
  62493. +}
  62494. +
  62495. +/*******************************************************************************
  62496. +* mvEthSetOtherMcastTable - Other Multicast address settings.
  62497. +*
  62498. +* DESCRIPTION:
  62499. +* Set all entries to the Other Multicast MAC Table. queue==-1 means reject all
  62500. +* INPUT:
  62501. +*
  62502. +* RETURN:
  62503. +*
  62504. +*******************************************************************************/
  62505. +MV_VOID mvEthSetOtherMcastTable(int portNo, int queue)
  62506. +{
  62507. + int offset;
  62508. + MV_U32 regValue;
  62509. +
  62510. + if(queue == -1)
  62511. + {
  62512. + regValue = 0;
  62513. + }
  62514. + else
  62515. + {
  62516. + regValue = (((0x01 | (queue<<1)) << 0) |
  62517. + ((0x01 | (queue<<1)) << 8) |
  62518. + ((0x01 | (queue<<1)) << 16) |
  62519. + ((0x01 | (queue<<1)) << 24));
  62520. + }
  62521. +
  62522. + for (offset=0; offset<=0xFC; offset+=4)
  62523. + {
  62524. + MV_REG_WRITE((ETH_DA_FILTER_OTH_MCAST_BASE(portNo) +
  62525. + offset), regValue);
  62526. + }
  62527. +}
  62528. +
  62529. +/*******************************************************************************
  62530. +* ethSetUcastAddr - This function Set the port unicast address table
  62531. +*
  62532. +* DESCRIPTION:
  62533. +* This function locates the proper entry in the Unicast table for the
  62534. +* specified MAC nibble and sets its properties according to function
  62535. +* parameters.
  62536. +*
  62537. +* INPUT:
  62538. +* int ethPortNum - Port number.
  62539. +* MV_U8 lastNibble - Unicast MAC Address last nibble.
  62540. +* int queue - Rx queue number for this MAC address.
  62541. +* value "-1" means remove address
  62542. +*
  62543. +* OUTPUT:
  62544. +* This function add/removes MAC addresses from the port unicast address
  62545. +* table.
  62546. +*
  62547. +* RETURN:
  62548. +* MV_TRUE is output succeeded.
  62549. +* MV_FALSE if option parameter is invalid.
  62550. +*
  62551. +*******************************************************************************/
  62552. +static MV_BOOL ethSetUcastAddr(int portNo, MV_U8 lastNibble, int queue)
  62553. +{
  62554. + unsigned int unicastReg;
  62555. + unsigned int tblOffset;
  62556. + unsigned int regOffset;
  62557. +
  62558. + /* Locate the Unicast table entry */
  62559. + lastNibble = (0xf & lastNibble);
  62560. + tblOffset = (lastNibble / 4) * 4; /* Register offset from unicast table base*/
  62561. + regOffset = lastNibble % 4; /* Entry offset within the above register */
  62562. +
  62563. +
  62564. + unicastReg = MV_REG_READ( (ETH_DA_FILTER_UCAST_BASE(portNo) +
  62565. + tblOffset));
  62566. +
  62567. +
  62568. + if(queue == -1)
  62569. + {
  62570. + /* Clear accepts frame bit at specified unicast DA table entry */
  62571. + unicastReg &= ~(0xFF << (8*regOffset));
  62572. + }
  62573. + else
  62574. + {
  62575. + unicastReg &= ~(0xFF << (8*regOffset));
  62576. + unicastReg |= ((0x01 | (queue<<1)) << (8*regOffset));
  62577. + }
  62578. + MV_REG_WRITE( (ETH_DA_FILTER_UCAST_BASE(portNo) + tblOffset),
  62579. + unicastReg);
  62580. +
  62581. + return MV_TRUE;
  62582. +}
  62583. +
  62584. +/*******************************************************************************
  62585. +* ethSetSpecialMcastAddr - Special Multicast address settings.
  62586. +*
  62587. +* DESCRIPTION:
  62588. +* This routine controls the MV device special MAC multicast support.
  62589. +* The Special Multicast Table for MAC addresses supports MAC of the form
  62590. +* 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0xFF).
  62591. +* The MAC DA[7:0] bits are used as a pointer to the Special Multicast
  62592. +* Table entries in the DA-Filter table.
  62593. +* This function set the Special Multicast Table appropriate entry
  62594. +* according to the argument given.
  62595. +*
  62596. +* INPUT:
  62597. +* int ethPortNum Port number.
  62598. +* unsigned char mcByte Multicast addr last byte (MAC DA[7:0] bits).
  62599. +* int queue Rx queue number for this MAC address.
  62600. +* int option 0 = Add, 1 = remove address.
  62601. +*
  62602. +* OUTPUT:
  62603. +* See description.
  62604. +*
  62605. +* RETURN:
  62606. +* MV_TRUE is output succeeded.
  62607. +* MV_FALSE if option parameter is invalid.
  62608. +*
  62609. +*******************************************************************************/
  62610. +static MV_BOOL ethSetSpecialMcastAddr(int ethPortNum, MV_U8 lastByte, int queue)
  62611. +{
  62612. + unsigned int smcTableReg;
  62613. + unsigned int tblOffset;
  62614. + unsigned int regOffset;
  62615. +
  62616. + /* Locate the SMC table entry */
  62617. + tblOffset = (lastByte / 4); /* Register offset from SMC table base */
  62618. + regOffset = lastByte % 4; /* Entry offset within the above register */
  62619. +
  62620. + smcTableReg = MV_REG_READ((ETH_DA_FILTER_SPEC_MCAST_BASE(ethPortNum) + tblOffset*4));
  62621. +
  62622. + if(queue == -1)
  62623. + {
  62624. + /* Clear accepts frame bit at specified Special DA table entry */
  62625. + smcTableReg &= ~(0xFF << (8 * regOffset));
  62626. + }
  62627. + else
  62628. + {
  62629. + smcTableReg &= ~(0xFF << (8 * regOffset));
  62630. + smcTableReg |= ((0x01 | (queue<<1)) << (8 * regOffset));
  62631. + }
  62632. + MV_REG_WRITE((ETH_DA_FILTER_SPEC_MCAST_BASE(ethPortNum) +
  62633. + tblOffset*4), smcTableReg);
  62634. +
  62635. + return MV_TRUE;
  62636. +}
  62637. +
  62638. +/*******************************************************************************
  62639. +* ethSetOtherMcastAddr - Multicast address settings.
  62640. +*
  62641. +* DESCRIPTION:
  62642. +* This routine controls the MV device Other MAC multicast support.
  62643. +* The Other Multicast Table is used for multicast of another type.
  62644. +* A CRC-8bit is used as an index to the Other Multicast Table entries
  62645. +* in the DA-Filter table.
  62646. +* The function gets the CRC-8bit value from the calling routine and
  62647. +* set the Other Multicast Table appropriate entry according to the
  62648. +* CRC-8 argument given.
  62649. +*
  62650. +* INPUT:
  62651. +* int ethPortNum Port number.
  62652. +* MV_U8 crc8 A CRC-8bit (Polynomial: x^8+x^2+x^1+1).
  62653. +* int queue Rx queue number for this MAC address.
  62654. +*
  62655. +* OUTPUT:
  62656. +* See description.
  62657. +*
  62658. +* RETURN:
  62659. +* MV_TRUE is output succeeded.
  62660. +* MV_FALSE if option parameter is invalid.
  62661. +*
  62662. +*******************************************************************************/
  62663. +static MV_BOOL ethSetOtherMcastAddr(int ethPortNum, MV_U8 crc8, int queue)
  62664. +{
  62665. + unsigned int omcTableReg;
  62666. + unsigned int tblOffset;
  62667. + unsigned int regOffset;
  62668. +
  62669. + /* Locate the OMC table entry */
  62670. + tblOffset = (crc8 / 4) * 4; /* Register offset from OMC table base */
  62671. + regOffset = crc8 % 4; /* Entry offset within the above register */
  62672. +
  62673. + omcTableReg = MV_REG_READ(
  62674. + (ETH_DA_FILTER_OTH_MCAST_BASE(ethPortNum) + tblOffset));
  62675. +
  62676. + if(queue == -1)
  62677. + {
  62678. + /* Clear accepts frame bit at specified Other DA table entry */
  62679. + omcTableReg &= ~(0xFF << (8 * regOffset));
  62680. + }
  62681. + else
  62682. + {
  62683. + omcTableReg &= ~(0xFF << (8 * regOffset));
  62684. + omcTableReg |= ((0x01 | (queue<<1)) << (8 * regOffset));
  62685. + }
  62686. +
  62687. + MV_REG_WRITE((ETH_DA_FILTER_OTH_MCAST_BASE(ethPortNum) + tblOffset),
  62688. + omcTableReg);
  62689. +
  62690. + return MV_TRUE;
  62691. +}
  62692. +
  62693. +
  62694. +/******************************************************************************/
  62695. +/* MIB Counters functions */
  62696. +/******************************************************************************/
  62697. +
  62698. +
  62699. +/*******************************************************************************
  62700. +* mvEthMibCounterRead - Read a MIB counter
  62701. +*
  62702. +* DESCRIPTION:
  62703. +* This function reads a MIB counter of a specific ethernet port.
  62704. +* NOTE - Read from ETH_MIB_GOOD_OCTETS_RECEIVED_LOW or
  62705. +* ETH_MIB_GOOD_OCTETS_SENT_LOW counters will return 64 bits value,
  62706. +* so pHigh32 pointer should not be NULL in this case.
  62707. +*
  62708. +* INPUT:
  62709. +* int ethPortNum - Ethernet Port number.
  62710. +* unsigned int mibOffset - MIB counter offset.
  62711. +*
  62712. +* OUTPUT:
  62713. +* MV_U32* pHigh32 - pointer to place where 32 most significant bits
  62714. +* of the counter will be stored.
  62715. +*
  62716. +* RETURN:
  62717. +* 32 low sgnificant bits of MIB counter value.
  62718. +*
  62719. +*******************************************************************************/
  62720. +MV_U32 mvEthMibCounterRead(void* pPortHandle, unsigned int mibOffset,
  62721. + MV_U32* pHigh32)
  62722. +{
  62723. + int portNo;
  62724. + MV_U32 valLow32, valHigh32;
  62725. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  62726. +
  62727. + portNo = pPortCtrl->portNo;
  62728. +
  62729. + valLow32 = MV_REG_READ(ETH_MIB_COUNTERS_BASE(portNo) + mibOffset);
  62730. +
  62731. + /* Implement FEr ETH. Erroneous Value when Reading the Upper 32-bits */
  62732. + /* of a 64-bit MIB Counter. */
  62733. + if( (mibOffset == ETH_MIB_GOOD_OCTETS_RECEIVED_LOW) ||
  62734. + (mibOffset == ETH_MIB_GOOD_OCTETS_SENT_LOW) )
  62735. + {
  62736. + valHigh32 = MV_REG_READ(ETH_MIB_COUNTERS_BASE(portNo) + mibOffset + 4);
  62737. + if(pHigh32 != NULL)
  62738. + *pHigh32 = valHigh32;
  62739. + }
  62740. + return valLow32;
  62741. +}
  62742. +
  62743. +/*******************************************************************************
  62744. +* mvEthMibCountersClear - Clear all MIB counters
  62745. +*
  62746. +* DESCRIPTION:
  62747. +* This function clears all MIB counters
  62748. +*
  62749. +* INPUT:
  62750. +* int ethPortNum - Ethernet Port number.
  62751. +*
  62752. +*
  62753. +* RETURN: void
  62754. +*
  62755. +*******************************************************************************/
  62756. +void mvEthMibCountersClear(void* pPortHandle)
  62757. +{
  62758. + int i, portNo;
  62759. + unsigned int dummy;
  62760. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  62761. +
  62762. + portNo = pPortCtrl->portNo;
  62763. +
  62764. + /* Perform dummy reads from MIB counters */
  62765. + for(i=ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i<ETH_MIB_LATE_COLLISION; i+=4)
  62766. + dummy = MV_REG_READ((ETH_MIB_COUNTERS_BASE(portNo) + i));
  62767. +}
  62768. +
  62769. +
  62770. +/******************************************************************************/
  62771. +/* RX Dispatching configuration routines */
  62772. +/******************************************************************************/
  62773. +
  62774. +int mvEthTosToRxqGet(void* pPortHandle, int tos)
  62775. +{
  62776. + MV_U32 regValue;
  62777. + int regIdx, regOffs, rxq;
  62778. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  62779. +
  62780. + if(tos > 0xFF)
  62781. + {
  62782. + mvOsPrintf("eth_%d: tos=0x%x is out of range\n", pPortCtrl->portNo, tos);
  62783. + return -1;
  62784. + }
  62785. + regIdx = mvOsDivide(tos>>2, 10);
  62786. + regOffs = mvOsReminder(tos>>2, 10);
  62787. +
  62788. + regValue = MV_REG_READ(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx) );
  62789. + rxq = (regValue >> (regOffs*3));
  62790. + rxq &= 0x7;
  62791. +
  62792. + return rxq;
  62793. +}
  62794. +
  62795. +/*******************************************************************************
  62796. +* mvEthTosToRxqSet - Map packets with special TOS value to special RX queue
  62797. +*
  62798. +* DESCRIPTION:
  62799. +*
  62800. +* INPUT:
  62801. +* void* pPortHandle - Pointer to port specific handler;
  62802. +* int tos - TOS value in the IP header of the packet
  62803. +* int rxq - RX Queue for packets with the configured TOS value
  62804. +* Negative value (-1) means no special processing for these packets,
  62805. +* so they will be processed as regular packets.
  62806. +*
  62807. +* RETURN: MV_STATUS
  62808. +*******************************************************************************/
  62809. +MV_STATUS mvEthTosToRxqSet(void* pPortHandle, int tos, int rxq)
  62810. +{
  62811. + MV_U32 regValue;
  62812. + int regIdx, regOffs;
  62813. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  62814. +
  62815. + if( (rxq < 0) || (rxq >= MV_ETH_RX_Q_NUM) )
  62816. + {
  62817. + mvOsPrintf("eth_%d: RX queue #%d is out of range\n", pPortCtrl->portNo, rxq);
  62818. + return MV_BAD_PARAM;
  62819. + }
  62820. + if(tos > 0xFF)
  62821. + {
  62822. + mvOsPrintf("eth_%d: tos=0x%x is out of range\n", pPortCtrl->portNo, tos);
  62823. + return MV_BAD_PARAM;
  62824. + }
  62825. + regIdx = mvOsDivide(tos>>2, 10);
  62826. + regOffs = mvOsReminder(tos>>2, 10);
  62827. +
  62828. + regValue = MV_REG_READ(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx) );
  62829. + regValue &= ~(0x7 << (regOffs*3));
  62830. + regValue |= (rxq << (regOffs*3));
  62831. +
  62832. + MV_REG_WRITE(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx), regValue);
  62833. + return MV_OK;
  62834. +}
  62835. +
  62836. +/*******************************************************************************
  62837. +* mvEthVlanPrioRxQueue - Configure RX queue to capture VLAN tagged packets with
  62838. +* special priority bits [0-2]
  62839. +*
  62840. +* DESCRIPTION:
  62841. +*
  62842. +* INPUT:
  62843. +* void* pPortHandle - Pointer to port specific handler;
  62844. +* int bpduQueue - Special queue to capture VLAN tagged packets with special
  62845. +* priority.
  62846. +* Negative value (-1) means no special processing for these packets,
  62847. +* so they will be processed as regular packets.
  62848. +*
  62849. +* RETURN: MV_STATUS
  62850. +* MV_OK - Success
  62851. +* MV_FAIL - Failed.
  62852. +*
  62853. +*******************************************************************************/
  62854. +MV_STATUS mvEthVlanPrioRxQueue(void* pPortHandle, int vlanPrio, int vlanPrioQueue)
  62855. +{
  62856. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  62857. + MV_U32 vlanPrioReg;
  62858. +
  62859. + if(vlanPrioQueue >= MV_ETH_RX_Q_NUM)
  62860. + {
  62861. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", vlanPrioQueue);
  62862. + return MV_BAD_PARAM;
  62863. + }
  62864. + if(vlanPrio >= 8)
  62865. + {
  62866. + mvOsPrintf("ethDrv: vlanPrio=%d is out of range\n", vlanPrio);
  62867. + return MV_BAD_PARAM;
  62868. + }
  62869. +
  62870. + vlanPrioReg = MV_REG_READ(ETH_VLAN_TAG_TO_PRIO_REG(pPortCtrl->portNo));
  62871. + vlanPrioReg &= ~(0x7 << (vlanPrio*3));
  62872. + vlanPrioReg |= (vlanPrioQueue << (vlanPrio*3));
  62873. + MV_REG_WRITE(ETH_VLAN_TAG_TO_PRIO_REG(pPortCtrl->portNo), vlanPrioReg);
  62874. +
  62875. + return MV_OK;
  62876. +}
  62877. +
  62878. +
  62879. +/*******************************************************************************
  62880. +* mvEthBpduRxQueue - Configure RX queue to capture BPDU packets.
  62881. +*
  62882. +* DESCRIPTION:
  62883. +* This function defines processing of BPDU packets.
  62884. +* BPDU packets can be accepted and captured to one of RX queues
  62885. +* or can be processing as regular Multicast packets.
  62886. +*
  62887. +* INPUT:
  62888. +* void* pPortHandle - Pointer to port specific handler;
  62889. +* int bpduQueue - Special queue to capture BPDU packets (DA is equal to
  62890. +* 01-80-C2-00-00-00 through 01-80-C2-00-00-FF,
  62891. +* except for the Flow-Control Pause packets).
  62892. +* Negative value (-1) means no special processing for BPDU,
  62893. +* packets so they will be processed as regular Multicast packets.
  62894. +*
  62895. +* RETURN: MV_STATUS
  62896. +* MV_OK - Success
  62897. +* MV_FAIL - Failed.
  62898. +*
  62899. +*******************************************************************************/
  62900. +MV_STATUS mvEthBpduRxQueue(void* pPortHandle, int bpduQueue)
  62901. +{
  62902. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  62903. + MV_U32 portCfgReg;
  62904. + MV_U32 portCfgExtReg;
  62905. +
  62906. + if(bpduQueue >= MV_ETH_RX_Q_NUM)
  62907. + {
  62908. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", bpduQueue);
  62909. + return MV_BAD_PARAM;
  62910. + }
  62911. +
  62912. + portCfgExtReg = MV_REG_READ(ETH_PORT_CONFIG_EXTEND_REG(pPortCtrl->portNo));
  62913. +
  62914. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  62915. + if(bpduQueue >= 0)
  62916. + {
  62917. + pPortCtrl->portConfig.rxBpduQ = bpduQueue;
  62918. +
  62919. + portCfgReg &= ~ETH_DEF_RX_BPDU_QUEUE_ALL_MASK;
  62920. + portCfgReg |= ETH_DEF_RX_BPDU_QUEUE_MASK(pPortCtrl->portConfig.rxBpduQ);
  62921. +
  62922. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  62923. +
  62924. + portCfgExtReg |= ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK;
  62925. + }
  62926. + else
  62927. + {
  62928. + pPortCtrl->portConfig.rxBpduQ = -1;
  62929. + /* no special processing for BPDU packets */
  62930. + portCfgExtReg &= (~ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK);
  62931. + }
  62932. +
  62933. + MV_REG_WRITE(ETH_PORT_CONFIG_EXTEND_REG(pPortCtrl->portNo), portCfgExtReg);
  62934. +
  62935. + return MV_OK;
  62936. +}
  62937. +
  62938. +
  62939. +/*******************************************************************************
  62940. +* mvEthArpRxQueue - Configure RX queue to capture ARP packets.
  62941. +*
  62942. +* DESCRIPTION:
  62943. +* This function defines processing of ARP (type=0x0806) packets.
  62944. +* ARP packets can be accepted and captured to one of RX queues
  62945. +* or can be processed as other Broadcast packets.
  62946. +*
  62947. +* INPUT:
  62948. +* void* pPortHandle - Pointer to port specific handler;
  62949. +* int arpQueue - Special queue to capture ARP packets (type=0x806).
  62950. +* Negative value (-1) means discard ARP packets
  62951. +*
  62952. +* RETURN: MV_STATUS
  62953. +* MV_OK - Success
  62954. +* MV_FAIL - Failed.
  62955. +*
  62956. +*******************************************************************************/
  62957. +MV_STATUS mvEthArpRxQueue(void* pPortHandle, int arpQueue)
  62958. +{
  62959. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  62960. + MV_U32 portCfgReg;
  62961. +
  62962. + if(arpQueue >= MV_ETH_RX_Q_NUM)
  62963. + {
  62964. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", arpQueue);
  62965. + return MV_BAD_PARAM;
  62966. + }
  62967. +
  62968. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  62969. +
  62970. + if(arpQueue >= 0)
  62971. + {
  62972. + pPortCtrl->portConfig.rxArpQ = arpQueue;
  62973. + portCfgReg &= ~ETH_DEF_RX_ARP_QUEUE_ALL_MASK;
  62974. + portCfgReg |= ETH_DEF_RX_ARP_QUEUE_MASK(pPortCtrl->portConfig.rxArpQ);
  62975. +
  62976. + portCfgReg &= (~ETH_REJECT_ARP_BCAST_MASK);
  62977. + }
  62978. + else
  62979. + {
  62980. + pPortCtrl->portConfig.rxArpQ = -1;
  62981. + portCfgReg |= ETH_REJECT_ARP_BCAST_MASK;
  62982. + }
  62983. +
  62984. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  62985. +
  62986. + return MV_OK;
  62987. +}
  62988. +
  62989. +
  62990. +/*******************************************************************************
  62991. +* mvEthTcpRxQueue - Configure RX queue to capture TCP packets.
  62992. +*
  62993. +* DESCRIPTION:
  62994. +* This function defines processing of TCP packets.
  62995. +* TCP packets can be accepted and captured to one of RX queues
  62996. +* or can be processed as regular Unicast packets.
  62997. +*
  62998. +* INPUT:
  62999. +* void* pPortHandle - Pointer to port specific handler;
  63000. +* int tcpQueue - Special queue to capture TCP packets. Value "-1"
  63001. +* means no special processing for TCP packets,
  63002. +* so they will be processed as regular
  63003. +*
  63004. +* RETURN: MV_STATUS
  63005. +* MV_OK - Success
  63006. +* MV_FAIL - Failed.
  63007. +*
  63008. +*******************************************************************************/
  63009. +MV_STATUS mvEthTcpRxQueue(void* pPortHandle, int tcpQueue)
  63010. +{
  63011. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63012. + MV_U32 portCfgReg;
  63013. +
  63014. + if(tcpQueue >= MV_ETH_RX_Q_NUM)
  63015. + {
  63016. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", tcpQueue);
  63017. + return MV_BAD_PARAM;
  63018. + }
  63019. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  63020. +
  63021. + if(tcpQueue >= 0)
  63022. + {
  63023. + pPortCtrl->portConfig.rxTcpQ = tcpQueue;
  63024. + portCfgReg &= ~ETH_DEF_RX_TCP_QUEUE_ALL_MASK;
  63025. + portCfgReg |= ETH_DEF_RX_TCP_QUEUE_MASK(pPortCtrl->portConfig.rxTcpQ);
  63026. +
  63027. + portCfgReg |= ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK;
  63028. + }
  63029. + else
  63030. + {
  63031. + pPortCtrl->portConfig.rxTcpQ = -1;
  63032. + portCfgReg &= (~ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK);
  63033. + }
  63034. +
  63035. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  63036. +
  63037. + return MV_OK;
  63038. +}
  63039. +
  63040. +
  63041. +/*******************************************************************************
  63042. +* mvEthUdpRxQueue - Configure RX queue to capture UDP packets.
  63043. +*
  63044. +* DESCRIPTION:
  63045. +* This function defines processing of UDP packets.
  63046. +* TCP packets can be accepted and captured to one of RX queues
  63047. +* or can be processed as regular Unicast packets.
  63048. +*
  63049. +* INPUT:
  63050. +* void* pPortHandle - Pointer to port specific handler;
  63051. +* int udpQueue - Special queue to capture UDP packets. Value "-1"
  63052. +* means no special processing for UDP packets,
  63053. +* so they will be processed as regular
  63054. +*
  63055. +* RETURN: MV_STATUS
  63056. +* MV_OK - Success
  63057. +* MV_FAIL - Failed.
  63058. +*
  63059. +*******************************************************************************/
  63060. +MV_STATUS mvEthUdpRxQueue(void* pPortHandle, int udpQueue)
  63061. +{
  63062. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63063. + MV_U32 portCfgReg;
  63064. +
  63065. + if(udpQueue >= MV_ETH_RX_Q_NUM)
  63066. + {
  63067. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", udpQueue);
  63068. + return MV_BAD_PARAM;
  63069. + }
  63070. +
  63071. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  63072. +
  63073. + if(udpQueue >= 0)
  63074. + {
  63075. + pPortCtrl->portConfig.rxUdpQ = udpQueue;
  63076. + portCfgReg &= ~ETH_DEF_RX_UDP_QUEUE_ALL_MASK;
  63077. + portCfgReg |= ETH_DEF_RX_UDP_QUEUE_MASK(pPortCtrl->portConfig.rxUdpQ);
  63078. +
  63079. + portCfgReg |= ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK;
  63080. + }
  63081. + else
  63082. + {
  63083. + pPortCtrl->portConfig.rxUdpQ = -1;
  63084. + portCfgReg &= ~ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK;
  63085. + }
  63086. +
  63087. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  63088. +
  63089. + return MV_OK;
  63090. +}
  63091. +
  63092. +
  63093. +/******************************************************************************/
  63094. +/* Speed, Duplex, FlowControl routines */
  63095. +/******************************************************************************/
  63096. +
  63097. +/*******************************************************************************
  63098. +* mvEthSpeedDuplexSet - Set Speed and Duplex of the port.
  63099. +*
  63100. +* DESCRIPTION:
  63101. +* This function configure the port to work with desirable Duplex and Speed.
  63102. +* Changing of these parameters are allowed only when port is disabled.
  63103. +* This function disable the port if was enabled, change duplex and speed
  63104. +* and, enable the port back if needed.
  63105. +*
  63106. +* INPUT:
  63107. +* void* pPortHandle - Pointer to port specific handler;
  63108. +* ETH_PORT_SPEED speed - Speed of the port.
  63109. +* ETH_PORT_SPEED duplex - Duplex of the port.
  63110. +*
  63111. +* RETURN: MV_STATUS
  63112. +* MV_OK - Success
  63113. +* MV_OUT_OF_RANGE - Failed. Port is out of valid range
  63114. +* MV_NOT_FOUND - Failed. Port is not initialized.
  63115. +* MV_BAD_PARAM - Input parameters (speed/duplex) in conflict.
  63116. +* MV_BAD_VALUE - Value of one of input parameters (speed, duplex)
  63117. +* is not valid
  63118. +*
  63119. +*******************************************************************************/
  63120. +MV_STATUS mvEthSpeedDuplexSet(void* pPortHandle, MV_ETH_PORT_SPEED speed,
  63121. + MV_ETH_PORT_DUPLEX duplex)
  63122. +{
  63123. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63124. + int port = pPortCtrl->portNo;
  63125. + MV_U32 portSerialCtrlReg;
  63126. +
  63127. + if( (port < 0) || (port >= (int)mvCtrlEthMaxPortGet()) )
  63128. + return MV_OUT_OF_RANGE;
  63129. +
  63130. + pPortCtrl = ethPortCtrl[port];
  63131. + if(pPortCtrl == NULL)
  63132. + return MV_NOT_FOUND;
  63133. +
  63134. + /* Check validity */
  63135. + if( (speed == MV_ETH_SPEED_1000) && (duplex == MV_ETH_DUPLEX_HALF) )
  63136. + return MV_BAD_PARAM;
  63137. +
  63138. + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));
  63139. + /* Set Speed */
  63140. + switch(speed)
  63141. + {
  63142. + case MV_ETH_SPEED_AN:
  63143. + portSerialCtrlReg &= ~ETH_DISABLE_SPEED_AUTO_NEG_MASK;
  63144. + break;
  63145. +
  63146. + case MV_ETH_SPEED_10:
  63147. + portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;
  63148. + portSerialCtrlReg &= ~ETH_SET_GMII_SPEED_1000_MASK;
  63149. + portSerialCtrlReg &= ~ETH_SET_MII_SPEED_100_MASK;
  63150. + break;
  63151. +
  63152. + case MV_ETH_SPEED_100:
  63153. + portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;
  63154. + portSerialCtrlReg &= ~ETH_SET_GMII_SPEED_1000_MASK;
  63155. + portSerialCtrlReg |= ETH_SET_MII_SPEED_100_MASK;
  63156. + break;
  63157. +
  63158. + case MV_ETH_SPEED_1000:
  63159. + portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;
  63160. + portSerialCtrlReg |= ETH_SET_GMII_SPEED_1000_MASK;
  63161. + break;
  63162. +
  63163. + default:
  63164. + mvOsPrintf("ethDrv: Unexpected Speed value %d\n", speed);
  63165. + return MV_BAD_VALUE;
  63166. + }
  63167. + /* Set duplex */
  63168. + switch(duplex)
  63169. + {
  63170. + case MV_ETH_DUPLEX_AN:
  63171. + portSerialCtrlReg &= ~ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;
  63172. + break;
  63173. +
  63174. + case MV_ETH_DUPLEX_HALF:
  63175. + portSerialCtrlReg |= ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;
  63176. + portSerialCtrlReg &= ~ETH_SET_FULL_DUPLEX_MASK;
  63177. + break;
  63178. +
  63179. + case MV_ETH_DUPLEX_FULL:
  63180. + portSerialCtrlReg |= ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;
  63181. + portSerialCtrlReg |= ETH_SET_FULL_DUPLEX_MASK;
  63182. + break;
  63183. +
  63184. + default:
  63185. + mvOsPrintf("ethDrv: Unexpected Duplex value %d\n", duplex);
  63186. + return MV_BAD_VALUE;
  63187. + }
  63188. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(port), portSerialCtrlReg);
  63189. +
  63190. + return MV_OK;
  63191. +}
  63192. +
  63193. +/*******************************************************************************
  63194. +* mvEthFlowCtrlSet - Set Flow Control of the port.
  63195. +*
  63196. +* DESCRIPTION:
  63197. +* This function configure the port to work with desirable Duplex and
  63198. +* Speed. Changing of these parameters are allowed only when port is
  63199. +* disabled. This function disable the port if was enabled, change
  63200. +* duplex and speed and, enable the port back if needed.
  63201. +*
  63202. +* INPUT:
  63203. +* void* pPortHandle - Pointer to port specific handler;
  63204. +* MV_ETH_PORT_FC flowControl - Flow control of the port.
  63205. +*
  63206. +* RETURN: MV_STATUS
  63207. +* MV_OK - Success
  63208. +* MV_OUT_OF_RANGE - Failed. Port is out of valid range
  63209. +* MV_NOT_FOUND - Failed. Port is not initialized.
  63210. +* MV_BAD_VALUE - Value flowControl parameters is not valid
  63211. +*
  63212. +*******************************************************************************/
  63213. +MV_STATUS mvEthFlowCtrlSet(void* pPortHandle, MV_ETH_PORT_FC flowControl)
  63214. +{
  63215. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63216. + int port = pPortCtrl->portNo;
  63217. + MV_U32 portSerialCtrlReg;
  63218. +
  63219. + if( (port < 0) || (port >= (int)mvCtrlEthMaxPortGet() ) )
  63220. + return MV_OUT_OF_RANGE;
  63221. +
  63222. + pPortCtrl = ethPortCtrl[port];
  63223. + if(pPortCtrl == NULL)
  63224. + return MV_NOT_FOUND;
  63225. +
  63226. + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));
  63227. + switch(flowControl)
  63228. + {
  63229. + case MV_ETH_FC_AN_ADV_DIS:
  63230. + portSerialCtrlReg &= ~ETH_DISABLE_FC_AUTO_NEG_MASK;
  63231. + portSerialCtrlReg &= ~ETH_ADVERTISE_SYM_FC_MASK;
  63232. + break;
  63233. +
  63234. + case MV_ETH_FC_AN_ADV_SYM:
  63235. + portSerialCtrlReg &= ~ETH_DISABLE_FC_AUTO_NEG_MASK;
  63236. + portSerialCtrlReg |= ETH_ADVERTISE_SYM_FC_MASK;
  63237. + break;
  63238. +
  63239. + case MV_ETH_FC_DISABLE:
  63240. + portSerialCtrlReg |= ETH_DISABLE_FC_AUTO_NEG_MASK;
  63241. + portSerialCtrlReg &= ~ETH_SET_FLOW_CTRL_MASK;
  63242. + break;
  63243. +
  63244. + case MV_ETH_FC_ENABLE:
  63245. + portSerialCtrlReg |= ETH_DISABLE_FC_AUTO_NEG_MASK;
  63246. + portSerialCtrlReg |= ETH_SET_FLOW_CTRL_MASK;
  63247. + break;
  63248. +
  63249. + default:
  63250. + mvOsPrintf("ethDrv: Unexpected FlowControl value %d\n", flowControl);
  63251. + return MV_BAD_VALUE;
  63252. + }
  63253. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(port), portSerialCtrlReg);
  63254. +
  63255. + return MV_OK;
  63256. +}
  63257. +
  63258. +/*******************************************************************************
  63259. +* mvEthHeaderModeSet - Set port header mode.
  63260. +*
  63261. +* DESCRIPTION:
  63262. +* This function configures the port to work in Marvell-Header mode.
  63263. +*
  63264. +* INPUT:
  63265. +* void* pPortHandle - Pointer to port specific handler;
  63266. +* MV_ETH_HEADER_MODE headerMode - The header mode to set the port in.
  63267. +*
  63268. +* RETURN: MV_STATUS
  63269. +* MV_OK - Success
  63270. +* MV_NOT_SUPPORTED- Feature not supported.
  63271. +* MV_OUT_OF_RANGE - Failed. Port is out of valid range
  63272. +* MV_NOT_FOUND - Failed. Port is not initialized.
  63273. +* MV_BAD_VALUE - Value of headerMode or numRxQueue parameter is not valid.
  63274. +*
  63275. +*******************************************************************************/
  63276. +MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode)
  63277. +{
  63278. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63279. + int port = pPortCtrl->portNo;
  63280. + MV_U32 mvHeaderReg;
  63281. + MV_U32 numRxQ = MV_ETH_RX_Q_NUM;
  63282. +
  63283. + if((port < 0) || (port >= mvCtrlEthMaxPortGet()))
  63284. + return MV_OUT_OF_RANGE;
  63285. +
  63286. + pPortCtrl = ethPortCtrl[port];
  63287. + if(pPortCtrl == NULL)
  63288. + return MV_NOT_FOUND;
  63289. +
  63290. + mvHeaderReg = MV_REG_READ(ETH_PORT_MARVELL_HEADER_REG(port));
  63291. + /* Disable header mode. */
  63292. + mvHeaderReg &= ~ETH_MVHDR_EN_MASK;
  63293. +
  63294. + if(headerMode != MV_ETH_DISABLE_HEADER_MODE)
  63295. + {
  63296. + /* Enable Header mode. */
  63297. + mvHeaderReg |= ETH_MVHDR_EN_MASK;
  63298. +
  63299. + /* Clear DA-Prefix & MHMask fields.*/
  63300. + mvHeaderReg &= ~(ETH_MVHDR_DAPREFIX_MASK | ETH_MVHDR_MHMASK_MASK);
  63301. +
  63302. + if(numRxQ > 1)
  63303. + {
  63304. + switch (headerMode)
  63305. + {
  63306. + case(MV_ETH_ENABLE_HEADER_MODE_PRI_2_1):
  63307. + mvHeaderReg |= ETH_MVHDR_DAPREFIX_PRI_1_2;
  63308. + break;
  63309. + case(MV_ETH_ENABLE_HEADER_MODE_PRI_DBNUM):
  63310. + mvHeaderReg |= ETH_MVHDR_DAPREFIX_DBNUM_PRI;
  63311. + break;
  63312. + case(MV_ETH_ENABLE_HEADER_MODE_PRI_SPID):
  63313. + mvHeaderReg |= ETH_MVHDR_DAPREFIX_SPID_PRI;
  63314. + break;
  63315. + default:
  63316. + break;
  63317. + }
  63318. +
  63319. + switch (numRxQ)
  63320. + {
  63321. + case (4):
  63322. + mvHeaderReg |= ETH_MVHDR_MHMASK_4_QUEUE;
  63323. + break;
  63324. + case (8):
  63325. + mvHeaderReg |= ETH_MVHDR_MHMASK_8_QUEUE;
  63326. + break;
  63327. + default:
  63328. + break;
  63329. + }
  63330. + }
  63331. + }
  63332. +
  63333. + MV_REG_WRITE(ETH_PORT_MARVELL_HEADER_REG(port), mvHeaderReg);
  63334. +
  63335. + return MV_OK;
  63336. +}
  63337. +
  63338. +#if (MV_ETH_VERSION >= 4)
  63339. +/*******************************************************************************
  63340. +* mvEthEjpModeSet - Enable / Disable EJP policy for TX.
  63341. +*
  63342. +* DESCRIPTION:
  63343. +* This function
  63344. +*
  63345. +* INPUT:
  63346. +* void* pPortHandle - Pointer to port specific handler;
  63347. +* MV_BOOL TRUE - enable EJP mode
  63348. +* FALSE - disable EJP mode
  63349. +*
  63350. +* OUTPUT: MV_STATUS
  63351. +* MV_OK - Success
  63352. +* Other - Failure
  63353. +*
  63354. +* RETURN: None.
  63355. +*
  63356. +*******************************************************************************/
  63357. +MV_STATUS mvEthEjpModeSet(void* pPortHandle, int mode)
  63358. +{
  63359. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63360. + int port = pPortCtrl->portNo;
  63361. +
  63362. + if((port < 0) || (port >= mvCtrlEthMaxPortGet()))
  63363. + return MV_OUT_OF_RANGE;
  63364. +
  63365. + pPortCtrl = ethPortCtrl[port];
  63366. + if(pPortCtrl == NULL)
  63367. + return MV_NOT_FOUND;
  63368. +
  63369. + pPortCtrl->portConfig.ejpMode = mode;
  63370. + if(mode)
  63371. + {
  63372. + /* EJP enabled */
  63373. + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(port), ETH_TX_EJP_ENABLE_MASK);
  63374. + }
  63375. + else
  63376. + {
  63377. + /* EJP disabled */
  63378. + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(port), 0);
  63379. + }
  63380. + mvOsPrintf("eth_%d: EJP %s - ETH_TXQ_CMD_1_REG: 0x%x = 0x%08x\n",
  63381. + port, mode ? "Enabled" : "Disabled", ETH_TXQ_CMD_1_REG(port),
  63382. + MV_REG_READ(ETH_TXQ_CMD_1_REG(port)));
  63383. +
  63384. + return MV_OK;
  63385. +}
  63386. +#endif /* MV_ETH_VERSION >= 4 */
  63387. +
  63388. +/*******************************************************************************
  63389. +* mvEthStatusGet - Get major properties of the port .
  63390. +*
  63391. +* DESCRIPTION:
  63392. +* This function get major properties of the port (link, speed, duplex,
  63393. +* flowControl, etc) and return them using the single structure.
  63394. +*
  63395. +* INPUT:
  63396. +* void* pPortHandle - Pointer to port specific handler;
  63397. +*
  63398. +* OUTPUT:
  63399. +* MV_ETH_PORT_STATUS* pStatus - Pointer to structure, were port status
  63400. +* will be placed.
  63401. +*
  63402. +* RETURN: None.
  63403. +*
  63404. +*******************************************************************************/
  63405. +void mvEthStatusGet(void* pPortHandle, MV_ETH_PORT_STATUS* pStatus)
  63406. +{
  63407. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63408. + int port = pPortCtrl->portNo;
  63409. +
  63410. + MV_U32 regValue;
  63411. +
  63412. + regValue = MV_REG_READ( ETH_PORT_STATUS_REG(port) );
  63413. +
  63414. + if(regValue & ETH_GMII_SPEED_1000_MASK)
  63415. + pStatus->speed = MV_ETH_SPEED_1000;
  63416. + else if(regValue & ETH_MII_SPEED_100_MASK)
  63417. + pStatus->speed = MV_ETH_SPEED_100;
  63418. + else
  63419. + pStatus->speed = MV_ETH_SPEED_10;
  63420. +
  63421. + if(regValue & ETH_LINK_UP_MASK)
  63422. + pStatus->isLinkUp = MV_TRUE;
  63423. + else
  63424. + pStatus->isLinkUp = MV_FALSE;
  63425. +
  63426. + if(regValue & ETH_FULL_DUPLEX_MASK)
  63427. + pStatus->duplex = MV_ETH_DUPLEX_FULL;
  63428. + else
  63429. + pStatus->duplex = MV_ETH_DUPLEX_HALF;
  63430. +
  63431. +
  63432. + if(regValue & ETH_ENABLE_RCV_FLOW_CTRL_MASK)
  63433. + pStatus->flowControl = MV_ETH_FC_ENABLE;
  63434. + else
  63435. + pStatus->flowControl = MV_ETH_FC_DISABLE;
  63436. +}
  63437. +
  63438. +
  63439. +/******************************************************************************/
  63440. +/* PHY Control Functions */
  63441. +/******************************************************************************/
  63442. +
  63443. +
  63444. +/*******************************************************************************
  63445. +* mvEthPhyAddrSet - Set the ethernet port PHY address.
  63446. +*
  63447. +* DESCRIPTION:
  63448. +* This routine set the ethernet port PHY address according to given
  63449. +* parameter.
  63450. +*
  63451. +* INPUT:
  63452. +* void* pPortHandle - Pointer to port specific handler;
  63453. +* int phyAddr - PHY address
  63454. +*
  63455. +* RETURN:
  63456. +* None.
  63457. +*
  63458. +*******************************************************************************/
  63459. +void mvEthPhyAddrSet(void* pPortHandle, int phyAddr)
  63460. +{
  63461. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63462. + int port = pPortCtrl->portNo;
  63463. + unsigned int regData;
  63464. +
  63465. + regData = MV_REG_READ(ETH_PHY_ADDR_REG(port));
  63466. +
  63467. + regData &= ~ETH_PHY_ADDR_MASK;
  63468. + regData |= phyAddr;
  63469. +
  63470. + MV_REG_WRITE(ETH_PHY_ADDR_REG(port), regData);
  63471. +
  63472. + return;
  63473. +}
  63474. +
  63475. +/*******************************************************************************
  63476. +* mvEthPhyAddrGet - Get the ethernet port PHY address.
  63477. +*
  63478. +* DESCRIPTION:
  63479. +* This routine returns the given ethernet port PHY address.
  63480. +*
  63481. +* INPUT:
  63482. +* void* pPortHandle - Pointer to port specific handler;
  63483. +*
  63484. +*
  63485. +* RETURN: int - PHY address.
  63486. +*
  63487. +*******************************************************************************/
  63488. +int mvEthPhyAddrGet(void* pPortHandle)
  63489. +{
  63490. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  63491. + int port = pPortCtrl->portNo;
  63492. + unsigned int regData;
  63493. +
  63494. + regData = MV_REG_READ(ETH_PHY_ADDR_REG(port));
  63495. +
  63496. + return ((regData >> (5 * port)) & 0x1f);
  63497. +}
  63498. +
  63499. +/******************************************************************************/
  63500. +/* Descriptor handling Functions */
  63501. +/******************************************************************************/
  63502. +
  63503. +/*******************************************************************************
  63504. +* etherInitRxDescRing - Curve a Rx chain desc list and buffer in memory.
  63505. +*
  63506. +* DESCRIPTION:
  63507. +* This function prepares a Rx chained list of descriptors and packet
  63508. +* buffers in a form of a ring. The routine must be called after port
  63509. +* initialization routine and before port start routine.
  63510. +* The Ethernet SDMA engine uses CPU bus addresses to access the various
  63511. +* devices in the system (i.e. DRAM). This function uses the ethernet
  63512. +* struct 'virtual to physical' routine (set by the user) to set the ring
  63513. +* with physical addresses.
  63514. +*
  63515. +* INPUT:
  63516. +* ETH_QUEUE_CTRL *pEthPortCtrl Ethernet Port Control srtuct.
  63517. +* int rxQueue Number of Rx queue.
  63518. +* int rxDescNum Number of Rx descriptors
  63519. +* MV_U8* rxDescBaseAddr Rx descriptors memory area base addr.
  63520. +*
  63521. +* OUTPUT:
  63522. +* The routine updates the Ethernet port control struct with information
  63523. +* regarding the Rx descriptors and buffers.
  63524. +*
  63525. +* RETURN: None
  63526. +*
  63527. +*******************************************************************************/
  63528. +static void ethInitRxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue)
  63529. +{
  63530. + ETH_RX_DESC *pRxDescBase, *pRxDesc, *pRxPrevDesc;
  63531. + int ix, rxDescNum = pPortCtrl->rxQueueConfig[queue].descrNum;
  63532. + ETH_QUEUE_CTRL *pQueueCtrl = &pPortCtrl->rxQueue[queue];
  63533. +
  63534. + /* Make sure descriptor address is cache line size aligned */
  63535. + pRxDescBase = (ETH_RX_DESC*)MV_ALIGN_UP((MV_ULONG)pQueueCtrl->descBuf.bufVirtPtr,
  63536. + CPU_D_CACHE_LINE_SIZE);
  63537. +
  63538. + pRxDesc = (ETH_RX_DESC*)pRxDescBase;
  63539. + pRxPrevDesc = pRxDesc;
  63540. +
  63541. + /* initialize the Rx descriptors ring */
  63542. + for (ix=0; ix<rxDescNum; ix++)
  63543. + {
  63544. + pRxDesc->bufSize = 0x0;
  63545. + pRxDesc->byteCnt = 0x0;
  63546. + pRxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
  63547. + pRxDesc->bufPtr = 0x0;
  63548. + pRxDesc->returnInfo = 0x0;
  63549. + pRxPrevDesc = pRxDesc;
  63550. + if(ix == (rxDescNum-1))
  63551. + {
  63552. + /* Closing Rx descriptors ring */
  63553. + pRxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pRxDescBase);
  63554. + }
  63555. + else
  63556. + {
  63557. + pRxDesc = (ETH_RX_DESC*)((MV_ULONG)pRxDesc + ETH_RX_DESC_ALIGNED_SIZE);
  63558. + pRxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pRxDesc);
  63559. + }
  63560. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxPrevDesc);
  63561. + }
  63562. +
  63563. + pQueueCtrl->pCurrentDescr = pRxDescBase;
  63564. + pQueueCtrl->pUsedDescr = pRxDescBase;
  63565. +
  63566. + pQueueCtrl->pFirstDescr = pRxDescBase;
  63567. + pQueueCtrl->pLastDescr = pRxDesc;
  63568. + pQueueCtrl->resource = 0;
  63569. +}
  63570. +
  63571. +void ethResetRxDescRing(void* pPortHndl, int queue)
  63572. +{
  63573. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  63574. + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->rxQueue[queue];
  63575. + ETH_RX_DESC* pRxDesc = (ETH_RX_DESC*)pQueueCtrl->pFirstDescr;
  63576. +
  63577. + pQueueCtrl->resource = 0;
  63578. + if(pQueueCtrl->pFirstDescr != NULL)
  63579. + {
  63580. + while(MV_TRUE)
  63581. + {
  63582. + pRxDesc->bufSize = 0x0;
  63583. + pRxDesc->byteCnt = 0x0;
  63584. + pRxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
  63585. + pRxDesc->bufPtr = 0x0;
  63586. + pRxDesc->returnInfo = 0x0;
  63587. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxDesc);
  63588. + if( (void*)pRxDesc == pQueueCtrl->pLastDescr)
  63589. + break;
  63590. + pRxDesc = RX_NEXT_DESC_PTR(pRxDesc, pQueueCtrl);
  63591. + }
  63592. + pQueueCtrl->pCurrentDescr = pQueueCtrl->pFirstDescr;
  63593. + pQueueCtrl->pUsedDescr = pQueueCtrl->pFirstDescr;
  63594. +
  63595. + /* Update RX Command register */
  63596. + pPortCtrl->portRxQueueCmdReg |= (1 << queue);
  63597. +
  63598. + /* update HW */
  63599. + MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue),
  63600. + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
  63601. + }
  63602. + else
  63603. + {
  63604. + /* Update RX Command register */
  63605. + pPortCtrl->portRxQueueCmdReg &= ~(1 << queue);
  63606. +
  63607. + /* update HW */
  63608. + MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue), 0);
  63609. + }
  63610. +}
  63611. +
  63612. +/*******************************************************************************
  63613. +* etherInitTxDescRing - Curve a Tx chain desc list and buffer in memory.
  63614. +*
  63615. +* DESCRIPTION:
  63616. +* This function prepares a Tx chained list of descriptors and packet
  63617. +* buffers in a form of a ring. The routine must be called after port
  63618. +* initialization routine and before port start routine.
  63619. +* The Ethernet SDMA engine uses CPU bus addresses to access the various
  63620. +* devices in the system (i.e. DRAM). This function uses the ethernet
  63621. +* struct 'virtual to physical' routine (set by the user) to set the ring
  63622. +* with physical addresses.
  63623. +*
  63624. +* INPUT:
  63625. +* ETH_PORT_CTRL *pEthPortCtrl Ethernet Port Control srtuct.
  63626. +* int txQueue Number of Tx queue.
  63627. +* int txDescNum Number of Tx descriptors
  63628. +* int txBuffSize Size of Tx buffer
  63629. +* MV_U8* pTxDescBase Tx descriptors memory area base addr.
  63630. +*
  63631. +* OUTPUT:
  63632. +* The routine updates the Ethernet port control struct with information
  63633. +* regarding the Tx descriptors and buffers.
  63634. +*
  63635. +* RETURN: None.
  63636. +*
  63637. +*******************************************************************************/
  63638. +static void ethInitTxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue)
  63639. +{
  63640. + ETH_TX_DESC *pTxDescBase, *pTxDesc, *pTxPrevDesc;
  63641. + int ix, txDescNum = pPortCtrl->txQueueConfig[queue].descrNum;
  63642. + ETH_QUEUE_CTRL *pQueueCtrl = &pPortCtrl->txQueue[queue];
  63643. +
  63644. + /* Make sure descriptor address is cache line size aligned */
  63645. + pTxDescBase = (ETH_TX_DESC*)MV_ALIGN_UP((MV_ULONG)pQueueCtrl->descBuf.bufVirtPtr,
  63646. + CPU_D_CACHE_LINE_SIZE);
  63647. +
  63648. + pTxDesc = (ETH_TX_DESC*)pTxDescBase;
  63649. + pTxPrevDesc = pTxDesc;
  63650. +
  63651. + /* initialize the Tx descriptors ring */
  63652. + for (ix=0; ix<txDescNum; ix++)
  63653. + {
  63654. + pTxDesc->byteCnt = 0x0000;
  63655. + pTxDesc->L4iChk = 0x0000;
  63656. + pTxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
  63657. + pTxDesc->bufPtr = 0x0;
  63658. + pTxDesc->returnInfo = 0x0;
  63659. +
  63660. + pTxPrevDesc = pTxDesc;
  63661. +
  63662. + if(ix == (txDescNum-1))
  63663. + {
  63664. + /* Closing Tx descriptors ring */
  63665. + pTxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pTxDescBase);
  63666. + }
  63667. + else
  63668. + {
  63669. + pTxDesc = (ETH_TX_DESC*)((MV_ULONG)pTxDesc + ETH_TX_DESC_ALIGNED_SIZE);
  63670. + pTxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pTxDesc);
  63671. + }
  63672. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxPrevDesc);
  63673. + }
  63674. +
  63675. + pQueueCtrl->pCurrentDescr = pTxDescBase;
  63676. + pQueueCtrl->pUsedDescr = pTxDescBase;
  63677. +
  63678. + pQueueCtrl->pFirstDescr = pTxDescBase;
  63679. + pQueueCtrl->pLastDescr = pTxDesc;
  63680. + /* Leave one TX descriptor out of use */
  63681. + pQueueCtrl->resource = txDescNum - 1;
  63682. +}
  63683. +
  63684. +void ethResetTxDescRing(void* pPortHndl, int queue)
  63685. +{
  63686. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  63687. + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->txQueue[queue];
  63688. + ETH_TX_DESC* pTxDesc = (ETH_TX_DESC*)pQueueCtrl->pFirstDescr;
  63689. +
  63690. + pQueueCtrl->resource = 0;
  63691. + if(pQueueCtrl->pFirstDescr != NULL)
  63692. + {
  63693. + while(MV_TRUE)
  63694. + {
  63695. + pTxDesc->byteCnt = 0x0000;
  63696. + pTxDesc->L4iChk = 0x0000;
  63697. + pTxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
  63698. + pTxDesc->bufPtr = 0x0;
  63699. + pTxDesc->returnInfo = 0x0;
  63700. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxDesc);
  63701. + pQueueCtrl->resource++;
  63702. + if( (void*)pTxDesc == pQueueCtrl->pLastDescr)
  63703. + break;
  63704. + pTxDesc = TX_NEXT_DESC_PTR(pTxDesc, pQueueCtrl);
  63705. + }
  63706. + /* Leave one TX descriptor out of use */
  63707. + pQueueCtrl->resource--;
  63708. + pQueueCtrl->pCurrentDescr = pQueueCtrl->pFirstDescr;
  63709. + pQueueCtrl->pUsedDescr = pQueueCtrl->pFirstDescr;
  63710. +
  63711. + /* Update TX Command register */
  63712. + pPortCtrl->portTxQueueCmdReg |= MV_32BIT_LE_FAST(1 << queue);
  63713. + /* update HW */
  63714. + MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue),
  63715. + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
  63716. + }
  63717. + else
  63718. + {
  63719. + /* Update TX Command register */
  63720. + pPortCtrl->portTxQueueCmdReg &= MV_32BIT_LE_FAST(~(1 << queue));
  63721. + /* update HW */
  63722. + MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue), 0 );
  63723. + }
  63724. +}
  63725. +
  63726. +/*******************************************************************************
  63727. +* ethAllocDescrMemory - Free memory allocated for RX and TX descriptors.
  63728. +*
  63729. +* DESCRIPTION:
  63730. +* This function allocates memory for RX and TX descriptors.
  63731. +* - If ETH_DESCR_IN_SRAM defined, allocate memory from SRAM.
  63732. +* - If ETH_DESCR_IN_SDRAM defined, allocate memory in SDRAM.
  63733. +*
  63734. +* INPUT:
  63735. +* int size - size of memory should be allocated.
  63736. +*
  63737. +* RETURN: None
  63738. +*
  63739. +*******************************************************************************/
  63740. +static MV_U8* ethAllocDescrMemory(ETH_PORT_CTRL* pPortCtrl, int descSize,
  63741. + MV_ULONG* pPhysAddr, MV_U32 *memHandle)
  63742. +{
  63743. + MV_U8* pVirt;
  63744. +
  63745. +#if defined(ETH_DESCR_IN_SRAM)
  63746. + if(ethDescInSram == MV_TRUE)
  63747. + pVirt = (char*)mvSramMalloc(descSize, pPhysAddr);
  63748. + else
  63749. +#endif /* ETH_DESCR_IN_SRAM */
  63750. + {
  63751. +#ifdef ETH_DESCR_UNCACHED
  63752. + pVirt = (MV_U8*)mvOsIoUncachedMalloc(pPortCtrl->osHandle, descSize,
  63753. + pPhysAddr,memHandle);
  63754. +#else
  63755. + pVirt = (MV_U8*)mvOsIoCachedMalloc(pPortCtrl->osHandle, descSize,
  63756. + pPhysAddr, memHandle);
  63757. +#endif /* ETH_DESCR_UNCACHED */
  63758. + }
  63759. + memset(pVirt, 0, descSize);
  63760. +
  63761. + return pVirt;
  63762. +}
  63763. +
  63764. +/*******************************************************************************
  63765. +* ethFreeDescrMemory - Free memory allocated for RX and TX descriptors.
  63766. +*
  63767. +* DESCRIPTION:
  63768. +* This function frees memory allocated for RX and TX descriptors.
  63769. +* - If ETH_DESCR_IN_SRAM defined, free memory using gtSramFree() function.
  63770. +* - If ETH_DESCR_IN_SDRAM defined, free memory using mvOsFree() function.
  63771. +*
  63772. +* INPUT:
  63773. +* void* pVirtAddr - virtual pointer to memory allocated for RX and TX
  63774. +* desriptors.
  63775. +*
  63776. +* RETURN: None
  63777. +*
  63778. +*******************************************************************************/
  63779. +void ethFreeDescrMemory(ETH_PORT_CTRL* pPortCtrl, MV_BUF_INFO* pDescBuf)
  63780. +{
  63781. + if( (pDescBuf == NULL) || (pDescBuf->bufVirtPtr == NULL) )
  63782. + return;
  63783. +
  63784. +#if defined(ETH_DESCR_IN_SRAM)
  63785. + if( ethDescInSram )
  63786. + {
  63787. + mvSramFree(pDescBuf->bufSize, pDescBuf->bufPhysAddr, pDescBuf->bufVirtPtr);
  63788. + return;
  63789. + }
  63790. +#endif /* ETH_DESCR_IN_SRAM */
  63791. +
  63792. +#ifdef ETH_DESCR_UNCACHED
  63793. + mvOsIoUncachedFree(pPortCtrl->osHandle, pDescBuf->bufSize, pDescBuf->bufPhysAddr,
  63794. + pDescBuf->bufVirtPtr,pDescBuf->memHandle);
  63795. +#else
  63796. + mvOsIoCachedFree(pPortCtrl->osHandle, pDescBuf->bufSize, pDescBuf->bufPhysAddr,
  63797. + pDescBuf->bufVirtPtr,pDescBuf->memHandle);
  63798. +#endif /* ETH_DESCR_UNCACHED */
  63799. +}
  63800. +
  63801. +/******************************************************************************/
  63802. +/* Other Functions */
  63803. +/******************************************************************************/
  63804. +
  63805. +void mvEthPortPowerUp(int port)
  63806. +{
  63807. + MV_U32 regVal;
  63808. +
  63809. + /* MAC Cause register should be cleared */
  63810. + MV_REG_WRITE(ETH_UNIT_INTR_CAUSE_REG(port), 0);
  63811. +
  63812. + if (mvBoardIsPortInSgmii(port))
  63813. + mvEthPortSgmiiConfig(port);
  63814. +
  63815. + /* Cancel Port Reset */
  63816. + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));
  63817. + regVal &= (~ETH_PORT_RESET_MASK);
  63818. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal);
  63819. + while( (MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port)) & ETH_PORT_RESET_MASK) != 0);
  63820. +}
  63821. +
  63822. +void mvEthPortPowerDown(int port)
  63823. +{
  63824. + MV_U32 regVal;
  63825. +
  63826. + /* Port must be DISABLED */
  63827. + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));
  63828. + if( (regVal & ETH_PORT_ENABLE_MASK) != 0)
  63829. + {
  63830. + mvOsPrintf("ethPort #%d: PowerDown - port must be Disabled (PSC=0x%x)\n",
  63831. + port, regVal);
  63832. + return;
  63833. + }
  63834. +
  63835. + /* Port Reset (Read after write the register as a precaution) */
  63836. + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));
  63837. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal | ETH_PORT_RESET_MASK);
  63838. + while((MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port)) & ETH_PORT_RESET_MASK) == 0);
  63839. +}
  63840. +
  63841. +static void mvEthPortSgmiiConfig(int port)
  63842. +{
  63843. + MV_U32 regVal;
  63844. +
  63845. + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));
  63846. +
  63847. + regVal |= (ETH_SGMII_MODE_MASK /*| ETH_INBAND_AUTO_NEG_ENABLE_MASK */);
  63848. + regVal &= (~ETH_INBAND_AUTO_NEG_BYPASS_MASK);
  63849. +
  63850. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal);
  63851. +}
  63852. +
  63853. +
  63854. +
  63855. +
  63856. +
  63857. +
  63858. +
  63859. +
  63860. +
  63861. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c
  63862. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c 1970-01-01 01:00:00.000000000 +0100
  63863. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c 2010-08-05 22:02:24.594868165 +0200
  63864. @@ -0,0 +1,748 @@
  63865. +/*******************************************************************************
  63866. +Copyright (C) Marvell International Ltd. and its affiliates
  63867. +
  63868. +This software file (the "File") is owned and distributed by Marvell
  63869. +International Ltd. and/or its affiliates ("Marvell") under the following
  63870. +alternative licensing terms. Once you have made an election to distribute the
  63871. +File under one of the following license alternatives, please (i) delete this
  63872. +introductory statement regarding license alternatives, (ii) delete the two
  63873. +license alternatives that you have not elected to use and (iii) preserve the
  63874. +Marvell copyright notice above.
  63875. +
  63876. +********************************************************************************
  63877. +Marvell Commercial License Option
  63878. +
  63879. +If you received this File from Marvell and you have entered into a commercial
  63880. +license agreement (a "Commercial License") with Marvell, the File is licensed
  63881. +to you under the terms of the applicable Commercial License.
  63882. +
  63883. +********************************************************************************
  63884. +Marvell GPL License Option
  63885. +
  63886. +If you received this File from Marvell, you may opt to use, redistribute and/or
  63887. +modify this File in accordance with the terms and conditions of the General
  63888. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  63889. +available along with the File in the license.txt file or by writing to the Free
  63890. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  63891. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  63892. +
  63893. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  63894. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  63895. +DISCLAIMED. The GPL License provides additional details about this warranty
  63896. +disclaimer.
  63897. +********************************************************************************
  63898. +Marvell BSD License Option
  63899. +
  63900. +If you received this File from Marvell, you may opt to use, redistribute and/or
  63901. +modify this File under the following licensing terms.
  63902. +Redistribution and use in source and binary forms, with or without modification,
  63903. +are permitted provided that the following conditions are met:
  63904. +
  63905. + * Redistributions of source code must retain the above copyright notice,
  63906. + this list of conditions and the following disclaimer.
  63907. +
  63908. + * Redistributions in binary form must reproduce the above copyright
  63909. + notice, this list of conditions and the following disclaimer in the
  63910. + documentation and/or other materials provided with the distribution.
  63911. +
  63912. + * Neither the name of Marvell nor the names of its contributors may be
  63913. + used to endorse or promote products derived from this software without
  63914. + specific prior written permission.
  63915. +
  63916. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  63917. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  63918. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  63919. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  63920. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  63921. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  63922. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  63923. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  63924. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  63925. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  63926. +
  63927. +*******************************************************************************/
  63928. +
  63929. +/*******************************************************************************
  63930. +* mvEthDebug.c - Source file for user friendly debug functions
  63931. +*
  63932. +* DESCRIPTION:
  63933. +*
  63934. +* DEPENDENCIES:
  63935. +* None.
  63936. +*
  63937. +*******************************************************************************/
  63938. +
  63939. +#include "mvOs.h"
  63940. +#include "mvCommon.h"
  63941. +#include "mvTypes.h"
  63942. +#include "mv802_3.h"
  63943. +#include "mvDebug.h"
  63944. +#include "ctrlEnv/mvCtrlEnvLib.h"
  63945. +#include "eth-phy/mvEthPhy.h"
  63946. +#include "eth/mvEth.h"
  63947. +#include "eth/gbe/mvEthDebug.h"
  63948. +
  63949. +/* #define mvOsPrintf printf */
  63950. +
  63951. +void mvEthPortShow(void* pHndl);
  63952. +void mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode);
  63953. +
  63954. +/******************************************************************************/
  63955. +/* Debug functions */
  63956. +/******************************************************************************/
  63957. +void ethRxCoal(int port, int usec)
  63958. +{
  63959. + void* pHndl;
  63960. +
  63961. + pHndl = mvEthPortHndlGet(port);
  63962. + if(pHndl != NULL)
  63963. + {
  63964. + mvEthRxCoalSet(pHndl, usec);
  63965. + }
  63966. +}
  63967. +
  63968. +void ethTxCoal(int port, int usec)
  63969. +{
  63970. + void* pHndl;
  63971. +
  63972. + pHndl = mvEthPortHndlGet(port);
  63973. + if(pHndl != NULL)
  63974. + {
  63975. + mvEthTxCoalSet(pHndl, usec);
  63976. + }
  63977. +}
  63978. +
  63979. +#if (MV_ETH_VERSION >= 4)
  63980. +void ethEjpModeSet(int port, int mode)
  63981. +{
  63982. + void* pHndl;
  63983. +
  63984. + pHndl = mvEthPortHndlGet(port);
  63985. + if(pHndl != NULL)
  63986. + {
  63987. + mvEthEjpModeSet(pHndl, mode);
  63988. + }
  63989. +}
  63990. +#endif /* (MV_ETH_VERSION >= 4) */
  63991. +
  63992. +void ethBpduRxQ(int port, int bpduQueue)
  63993. +{
  63994. + void* pHndl;
  63995. +
  63996. + pHndl = mvEthPortHndlGet(port);
  63997. + if(pHndl != NULL)
  63998. + {
  63999. + mvEthBpduRxQueue(pHndl, bpduQueue);
  64000. + }
  64001. +}
  64002. +
  64003. +void ethArpRxQ(int port, int arpQueue)
  64004. +{
  64005. + void* pHndl;
  64006. +
  64007. + pHndl = mvEthPortHndlGet(port);
  64008. + if(pHndl != NULL)
  64009. + {
  64010. + mvEthArpRxQueue(pHndl, arpQueue);
  64011. + }
  64012. +}
  64013. +
  64014. +void ethTcpRxQ(int port, int tcpQueue)
  64015. +{
  64016. + void* pHndl;
  64017. +
  64018. + pHndl = mvEthPortHndlGet(port);
  64019. + if(pHndl != NULL)
  64020. + {
  64021. + mvEthTcpRxQueue(pHndl, tcpQueue);
  64022. + }
  64023. +}
  64024. +
  64025. +void ethUdpRxQ(int port, int udpQueue)
  64026. +{
  64027. + void* pHndl;
  64028. +
  64029. + pHndl = mvEthPortHndlGet(port);
  64030. + if(pHndl != NULL)
  64031. + {
  64032. + mvEthUdpRxQueue(pHndl, udpQueue);
  64033. + }
  64034. +}
  64035. +
  64036. +void ethTxPolicyRegs(int port)
  64037. +{
  64038. + int queue;
  64039. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)mvEthPortHndlGet(port);
  64040. +
  64041. + if(pPortCtrl == NULL)
  64042. + {
  64043. + return;
  64044. + }
  64045. + mvOsPrintf("Port #%d TX Policy: EJP=%d, TXQs: ",
  64046. + port, pPortCtrl->portConfig.ejpMode);
  64047. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  64048. + {
  64049. + if(pPortCtrl->txQueueConfig[queue].descrNum > 0)
  64050. + mvOsPrintf("%d, ", queue);
  64051. + }
  64052. + mvOsPrintf("\n");
  64053. +
  64054. + mvOsPrintf("\n\t TX policy Port #%d configuration registers\n", port);
  64055. +
  64056. + mvOsPrintf("ETH_TX_QUEUE_COMMAND_REG : 0x%X = 0x%08x\n",
  64057. + ETH_TX_QUEUE_COMMAND_REG(port),
  64058. + MV_REG_READ( ETH_TX_QUEUE_COMMAND_REG(port) ) );
  64059. +
  64060. + mvOsPrintf("ETH_TX_FIXED_PRIO_CFG_REG : 0x%X = 0x%08x\n",
  64061. + ETH_TX_FIXED_PRIO_CFG_REG(port),
  64062. + MV_REG_READ( ETH_TX_FIXED_PRIO_CFG_REG(port) ) );
  64063. +
  64064. + mvOsPrintf("ETH_TX_TOKEN_RATE_CFG_REG : 0x%X = 0x%08x\n",
  64065. + ETH_TX_TOKEN_RATE_CFG_REG(port),
  64066. + MV_REG_READ( ETH_TX_TOKEN_RATE_CFG_REG(port) ) );
  64067. +
  64068. + mvOsPrintf("ETH_MAX_TRANSMIT_UNIT_REG : 0x%X = 0x%08x\n",
  64069. + ETH_MAX_TRANSMIT_UNIT_REG(port),
  64070. + MV_REG_READ( ETH_MAX_TRANSMIT_UNIT_REG(port) ) );
  64071. +
  64072. + mvOsPrintf("ETH_TX_TOKEN_BUCKET_SIZE_REG : 0x%X = 0x%08x\n",
  64073. + ETH_TX_TOKEN_BUCKET_SIZE_REG(port),
  64074. + MV_REG_READ( ETH_TX_TOKEN_BUCKET_SIZE_REG(port) ) );
  64075. +
  64076. + mvOsPrintf("ETH_TX_TOKEN_BUCKET_COUNT_REG : 0x%X = 0x%08x\n",
  64077. + ETH_TX_TOKEN_BUCKET_COUNT_REG(port),
  64078. + MV_REG_READ( ETH_TX_TOKEN_BUCKET_COUNT_REG(port) ) );
  64079. +
  64080. + for(queue=0; queue<MV_ETH_MAX_TXQ; queue++)
  64081. + {
  64082. + mvOsPrintf("\n\t TX policy Port #%d, Queue #%d configuration registers\n", port, queue);
  64083. +
  64084. + mvOsPrintf("ETH_TXQ_TOKEN_COUNT_REG : 0x%X = 0x%08x\n",
  64085. + ETH_TXQ_TOKEN_COUNT_REG(port, queue),
  64086. + MV_REG_READ( ETH_TXQ_TOKEN_COUNT_REG(port, queue) ) );
  64087. +
  64088. + mvOsPrintf("ETH_TXQ_TOKEN_CFG_REG : 0x%X = 0x%08x\n",
  64089. + ETH_TXQ_TOKEN_CFG_REG(port, queue),
  64090. + MV_REG_READ( ETH_TXQ_TOKEN_CFG_REG(port, queue) ) );
  64091. +
  64092. + mvOsPrintf("ETH_TXQ_ARBITER_CFG_REG : 0x%X = 0x%08x\n",
  64093. + ETH_TXQ_ARBITER_CFG_REG(port, queue),
  64094. + MV_REG_READ( ETH_TXQ_ARBITER_CFG_REG(port, queue) ) );
  64095. + }
  64096. + mvOsPrintf("\n");
  64097. +}
  64098. +
  64099. +/* Print important registers of Ethernet port */
  64100. +void ethPortRegs(int port)
  64101. +{
  64102. + mvOsPrintf("\n\t ethGiga #%d port Registers:\n", port);
  64103. +
  64104. + mvOsPrintf("ETH_PORT_STATUS_REG : 0x%X = 0x%08x\n",
  64105. + ETH_PORT_STATUS_REG(port),
  64106. + MV_REG_READ( ETH_PORT_STATUS_REG(port) ) );
  64107. +
  64108. + mvOsPrintf("ETH_PORT_SERIAL_CTRL_REG : 0x%X = 0x%08x\n",
  64109. + ETH_PORT_SERIAL_CTRL_REG(port),
  64110. + MV_REG_READ( ETH_PORT_SERIAL_CTRL_REG(port) ) );
  64111. +
  64112. + mvOsPrintf("ETH_PORT_CONFIG_REG : 0x%X = 0x%08x\n",
  64113. + ETH_PORT_CONFIG_REG(port),
  64114. + MV_REG_READ( ETH_PORT_CONFIG_REG(port) ) );
  64115. +
  64116. + mvOsPrintf("ETH_PORT_CONFIG_EXTEND_REG : 0x%X = 0x%08x\n",
  64117. + ETH_PORT_CONFIG_EXTEND_REG(port),
  64118. + MV_REG_READ( ETH_PORT_CONFIG_EXTEND_REG(port) ) );
  64119. +
  64120. + mvOsPrintf("ETH_SDMA_CONFIG_REG : 0x%X = 0x%08x\n",
  64121. + ETH_SDMA_CONFIG_REG(port),
  64122. + MV_REG_READ( ETH_SDMA_CONFIG_REG(port) ) );
  64123. +
  64124. + mvOsPrintf("ETH_TX_FIFO_URGENT_THRESH_REG : 0x%X = 0x%08x\n",
  64125. + ETH_TX_FIFO_URGENT_THRESH_REG(port),
  64126. + MV_REG_READ( ETH_TX_FIFO_URGENT_THRESH_REG(port) ) );
  64127. +
  64128. + mvOsPrintf("ETH_RX_QUEUE_COMMAND_REG : 0x%X = 0x%08x\n",
  64129. + ETH_RX_QUEUE_COMMAND_REG(port),
  64130. + MV_REG_READ( ETH_RX_QUEUE_COMMAND_REG(port) ) );
  64131. +
  64132. + mvOsPrintf("ETH_TX_QUEUE_COMMAND_REG : 0x%X = 0x%08x\n",
  64133. + ETH_TX_QUEUE_COMMAND_REG(port),
  64134. + MV_REG_READ( ETH_TX_QUEUE_COMMAND_REG(port) ) );
  64135. +
  64136. + mvOsPrintf("ETH_INTR_CAUSE_REG : 0x%X = 0x%08x\n",
  64137. + ETH_INTR_CAUSE_REG(port),
  64138. + MV_REG_READ( ETH_INTR_CAUSE_REG(port) ) );
  64139. +
  64140. + mvOsPrintf("ETH_INTR_EXTEND_CAUSE_REG : 0x%X = 0x%08x\n",
  64141. + ETH_INTR_CAUSE_EXT_REG(port),
  64142. + MV_REG_READ( ETH_INTR_CAUSE_EXT_REG(port) ) );
  64143. +
  64144. + mvOsPrintf("ETH_INTR_MASK_REG : 0x%X = 0x%08x\n",
  64145. + ETH_INTR_MASK_REG(port),
  64146. + MV_REG_READ( ETH_INTR_MASK_REG(port) ) );
  64147. +
  64148. + mvOsPrintf("ETH_INTR_EXTEND_MASK_REG : 0x%X = 0x%08x\n",
  64149. + ETH_INTR_MASK_EXT_REG(port),
  64150. + MV_REG_READ( ETH_INTR_MASK_EXT_REG(port) ) );
  64151. +
  64152. + mvOsPrintf("ETH_RX_DESCR_STAT_CMD_REG : 0x%X = 0x%08x\n",
  64153. + ETH_RX_DESCR_STAT_CMD_REG(port, 0),
  64154. + MV_REG_READ( ETH_RX_DESCR_STAT_CMD_REG(port, 0) ) );
  64155. +
  64156. + mvOsPrintf("ETH_RX_BYTE_COUNT_REG : 0x%X = 0x%08x\n",
  64157. + ETH_RX_BYTE_COUNT_REG(port, 0),
  64158. + MV_REG_READ( ETH_RX_BYTE_COUNT_REG(port, 0) ) );
  64159. +
  64160. + mvOsPrintf("ETH_RX_BUF_PTR_REG : 0x%X = 0x%08x\n",
  64161. + ETH_RX_BUF_PTR_REG(port, 0),
  64162. + MV_REG_READ( ETH_RX_BUF_PTR_REG(port, 0) ) );
  64163. +
  64164. + mvOsPrintf("ETH_RX_CUR_DESC_PTR_REG : 0x%X = 0x%08x\n",
  64165. + ETH_RX_CUR_DESC_PTR_REG(port, 0),
  64166. + MV_REG_READ( ETH_RX_CUR_DESC_PTR_REG(port, 0) ) );
  64167. +}
  64168. +
  64169. +
  64170. +/* Print Giga Ethernet UNIT registers */
  64171. +void ethRegs(int port)
  64172. +{
  64173. + mvOsPrintf("ETH_PHY_ADDR_REG : 0x%X = 0x%08x\n",
  64174. + ETH_PHY_ADDR_REG(port),
  64175. + MV_REG_READ(ETH_PHY_ADDR_REG(port)) );
  64176. +
  64177. + mvOsPrintf("ETH_UNIT_INTR_CAUSE_REG : 0x%X = 0x%08x\n",
  64178. + ETH_UNIT_INTR_CAUSE_REG(port),
  64179. + MV_REG_READ( ETH_UNIT_INTR_CAUSE_REG(port)) );
  64180. +
  64181. + mvOsPrintf("ETH_UNIT_INTR_MASK_REG : 0x%X = 0x%08x\n",
  64182. + ETH_UNIT_INTR_MASK_REG(port),
  64183. + MV_REG_READ( ETH_UNIT_INTR_MASK_REG(port)) );
  64184. +
  64185. + mvOsPrintf("ETH_UNIT_ERROR_ADDR_REG : 0x%X = 0x%08x\n",
  64186. + ETH_UNIT_ERROR_ADDR_REG(port),
  64187. + MV_REG_READ(ETH_UNIT_ERROR_ADDR_REG(port)) );
  64188. +
  64189. + mvOsPrintf("ETH_UNIT_INT_ADDR_ERROR_REG : 0x%X = 0x%08x\n",
  64190. + ETH_UNIT_INT_ADDR_ERROR_REG(port),
  64191. + MV_REG_READ(ETH_UNIT_INT_ADDR_ERROR_REG(port)) );
  64192. +
  64193. +}
  64194. +
  64195. +/******************************************************************************/
  64196. +/* MIB Counters functions */
  64197. +/******************************************************************************/
  64198. +
  64199. +/*******************************************************************************
  64200. +* ethClearMibCounters - Clear all MIB counters
  64201. +*
  64202. +* DESCRIPTION:
  64203. +* This function clears all MIB counters of a specific ethernet port.
  64204. +* A read from the MIB counter will reset the counter.
  64205. +*
  64206. +* INPUT:
  64207. +* int port - Ethernet Port number.
  64208. +*
  64209. +* RETURN: None
  64210. +*
  64211. +*******************************************************************************/
  64212. +void ethClearCounters(int port)
  64213. +{
  64214. + void* pHndl;
  64215. +
  64216. + pHndl = mvEthPortHndlGet(port);
  64217. + if(pHndl != NULL)
  64218. + mvEthMibCountersClear(pHndl);
  64219. +
  64220. + return;
  64221. +}
  64222. +
  64223. +
  64224. +/* Print counters of the Ethernet port */
  64225. +void ethPortCounters(int port)
  64226. +{
  64227. + MV_U32 regValue, regValHigh;
  64228. + void* pHndl;
  64229. +
  64230. + pHndl = mvEthPortHndlGet(port);
  64231. + if(pHndl == NULL)
  64232. + return;
  64233. +
  64234. + mvOsPrintf("\n\t Port #%d MIB Counters\n\n", port);
  64235. +
  64236. + mvOsPrintf("GoodFramesReceived = %u\n",
  64237. + mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FRAMES_RECEIVED, NULL));
  64238. + mvOsPrintf("BadFramesReceived = %u\n",
  64239. + mvEthMibCounterRead(pHndl, ETH_MIB_BAD_FRAMES_RECEIVED, NULL));
  64240. + mvOsPrintf("BroadcastFramesReceived = %u\n",
  64241. + mvEthMibCounterRead(pHndl, ETH_MIB_BROADCAST_FRAMES_RECEIVED, NULL));
  64242. + mvOsPrintf("MulticastFramesReceived = %u\n",
  64243. + mvEthMibCounterRead(pHndl, ETH_MIB_MULTICAST_FRAMES_RECEIVED, NULL));
  64244. +
  64245. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_OCTETS_RECEIVED_LOW,
  64246. + &regValHigh);
  64247. + mvOsPrintf("GoodOctetsReceived = 0x%08x%08x\n",
  64248. + regValHigh, regValue);
  64249. +
  64250. + mvOsPrintf("\n");
  64251. + mvOsPrintf("GoodFramesSent = %u\n",
  64252. + mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FRAMES_SENT, NULL));
  64253. + mvOsPrintf("BroadcastFramesSent = %u\n",
  64254. + mvEthMibCounterRead(pHndl, ETH_MIB_BROADCAST_FRAMES_SENT, NULL));
  64255. + mvOsPrintf("MulticastFramesSent = %u\n",
  64256. + mvEthMibCounterRead(pHndl, ETH_MIB_MULTICAST_FRAMES_SENT, NULL));
  64257. +
  64258. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_OCTETS_SENT_LOW,
  64259. + &regValHigh);
  64260. + mvOsPrintf("GoodOctetsSent = 0x%08x%08x\n", regValHigh, regValue);
  64261. +
  64262. +
  64263. + mvOsPrintf("\n\t FC Control Counters\n");
  64264. +
  64265. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_UNREC_MAC_CONTROL_RECEIVED, NULL);
  64266. + mvOsPrintf("UnrecogMacControlReceived = %u\n", regValue);
  64267. +
  64268. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FC_RECEIVED, NULL);
  64269. + mvOsPrintf("GoodFCFramesReceived = %u\n", regValue);
  64270. +
  64271. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_FC_RECEIVED, NULL);
  64272. + mvOsPrintf("BadFCFramesReceived = %u\n", regValue);
  64273. +
  64274. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_FC_SENT, NULL);
  64275. + mvOsPrintf("FCFramesSent = %u\n", regValue);
  64276. +
  64277. +
  64278. + mvOsPrintf("\n\t RX Errors\n");
  64279. +
  64280. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_OCTETS_RECEIVED, NULL);
  64281. + mvOsPrintf("BadOctetsReceived = %u\n", regValue);
  64282. +
  64283. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_UNDERSIZE_RECEIVED, NULL);
  64284. + mvOsPrintf("UndersizeFramesReceived = %u\n", regValue);
  64285. +
  64286. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_FRAGMENTS_RECEIVED, NULL);
  64287. + mvOsPrintf("FragmentsReceived = %u\n", regValue);
  64288. +
  64289. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_OVERSIZE_RECEIVED, NULL);
  64290. + mvOsPrintf("OversizeFramesReceived = %u\n", regValue);
  64291. +
  64292. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_JABBER_RECEIVED, NULL);
  64293. + mvOsPrintf("JabbersReceived = %u\n", regValue);
  64294. +
  64295. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_MAC_RECEIVE_ERROR, NULL);
  64296. + mvOsPrintf("MacReceiveErrors = %u\n", regValue);
  64297. +
  64298. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_CRC_EVENT, NULL);
  64299. + mvOsPrintf("BadCrcReceived = %u\n", regValue);
  64300. +
  64301. + mvOsPrintf("\n\t TX Errors\n");
  64302. +
  64303. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR, NULL);
  64304. + mvOsPrintf("TxMacErrors = %u\n", regValue);
  64305. +
  64306. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_EXCESSIVE_COLLISION, NULL);
  64307. + mvOsPrintf("TxExcessiveCollisions = %u\n", regValue);
  64308. +
  64309. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_COLLISION, NULL);
  64310. + mvOsPrintf("TxCollisions = %u\n", regValue);
  64311. +
  64312. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_LATE_COLLISION, NULL);
  64313. + mvOsPrintf("TxLateCollisions = %u\n", regValue);
  64314. +
  64315. +
  64316. + mvOsPrintf("\n");
  64317. + regValue = MV_REG_READ( ETH_RX_DISCARD_PKTS_CNTR_REG(port));
  64318. + mvOsPrintf("Rx Discard packets counter = %u\n", regValue);
  64319. +
  64320. + regValue = MV_REG_READ(ETH_RX_OVERRUN_PKTS_CNTR_REG(port));
  64321. + mvOsPrintf("Rx Overrun packets counter = %u\n", regValue);
  64322. +}
  64323. +
  64324. +/* Print RMON counters of the Ethernet port */
  64325. +void ethPortRmonCounters(int port)
  64326. +{
  64327. + void* pHndl;
  64328. +
  64329. + pHndl = mvEthPortHndlGet(port);
  64330. + if(pHndl == NULL)
  64331. + return;
  64332. +
  64333. + mvOsPrintf("\n\t Port #%d RMON MIB Counters\n\n", port);
  64334. +
  64335. + mvOsPrintf("64 ByteFramesReceived = %u\n",
  64336. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_64_OCTETS, NULL));
  64337. + mvOsPrintf("65...127 ByteFramesReceived = %u\n",
  64338. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_65_TO_127_OCTETS, NULL));
  64339. + mvOsPrintf("128...255 ByteFramesReceived = %u\n",
  64340. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_128_TO_255_OCTETS, NULL));
  64341. + mvOsPrintf("256...511 ByteFramesReceived = %u\n",
  64342. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_256_TO_511_OCTETS, NULL));
  64343. + mvOsPrintf("512...1023 ByteFramesReceived = %u\n",
  64344. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_512_TO_1023_OCTETS, NULL));
  64345. + mvOsPrintf("1024...Max ByteFramesReceived = %u\n",
  64346. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_1024_TO_MAX_OCTETS, NULL));
  64347. +}
  64348. +
  64349. +/* Print port information */
  64350. +void ethPortStatus(int port)
  64351. +{
  64352. + void* pHndl;
  64353. +
  64354. + pHndl = mvEthPortHndlGet(port);
  64355. + if(pHndl != NULL)
  64356. + {
  64357. + mvEthPortShow(pHndl);
  64358. + }
  64359. +}
  64360. +
  64361. +/* Print port queues information */
  64362. +void ethPortQueues(int port, int rxQueue, int txQueue, int mode)
  64363. +{
  64364. + void* pHndl;
  64365. +
  64366. + pHndl = mvEthPortHndlGet(port);
  64367. + if(pHndl != NULL)
  64368. + {
  64369. + mvEthQueuesShow(pHndl, rxQueue, txQueue, mode);
  64370. + }
  64371. +}
  64372. +
  64373. +void ethUcastSet(int port, char* macStr, int queue)
  64374. +{
  64375. + void* pHndl;
  64376. + MV_U8 macAddr[MV_MAC_ADDR_SIZE];
  64377. +
  64378. + pHndl = mvEthPortHndlGet(port);
  64379. + if(pHndl != NULL)
  64380. + {
  64381. + mvMacStrToHex(macStr, macAddr);
  64382. + mvEthMacAddrSet(pHndl, macAddr, queue);
  64383. + }
  64384. +}
  64385. +
  64386. +
  64387. +void ethPortUcastShow(int port)
  64388. +{
  64389. + MV_U32 unicastReg, macL, macH;
  64390. + int i, j;
  64391. +
  64392. + macL = MV_REG_READ(ETH_MAC_ADDR_LOW_REG(port));
  64393. + macH = MV_REG_READ(ETH_MAC_ADDR_HIGH_REG(port));
  64394. +
  64395. + mvOsPrintf("\n\t Port #%d Unicast MAC table: %02x:%02x:%02x:%02x:%02x:%02x\n\n",
  64396. + port, ((macH >> 24) & 0xff), ((macH >> 16) & 0xff),
  64397. + ((macH >> 8) & 0xff), (macH & 0xff),
  64398. + ((macL >> 8) & 0xff), (macL & 0xff) );
  64399. +
  64400. + for (i=0; i<4; i++)
  64401. + {
  64402. + unicastReg = MV_REG_READ( (ETH_DA_FILTER_UCAST_BASE(port) + i*4));
  64403. + for(j=0; j<4; j++)
  64404. + {
  64405. + MV_U8 macEntry = (unicastReg >> (8*j)) & 0xFF;
  64406. +
  64407. + mvOsPrintf("%X: %8s, Q = %d\n", i*4+j,
  64408. + (macEntry & BIT0) ? "Accept" : "Reject", (macEntry >> 1) & 0x7);
  64409. + }
  64410. + }
  64411. +}
  64412. +
  64413. +void ethMcastAdd(int port, char* macStr, int queue)
  64414. +{
  64415. + void* pHndl;
  64416. + MV_U8 macAddr[MV_MAC_ADDR_SIZE];
  64417. +
  64418. + pHndl = mvEthPortHndlGet(port);
  64419. + if(pHndl != NULL)
  64420. + {
  64421. + mvMacStrToHex(macStr, macAddr);
  64422. + mvEthMcastAddrSet(pHndl, macAddr, queue);
  64423. + }
  64424. +}
  64425. +
  64426. +void ethPortMcast(int port)
  64427. +{
  64428. + int tblIdx, regIdx;
  64429. + MV_U32 regVal;
  64430. +
  64431. + mvOsPrintf("\n\t Port #%d Special (IP) Multicast table: 01:00:5E:00:00:XX\n\n",
  64432. + port);
  64433. +
  64434. + for(tblIdx=0; tblIdx<(256/4); tblIdx++)
  64435. + {
  64436. + regVal = MV_REG_READ((ETH_DA_FILTER_SPEC_MCAST_BASE(port) + tblIdx*4));
  64437. + for(regIdx=0; regIdx<4; regIdx++)
  64438. + {
  64439. + if((regVal & (0x01 << (regIdx*8))) != 0)
  64440. + {
  64441. + mvOsPrintf("0x%02X: Accepted, rxQ = %d\n",
  64442. + tblIdx*4+regIdx, ((regVal >> (regIdx*8+1)) & 0x07));
  64443. + }
  64444. + }
  64445. + }
  64446. + mvOsPrintf("\n\t Port #%d Other Multicast table\n\n", port);
  64447. + for(tblIdx=0; tblIdx<(256/4); tblIdx++)
  64448. + {
  64449. + regVal = MV_REG_READ((ETH_DA_FILTER_OTH_MCAST_BASE(port) + tblIdx*4));
  64450. + for(regIdx=0; regIdx<4; regIdx++)
  64451. + {
  64452. + if((regVal & (0x01 << (regIdx*8))) != 0)
  64453. + {
  64454. + mvOsPrintf("Crc8=0x%02X: Accepted, rxQ = %d\n",
  64455. + tblIdx*4+regIdx, ((regVal >> (regIdx*8+1)) & 0x07));
  64456. + }
  64457. + }
  64458. + }
  64459. +}
  64460. +
  64461. +
  64462. +/* Print status of Ethernet port */
  64463. +void mvEthPortShow(void* pHndl)
  64464. +{
  64465. + MV_U32 regValue, rxCoal, txCoal;
  64466. + int speed, queue, port;
  64467. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pHndl;
  64468. +
  64469. + port = pPortCtrl->portNo;
  64470. +
  64471. + regValue = MV_REG_READ( ETH_PORT_STATUS_REG(port) );
  64472. +
  64473. + mvOsPrintf("\n\t ethGiga #%d port Status: 0x%04x = 0x%08x\n\n",
  64474. + port, ETH_PORT_STATUS_REG(port), regValue);
  64475. +
  64476. + mvOsPrintf("descInSram=%d, descSwCoher=%d\n",
  64477. + ethDescInSram, ethDescSwCoher);
  64478. +
  64479. + if(regValue & ETH_GMII_SPEED_1000_MASK)
  64480. + speed = 1000;
  64481. + else if(regValue & ETH_MII_SPEED_100_MASK)
  64482. + speed = 100;
  64483. + else
  64484. + speed = 10;
  64485. +
  64486. + mvEthCoalGet(pPortCtrl, &rxCoal, &txCoal);
  64487. +
  64488. + /* Link, Speed, Duplex, FlowControl */
  64489. + mvOsPrintf("Link=%s, Speed=%d, Duplex=%s, RxFlowControl=%s",
  64490. + (regValue & ETH_LINK_UP_MASK) ? "UP" : "DOWN",
  64491. + speed,
  64492. + (regValue & ETH_FULL_DUPLEX_MASK) ? "FULL" : "HALF",
  64493. + (regValue & ETH_ENABLE_RCV_FLOW_CTRL_MASK) ? "ENABLE" : "DISABLE");
  64494. +
  64495. + mvOsPrintf("\n");
  64496. +
  64497. + mvOsPrintf("RxCoal = %d usec, TxCoal = %d usec\n",
  64498. + rxCoal, txCoal);
  64499. +
  64500. + mvOsPrintf("rxDefQ=%d, arpQ=%d, bpduQ=%d, tcpQ=%d, udpQ=%d\n\n",
  64501. + pPortCtrl->portConfig.rxDefQ, pPortCtrl->portConfig.rxArpQ,
  64502. + pPortCtrl->portConfig.rxBpduQ,
  64503. + pPortCtrl->portConfig.rxTcpQ, pPortCtrl->portConfig.rxUdpQ);
  64504. +
  64505. + /* Print all RX and TX queues */
  64506. + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
  64507. + {
  64508. + mvOsPrintf("RX Queue #%d: base=0x%lx, free=%d\n",
  64509. + queue, (MV_ULONG)pPortCtrl->rxQueue[queue].pFirstDescr,
  64510. + mvEthRxResourceGet(pPortCtrl, queue) );
  64511. + }
  64512. + mvOsPrintf("\n");
  64513. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  64514. + {
  64515. + mvOsPrintf("TX Queue #%d: base=0x%lx, free=%d\n",
  64516. + queue, (MV_ULONG)pPortCtrl->txQueue[queue].pFirstDescr,
  64517. + mvEthTxResourceGet(pPortCtrl, queue) );
  64518. + }
  64519. +}
  64520. +
  64521. +/* Print RX and TX queue of the Ethernet port */
  64522. +void mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode)
  64523. +{
  64524. + ETH_PORT_CTRL *pPortCtrl = (ETH_PORT_CTRL*)pHndl;
  64525. + ETH_QUEUE_CTRL *pQueueCtrl;
  64526. + MV_U32 regValue;
  64527. + ETH_RX_DESC *pRxDescr;
  64528. + ETH_TX_DESC *pTxDescr;
  64529. + int i, port = pPortCtrl->portNo;
  64530. +
  64531. + if( (rxQueue >=0) && (rxQueue < MV_ETH_RX_Q_NUM) )
  64532. + {
  64533. + pQueueCtrl = &(pPortCtrl->rxQueue[rxQueue]);
  64534. + mvOsPrintf("Port #%d, RX Queue #%d\n\n", port, rxQueue);
  64535. +
  64536. + mvOsPrintf("CURR_RX_DESC_PTR : 0x%X = 0x%08x\n",
  64537. + ETH_RX_CUR_DESC_PTR_REG(port, rxQueue),
  64538. + MV_REG_READ( ETH_RX_CUR_DESC_PTR_REG(port, rxQueue)));
  64539. +
  64540. +
  64541. + if(pQueueCtrl->pFirstDescr != NULL)
  64542. + {
  64543. + mvOsPrintf("pFirstDescr=0x%lx, pLastDescr=0x%lx, numOfResources=%d\n",
  64544. + (MV_ULONG)pQueueCtrl->pFirstDescr, (MV_ULONG)pQueueCtrl->pLastDescr,
  64545. + pQueueCtrl->resource);
  64546. + mvOsPrintf("pCurrDescr: 0x%lx, pUsedDescr: 0x%lx\n",
  64547. + (MV_ULONG)pQueueCtrl->pCurrentDescr,
  64548. + (MV_ULONG)pQueueCtrl->pUsedDescr);
  64549. +
  64550. + if(mode == 1)
  64551. + {
  64552. + pRxDescr = (ETH_RX_DESC*)pQueueCtrl->pFirstDescr;
  64553. + i = 0;
  64554. + do
  64555. + {
  64556. + mvOsPrintf("%3d. desc=%08x (%08x), cmd=%08x, data=%4d, buf=%4d, buf=%08x, pkt=%lx, os=%lx\n",
  64557. + i, (MV_U32)pRxDescr, (MV_U32)ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pRxDescr),
  64558. + pRxDescr->cmdSts, pRxDescr->byteCnt, (MV_U32)pRxDescr->bufSize,
  64559. + (unsigned int)pRxDescr->bufPtr, (MV_ULONG)pRxDescr->returnInfo,
  64560. + ((MV_PKT_INFO*)pRxDescr->returnInfo)->osInfo);
  64561. +
  64562. + ETH_DESCR_INV(pPortCtrl, pRxDescr);
  64563. + pRxDescr = RX_NEXT_DESC_PTR(pRxDescr, pQueueCtrl);
  64564. + i++;
  64565. + } while (pRxDescr != pQueueCtrl->pFirstDescr);
  64566. + }
  64567. + }
  64568. + else
  64569. + mvOsPrintf("RX Queue #%d is NOT CREATED\n", rxQueue);
  64570. + }
  64571. +
  64572. + if( (txQueue >=0) && (txQueue < MV_ETH_TX_Q_NUM) )
  64573. + {
  64574. + pQueueCtrl = &(pPortCtrl->txQueue[txQueue]);
  64575. + mvOsPrintf("Port #%d, TX Queue #%d\n\n", port, txQueue);
  64576. +
  64577. + regValue = MV_REG_READ( ETH_TX_CUR_DESC_PTR_REG(port, txQueue));
  64578. + mvOsPrintf("CURR_TX_DESC_PTR : 0x%X = 0x%08x\n",
  64579. + ETH_TX_CUR_DESC_PTR_REG(port, txQueue), regValue);
  64580. +
  64581. + if(pQueueCtrl->pFirstDescr != NULL)
  64582. + {
  64583. + mvOsPrintf("pFirstDescr=0x%lx, pLastDescr=0x%lx, numOfResources=%d\n",
  64584. + (MV_ULONG)pQueueCtrl->pFirstDescr,
  64585. + (MV_ULONG)pQueueCtrl->pLastDescr,
  64586. + pQueueCtrl->resource);
  64587. + mvOsPrintf("pCurrDescr: 0x%lx, pUsedDescr: 0x%lx\n",
  64588. + (MV_ULONG)pQueueCtrl->pCurrentDescr,
  64589. + (MV_ULONG)pQueueCtrl->pUsedDescr);
  64590. +
  64591. + if(mode == 1)
  64592. + {
  64593. + pTxDescr = (ETH_TX_DESC*)pQueueCtrl->pFirstDescr;
  64594. + i = 0;
  64595. + do
  64596. + {
  64597. + mvOsPrintf("%3d. desc=%08x (%08x), cmd=%08x, data=%4d, buf=%08x, pkt=%lx, os=%lx\n",
  64598. + i, (MV_U32)pTxDescr, (MV_U32)ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxDescr),
  64599. + pTxDescr->cmdSts, pTxDescr->byteCnt,
  64600. + (MV_U32)pTxDescr->bufPtr, (MV_ULONG)pTxDescr->returnInfo,
  64601. + pTxDescr->returnInfo ? (((MV_PKT_INFO*)pTxDescr->returnInfo)->osInfo) : 0x0);
  64602. +
  64603. + ETH_DESCR_INV(pPortCtrl, pTxDescr);
  64604. + pTxDescr = TX_NEXT_DESC_PTR(pTxDescr, pQueueCtrl);
  64605. + i++;
  64606. + } while (pTxDescr != pQueueCtrl->pFirstDescr);
  64607. + }
  64608. + }
  64609. + else
  64610. + mvOsPrintf("TX Queue #%d is NOT CREATED\n", txQueue);
  64611. + }
  64612. +}
  64613. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h
  64614. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h 1970-01-01 01:00:00.000000000 +0100
  64615. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h 2010-08-05 22:02:24.634868301 +0200
  64616. @@ -0,0 +1,146 @@
  64617. +/*******************************************************************************
  64618. +Copyright (C) Marvell International Ltd. and its affiliates
  64619. +
  64620. +This software file (the "File") is owned and distributed by Marvell
  64621. +International Ltd. and/or its affiliates ("Marvell") under the following
  64622. +alternative licensing terms. Once you have made an election to distribute the
  64623. +File under one of the following license alternatives, please (i) delete this
  64624. +introductory statement regarding license alternatives, (ii) delete the two
  64625. +license alternatives that you have not elected to use and (iii) preserve the
  64626. +Marvell copyright notice above.
  64627. +
  64628. +********************************************************************************
  64629. +Marvell Commercial License Option
  64630. +
  64631. +If you received this File from Marvell and you have entered into a commercial
  64632. +license agreement (a "Commercial License") with Marvell, the File is licensed
  64633. +to you under the terms of the applicable Commercial License.
  64634. +
  64635. +********************************************************************************
  64636. +Marvell GPL License Option
  64637. +
  64638. +If you received this File from Marvell, you may opt to use, redistribute and/or
  64639. +modify this File in accordance with the terms and conditions of the General
  64640. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  64641. +available along with the File in the license.txt file or by writing to the Free
  64642. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  64643. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  64644. +
  64645. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  64646. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  64647. +DISCLAIMED. The GPL License provides additional details about this warranty
  64648. +disclaimer.
  64649. +********************************************************************************
  64650. +Marvell BSD License Option
  64651. +
  64652. +If you received this File from Marvell, you may opt to use, redistribute and/or
  64653. +modify this File under the following licensing terms.
  64654. +Redistribution and use in source and binary forms, with or without modification,
  64655. +are permitted provided that the following conditions are met:
  64656. +
  64657. + * Redistributions of source code must retain the above copyright notice,
  64658. + this list of conditions and the following disclaimer.
  64659. +
  64660. + * Redistributions in binary form must reproduce the above copyright
  64661. + notice, this list of conditions and the following disclaimer in the
  64662. + documentation and/or other materials provided with the distribution.
  64663. +
  64664. + * Neither the name of Marvell nor the names of its contributors may be
  64665. + used to endorse or promote products derived from this software without
  64666. + specific prior written permission.
  64667. +
  64668. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  64669. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  64670. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  64671. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  64672. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  64673. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  64674. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  64675. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  64676. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  64677. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  64678. +
  64679. +*******************************************************************************/
  64680. +#ifndef __MV_ETH_DEBUG_H__
  64681. +#define __MV_ETH_DEBUG_H__
  64682. +
  64683. +#if 0
  64684. +/*
  64685. + ** Externs
  64686. + */
  64687. +void ethBpduRxQ(int port, int bpduQueue);
  64688. +void ethArpRxQ(int port, int bpduQueue);
  64689. +void ethTcpRxQ(int port, int bpduQueue);
  64690. +void ethUdpRxQ(int port, int bpduQueue);
  64691. +void ethMcastAdd(int port, char* macStr, int queue);
  64692. +
  64693. +#ifdef INCLUDE_MULTI_QUEUE
  64694. +void ethRxPolicy( int port);
  64695. +void ethTxPolicy( int port);
  64696. +void ethTxPolDA(int port, char* macStr, int txQ, char* headerHexStr);
  64697. +void ethRxPolMode(int port, MV_ETH_PRIO_MODE prioMode);
  64698. +void ethRxPolQ(int port, int rxQueue, int rxQuota);
  64699. +#endif /* INCLUDE_MULTI_QUEUE */
  64700. +
  64701. +void print_egiga_stat(void *sc, unsigned int port);
  64702. +void ethPortStatus (int port);
  64703. +void ethPortQueues( int port, int rxQueue, int txQueue, int mode);
  64704. +void ethPortMcast(int port);
  64705. +void ethPortRegs(int port);
  64706. +void ethPortCounters(int port);
  64707. +void ethPortRmonCounters(int port);
  64708. +void ethRxCoal(int port, int usec);
  64709. +void ethTxCoal(int port, int usec);
  64710. +
  64711. +void ethRegs(int port);
  64712. +void ethClearCounters(int port);
  64713. +void ethUcastSet(int port, char* macStr, int queue);
  64714. +void ethPortUcastShow(int port);
  64715. +
  64716. +#ifdef CONFIG_MV_ETH_HEADER
  64717. +void run_com_header(const char *buffer);
  64718. +#endif
  64719. +
  64720. +#ifdef INCLUDE_MULTI_QUEUE
  64721. +void ethRxPolMode(int port, MV_ETH_PRIO_MODE prioMode);
  64722. +void ethRxPolQ(int port, int queue, int quota);
  64723. +void ethRxPolicy(int port);
  64724. +void ethTxPolDef(int port, int txQ, char* headerHexStr);
  64725. +void ethTxPolDA(int port, char* macStr, int txQ, char* headerHexStr);
  64726. +void ethTxPolicy(int port);
  64727. +#endif /* INCLUDE_MULTI_QUEUE */
  64728. +
  64729. +#if (MV_ETH_VERSION >= 4)
  64730. +void ethEjpModeSet(int port, int mode)
  64731. +#endif
  64732. +#endif /* 0 */
  64733. +
  64734. +
  64735. +
  64736. +
  64737. +void ethRxCoal(int port, int usec);
  64738. +void ethTxCoal(int port, int usec);
  64739. +#if (MV_ETH_VERSION >= 4)
  64740. +void ethEjpModeSet(int port, int mode);
  64741. +#endif /* (MV_ETH_VERSION >= 4) */
  64742. +
  64743. +void ethBpduRxQ(int port, int bpduQueue);
  64744. +void ethArpRxQ(int port, int arpQueue);
  64745. +void ethTcpRxQ(int port, int tcpQueue);
  64746. +void ethUdpRxQ(int port, int udpQueue);
  64747. +void ethTxPolicyRegs(int port);
  64748. +void ethPortRegs(int port);
  64749. +void ethRegs(int port);
  64750. +void ethClearCounters(int port);
  64751. +void ethPortCounters(int port);
  64752. +void ethPortRmonCounters(int port);
  64753. +void ethPortStatus(int port);
  64754. +void ethPortQueues(int port, int rxQueue, int txQueue, int mode);
  64755. +void ethUcastSet(int port, char* macStr, int queue);
  64756. +void ethPortUcastShow(int port);
  64757. +void ethMcastAdd(int port, char* macStr, int queue);
  64758. +void ethPortMcast(int port);
  64759. +void mvEthPortShow(void* pHndl);
  64760. +void mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode);
  64761. +
  64762. +#endif
  64763. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h
  64764. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h 1970-01-01 01:00:00.000000000 +0100
  64765. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h 2010-08-05 22:02:24.664868309 +0200
  64766. @@ -0,0 +1,751 @@
  64767. +/*******************************************************************************
  64768. +Copyright (C) Marvell International Ltd. and its affiliates
  64769. +
  64770. +This software file (the "File") is owned and distributed by Marvell
  64771. +International Ltd. and/or its affiliates ("Marvell") under the following
  64772. +alternative licensing terms. Once you have made an election to distribute the
  64773. +File under one of the following license alternatives, please (i) delete this
  64774. +introductory statement regarding license alternatives, (ii) delete the two
  64775. +license alternatives that you have not elected to use and (iii) preserve the
  64776. +Marvell copyright notice above.
  64777. +
  64778. +********************************************************************************
  64779. +Marvell Commercial License Option
  64780. +
  64781. +If you received this File from Marvell and you have entered into a commercial
  64782. +license agreement (a "Commercial License") with Marvell, the File is licensed
  64783. +to you under the terms of the applicable Commercial License.
  64784. +
  64785. +********************************************************************************
  64786. +Marvell GPL License Option
  64787. +
  64788. +If you received this File from Marvell, you may opt to use, redistribute and/or
  64789. +modify this File in accordance with the terms and conditions of the General
  64790. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  64791. +available along with the File in the license.txt file or by writing to the Free
  64792. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  64793. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  64794. +
  64795. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  64796. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  64797. +DISCLAIMED. The GPL License provides additional details about this warranty
  64798. +disclaimer.
  64799. +********************************************************************************
  64800. +Marvell BSD License Option
  64801. +
  64802. +If you received this File from Marvell, you may opt to use, redistribute and/or
  64803. +modify this File under the following licensing terms.
  64804. +Redistribution and use in source and binary forms, with or without modification,
  64805. +are permitted provided that the following conditions are met:
  64806. +
  64807. + * Redistributions of source code must retain the above copyright notice,
  64808. + this list of conditions and the following disclaimer.
  64809. +
  64810. + * Redistributions in binary form must reproduce the above copyright
  64811. + notice, this list of conditions and the following disclaimer in the
  64812. + documentation and/or other materials provided with the distribution.
  64813. +
  64814. + * Neither the name of Marvell nor the names of its contributors may be
  64815. + used to endorse or promote products derived from this software without
  64816. + specific prior written permission.
  64817. +
  64818. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  64819. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  64820. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  64821. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  64822. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  64823. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  64824. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  64825. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  64826. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  64827. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  64828. +
  64829. +*******************************************************************************/
  64830. +
  64831. +/*******************************************************************************
  64832. +* mvEth.h - Header File for : Marvell Gigabit Ethernet Controller
  64833. +*
  64834. +* DESCRIPTION:
  64835. +* This header file contains macros typedefs and function declaration specific to
  64836. +* the Marvell Gigabit Ethernet Controller.
  64837. +*
  64838. +* DEPENDENCIES:
  64839. +* None.
  64840. +*
  64841. +*******************************************************************************/
  64842. +
  64843. +#ifndef __mvEthGbe_h__
  64844. +#define __mvEthGbe_h__
  64845. +
  64846. +extern MV_BOOL ethDescInSram;
  64847. +extern MV_BOOL ethDescSwCoher;
  64848. +extern ETH_PORT_CTRL* ethPortCtrl[];
  64849. +
  64850. +static INLINE MV_ULONG ethDescVirtToPhy(ETH_QUEUE_CTRL* pQueueCtrl, MV_U8* pDesc)
  64851. +{
  64852. +#if defined (ETH_DESCR_IN_SRAM)
  64853. + if( ethDescInSram )
  64854. + return mvSramVirtToPhy(pDesc);
  64855. + else
  64856. +#endif /* ETH_DESCR_IN_SRAM */
  64857. + return (pQueueCtrl->descBuf.bufPhysAddr + (pDesc - pQueueCtrl->descBuf.bufVirtPtr));
  64858. +}
  64859. +/* Return port handler */
  64860. +#define mvEthPortHndlGet(port) ethPortCtrl[port]
  64861. +
  64862. +/* Used as WA for HW/SW race on TX */
  64863. +static INLINE int mvEthPortTxEnable(void* pPortHndl, int queue, int max_deep)
  64864. +{
  64865. + int deep = 0;
  64866. + MV_U32 txCurrReg, txEnReg;
  64867. + ETH_TX_DESC* pTxLastDesc;
  64868. + ETH_QUEUE_CTRL* pQueueCtrl;
  64869. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  64870. +
  64871. + txEnReg = MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo));
  64872. + if( (txEnReg & MV_32BIT_LE_FAST(ETH_TXQ_ENABLE_MASK)) == 0)
  64873. + {
  64874. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;
  64875. + return 0;
  64876. + }
  64877. +
  64878. + pQueueCtrl = &pPortCtrl->txQueue[queue];
  64879. + pTxLastDesc = pQueueCtrl->pCurrentDescr;
  64880. + txCurrReg = MV_REG_READ(ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue));
  64881. + if(ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxLastDesc) == txCurrReg)
  64882. + {
  64883. + /* All descriptors are processed, no chance for race */
  64884. + return 0;
  64885. + }
  64886. +
  64887. + /* Check distance betwee HW and SW location: */
  64888. + /* If distance between HW and SW pointers is less than max_deep descriptors */
  64889. + /* Race condition is possible, so wait end of TX and restart TXQ */
  64890. + while(deep < max_deep)
  64891. + {
  64892. + pTxLastDesc = TX_PREV_DESC_PTR(pTxLastDesc, pQueueCtrl);
  64893. + if(ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxLastDesc) == txCurrReg)
  64894. + {
  64895. + int count = 0;
  64896. +
  64897. + while( (txEnReg & MV_32BIT_LE_FAST(ETH_TXQ_ENABLE_MASK)) != 0)
  64898. + {
  64899. + count++;
  64900. + if(count > 10000)
  64901. + {
  64902. + mvOsPrintf("mvEthPortTxEnable: timeout - TXQ_CMD=0x%08x\n",
  64903. + MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) );
  64904. + break;
  64905. + }
  64906. + txEnReg = MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo));
  64907. + }
  64908. +
  64909. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;
  64910. + return count;
  64911. + }
  64912. + deep++;
  64913. + }
  64914. + /* Distance between HW and SW pointers is more than max_deep descriptors, */
  64915. + /* So NO race condition - do nothing */
  64916. + return -1;
  64917. +}
  64918. +
  64919. +
  64920. +/* defines */
  64921. +#define ETH_CSUM_MIN_BYTE_COUNT 72
  64922. +
  64923. +/* Tailgate and Kirwood have only 2K TX FIFO */
  64924. +#if (MV_ETH_VERSION == 2) || (MV_ETH_VERSION == 4)
  64925. +#define ETH_CSUM_MAX_BYTE_COUNT 1600
  64926. +#else
  64927. +#define ETH_CSUM_MAX_BYTE_COUNT 9*1024
  64928. +#endif /* MV_ETH_VERSION */
  64929. +
  64930. +#define ETH_MV_HEADER_SIZE 2
  64931. +#define ETH_MV_TX_EN
  64932. +
  64933. +/* An offest in Tx descriptors to store data for buffers less than 8 Bytes */
  64934. +#define MIN_TX_BUFF_LOAD 8
  64935. +#define TX_BUF_OFFSET_IN_DESC (ETH_TX_DESC_ALIGNED_SIZE - MIN_TX_BUFF_LOAD)
  64936. +
  64937. +/* Default port configuration value */
  64938. +#define PORT_CONFIG_VALUE \
  64939. + ETH_DEF_RX_QUEUE_MASK(0) | \
  64940. + ETH_DEF_RX_ARP_QUEUE_MASK(0) | \
  64941. + ETH_DEF_RX_TCP_QUEUE_MASK(0) | \
  64942. + ETH_DEF_RX_UDP_QUEUE_MASK(0) | \
  64943. + ETH_DEF_RX_BPDU_QUEUE_MASK(0) | \
  64944. + ETH_RX_CHECKSUM_WITH_PSEUDO_HDR
  64945. +
  64946. +/* Default port extend configuration value */
  64947. +#define PORT_CONFIG_EXTEND_VALUE 0
  64948. +
  64949. +#define PORT_SERIAL_CONTROL_VALUE \
  64950. + ETH_DISABLE_FC_AUTO_NEG_MASK | \
  64951. + BIT9 | \
  64952. + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
  64953. + ETH_MAX_RX_PACKET_1552BYTE | \
  64954. + ETH_SET_FULL_DUPLEX_MASK
  64955. +
  64956. +#define PORT_SERIAL_CONTROL_100MB_FORCE_VALUE \
  64957. + ETH_FORCE_LINK_PASS_MASK | \
  64958. + ETH_DISABLE_DUPLEX_AUTO_NEG_MASK | \
  64959. + ETH_DISABLE_FC_AUTO_NEG_MASK | \
  64960. + BIT9 | \
  64961. + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
  64962. + ETH_DISABLE_SPEED_AUTO_NEG_MASK | \
  64963. + ETH_SET_FULL_DUPLEX_MASK | \
  64964. + ETH_SET_MII_SPEED_100_MASK | \
  64965. + ETH_MAX_RX_PACKET_1552BYTE
  64966. +
  64967. +
  64968. +#define PORT_SERIAL_CONTROL_1000MB_FORCE_VALUE \
  64969. + ETH_FORCE_LINK_PASS_MASK | \
  64970. + ETH_DISABLE_DUPLEX_AUTO_NEG_MASK | \
  64971. + ETH_DISABLE_FC_AUTO_NEG_MASK | \
  64972. + BIT9 | \
  64973. + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
  64974. + ETH_DISABLE_SPEED_AUTO_NEG_MASK | \
  64975. + ETH_SET_FULL_DUPLEX_MASK | \
  64976. + ETH_SET_GMII_SPEED_1000_MASK | \
  64977. + ETH_MAX_RX_PACKET_1552BYTE
  64978. +
  64979. +#define PORT_SERIAL_CONTROL_SGMII_IBAN_VALUE \
  64980. + ETH_DISABLE_FC_AUTO_NEG_MASK | \
  64981. + BIT9 | \
  64982. + ETH_IN_BAND_AN_EN_MASK | \
  64983. + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
  64984. + ETH_MAX_RX_PACKET_1552BYTE
  64985. +
  64986. +/* Function headers: */
  64987. +MV_VOID mvEthSetSpecialMcastTable(int portNo, int queue);
  64988. +MV_STATUS mvEthArpRxQueue(void* pPortHandle, int arpQueue);
  64989. +MV_STATUS mvEthUdpRxQueue(void* pPortHandle, int udpQueue);
  64990. +MV_STATUS mvEthTcpRxQueue(void* pPortHandle, int tcpQueue);
  64991. +MV_STATUS mvEthMacAddrGet(int portNo, unsigned char *pAddr);
  64992. +MV_VOID mvEthSetOtherMcastTable(int portNo, int queue);
  64993. +MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode);
  64994. +/* Interrupt Coalesting functions */
  64995. +MV_U32 mvEthRxCoalSet(void* pPortHndl, MV_U32 uSec);
  64996. +MV_U32 mvEthTxCoalSet(void* pPortHndl, MV_U32 uSec);
  64997. +MV_STATUS mvEthCoalGet(void* pPortHndl, MV_U32* pRxCoal, MV_U32* pTxCoal);
  64998. +
  64999. +/******************************************************************************/
  65000. +/* Data Flow functions */
  65001. +/******************************************************************************/
  65002. +static INLINE void mvEthPortTxRestart(void* pPortHndl)
  65003. +{
  65004. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65005. +
  65006. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;
  65007. +}
  65008. +
  65009. +/* Get number of Free resources in specific TX queue */
  65010. +static INLINE int mvEthTxResourceGet(void* pPortHndl, int txQueue)
  65011. +{
  65012. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65013. +
  65014. + return (pPortCtrl->txQueue[txQueue].resource);
  65015. +}
  65016. +
  65017. +/* Get number of Free resources in specific RX queue */
  65018. +static INLINE int mvEthRxResourceGet(void* pPortHndl, int rxQueue)
  65019. +{
  65020. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65021. +
  65022. + return (pPortCtrl->rxQueue[rxQueue].resource);
  65023. +}
  65024. +
  65025. +static INLINE int mvEthTxQueueIsFull(void* pPortHndl, int txQueue)
  65026. +{
  65027. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65028. +
  65029. + if(pPortCtrl->txQueue[txQueue].resource == 0)
  65030. + return MV_TRUE;
  65031. +
  65032. + return MV_FALSE;
  65033. +}
  65034. +
  65035. +/* Get number of Free resources in specific RX queue */
  65036. +static INLINE int mvEthRxQueueIsFull(void* pPortHndl, int rxQueue)
  65037. +{
  65038. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65039. + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];
  65040. +
  65041. + if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&
  65042. + (pQueueCtrl->resource != 0) )
  65043. + return MV_TRUE;
  65044. +
  65045. + return MV_FALSE;
  65046. +}
  65047. +
  65048. +static INLINE int mvEthTxQueueIsEmpty(void* pPortHndl, int txQueue)
  65049. +{
  65050. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65051. + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  65052. +
  65053. + if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&
  65054. + (pQueueCtrl->resource != 0) )
  65055. + {
  65056. + return MV_TRUE;
  65057. + }
  65058. + return MV_FALSE;
  65059. +}
  65060. +
  65061. +/* Get number of Free resources in specific RX queue */
  65062. +static INLINE int mvEthRxQueueIsEmpty(void* pPortHndl, int rxQueue)
  65063. +{
  65064. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65065. +
  65066. + if(pPortCtrl->rxQueue[rxQueue].resource == 0)
  65067. + return MV_TRUE;
  65068. +
  65069. + return MV_FALSE;
  65070. +}
  65071. +
  65072. +/*******************************************************************************
  65073. +* mvEthPortTx - Send an Ethernet packet
  65074. +*
  65075. +* DESCRIPTION:
  65076. +* This routine send a given packet described by pPktInfo parameter.
  65077. +* Single buffer only.
  65078. +*
  65079. +* INPUT:
  65080. +* void* pEthPortHndl - Ethernet Port handler.
  65081. +* int txQueue - Number of Tx queue.
  65082. +* MV_PKT_INFO *pPktInfo - User packet to send.
  65083. +*
  65084. +* RETURN:
  65085. +* MV_NO_RESOURCE - No enough resources to send this packet.
  65086. +* MV_ERROR - Unexpected Fatal error.
  65087. +* MV_OK - Packet send successfully.
  65088. +*
  65089. +*******************************************************************************/
  65090. +static INLINE MV_STATUS mvEthPortTx(void* pEthPortHndl, int txQueue, MV_PKT_INFO* pPktInfo)
  65091. +{
  65092. + ETH_TX_DESC* pTxCurrDesc;
  65093. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  65094. + ETH_QUEUE_CTRL* pQueueCtrl;
  65095. + int portNo;
  65096. + MV_BUF_INFO* pBufInfo = pPktInfo->pFrags;
  65097. +
  65098. +#ifdef ETH_DEBUG
  65099. + if(pPortCtrl->portState != MV_ACTIVE)
  65100. + return MV_BAD_STATE;
  65101. +#endif /* ETH_DEBUG */
  65102. +
  65103. + portNo = pPortCtrl->portNo;
  65104. + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  65105. +
  65106. + /* Get the Tx Desc ring indexes */
  65107. + pTxCurrDesc = pQueueCtrl->pCurrentDescr;
  65108. +
  65109. + /* Check if there is enough resources to send the packet */
  65110. + if(pQueueCtrl->resource == 0)
  65111. + return MV_NO_RESOURCE;
  65112. +
  65113. + pTxCurrDesc->byteCnt = pBufInfo->dataSize;
  65114. +
  65115. + /* Flash Buffer */
  65116. + if(pPktInfo->pktSize != 0)
  65117. + {
  65118. +#ifdef MV_NETBSD
  65119. + pTxCurrDesc->bufPtr = pBufInfo->bufPhysAddr;
  65120. + ETH_PACKET_CACHE_FLUSH(pBufInfo->bufVirtPtr, pPktInfo->pktSize);
  65121. +#else
  65122. + pTxCurrDesc->bufPtr = ETH_PACKET_CACHE_FLUSH(pBufInfo->bufVirtPtr, pPktInfo->pktSize);
  65123. +#endif
  65124. + pPktInfo->pktSize = 0;
  65125. + }
  65126. + else
  65127. + pTxCurrDesc->bufPtr = pBufInfo->bufPhysAddr;
  65128. +
  65129. + pTxCurrDesc->returnInfo = (MV_ULONG)pPktInfo;
  65130. +
  65131. + /* There is only one buffer in the packet */
  65132. + /* The OSG might set some bits for checksum offload, so add them to first descriptor */
  65133. + pTxCurrDesc->cmdSts = pPktInfo->status |
  65134. + ETH_BUFFER_OWNED_BY_DMA |
  65135. + ETH_TX_GENERATE_CRC_MASK |
  65136. + ETH_TX_ENABLE_INTERRUPT_MASK |
  65137. + ETH_TX_ZERO_PADDING_MASK |
  65138. + ETH_TX_FIRST_DESC_MASK |
  65139. + ETH_TX_LAST_DESC_MASK;
  65140. +
  65141. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
  65142. +
  65143. + pQueueCtrl->resource--;
  65144. + pQueueCtrl->pCurrentDescr = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);
  65145. +
  65146. + /* Apply send command */
  65147. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(portNo)) = pPortCtrl->portTxQueueCmdReg;
  65148. +
  65149. + return MV_OK;
  65150. +}
  65151. +
  65152. +
  65153. +/*******************************************************************************
  65154. +* mvEthPortSgTx - Send an Ethernet packet
  65155. +*
  65156. +* DESCRIPTION:
  65157. +* This routine send a given packet described by pBufInfo parameter. It
  65158. +* supports transmitting of a packet spaned over multiple buffers.
  65159. +*
  65160. +* INPUT:
  65161. +* void* pEthPortHndl - Ethernet Port handler.
  65162. +* int txQueue - Number of Tx queue.
  65163. +* MV_PKT_INFO *pPktInfo - User packet to send.
  65164. +*
  65165. +* RETURN:
  65166. +* MV_NO_RESOURCE - No enough resources to send this packet.
  65167. +* MV_ERROR - Unexpected Fatal error.
  65168. +* MV_OK - Packet send successfully.
  65169. +*
  65170. +*******************************************************************************/
  65171. +static INLINE MV_STATUS mvEthPortSgTx(void* pEthPortHndl, int txQueue, MV_PKT_INFO* pPktInfo)
  65172. +{
  65173. + ETH_TX_DESC* pTxFirstDesc;
  65174. + ETH_TX_DESC* pTxCurrDesc;
  65175. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  65176. + ETH_QUEUE_CTRL* pQueueCtrl;
  65177. + int portNo, bufCount;
  65178. + MV_BUF_INFO* pBufInfo = pPktInfo->pFrags;
  65179. + MV_U8* pTxBuf;
  65180. +
  65181. +#ifdef ETH_DEBUG
  65182. + if(pPortCtrl->portState != MV_ACTIVE)
  65183. + return MV_BAD_STATE;
  65184. +#endif /* ETH_DEBUG */
  65185. +
  65186. + portNo = pPortCtrl->portNo;
  65187. + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  65188. +
  65189. + /* Get the Tx Desc ring indexes */
  65190. + pTxCurrDesc = pQueueCtrl->pCurrentDescr;
  65191. +
  65192. + /* Check if there is enough resources to send the packet */
  65193. + if(pQueueCtrl->resource < pPktInfo->numFrags)
  65194. + return MV_NO_RESOURCE;
  65195. +
  65196. + /* Remember first desc */
  65197. + pTxFirstDesc = pTxCurrDesc;
  65198. +
  65199. + bufCount = 0;
  65200. + while(MV_TRUE)
  65201. + {
  65202. + if(pBufInfo[bufCount].dataSize <= MIN_TX_BUFF_LOAD)
  65203. + {
  65204. + /* Buffers with a payload smaller than MIN_TX_BUFF_LOAD (8 bytes) must be aligned */
  65205. + /* to 64-bit boundary. Two options here: */
  65206. + /* 1) Usually, copy the payload to the reserved 8 bytes inside descriptor. */
  65207. + /* 2) In the Half duplex workaround, the reserved 8 bytes inside descriptor are used */
  65208. + /* as a pointer to the aligned buffer, copy the small payload to this buffer. */
  65209. + pTxBuf = ((MV_U8*)pTxCurrDesc)+TX_BUF_OFFSET_IN_DESC;
  65210. + mvOsBCopy(pBufInfo[bufCount].bufVirtPtr, pTxBuf, pBufInfo[bufCount].dataSize);
  65211. + pTxCurrDesc->bufPtr = ethDescVirtToPhy(pQueueCtrl, pTxBuf);
  65212. + }
  65213. + else
  65214. + {
  65215. + /* Flash Buffer */
  65216. +#ifdef MV_NETBSD
  65217. + pTxCurrDesc->bufPtr = pBufInfo[bufCount].bufPhysAddr;
  65218. + ETH_PACKET_CACHE_FLUSH(pBufInfo[bufCount].bufVirtPtr, pBufInfo[bufCount].dataSize);
  65219. +#else
  65220. + pTxCurrDesc->bufPtr = ETH_PACKET_CACHE_FLUSH(pBufInfo[bufCount].bufVirtPtr, pBufInfo[bufCount].dataSize);
  65221. +#endif
  65222. + }
  65223. +
  65224. + pTxCurrDesc->byteCnt = pBufInfo[bufCount].dataSize;
  65225. + bufCount++;
  65226. +
  65227. + if(bufCount >= pPktInfo->numFrags)
  65228. + break;
  65229. +
  65230. + if(bufCount > 1)
  65231. + {
  65232. + /* There is middle buffer of the packet Not First and Not Last */
  65233. + pTxCurrDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA;
  65234. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
  65235. + }
  65236. + /* Go to next descriptor and next buffer */
  65237. + pTxCurrDesc = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);
  65238. + }
  65239. + /* Set last desc with DMA ownership and interrupt enable. */
  65240. + pTxCurrDesc->returnInfo = (MV_ULONG)pPktInfo;
  65241. + if(bufCount == 1)
  65242. + {
  65243. + /* There is only one buffer in the packet */
  65244. + /* The OSG might set some bits for checksum offload, so add them to first descriptor */
  65245. + pTxCurrDesc->cmdSts = pPktInfo->status |
  65246. + ETH_BUFFER_OWNED_BY_DMA |
  65247. + ETH_TX_GENERATE_CRC_MASK |
  65248. + ETH_TX_ENABLE_INTERRUPT_MASK |
  65249. + ETH_TX_ZERO_PADDING_MASK |
  65250. + ETH_TX_FIRST_DESC_MASK |
  65251. + ETH_TX_LAST_DESC_MASK;
  65252. +
  65253. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
  65254. + }
  65255. + else
  65256. + {
  65257. + /* Last but not First */
  65258. + pTxCurrDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA |
  65259. + ETH_TX_ENABLE_INTERRUPT_MASK |
  65260. + ETH_TX_ZERO_PADDING_MASK |
  65261. + ETH_TX_LAST_DESC_MASK;
  65262. +
  65263. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
  65264. +
  65265. + /* Update First when more than one buffer in the packet */
  65266. + /* The OSG might set some bits for checksum offload, so add them to first descriptor */
  65267. + pTxFirstDesc->cmdSts = pPktInfo->status |
  65268. + ETH_BUFFER_OWNED_BY_DMA |
  65269. + ETH_TX_GENERATE_CRC_MASK |
  65270. + ETH_TX_FIRST_DESC_MASK;
  65271. +
  65272. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxFirstDesc);
  65273. + }
  65274. + /* Update txQueue state */
  65275. + pQueueCtrl->resource -= bufCount;
  65276. + pQueueCtrl->pCurrentDescr = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);
  65277. +
  65278. + /* Apply send command */
  65279. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(portNo)) = pPortCtrl->portTxQueueCmdReg;
  65280. +
  65281. + return MV_OK;
  65282. +}
  65283. +
  65284. +/*******************************************************************************
  65285. +* mvEthPortTxDone - Free all used Tx descriptors and mBlks.
  65286. +*
  65287. +* DESCRIPTION:
  65288. +* This routine returns the transmitted packet information to the caller.
  65289. +*
  65290. +* INPUT:
  65291. +* void* pEthPortHndl - Ethernet Port handler.
  65292. +* int txQueue - Number of Tx queue.
  65293. +*
  65294. +* OUTPUT:
  65295. +* MV_PKT_INFO *pPktInfo - Pointer to packet was sent.
  65296. +*
  65297. +* RETURN:
  65298. +* MV_NOT_FOUND - No transmitted packets to return. Transmit in progress.
  65299. +* MV_EMPTY - No transmitted packets to return. TX Queue is empty.
  65300. +* MV_ERROR - Unexpected Fatal error.
  65301. +* MV_OK - There is transmitted packet in the queue,
  65302. +* 'pPktInfo' filled with relevant information.
  65303. +*
  65304. +*******************************************************************************/
  65305. +static INLINE MV_PKT_INFO* mvEthPortTxDone(void* pEthPortHndl, int txQueue)
  65306. +{
  65307. + ETH_TX_DESC* pTxCurrDesc;
  65308. + ETH_TX_DESC* pTxUsedDesc;
  65309. + ETH_QUEUE_CTRL* pQueueCtrl;
  65310. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  65311. + MV_PKT_INFO* pPktInfo;
  65312. + MV_U32 commandStatus;
  65313. +
  65314. + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  65315. +
  65316. + pTxUsedDesc = pQueueCtrl->pUsedDescr;
  65317. + pTxCurrDesc = pQueueCtrl->pCurrentDescr;
  65318. +
  65319. + while(MV_TRUE)
  65320. + {
  65321. + /* No more used descriptors */
  65322. + commandStatus = pTxUsedDesc->cmdSts;
  65323. + if (commandStatus & (ETH_BUFFER_OWNED_BY_DMA))
  65324. + {
  65325. + ETH_DESCR_INV(pPortCtrl, pTxUsedDesc);
  65326. + return NULL;
  65327. + }
  65328. + if( (pTxUsedDesc == pTxCurrDesc) &&
  65329. + (pQueueCtrl->resource != 0) )
  65330. + {
  65331. + return NULL;
  65332. + }
  65333. + pQueueCtrl->resource++;
  65334. + pQueueCtrl->pUsedDescr = TX_NEXT_DESC_PTR(pTxUsedDesc, pQueueCtrl);
  65335. + if(commandStatus & (ETH_TX_LAST_DESC_MASK))
  65336. + {
  65337. + pPktInfo = (MV_PKT_INFO*)pTxUsedDesc->returnInfo;
  65338. + pPktInfo->status = commandStatus;
  65339. + return pPktInfo;
  65340. + }
  65341. + pTxUsedDesc = pQueueCtrl->pUsedDescr;
  65342. + }
  65343. +}
  65344. +
  65345. +/*******************************************************************************
  65346. +* mvEthPortRx - Get new received packets from Rx queue.
  65347. +*
  65348. +* DESCRIPTION:
  65349. +* This routine returns the received data to the caller. There is no
  65350. +* data copying during routine operation. All information is returned
  65351. +* using pointer to packet information struct passed from the caller.
  65352. +*
  65353. +* INPUT:
  65354. +* void* pEthPortHndl - Ethernet Port handler.
  65355. +* int rxQueue - Number of Rx queue.
  65356. +*
  65357. +* OUTPUT:
  65358. +* MV_PKT_INFO *pPktInfo - Pointer to received packet.
  65359. +*
  65360. +* RETURN:
  65361. +* MV_NO_RESOURCE - No free resources in RX queue.
  65362. +* MV_ERROR - Unexpected Fatal error.
  65363. +* MV_OK - New packet received and 'pBufInfo' structure filled
  65364. +* with relevant information.
  65365. +*
  65366. +*******************************************************************************/
  65367. +static INLINE MV_PKT_INFO* mvEthPortRx(void* pEthPortHndl, int rxQueue)
  65368. +{
  65369. + ETH_RX_DESC *pRxCurrDesc;
  65370. + MV_U32 commandStatus;
  65371. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  65372. + ETH_QUEUE_CTRL* pQueueCtrl;
  65373. + MV_PKT_INFO* pPktInfo;
  65374. +
  65375. + pQueueCtrl = &(pPortCtrl->rxQueue[rxQueue]);
  65376. +
  65377. + /* Check resources */
  65378. + if(pQueueCtrl->resource == 0)
  65379. + {
  65380. + mvOsPrintf("ethPortRx: no more resources\n");
  65381. + return NULL;
  65382. + }
  65383. + while(MV_TRUE)
  65384. + {
  65385. + /* Get the Rx Desc ring 'curr and 'used' indexes */
  65386. + pRxCurrDesc = pQueueCtrl->pCurrentDescr;
  65387. +
  65388. + commandStatus = pRxCurrDesc->cmdSts;
  65389. + if (commandStatus & (ETH_BUFFER_OWNED_BY_DMA))
  65390. + {
  65391. + /* Nothing to receive... */
  65392. + ETH_DESCR_INV(pPortCtrl, pRxCurrDesc);
  65393. + return NULL;
  65394. + }
  65395. +
  65396. + /* Valid RX only if FIRST and LAST bits are set */
  65397. + if( (commandStatus & (ETH_RX_LAST_DESC_MASK | ETH_RX_FIRST_DESC_MASK)) ==
  65398. + (ETH_RX_LAST_DESC_MASK | ETH_RX_FIRST_DESC_MASK) )
  65399. + {
  65400. + pPktInfo = (MV_PKT_INFO*)pRxCurrDesc->returnInfo;
  65401. + pPktInfo->pFrags->dataSize = pRxCurrDesc->byteCnt - 4;
  65402. + pPktInfo->status = commandStatus;
  65403. + pPktInfo->fragIP = pRxCurrDesc->bufSize & ETH_RX_IP_FRAGMENTED_FRAME_MASK;
  65404. +
  65405. + pQueueCtrl->resource--;
  65406. + /* Update 'curr' in data structure */
  65407. + pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxCurrDesc, pQueueCtrl);
  65408. +
  65409. +#ifdef INCLUDE_SYNC_BARR
  65410. + mvCpuIfSyncBarr(DRAM_TARGET);
  65411. +#endif
  65412. + return pPktInfo;
  65413. + }
  65414. + else
  65415. + {
  65416. + ETH_RX_DESC* pRxUsedDesc = pQueueCtrl->pUsedDescr;
  65417. +
  65418. +#ifdef ETH_DEBUG
  65419. + mvOsPrintf("ethDrv: Unexpected Jumbo frame: "
  65420. + "status=0x%08x, byteCnt=%d, pData=0x%x\n",
  65421. + commandStatus, pRxCurrDesc->byteCnt, pRxCurrDesc->bufPtr);
  65422. +#endif /* ETH_DEBUG */
  65423. +
  65424. + /* move buffer from pCurrentDescr position to pUsedDescr position */
  65425. + pRxUsedDesc->bufPtr = pRxCurrDesc->bufPtr;
  65426. + pRxUsedDesc->returnInfo = pRxCurrDesc->returnInfo;
  65427. + pRxUsedDesc->bufSize = pRxCurrDesc->bufSize & ETH_RX_BUFFER_MASK;
  65428. +
  65429. + /* Return the descriptor to DMA ownership */
  65430. + pRxUsedDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA |
  65431. + ETH_RX_ENABLE_INTERRUPT_MASK;
  65432. +
  65433. + /* Flush descriptor and CPU pipe */
  65434. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxUsedDesc);
  65435. +
  65436. + /* Move the used descriptor pointer to the next descriptor */
  65437. + pQueueCtrl->pUsedDescr = RX_NEXT_DESC_PTR(pRxUsedDesc, pQueueCtrl);
  65438. + pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxCurrDesc, pQueueCtrl);
  65439. + }
  65440. + }
  65441. +}
  65442. +
  65443. +/*******************************************************************************
  65444. +* mvEthPortRxDone - Returns a Rx buffer back to the Rx ring.
  65445. +*
  65446. +* DESCRIPTION:
  65447. +* This routine returns a Rx buffer back to the Rx ring.
  65448. +*
  65449. +* INPUT:
  65450. +* void* pEthPortHndl - Ethernet Port handler.
  65451. +* int rxQueue - Number of Rx queue.
  65452. +* MV_PKT_INFO *pPktInfo - Pointer to received packet.
  65453. +*
  65454. +* RETURN:
  65455. +* MV_ERROR - Unexpected Fatal error.
  65456. +* MV_OUT_OF_RANGE - RX queue is already FULL, so this buffer can't be
  65457. +* returned to this queue.
  65458. +* MV_FULL - Buffer returned successfully and RX queue became full.
  65459. +* More buffers should not be returned at the time.
  65460. +* MV_OK - Buffer returned successfully and there are more free
  65461. +* places in the queue.
  65462. +*
  65463. +*******************************************************************************/
  65464. +static INLINE MV_STATUS mvEthPortRxDone(void* pEthPortHndl, int rxQueue, MV_PKT_INFO *pPktInfo)
  65465. +{
  65466. + ETH_RX_DESC* pRxUsedDesc;
  65467. + ETH_QUEUE_CTRL* pQueueCtrl;
  65468. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  65469. +
  65470. + pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];
  65471. +
  65472. + /* Get 'used' Rx descriptor */
  65473. + pRxUsedDesc = pQueueCtrl->pUsedDescr;
  65474. +
  65475. + /* Check that ring is not FULL */
  65476. + if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&
  65477. + (pQueueCtrl->resource != 0) )
  65478. + {
  65479. + mvOsPrintf("%s %d: out of range Error resource=%d, curr=%p, used=%p\n",
  65480. + __FUNCTION__, pPortCtrl->portNo, pQueueCtrl->resource,
  65481. + pQueueCtrl->pCurrentDescr, pQueueCtrl->pUsedDescr);
  65482. + return MV_OUT_OF_RANGE;
  65483. + }
  65484. +
  65485. + pRxUsedDesc->bufPtr = pPktInfo->pFrags->bufPhysAddr;
  65486. + pRxUsedDesc->returnInfo = (MV_ULONG)pPktInfo;
  65487. + pRxUsedDesc->bufSize = pPktInfo->pFrags->bufSize & ETH_RX_BUFFER_MASK;
  65488. +
  65489. + /* Invalidate data buffer accordingly with pktSize */
  65490. + if(pPktInfo->pktSize != 0)
  65491. + {
  65492. + ETH_PACKET_CACHE_INVALIDATE(pPktInfo->pFrags->bufVirtPtr, pPktInfo->pktSize);
  65493. + pPktInfo->pktSize = 0;
  65494. + }
  65495. +
  65496. + /* Return the descriptor to DMA ownership */
  65497. + pRxUsedDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT_MASK;
  65498. +
  65499. + /* Flush descriptor and CPU pipe */
  65500. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxUsedDesc);
  65501. +
  65502. + pQueueCtrl->resource++;
  65503. +
  65504. + /* Move the used descriptor pointer to the next descriptor */
  65505. + pQueueCtrl->pUsedDescr = RX_NEXT_DESC_PTR(pRxUsedDesc, pQueueCtrl);
  65506. +
  65507. + /* If ring became Full return MV_FULL */
  65508. + if(pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr)
  65509. + return MV_FULL;
  65510. +
  65511. + return MV_OK;
  65512. +}
  65513. +
  65514. +
  65515. +#endif /* __mvEthGbe_h__ */
  65516. +
  65517. +
  65518. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h
  65519. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h 1970-01-01 01:00:00.000000000 +0100
  65520. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h 2010-08-05 22:02:24.704867864 +0200
  65521. @@ -0,0 +1,700 @@
  65522. +/*******************************************************************************
  65523. +Copyright (C) Marvell International Ltd. and its affiliates
  65524. +
  65525. +This software file (the "File") is owned and distributed by Marvell
  65526. +International Ltd. and/or its affiliates ("Marvell") under the following
  65527. +alternative licensing terms. Once you have made an election to distribute the
  65528. +File under one of the following license alternatives, please (i) delete this
  65529. +introductory statement regarding license alternatives, (ii) delete the two
  65530. +license alternatives that you have not elected to use and (iii) preserve the
  65531. +Marvell copyright notice above.
  65532. +
  65533. +********************************************************************************
  65534. +Marvell Commercial License Option
  65535. +
  65536. +If you received this File from Marvell and you have entered into a commercial
  65537. +license agreement (a "Commercial License") with Marvell, the File is licensed
  65538. +to you under the terms of the applicable Commercial License.
  65539. +
  65540. +********************************************************************************
  65541. +Marvell GPL License Option
  65542. +
  65543. +If you received this File from Marvell, you may opt to use, redistribute and/or
  65544. +modify this File in accordance with the terms and conditions of the General
  65545. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  65546. +available along with the File in the license.txt file or by writing to the Free
  65547. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  65548. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  65549. +
  65550. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  65551. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  65552. +DISCLAIMED. The GPL License provides additional details about this warranty
  65553. +disclaimer.
  65554. +********************************************************************************
  65555. +Marvell BSD License Option
  65556. +
  65557. +If you received this File from Marvell, you may opt to use, redistribute and/or
  65558. +modify this File under the following licensing terms.
  65559. +Redistribution and use in source and binary forms, with or without modification,
  65560. +are permitted provided that the following conditions are met:
  65561. +
  65562. + * Redistributions of source code must retain the above copyright notice,
  65563. + this list of conditions and the following disclaimer.
  65564. +
  65565. + * Redistributions in binary form must reproduce the above copyright
  65566. + notice, this list of conditions and the following disclaimer in the
  65567. + documentation and/or other materials provided with the distribution.
  65568. +
  65569. + * Neither the name of Marvell nor the names of its contributors may be
  65570. + used to endorse or promote products derived from this software without
  65571. + specific prior written permission.
  65572. +
  65573. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  65574. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  65575. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  65576. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  65577. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  65578. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  65579. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  65580. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  65581. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  65582. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  65583. +
  65584. +*******************************************************************************/
  65585. +
  65586. +
  65587. +#ifndef __INCmvEthRegsh
  65588. +#define __INCmvEthRegsh
  65589. +
  65590. +#ifdef __cplusplus
  65591. +extern "C" {
  65592. +#endif /* __cplusplus */
  65593. +
  65594. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  65595. +
  65596. +/****************************************/
  65597. +/* Ethernet Unit Registers */
  65598. +/****************************************/
  65599. +#define ETH_REG_BASE MV_ETH_REG_BASE
  65600. +
  65601. +#define ETH_PHY_ADDR_REG(port) (ETH_REG_BASE(port) + 0x000)
  65602. +#define ETH_SMI_REG(port) (ETH_REG_BASE(port) + 0x004)
  65603. +#define ETH_UNIT_DEF_ADDR_REG(port) (ETH_REG_BASE(port) + 0x008)
  65604. +#define ETH_UNIT_DEF_ID_REG(port) (ETH_REG_BASE(port) + 0x00c)
  65605. +#define ETH_UNIT_RESERVED(port) (ETH_REG_BASE(port) + 0x014)
  65606. +#define ETH_UNIT_INTR_CAUSE_REG(port) (ETH_REG_BASE(port) + 0x080)
  65607. +#define ETH_UNIT_INTR_MASK_REG(port) (ETH_REG_BASE(port) + 0x084)
  65608. +
  65609. +
  65610. +#define ETH_UNIT_ERROR_ADDR_REG(port) (ETH_REG_BASE(port) + 0x094)
  65611. +#define ETH_UNIT_INT_ADDR_ERROR_REG(port) (ETH_REG_BASE(port) + 0x098)
  65612. +#define ETH_UNIT_CONTROL_REG(port) (ETH_REG_BASE(port) + 0x0B0)
  65613. +
  65614. +#define ETH_PORT_CONFIG_REG(port) (ETH_REG_BASE(port) + 0x400)
  65615. +#define ETH_PORT_CONFIG_EXTEND_REG(port) (ETH_REG_BASE(port) + 0x404)
  65616. +#define ETH_MII_SERIAL_PARAM_REG(port) (ETH_REG_BASE(port) + 0x408)
  65617. +#define ETH_GMII_SERIAL_PARAM_REG(port) (ETH_REG_BASE(port) + 0x40c)
  65618. +#define ETH_VLAN_ETHER_TYPE_REG(port) (ETH_REG_BASE(port) + 0x410)
  65619. +#define ETH_MAC_ADDR_LOW_REG(port) (ETH_REG_BASE(port) + 0x414)
  65620. +#define ETH_MAC_ADDR_HIGH_REG(port) (ETH_REG_BASE(port) + 0x418)
  65621. +#define ETH_SDMA_CONFIG_REG(port) (ETH_REG_BASE(port) + 0x41c)
  65622. +#define ETH_DIFF_SERV_PRIO_REG(port, code) (ETH_REG_BASE(port) + 0x420 + ((code)<<2))
  65623. +#define ETH_PORT_SERIAL_CTRL_REG(port) (ETH_REG_BASE(port) + 0x43c)
  65624. +#define ETH_VLAN_TAG_TO_PRIO_REG(port) (ETH_REG_BASE(port) + 0x440)
  65625. +#define ETH_PORT_STATUS_REG(port) (ETH_REG_BASE(port) + 0x444)
  65626. +
  65627. +#define ETH_RX_QUEUE_COMMAND_REG(port) (ETH_REG_BASE(port) + 0x680)
  65628. +#define ETH_TX_QUEUE_COMMAND_REG(port) (ETH_REG_BASE(port) + 0x448)
  65629. +
  65630. +#define ETH_PORT_SERIAL_CTRL_1_REG(port) (ETH_REG_BASE(port) + 0x44c)
  65631. +#define ETH_PORT_STATUS_1_REG(port) (ETH_REG_BASE(port) + 0x450)
  65632. +#define ETH_PORT_MARVELL_HEADER_REG(port) (ETH_REG_BASE(port) + 0x454)
  65633. +#define ETH_PORT_FIFO_PARAMS_REG(port) (ETH_REG_BASE(port) + 0x458)
  65634. +#define ETH_MAX_TOKEN_BUCKET_SIZE_REG(port) (ETH_REG_BASE(port) + 0x45c)
  65635. +#define ETH_INTR_CAUSE_REG(port) (ETH_REG_BASE(port) + 0x460)
  65636. +#define ETH_INTR_CAUSE_EXT_REG(port) (ETH_REG_BASE(port) + 0x464)
  65637. +#define ETH_INTR_MASK_REG(port) (ETH_REG_BASE(port) + 0x468)
  65638. +#define ETH_INTR_MASK_EXT_REG(port) (ETH_REG_BASE(port) + 0x46c)
  65639. +#define ETH_TX_FIFO_URGENT_THRESH_REG(port) (ETH_REG_BASE(port) + 0x474)
  65640. +#define ETH_RX_MINIMAL_FRAME_SIZE_REG(port) (ETH_REG_BASE(port) + 0x47c)
  65641. +#define ETH_RX_DISCARD_PKTS_CNTR_REG(port) (ETH_REG_BASE(port) + 0x484)
  65642. +#define ETH_RX_OVERRUN_PKTS_CNTR_REG(port) (ETH_REG_BASE(port) + 0x488)
  65643. +#define ETH_INTERNAL_ADDR_ERROR_REG(port) (ETH_REG_BASE(port) + 0x494)
  65644. +#define ETH_TX_FIXED_PRIO_CFG_REG(port) (ETH_REG_BASE(port) + 0x4dc)
  65645. +#define ETH_TX_TOKEN_RATE_CFG_REG(port) (ETH_REG_BASE(port) + 0x4e0)
  65646. +#define ETH_TX_QUEUE_COMMAND1_REG(port) (ETH_REG_BASE(port) + 0x4e4)
  65647. +#define ETH_MAX_TRANSMIT_UNIT_REG(port) (ETH_REG_BASE(port) + 0x4e8)
  65648. +#define ETH_TX_TOKEN_BUCKET_SIZE_REG(port) (ETH_REG_BASE(port) + 0x4ec)
  65649. +#define ETH_TX_TOKEN_BUCKET_COUNT_REG(port) (ETH_REG_BASE(port) + 0x780)
  65650. +#define ETH_RX_DESCR_STAT_CMD_REG(port, q) (ETH_REG_BASE(port) + 0x600 + ((q)<<4))
  65651. +#define ETH_RX_BYTE_COUNT_REG(port, q) (ETH_REG_BASE(port) + 0x604 + ((q)<<4))
  65652. +#define ETH_RX_BUF_PTR_REG(port, q) (ETH_REG_BASE(port) + 0x608 + ((q)<<4))
  65653. +#define ETH_RX_CUR_DESC_PTR_REG(port, q) (ETH_REG_BASE(port) + 0x60c + ((q)<<4))
  65654. +#define ETH_TX_CUR_DESC_PTR_REG(port, q) (ETH_REG_BASE(port) + 0x6c0 + ((q)<<2))
  65655. +
  65656. +#define ETH_TXQ_TOKEN_COUNT_REG(port, q) (ETH_REG_BASE(port) + 0x700 + ((q)<<4))
  65657. +#define ETH_TXQ_TOKEN_CFG_REG(port, q) (ETH_REG_BASE(port) + 0x704 + ((q)<<4))
  65658. +#define ETH_TXQ_ARBITER_CFG_REG(port, q) (ETH_REG_BASE(port) + 0x708 + ((q)<<4))
  65659. +
  65660. +#if (MV_ETH_VERSION >= 4)
  65661. +#define ETH_TXQ_CMD_1_REG(port) (ETH_REG_BASE(port) + 0x4E4)
  65662. +#define ETH_EJP_TX_HI_IPG_REG(port) (ETH_REG_BASE(port) + 0x7A8)
  65663. +#define ETH_EJP_TX_LO_IPG_REG(port) (ETH_REG_BASE(port) + 0x7B8)
  65664. +#define ETH_EJP_HI_TKN_LO_PKT_REG(port) (ETH_REG_BASE(port) + 0x7C0)
  65665. +#define ETH_EJP_HI_TKN_ASYNC_PKT_REG(port) (ETH_REG_BASE(port) + 0x7C4)
  65666. +#define ETH_EJP_LO_TKN_ASYNC_PKT_REG(port) (ETH_REG_BASE(port) + 0x7C8)
  65667. +#define ETH_EJP_TX_SPEED_REG(port) (ETH_REG_BASE(port) + 0x7D0)
  65668. +#endif /* MV_ETH_VERSION >= 4 */
  65669. +
  65670. +#define ETH_MIB_COUNTERS_BASE(port) (ETH_REG_BASE(port) + 0x1000)
  65671. +#define ETH_DA_FILTER_SPEC_MCAST_BASE(port) (ETH_REG_BASE(port) + 0x1400)
  65672. +#define ETH_DA_FILTER_OTH_MCAST_BASE(port) (ETH_REG_BASE(port) + 0x1500)
  65673. +#define ETH_DA_FILTER_UCAST_BASE(port) (ETH_REG_BASE(port) + 0x1600)
  65674. +
  65675. +/* Phy address register definitions */
  65676. +#define ETH_PHY_ADDR_OFFS 0
  65677. +#define ETH_PHY_ADDR_MASK (0x1f <<ETH_PHY_ADDR_OFFS)
  65678. +
  65679. +/* MIB Counters register definitions */
  65680. +#define ETH_MIB_GOOD_OCTETS_RECEIVED_LOW 0x0
  65681. +#define ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH 0x4
  65682. +#define ETH_MIB_BAD_OCTETS_RECEIVED 0x8
  65683. +#define ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR 0xc
  65684. +#define ETH_MIB_GOOD_FRAMES_RECEIVED 0x10
  65685. +#define ETH_MIB_BAD_FRAMES_RECEIVED 0x14
  65686. +#define ETH_MIB_BROADCAST_FRAMES_RECEIVED 0x18
  65687. +#define ETH_MIB_MULTICAST_FRAMES_RECEIVED 0x1c
  65688. +#define ETH_MIB_FRAMES_64_OCTETS 0x20
  65689. +#define ETH_MIB_FRAMES_65_TO_127_OCTETS 0x24
  65690. +#define ETH_MIB_FRAMES_128_TO_255_OCTETS 0x28
  65691. +#define ETH_MIB_FRAMES_256_TO_511_OCTETS 0x2c
  65692. +#define ETH_MIB_FRAMES_512_TO_1023_OCTETS 0x30
  65693. +#define ETH_MIB_FRAMES_1024_TO_MAX_OCTETS 0x34
  65694. +#define ETH_MIB_GOOD_OCTETS_SENT_LOW 0x38
  65695. +#define ETH_MIB_GOOD_OCTETS_SENT_HIGH 0x3c
  65696. +#define ETH_MIB_GOOD_FRAMES_SENT 0x40
  65697. +#define ETH_MIB_EXCESSIVE_COLLISION 0x44
  65698. +#define ETH_MIB_MULTICAST_FRAMES_SENT 0x48
  65699. +#define ETH_MIB_BROADCAST_FRAMES_SENT 0x4c
  65700. +#define ETH_MIB_UNREC_MAC_CONTROL_RECEIVED 0x50
  65701. +#define ETH_MIB_FC_SENT 0x54
  65702. +#define ETH_MIB_GOOD_FC_RECEIVED 0x58
  65703. +#define ETH_MIB_BAD_FC_RECEIVED 0x5c
  65704. +#define ETH_MIB_UNDERSIZE_RECEIVED 0x60
  65705. +#define ETH_MIB_FRAGMENTS_RECEIVED 0x64
  65706. +#define ETH_MIB_OVERSIZE_RECEIVED 0x68
  65707. +#define ETH_MIB_JABBER_RECEIVED 0x6c
  65708. +#define ETH_MIB_MAC_RECEIVE_ERROR 0x70
  65709. +#define ETH_MIB_BAD_CRC_EVENT 0x74
  65710. +#define ETH_MIB_COLLISION 0x78
  65711. +#define ETH_MIB_LATE_COLLISION 0x7c
  65712. +
  65713. +
  65714. +/****************************************/
  65715. +/* Ethernet Unit Register BITs */
  65716. +/****************************************/
  65717. +
  65718. +#define ETH_RXQ_ENABLE_OFFSET 0
  65719. +#define ETH_RXQ_ENABLE_MASK (0x000000FF << ETH_RXQ_ENABLE_OFFSET)
  65720. +
  65721. +#define ETH_RXQ_DISABLE_OFFSET 8
  65722. +#define ETH_RXQ_DISABLE_MASK (0x000000FF << ETH_RXQ_DISABLE_OFFSET)
  65723. +
  65724. +/***** BITs of Transmit Queue Command (TQC) register *****/
  65725. +#define ETH_TXQ_ENABLE_OFFSET 0
  65726. +#define ETH_TXQ_ENABLE_MASK (0x000000FF << ETH_TXQ_ENABLE_OFFSET)
  65727. +
  65728. +#define ETH_TXQ_DISABLE_OFFSET 8
  65729. +#define ETH_TXQ_DISABLE_MASK (0x000000FF << ETH_TXQ_DISABLE_OFFSET)
  65730. +
  65731. +#if (MV_ETH_VERSION >= 4)
  65732. +#define ETH_TX_EJP_RESET_BIT 0
  65733. +#define ETH_TX_EJP_RESET_MASK (1 << ETH_TX_EJP_RESET_BIT)
  65734. +
  65735. +#define ETH_TX_EJP_ENABLE_BIT 2
  65736. +#define ETH_TX_EJP_ENABLE_MASK (1 << ETH_TX_EJP_ENABLE_BIT)
  65737. +
  65738. +#define ETH_TX_LEGACY_WRR_BIT 3
  65739. +#define ETH_TX_LEGACY_WRR_MASK (1 << ETH_TX_LEGACY_WRR_BIT)
  65740. +#endif /* (MV_ETH_VERSION >= 4) */
  65741. +
  65742. +/***** BITs of Ethernet Port Status reg (PSR) *****/
  65743. +#define ETH_LINK_UP_BIT 1
  65744. +#define ETH_LINK_UP_MASK (1<<ETH_LINK_UP_BIT)
  65745. +
  65746. +#define ETH_FULL_DUPLEX_BIT 2
  65747. +#define ETH_FULL_DUPLEX_MASK (1<<ETH_FULL_DUPLEX_BIT)
  65748. +
  65749. +#define ETH_ENABLE_RCV_FLOW_CTRL_BIT 3
  65750. +#define ETH_ENABLE_RCV_FLOW_CTRL_MASK (1<<ETH_ENABLE_RCV_FLOW_CTRL_BIT)
  65751. +
  65752. +#define ETH_GMII_SPEED_1000_BIT 4
  65753. +#define ETH_GMII_SPEED_1000_MASK (1<<ETH_GMII_SPEED_1000_BIT)
  65754. +
  65755. +#define ETH_MII_SPEED_100_BIT 5
  65756. +#define ETH_MII_SPEED_100_MASK (1<<ETH_MII_SPEED_100_BIT)
  65757. +
  65758. +#define ETH_TX_IN_PROGRESS_BIT 7
  65759. +#define ETH_TX_IN_PROGRESS_MASK (1<<ETH_TX_IN_PROGRESS_BIT)
  65760. +
  65761. +#define ETH_TX_FIFO_EMPTY_BIT 10
  65762. +#define ETH_TX_FIFO_EMPTY_MASK (1<<ETH_TX_FIFO_EMPTY_BIT)
  65763. +
  65764. +/***** BITs of Ethernet Port Status 1 reg (PS1R) *****/
  65765. +#define ETH_AUTO_NEG_DONE_BIT 4
  65766. +#define ETH_AUTO_NEG_DONE_MASK (1<<ETH_AUTO_NEG_DONE_BIT)
  65767. +
  65768. +#define ETH_SERDES_PLL_LOCKED_BIT 6
  65769. +#define ETH_SERDES_PLL_LOCKED_MASK (1<<ETH_SERDES_PLL_LOCKED_BIT)
  65770. +
  65771. +/***** BITs of Port Configuration reg (PxCR) *****/
  65772. +#define ETH_UNICAST_PROMISCUOUS_MODE_BIT 0
  65773. +#define ETH_UNICAST_PROMISCUOUS_MODE_MASK (1<<ETH_UNICAST_PROMISCUOUS_MODE_BIT)
  65774. +
  65775. +#define ETH_DEF_RX_QUEUE_OFFSET 1
  65776. +#define ETH_DEF_RX_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_QUEUE_OFFSET)
  65777. +#define ETH_DEF_RX_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_QUEUE_OFFSET)
  65778. +
  65779. +#define ETH_DEF_RX_ARP_QUEUE_OFFSET 4
  65780. +#define ETH_DEF_RX_ARP_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_ARP_QUEUE_OFFSET)
  65781. +#define ETH_DEF_RX_ARP_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_ARP_QUEUE_OFFSET)
  65782. +
  65783. +#define ETH_REJECT_NOT_IP_ARP_BCAST_BIT 7
  65784. +#define ETH_REJECT_NOT_IP_ARP_BCAST_MASK (1<<ETH_REJECT_NOT_IP_ARP_BCAST_BIT)
  65785. +
  65786. +#define ETH_REJECT_IP_BCAST_BIT 8
  65787. +#define ETH_REJECT_IP_BCAST_MASK (1<<ETH_REJECT_IP_BCAST_BIT)
  65788. +
  65789. +#define ETH_REJECT_ARP_BCAST_BIT 9
  65790. +#define ETH_REJECT_ARP_BCAST_MASK (1<<ETH_REJECT_ARP_BCAST_BIT)
  65791. +
  65792. +#define ETH_TX_NO_SET_ERROR_SUMMARY_BIT 12
  65793. +#define ETH_TX_NO_SET_ERROR_SUMMARY_MASK (1<<ETH_TX_NO_SET_ERROR_SUMMARY_BIT)
  65794. +
  65795. +#define ETH_CAPTURE_TCP_FRAMES_ENABLE_BIT 14
  65796. +#define ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK (1<<ETH_CAPTURE_TCP_FRAMES_ENABLE_BIT)
  65797. +
  65798. +#define ETH_CAPTURE_UDP_FRAMES_ENABLE_BIT 15
  65799. +#define ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK (1<<ETH_CAPTURE_UDP_FRAMES_ENABLE_BIT)
  65800. +
  65801. +#define ETH_DEF_RX_TCP_QUEUE_OFFSET 16
  65802. +#define ETH_DEF_RX_TCP_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_TCP_QUEUE_OFFSET)
  65803. +#define ETH_DEF_RX_TCP_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_TCP_QUEUE_OFFSET)
  65804. +
  65805. +#define ETH_DEF_RX_UDP_QUEUE_OFFSET 19
  65806. +#define ETH_DEF_RX_UDP_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_UDP_QUEUE_OFFSET)
  65807. +#define ETH_DEF_RX_UDP_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_UDP_QUEUE_OFFSET)
  65808. +
  65809. +#define ETH_DEF_RX_BPDU_QUEUE_OFFSET 22
  65810. +#define ETH_DEF_RX_BPDU_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_BPDU_QUEUE_OFFSET)
  65811. +#define ETH_DEF_RX_BPDU_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_BPDU_QUEUE_OFFSET)
  65812. +
  65813. +#define ETH_RX_CHECKSUM_MODE_OFFSET 25
  65814. +#define ETH_RX_CHECKSUM_NO_PSEUDO_HDR (0<<ETH_RX_CHECKSUM_MODE_OFFSET)
  65815. +#define ETH_RX_CHECKSUM_WITH_PSEUDO_HDR (1<<ETH_RX_CHECKSUM_MODE_OFFSET)
  65816. +
  65817. +/***** BITs of Port Configuration Extend reg (PxCXR) *****/
  65818. +#define ETH_CAPTURE_SPAN_BPDU_ENABLE_BIT 1
  65819. +#define ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK (1<<ETH_CAPTURE_SPAN_BPDU_ENABLE_BIT)
  65820. +
  65821. +#define ETH_TX_DISABLE_GEN_CRC_BIT 3
  65822. +#define ETH_TX_DISABLE_GEN_CRC_MASK (1<<ETH_TX_DISABLE_GEN_CRC_BIT)
  65823. +
  65824. +/***** BITs of Tx/Rx queue command reg (RQCR/TQCR) *****/
  65825. +#define ETH_QUEUE_ENABLE_OFFSET 0
  65826. +#define ETH_QUEUE_ENABLE_ALL_MASK (0xFF<<ETH_QUEUE_ENABLE_OFFSET)
  65827. +#define ETH_QUEUE_ENABLE_MASK(queue) (1<<((queue)+ETH_QUEUE_ENABLE_OFFSET))
  65828. +
  65829. +#define ETH_QUEUE_DISABLE_OFFSET 8
  65830. +#define ETH_QUEUE_DISABLE_ALL_MASK (0xFF<<ETH_QUEUE_DISABLE_OFFSET)
  65831. +#define ETH_QUEUE_DISABLE_MASK(queue) (1<<((queue)+ETH_QUEUE_DISABLE_OFFSET))
  65832. +
  65833. +
  65834. +/***** BITs of Port Sdma Configuration reg (SDCR) *****/
  65835. +#define ETH_RX_FRAME_INTERRUPT_BIT 0
  65836. +#define ETH_RX_FRAME_INTERRUPT_MASK (1<<ETH_RX_FRAME_INTERRUPT_BIT)
  65837. +
  65838. +#define ETH_BURST_SIZE_1_64BIT_VALUE 0
  65839. +#define ETH_BURST_SIZE_2_64BIT_VALUE 1
  65840. +#define ETH_BURST_SIZE_4_64BIT_VALUE 2
  65841. +#define ETH_BURST_SIZE_8_64BIT_VALUE 3
  65842. +#define ETH_BURST_SIZE_16_64BIT_VALUE 4
  65843. +
  65844. +#define ETH_RX_BURST_SIZE_OFFSET 1
  65845. +#define ETH_RX_BURST_SIZE_ALL_MASK (0x7<<ETH_RX_BURST_SIZE_OFFSET)
  65846. +#define ETH_RX_BURST_SIZE_MASK(burst) ((burst)<<ETH_RX_BURST_SIZE_OFFSET)
  65847. +
  65848. +#define ETH_RX_NO_DATA_SWAP_BIT 4
  65849. +#define ETH_RX_NO_DATA_SWAP_MASK (1<<ETH_RX_NO_DATA_SWAP_BIT)
  65850. +#define ETH_RX_DATA_SWAP_MASK (0<<ETH_RX_NO_DATA_SWAP_BIT)
  65851. +
  65852. +#define ETH_TX_NO_DATA_SWAP_BIT 5
  65853. +#define ETH_TX_NO_DATA_SWAP_MASK (1<<ETH_TX_NO_DATA_SWAP_BIT)
  65854. +#define ETH_TX_DATA_SWAP_MASK (0<<ETH_TX_NO_DATA_SWAP_BIT)
  65855. +
  65856. +#define ETH_DESC_SWAP_BIT 6
  65857. +#define ETH_DESC_SWAP_MASK (1<<ETH_DESC_SWAP_BIT)
  65858. +#define ETH_NO_DESC_SWAP_MASK (0<<ETH_DESC_SWAP_BIT)
  65859. +
  65860. +#define ETH_RX_INTR_COAL_OFFSET 7
  65861. +#define ETH_RX_INTR_COAL_ALL_MASK (0x3fff<<ETH_RX_INTR_COAL_OFFSET)
  65862. +#define ETH_RX_INTR_COAL_MASK(value) (((value)<<ETH_RX_INTR_COAL_OFFSET) \
  65863. + & ETH_RX_INTR_COAL_ALL_MASK)
  65864. +
  65865. +#define ETH_TX_BURST_SIZE_OFFSET 22
  65866. +#define ETH_TX_BURST_SIZE_ALL_MASK (0x7<<ETH_TX_BURST_SIZE_OFFSET)
  65867. +#define ETH_TX_BURST_SIZE_MASK(burst) ((burst)<<ETH_TX_BURST_SIZE_OFFSET)
  65868. +
  65869. +#define ETH_RX_INTR_COAL_MSB_BIT 25
  65870. +#define ETH_RX_INTR_COAL_MSB_MASK (1<<ETH_RX_INTR_COAL_MSB_BIT)
  65871. +
  65872. +/* BITs Port #x Tx FIFO Urgent Threshold (PxTFUT) */
  65873. +#define ETH_TX_INTR_COAL_OFFSET 4
  65874. +#define ETH_TX_INTR_COAL_ALL_MASK (0x3fff << ETH_TX_INTR_COAL_OFFSET)
  65875. +#define ETH_TX_INTR_COAL_MASK(value) (((value) << ETH_TX_INTR_COAL_OFFSET) \
  65876. + & ETH_TX_INTR_COAL_ALL_MASK)
  65877. +
  65878. +/* BITs of Port Serial Control reg (PSCR) */
  65879. +#define ETH_PORT_ENABLE_BIT 0
  65880. +#define ETH_PORT_ENABLE_MASK (1<<ETH_PORT_ENABLE_BIT)
  65881. +
  65882. +#define ETH_FORCE_LINK_PASS_BIT 1
  65883. +#define ETH_FORCE_LINK_PASS_MASK (1<<ETH_FORCE_LINK_PASS_BIT)
  65884. +
  65885. +#define ETH_DISABLE_DUPLEX_AUTO_NEG_BIT 2
  65886. +#define ETH_DISABLE_DUPLEX_AUTO_NEG_MASK (1<<ETH_DISABLE_DUPLEX_AUTO_NEG_BIT)
  65887. +
  65888. +#define ETH_DISABLE_FC_AUTO_NEG_BIT 3
  65889. +#define ETH_DISABLE_FC_AUTO_NEG_MASK (1<<ETH_DISABLE_FC_AUTO_NEG_BIT)
  65890. +
  65891. +#define ETH_ADVERTISE_SYM_FC_BIT 4
  65892. +#define ETH_ADVERTISE_SYM_FC_MASK (1<<ETH_ADVERTISE_SYM_FC_BIT)
  65893. +
  65894. +#define ETH_TX_FC_MODE_OFFSET 5
  65895. +#define ETH_TX_FC_MODE_MASK (3<<ETH_TX_FC_MODE_OFFSET)
  65896. +#define ETH_TX_FC_NO_PAUSE (0<<ETH_TX_FC_MODE_OFFSET)
  65897. +#define ETH_TX_FC_SEND_PAUSE (1<<ETH_TX_FC_MODE_OFFSET)
  65898. +
  65899. +#define ETH_TX_BP_MODE_OFFSET 7
  65900. +#define ETH_TX_BP_MODE_MASK (3<<ETH_TX_BP_MODE_OFFSET)
  65901. +#define ETH_TX_BP_NO_JAM (0<<ETH_TX_BP_MODE_OFFSET)
  65902. +#define ETH_TX_BP_SEND_JAM (1<<ETH_TX_BP_MODE_OFFSET)
  65903. +
  65904. +#define ETH_DO_NOT_FORCE_LINK_FAIL_BIT 10
  65905. +#define ETH_DO_NOT_FORCE_LINK_FAIL_MASK (1<<ETH_DO_NOT_FORCE_LINK_FAIL_BIT)
  65906. +
  65907. +#define ETH_RETRANSMIT_FOREVER_BIT 11
  65908. +#define ETH_RETRANSMIT_FOREVER_MASK (1<<ETH_RETRANSMIT_FOREVER_BIT)
  65909. +
  65910. +#define ETH_DISABLE_SPEED_AUTO_NEG_BIT 13
  65911. +#define ETH_DISABLE_SPEED_AUTO_NEG_MASK (1<<ETH_DISABLE_SPEED_AUTO_NEG_BIT)
  65912. +
  65913. +#define ETH_DTE_ADVERT_BIT 14
  65914. +#define ETH_DTE_ADVERT_MASK (1<<ETH_DTE_ADVERT_BIT)
  65915. +
  65916. +#define ETH_MII_PHY_MODE_BIT 15
  65917. +#define ETH_MII_PHY_MODE_MAC (0<<ETH_MII_PHY_MODE_BIT)
  65918. +#define ETH_MII_PHY_MODE_PHY (1<<ETH_MII_PHY_MODE_BIT)
  65919. +
  65920. +#define ETH_MII_SOURCE_SYNCH_BIT 16
  65921. +#define ETH_MII_STANDARD_SYNCH (0<<ETH_MII_SOURCE_SYNCH_BIT)
  65922. +#define ETH_MII_400Mbps_SYNCH (1<<ETH_MII_SOURCE_CLK_BIT)
  65923. +
  65924. +#define ETH_MAX_RX_PACKET_SIZE_OFFSET 17
  65925. +#define ETH_MAX_RX_PACKET_SIZE_MASK (7<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  65926. +#define ETH_MAX_RX_PACKET_1518BYTE (0<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  65927. +#define ETH_MAX_RX_PACKET_1522BYTE (1<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  65928. +#define ETH_MAX_RX_PACKET_1552BYTE (2<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  65929. +#define ETH_MAX_RX_PACKET_9022BYTE (3<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  65930. +#define ETH_MAX_RX_PACKET_9192BYTE (4<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  65931. +#define ETH_MAX_RX_PACKET_9700BYTE (5<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  65932. +
  65933. +#define ETH_SET_FULL_DUPLEX_BIT 21
  65934. +#define ETH_SET_FULL_DUPLEX_MASK (1<<ETH_SET_FULL_DUPLEX_BIT)
  65935. +
  65936. +#define ETH_SET_FLOW_CTRL_BIT 22
  65937. +#define ETH_SET_FLOW_CTRL_MASK (1<<ETH_SET_FLOW_CTRL_BIT)
  65938. +
  65939. +#define ETH_SET_GMII_SPEED_1000_BIT 23
  65940. +#define ETH_SET_GMII_SPEED_1000_MASK (1<<ETH_SET_GMII_SPEED_1000_BIT)
  65941. +
  65942. +#define ETH_SET_MII_SPEED_100_BIT 24
  65943. +#define ETH_SET_MII_SPEED_100_MASK (1<<ETH_SET_MII_SPEED_100_BIT)
  65944. +
  65945. +/* BITs of Port Serial Control 1 reg (PSC1R) */
  65946. +#define ETH_PSC_ENABLE_BIT 2
  65947. +#define ETH_PSC_ENABLE_MASK (1<<ETH_PSC_ENABLE_BIT)
  65948. +
  65949. +#define ETH_RGMII_ENABLE_BIT 3
  65950. +#define ETH_RGMII_ENABLE_MASK (1<<ETH_RGMII_ENABLE_BIT)
  65951. +
  65952. +#define ETH_PORT_RESET_BIT 4
  65953. +#define ETH_PORT_RESET_MASK (1<<ETH_PORT_RESET_BIT)
  65954. +
  65955. +#define ETH_INBAND_AUTO_NEG_ENABLE_BIT 6
  65956. +#define ETH_INBAND_AUTO_NEG_ENABLE_MASK (1<<ETH_INBAND_AUTO_NEG_ENABLE_BIT)
  65957. +
  65958. +#define ETH_INBAND_AUTO_NEG_BYPASS_BIT 7
  65959. +#define ETH_INBAND_AUTO_NEG_BYPASS_MASK (1<<ETH_INBAND_AUTO_NEG_BYPASS_BIT)
  65960. +
  65961. +#define ETH_INBAND_AUTO_NEG_START_BIT 8
  65962. +#define ETH_INBAND_AUTO_NEG_START_MASK (1<<ETH_INBAND_AUTO_NEG_START_BIT)
  65963. +
  65964. +#define ETH_PORT_TYPE_BIT 11
  65965. +#define ETH_PORT_TYPE_1000BasedX_MASK (1<<ETH_PORT_TYPE_BIT)
  65966. +
  65967. +#define ETH_SGMII_MODE_BIT 12
  65968. +#define ETH_1000BaseX_MODE_MASK (0<<ETH_SGMII_MODE_BIT)
  65969. +#define ETH_SGMII_MODE_MASK (1<<ETH_SGMII_MODE_BIT)
  65970. +
  65971. +#define ETH_MGMII_MODE_BIT 13
  65972. +
  65973. +#define ETH_EN_MII_ODD_PRE_BIT 22
  65974. +#define ETH_EN_MII_ODD_PRE_MASK (1<<ETH_EN_MII_ODD_PRE_BIT)
  65975. +
  65976. +/* BITs of SDMA Descriptor Command/Status field */
  65977. +#if defined(MV_CPU_BE)
  65978. +typedef struct _ethRxDesc
  65979. +{
  65980. + MV_U16 byteCnt ; /* Descriptor buffer byte count */
  65981. + MV_U16 bufSize ; /* Buffer size */
  65982. + MV_U32 cmdSts ; /* Descriptor command status */
  65983. + MV_U32 nextDescPtr; /* Next descriptor pointer */
  65984. + MV_U32 bufPtr ; /* Descriptor buffer pointer */
  65985. + MV_ULONG returnInfo ; /* User resource return information */
  65986. +} ETH_RX_DESC;
  65987. +
  65988. +typedef struct _ethTxDesc
  65989. +{
  65990. + MV_U16 byteCnt ; /* Descriptor buffer byte count */
  65991. + MV_U16 L4iChk ; /* CPU provided TCP Checksum */
  65992. + MV_U32 cmdSts ; /* Descriptor command status */
  65993. + MV_U32 nextDescPtr; /* Next descriptor pointer */
  65994. + MV_U32 bufPtr ; /* Descriptor buffer pointer */
  65995. + MV_ULONG returnInfo ; /* User resource return information */
  65996. + MV_U8* alignBufPtr; /* Pointer to 8 byte aligned buffer */
  65997. +} ETH_TX_DESC;
  65998. +
  65999. +#elif defined(MV_CPU_LE)
  66000. +
  66001. +typedef struct _ethRxDesc
  66002. +{
  66003. + MV_U32 cmdSts ; /* Descriptor command status */
  66004. + MV_U16 bufSize ; /* Buffer size */
  66005. + MV_U16 byteCnt ; /* Descriptor buffer byte count */
  66006. + MV_U32 bufPtr ; /* Descriptor buffer pointer */
  66007. + MV_U32 nextDescPtr; /* Next descriptor pointer */
  66008. + MV_ULONG returnInfo ; /* User resource return information */
  66009. +} ETH_RX_DESC;
  66010. +
  66011. +typedef struct _ethTxDesc
  66012. +{
  66013. + MV_U32 cmdSts ; /* Descriptor command status */
  66014. + MV_U16 L4iChk ; /* CPU provided TCP Checksum */
  66015. + MV_U16 byteCnt ; /* Descriptor buffer byte count */
  66016. + MV_U32 bufPtr ; /* Descriptor buffer pointer */
  66017. + MV_U32 nextDescPtr; /* Next descriptor pointer */
  66018. + MV_ULONG returnInfo ; /* User resource return information */
  66019. + MV_U8* alignBufPtr; /* Pointer to 32 byte aligned buffer */
  66020. +} ETH_TX_DESC;
  66021. +
  66022. +#else
  66023. +#error "MV_CPU_BE or MV_CPU_LE must be defined"
  66024. +#endif /* MV_CPU_BE || MV_CPU_LE */
  66025. +
  66026. +/* Buffer offset from buffer pointer */
  66027. +#define ETH_RX_BUF_OFFSET 0x2
  66028. +
  66029. +
  66030. +/* Tx & Rx descriptor bits */
  66031. +#define ETH_ERROR_SUMMARY_BIT 0
  66032. +#define ETH_ERROR_SUMMARY_MASK (1<<ETH_ERROR_SUMMARY_BIT)
  66033. +
  66034. +#define ETH_BUFFER_OWNER_BIT 31
  66035. +#define ETH_BUFFER_OWNED_BY_DMA (1<<ETH_BUFFER_OWNER_BIT)
  66036. +#define ETH_BUFFER_OWNED_BY_HOST (0<<ETH_BUFFER_OWNER_BIT)
  66037. +
  66038. +/* Tx descriptor bits */
  66039. +#define ETH_TX_ERROR_CODE_OFFSET 1
  66040. +#define ETH_TX_ERROR_CODE_MASK (3<<ETH_TX_ERROR_CODE_OFFSET)
  66041. +#define ETH_TX_LATE_COLLISION_ERROR (0<<ETH_TX_ERROR_CODE_OFFSET)
  66042. +#define ETH_TX_UNDERRUN_ERROR (1<<ETH_TX_ERROR_CODE_OFFSET)
  66043. +#define ETH_TX_EXCESSIVE_COLLISION_ERROR (2<<ETH_TX_ERROR_CODE_OFFSET)
  66044. +
  66045. +#define ETH_TX_LLC_SNAP_FORMAT_BIT 9
  66046. +#define ETH_TX_LLC_SNAP_FORMAT_MASK (1<<ETH_TX_LLC_SNAP_FORMAT_BIT)
  66047. +
  66048. +#define ETH_TX_IP_FRAG_BIT 10
  66049. +#define ETH_TX_IP_FRAG_MASK (1<<ETH_TX_IP_FRAG_BIT)
  66050. +#define ETH_TX_IP_FRAG (0<<ETH_TX_IP_FRAG_BIT)
  66051. +#define ETH_TX_IP_NO_FRAG (1<<ETH_TX_IP_FRAG_BIT)
  66052. +
  66053. +#define ETH_TX_IP_HEADER_LEN_OFFSET 11
  66054. +#define ETH_TX_IP_HEADER_LEN_ALL_MASK (0xF<<ETH_TX_IP_HEADER_LEN_OFFSET)
  66055. +#define ETH_TX_IP_HEADER_LEN_MASK(len) ((len)<<ETH_TX_IP_HEADER_LEN_OFFSET)
  66056. +
  66057. +#define ETH_TX_VLAN_TAGGED_FRAME_BIT 15
  66058. +#define ETH_TX_VLAN_TAGGED_FRAME_MASK (1<<ETH_TX_VLAN_TAGGED_FRAME_BIT)
  66059. +
  66060. +#define ETH_TX_L4_TYPE_BIT 16
  66061. +#define ETH_TX_L4_TCP_TYPE (0<<ETH_TX_L4_TYPE_BIT)
  66062. +#define ETH_TX_L4_UDP_TYPE (1<<ETH_TX_L4_TYPE_BIT)
  66063. +
  66064. +#define ETH_TX_GENERATE_L4_CHKSUM_BIT 17
  66065. +#define ETH_TX_GENERATE_L4_CHKSUM_MASK (1<<ETH_TX_GENERATE_L4_CHKSUM_BIT)
  66066. +
  66067. +#define ETH_TX_GENERATE_IP_CHKSUM_BIT 18
  66068. +#define ETH_TX_GENERATE_IP_CHKSUM_MASK (1<<ETH_TX_GENERATE_IP_CHKSUM_BIT)
  66069. +
  66070. +#define ETH_TX_ZERO_PADDING_BIT 19
  66071. +#define ETH_TX_ZERO_PADDING_MASK (1<<ETH_TX_ZERO_PADDING_BIT)
  66072. +
  66073. +#define ETH_TX_LAST_DESC_BIT 20
  66074. +#define ETH_TX_LAST_DESC_MASK (1<<ETH_TX_LAST_DESC_BIT)
  66075. +
  66076. +#define ETH_TX_FIRST_DESC_BIT 21
  66077. +#define ETH_TX_FIRST_DESC_MASK (1<<ETH_TX_FIRST_DESC_BIT)
  66078. +
  66079. +#define ETH_TX_GENERATE_CRC_BIT 22
  66080. +#define ETH_TX_GENERATE_CRC_MASK (1<<ETH_TX_GENERATE_CRC_BIT)
  66081. +
  66082. +#define ETH_TX_ENABLE_INTERRUPT_BIT 23
  66083. +#define ETH_TX_ENABLE_INTERRUPT_MASK (1<<ETH_TX_ENABLE_INTERRUPT_BIT)
  66084. +
  66085. +#define ETH_TX_AUTO_MODE_BIT 30
  66086. +#define ETH_TX_AUTO_MODE_MASK (1<<ETH_TX_AUTO_MODE_BIT)
  66087. +
  66088. +
  66089. +/* Rx descriptor bits */
  66090. +#define ETH_RX_ERROR_CODE_OFFSET 1
  66091. +#define ETH_RX_ERROR_CODE_MASK (3<<ETH_RX_ERROR_CODE_OFFSET)
  66092. +#define ETH_RX_CRC_ERROR (0<<ETH_RX_ERROR_CODE_OFFSET)
  66093. +#define ETH_RX_OVERRUN_ERROR (1<<ETH_RX_ERROR_CODE_OFFSET)
  66094. +#define ETH_RX_MAX_FRAME_LEN_ERROR (2<<ETH_RX_ERROR_CODE_OFFSET)
  66095. +#define ETH_RX_RESOURCE_ERROR (3<<ETH_RX_ERROR_CODE_OFFSET)
  66096. +
  66097. +#define ETH_RX_L4_CHECKSUM_OFFSET 3
  66098. +#define ETH_RX_L4_CHECKSUM_MASK (0xffff<<ETH_RX_L4_CHECKSUM_OFFSET)
  66099. +
  66100. +#define ETH_RX_VLAN_TAGGED_FRAME_BIT 19
  66101. +#define ETH_RX_VLAN_TAGGED_FRAME_MASK (1<<ETH_RX_VLAN_TAGGED_FRAME_BIT)
  66102. +
  66103. +#define ETH_RX_BPDU_FRAME_BIT 20
  66104. +#define ETH_RX_BPDU_FRAME_MASK (1<<ETH_RX_BPDU_FRAME_BIT)
  66105. +
  66106. +#define ETH_RX_L4_TYPE_OFFSET 21
  66107. +#define ETH_RX_L4_TYPE_MASK (3<<ETH_RX_L4_TYPE_OFFSET)
  66108. +#define ETH_RX_L4_TCP_TYPE (0<<ETH_RX_L4_TYPE_OFFSET)
  66109. +#define ETH_RX_L4_UDP_TYPE (1<<ETH_RX_L4_TYPE_OFFSET)
  66110. +#define ETH_RX_L4_OTHER_TYPE (2<<ETH_RX_L4_TYPE_OFFSET)
  66111. +
  66112. +#define ETH_RX_NOT_LLC_SNAP_FORMAT_BIT 23
  66113. +#define ETH_RX_NOT_LLC_SNAP_FORMAT_MASK (1<<ETH_RX_NOT_LLC_SNAP_FORMAT_BIT)
  66114. +
  66115. +#define ETH_RX_IP_FRAME_TYPE_BIT 24
  66116. +#define ETH_RX_IP_FRAME_TYPE_MASK (1<<ETH_RX_IP_FRAME_TYPE_BIT)
  66117. +
  66118. +#define ETH_RX_IP_HEADER_OK_BIT 25
  66119. +#define ETH_RX_IP_HEADER_OK_MASK (1<<ETH_RX_IP_HEADER_OK_BIT)
  66120. +
  66121. +#define ETH_RX_LAST_DESC_BIT 26
  66122. +#define ETH_RX_LAST_DESC_MASK (1<<ETH_RX_LAST_DESC_BIT)
  66123. +
  66124. +#define ETH_RX_FIRST_DESC_BIT 27
  66125. +#define ETH_RX_FIRST_DESC_MASK (1<<ETH_RX_FIRST_DESC_BIT)
  66126. +
  66127. +#define ETH_RX_UNKNOWN_DA_BIT 28
  66128. +#define ETH_RX_UNKNOWN_DA_MASK (1<<ETH_RX_UNKNOWN_DA_BIT)
  66129. +
  66130. +#define ETH_RX_ENABLE_INTERRUPT_BIT 29
  66131. +#define ETH_RX_ENABLE_INTERRUPT_MASK (1<<ETH_RX_ENABLE_INTERRUPT_BIT)
  66132. +
  66133. +#define ETH_RX_L4_CHECKSUM_OK_BIT 30
  66134. +#define ETH_RX_L4_CHECKSUM_OK_MASK (1<<ETH_RX_L4_CHECKSUM_OK_BIT)
  66135. +
  66136. +/* Rx descriptor bufSize field */
  66137. +#define ETH_RX_IP_FRAGMENTED_FRAME_BIT 2
  66138. +#define ETH_RX_IP_FRAGMENTED_FRAME_MASK (1<<ETH_RX_IP_FRAGMENTED_FRAME_BIT)
  66139. +
  66140. +#define ETH_RX_BUFFER_MASK 0xFFF8
  66141. +
  66142. +
  66143. +/* Ethernet Cause Register BITs */
  66144. +#define ETH_CAUSE_RX_READY_SUM_BIT 0
  66145. +#define ETH_CAUSE_EXTEND_BIT 1
  66146. +
  66147. +#define ETH_CAUSE_RX_READY_OFFSET 2
  66148. +#define ETH_CAUSE_RX_READY_BIT(queue) (ETH_CAUSE_RX_READY_OFFSET + (queue))
  66149. +#define ETH_CAUSE_RX_READY_MASK(queue) (1 << (ETH_CAUSE_RX_READY_BIT(queue)))
  66150. +
  66151. +#define ETH_CAUSE_RX_ERROR_SUM_BIT 10
  66152. +#define ETH_CAUSE_RX_ERROR_OFFSET 11
  66153. +#define ETH_CAUSE_RX_ERROR_BIT(queue) (ETH_CAUSE_RX_ERROR_OFFSET + (queue))
  66154. +#define ETH_CAUSE_RX_ERROR_MASK(queue) (1 << (ETH_CAUSE_RX_ERROR_BIT(queue)))
  66155. +
  66156. +#define ETH_CAUSE_TX_END_BIT 19
  66157. +#define ETH_CAUSE_SUM_BIT 31
  66158. +
  66159. +/* Ethernet Cause Extended Register BITs */
  66160. +#define ETH_CAUSE_TX_BUF_OFFSET 0
  66161. +#define ETH_CAUSE_TX_BUF_BIT(queue) (ETH_CAUSE_TX_BUF_OFFSET + (queue))
  66162. +#define ETH_CAUSE_TX_BUF_MASK(queue) (1 << (ETH_CAUSE_TX_BUF_BIT(queue)))
  66163. +
  66164. +#define ETH_CAUSE_TX_ERROR_OFFSET 8
  66165. +#define ETH_CAUSE_TX_ERROR_BIT(queue) (ETH_CAUSE_TX_ERROR_OFFSET + (queue))
  66166. +#define ETH_CAUSE_TX_ERROR_MASK(queue) (1 << (ETH_CAUSE_TX_ERROR_BIT(queue)))
  66167. +
  66168. +#define ETH_CAUSE_PHY_STATUS_CHANGE_BIT 16
  66169. +#define ETH_CAUSE_RX_OVERRUN_BIT 18
  66170. +#define ETH_CAUSE_TX_UNDERRUN_BIT 19
  66171. +#define ETH_CAUSE_LINK_STATE_CHANGE_BIT 20
  66172. +#define ETH_CAUSE_INTERNAL_ADDR_ERR_BIT 23
  66173. +#define ETH_CAUSE_EXTEND_SUM_BIT 31
  66174. +
  66175. +/* Marvell Header Register */
  66176. +/* Marvell Header register bits */
  66177. +#define ETH_MVHDR_EN_BIT 0
  66178. +#define ETH_MVHDR_EN_MASK (1 << ETH_MVHDR_EN_BIT)
  66179. +
  66180. +#define ETH_MVHDR_DAPREFIX_BIT 1
  66181. +#define ETH_MVHDR_DAPREFIX_MASK (0x3 << ETH_MVHDR_DAPREFIX_BIT)
  66182. +#define ETH_MVHDR_DAPREFIX_PRI_1_2 (0x1 << ETH_MVHDR_DAPREFIX_BIT)
  66183. +#define ETH_MVHDR_DAPREFIX_DBNUM_PRI (0x2 << ETH_MVHDR_DAPREFIX_BIT)
  66184. +#define ETH_MVHDR_DAPREFIX_SPID_PRI (0x3 << ETH_MVHDR_DAPREFIX_BIT)
  66185. +
  66186. +#define ETH_MVHDR_MHMASK_BIT 8
  66187. +#define ETH_MVHDR_MHMASK_MASK (0x3 << ETH_MVHDR_MHMASK_BIT)
  66188. +#define ETH_MVHDR_MHMASK_8_QUEUE (0x0 << ETH_MVHDR_MHMASK_BIT)
  66189. +#define ETH_MVHDR_MHMASK_4_QUEUE (0x1 << ETH_MVHDR_MHMASK_BIT)
  66190. +#define ETH_MVHDR_MHMASK_2_QUEUE (0x3 << ETH_MVHDR_MHMASK_BIT)
  66191. +
  66192. +
  66193. +/* Relevant for 6183 ONLY */
  66194. +#define ETH_UNIT_PORTS_PADS_CALIB_0_REG (MV_ETH_REG_BASE(0) + 0x0A0)
  66195. +#define ETH_UNIT_PORTS_PADS_CALIB_1_REG (MV_ETH_REG_BASE(0) + 0x0A4)
  66196. +#define ETH_UNIT_PORTS_PADS_CALIB_2_REG (MV_ETH_REG_BASE(0) + 0x0A8)
  66197. +/* Ethernet Unit Ports Pads Calibration_REG (ETH_UNIT_PORTS_PADS_CALIB_x_REG) */
  66198. +#define ETH_ETHERNET_PAD_CLIB_DRVN_OFFS 0
  66199. +#define ETH_ETHERNET_PAD_CLIB_DRVN_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_DRVN_OFFS)
  66200. +
  66201. +#define ETH_ETHERNET_PAD_CLIB_DRVP_OFFS 5
  66202. +#define ETH_ETHERNET_PAD_CLIB_DRVP_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_DRVP_OFFS)
  66203. +
  66204. +#define ETH_ETHERNET_PAD_CLIB_TUNEEN_OFFS 16
  66205. +#define ETH_ETHERNET_PAD_CLIB_TUNEEN_MASK (0x1 << ETH_ETHERNET_PAD_CLIB_TUNEEN_OFFS)
  66206. +
  66207. +#define ETH_ETHERNET_PAD_CLIB_LOCKN_OFFS 17
  66208. +#define ETH_ETHERNET_PAD_CLIB_LOCKN_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_LOCKN_OFFS)
  66209. +
  66210. +#define ETH_ETHERNET_PAD_CLIB_OFFST_OFFS 24
  66211. +#define ETH_ETHERNET_PAD_CLIB_OFFST_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_OFFST_OFFS)
  66212. +
  66213. +#define ETH_ETHERNET_PAD_CLIB_WR_EN_OFFS 31
  66214. +#define ETH_ETHERNET_PAD_CLIB_WR_EN_MASK (0x1 << ETH_ETHERNET_PAD_CLIB_WR_EN_OFFS)
  66215. +
  66216. +
  66217. +#ifdef __cplusplus
  66218. +}
  66219. +#endif /* __cplusplus */
  66220. +
  66221. +#endif /* __INCmvEthRegsh */
  66222. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h
  66223. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h 1970-01-01 01:00:00.000000000 +0100
  66224. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h 2010-08-05 22:02:24.753792702 +0200
  66225. @@ -0,0 +1,356 @@
  66226. +/*******************************************************************************
  66227. +Copyright (C) Marvell International Ltd. and its affiliates
  66228. +
  66229. +This software file (the "File") is owned and distributed by Marvell
  66230. +International Ltd. and/or its affiliates ("Marvell") under the following
  66231. +alternative licensing terms. Once you have made an election to distribute the
  66232. +File under one of the following license alternatives, please (i) delete this
  66233. +introductory statement regarding license alternatives, (ii) delete the two
  66234. +license alternatives that you have not elected to use and (iii) preserve the
  66235. +Marvell copyright notice above.
  66236. +
  66237. +********************************************************************************
  66238. +Marvell Commercial License Option
  66239. +
  66240. +If you received this File from Marvell and you have entered into a commercial
  66241. +license agreement (a "Commercial License") with Marvell, the File is licensed
  66242. +to you under the terms of the applicable Commercial License.
  66243. +
  66244. +********************************************************************************
  66245. +Marvell GPL License Option
  66246. +
  66247. +If you received this File from Marvell, you may opt to use, redistribute and/or
  66248. +modify this File in accordance with the terms and conditions of the General
  66249. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  66250. +available along with the File in the license.txt file or by writing to the Free
  66251. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  66252. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  66253. +
  66254. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  66255. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  66256. +DISCLAIMED. The GPL License provides additional details about this warranty
  66257. +disclaimer.
  66258. +********************************************************************************
  66259. +Marvell BSD License Option
  66260. +
  66261. +If you received this File from Marvell, you may opt to use, redistribute and/or
  66262. +modify this File under the following licensing terms.
  66263. +Redistribution and use in source and binary forms, with or without modification,
  66264. +are permitted provided that the following conditions are met:
  66265. +
  66266. + * Redistributions of source code must retain the above copyright notice,
  66267. + this list of conditions and the following disclaimer.
  66268. +
  66269. + * Redistributions in binary form must reproduce the above copyright
  66270. + notice, this list of conditions and the following disclaimer in the
  66271. + documentation and/or other materials provided with the distribution.
  66272. +
  66273. + * Neither the name of Marvell nor the names of its contributors may be
  66274. + used to endorse or promote products derived from this software without
  66275. + specific prior written permission.
  66276. +
  66277. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  66278. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  66279. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  66280. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  66281. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  66282. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  66283. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  66284. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  66285. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  66286. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  66287. +
  66288. +*******************************************************************************/
  66289. +
  66290. +/*******************************************************************************
  66291. +* mvEth.h - Header File for : Ethernet Controller
  66292. +*
  66293. +* DESCRIPTION:
  66294. +* This header file contains macros typedefs and function declaration for
  66295. +* Marvell Gigabit Ethernet Controllers.
  66296. +*
  66297. +* DEPENDENCIES:
  66298. +* None.
  66299. +*
  66300. +*******************************************************************************/
  66301. +
  66302. +#ifndef __mvEth_h__
  66303. +#define __mvEth_h__
  66304. +
  66305. +/* includes */
  66306. +#include "mvTypes.h"
  66307. +#include "mv802_3.h"
  66308. +#include "ctrlEnv/mvCtrlEnvLib.h"
  66309. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  66310. +#include "eth/gbe/mvEthRegs.h"
  66311. +#include "mvSysHwConfig.h"
  66312. +
  66313. +/* defines */
  66314. +
  66315. +#define MV_ETH_EXTRA_FRAGS_NUM 2
  66316. +
  66317. +
  66318. +typedef enum
  66319. +{
  66320. + MV_ETH_SPEED_AN,
  66321. + MV_ETH_SPEED_10,
  66322. + MV_ETH_SPEED_100,
  66323. + MV_ETH_SPEED_1000
  66324. +
  66325. +} MV_ETH_PORT_SPEED;
  66326. +
  66327. +typedef enum
  66328. +{
  66329. + MV_ETH_DUPLEX_AN,
  66330. + MV_ETH_DUPLEX_HALF,
  66331. + MV_ETH_DUPLEX_FULL
  66332. +
  66333. +} MV_ETH_PORT_DUPLEX;
  66334. +
  66335. +typedef enum
  66336. +{
  66337. + MV_ETH_FC_AN_ADV_DIS,
  66338. + MV_ETH_FC_AN_ADV_SYM,
  66339. + MV_ETH_FC_DISABLE,
  66340. + MV_ETH_FC_ENABLE
  66341. +
  66342. +} MV_ETH_PORT_FC;
  66343. +
  66344. +typedef enum
  66345. +{
  66346. + MV_ETH_PRIO_FIXED = 0, /* Fixed priority mode */
  66347. + MV_ETH_PRIO_WRR = 1 /* Weighted round robin priority mode */
  66348. +} MV_ETH_PRIO_MODE;
  66349. +
  66350. +/* Ethernet port specific infomation */
  66351. +typedef struct
  66352. +{
  66353. + int maxRxPktSize;
  66354. + int rxDefQ;
  66355. + int rxBpduQ;
  66356. + int rxArpQ;
  66357. + int rxTcpQ;
  66358. + int rxUdpQ;
  66359. + int ejpMode;
  66360. +} MV_ETH_PORT_CFG;
  66361. +
  66362. +typedef struct
  66363. +{
  66364. + int descrNum;
  66365. +} MV_ETH_RX_Q_CFG;
  66366. +
  66367. +typedef struct
  66368. +{
  66369. + int descrNum;
  66370. + MV_ETH_PRIO_MODE prioMode;
  66371. + int quota;
  66372. +} MV_ETH_TX_Q_CFG;
  66373. +
  66374. +typedef struct
  66375. +{
  66376. + int maxRxPktSize;
  66377. + int rxDefQ;
  66378. + int txDescrNum[MV_ETH_TX_Q_NUM];
  66379. + int rxDescrNum[MV_ETH_RX_Q_NUM];
  66380. + void *osHandle;
  66381. +} MV_ETH_PORT_INIT;
  66382. +
  66383. +typedef struct
  66384. +{
  66385. + MV_BOOL isLinkUp;
  66386. + MV_ETH_PORT_SPEED speed;
  66387. + MV_ETH_PORT_DUPLEX duplex;
  66388. + MV_ETH_PORT_FC flowControl;
  66389. +
  66390. +} MV_ETH_PORT_STATUS;
  66391. +
  66392. +typedef enum
  66393. +{
  66394. + MV_ETH_DISABLE_HEADER_MODE = 0,
  66395. + MV_ETH_ENABLE_HEADER_MODE_PRI_2_1 = 1,
  66396. + MV_ETH_ENABLE_HEADER_MODE_PRI_DBNUM = 2,
  66397. + MV_ETH_ENABLE_HEADER_MODE_PRI_SPID = 3
  66398. +} MV_ETH_HEADER_MODE;
  66399. +
  66400. +
  66401. +/* ethernet.h API list */
  66402. +void mvEthHalInit(void);
  66403. +void mvEthMemAttrGet(MV_BOOL* pIsSram, MV_BOOL* pIsSwCoher);
  66404. +
  66405. +/* Port Initalization routines */
  66406. +void* mvEthPortInit (int port, MV_ETH_PORT_INIT *pPortInit);
  66407. +void ethResetTxDescRing(void* pPortHndl, int queue);
  66408. +void ethResetRxDescRing(void* pPortHndl, int queue);
  66409. +
  66410. +void* mvEthPortHndlGet(int port);
  66411. +
  66412. +void mvEthPortFinish(void* pEthPortHndl);
  66413. +MV_STATUS mvEthPortDown(void* pEthPortHndl);
  66414. +MV_STATUS mvEthPortDisable(void* pEthPortHndl);
  66415. +MV_STATUS mvEthPortUp(void* pEthPortHndl);
  66416. +MV_STATUS mvEthPortEnable(void* pEthPortHndl);
  66417. +
  66418. +/* Port data flow routines */
  66419. +MV_PKT_INFO *mvEthPortForceTxDone(void* pEthPortHndl, int txQueue);
  66420. +MV_PKT_INFO *mvEthPortForceRx(void* pEthPortHndl, int rxQueue);
  66421. +
  66422. +/* Port Configuration routines */
  66423. +MV_STATUS mvEthDefaultsSet(void* pEthPortHndl);
  66424. +MV_STATUS mvEthMaxRxSizeSet(void* pPortHndl, int maxRxSize);
  66425. +
  66426. +/* Port RX MAC Filtering control routines */
  66427. +MV_U8 mvEthMcastCrc8Get(MV_U8* pAddr);
  66428. +MV_STATUS mvEthRxFilterModeSet(void* pPortHndl, MV_BOOL isPromisc);
  66429. +MV_STATUS mvEthMacAddrSet(void* pPortHandle, MV_U8* pMacAddr, int queue);
  66430. +MV_STATUS mvEthMcastAddrSet(void* pPortHandle, MV_U8 *pAddr, int queue);
  66431. +
  66432. +/* MIB Counters APIs */
  66433. +MV_U32 mvEthMibCounterRead(void* pPortHndl, unsigned int mibOffset,
  66434. + MV_U32* pHigh32);
  66435. +void mvEthMibCountersClear(void* pPortHandle);
  66436. +
  66437. +/* TX Scheduling configuration routines */
  66438. +MV_STATUS mvEthTxQueueConfig(void* pPortHandle, int txQueue,
  66439. + MV_ETH_PRIO_MODE txPrioMode, int txQuota);
  66440. +
  66441. +/* RX Dispatching configuration routines */
  66442. +MV_STATUS mvEthBpduRxQueue(void* pPortHandle, int bpduQueue);
  66443. +MV_STATUS mvEthVlanPrioRxQueue(void* pPortHandle, int vlanPrio, int vlanPrioQueue);
  66444. +MV_STATUS mvEthTosToRxqSet(void* pPortHandle, int tos, int rxq);
  66445. +int mvEthTosToRxqGet(void* pPortHandle, int tos);
  66446. +
  66447. +/* Speed, Duplex, FlowControl routines */
  66448. +MV_STATUS mvEthSpeedDuplexSet(void* pPortHandle, MV_ETH_PORT_SPEED speed,
  66449. + MV_ETH_PORT_DUPLEX duplex);
  66450. +
  66451. +MV_STATUS mvEthFlowCtrlSet(void* pPortHandle, MV_ETH_PORT_FC flowControl);
  66452. +
  66453. +#if (MV_ETH_VERSION >= 4)
  66454. +MV_STATUS mvEthEjpModeSet(void* pPortHandle, int mode);
  66455. +#endif /* (MV_ETH_VERSION >= 4) */
  66456. +
  66457. +void mvEthStatusGet(void* pPortHandle, MV_ETH_PORT_STATUS* pStatus);
  66458. +
  66459. +/* Marvell Header control */
  66460. +MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode);
  66461. +
  66462. +/* PHY routines */
  66463. +void mvEthPhyAddrSet(void* pPortHandle, int phyAddr);
  66464. +int mvEthPhyAddrGet(void* pPortHandle);
  66465. +
  66466. +/* Power management routines */
  66467. +void mvEthPortPowerDown(int port);
  66468. +void mvEthPortPowerUp(int port);
  66469. +
  66470. +/******************** ETH PRIVATE ************************/
  66471. +
  66472. +/*#define UNCACHED_TX_BUFFERS*/
  66473. +/*#define UNCACHED_RX_BUFFERS*/
  66474. +
  66475. +
  66476. +/* Port attributes */
  66477. +/* Size of a Tx/Rx descriptor used in chain list data structure */
  66478. +#define ETH_RX_DESC_ALIGNED_SIZE 32
  66479. +#define ETH_TX_DESC_ALIGNED_SIZE 32
  66480. +
  66481. +#define TX_DISABLE_TIMEOUT_MSEC 1000
  66482. +#define RX_DISABLE_TIMEOUT_MSEC 1000
  66483. +#define TX_FIFO_EMPTY_TIMEOUT_MSEC 10000
  66484. +#define PORT_DISABLE_WAIT_TCLOCKS 5000
  66485. +
  66486. +/* Macros that save access to desc in order to find next desc pointer */
  66487. +#define RX_NEXT_DESC_PTR(pRxDescr, pQueueCtrl) \
  66488. + ((pRxDescr) == (pQueueCtrl)->pLastDescr) ? \
  66489. + (ETH_RX_DESC*)((pQueueCtrl)->pFirstDescr) : \
  66490. + (ETH_RX_DESC*)(((MV_ULONG)(pRxDescr)) + ETH_RX_DESC_ALIGNED_SIZE)
  66491. +
  66492. +#define TX_NEXT_DESC_PTR(pTxDescr, pQueueCtrl) \
  66493. + ((pTxDescr) == (pQueueCtrl)->pLastDescr) ? \
  66494. + (ETH_TX_DESC*)((pQueueCtrl)->pFirstDescr) : \
  66495. + (ETH_TX_DESC*)(((MV_ULONG)(pTxDescr)) + ETH_TX_DESC_ALIGNED_SIZE)
  66496. +
  66497. +#define RX_PREV_DESC_PTR(pRxDescr, pQueueCtrl) \
  66498. + ((pRxDescr) == (pQueueCtrl)->pFirstDescr) ? \
  66499. + (ETH_RX_DESC*)((pQueueCtrl)->pLastDescr) : \
  66500. + (ETH_RX_DESC*)(((MV_ULONG)(pRxDescr)) - ETH_RX_DESC_ALIGNED_SIZE)
  66501. +
  66502. +#define TX_PREV_DESC_PTR(pTxDescr, pQueueCtrl) \
  66503. + ((pTxDescr) == (pQueueCtrl)->pFirstDescr) ? \
  66504. + (ETH_TX_DESC*)((pQueueCtrl)->pLastDescr) : \
  66505. + (ETH_TX_DESC*)(((MV_ULONG)(pTxDescr)) - ETH_TX_DESC_ALIGNED_SIZE)
  66506. +
  66507. +
  66508. +/* Queue specific information */
  66509. +typedef struct
  66510. +{
  66511. + void* pFirstDescr;
  66512. + void* pLastDescr;
  66513. + void* pCurrentDescr;
  66514. + void* pUsedDescr;
  66515. + int resource;
  66516. + MV_BUF_INFO descBuf;
  66517. +} ETH_QUEUE_CTRL;
  66518. +
  66519. +
  66520. +/* Ethernet port specific infomation */
  66521. +typedef struct _ethPortCtrl
  66522. +{
  66523. + int portNo;
  66524. + ETH_QUEUE_CTRL rxQueue[MV_ETH_RX_Q_NUM]; /* Rx ring resource */
  66525. + ETH_QUEUE_CTRL txQueue[MV_ETH_TX_Q_NUM]; /* Tx ring resource */
  66526. +
  66527. + MV_ETH_PORT_CFG portConfig;
  66528. + MV_ETH_RX_Q_CFG rxQueueConfig[MV_ETH_RX_Q_NUM];
  66529. + MV_ETH_TX_Q_CFG txQueueConfig[MV_ETH_TX_Q_NUM];
  66530. +
  66531. + /* Register images - For DP */
  66532. + MV_U32 portTxQueueCmdReg; /* Port active Tx queues summary */
  66533. + MV_U32 portRxQueueCmdReg; /* Port active Rx queues summary */
  66534. +
  66535. + MV_STATE portState;
  66536. +
  66537. + MV_U8 mcastCount[256];
  66538. + MV_U32* hashPtr;
  66539. + void *osHandle;
  66540. +} ETH_PORT_CTRL;
  66541. +
  66542. +/************** MACROs ****************/
  66543. +
  66544. +/* MACROs to Flush / Invalidate TX / RX Buffers */
  66545. +#if (ETHER_DRAM_COHER == MV_CACHE_COHER_SW) && !defined(UNCACHED_TX_BUFFERS)
  66546. +# define ETH_PACKET_CACHE_FLUSH(pAddr, size) \
  66547. + mvOsCacheClear(NULL, (pAddr), (size)); \
  66548. + /*CPU_PIPE_FLUSH;*/
  66549. +#else
  66550. +# define ETH_PACKET_CACHE_FLUSH(pAddr, size) \
  66551. + mvOsIoVirtToPhy(NULL, (pAddr));
  66552. +#endif /* ETHER_DRAM_COHER == MV_CACHE_COHER_SW */
  66553. +
  66554. +#if ( (ETHER_DRAM_COHER == MV_CACHE_COHER_SW) && !defined(UNCACHED_RX_BUFFERS) )
  66555. +# define ETH_PACKET_CACHE_INVALIDATE(pAddr, size) \
  66556. + mvOsCacheInvalidate (NULL, (pAddr), (size)); \
  66557. + /*CPU_PIPE_FLUSH;*/
  66558. +#else
  66559. +# define ETH_PACKET_CACHE_INVALIDATE(pAddr, size)
  66560. +#endif /* ETHER_DRAM_COHER == MV_CACHE_COHER_SW && !UNCACHED_RX_BUFFERS */
  66561. +
  66562. +#ifdef ETH_DESCR_UNCACHED
  66563. +
  66564. +#define ETH_DESCR_FLUSH_INV(pPortCtrl, pDescr)
  66565. +#define ETH_DESCR_INV(pPortCtrl, pDescr)
  66566. +
  66567. +#else
  66568. +
  66569. +#define ETH_DESCR_FLUSH_INV(pPortCtrl, pDescr) \
  66570. + mvOsCacheLineFlushInv(pPortCtrl->osHandle, (MV_ULONG)(pDescr))
  66571. +
  66572. +#define ETH_DESCR_INV(pPortCtrl, pDescr) \
  66573. + mvOsCacheLineInv(pPortCtrl->osHandle, (MV_ULONG)(pDescr))
  66574. +
  66575. +#endif /* ETH_DESCR_UNCACHED */
  66576. +
  66577. +#include "eth/gbe/mvEthGbe.h"
  66578. +
  66579. +#endif /* __mvEth_h__ */
  66580. +
  66581. +
  66582. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c
  66583. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c 1970-01-01 01:00:00.000000000 +0100
  66584. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c 2010-08-05 22:02:24.794414952 +0200
  66585. @@ -0,0 +1,362 @@
  66586. +/*******************************************************************************
  66587. +Copyright (C) Marvell International Ltd. and its affiliates
  66588. +
  66589. +This software file (the "File") is owned and distributed by Marvell
  66590. +International Ltd. and/or its affiliates ("Marvell") under the following
  66591. +alternative licensing terms. Once you have made an election to distribute the
  66592. +File under one of the following license alternatives, please (i) delete this
  66593. +introductory statement regarding license alternatives, (ii) delete the two
  66594. +license alternatives that you have not elected to use and (iii) preserve the
  66595. +Marvell copyright notice above.
  66596. +
  66597. +********************************************************************************
  66598. +Marvell Commercial License Option
  66599. +
  66600. +If you received this File from Marvell and you have entered into a commercial
  66601. +license agreement (a "Commercial License") with Marvell, the File is licensed
  66602. +to you under the terms of the applicable Commercial License.
  66603. +
  66604. +********************************************************************************
  66605. +Marvell GPL License Option
  66606. +
  66607. +If you received this File from Marvell, you may opt to use, redistribute and/or
  66608. +modify this File in accordance with the terms and conditions of the General
  66609. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  66610. +available along with the File in the license.txt file or by writing to the Free
  66611. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  66612. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  66613. +
  66614. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  66615. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  66616. +DISCLAIMED. The GPL License provides additional details about this warranty
  66617. +disclaimer.
  66618. +********************************************************************************
  66619. +Marvell BSD License Option
  66620. +
  66621. +If you received this File from Marvell, you may opt to use, redistribute and/or
  66622. +modify this File under the following licensing terms.
  66623. +Redistribution and use in source and binary forms, with or without modification,
  66624. +are permitted provided that the following conditions are met:
  66625. +
  66626. + * Redistributions of source code must retain the above copyright notice,
  66627. + this list of conditions and the following disclaimer.
  66628. +
  66629. + * Redistributions in binary form must reproduce the above copyright
  66630. + notice, this list of conditions and the following disclaimer in the
  66631. + documentation and/or other materials provided with the distribution.
  66632. +
  66633. + * Neither the name of Marvell nor the names of its contributors may be
  66634. + used to endorse or promote products derived from this software without
  66635. + specific prior written permission.
  66636. +
  66637. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  66638. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  66639. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  66640. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  66641. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  66642. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  66643. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  66644. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  66645. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  66646. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  66647. +
  66648. +*******************************************************************************/
  66649. +
  66650. +#include "gpp/mvGpp.h"
  66651. +#include "ctrlEnv/mvCtrlEnvLib.h"
  66652. +/* defines */
  66653. +#ifdef MV_DEBUG
  66654. + #define DB(x) x
  66655. +#else
  66656. + #define DB(x)
  66657. +#endif
  66658. +
  66659. +static MV_VOID gppRegSet(MV_U32 group, MV_U32 regOffs,MV_U32 mask,MV_U32 value);
  66660. +
  66661. +/*******************************************************************************
  66662. +* mvGppTypeSet - Enable a GPP (OUT) pin
  66663. +*
  66664. +* DESCRIPTION:
  66665. +*
  66666. +* INPUT:
  66667. +* group - GPP group number
  66668. +* mask - 32bit mask value. Each set bit in the mask means that the type
  66669. +* of corresponding GPP will be set. Other GPPs are ignored.
  66670. +* value - 32bit value that describes GPP type per pin.
  66671. +*
  66672. +* OUTPUT:
  66673. +* None.
  66674. +*
  66675. +* EXAMPLE:
  66676. +* Set GPP8 to input and GPP15 to output.
  66677. +* mvGppTypeSet(0, (GPP8 | GPP15),
  66678. +* ((MV_GPP_IN & GPP8) | (MV_GPP_OUT & GPP15)) );
  66679. +*
  66680. +* RETURN:
  66681. +* None.
  66682. +*
  66683. +*******************************************************************************/
  66684. +MV_STATUS mvGppTypeSet(MV_U32 group, MV_U32 mask, MV_U32 value)
  66685. +{
  66686. + if (group >= MV_GPP_MAX_GROUP)
  66687. + {
  66688. + DB(mvOsPrintf("mvGppTypeSet: ERR. invalid group number \n"));
  66689. + return MV_BAD_PARAM;
  66690. + }
  66691. +
  66692. + gppRegSet(group, GPP_DATA_OUT_EN_REG(group), mask, value);
  66693. +
  66694. + /* Workaround for Erratum FE-MISC-70*/
  66695. + if(mvCtrlRevGet()==MV_88F6XXX_A0_REV && (group == 1))
  66696. + {
  66697. + mask &= 0x2;
  66698. + gppRegSet(0, GPP_DATA_OUT_EN_REG(0), mask, value);
  66699. + } /*End of WA*/
  66700. +
  66701. + return MV_OK;
  66702. +
  66703. +}
  66704. +
  66705. +/*******************************************************************************
  66706. +* mvGppBlinkEn - Set a GPP (IN) Pin list to blink every ~100ms
  66707. +*
  66708. +* DESCRIPTION:
  66709. +*
  66710. +* INPUT:
  66711. +* group - GPP group number
  66712. +* mask - 32bit mask value. Each set bit in the mask means that the type
  66713. +* of corresponding GPP will be set. Other GPPs are ignored.
  66714. +* value - 32bit value that describes GPP blink per pin.
  66715. +*
  66716. +* OUTPUT:
  66717. +* None.
  66718. +*
  66719. +* EXAMPLE:
  66720. +* Set GPP8 to be static and GPP15 to be blinking.
  66721. +* mvGppBlinkEn(0, (GPP8 | GPP15),
  66722. +* ((MV_GPP_OUT_STATIC & GPP8) | (MV_GPP_OUT_BLINK & GPP15)) );
  66723. +*
  66724. +* RETURN:
  66725. +* None.
  66726. +*
  66727. +*******************************************************************************/
  66728. +MV_STATUS mvGppBlinkEn(MV_U32 group, MV_U32 mask, MV_U32 value)
  66729. +{
  66730. + if (group >= MV_GPP_MAX_GROUP)
  66731. + {
  66732. + DB(mvOsPrintf("mvGppBlinkEn: ERR. invalid group number \n"));
  66733. + return MV_BAD_PARAM;
  66734. + }
  66735. +
  66736. + gppRegSet(group, GPP_BLINK_EN_REG(group), mask, value);
  66737. +
  66738. + return MV_OK;
  66739. +
  66740. +}
  66741. +/*******************************************************************************
  66742. +* mvGppPolaritySet - Set a GPP (IN) Pin list Polarity mode
  66743. +*
  66744. +* DESCRIPTION:
  66745. +*
  66746. +* INPUT:
  66747. +* group - GPP group number
  66748. +* mask - 32bit mask value. Each set bit in the mask means that the type
  66749. +* of corresponding GPP will be set. Other GPPs are ignored.
  66750. +* value - 32bit value that describes GPP polarity per pin.
  66751. +*
  66752. +* OUTPUT:
  66753. +* None.
  66754. +*
  66755. +* EXAMPLE:
  66756. +* Set GPP8 to the actual pin value and GPP15 to be inverted.
  66757. +* mvGppPolaritySet(0, (GPP8 | GPP15),
  66758. +* ((MV_GPP_IN_ORIGIN & GPP8) | (MV_GPP_IN_INVERT & GPP15)) );
  66759. +*
  66760. +* RETURN:
  66761. +* None.
  66762. +*
  66763. +*******************************************************************************/
  66764. +MV_STATUS mvGppPolaritySet(MV_U32 group, MV_U32 mask, MV_U32 value)
  66765. +{
  66766. + if (group >= MV_GPP_MAX_GROUP)
  66767. + {
  66768. + DB(mvOsPrintf("mvGppPolaritySet: ERR. invalid group number \n"));
  66769. + return MV_BAD_PARAM;
  66770. + }
  66771. +
  66772. + gppRegSet(group, GPP_DATA_IN_POL_REG(group), mask, value);
  66773. +
  66774. + return MV_OK;
  66775. +
  66776. +}
  66777. +
  66778. +/*******************************************************************************
  66779. +* mvGppPolarityGet - Get a value of relevant bits from GPP Polarity register.
  66780. +*
  66781. +* DESCRIPTION:
  66782. +*
  66783. +* INPUT:
  66784. +* group - GPP group number
  66785. +* mask - 32bit mask value. Each set bit in the mask means that the
  66786. +* returned value is valid for it.
  66787. +*
  66788. +* OUTPUT:
  66789. +* None.
  66790. +*
  66791. +* EXAMPLE:
  66792. +* Get GPP8 and GPP15 value.
  66793. +* mvGppPolarityGet(0, (GPP8 | GPP15));
  66794. +*
  66795. +* RETURN:
  66796. +* 32bit value that describes GPP polatity mode per pin.
  66797. +*
  66798. +*******************************************************************************/
  66799. +MV_U32 mvGppPolarityGet(MV_U32 group, MV_U32 mask)
  66800. +{
  66801. + MV_U32 regVal;
  66802. +
  66803. + if (group >= MV_GPP_MAX_GROUP)
  66804. + {
  66805. + DB(mvOsPrintf("mvGppActiveSet: Error invalid group number \n"));
  66806. + return MV_ERROR;
  66807. + }
  66808. + regVal = MV_REG_READ(GPP_DATA_IN_POL_REG(group));
  66809. +
  66810. + return (regVal & mask);
  66811. +}
  66812. +
  66813. +/*******************************************************************************
  66814. +* mvGppValueGet - Get a GPP Pin list value.
  66815. +*
  66816. +* DESCRIPTION:
  66817. +* This function get GPP value.
  66818. +*
  66819. +* INPUT:
  66820. +* group - GPP group number
  66821. +* mask - 32bit mask value. Each set bit in the mask means that the
  66822. +* returned value is valid for it.
  66823. +*
  66824. +* OUTPUT:
  66825. +* None.
  66826. +*
  66827. +* EXAMPLE:
  66828. +* Get GPP8 and GPP15 value.
  66829. +* mvGppValueGet(0, (GPP8 | GPP15));
  66830. +*
  66831. +* RETURN:
  66832. +* 32bit value that describes GPP activity mode per pin.
  66833. +*
  66834. +*******************************************************************************/
  66835. +MV_U32 mvGppValueGet(MV_U32 group, MV_U32 mask)
  66836. +{
  66837. + MV_U32 gppData;
  66838. +
  66839. + gppData = MV_REG_READ(GPP_DATA_IN_REG(group));
  66840. +
  66841. + gppData &= mask;
  66842. +
  66843. + return gppData;
  66844. +
  66845. +}
  66846. +
  66847. +/*******************************************************************************
  66848. +* mvGppValueSet - Set a GPP Pin list value.
  66849. +*
  66850. +* DESCRIPTION:
  66851. +* This function set value for given GPP pin list.
  66852. +*
  66853. +* INPUT:
  66854. +* group - GPP group number
  66855. +* mask - 32bit mask value. Each set bit in the mask means that the
  66856. +* value of corresponding GPP will be set accordingly. Other GPP
  66857. +* are not affected.
  66858. +* value - 32bit value that describes GPP value per pin.
  66859. +*
  66860. +* OUTPUT:
  66861. +* None.
  66862. +*
  66863. +* EXAMPLE:
  66864. +* Set GPP8 value of '0' and GPP15 value of '1'.
  66865. +* mvGppActiveSet(0, (GPP8 | GPP15), ((0 & GPP8) | (GPP15)) );
  66866. +*
  66867. +* RETURN:
  66868. +* None.
  66869. +*
  66870. +*******************************************************************************/
  66871. +MV_STATUS mvGppValueSet (MV_U32 group, MV_U32 mask, MV_U32 value)
  66872. +{
  66873. + MV_U32 outEnable, tmp;
  66874. + MV_U32 i;
  66875. +
  66876. + if (group >= MV_GPP_MAX_GROUP)
  66877. + {
  66878. + DB(mvOsPrintf("mvGppValueSet: Error invalid group number \n"));
  66879. + return MV_BAD_PARAM;
  66880. + }
  66881. +
  66882. + /* verify that the gpp pin is configured as output */
  66883. + /* Note that in the register out enabled -> bit = '0'. */
  66884. + outEnable = ~MV_REG_READ(GPP_DATA_OUT_EN_REG(group));
  66885. +
  66886. + /* Workaround for Erratum FE-MISC-70*/
  66887. + if(mvCtrlRevGet()==MV_88F6XXX_A0_REV && (group == 1))
  66888. + {
  66889. + tmp = ~MV_REG_READ(GPP_DATA_OUT_EN_REG(0));
  66890. + outEnable &= 0xfffffffd;
  66891. + outEnable |= (tmp & 0x2);
  66892. + } /*End of WA*/
  66893. +
  66894. + for (i = 0 ; i < 32 ;i++)
  66895. + {
  66896. + if (((mask & (1 << i)) & (outEnable & (1 << i))) != (mask & (1 << i)))
  66897. + {
  66898. + mvOsPrintf("mvGppValueSet: Err. An attempt to set output "\
  66899. + "value to GPP %d in input mode.\n", i);
  66900. + return MV_ERROR;
  66901. + }
  66902. + }
  66903. +
  66904. + gppRegSet(group, GPP_DATA_OUT_REG(group), mask, value);
  66905. +
  66906. + return MV_OK;
  66907. +
  66908. +}
  66909. +/*******************************************************************************
  66910. +* gppRegSet - Set a specific GPP pin on a specific GPP register
  66911. +*
  66912. +* DESCRIPTION:
  66913. +* This function set a specific GPP pin on a specific GPP register
  66914. +*
  66915. +* INPUT:
  66916. +* regOffs - GPP Register offset
  66917. +* group - GPP group number
  66918. +* mask - 32bit mask value. Each set bit in the mask means that the
  66919. +* value of corresponding GPP will be set accordingly. Other GPP
  66920. +* are not affected.
  66921. +* value - 32bit value that describes GPP value per pin.
  66922. +*
  66923. +* OUTPUT:
  66924. +* None.
  66925. +*
  66926. +* EXAMPLE:
  66927. +* Set GPP8 value of '0' and GPP15 value of '1'.
  66928. +* mvGppActiveSet(0, (GPP8 | GPP15), ((0 & GPP8) | (1 & GPP15)) );
  66929. +*
  66930. +* RETURN:
  66931. +* None.
  66932. +*
  66933. +*******************************************************************************/
  66934. +static MV_VOID gppRegSet (MV_U32 group, MV_U32 regOffs,MV_U32 mask,MV_U32 value)
  66935. +{
  66936. + MV_U32 gppData;
  66937. +
  66938. + gppData = MV_REG_READ(regOffs);
  66939. +
  66940. + gppData &= ~mask;
  66941. +
  66942. + gppData |= (value & mask);
  66943. +
  66944. + MV_REG_WRITE(regOffs, gppData);
  66945. +}
  66946. +
  66947. +
  66948. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h
  66949. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h 1970-01-01 01:00:00.000000000 +0100
  66950. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h 2010-08-05 22:02:24.834868352 +0200
  66951. @@ -0,0 +1,118 @@
  66952. +/*******************************************************************************
  66953. +Copyright (C) Marvell International Ltd. and its affiliates
  66954. +
  66955. +This software file (the "File") is owned and distributed by Marvell
  66956. +International Ltd. and/or its affiliates ("Marvell") under the following
  66957. +alternative licensing terms. Once you have made an election to distribute the
  66958. +File under one of the following license alternatives, please (i) delete this
  66959. +introductory statement regarding license alternatives, (ii) delete the two
  66960. +license alternatives that you have not elected to use and (iii) preserve the
  66961. +Marvell copyright notice above.
  66962. +
  66963. +********************************************************************************
  66964. +Marvell Commercial License Option
  66965. +
  66966. +If you received this File from Marvell and you have entered into a commercial
  66967. +license agreement (a "Commercial License") with Marvell, the File is licensed
  66968. +to you under the terms of the applicable Commercial License.
  66969. +
  66970. +********************************************************************************
  66971. +Marvell GPL License Option
  66972. +
  66973. +If you received this File from Marvell, you may opt to use, redistribute and/or
  66974. +modify this File in accordance with the terms and conditions of the General
  66975. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  66976. +available along with the File in the license.txt file or by writing to the Free
  66977. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  66978. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  66979. +
  66980. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  66981. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  66982. +DISCLAIMED. The GPL License provides additional details about this warranty
  66983. +disclaimer.
  66984. +********************************************************************************
  66985. +Marvell BSD License Option
  66986. +
  66987. +If you received this File from Marvell, you may opt to use, redistribute and/or
  66988. +modify this File under the following licensing terms.
  66989. +Redistribution and use in source and binary forms, with or without modification,
  66990. +are permitted provided that the following conditions are met:
  66991. +
  66992. + * Redistributions of source code must retain the above copyright notice,
  66993. + this list of conditions and the following disclaimer.
  66994. +
  66995. + * Redistributions in binary form must reproduce the above copyright
  66996. + notice, this list of conditions and the following disclaimer in the
  66997. + documentation and/or other materials provided with the distribution.
  66998. +
  66999. + * Neither the name of Marvell nor the names of its contributors may be
  67000. + used to endorse or promote products derived from this software without
  67001. + specific prior written permission.
  67002. +
  67003. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  67004. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  67005. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  67006. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  67007. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  67008. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  67009. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  67010. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  67011. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  67012. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  67013. +
  67014. +*******************************************************************************/
  67015. +
  67016. +#ifndef __INCmvGppH
  67017. +#define __INCmvGppH
  67018. +
  67019. +#include "mvCommon.h"
  67020. +#include "mvOs.h"
  67021. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  67022. +#include "gpp/mvGppRegs.h"
  67023. +
  67024. +/* These macros describes the GPP type. Each of the GPPs pins can */
  67025. +/* be assigned to act as a general purpose input or output pin. */
  67026. +#define MV_GPP_IN 0xFFFFFFFF /* GPP input */
  67027. +#define MV_GPP_OUT 0 /* GPP output */
  67028. +
  67029. +
  67030. +/* These macros describes the GPP Out Enable. */
  67031. +#define MV_GPP_OUT_DIS 0xFFFFFFFF /* Out pin disabled*/
  67032. +#define MV_GPP_OUT_EN 0 /* Out pin enabled*/
  67033. +
  67034. +/* These macros describes the GPP Out Blinking. */
  67035. +/* When set and the corresponding bit in GPIO Data Out Enable Control */
  67036. +/* Register is enabled, the GPIO pin blinks every ~100 ms (a period of */
  67037. +/* 2^24 TCLK clocks). */
  67038. +#define MV_GPP_OUT_BLINK 0xFFFFFFFF /* Out pin blinking*/
  67039. +#define MV_GPP_OUT_STATIC 0 /* Out pin static*/
  67040. +
  67041. +
  67042. +/* These macros describes the GPP Polarity. */
  67043. +/* When set to 1 GPIO Data In Register reflects the inverted value of the */
  67044. +/* corresponding pin. */
  67045. +
  67046. +#define MV_GPP_IN_INVERT 0xFFFFFFFF /* Inverted value is got*/
  67047. +#define MV_GPP_IN_ORIGIN 0 /* original value is got*/
  67048. +
  67049. +/* mvGppTypeSet - Set PP pin mode (IN or OUT) */
  67050. +MV_STATUS mvGppTypeSet(MV_U32 group, MV_U32 mask, MV_U32 value);
  67051. +
  67052. +/* mvGppBlinkEn - Set a GPP (IN) Pin list to blink every ~100ms */
  67053. +MV_STATUS mvGppBlinkEn(MV_U32 group, MV_U32 mask, MV_U32 value);
  67054. +
  67055. +/* mvGppPolaritySet - Set a GPP (IN) Pin list Polarity mode. */
  67056. +MV_STATUS mvGppPolaritySet(MV_U32 group, MV_U32 mask, MV_U32 value);
  67057. +
  67058. +/* mvGppPolarityGet - Get the Polarity of a GPP Pin */
  67059. +MV_U32 mvGppPolarityGet(MV_U32 group, MV_U32 mask);
  67060. +
  67061. +/* mvGppValueGet - Get a GPP Pin list value.*/
  67062. +MV_U32 mvGppValueGet(MV_U32 group, MV_U32 mask);
  67063. +
  67064. +
  67065. +/* mvGppValueSet - Set a GPP Pin list value. */
  67066. +MV_STATUS mvGppValueSet (MV_U32 group, MV_U32 mask, MV_U32 value);
  67067. +
  67068. +#endif /* #ifndef __INCmvGppH */
  67069. +
  67070. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h
  67071. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h 1970-01-01 01:00:00.000000000 +0100
  67072. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h 2010-08-05 22:02:24.874868174 +0200
  67073. @@ -0,0 +1,116 @@
  67074. +/*******************************************************************************
  67075. +Copyright (C) Marvell International Ltd. and its affiliates
  67076. +
  67077. +This software file (the "File") is owned and distributed by Marvell
  67078. +International Ltd. and/or its affiliates ("Marvell") under the following
  67079. +alternative licensing terms. Once you have made an election to distribute the
  67080. +File under one of the following license alternatives, please (i) delete this
  67081. +introductory statement regarding license alternatives, (ii) delete the two
  67082. +license alternatives that you have not elected to use and (iii) preserve the
  67083. +Marvell copyright notice above.
  67084. +
  67085. +********************************************************************************
  67086. +Marvell Commercial License Option
  67087. +
  67088. +If you received this File from Marvell and you have entered into a commercial
  67089. +license agreement (a "Commercial License") with Marvell, the File is licensed
  67090. +to you under the terms of the applicable Commercial License.
  67091. +
  67092. +********************************************************************************
  67093. +Marvell GPL License Option
  67094. +
  67095. +If you received this File from Marvell, you may opt to use, redistribute and/or
  67096. +modify this File in accordance with the terms and conditions of the General
  67097. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  67098. +available along with the File in the license.txt file or by writing to the Free
  67099. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  67100. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  67101. +
  67102. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  67103. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  67104. +DISCLAIMED. The GPL License provides additional details about this warranty
  67105. +disclaimer.
  67106. +********************************************************************************
  67107. +Marvell BSD License Option
  67108. +
  67109. +If you received this File from Marvell, you may opt to use, redistribute and/or
  67110. +modify this File under the following licensing terms.
  67111. +Redistribution and use in source and binary forms, with or without modification,
  67112. +are permitted provided that the following conditions are met:
  67113. +
  67114. + * Redistributions of source code must retain the above copyright notice,
  67115. + this list of conditions and the following disclaimer.
  67116. +
  67117. + * Redistributions in binary form must reproduce the above copyright
  67118. + notice, this list of conditions and the following disclaimer in the
  67119. + documentation and/or other materials provided with the distribution.
  67120. +
  67121. + * Neither the name of Marvell nor the names of its contributors may be
  67122. + used to endorse or promote products derived from this software without
  67123. + specific prior written permission.
  67124. +
  67125. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  67126. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  67127. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  67128. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  67129. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  67130. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  67131. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  67132. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  67133. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  67134. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  67135. +
  67136. +*******************************************************************************/
  67137. +
  67138. +#ifndef __INCmvGppRegsH
  67139. +#define __INCmvGppRegsH
  67140. +
  67141. +#define MV_GPP0 BIT0
  67142. +#define MV_GPP1 BIT1
  67143. +#define MV_GPP2 BIT2
  67144. +#define MV_GPP3 BIT3
  67145. +#define MV_GPP4 BIT4
  67146. +#define MV_GPP5 BIT5
  67147. +#define MV_GPP6 BIT6
  67148. +#define MV_GPP7 BIT7
  67149. +#define MV_GPP8 BIT8
  67150. +#define MV_GPP9 BIT9
  67151. +#define MV_GPP10 BIT10
  67152. +#define MV_GPP11 BIT11
  67153. +#define MV_GPP12 BIT12
  67154. +#define MV_GPP13 BIT13
  67155. +#define MV_GPP14 BIT14
  67156. +#define MV_GPP15 BIT15
  67157. +#define MV_GPP16 BIT16
  67158. +#define MV_GPP17 BIT17
  67159. +#define MV_GPP18 BIT18
  67160. +#define MV_GPP19 BIT19
  67161. +#define MV_GPP20 BIT20
  67162. +#define MV_GPP21 BIT21
  67163. +#define MV_GPP22 BIT22
  67164. +#define MV_GPP23 BIT23
  67165. +#define MV_GPP24 BIT24
  67166. +#define MV_GPP25 BIT25
  67167. +#define MV_GPP26 BIT26
  67168. +#define MV_GPP27 BIT27
  67169. +#define MV_GPP28 BIT28
  67170. +#define MV_GPP29 BIT29
  67171. +#define MV_GPP30 BIT30
  67172. +#define MV_GPP31 BIT31
  67173. +
  67174. +
  67175. +/* registers offsets */
  67176. +
  67177. +#define GPP_DATA_OUT_REG(grp) ((grp == 0) ? 0x10100 : 0x10140)
  67178. +#define GPP_DATA_OUT_EN_REG(grp) ((grp == 0) ? 0x10104 : 0x10144)
  67179. +#define GPP_BLINK_EN_REG(grp) ((grp == 0) ? 0x10108 : 0x10148)
  67180. +#define GPP_DATA_IN_POL_REG(grp) ((grp == 0) ? 0x1010C : 0x1014c)
  67181. +#define GPP_DATA_IN_REG(grp) ((grp == 0) ? 0x10110 : 0x10150)
  67182. +#define GPP_INT_CAUSE_REG(grp) ((grp == 0) ? 0x10114 : 0x10154)
  67183. +#define GPP_INT_MASK_REG(grp) ((grp == 0) ? 0x10118 : 0x10158)
  67184. +#define GPP_INT_LVL_REG(grp) ((grp == 0) ? 0x1011c : 0x1015c)
  67185. +
  67186. +#define GPP_DATA_OUT_SET_REG 0x10120
  67187. +#define GPP_DATA_OUT_CLEAR_REG 0x10124
  67188. +
  67189. +#endif /* #ifndef __INCmvGppRegsH */
  67190. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c
  67191. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c 1970-01-01 01:00:00.000000000 +0100
  67192. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c 2010-08-05 22:02:24.904868011 +0200
  67193. @@ -0,0 +1,1047 @@
  67194. +/*******************************************************************************
  67195. +Copyright (C) Marvell International Ltd. and its affiliates
  67196. +
  67197. +This software file (the "File") is owned and distributed by Marvell
  67198. +International Ltd. and/or its affiliates ("Marvell") under the following
  67199. +alternative licensing terms. Once you have made an election to distribute the
  67200. +File under one of the following license alternatives, please (i) delete this
  67201. +introductory statement regarding license alternatives, (ii) delete the two
  67202. +license alternatives that you have not elected to use and (iii) preserve the
  67203. +Marvell copyright notice above.
  67204. +
  67205. +********************************************************************************
  67206. +Marvell Commercial License Option
  67207. +
  67208. +If you received this File from Marvell and you have entered into a commercial
  67209. +license agreement (a "Commercial License") with Marvell, the File is licensed
  67210. +to you under the terms of the applicable Commercial License.
  67211. +
  67212. +********************************************************************************
  67213. +Marvell GPL License Option
  67214. +
  67215. +If you received this File from Marvell, you may opt to use, redistribute and/or
  67216. +modify this File in accordance with the terms and conditions of the General
  67217. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  67218. +available along with the File in the license.txt file or by writing to the Free
  67219. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  67220. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  67221. +
  67222. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  67223. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  67224. +DISCLAIMED. The GPL License provides additional details about this warranty
  67225. +disclaimer.
  67226. +********************************************************************************
  67227. +Marvell BSD License Option
  67228. +
  67229. +If you received this File from Marvell, you may opt to use, redistribute and/or
  67230. +modify this File under the following licensing terms.
  67231. +Redistribution and use in source and binary forms, with or without modification,
  67232. +are permitted provided that the following conditions are met:
  67233. +
  67234. + * Redistributions of source code must retain the above copyright notice,
  67235. + this list of conditions and the following disclaimer.
  67236. +
  67237. + * Redistributions in binary form must reproduce the above copyright
  67238. + notice, this list of conditions and the following disclaimer in the
  67239. + documentation and/or other materials provided with the distribution.
  67240. +
  67241. + * Neither the name of Marvell nor the names of its contributors may be
  67242. + used to endorse or promote products derived from this software without
  67243. + specific prior written permission.
  67244. +
  67245. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  67246. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  67247. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  67248. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  67249. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  67250. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  67251. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  67252. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  67253. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  67254. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  67255. +
  67256. +*******************************************************************************/
  67257. +#include "pci/mvPci.h"
  67258. +
  67259. +#include "ctrlEnv/mvCtrlEnvLib.h"
  67260. +
  67261. +/* defines */
  67262. +#ifdef MV_DEBUG
  67263. + #define DB(x) x
  67264. +#else
  67265. + #define DB(x)
  67266. +#endif
  67267. +
  67268. +
  67269. +
  67270. +MV_VOID mvPciHalInit(MV_U32 pciIf, MV_PCI_MOD pciIfmod)
  67271. +{
  67272. + if (MV_PCI_MOD_HOST == pciIfmod)
  67273. + {
  67274. +
  67275. + mvPciLocalBusNumSet(pciIf, PCI_HOST_BUS_NUM(pciIf));
  67276. + mvPciLocalDevNumSet(pciIf, PCI_HOST_DEV_NUM(pciIf));
  67277. +
  67278. + /* Local device master Enable */
  67279. + mvPciMasterEnable(pciIf, MV_TRUE);
  67280. +
  67281. + /* Local device slave Enable */
  67282. + mvPciSlaveEnable(pciIf, mvPciLocalBusNumGet(pciIf),
  67283. + mvPciLocalDevNumGet(pciIf), MV_TRUE);
  67284. + }
  67285. + /* enable CPU-2-PCI ordering */
  67286. + MV_REG_BIT_SET(PCI_CMD_REG(0), PCR_CPU_TO_PCI_ORDER_EN);
  67287. +}
  67288. +
  67289. +/*******************************************************************************
  67290. +* mvPciCommandSet - Set PCI comman register value.
  67291. +*
  67292. +* DESCRIPTION:
  67293. +* This function sets a given PCI interface with its command register
  67294. +* value.
  67295. +*
  67296. +* INPUT:
  67297. +* pciIf - PCI interface number.
  67298. +* command - 32bit value to be written to comamnd register.
  67299. +*
  67300. +* OUTPUT:
  67301. +* None.
  67302. +*
  67303. +* RETURN:
  67304. +* MV_BAD_PARAM if pciIf is not in range otherwise MV_OK
  67305. +*
  67306. +*******************************************************************************/
  67307. +MV_STATUS mvPciCommandSet(MV_U32 pciIf, MV_U32 command)
  67308. +{
  67309. + MV_U32 locBusNum, locDevNum, regVal;
  67310. +
  67311. + locBusNum = mvPciLocalBusNumGet(pciIf);
  67312. + locDevNum = mvPciLocalDevNumGet(pciIf);
  67313. +
  67314. + /* Parameter checking */
  67315. + if (pciIf >= mvCtrlPciMaxIfGet())
  67316. + {
  67317. + mvOsPrintf("mvPciCommandSet: ERR. Invalid PCI IF num %d\n", pciIf);
  67318. + return MV_BAD_PARAM;
  67319. + }
  67320. +
  67321. + /* Set command register */
  67322. + MV_REG_WRITE(PCI_CMD_REG(pciIf), command);
  67323. +
  67324. + /* Upodate device max outstanding split tarnsaction */
  67325. + if ((command & PCR_CPU_TO_PCI_ORDER_EN) &&
  67326. + (command & PCR_PCI_TO_CPU_ORDER_EN))
  67327. + {
  67328. + /* Read PCI-X command register */
  67329. + regVal = mvPciConfigRead (pciIf, locBusNum, locDevNum, 0, PCIX_COMMAND);
  67330. +
  67331. + /* clear bits 22:20 */
  67332. + regVal &= 0xff8fffff;
  67333. +
  67334. + /* set reset value */
  67335. + regVal |= (0x3 << 20);
  67336. +
  67337. + /* Write back the value */
  67338. + mvPciConfigWrite (pciIf, locBusNum, locDevNum, 0, PCIX_COMMAND, regVal);
  67339. + }
  67340. +
  67341. + return MV_OK;
  67342. +
  67343. +
  67344. +}
  67345. +
  67346. +
  67347. +/*******************************************************************************
  67348. +* mvPciModeGet - Get PCI interface mode.
  67349. +*
  67350. +* DESCRIPTION:
  67351. +* This function returns the given PCI interface mode.
  67352. +*
  67353. +* INPUT:
  67354. +* pciIf - PCI interface number.
  67355. +*
  67356. +* OUTPUT:
  67357. +* pPciMode - Pointer to PCI mode structure.
  67358. +*
  67359. +* RETURN:
  67360. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  67361. +*
  67362. +*******************************************************************************/
  67363. +MV_STATUS mvPciModeGet(MV_U32 pciIf, MV_PCI_MODE *pPciMode)
  67364. +{
  67365. + MV_U32 pciMode;
  67366. +
  67367. + /* Parameter checking */
  67368. + if (pciIf >= mvCtrlPciMaxIfGet())
  67369. + {
  67370. + mvOsPrintf("mvPciModeGet: ERR. Invalid PCI interface %d\n", pciIf);
  67371. + return MV_BAD_PARAM;
  67372. + }
  67373. + if (NULL == pPciMode)
  67374. + {
  67375. + mvOsPrintf("mvPciModeGet: ERR. pPciMode = NULL \n");
  67376. + return MV_BAD_PARAM;
  67377. + }
  67378. +
  67379. + /* Read pci mode register */
  67380. + pciMode = MV_REG_READ(PCI_MODE_REG(pciIf));
  67381. +
  67382. + switch (pciMode & PMR_PCI_MODE_MASK)
  67383. + {
  67384. + case PMR_PCI_MODE_CONV:
  67385. + pPciMode->pciType = MV_PCI_CONV;
  67386. +
  67387. + if (MV_REG_READ(PCI_DLL_CTRL_REG(pciIf)) & PDC_DLL_EN)
  67388. + {
  67389. + pPciMode->pciSpeed = 66000000; /* 66MHZ */
  67390. + }
  67391. + else
  67392. + {
  67393. + pPciMode->pciSpeed = 33000000; /* 33MHZ */
  67394. + }
  67395. +
  67396. + break;
  67397. +
  67398. + case PMR_PCI_MODE_PCIX_66MHZ:
  67399. + pPciMode->pciType = MV_PCIX;
  67400. + pPciMode->pciSpeed = 66000000; /* 66MHZ */
  67401. + break;
  67402. +
  67403. + case PMR_PCI_MODE_PCIX_100MHZ:
  67404. + pPciMode->pciType = MV_PCIX;
  67405. + pPciMode->pciSpeed = 100000000; /* 100MHZ */
  67406. + break;
  67407. +
  67408. + case PMR_PCI_MODE_PCIX_133MHZ:
  67409. + pPciMode->pciType = MV_PCIX;
  67410. + pPciMode->pciSpeed = 133000000; /* 133MHZ */
  67411. + break;
  67412. +
  67413. + default:
  67414. + {
  67415. + mvOsPrintf("mvPciModeGet: ERR. Non existing mode !!\n");
  67416. + return MV_ERROR;
  67417. + }
  67418. + }
  67419. +
  67420. + switch (pciMode & PMR_PCI_64_MASK)
  67421. + {
  67422. + case PMR_PCI_64_64BIT:
  67423. + pPciMode->pciWidth = MV_PCI_64;
  67424. + break;
  67425. +
  67426. + case PMR_PCI_64_32BIT:
  67427. + pPciMode->pciWidth = MV_PCI_32;
  67428. + break;
  67429. +
  67430. + default:
  67431. + {
  67432. + mvOsPrintf("mvPciModeGet: ERR. Non existing mode !!\n");
  67433. + return MV_ERROR;
  67434. + }
  67435. + }
  67436. +
  67437. + return MV_OK;
  67438. +}
  67439. +
  67440. +/*******************************************************************************
  67441. +* mvPciRetrySet - Set PCI retry counters
  67442. +*
  67443. +* DESCRIPTION:
  67444. +* This function specifies the number of times the PCI controller
  67445. +* retries a transaction before it quits.
  67446. +* Applies to the PCI Master when acting as a requester.
  67447. +* Applies to the PCI slave when acting as a completer (PCI-X mode).
  67448. +* A 0x00 value means a "retry forever".
  67449. +*
  67450. +* INPUT:
  67451. +* pciIf - PCI interface number.
  67452. +* counter - Number of times PCI controller retry. Use counter value
  67453. +* up to PRR_RETRY_CNTR_MAX.
  67454. +*
  67455. +* OUTPUT:
  67456. +* None.
  67457. +*
  67458. +* RETURN:
  67459. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  67460. +*
  67461. +*******************************************************************************/
  67462. +MV_STATUS mvPciRetrySet(MV_U32 pciIf, MV_U32 counter)
  67463. +{
  67464. + MV_U32 pciRetry;
  67465. +
  67466. + /* Parameter checking */
  67467. + if (pciIf >= mvCtrlPciMaxIfGet())
  67468. + {
  67469. + mvOsPrintf("mvPciRetrySet: ERR. Invalid PCI interface %d\n", pciIf);
  67470. + return MV_BAD_PARAM;
  67471. + }
  67472. +
  67473. + if (counter >= PRR_RETRY_CNTR_MAX)
  67474. + {
  67475. + mvOsPrintf("mvPciRetrySet: ERR. Invalid counter: %d\n", counter);
  67476. + return MV_BAD_PARAM;
  67477. +
  67478. + }
  67479. +
  67480. + /* Reading PCI retry register */
  67481. + pciRetry = MV_REG_READ(PCI_RETRY_REG(pciIf));
  67482. +
  67483. + pciRetry &= ~PRR_RETRY_CNTR_MASK;
  67484. +
  67485. + pciRetry |= (counter << PRR_RETRY_CNTR_OFFS);
  67486. +
  67487. + /* write new value */
  67488. + MV_REG_WRITE(PCI_RETRY_REG(pciIf), pciRetry);
  67489. +
  67490. + return MV_OK;
  67491. +}
  67492. +
  67493. +
  67494. +/*******************************************************************************
  67495. +* mvPciDiscardTimerSet - Set PCI discard timer
  67496. +*
  67497. +* DESCRIPTION:
  67498. +* This function set PCI discard timer.
  67499. +* In conventional PCI mode:
  67500. +* Specifies the number of PCLK cycles the PCI slave keeps a non-accessed
  67501. +* read buffers (non-completed delayed read) before invalidate the buffer.
  67502. +* Set to '0' to disable the timer. The PCI slave waits for delayed
  67503. +* read completion forever.
  67504. +* In PCI-X mode:
  67505. +* Specifies the number of PCLK cycles the PCI master waits for split
  67506. +* completion transaction, before it invalidates the pre-allocated read
  67507. +* buffer.
  67508. +* Set to '0' to disable the timer. The PCI master waits for split
  67509. +* completion forever.
  67510. +* NOTE: Must be set to a number greater than MV_PCI_MAX_DISCARD_CLK,
  67511. +* unless using the "wait for ever" setting 0x0.
  67512. +* NOTE: Must not be updated while there are pending read requests.
  67513. +*
  67514. +* INPUT:
  67515. +* pciIf - PCI interface number.
  67516. +* pClkCycles - Number of PCI clock cycles.
  67517. +*
  67518. +* OUTPUT:
  67519. +* None.
  67520. +*
  67521. +* RETURN:
  67522. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  67523. +*
  67524. +*******************************************************************************/
  67525. +MV_STATUS mvPciDiscardTimerSet(MV_U32 pciIf, MV_U32 pClkCycles)
  67526. +{
  67527. + MV_U32 pciDiscardTimer;
  67528. +
  67529. + /* Parameter checking */
  67530. + if (pciIf >= mvCtrlPciMaxIfGet())
  67531. + {
  67532. + mvOsPrintf("mvPciDiscardTimerSet: ERR. Invalid PCI interface %d\n",
  67533. + pciIf);
  67534. + return MV_BAD_PARAM;
  67535. + }
  67536. +
  67537. + if (pClkCycles >= PDTR_TIMER_MIN)
  67538. + {
  67539. + mvOsPrintf("mvPciDiscardTimerSet: ERR. Invalid Clk value: %d\n",
  67540. + pClkCycles);
  67541. + return MV_BAD_PARAM;
  67542. +
  67543. + }
  67544. +
  67545. + /* Read PCI Discard Timer */
  67546. + pciDiscardTimer = MV_REG_READ(PCI_DISCARD_TIMER_REG(pciIf));
  67547. +
  67548. + pciDiscardTimer &= ~PDTR_TIMER_MASK;
  67549. +
  67550. + pciDiscardTimer |= (pClkCycles << PDTR_TIMER_OFFS);
  67551. +
  67552. + /* Write new value */
  67553. + MV_REG_WRITE(PCI_DISCARD_TIMER_REG(pciIf), pciDiscardTimer);
  67554. +
  67555. + return MV_OK;
  67556. +
  67557. +}
  67558. +
  67559. +/* PCI Arbiter routines */
  67560. +
  67561. +/*******************************************************************************
  67562. +* mvPciArbEnable - PCI arbiter enable/disable
  67563. +*
  67564. +* DESCRIPTION:
  67565. +* This fuction enable/disables a given PCI interface arbiter.
  67566. +* NOTE: Arbiter setting can not be changed while in work. It should only
  67567. +* be set once.
  67568. +* INPUT:
  67569. +* pciIf - PCI interface number.
  67570. +* enable - Enable/disable parameter. If enable = MV_TRUE then enable.
  67571. +*
  67572. +* OUTPUT:
  67573. +* None.
  67574. +*
  67575. +* RETURN:
  67576. +* None.
  67577. +*
  67578. +*******************************************************************************/
  67579. +MV_STATUS mvPciArbEnable(MV_U32 pciIf, MV_BOOL enable)
  67580. +{
  67581. + MV_U32 regVal;
  67582. +
  67583. + /* Parameter checking */
  67584. + if (pciIf >= mvCtrlPciMaxIfGet())
  67585. + {
  67586. + mvOsPrintf("mvPciArbEnable: ERR. Invalid PCI interface %d\n", pciIf);
  67587. + return MV_ERROR;
  67588. + }
  67589. +
  67590. + /* Set PCI Arbiter Control register according to default configuration */
  67591. + regVal = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
  67592. +
  67593. + /* Make sure arbiter disabled before changing its values */
  67594. + MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE);
  67595. +
  67596. + regVal &= ~PCI_ARBITER_CTRL_DEFAULT_MASK;
  67597. +
  67598. + regVal |= PCI_ARBITER_CTRL_DEFAULT; /* Set default configuration */
  67599. +
  67600. + if (MV_TRUE == enable)
  67601. + {
  67602. + regVal |= PACR_ARB_ENABLE;
  67603. + }
  67604. + else
  67605. + {
  67606. + regVal &= ~PACR_ARB_ENABLE;
  67607. + }
  67608. +
  67609. + /* Write to register */
  67610. + MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), regVal);
  67611. +
  67612. + return MV_OK;
  67613. +}
  67614. +
  67615. +
  67616. +/*******************************************************************************
  67617. +* mvPciArbParkDis - Disable arbiter parking on agent
  67618. +*
  67619. +* DESCRIPTION:
  67620. +* This function disables the PCI arbiter from parking on the given agent
  67621. +* list.
  67622. +*
  67623. +* INPUT:
  67624. +* pciIf - PCI interface number.
  67625. +* pciAgentMask - When a bit in the mask is set to '1', parking on
  67626. +* the associated PCI master is disabled. Mask bit
  67627. +* refers to bit 0 - 6. For example disable parking on PCI
  67628. +* agent 3 set pciAgentMask 0x4 (bit 3 is set).
  67629. +*
  67630. +* OUTPUT:
  67631. +* None.
  67632. +*
  67633. +* RETURN:
  67634. +* None.
  67635. +*
  67636. +*******************************************************************************/
  67637. +MV_STATUS mvPciArbParkDis(MV_U32 pciIf, MV_U32 pciAgentMask)
  67638. +{
  67639. + MV_U32 pciArbiterCtrl;
  67640. +
  67641. + /* Parameter checking */
  67642. + if (pciIf >= mvCtrlPciMaxIfGet())
  67643. + {
  67644. + mvOsPrintf("mvPciArbParkDis: ERR. Invalid PCI interface %d\n", pciIf);
  67645. + return MV_ERROR;
  67646. + }
  67647. +
  67648. + /* Reading Arbiter Control register */
  67649. + pciArbiterCtrl = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
  67650. +
  67651. + /* Arbiter must be disabled before changing parking */
  67652. + MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE);
  67653. +
  67654. + /* do the change */
  67655. + pciArbiterCtrl &= ~PACR_PARK_DIS_MASK;
  67656. + pciArbiterCtrl |= (pciAgentMask << PACR_PARK_DIS_OFFS);
  67657. +
  67658. + /* writing new value ( if th earbiter was enabled before the change */
  67659. + /* here it will be reenabled */
  67660. + MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), pciArbiterCtrl);
  67661. +
  67662. + return MV_OK;
  67663. +}
  67664. +
  67665. +
  67666. +/*******************************************************************************
  67667. +* mvPciArbBrokDetectSet - Set PCI arbiter broken detection
  67668. +*
  67669. +* DESCRIPTION:
  67670. +* This function sets the maximum number of cycles that the arbiter
  67671. +* waits for a PCI master to respond to its grant assertion. If a
  67672. +* PCI agent fails to respond within this time, the PCI arbiter aborts
  67673. +* the transaction and performs a new arbitration cycle.
  67674. +* NOTE: Value must be greater than '1' for conventional PCI and
  67675. +* greater than '5' for PCI-X.
  67676. +*
  67677. +* INPUT:
  67678. +* pciIf - PCI interface number.
  67679. +* pClkCycles - Number of PCI clock cycles. If equal to '0' the broken
  67680. +* master detection is disabled.
  67681. +*
  67682. +* OUTPUT:
  67683. +* None.
  67684. +*
  67685. +* RETURN:
  67686. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  67687. +*
  67688. +*******************************************************************************/
  67689. +MV_STATUS mvPciArbBrokDetectSet(MV_U32 pciIf, MV_U32 pClkCycles)
  67690. +{
  67691. + MV_U32 pciArbiterCtrl;
  67692. + MV_U32 pciMode;
  67693. +
  67694. + /* Parameter checking */
  67695. + if (pciIf >= mvCtrlPciMaxIfGet())
  67696. + {
  67697. + mvOsPrintf("mvPciArbBrokDetectSet: ERR. Invalid PCI interface %d\n",
  67698. + pciIf);
  67699. + return MV_BAD_PARAM;
  67700. + }
  67701. +
  67702. + /* Checking PCI mode and if pClkCycles is legal value */
  67703. + pciMode = MV_REG_READ(PCI_MODE_REG(pciIf));
  67704. + pciMode &= PMR_PCI_MODE_MASK;
  67705. +
  67706. + if (PMR_PCI_MODE_CONV == pciMode)
  67707. + {
  67708. + if (pClkCycles < PACR_BROKEN_VAL_CONV_MIN)
  67709. + return MV_ERROR;
  67710. + }
  67711. + else
  67712. + {
  67713. + if (pClkCycles < PACR_BROKEN_VAL_PCIX_MIN)
  67714. + return MV_ERROR;
  67715. + }
  67716. +
  67717. + pClkCycles <<= PACR_BROKEN_VAL_OFFS;
  67718. +
  67719. + /* Reading Arbiter Control register */
  67720. + pciArbiterCtrl = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
  67721. + pciArbiterCtrl &= ~PACR_BROKEN_VAL_MASK;
  67722. + pciArbiterCtrl |= pClkCycles;
  67723. +
  67724. + /* Arbiter must be disabled before changing broken detection */
  67725. + MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE);
  67726. +
  67727. + /* writing new value ( if th earbiter was enabled before the change */
  67728. + /* here it will be reenabled */
  67729. +
  67730. + MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), pciArbiterCtrl);
  67731. +
  67732. + return MV_OK;
  67733. +}
  67734. +
  67735. +/* PCI configuration space read write */
  67736. +
  67737. +/*******************************************************************************
  67738. +* mvPciConfigRead - Read from configuration space
  67739. +*
  67740. +* DESCRIPTION:
  67741. +* This function performs a 32 bit read from PCI configuration space.
  67742. +* It supports both type 0 and type 1 of Configuration Transactions
  67743. +* (local and over bridge). In order to read from local bus segment, use
  67744. +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
  67745. +* will result configuration transaction of type 1 (over bridge).
  67746. +*
  67747. +* INPUT:
  67748. +* pciIf - PCI interface number.
  67749. +* bus - PCI segment bus number.
  67750. +* dev - PCI device number.
  67751. +* func - Function number.
  67752. +* regOffs - Register offset.
  67753. +*
  67754. +* OUTPUT:
  67755. +* None.
  67756. +*
  67757. +* RETURN:
  67758. +* 32bit register data, 0xffffffff on error
  67759. +*
  67760. +*******************************************************************************/
  67761. +MV_U32 mvPciConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  67762. + MV_U32 regOff)
  67763. +{
  67764. + MV_U32 pciData = 0;
  67765. +
  67766. + /* Parameter checking */
  67767. + if (PCI_DEFAULT_IF != pciIf)
  67768. + {
  67769. + if (pciIf >= mvCtrlPciMaxIfGet())
  67770. + {
  67771. + mvOsPrintf("mvPciConfigRead: ERR. Invalid PCI interface %d\n",pciIf);
  67772. + return 0xFFFFFFFF;
  67773. + }
  67774. + }
  67775. +
  67776. + if (dev >= MAX_PCI_DEVICES)
  67777. + {
  67778. + DB(mvOsPrintf("mvPciConfigRead: ERR. device number illigal %d\n", dev));
  67779. + return 0xFFFFFFFF;
  67780. + }
  67781. +
  67782. + if (func >= MAX_PCI_FUNCS)
  67783. + {
  67784. + DB(mvOsPrintf("mvPciConfigRead: ERR. function number illigal %d\n", func));
  67785. + return 0xFFFFFFFF;
  67786. + }
  67787. +
  67788. + if (bus >= MAX_PCI_BUSSES)
  67789. + {
  67790. + DB(mvOsPrintf("mvPciConfigRead: ERR. bus number illigal %d\n", bus));
  67791. + return MV_ERROR;
  67792. + }
  67793. +
  67794. +
  67795. + /* Creating PCI address to be passed */
  67796. + pciData |= (bus << PCAR_BUS_NUM_OFFS);
  67797. + pciData |= (dev << PCAR_DEVICE_NUM_OFFS);
  67798. + pciData |= (func << PCAR_FUNC_NUM_OFFS);
  67799. + pciData |= (regOff & PCAR_REG_NUM_MASK);
  67800. +
  67801. + pciData |= PCAR_CONFIG_EN;
  67802. +
  67803. + /* Write the address to the PCI configuration address register */
  67804. + MV_REG_WRITE(PCI_CONFIG_ADDR_REG(pciIf), pciData);
  67805. +
  67806. + /* In order to let the PCI controller absorbed the address of the read */
  67807. + /* transaction we perform a validity check that the address was written */
  67808. + if(pciData != MV_REG_READ(PCI_CONFIG_ADDR_REG(pciIf)))
  67809. + {
  67810. + return MV_ERROR;
  67811. + }
  67812. + /* Read the Data returned in the PCI Data register */
  67813. + pciData = MV_REG_READ(PCI_CONFIG_DATA_REG(pciIf));
  67814. +
  67815. + return pciData;
  67816. +}
  67817. +
  67818. +/*******************************************************************************
  67819. +* mvPciConfigWrite - Write to configuration space
  67820. +*
  67821. +* DESCRIPTION:
  67822. +* This function performs a 32 bit write to PCI configuration space.
  67823. +* It supports both type 0 and type 1 of Configuration Transactions
  67824. +* (local and over bridge). In order to write to local bus segment, use
  67825. +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
  67826. +* will result configuration transaction of type 1 (over bridge).
  67827. +*
  67828. +* INPUT:
  67829. +* pciIf - PCI interface number.
  67830. +* bus - PCI segment bus number.
  67831. +* dev - PCI device number.
  67832. +* func - Function number.
  67833. +* regOffs - Register offset.
  67834. +* data - 32bit data.
  67835. +*
  67836. +* OUTPUT:
  67837. +* None.
  67838. +*
  67839. +* RETURN:
  67840. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  67841. +*
  67842. +*******************************************************************************/
  67843. +MV_STATUS mvPciConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  67844. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  67845. +{
  67846. + MV_U32 pciData = 0;
  67847. +
  67848. + /* Parameter checking */
  67849. + if (PCI_DEFAULT_IF != pciIf)
  67850. + {
  67851. + if (pciIf >= mvCtrlPciMaxIfGet())
  67852. + {
  67853. + mvOsPrintf("mvPciConfigWrite: ERR. Invalid PCI interface %d\n",
  67854. + pciIf);
  67855. + return 0xFFFFFFFF;
  67856. + }
  67857. + }
  67858. +
  67859. + if (dev >= MAX_PCI_DEVICES)
  67860. + {
  67861. + mvOsPrintf("mvPciConfigWrite: ERR. device number illigal %d\n",dev);
  67862. + return MV_BAD_PARAM;
  67863. + }
  67864. +
  67865. + if (func >= MAX_PCI_FUNCS)
  67866. + {
  67867. + mvOsPrintf("mvPciConfigWrite: ERR. function number illigal %d\n", func);
  67868. + return MV_ERROR;
  67869. + }
  67870. +
  67871. + if (bus >= MAX_PCI_BUSSES)
  67872. + {
  67873. + mvOsPrintf("mvPciConfigWrite: ERR. bus number illigal %d\n", bus);
  67874. + return MV_ERROR;
  67875. + }
  67876. +
  67877. + /* Creating PCI address to be passed */
  67878. + pciData |= (bus << PCAR_BUS_NUM_OFFS);
  67879. + pciData |= (dev << PCAR_DEVICE_NUM_OFFS);
  67880. + pciData |= (func << PCAR_FUNC_NUM_OFFS);
  67881. + pciData |= (regOff & PCAR_REG_NUM_MASK);
  67882. +
  67883. + pciData |= PCAR_CONFIG_EN;
  67884. +
  67885. + /* Write the address to the PCI configuration address register */
  67886. + MV_REG_WRITE(PCI_CONFIG_ADDR_REG(pciIf), pciData);
  67887. +
  67888. + /* In order to let the PCI controller absorbed the address of the read */
  67889. + /* transaction we perform a validity check that the address was written */
  67890. + if(pciData != MV_REG_READ(PCI_CONFIG_ADDR_REG(pciIf)))
  67891. + {
  67892. + return MV_ERROR;
  67893. + }
  67894. +
  67895. + /* Write the Data passed to the PCI Data register */
  67896. + MV_REG_WRITE(PCI_CONFIG_DATA_REG(pciIf), data);
  67897. +
  67898. + return MV_OK;
  67899. +}
  67900. +
  67901. +/*******************************************************************************
  67902. +* mvPciMasterEnable - Enable/disale PCI interface master transactions.
  67903. +*
  67904. +* DESCRIPTION:
  67905. +* This function performs read modified write to PCI command status
  67906. +* (offset 0x4) to set/reset bit 2. After this bit is set, the PCI
  67907. +* master is allowed to gain ownership on the bus, otherwise it is
  67908. +* incapable to do so.
  67909. +*
  67910. +* INPUT:
  67911. +* pciIf - PCI interface number.
  67912. +* enable - Enable/disable parameter.
  67913. +*
  67914. +* OUTPUT:
  67915. +* None.
  67916. +*
  67917. +* RETURN:
  67918. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  67919. +*
  67920. +*******************************************************************************/
  67921. +MV_STATUS mvPciMasterEnable(MV_U32 pciIf, MV_BOOL enable)
  67922. +{
  67923. + MV_U32 pciCommandStatus;
  67924. + MV_U32 RegOffs;
  67925. + MV_U32 localBus;
  67926. + MV_U32 localDev;
  67927. +
  67928. + /* Parameter checking */
  67929. + if (pciIf >= mvCtrlPciMaxIfGet())
  67930. + {
  67931. + mvOsPrintf("mvPciMasterEnable: ERR. Invalid PCI interface %d\n", pciIf);
  67932. + return MV_ERROR;
  67933. + }
  67934. +
  67935. + localBus = mvPciLocalBusNumGet(pciIf);
  67936. + localDev = mvPciLocalDevNumGet(pciIf);
  67937. +
  67938. + RegOffs = PCI_STATUS_AND_COMMAND;
  67939. +
  67940. + pciCommandStatus = mvPciConfigRead(pciIf, localBus, localDev, 0, RegOffs);
  67941. +
  67942. + if (MV_TRUE == enable)
  67943. + {
  67944. + pciCommandStatus |= PSCR_MASTER_EN;
  67945. + }
  67946. + else
  67947. + {
  67948. + pciCommandStatus &= ~PSCR_MASTER_EN;
  67949. + }
  67950. +
  67951. + mvPciConfigWrite(pciIf, localBus, localDev, 0, RegOffs, pciCommandStatus);
  67952. +
  67953. + return MV_OK;
  67954. +}
  67955. +
  67956. +
  67957. +/*******************************************************************************
  67958. +* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.
  67959. +*
  67960. +* DESCRIPTION:
  67961. +* This function performs read modified write to PCI command status
  67962. +* (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
  67963. +* the PCI slave is allowed to respond to PCI IO space access (bit 0)
  67964. +* and PCI memory space access (bit 1).
  67965. +*
  67966. +* INPUT:
  67967. +* pciIf - PCI interface number.
  67968. +* dev - PCI device number.
  67969. +* enable - Enable/disable parameter.
  67970. +*
  67971. +* OUTPUT:
  67972. +* None.
  67973. +*
  67974. +* RETURN:
  67975. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  67976. +*
  67977. +*******************************************************************************/
  67978. +MV_STATUS mvPciSlaveEnable(MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_BOOL enable)
  67979. +{
  67980. + MV_U32 pciCommandStatus;
  67981. + MV_U32 RegOffs;
  67982. +
  67983. + /* Parameter checking */
  67984. + if (pciIf >= mvCtrlPciMaxIfGet())
  67985. + {
  67986. + mvOsPrintf("mvPciSlaveEnable: ERR. Invalid PCI interface %d\n", pciIf);
  67987. + return MV_BAD_PARAM;
  67988. + }
  67989. + if (dev >= MAX_PCI_DEVICES)
  67990. + {
  67991. + mvOsPrintf("mvPciLocalDevNumSet: ERR. device number illigal %d\n", dev);
  67992. + return MV_BAD_PARAM;
  67993. +
  67994. + }
  67995. +
  67996. + RegOffs = PCI_STATUS_AND_COMMAND;
  67997. +
  67998. + pciCommandStatus=mvPciConfigRead(pciIf, bus, dev, 0, RegOffs);
  67999. +
  68000. + if (MV_TRUE == enable)
  68001. + {
  68002. + pciCommandStatus |= (PSCR_IO_EN | PSCR_MEM_EN);
  68003. + }
  68004. + else
  68005. + {
  68006. + pciCommandStatus &= ~(PSCR_IO_EN | PSCR_MEM_EN);
  68007. + }
  68008. +
  68009. + mvPciConfigWrite(pciIf, bus, dev, 0, RegOffs, pciCommandStatus);
  68010. +
  68011. + return MV_OK;
  68012. +}
  68013. +
  68014. +/*******************************************************************************
  68015. +* mvPciLocalBusNumSet - Set PCI interface local bus number.
  68016. +*
  68017. +* DESCRIPTION:
  68018. +* This function sets given PCI interface its local bus number.
  68019. +* Note: In case the PCI interface is PCI-X, the information is read-only.
  68020. +*
  68021. +* INPUT:
  68022. +* pciIf - PCI interface number.
  68023. +* busNum - Bus number.
  68024. +*
  68025. +* OUTPUT:
  68026. +* None.
  68027. +*
  68028. +* RETURN:
  68029. +* MV_NOT_ALLOWED in case PCI interface is PCI-X.
  68030. +* MV_BAD_PARAM on bad parameters ,
  68031. +* otherwise MV_OK
  68032. +*
  68033. +*******************************************************************************/
  68034. +MV_STATUS mvPciLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum)
  68035. +{
  68036. + MV_U32 pciP2PConfig;
  68037. + MV_PCI_MODE pciMode;
  68038. + MV_U32 localBus;
  68039. + MV_U32 localDev;
  68040. +
  68041. +
  68042. + /* Parameter checking */
  68043. + if (pciIf >= mvCtrlPciMaxIfGet())
  68044. + {
  68045. + mvOsPrintf("mvPciLocalBusNumSet: ERR. Invalid PCI interface %d\n",pciIf);
  68046. + return MV_BAD_PARAM;
  68047. + }
  68048. + if (busNum >= MAX_PCI_BUSSES)
  68049. + {
  68050. + mvOsPrintf("mvPciLocalBusNumSet: ERR. bus number illigal %d\n", busNum);
  68051. + return MV_ERROR;
  68052. +
  68053. + }
  68054. +
  68055. + localBus = mvPciLocalBusNumGet(pciIf);
  68056. + localDev = mvPciLocalDevNumGet(pciIf);
  68057. +
  68058. +
  68059. + /* PCI interface mode */
  68060. + mvPciModeGet(pciIf, &pciMode);
  68061. +
  68062. + /* if PCI type is PCI-X then it is not allowed to change the dev number */
  68063. + if (MV_PCIX == pciMode.pciType)
  68064. + {
  68065. + pciP2PConfig = mvPciConfigRead(pciIf, localBus, localDev, 0, PCIX_STATUS );
  68066. +
  68067. + pciP2PConfig &= ~PXS_BN_MASK;
  68068. +
  68069. + pciP2PConfig |= (busNum << PXS_BN_OFFS) & PXS_BN_MASK;
  68070. +
  68071. + mvPciConfigWrite(pciIf, localBus, localDev, 0, PCIX_STATUS,pciP2PConfig );
  68072. +
  68073. + }
  68074. + else
  68075. + {
  68076. + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
  68077. +
  68078. + pciP2PConfig &= ~PPCR_BUS_NUM_MASK;
  68079. +
  68080. + pciP2PConfig |= (busNum << PPCR_BUS_NUM_OFFS) & PPCR_BUS_NUM_MASK;
  68081. +
  68082. + MV_REG_WRITE(PCI_P2P_CONFIG_REG(pciIf), pciP2PConfig);
  68083. +
  68084. + }
  68085. +
  68086. +
  68087. + return MV_OK;
  68088. +}
  68089. +
  68090. +
  68091. +/*******************************************************************************
  68092. +* mvPciLocalBusNumGet - Get PCI interface local bus number.
  68093. +*
  68094. +* DESCRIPTION:
  68095. +* This function gets the local bus number of a given PCI interface.
  68096. +*
  68097. +* INPUT:
  68098. +* pciIf - PCI interface number.
  68099. +*
  68100. +* OUTPUT:
  68101. +* None.
  68102. +*
  68103. +* RETURN:
  68104. +* Local bus number.0xffffffff on Error
  68105. +*
  68106. +*******************************************************************************/
  68107. +MV_U32 mvPciLocalBusNumGet(MV_U32 pciIf)
  68108. +{
  68109. + MV_U32 pciP2PConfig;
  68110. +
  68111. + /* Parameter checking */
  68112. + if (PCI_DEFAULT_IF != pciIf)
  68113. + {
  68114. + if (pciIf >= mvCtrlPciMaxIfGet())
  68115. + {
  68116. + mvOsPrintf("mvPciLocalBusNumGet: ERR. Invalid PCI interface %d\n",
  68117. + pciIf);
  68118. + return 0xFFFFFFFF;
  68119. + }
  68120. + }
  68121. +
  68122. + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
  68123. + pciP2PConfig &= PPCR_BUS_NUM_MASK;
  68124. + return (pciP2PConfig >> PPCR_BUS_NUM_OFFS);
  68125. +}
  68126. +
  68127. +
  68128. +/*******************************************************************************
  68129. +* mvPciLocalDevNumSet - Set PCI interface local device number.
  68130. +*
  68131. +* DESCRIPTION:
  68132. +* This function sets given PCI interface its local device number.
  68133. +* Note: In case the PCI interface is PCI-X, the information is read-only.
  68134. +*
  68135. +* INPUT:
  68136. +* pciIf - PCI interface number.
  68137. +* devNum - Device number.
  68138. +*
  68139. +* OUTPUT:
  68140. +* None.
  68141. +*
  68142. +* RETURN:
  68143. +* MV_NOT_ALLOWED in case PCI interface is PCI-X. MV_BAD_PARAM on bad parameters ,
  68144. +* otherwise MV_OK
  68145. +*
  68146. +*******************************************************************************/
  68147. +MV_STATUS mvPciLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum)
  68148. +{
  68149. + MV_U32 pciP2PConfig;
  68150. + MV_PCI_MODE pciMode;
  68151. + MV_U32 localBus;
  68152. + MV_U32 localDev;
  68153. +
  68154. + /* Parameter checking */
  68155. + if (pciIf >= mvCtrlPciMaxIfGet())
  68156. + {
  68157. + mvOsPrintf("mvPciLocalDevNumSet: ERR. Invalid PCI interface %d\n",pciIf);
  68158. + return MV_BAD_PARAM;
  68159. + }
  68160. + if (devNum >= MAX_PCI_DEVICES)
  68161. + {
  68162. + mvOsPrintf("mvPciLocalDevNumSet: ERR. device number illigal %d\n",
  68163. + devNum);
  68164. + return MV_BAD_PARAM;
  68165. +
  68166. + }
  68167. +
  68168. + localBus = mvPciLocalBusNumGet(pciIf);
  68169. + localDev = mvPciLocalDevNumGet(pciIf);
  68170. +
  68171. + /* PCI interface mode */
  68172. + mvPciModeGet(pciIf, &pciMode);
  68173. +
  68174. + /* if PCI type is PCIX then it is not allowed to change the dev number */
  68175. + if (MV_PCIX == pciMode.pciType)
  68176. + {
  68177. + pciP2PConfig = mvPciConfigRead(pciIf, localBus, localDev, 0, PCIX_STATUS );
  68178. +
  68179. + pciP2PConfig &= ~PXS_DN_MASK;
  68180. +
  68181. + pciP2PConfig |= (devNum << PXS_DN_OFFS) & PXS_DN_MASK;
  68182. +
  68183. + mvPciConfigWrite(pciIf,localBus, localDev, 0, PCIX_STATUS,pciP2PConfig );
  68184. + }
  68185. + else
  68186. + {
  68187. + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
  68188. +
  68189. + pciP2PConfig &= ~PPCR_DEV_NUM_MASK;
  68190. +
  68191. + pciP2PConfig |= (devNum << PPCR_DEV_NUM_OFFS) & PPCR_DEV_NUM_MASK;
  68192. +
  68193. + MV_REG_WRITE(PCI_P2P_CONFIG_REG(pciIf), pciP2PConfig);
  68194. + }
  68195. +
  68196. + return MV_OK;
  68197. +}
  68198. +
  68199. +/*******************************************************************************
  68200. +* mvPciLocalDevNumGet - Get PCI interface local device number.
  68201. +*
  68202. +* DESCRIPTION:
  68203. +* This function gets the local device number of a given PCI interface.
  68204. +*
  68205. +* INPUT:
  68206. +* pciIf - PCI interface number.
  68207. +*
  68208. +* OUTPUT:
  68209. +* None.
  68210. +*
  68211. +* RETURN:
  68212. +* Local device number. 0xffffffff on Error
  68213. +*
  68214. +*******************************************************************************/
  68215. +MV_U32 mvPciLocalDevNumGet(MV_U32 pciIf)
  68216. +{
  68217. + MV_U32 pciP2PConfig;
  68218. +
  68219. + /* Parameter checking */
  68220. +
  68221. + if (PCI_DEFAULT_IF != pciIf)
  68222. + {
  68223. + if (pciIf >= mvCtrlPciMaxIfGet())
  68224. + {
  68225. + mvOsPrintf("mvPciLocalDevNumGet: ERR. Invalid PCI interface %d\n",
  68226. + pciIf);
  68227. + return 0xFFFFFFFF;
  68228. + }
  68229. + }
  68230. +
  68231. + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
  68232. +
  68233. + pciP2PConfig &= PPCR_DEV_NUM_MASK;
  68234. +
  68235. + return (pciP2PConfig >> PPCR_DEV_NUM_OFFS);
  68236. +}
  68237. +
  68238. +
  68239. +
  68240. +
  68241. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h
  68242. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h 1970-01-01 01:00:00.000000000 +0100
  68243. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h 2010-08-05 22:02:24.944868193 +0200
  68244. @@ -0,0 +1,185 @@
  68245. +/*******************************************************************************
  68246. +Copyright (C) Marvell International Ltd. and its affiliates
  68247. +
  68248. +This software file (the "File") is owned and distributed by Marvell
  68249. +International Ltd. and/or its affiliates ("Marvell") under the following
  68250. +alternative licensing terms. Once you have made an election to distribute the
  68251. +File under one of the following license alternatives, please (i) delete this
  68252. +introductory statement regarding license alternatives, (ii) delete the two
  68253. +license alternatives that you have not elected to use and (iii) preserve the
  68254. +Marvell copyright notice above.
  68255. +
  68256. +********************************************************************************
  68257. +Marvell Commercial License Option
  68258. +
  68259. +If you received this File from Marvell and you have entered into a commercial
  68260. +license agreement (a "Commercial License") with Marvell, the File is licensed
  68261. +to you under the terms of the applicable Commercial License.
  68262. +
  68263. +********************************************************************************
  68264. +Marvell GPL License Option
  68265. +
  68266. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68267. +modify this File in accordance with the terms and conditions of the General
  68268. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  68269. +available along with the File in the license.txt file or by writing to the Free
  68270. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  68271. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  68272. +
  68273. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  68274. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  68275. +DISCLAIMED. The GPL License provides additional details about this warranty
  68276. +disclaimer.
  68277. +********************************************************************************
  68278. +Marvell BSD License Option
  68279. +
  68280. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68281. +modify this File under the following licensing terms.
  68282. +Redistribution and use in source and binary forms, with or without modification,
  68283. +are permitted provided that the following conditions are met:
  68284. +
  68285. + * Redistributions of source code must retain the above copyright notice,
  68286. + this list of conditions and the following disclaimer.
  68287. +
  68288. + * Redistributions in binary form must reproduce the above copyright
  68289. + notice, this list of conditions and the following disclaimer in the
  68290. + documentation and/or other materials provided with the distribution.
  68291. +
  68292. + * Neither the name of Marvell nor the names of its contributors may be
  68293. + used to endorse or promote products derived from this software without
  68294. + specific prior written permission.
  68295. +
  68296. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  68297. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  68298. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  68299. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  68300. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  68301. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  68302. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  68303. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  68304. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  68305. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  68306. +
  68307. +*******************************************************************************/
  68308. +
  68309. +
  68310. +#ifndef __INCPCIH
  68311. +#define __INCPCIH
  68312. +
  68313. +#include "mvCommon.h"
  68314. +#include "mvOs.h"
  68315. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  68316. +#include "pci/mvPciRegs.h"
  68317. +
  68318. +
  68319. +/* NOTE not supported in this driver:
  68320. +
  68321. + Built In Self Test (BIST)
  68322. + Vital Product Data (VPD)
  68323. + Message Signaled Interrupt (MSI)
  68324. + Power Management
  68325. + Compact PCI Hot Swap
  68326. + Header retarget
  68327. +
  68328. +Registers not supported:
  68329. +1) PCI DLL Status and Control (PCI0 0x1D20, PCI1 0x1DA0)
  68330. +2) PCI/MPP Pads Calibration (CI0/MPP[31:16] 0x1D1C, PCI1/MPP[15:0] 0X1D9C)
  68331. +*/
  68332. +
  68333. +/* defines */
  68334. +/* The number of supported PCI interfaces depend on Marvell controller */
  68335. +/* device number. This device number ID is located on the PCI unit */
  68336. +/* configuration header. This creates a loop where calling PCI */
  68337. +/* configuration read/write routine results a call to get PCI configuration */
  68338. +/* information etc. This macro defines a default PCI interface. This PCI */
  68339. +/* interface is sure to exist. */
  68340. +#define PCI_DEFAULT_IF 0
  68341. +
  68342. +
  68343. +/* typedefs */
  68344. +/* The Marvell controller supports both conventional PCI and PCI-X. */
  68345. +/* This enumeration describes the PCI type. */
  68346. +typedef enum _mvPciType
  68347. +{
  68348. + MV_PCI_CONV, /* Conventional PCI */
  68349. + MV_PCIX /* PCI-X */
  68350. +}MV_PCI_TYPE;
  68351. +
  68352. +typedef enum _mvPciMod
  68353. +{
  68354. + MV_PCI_MOD_HOST,
  68355. + MV_PCI_MOD_DEVICE
  68356. +}MV_PCI_MOD;
  68357. +
  68358. +
  68359. +/* The Marvell controller supports both PCI width of 32 and 64 bit. */
  68360. +/* This enumerator describes PCI width */
  68361. +typedef enum _mvPciWidth
  68362. +{
  68363. + MV_PCI_32, /* PCI width 32bit */
  68364. + MV_PCI_64 /* PCI width 64bit */
  68365. +}MV_PCI_WIDTH;
  68366. +
  68367. +/* This structure describes the PCI unit configured type, speed and width. */
  68368. +typedef struct _mvPciMode
  68369. +{
  68370. + MV_PCI_TYPE pciType; /* PCI type */
  68371. + MV_U32 pciSpeed; /* Assuming PCI base clock on board is 33MHz */
  68372. + MV_PCI_WIDTH pciWidth; /* PCI bus width */
  68373. +}MV_PCI_MODE;
  68374. +
  68375. +/* mvPciInit - Initialize PCI interfaces*/
  68376. +MV_VOID mvPciHalInit(MV_U32 pciIf, MV_PCI_MOD pciIfmod);
  68377. +
  68378. +/* mvPciCommandSet - Set PCI comman register value.*/
  68379. +MV_STATUS mvPciCommandSet(MV_U32 pciIf, MV_U32 command);
  68380. +
  68381. +/* mvPciModeGet - Get PCI interface mode.*/
  68382. +MV_STATUS mvPciModeGet(MV_U32 pciIf, MV_PCI_MODE *pPciMode);
  68383. +
  68384. +/* mvPciRetrySet - Set PCI retry counters*/
  68385. +MV_STATUS mvPciRetrySet(MV_U32 pciIf, MV_U32 counter);
  68386. +
  68387. +/* mvPciDiscardTimerSet - Set PCI discard timer*/
  68388. +MV_STATUS mvPciDiscardTimerSet(MV_U32 pciIf, MV_U32 pClkCycles);
  68389. +
  68390. +/* mvPciArbEnable - PCI arbiter enable/disable*/
  68391. +MV_STATUS mvPciArbEnable(MV_U32 pciIf, MV_BOOL enable);
  68392. +
  68393. +/* mvPciArbParkDis - Disable arbiter parking on agent */
  68394. +MV_STATUS mvPciArbParkDis(MV_U32 pciIf, MV_U32 pciAgentMask);
  68395. +
  68396. +/* mvPciArbBrokDetectSet - Set PCI arbiter broken detection */
  68397. +MV_STATUS mvPciArbBrokDetectSet(MV_U32 pciIf, MV_U32 pClkCycles);
  68398. +
  68399. +/* mvPciConfigRead - Read from configuration space */
  68400. +MV_U32 mvPciConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  68401. + MV_U32 func,MV_U32 regOff);
  68402. +
  68403. +/* mvPciConfigWrite - Write to configuration space */
  68404. +MV_STATUS mvPciConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  68405. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  68406. +
  68407. +/* mvPciMasterEnable - Enable/disale PCI interface master transactions.*/
  68408. +MV_STATUS mvPciMasterEnable(MV_U32 pciIf, MV_BOOL enable);
  68409. +
  68410. +/* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.*/
  68411. +MV_STATUS mvPciSlaveEnable(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,MV_BOOL enable);
  68412. +
  68413. +/* mvPciLocalBusNumSet - Set PCI interface local bus number.*/
  68414. +MV_STATUS mvPciLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum);
  68415. +
  68416. +/* mvPciLocalBusNumGet - Get PCI interface local bus number.*/
  68417. +MV_U32 mvPciLocalBusNumGet(MV_U32 pciIf);
  68418. +
  68419. +/* mvPciLocalDevNumSet - Set PCI interface local device number.*/
  68420. +MV_STATUS mvPciLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum);
  68421. +
  68422. +/* mvPciLocalDevNumGet - Get PCI interface local device number.*/
  68423. +MV_U32 mvPciLocalDevNumGet(MV_U32 pciIf);
  68424. +
  68425. +
  68426. +#endif /* #ifndef __INCPCIH */
  68427. +
  68428. +
  68429. +
  68430. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h
  68431. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h 1970-01-01 01:00:00.000000000 +0100
  68432. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h 2010-08-05 22:02:24.984868234 +0200
  68433. @@ -0,0 +1,411 @@
  68434. +/*******************************************************************************
  68435. +Copyright (C) Marvell International Ltd. and its affiliates
  68436. +
  68437. +This software file (the "File") is owned and distributed by Marvell
  68438. +International Ltd. and/or its affiliates ("Marvell") under the following
  68439. +alternative licensing terms. Once you have made an election to distribute the
  68440. +File under one of the following license alternatives, please (i) delete this
  68441. +introductory statement regarding license alternatives, (ii) delete the two
  68442. +license alternatives that you have not elected to use and (iii) preserve the
  68443. +Marvell copyright notice above.
  68444. +
  68445. +********************************************************************************
  68446. +Marvell Commercial License Option
  68447. +
  68448. +If you received this File from Marvell and you have entered into a commercial
  68449. +license agreement (a "Commercial License") with Marvell, the File is licensed
  68450. +to you under the terms of the applicable Commercial License.
  68451. +
  68452. +********************************************************************************
  68453. +Marvell GPL License Option
  68454. +
  68455. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68456. +modify this File in accordance with the terms and conditions of the General
  68457. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  68458. +available along with the File in the license.txt file or by writing to the Free
  68459. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  68460. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  68461. +
  68462. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  68463. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  68464. +DISCLAIMED. The GPL License provides additional details about this warranty
  68465. +disclaimer.
  68466. +********************************************************************************
  68467. +Marvell BSD License Option
  68468. +
  68469. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68470. +modify this File under the following licensing terms.
  68471. +Redistribution and use in source and binary forms, with or without modification,
  68472. +are permitted provided that the following conditions are met:
  68473. +
  68474. + * Redistributions of source code must retain the above copyright notice,
  68475. + this list of conditions and the following disclaimer.
  68476. +
  68477. + * Redistributions in binary form must reproduce the above copyright
  68478. + notice, this list of conditions and the following disclaimer in the
  68479. + documentation and/or other materials provided with the distribution.
  68480. +
  68481. + * Neither the name of Marvell nor the names of its contributors may be
  68482. + used to endorse or promote products derived from this software without
  68483. + specific prior written permission.
  68484. +
  68485. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  68486. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  68487. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  68488. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  68489. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  68490. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  68491. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  68492. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  68493. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  68494. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  68495. +
  68496. +*******************************************************************************/
  68497. +
  68498. +#ifndef __INCPCIREGSH
  68499. +#define __INCPCIREGSH
  68500. +
  68501. +
  68502. +#include "pci-if/mvPciIfRegs.h"
  68503. +/* defines */
  68504. +#define MAX_PCI_DEVICES 32
  68505. +#define MAX_PCI_FUNCS 8
  68506. +#define MAX_PCI_BUSSES 128
  68507. +
  68508. +/* enumerators */
  68509. +
  68510. +/* This enumerator described the possible PCI slave targets. */
  68511. +/* PCI slave targets are designated memory/IO address spaces that the */
  68512. +/* PCI slave targets can access. They are also refered as "targets" */
  68513. +/* this enumeratoe order is determined by the content of :
  68514. + PCI_BASE_ADDR_ENABLE_REG */
  68515. +
  68516. +
  68517. +/* registers offsetes defines */
  68518. +
  68519. +
  68520. +
  68521. +/*************************/
  68522. +/* PCI control registers */
  68523. +/*************************/
  68524. +/* maen : should add new registers */
  68525. +#define PCI_CMD_REG(pciIf) (0x30c00 + ((pciIf) * 0x80))
  68526. +#define PCI_MODE_REG(pciIf) (0x30d00 + ((pciIf) * 0x80))
  68527. +#define PCI_RETRY_REG(pciIf) (0x30c04 + ((pciIf) * 0x80))
  68528. +#define PCI_DISCARD_TIMER_REG(pciIf) (0x30d04 + ((pciIf) * 0x80))
  68529. +#define PCI_ARBITER_CTRL_REG(pciIf) (0x31d00 + ((pciIf) * 0x80))
  68530. +#define PCI_P2P_CONFIG_REG(pciIf) (0x31d14 + ((pciIf) * 0x80))
  68531. +#define PCI_ACCESS_CTRL_BASEL_REG(pciIf, targetWin) \
  68532. + (0x31e00 + ((pciIf) * 0x80) + ((targetWin) * 0x10))
  68533. +#define PCI_ACCESS_CTRL_BASEH_REG(pciIf, targetWin) \
  68534. + (0x31e04 + ((pciIf) * 0x80) + ((targetWin) * 0x10))
  68535. +#define PCI_ACCESS_CTRL_SIZE_REG(pciIf, targetWin) \
  68536. + (0x31e08 + ((pciIf) * 0x80) + ((targetWin) * 0x10))
  68537. +
  68538. +#define PCI_DLL_CTRL_REG(pciIf) (0x31d20 + ((pciIf) * 0x80))
  68539. +
  68540. +/* PCI Dll Control (PDC)*/
  68541. +#define PDC_DLL_EN BIT0
  68542. +
  68543. +
  68544. +/* PCI Command Register (PCR) */
  68545. +#define PCR_MASTER_BYTE_SWAP_EN BIT0
  68546. +#define PCR_MASTER_WR_COMBINE_EN BIT4
  68547. +#define PCR_MASTER_RD_COMBINE_EN BIT5
  68548. +#define PCR_MASTER_WR_TRIG_WHOLE BIT6
  68549. +#define PCR_MASTER_RD_TRIG_WHOLE BIT7
  68550. +#define PCR_MASTER_MEM_RD_LINE_EN BIT8
  68551. +#define PCR_MASTER_MEM_RD_MULT_EN BIT9
  68552. +#define PCR_MASTER_WORD_SWAP_EN BIT10
  68553. +#define PCR_SLAVE_WORD_SWAP_EN BIT11
  68554. +#define PCR_NS_ACCORDING_RCV_TRANS BIT14
  68555. +#define PCR_MASTER_PCIX_REQ64N_EN BIT15
  68556. +#define PCR_SLAVE_BYTE_SWAP_EN BIT16
  68557. +#define PCR_MASTER_DAC_EN BIT17
  68558. +#define PCR_MASTER_M64_ALLIGN BIT18
  68559. +#define PCR_ERRORS_PROPAGATION_EN BIT19
  68560. +#define PCR_SLAVE_SWAP_ENABLE BIT20
  68561. +#define PCR_MASTER_SWAP_ENABLE BIT21
  68562. +#define PCR_MASTER_INT_SWAP_EN BIT22
  68563. +#define PCR_LOOP_BACK_ENABLE BIT23
  68564. +#define PCR_SLAVE_INTREG_SWAP_OFFS 24
  68565. +#define PCR_SLAVE_INTREG_SWAP_MASK 0x3
  68566. +#define PCR_SLAVE_INTREG_BYTE_SWAP \
  68567. + (MV_BYTE_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
  68568. +#define PCR_SLAVE_INTREG_NO_SWAP \
  68569. + (MV_NO_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
  68570. +#define PCR_SLAVE_INTREG_BYTE_WORD \
  68571. + (MV_BYTE_WORD_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
  68572. +#define PCR_SLAVE_INTREG_WORD_SWAP \
  68573. + (MV_WORD_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
  68574. +#define PCR_RESET_REASSERTION_EN BIT26
  68575. +#define PCR_PCI_TO_CPU_REG_ORDER_EN BIT28
  68576. +#define PCR_CPU_TO_PCI_ORDER_EN BIT29
  68577. +#define PCR_PCI_TO_CPU_ORDER_EN BIT30
  68578. +
  68579. +/* PCI Mode Register (PMR) */
  68580. +#define PMR_PCI_ID_OFFS 0 /* PCI Interface ID */
  68581. +#define PMR_PCI_ID_MASK (0x1 << PMR_PCI_ID_OFFS)
  68582. +#define PMR_PCI_ID_PCI(pciNum) ((pciNum) << PCI_MODE_PCIID_OFFS)
  68583. +
  68584. +#define PMR_PCI_64_OFFS 2 /* 64-bit PCI Interface */
  68585. +#define PMR_PCI_64_MASK (0x1 << PMR_PCI_64_OFFS)
  68586. +#define PMR_PCI_64_64BIT (0x1 << PMR_PCI_64_OFFS)
  68587. +#define PMR_PCI_64_32BIT (0x0 << PMR_PCI_64_OFFS)
  68588. +
  68589. +#define PMR_PCI_MODE_OFFS 4 /* PCI interface mode of operation */
  68590. +#define PMR_PCI_MODE_MASK (0x3 << PMR_PCI_MODE_OFFS)
  68591. +#define PMR_PCI_MODE_CONV (0x0 << PMR_PCI_MODE_OFFS)
  68592. +#define PMR_PCI_MODE_PCIX_66MHZ (0x1 << PMR_PCI_MODE_OFFS)
  68593. +#define PMR_PCI_MODE_PCIX_100MHZ (0x2 << PMR_PCI_MODE_OFFS)
  68594. +#define PMR_PCI_MODE_PCIX_133MHZ (0x3 << PMR_PCI_MODE_OFFS)
  68595. +
  68596. +#define PMR_EXP_ROM_SUPPORT BIT8 /* Expansion ROM Active */
  68597. +
  68598. +#define PMR_PCI_RESET_OFFS 31 /* PCI Interface Reset Indication */
  68599. +#define PMR_PCI_RESET_MASK (0x1 << PMR_PCI_RESET_OFFS)
  68600. +#define PMR_PCI_RESET_PCIXRST (0x0 << PMR_PCI_RESET_OFFS)
  68601. +
  68602. +
  68603. +/* PCI Retry Register (PRR) */
  68604. +#define PRR_RETRY_CNTR_OFFS 16 /* Retry Counter */
  68605. +#define PRR_RETRY_CNTR_MAX 0xff
  68606. +#define PRR_RETRY_CNTR_MASK (PRR_RETRY_CNTR_MAX << PRR_RETRY_CNTR_OFFS)
  68607. +
  68608. +
  68609. +/* PCI Discard Timer Register (PDTR) */
  68610. +#define PDTR_TIMER_OFFS 0 /* Timer */
  68611. +#define PDTR_TIMER_MAX 0xffff
  68612. +#define PDTR_TIMER_MIN 0x7F
  68613. +#define PDTR_TIMER_MASK (PDTR_TIMER_MAX << PDTR_TIMER_OFFS)
  68614. +
  68615. +
  68616. +/* PCI Arbiter Control Register (PACR) */
  68617. +#define PACR_BROKEN_DETECT_EN BIT1 /* Broken Detection Enable */
  68618. +
  68619. +#define PACR_BROKEN_VAL_OFFS 3 /* Broken Value */
  68620. +#define PACR_BROKEN_VAL_MASK (0xf << PACR_BROKEN_VAL_OFFS)
  68621. +#define PACR_BROKEN_VAL_CONV_MIN 0x2
  68622. +#define PACR_BROKEN_VAL_PCIX_MIN 0x6
  68623. +
  68624. +#define PACR_PARK_DIS_OFFS 14 /* Parking Disable */
  68625. +#define PACR_PARK_DIS_MAX_AGENT 0x3f
  68626. +#define PACR_PARK_DIS_MASK (PACR_PARK_DIS_MAX_AGENT<<PACR_PARK_DIS_OFFS)
  68627. +#define PACR_PARK_DIS(agent) ((1 << (agent)) << PACR_PARK_DIS_OFFS)
  68628. +
  68629. +#define PACR_ARB_ENABLE BIT31 /* Enable Internal Arbiter */
  68630. +
  68631. +
  68632. +/* PCI P2P Configuration Register (PPCR) */
  68633. +#define PPCR_2ND_BUS_L_OFFS 0 /* 2nd PCI Interface Bus Range Lower */
  68634. +#define PPCR_2ND_BUS_L_MASK (0xff << PPCR_2ND_BUS_L_OFFS)
  68635. +
  68636. +#define PPCR_2ND_BUS_H_OFFS 8 /* 2nd PCI Interface Bus Range Upper */
  68637. +#define PPCR_2ND_BUS_H_MASK (0xff << PPCR_2ND_BUS_H_OFFS)
  68638. +
  68639. +#define PPCR_BUS_NUM_OFFS 16 /* The PCI interface's Bus number */
  68640. +#define PPCR_BUS_NUM_MASK (0xff << PPCR_BUS_NUM_OFFS)
  68641. +
  68642. +#define PPCR_DEV_NUM_OFFS 24 /* The PCI interface’s Device number */
  68643. +#define PPCR_DEV_NUM_MASK (0xff << PPCR_DEV_NUM_OFFS)
  68644. +
  68645. +
  68646. +/* PCI Access Control Base Low Register (PACBLR) */
  68647. +#define PACBLR_EN BIT0 /* Access control window enable */
  68648. +
  68649. +#define PACBLR_ACCPROT BIT4 /* Access Protect */
  68650. +#define PACBLR_WRPROT BIT5 /* Write Protect */
  68651. +
  68652. +#define PACBLR_PCISWAP_OFFS 6 /* PCI slave Data Swap Control */
  68653. +#define PACBLR_PCISWAP_MASK (0x3 << PACBLR_PCISWAP_OFFS)
  68654. +#define PACBLR_PCISWAP_BYTE (0x0 << PACBLR_PCISWAP_OFFS)
  68655. +#define PACBLR_PCISWAP_NO_SWAP (0x1 << PACBLR_PCISWAP_OFFS)
  68656. +#define PACBLR_PCISWAP_BYTE_WORD (0x2 << PACBLR_PCISWAP_OFFS)
  68657. +#define PACBLR_PCISWAP_WORD (0x3 << PACBLR_PCISWAP_OFFS)
  68658. +
  68659. +#define PACBLR_RDMBURST_OFFS 8 /* Read Max Burst */
  68660. +#define PACBLR_RDMBURST_MASK (0x3 << PACBLR_RDMBURST_OFFS)
  68661. +#define PACBLR_RDMBURST_32BYTE (0x0 << PACBLR_RDMBURST_OFFS)
  68662. +#define PACBLR_RDMBURST_64BYTE (0x1 << PACBLR_RDMBURST_OFFS)
  68663. +#define PACBLR_RDMBURST_128BYTE (0x2 << PACBLR_RDMBURST_OFFS)
  68664. +
  68665. +#define PACBLR_RDSIZE_OFFS 10 /* Typical PCI read transaction Size. */
  68666. +#define PACBLR_RDSIZE_MASK (0x3 << PACBLR_RDSIZE_OFFS)
  68667. +#define PACBLR_RDSIZE_32BYTE (0x0 << PACBLR_RDSIZE_OFFS)
  68668. +#define PACBLR_RDSIZE_64BYTE (0x1 << PACBLR_RDSIZE_OFFS)
  68669. +#define PACBLR_RDSIZE_128BYTE (0x2 << PACBLR_RDSIZE_OFFS)
  68670. +#define PACBLR_RDSIZE_256BYTE (0x3 << PACBLR_RDSIZE_OFFS)
  68671. +
  68672. +#define PACBLR_BASE_L_OFFS 12 /* Corresponds to address bits [31:12] */
  68673. +#define PACBLR_BASE_L_MASK (0xfffff << PACBLR_BASE_L_OFFS)
  68674. +#define PACBLR_BASE_L_ALIGNMENT (1 << PACBLR_BASE_L_OFFS)
  68675. +#define PACBLR_BASE_ALIGN_UP(base) \
  68676. + ((base+PACBLR_BASE_L_ALIGNMENT)&PACBLR_BASE_L_MASK)
  68677. +#define PACBLR_BASE_ALIGN_DOWN(base) (base & PACBLR_BASE_L_MASK)
  68678. +
  68679. +
  68680. +/* PCI Access Control Base High Register (PACBHR) */
  68681. +#define PACBHR_BASE_H_OFFS 0 /* Corresponds to address bits [63:32] */
  68682. +#define PACBHR_CTRL_BASE_H_MASK (0xffffffff << PACBHR_BASE_H_OFFS)
  68683. +
  68684. +/* PCI Access Control Size Register (PACSR) */
  68685. +#define PACSR_WRMBURST_OFFS 8 /* Write Max Burst */
  68686. +#define PACSR_WRMBURST_MASK (0x3 << PACSR_WRMBURST_OFFS)
  68687. +#define PACSR_WRMBURST_32BYTE (0x0 << PACSR_WRMBURST_OFFS)
  68688. +#define PACSR_WRMBURST_64BYTE (0x1 << PACSR_WRMBURST_OFFS)
  68689. +#define PACSR_WRMBURST_128BYTE (0x2 << PACSR_WRMBURST_OFFS)
  68690. +
  68691. +#define PACSR_PCI_ORDERING BIT11 /* PCI Ordering required */
  68692. +
  68693. +#define PACSR_SIZE_OFFS 12 /* PCI access window size */
  68694. +#define PACSR_SIZE_MASK (0xfffff << PACSR_SIZE_OFFS)
  68695. +#define PACSR_SIZE_ALIGNMENT (1 << PACSR_SIZE_OFFS)
  68696. +#define PACSR_SIZE_ALIGN_UP(size) \
  68697. + ((size+PACSR_SIZE_ALIGNMENT)&PACSR_SIZE_MASK)
  68698. +#define PACSR_SIZE_ALIGN_DOWN(size) (size & PACSR_SIZE_MASK)
  68699. +
  68700. +
  68701. +/***************************************/
  68702. +/* PCI Configuration Access Registers */
  68703. +/***************************************/
  68704. +
  68705. +#define PCI_CONFIG_ADDR_REG(pciIf) (0x30C78 - ((pciIf) * 0x80) )
  68706. +#define PCI_CONFIG_DATA_REG(pciIf) (0x30C7C - ((pciIf) * 0x80) )
  68707. +#define PCI_INT_ACK_REG(pciIf) (0x30C34 + ((pciIf) * 0x80) )
  68708. +
  68709. +/* PCI Configuration Address Register (PCAR) */
  68710. +#define PCAR_REG_NUM_OFFS 2
  68711. +#define PCAR_REG_NUM_MASK (0x3F << PCAR_REG_NUM_OFFS)
  68712. +
  68713. +#define PCAR_FUNC_NUM_OFFS 8
  68714. +#define PCAR_FUNC_NUM_MASK (0x7 << PCAR_FUNC_NUM_OFFS)
  68715. +
  68716. +#define PCAR_DEVICE_NUM_OFFS 11
  68717. +#define PCAR_DEVICE_NUM_MASK (0x1F << PCAR_DEVICE_NUM_OFFS)
  68718. +
  68719. +#define PCAR_BUS_NUM_OFFS 16
  68720. +#define PCAR_BUS_NUM_MASK (0xFF << PCAR_BUS_NUM_OFFS)
  68721. +
  68722. +#define PCAR_CONFIG_EN BIT31
  68723. +
  68724. +
  68725. +/***************************************/
  68726. +/* PCI Configuration registers */
  68727. +/***************************************/
  68728. +
  68729. +/*********************************************/
  68730. +/* PCI Configuration, Function 0, Registers */
  68731. +/*********************************************/
  68732. +
  68733. +/* Marvell Specific */
  68734. +#define PCI_SCS0_BASE_ADDR_LOW 0x010
  68735. +#define PCI_SCS0_BASE_ADDR_HIGH 0x014
  68736. +#define PCI_SCS1_BASE_ADDR_LOW 0x018
  68737. +#define PCI_SCS1_BASE_ADDR_HIGH 0x01C
  68738. +#define PCI_INTER_REG_MEM_MAPPED_BASE_ADDR_L 0x020
  68739. +#define PCI_INTER_REG_MEM_MAPPED_BASE_ADDR_H 0x024
  68740. +
  68741. +/* capability list */
  68742. +#define PCI_POWER_MNG_CAPABILITY 0x040
  68743. +#define PCI_POWER_MNG_STATUS_CONTROL 0x044
  68744. +#define PCI_VPD_ADDRESS_REG 0x048
  68745. +#define PCI_VPD_DATA_REG 0x04c
  68746. +#define PCI_MSI_MESSAGE_CONTROL 0x050
  68747. +#define PCI_MSI_MESSAGE_ADDR 0x054
  68748. +#define PCI_MSI_MESSAGE_UPPER_ADDR 0x058
  68749. +#define PCI_MSI_MESSAGE_DATA 0x05c
  68750. +#define PCIX_COMMAND 0x060
  68751. +#define PCIX_STATUS 0x064
  68752. +#define PCI_COMPACT_PCI_HOT_SWAP 0x068
  68753. +
  68754. +
  68755. +/*********************************************/
  68756. +/* PCI Configuration, Function 1, Registers */
  68757. +/*********************************************/
  68758. +
  68759. +#define PCI_SCS2_BASE_ADDR_LOW 0x10
  68760. +#define PCI_SCS2_BASE_ADDR_HIGH 0x14
  68761. +#define PCI_SCS3_BASE_ADDR_LOW 0x18
  68762. +#define PCI_SCS3_BASE_ADDR_HIGH 0x1c
  68763. +
  68764. +
  68765. +/***********************************************/
  68766. +/* PCI Configuration, Function 2, Registers */
  68767. +/***********************************************/
  68768. +
  68769. +#define PCI_DEVCS0_BASE_ADDR_LOW 0x10
  68770. +#define PCI_DEVCS0_BASE_ADDR_HIGH 0x14
  68771. +#define PCI_DEVCS1_BASE_ADDR_LOW 0x18
  68772. +#define PCI_DEVCS1_BASE_ADDR_HIGH 0x1c
  68773. +#define PCI_DEVCS2_BASE_ADDR_LOW 0x20
  68774. +#define PCI_DEVCS2_BASE_ADDR_HIGH 0x24
  68775. +
  68776. +/***********************************************/
  68777. +/* PCI Configuration, Function 3, Registers */
  68778. +/***********************************************/
  68779. +
  68780. +#define PCI_BOOTCS_BASE_ADDR_LOW 0x18
  68781. +#define PCI_BOOTCS_BASE_ADDR_HIGH 0x1c
  68782. +
  68783. +/***********************************************/
  68784. +/* PCI Configuration, Function 4, Registers */
  68785. +/***********************************************/
  68786. +
  68787. +#define PCI_P2P_MEM0_BASE_ADDR_LOW 0x10
  68788. +#define PCI_P2P_MEM0_BASE_ADDR_HIGH 0x14
  68789. +#define PCI_P2P_IO_BASE_ADDR 0x20
  68790. +#define PCI_INTER_REGS_IO_MAPPED_BASE_ADDR 0x24
  68791. +
  68792. +/* PCIX_STATUS register fields (PXS) */
  68793. +
  68794. +#define PXS_FN_OFFS 0 /* Description Number */
  68795. +#define PXS_FN_MASK (0x7 << PXS_FN_OFFS)
  68796. +
  68797. +#define PXS_DN_OFFS 3 /* Device Number */
  68798. +#define PXS_DN_MASK (0x1f << PXS_DN_OFFS)
  68799. +
  68800. +#define PXS_BN_OFFS 8 /* Bus Number */
  68801. +#define PXS_BN_MASK (0xff << PXS_BN_OFFS)
  68802. +
  68803. +
  68804. +/* PCI Error Report Register Map */
  68805. +#define PCI_SERRN_MASK_REG(pciIf) (0x30c28 + (pciIf * 0x80))
  68806. +#define PCI_CAUSE_REG(pciIf) (0x31d58 + (pciIf * 0x80))
  68807. +#define PCI_MASK_REG(pciIf) (0x31d5C + (pciIf * 0x80))
  68808. +#define PCI_ERROR_ADDR_LOW_REG(pciIf) (0x31d40 + (pciIf * 0x80))
  68809. +#define PCI_ERROR_ADDR_HIGH_REG(pciIf) (0x31d44 + (pciIf * 0x80))
  68810. +#define PCI_ERROR_ATTRIBUTE_REG(pciIf) (0x31d48 + (pciIf * 0x80))
  68811. +#define PCI_ERROR_COMMAND_REG(pciIf) (0x31d50 + (pciIf * 0x80))
  68812. +
  68813. +/* PCI Interrupt Cause Register (PICR) */
  68814. +#define PICR_ERR_SEL_OFFS 27
  68815. +#define PICR_ERR_SEL_MASK (0x1f << PICR_ERR_SEL_OFFS)
  68816. +
  68817. +/* PCI Error Command Register (PECR) */
  68818. +#define PECR_ERR_CMD_OFFS 0
  68819. +#define PECR_ERR_CMD_MASK (0xf << PECR_ERR_CMD_OFFS)
  68820. +#define PECR_DAC BIT4
  68821. +
  68822. +
  68823. +/* defaults */
  68824. +/* Set bits means value is about to change according to new value */
  68825. +#define PCI_COMMAND_DEFAULT_MASK 0xffffdff1
  68826. +#define PCI_COMMAND_DEFAULT \
  68827. + (PCR_MASTER_WR_TRIG_WHOLE | \
  68828. + PCR_MASTER_RD_TRIG_WHOLE | \
  68829. + PCR_MASTER_MEM_RD_LINE_EN | \
  68830. + PCR_MASTER_MEM_RD_MULT_EN | \
  68831. + PCR_NS_ACCORDING_RCV_TRANS | \
  68832. + PCR_MASTER_PCIX_REQ64N_EN | \
  68833. + PCR_MASTER_DAC_EN | \
  68834. + PCR_MASTER_M64_ALLIGN | \
  68835. + PCR_ERRORS_PROPAGATION_EN)
  68836. +
  68837. +
  68838. +#define PCI_ARBITER_CTRL_DEFAULT_MASK 0x801fc07a
  68839. +#define PCI_ARBITER_CTRL_DEFAULT \
  68840. + (PACR_BROKEN_VAL_PCIX_MIN << PACR_BROKEN_VAL_OFFS)
  68841. +
  68842. +
  68843. +#endif /* #ifndef __INCPCIREGSH */
  68844. +
  68845. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c
  68846. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c 1970-01-01 01:00:00.000000000 +0100
  68847. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c 2010-08-05 22:02:25.024868398 +0200
  68848. @@ -0,0 +1,669 @@
  68849. +/*******************************************************************************
  68850. +Copyright (C) Marvell International Ltd. and its affiliates
  68851. +
  68852. +This software file (the "File") is owned and distributed by Marvell
  68853. +International Ltd. and/or its affiliates ("Marvell") under the following
  68854. +alternative licensing terms. Once you have made an election to distribute the
  68855. +File under one of the following license alternatives, please (i) delete this
  68856. +introductory statement regarding license alternatives, (ii) delete the two
  68857. +license alternatives that you have not elected to use and (iii) preserve the
  68858. +Marvell copyright notice above.
  68859. +
  68860. +********************************************************************************
  68861. +Marvell Commercial License Option
  68862. +
  68863. +If you received this File from Marvell and you have entered into a commercial
  68864. +license agreement (a "Commercial License") with Marvell, the File is licensed
  68865. +to you under the terms of the applicable Commercial License.
  68866. +
  68867. +********************************************************************************
  68868. +Marvell GPL License Option
  68869. +
  68870. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68871. +modify this File in accordance with the terms and conditions of the General
  68872. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  68873. +available along with the File in the license.txt file or by writing to the Free
  68874. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  68875. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  68876. +
  68877. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  68878. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  68879. +DISCLAIMED. The GPL License provides additional details about this warranty
  68880. +disclaimer.
  68881. +********************************************************************************
  68882. +Marvell BSD License Option
  68883. +
  68884. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68885. +modify this File under the following licensing terms.
  68886. +Redistribution and use in source and binary forms, with or without modification,
  68887. +are permitted provided that the following conditions are met:
  68888. +
  68889. + * Redistributions of source code must retain the above copyright notice,
  68890. + this list of conditions and the following disclaimer.
  68891. +
  68892. + * Redistributions in binary form must reproduce the above copyright
  68893. + notice, this list of conditions and the following disclaimer in the
  68894. + documentation and/or other materials provided with the distribution.
  68895. +
  68896. + * Neither the name of Marvell nor the names of its contributors may be
  68897. + used to endorse or promote products derived from this software without
  68898. + specific prior written permission.
  68899. +
  68900. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  68901. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  68902. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  68903. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  68904. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  68905. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  68906. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  68907. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  68908. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  68909. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  68910. +
  68911. +*******************************************************************************/
  68912. +
  68913. +#include "mvPciIf.h"
  68914. +#include "ctrlEnv/sys/mvSysPex.h"
  68915. +
  68916. +#if defined(MV_INCLUDE_PCI)
  68917. +#include "ctrlEnv/sys/mvSysPci.h"
  68918. +#endif
  68919. +
  68920. +
  68921. +/* defines */
  68922. +#ifdef MV_DEBUG
  68923. + #define DB(x) x
  68924. +#else
  68925. + #define DB(x)
  68926. +#endif
  68927. +
  68928. +
  68929. +/*******************************************************************************
  68930. +* mvPciInit - Initialize PCI interfaces
  68931. +*
  68932. +* DESCRIPTION:
  68933. +*
  68934. +* INPUT:
  68935. +*
  68936. +*
  68937. +* OUTPUT:
  68938. +* None.
  68939. +*
  68940. +* RETURN:
  68941. +* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
  68942. +*
  68943. +*******************************************************************************/
  68944. +
  68945. +
  68946. +MV_STATUS mvPciIfInit(MV_U32 pciIf, PCI_IF_MODE pciIfmode)
  68947. +{
  68948. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  68949. +
  68950. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  68951. + {
  68952. + #if defined(MV_INCLUDE_PCI)
  68953. +
  68954. + MV_PCI_MOD pciMod;
  68955. +
  68956. + if (PCI_IF_MODE_HOST == pciIfmode)
  68957. + {
  68958. + pciMod = MV_PCI_MOD_HOST;
  68959. + }
  68960. + else if (PCI_IF_MODE_DEVICE == pciIfmode)
  68961. + {
  68962. + pciMod = MV_PCI_MOD_DEVICE;
  68963. + }
  68964. + else
  68965. + {
  68966. + mvOsPrintf("%s: ERROR!!! Bus %d mode %d neither host nor device!\n",
  68967. + __FUNCTION__, pciIf, pciIfmode);
  68968. + return MV_FAIL;
  68969. + }
  68970. +
  68971. + return mvPciInit(pciIf - MV_PCI_START_IF, pciMod);
  68972. + #else
  68973. + return MV_OK;
  68974. + #endif
  68975. + }
  68976. + else if (PCI_IF_TYPE_PEX == pciIfType)
  68977. + {
  68978. + #if defined(MV_INCLUDE_PEX)
  68979. +
  68980. + MV_PEX_TYPE pexType;
  68981. +
  68982. + if (PCI_IF_MODE_HOST == pciIfmode)
  68983. + {
  68984. + pexType = MV_PEX_ROOT_COMPLEX;
  68985. + }
  68986. + else if (PCI_IF_MODE_DEVICE == pciIfmode)
  68987. + {
  68988. + pexType = MV_PEX_END_POINT;
  68989. + }
  68990. + else
  68991. + {
  68992. + mvOsPrintf("%s: ERROR!!! Bus %d type %d neither root complex nor" \
  68993. + " end point\n", __FUNCTION__, pciIf, pciIfmode);
  68994. + return MV_FAIL;
  68995. + }
  68996. + return mvPexInit(pciIf - MV_PEX_START_IF, pexType);
  68997. +
  68998. + #else
  68999. + return MV_OK;
  69000. + #endif
  69001. +
  69002. + }
  69003. + else
  69004. + {
  69005. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69006. + }
  69007. +
  69008. + return MV_FAIL;
  69009. +
  69010. +}
  69011. +
  69012. +/* PCI configuration space read write */
  69013. +
  69014. +/*******************************************************************************
  69015. +* mvPciConfigRead - Read from configuration space
  69016. +*
  69017. +* DESCRIPTION:
  69018. +* This function performs a 32 bit read from PCI configuration space.
  69019. +* It supports both type 0 and type 1 of Configuration Transactions
  69020. +* (local and over bridge). In order to read from local bus segment, use
  69021. +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
  69022. +* will result configuration transaction of type 1 (over bridge).
  69023. +*
  69024. +* INPUT:
  69025. +* pciIf - PCI interface number.
  69026. +* bus - PCI segment bus number.
  69027. +* dev - PCI device number.
  69028. +* func - Function number.
  69029. +* regOffs - Register offset.
  69030. +*
  69031. +* OUTPUT:
  69032. +* None.
  69033. +*
  69034. +* RETURN:
  69035. +* 32bit register data, 0xffffffff on error
  69036. +*
  69037. +*******************************************************************************/
  69038. +MV_U32 mvPciIfConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  69039. + MV_U32 regOff)
  69040. +{
  69041. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69042. +
  69043. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69044. + {
  69045. + #if defined(MV_INCLUDE_PCI)
  69046. + return mvPciConfigRead(pciIf - MV_PCI_START_IF,
  69047. + bus,
  69048. + dev,
  69049. + func,
  69050. + regOff);
  69051. + #else
  69052. + return 0xffffffff;
  69053. + #endif
  69054. + }
  69055. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69056. + {
  69057. + #if defined(MV_INCLUDE_PEX)
  69058. + return mvPexConfigRead(pciIf - MV_PEX_START_IF,
  69059. + bus,
  69060. + dev,
  69061. + func,
  69062. + regOff);
  69063. + #else
  69064. + return 0xffffffff;
  69065. + #endif
  69066. +
  69067. + }
  69068. + else
  69069. + {
  69070. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69071. + }
  69072. +
  69073. + return 0;
  69074. +
  69075. +}
  69076. +
  69077. +/*******************************************************************************
  69078. +* mvPciConfigWrite - Write to configuration space
  69079. +*
  69080. +* DESCRIPTION:
  69081. +* This function performs a 32 bit write to PCI configuration space.
  69082. +* It supports both type 0 and type 1 of Configuration Transactions
  69083. +* (local and over bridge). In order to write to local bus segment, use
  69084. +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
  69085. +* will result configuration transaction of type 1 (over bridge).
  69086. +*
  69087. +* INPUT:
  69088. +* pciIf - PCI interface number.
  69089. +* bus - PCI segment bus number.
  69090. +* dev - PCI device number.
  69091. +* func - Function number.
  69092. +* regOffs - Register offset.
  69093. +* data - 32bit data.
  69094. +*
  69095. +* OUTPUT:
  69096. +* None.
  69097. +*
  69098. +* RETURN:
  69099. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  69100. +*
  69101. +*******************************************************************************/
  69102. +MV_STATUS mvPciIfConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  69103. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  69104. +{
  69105. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69106. +
  69107. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69108. + {
  69109. + #if defined(MV_INCLUDE_PCI)
  69110. + return mvPciConfigWrite(pciIf - MV_PCI_START_IF,
  69111. + bus,
  69112. + dev,
  69113. + func,
  69114. + regOff,
  69115. + data);
  69116. + #else
  69117. + return MV_OK;
  69118. + #endif
  69119. + }
  69120. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69121. + {
  69122. + #if defined(MV_INCLUDE_PEX)
  69123. + return mvPexConfigWrite(pciIf - MV_PEX_START_IF,
  69124. + bus,
  69125. + dev,
  69126. + func,
  69127. + regOff,
  69128. + data);
  69129. + #else
  69130. + return MV_OK;
  69131. + #endif
  69132. +
  69133. + }
  69134. + else
  69135. + {
  69136. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69137. + }
  69138. +
  69139. + return MV_FAIL;
  69140. +
  69141. +}
  69142. +
  69143. +/*******************************************************************************
  69144. +* mvPciMasterEnable - Enable/disale PCI interface master transactions.
  69145. +*
  69146. +* DESCRIPTION:
  69147. +* This function performs read modified write to PCI command status
  69148. +* (offset 0x4) to set/reset bit 2. After this bit is set, the PCI
  69149. +* master is allowed to gain ownership on the bus, otherwise it is
  69150. +* incapable to do so.
  69151. +*
  69152. +* INPUT:
  69153. +* pciIf - PCI interface number.
  69154. +* enable - Enable/disable parameter.
  69155. +*
  69156. +* OUTPUT:
  69157. +* None.
  69158. +*
  69159. +* RETURN:
  69160. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  69161. +*
  69162. +*******************************************************************************/
  69163. +MV_STATUS mvPciIfMasterEnable(MV_U32 pciIf, MV_BOOL enable)
  69164. +{
  69165. +
  69166. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69167. +
  69168. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69169. + {
  69170. + #if defined(MV_INCLUDE_PCI)
  69171. + return mvPciMasterEnable(pciIf - MV_PCI_START_IF,
  69172. + enable);
  69173. + #else
  69174. + return MV_OK;
  69175. + #endif
  69176. + }
  69177. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69178. + {
  69179. + #if defined(MV_INCLUDE_PEX)
  69180. + return mvPexMasterEnable(pciIf - MV_PEX_START_IF,
  69181. + enable);
  69182. + #else
  69183. + return MV_OK;
  69184. + #endif
  69185. + }
  69186. + else
  69187. + {
  69188. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69189. + }
  69190. +
  69191. + return MV_FAIL;
  69192. +
  69193. +}
  69194. +
  69195. +
  69196. +/*******************************************************************************
  69197. +* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.
  69198. +*
  69199. +* DESCRIPTION:
  69200. +* This function performs read modified write to PCI command status
  69201. +* (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
  69202. +* the PCI slave is allowed to respond to PCI IO space access (bit 0)
  69203. +* and PCI memory space access (bit 1).
  69204. +*
  69205. +* INPUT:
  69206. +* pciIf - PCI interface number.
  69207. +* dev - PCI device number.
  69208. +* enable - Enable/disable parameter.
  69209. +*
  69210. +* OUTPUT:
  69211. +* None.
  69212. +*
  69213. +* RETURN:
  69214. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  69215. +*
  69216. +*******************************************************************************/
  69217. +MV_STATUS mvPciIfSlaveEnable(MV_U32 pciIf,MV_U32 bus, MV_U32 dev, MV_BOOL enable)
  69218. +{
  69219. +
  69220. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69221. +
  69222. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69223. + {
  69224. + #if defined(MV_INCLUDE_PCI)
  69225. + return mvPciSlaveEnable(pciIf - MV_PCI_START_IF,bus,dev,
  69226. + enable);
  69227. + #else
  69228. + return MV_OK;
  69229. + #endif
  69230. + }
  69231. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69232. + {
  69233. + #if defined(MV_INCLUDE_PEX)
  69234. + return mvPexSlaveEnable(pciIf - MV_PEX_START_IF,bus,dev,
  69235. + enable);
  69236. + #else
  69237. + return MV_OK;
  69238. + #endif
  69239. + }
  69240. + else
  69241. + {
  69242. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69243. + }
  69244. +
  69245. + return MV_FAIL;
  69246. +
  69247. +}
  69248. +
  69249. +/*******************************************************************************
  69250. +* mvPciLocalBusNumSet - Set PCI interface local bus number.
  69251. +*
  69252. +* DESCRIPTION:
  69253. +* This function sets given PCI interface its local bus number.
  69254. +* Note: In case the PCI interface is PCI-X, the information is read-only.
  69255. +*
  69256. +* INPUT:
  69257. +* pciIf - PCI interface number.
  69258. +* busNum - Bus number.
  69259. +*
  69260. +* OUTPUT:
  69261. +* None.
  69262. +*
  69263. +* RETURN:
  69264. +* MV_NOT_ALLOWED in case PCI interface is PCI-X.
  69265. +* MV_BAD_PARAM on bad parameters ,
  69266. +* otherwise MV_OK
  69267. +*
  69268. +*******************************************************************************/
  69269. +MV_STATUS mvPciIfLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum)
  69270. +{
  69271. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69272. +
  69273. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69274. + {
  69275. + #if defined(MV_INCLUDE_PCI)
  69276. + return mvPciLocalBusNumSet(pciIf - MV_PCI_START_IF,
  69277. + busNum);
  69278. + #else
  69279. + return MV_OK;
  69280. + #endif
  69281. + }
  69282. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69283. + {
  69284. + #if defined(MV_INCLUDE_PEX)
  69285. + return mvPexLocalBusNumSet(pciIf - MV_PEX_START_IF,
  69286. + busNum);
  69287. + #else
  69288. + return MV_OK;
  69289. + #endif
  69290. + }
  69291. + else
  69292. + {
  69293. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69294. + }
  69295. +
  69296. + return MV_FAIL;
  69297. +
  69298. +}
  69299. +
  69300. +/*******************************************************************************
  69301. +* mvPciLocalBusNumGet - Get PCI interface local bus number.
  69302. +*
  69303. +* DESCRIPTION:
  69304. +* This function gets the local bus number of a given PCI interface.
  69305. +*
  69306. +* INPUT:
  69307. +* pciIf - PCI interface number.
  69308. +*
  69309. +* OUTPUT:
  69310. +* None.
  69311. +*
  69312. +* RETURN:
  69313. +* Local bus number.0xffffffff on Error
  69314. +*
  69315. +*******************************************************************************/
  69316. +MV_U32 mvPciIfLocalBusNumGet(MV_U32 pciIf)
  69317. +{
  69318. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69319. +
  69320. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69321. + {
  69322. + #if defined(MV_INCLUDE_PCI)
  69323. + return mvPciLocalBusNumGet(pciIf - MV_PCI_START_IF);
  69324. + #else
  69325. + return 0xFFFFFFFF;
  69326. + #endif
  69327. + }
  69328. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69329. + {
  69330. + #if defined(MV_INCLUDE_PEX)
  69331. + return mvPexLocalBusNumGet(pciIf - MV_PEX_START_IF);
  69332. + #else
  69333. + return 0xFFFFFFFF;
  69334. + #endif
  69335. +
  69336. + }
  69337. + else
  69338. + {
  69339. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n",__FUNCTION__, pciIf);
  69340. + }
  69341. +
  69342. + return 0;
  69343. +
  69344. +}
  69345. +
  69346. +
  69347. +/*******************************************************************************
  69348. +* mvPciLocalDevNumSet - Set PCI interface local device number.
  69349. +*
  69350. +* DESCRIPTION:
  69351. +* This function sets given PCI interface its local device number.
  69352. +* Note: In case the PCI interface is PCI-X, the information is read-only.
  69353. +*
  69354. +* INPUT:
  69355. +* pciIf - PCI interface number.
  69356. +* devNum - Device number.
  69357. +*
  69358. +* OUTPUT:
  69359. +* None.
  69360. +*
  69361. +* RETURN:
  69362. +* MV_NOT_ALLOWED in case PCI interface is PCI-X. MV_BAD_PARAM on bad parameters ,
  69363. +* otherwise MV_OK
  69364. +*
  69365. +*******************************************************************************/
  69366. +MV_STATUS mvPciIfLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum)
  69367. +{
  69368. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69369. +
  69370. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69371. + {
  69372. + #if defined(MV_INCLUDE_PCI)
  69373. + return mvPciLocalDevNumSet(pciIf - MV_PCI_START_IF,
  69374. + devNum);
  69375. + #else
  69376. + return MV_OK;
  69377. + #endif
  69378. + }
  69379. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69380. + {
  69381. + #if defined(MV_INCLUDE_PEX)
  69382. + return mvPexLocalDevNumSet(pciIf - MV_PEX_START_IF,
  69383. + devNum);
  69384. + #else
  69385. + return MV_OK;
  69386. + #endif
  69387. + }
  69388. + else
  69389. + {
  69390. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69391. + }
  69392. +
  69393. + return MV_FAIL;
  69394. +
  69395. +}
  69396. +
  69397. +/*******************************************************************************
  69398. +* mvPciLocalDevNumGet - Get PCI interface local device number.
  69399. +*
  69400. +* DESCRIPTION:
  69401. +* This function gets the local device number of a given PCI interface.
  69402. +*
  69403. +* INPUT:
  69404. +* pciIf - PCI interface number.
  69405. +*
  69406. +* OUTPUT:
  69407. +* None.
  69408. +*
  69409. +* RETURN:
  69410. +* Local device number. 0xffffffff on Error
  69411. +*
  69412. +*******************************************************************************/
  69413. +MV_U32 mvPciIfLocalDevNumGet(MV_U32 pciIf)
  69414. +{
  69415. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69416. +
  69417. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69418. + {
  69419. + #if defined(MV_INCLUDE_PCI)
  69420. + return mvPciLocalDevNumGet(pciIf - MV_PCI_START_IF);
  69421. + #else
  69422. + return 0xFFFFFFFF;
  69423. + #endif
  69424. + }
  69425. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69426. + {
  69427. + #if defined(MV_INCLUDE_PEX)
  69428. + return mvPexLocalDevNumGet(pciIf - MV_PEX_START_IF);
  69429. + #else
  69430. + return 0xFFFFFFFF;
  69431. + #endif
  69432. +
  69433. + }
  69434. + else
  69435. + {
  69436. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69437. + }
  69438. +
  69439. + return 0;
  69440. +
  69441. +}
  69442. +
  69443. +/*******************************************************************************
  69444. +* mvPciIfTypeGet -
  69445. +*
  69446. +* DESCRIPTION:
  69447. +*
  69448. +* INPUT:
  69449. +*
  69450. +* OUTPUT:
  69451. +* None.
  69452. +*
  69453. +* RETURN:
  69454. +*
  69455. +*******************************************************************************/
  69456. +
  69457. +PCI_IF_TYPE mvPciIfTypeGet(MV_U32 pciIf)
  69458. +{
  69459. +
  69460. + if ((pciIf >= MV_PCI_START_IF)&&(pciIf < MV_PCI_MAX_IF + MV_PCI_START_IF))
  69461. + {
  69462. + return PCI_IF_TYPE_CONVEN_PCIX;
  69463. + }
  69464. + else if ((pciIf >= MV_PEX_START_IF) &&
  69465. + (pciIf < MV_PEX_MAX_IF + MV_PEX_START_IF))
  69466. + {
  69467. + return PCI_IF_TYPE_PEX;
  69468. +
  69469. + }
  69470. + else
  69471. + {
  69472. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69473. + }
  69474. +
  69475. + return 0xffffffff;
  69476. +
  69477. +}
  69478. +
  69479. +/*******************************************************************************
  69480. +* mvPciIfTypeGet -
  69481. +*
  69482. +* DESCRIPTION:
  69483. +*
  69484. +* INPUT:
  69485. +*
  69486. +* OUTPUT:
  69487. +* None.
  69488. +*
  69489. +* RETURN:
  69490. +*
  69491. +*******************************************************************************/
  69492. +
  69493. +MV_U32 mvPciRealIfNumGet(MV_U32 pciIf)
  69494. +{
  69495. +
  69496. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  69497. +
  69498. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  69499. + {
  69500. + return (pciIf - MV_PCI_START_IF);
  69501. + }
  69502. + else if (PCI_IF_TYPE_PEX == pciIfType)
  69503. + {
  69504. + return (pciIf - MV_PEX_START_IF);
  69505. +
  69506. + }
  69507. + else
  69508. + {
  69509. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  69510. + }
  69511. +
  69512. + return 0xffffffff;
  69513. +
  69514. +}
  69515. +
  69516. +
  69517. +
  69518. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h
  69519. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h 1970-01-01 01:00:00.000000000 +0100
  69520. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h 2010-08-05 22:02:25.054867990 +0200
  69521. @@ -0,0 +1,134 @@
  69522. +/*******************************************************************************
  69523. +Copyright (C) Marvell International Ltd. and its affiliates
  69524. +
  69525. +This software file (the "File") is owned and distributed by Marvell
  69526. +International Ltd. and/or its affiliates ("Marvell") under the following
  69527. +alternative licensing terms. Once you have made an election to distribute the
  69528. +File under one of the following license alternatives, please (i) delete this
  69529. +introductory statement regarding license alternatives, (ii) delete the two
  69530. +license alternatives that you have not elected to use and (iii) preserve the
  69531. +Marvell copyright notice above.
  69532. +
  69533. +********************************************************************************
  69534. +Marvell Commercial License Option
  69535. +
  69536. +If you received this File from Marvell and you have entered into a commercial
  69537. +license agreement (a "Commercial License") with Marvell, the File is licensed
  69538. +to you under the terms of the applicable Commercial License.
  69539. +
  69540. +********************************************************************************
  69541. +Marvell GPL License Option
  69542. +
  69543. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69544. +modify this File in accordance with the terms and conditions of the General
  69545. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  69546. +available along with the File in the license.txt file or by writing to the Free
  69547. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  69548. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  69549. +
  69550. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  69551. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  69552. +DISCLAIMED. The GPL License provides additional details about this warranty
  69553. +disclaimer.
  69554. +********************************************************************************
  69555. +Marvell BSD License Option
  69556. +
  69557. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69558. +modify this File under the following licensing terms.
  69559. +Redistribution and use in source and binary forms, with or without modification,
  69560. +are permitted provided that the following conditions are met:
  69561. +
  69562. + * Redistributions of source code must retain the above copyright notice,
  69563. + this list of conditions and the following disclaimer.
  69564. +
  69565. + * Redistributions in binary form must reproduce the above copyright
  69566. + notice, this list of conditions and the following disclaimer in the
  69567. + documentation and/or other materials provided with the distribution.
  69568. +
  69569. + * Neither the name of Marvell nor the names of its contributors may be
  69570. + used to endorse or promote products derived from this software without
  69571. + specific prior written permission.
  69572. +
  69573. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  69574. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  69575. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  69576. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  69577. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  69578. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  69579. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  69580. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  69581. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  69582. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  69583. +
  69584. +*******************************************************************************/
  69585. +
  69586. +#ifndef __INCPCIIFH
  69587. +#define __INCPCIIFH
  69588. +
  69589. +#include "mvSysHwConfig.h"
  69590. +#include "pci-if/mvPciIfRegs.h"
  69591. +#if defined(MV_INCLUDE_PEX)
  69592. +#include "pex/mvPex.h"
  69593. +#endif
  69594. +#if defined(MV_INCLUDE_PCI)
  69595. +#include "pci/mvPci.h"
  69596. +#endif
  69597. +#include "ctrlEnv/mvCtrlEnvLib.h"
  69598. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  69599. +
  69600. +typedef enum _mvPCIIfType
  69601. +{
  69602. + PCI_IF_TYPE_CONVEN_PCIX,
  69603. + PCI_IF_TYPE_PEX
  69604. +
  69605. +}PCI_IF_TYPE;
  69606. +
  69607. +typedef enum _mvPCIIfMode
  69608. +{
  69609. + PCI_IF_MODE_HOST,
  69610. + PCI_IF_MODE_DEVICE
  69611. +}PCI_IF_MODE;
  69612. +
  69613. +
  69614. +/* Global Functions prototypes */
  69615. +
  69616. +/* mvPciIfInit - Initialize PCI interfaces*/
  69617. +MV_STATUS mvPciIfInit(MV_U32 pciIf, PCI_IF_MODE pciIfmode);
  69618. +
  69619. +/* mvPciIfConfigRead - Read from configuration space */
  69620. +MV_U32 mvPciIfConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  69621. + MV_U32 func,MV_U32 regOff);
  69622. +
  69623. +/* mvPciIfConfigWrite - Write to configuration space */
  69624. +MV_STATUS mvPciIfConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  69625. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  69626. +
  69627. +/* mvPciIfMasterEnable - Enable/disale PCI interface master transactions.*/
  69628. +MV_STATUS mvPciIfMasterEnable(MV_U32 pciIf, MV_BOOL enable);
  69629. +
  69630. +/* mvPciIfSlaveEnable - Enable/disale PCI interface slave transactions.*/
  69631. +MV_STATUS mvPciIfSlaveEnable(MV_U32 pciIf,MV_U32 bus, MV_U32 dev,
  69632. + MV_BOOL enable);
  69633. +
  69634. +/* mvPciIfLocalBusNumSet - Set PCI interface local bus number.*/
  69635. +MV_STATUS mvPciIfLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum);
  69636. +
  69637. +/* mvPciIfLocalBusNumGet - Get PCI interface local bus number.*/
  69638. +MV_U32 mvPciIfLocalBusNumGet(MV_U32 pciIf);
  69639. +
  69640. +/* mvPciIfLocalDevNumSet - Set PCI interface local device number.*/
  69641. +MV_STATUS mvPciIfLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum);
  69642. +
  69643. +/* mvPciIfLocalDevNumGet - Get PCI interface local device number.*/
  69644. +MV_U32 mvPciIfLocalDevNumGet(MV_U32 pciIf);
  69645. +
  69646. +/* mvPciIfTypeGet - Get PCI If type*/
  69647. +PCI_IF_TYPE mvPciIfTypeGet(MV_U32 pciIf);
  69648. +
  69649. +MV_U32 mvPciRealIfNumGet(MV_U32 pciIf);
  69650. +
  69651. +/* mvPciIfAddrDecShow - Display address decode windows attributes */
  69652. +MV_VOID mvPciIfAddrDecShow(MV_VOID);
  69653. +
  69654. +#endif /* #ifndef __INCPCIIFH */
  69655. +
  69656. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h
  69657. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h 1970-01-01 01:00:00.000000000 +0100
  69658. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h 2010-08-05 22:02:25.094867960 +0200
  69659. @@ -0,0 +1,245 @@
  69660. +/*******************************************************************************
  69661. +Copyright (C) Marvell International Ltd. and its affiliates
  69662. +
  69663. +This software file (the "File") is owned and distributed by Marvell
  69664. +International Ltd. and/or its affiliates ("Marvell") under the following
  69665. +alternative licensing terms. Once you have made an election to distribute the
  69666. +File under one of the following license alternatives, please (i) delete this
  69667. +introductory statement regarding license alternatives, (ii) delete the two
  69668. +license alternatives that you have not elected to use and (iii) preserve the
  69669. +Marvell copyright notice above.
  69670. +
  69671. +********************************************************************************
  69672. +Marvell Commercial License Option
  69673. +
  69674. +If you received this File from Marvell and you have entered into a commercial
  69675. +license agreement (a "Commercial License") with Marvell, the File is licensed
  69676. +to you under the terms of the applicable Commercial License.
  69677. +
  69678. +********************************************************************************
  69679. +Marvell GPL License Option
  69680. +
  69681. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69682. +modify this File in accordance with the terms and conditions of the General
  69683. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  69684. +available along with the File in the license.txt file or by writing to the Free
  69685. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  69686. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  69687. +
  69688. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  69689. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  69690. +DISCLAIMED. The GPL License provides additional details about this warranty
  69691. +disclaimer.
  69692. +********************************************************************************
  69693. +Marvell BSD License Option
  69694. +
  69695. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69696. +modify this File under the following licensing terms.
  69697. +Redistribution and use in source and binary forms, with or without modification,
  69698. +are permitted provided that the following conditions are met:
  69699. +
  69700. + * Redistributions of source code must retain the above copyright notice,
  69701. + this list of conditions and the following disclaimer.
  69702. +
  69703. + * Redistributions in binary form must reproduce the above copyright
  69704. + notice, this list of conditions and the following disclaimer in the
  69705. + documentation and/or other materials provided with the distribution.
  69706. +
  69707. + * Neither the name of Marvell nor the names of its contributors may be
  69708. + used to endorse or promote products derived from this software without
  69709. + specific prior written permission.
  69710. +
  69711. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  69712. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  69713. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  69714. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  69715. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  69716. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  69717. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  69718. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  69719. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  69720. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  69721. +
  69722. +*******************************************************************************/
  69723. +
  69724. +#ifndef __INCPCIIFREGSH
  69725. +#define __INCPCIIFREGSH
  69726. +
  69727. +
  69728. +/* defines */
  69729. +#define MAX_PCI_DEVICES 32
  69730. +#define MAX_PCI_FUNCS 8
  69731. +#define MAX_PCI_BUSSES 128
  69732. +
  69733. +/***************************************/
  69734. +/* PCI Configuration registers */
  69735. +/***************************************/
  69736. +
  69737. +/*********************************************/
  69738. +/* PCI Configuration, Function 0, Registers */
  69739. +/*********************************************/
  69740. +
  69741. +
  69742. +/* Standard registers */
  69743. +#define PCI_DEVICE_AND_VENDOR_ID 0x000
  69744. +#define PCI_STATUS_AND_COMMAND 0x004
  69745. +#define PCI_CLASS_CODE_AND_REVISION_ID 0x008
  69746. +#define PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE 0x00C
  69747. +#define PCI_MEMORY_BAR_BASE_ADDR(barNum) (0x010 + ((barNum) << 2))
  69748. +#define PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID 0x02C
  69749. +#define PCI_EXPANSION_ROM_BASE_ADDR_REG 0x030
  69750. +#define PCI_CAPABILTY_LIST_POINTER 0x034
  69751. +#define PCI_INTERRUPT_PIN_AND_LINE 0x03C
  69752. +
  69753. +
  69754. +/* PCI Device and Vendor ID Register (PDVIR) */
  69755. +#define PDVIR_VEN_ID_OFFS 0 /* Vendor ID */
  69756. +#define PDVIR_VEN_ID_MASK (0xffff << PDVIR_VEN_ID_OFFS)
  69757. +
  69758. +#define PDVIR_DEV_ID_OFFS 16 /* Device ID */
  69759. +#define PDVIR_DEV_ID_MASK (0xffff << PDVIR_DEV_ID_OFFS)
  69760. +
  69761. +/* PCI Status and Command Register (PSCR) */
  69762. +#define PSCR_IO_EN BIT0 /* IO Enable */
  69763. +#define PSCR_MEM_EN BIT1 /* Memory Enable */
  69764. +#define PSCR_MASTER_EN BIT2 /* Master Enable */
  69765. +#define PSCR_SPECIAL_EN BIT3 /* Special Cycle Enable */
  69766. +#define PSCR_MEM_WRI_INV BIT4 /* Memory Write and Invalidate Enable */
  69767. +#define PSCR_VGA BIT5 /* VGA Palette Snoops */
  69768. +#define PSCR_PERR_EN BIT6 /* Parity Errors Respond Enable */
  69769. +#define PSCR_ADDR_STEP BIT7 /* Address Stepping Enable (Wait Cycle En)*/
  69770. +#define PSCR_SERR_EN BIT8 /* Ability to assert SERR# line */
  69771. +#define PSCR_FAST_BTB_EN BIT9 /* generate fast back-to-back transactions*/
  69772. +#define PSCR_CAP_LIST BIT20 /* Capability List Support */
  69773. +#define PSCR_66MHZ_EN BIT21 /* 66 MHz Capable */
  69774. +#define PSCR_UDF_EN BIT22 /* User definable features */
  69775. +#define PSCR_TAR_FAST_BB BIT23 /* fast back-to-back transactions capable */
  69776. +#define PSCR_DATA_PERR BIT24 /* Data Parity reported */
  69777. +
  69778. +#define PSCR_DEVSEL_TIM_OFFS 25 /* DEVSEL timing */
  69779. +#define PSCR_DEVSEL_TIM_MASK (0x3 << PSCR_DEVSEL_TIM_OFFS)
  69780. +#define PSCR_DEVSEL_TIM_FAST (0x0 << PSCR_DEVSEL_TIM_OFFS)
  69781. +#define PSCR_DEVSEL_TIM_MED (0x1 << PSCR_DEVSEL_TIM_OFFS)
  69782. +#define PSCR_DEVSEL_TIM_SLOW (0x2 << PSCR_DEVSEL_TIM_OFFS)
  69783. +
  69784. +#define PSCR_SLAVE_TABORT BIT27 /* Signalled Target Abort */
  69785. +#define PSCR_MASTER_TABORT BIT28 /* Recieved Target Abort */
  69786. +#define PSCR_MABORT BIT29 /* Recieved Master Abort */
  69787. +#define PSCR_SYSERR BIT30 /* Signalled system error */
  69788. +#define PSCR_DET_PARERR BIT31 /* Detect Parity Error */
  69789. +
  69790. +/* PCI configuration register offset=0x08 fields
  69791. + (PCI_CLASS_CODE_AND_REVISION_ID)(PCCRI) */
  69792. +
  69793. +#define PCCRIR_REVID_OFFS 0 /* Revision ID */
  69794. +#define PCCRIR_REVID_MASK (0xff << PCCRIR_REVID_OFFS)
  69795. +
  69796. +#define PCCRIR_FULL_CLASS_OFFS 8 /* Full Class Code */
  69797. +#define PCCRIR_FULL_CLASS_MASK (0xffffff << PCCRIR_FULL_CLASS_OFFS)
  69798. +
  69799. +#define PCCRIR_PROGIF_OFFS 8 /* Prog .I/F*/
  69800. +#define PCCRIR_PROGIF_MASK (0xff << PCCRIR_PROGIF_OFFS)
  69801. +
  69802. +#define PCCRIR_SUB_CLASS_OFFS 16 /* Sub Class*/
  69803. +#define PCCRIR_SUB_CLASS_MASK (0xff << PCCRIR_SUB_CLASS_OFFS)
  69804. +
  69805. +#define PCCRIR_BASE_CLASS_OFFS 24 /* Base Class*/
  69806. +#define PCCRIR_BASE_CLASS_MASK (0xff << PCCRIR_BASE_CLASS_OFFS)
  69807. +
  69808. +/* PCI configuration register offset=0x0C fields
  69809. + (PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE)(PBHTLTCL) */
  69810. +
  69811. +#define PBHTLTCLR_CACHELINE_OFFS 0 /* Specifies the cache line size */
  69812. +#define PBHTLTCLR_CACHELINE_MASK (0xff << PBHTLTCLR_CACHELINE_OFFS)
  69813. +
  69814. +#define PBHTLTCLR_LATTIMER_OFFS 8 /* latency timer */
  69815. +#define PBHTLTCLR_LATTIMER_MASK (0xff << PBHTLTCLR_LATTIMER_OFFS)
  69816. +
  69817. +#define PBHTLTCLR_HEADTYPE_FULL_OFFS 16 /* Full Header Type */
  69818. +#define PBHTLTCLR_HEADTYPE_FULL_MASK (0xff << PBHTLTCLR_HEADTYPE_FULL_OFFS)
  69819. +
  69820. +#define PBHTLTCLR_MULTI_FUNC BIT23 /* Multi/Single function */
  69821. +
  69822. +#define PBHTLTCLR_HEADER_OFFS 16 /* Header type */
  69823. +#define PBHTLTCLR_HEADER_MASK (0x7f << PBHTLTCLR_HEADER_OFFS)
  69824. +#define PBHTLTCLR_HEADER_STANDARD (0x0 << PBHTLTCLR_HEADER_OFFS)
  69825. +#define PBHTLTCLR_HEADER_PCI2PCI_BRIDGE (0x1 << PBHTLTCLR_HEADER_OFFS)
  69826. +
  69827. +
  69828. +#define PBHTLTCLR_BISTCOMP_OFFS 24 /* BIST Completion Code */
  69829. +#define PBHTLTCLR_BISTCOMP_MASK (0xf << PBHTLTCLR_BISTCOMP_OFFS)
  69830. +
  69831. +#define PBHTLTCLR_BISTACT BIT30 /* BIST Activate bit */
  69832. +#define PBHTLTCLR_BISTCAP BIT31 /* BIST Capable Bit */
  69833. +
  69834. +
  69835. +/* PCI Bar Base Low Register (PBBLR) */
  69836. +#define PBBLR_IOSPACE BIT0 /* Memory Space Indicator */
  69837. +
  69838. +#define PBBLR_TYPE_OFFS 1 /* BAR Type/Init Val. */
  69839. +#define PBBLR_TYPE_MASK (0x3 << PBBLR_TYPE_OFFS)
  69840. +#define PBBLR_TYPE_32BIT_ADDR (0x0 << PBBLR_TYPE_OFFS)
  69841. +#define PBBLR_TYPE_64BIT_ADDR (0x2 << PBBLR_TYPE_OFFS)
  69842. +
  69843. +#define PBBLR_PREFETCH_EN BIT3 /* Prefetch Enable */
  69844. +
  69845. +
  69846. +#define PBBLR_MEM_BASE_OFFS 4 /* Memory Bar Base address. Corresponds to
  69847. + address bits [31:4] */
  69848. +#define PBBLR_MEM_BASE_MASK (0xfffffff << PBBLR_MEM_BASE_OFFS)
  69849. +
  69850. +#define PBBLR_IO_BASE_OFFS 2 /* IO Bar Base address. Corresponds to
  69851. + address bits [31:2] */
  69852. +#define PBBLR_IO_BASE_MASK (0x3fffffff << PBBLR_IO_BASE_OFFS)
  69853. +
  69854. +
  69855. +#define PBBLR_BASE_OFFS 12 /* Base address. Address bits [31:12] */
  69856. +#define PBBLR_BASE_MASK (0xfffff << PBBLR_BASE_OFFS)
  69857. +#define PBBLR_BASE_ALIGNMET (1 << PBBLR_BASE_OFFS)
  69858. +
  69859. +
  69860. +/* PCI Bar Base High Fegister (PBBHR) */
  69861. +#define PBBHR_BASE_OFFS 0 /* Base address. Address bits [31:12] */
  69862. +#define PBBHR_BASE_MASK (0xffffffff << PBBHR_BASE_OFFS)
  69863. +
  69864. +
  69865. +/* PCI configuration register offset=0x2C fields
  69866. + (PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID)(PSISVI) */
  69867. +
  69868. +#define PSISVIR_VENID_OFFS 0 /* Subsystem Manufacturer Vendor ID Number */
  69869. +#define PSISVIR_VENID_MASK (0xffff << PSISVIR_VENID_OFFS)
  69870. +
  69871. +#define PSISVIR_DEVID_OFFS 16 /* Subsystem Device ID Number */
  69872. +#define PSISVIR_DEVID_MASK (0xffff << PSISVIR_DEVID_OFFS)
  69873. +
  69874. +/* PCI configuration register offset=0x30 fields
  69875. + (PCI_EXPANSION_ROM_BASE_ADDR_REG)(PERBA) */
  69876. +
  69877. +#define PERBAR_EXPROMEN BIT0 /* Expansion ROM Enable */
  69878. +
  69879. +#define PERBAR_BASE_OFFS 12 /* Expansion ROM Base Address */
  69880. +#define PERBAR_BASE_MASK (0xfffff << PERBAR_BASE_OFFS)
  69881. +
  69882. +/* PCI configuration register offset=0x34 fields
  69883. + (PCI_CAPABILTY_LIST_POINTER)(PCLP) */
  69884. +
  69885. +#define PCLPR_CAPPTR_OFFS 0 /* Capability List Pointer */
  69886. +#define PCLPR_CAPPTR_MASK (0xff << PCLPR_CAPPTR_OFFS)
  69887. +
  69888. +/* PCI configuration register offset=0x3C fields
  69889. + (PCI_INTERRUPT_PIN_AND_LINE)(PIPL) */
  69890. +
  69891. +#define PIPLR_INTLINE_OFFS 0 /* Interrupt line (IRQ) */
  69892. +#define PIPLR_INTLINE_MASK (0xff << PIPLR_INTLINE_OFFS)
  69893. +
  69894. +#define PIPLR_INTPIN_OFFS 8 /* interrupt pin (A,B,C,D) */
  69895. +#define PIPLR_INTPIN_MASK (0xff << PIPLR_INTPIN_OFFS)
  69896. +
  69897. +#define PIPLR_MINGRANT_OFFS 16 /* Minimum Grant on 250 nano seconds units */
  69898. +#define PIPLR_MINGRANT_MASK (0xff << PIPLR_MINGRANT_OFFS)
  69899. +
  69900. +#define PIPLR_MAXLATEN_OFFS 24 /* Maximum latency on 250 nano seconds units */
  69901. +#define PIPLR_MAXLATEN_MASK (0xff << PIPLR_MAXLATEN_OFFS)
  69902. +
  69903. +#endif /* #ifndef __INCPCIIFREGSH */
  69904. +
  69905. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c
  69906. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c 1970-01-01 01:00:00.000000000 +0100
  69907. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c 2010-08-05 22:02:25.133718334 +0200
  69908. @@ -0,0 +1,1006 @@
  69909. +/*******************************************************************************
  69910. +Copyright (C) Marvell International Ltd. and its affiliates
  69911. +
  69912. +This software file (the "File") is owned and distributed by Marvell
  69913. +International Ltd. and/or its affiliates ("Marvell") under the following
  69914. +alternative licensing terms. Once you have made an election to distribute the
  69915. +File under one of the following license alternatives, please (i) delete this
  69916. +introductory statement regarding license alternatives, (ii) delete the two
  69917. +license alternatives that you have not elected to use and (iii) preserve the
  69918. +Marvell copyright notice above.
  69919. +
  69920. +********************************************************************************
  69921. +Marvell Commercial License Option
  69922. +
  69923. +If you received this File from Marvell and you have entered into a commercial
  69924. +license agreement (a "Commercial License") with Marvell, the File is licensed
  69925. +to you under the terms of the applicable Commercial License.
  69926. +
  69927. +********************************************************************************
  69928. +Marvell GPL License Option
  69929. +
  69930. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69931. +modify this File in accordance with the terms and conditions of the General
  69932. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  69933. +available along with the File in the license.txt file or by writing to the Free
  69934. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  69935. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  69936. +
  69937. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  69938. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  69939. +DISCLAIMED. The GPL License provides additional details about this warranty
  69940. +disclaimer.
  69941. +********************************************************************************
  69942. +Marvell BSD License Option
  69943. +
  69944. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69945. +modify this File under the following licensing terms.
  69946. +Redistribution and use in source and binary forms, with or without modification,
  69947. +are permitted provided that the following conditions are met:
  69948. +
  69949. + * Redistributions of source code must retain the above copyright notice,
  69950. + this list of conditions and the following disclaimer.
  69951. +
  69952. + * Redistributions in binary form must reproduce the above copyright
  69953. + notice, this list of conditions and the following disclaimer in the
  69954. + documentation and/or other materials provided with the distribution.
  69955. +
  69956. + * Neither the name of Marvell nor the names of its contributors may be
  69957. + used to endorse or promote products derived from this software without
  69958. + specific prior written permission.
  69959. +
  69960. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  69961. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  69962. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  69963. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  69964. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  69965. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  69966. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  69967. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  69968. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  69969. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  69970. +
  69971. +*******************************************************************************/
  69972. +
  69973. +/* includes */
  69974. +#include "mvPciUtils.h"
  69975. +
  69976. +#include "ctrlEnv/mvCtrlEnvLib.h"
  69977. +
  69978. +/* #define MV_DEBUG */
  69979. +/* defines */
  69980. +#ifdef MV_DEBUG
  69981. + #define DB(x) x
  69982. + #define mvOsPrintf printf
  69983. +#else
  69984. + #define DB(x)
  69985. +#endif
  69986. +
  69987. +/*
  69988. +This module only support scanning of Header type 00h of pci devices
  69989. +There is no suppotr for Header type 01h of pci devices ( PCI bridges )
  69990. +*/
  69991. +
  69992. +
  69993. +static MV_STATUS pciDetectDevice(MV_U32 pciIf,
  69994. + MV_U32 bus,
  69995. + MV_U32 dev,
  69996. + MV_U32 func,
  69997. + MV_PCI_DEVICE *pPciAgent);
  69998. +
  69999. +static MV_U32 pciDetectDeviceBars(MV_U32 pciIf,
  70000. + MV_U32 bus,
  70001. + MV_U32 dev,
  70002. + MV_U32 func,
  70003. + MV_PCI_DEVICE *pPciAgent);
  70004. +
  70005. +
  70006. +
  70007. +
  70008. +
  70009. +
  70010. +/*******************************************************************************
  70011. +* mvPciScan - Scan a PCI interface bus
  70012. +*
  70013. +* DESCRIPTION:
  70014. +* Performs a full scan on a PCI interface and returns all possible details
  70015. +* on the agents found on the bus.
  70016. +*
  70017. +* INPUT:
  70018. +* pciIf - PCI Interface
  70019. +* pPciAgents - Pointer to an Array of the pci agents to be detected
  70020. +* pPciAgentsNum - pPciAgents array maximum number of elements
  70021. +*
  70022. +* OUTPUT:
  70023. +* pPciAgents - Array of the pci agents detected on the bus
  70024. +* pPciAgentsNum - Number of pci agents detected on the bus
  70025. +*
  70026. +* RETURN:
  70027. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  70028. +*
  70029. +*******************************************************************************/
  70030. +
  70031. +MV_STATUS mvPciScan(MV_U32 pciIf,
  70032. + MV_PCI_DEVICE *pPciAgents,
  70033. + MV_U32 *pPciAgentsNum)
  70034. +{
  70035. +
  70036. + MV_U32 devIndex,funcIndex=0,busIndex=0,detectedDevNum=0;
  70037. + MV_U32 localBus=mvPciIfLocalBusNumGet(pciIf);
  70038. + MV_PCI_DEVICE *pPciDevice;
  70039. + MV_PCI_DEVICE *pMainDevice;
  70040. +
  70041. + DB(mvOsPrintf("mvPciScan: PCI interface num %d\n", pciIf));
  70042. + /* Parameter checking */
  70043. + if (pciIf >= mvCtrlPexMaxIfGet())
  70044. + {
  70045. + DB(mvOsPrintf("mvPciScan: ERR. Invalid PCI interface num %d\n", pciIf));
  70046. + return MV_BAD_PARAM;
  70047. + }
  70048. + if (NULL == pPciAgents)
  70049. + {
  70050. + DB(mvOsPrintf("mvPciScan: ERR. pPciAgents=NULL \n"));
  70051. + return MV_BAD_PARAM;
  70052. + }
  70053. + if (NULL == pPciAgentsNum)
  70054. + {
  70055. + DB(mvOsPrintf("mvPciScan: ERR. pPciAgentsNum=NULL \n"));
  70056. + return MV_BAD_PARAM;
  70057. + }
  70058. +
  70059. +
  70060. + DB(mvOsPrintf("mvPciScan: PCI interface num %d mvPciMasterEnable\n", pciIf));
  70061. + /* Master enable the MV PCI master */
  70062. + if (MV_OK != mvPciIfMasterEnable(pciIf,MV_TRUE))
  70063. + {
  70064. + DB(mvOsPrintf("mvPciScan: ERR. mvPciMasterEnable failed \n"));
  70065. + return MV_ERROR;
  70066. +
  70067. + }
  70068. +
  70069. + DB(mvOsPrintf("mvPciScan: PCI interface num scan%d\n", pciIf));
  70070. +
  70071. + /* go through all busses */
  70072. + for (busIndex=localBus ; busIndex < MAX_PCI_BUSSES ; busIndex++)
  70073. + {
  70074. + /* go through all possible devices on the local bus */
  70075. + for (devIndex=0 ; devIndex < MAX_PCI_DEVICES ; devIndex++)
  70076. + {
  70077. + /* always start with function equal to zero */
  70078. + funcIndex=0;
  70079. +
  70080. + pPciDevice=&pPciAgents[detectedDevNum];
  70081. + DB(mvOsPrintf("mvPciScan: PCI interface num scan%d:%d\n", busIndex, devIndex));
  70082. +
  70083. + if (MV_ERROR == pciDetectDevice(pciIf,
  70084. + busIndex,
  70085. + devIndex,
  70086. + funcIndex,
  70087. + pPciDevice))
  70088. + {
  70089. + /* no device detected , try the next address */
  70090. + continue;
  70091. + }
  70092. +
  70093. + /* We are here ! means we have detected a device*/
  70094. + /* always we start with only one function per device */
  70095. + pMainDevice = pPciDevice;
  70096. + pPciDevice->funtionsNum = 1;
  70097. +
  70098. +
  70099. + /* move on */
  70100. + detectedDevNum++;
  70101. +
  70102. +
  70103. + /* check if we have no more room for a new device */
  70104. + if (detectedDevNum == *pPciAgentsNum)
  70105. + {
  70106. + DB(mvOsPrintf("mvPciScan: ERR. array passed too small \n"));
  70107. + return MV_ERROR;
  70108. + }
  70109. +
  70110. + /* check the detected device if it is a multi functional device then
  70111. + scan all device functions*/
  70112. + if (pPciDevice->isMultiFunction == MV_TRUE)
  70113. + {
  70114. + /* start with function number 1 because we have already detected
  70115. + function 0 */
  70116. + for (funcIndex=1; funcIndex<MAX_PCI_FUNCS ; funcIndex++)
  70117. + {
  70118. + pPciDevice=&pPciAgents[detectedDevNum];
  70119. +
  70120. + if (MV_ERROR == pciDetectDevice(pciIf,
  70121. + busIndex,
  70122. + devIndex,
  70123. + funcIndex,
  70124. + pPciDevice))
  70125. + {
  70126. + /* no device detected means no more functions !*/
  70127. + continue;
  70128. + }
  70129. + /* We are here ! means we have detected a device */
  70130. +
  70131. + /* move on */
  70132. + pMainDevice->funtionsNum++;
  70133. + detectedDevNum++;
  70134. +
  70135. + /* check if we have no more room for a new device */
  70136. + if (detectedDevNum == *pPciAgentsNum)
  70137. + {
  70138. + DB(mvOsPrintf("mvPciScan: ERR. Array too small\n"));
  70139. + return MV_ERROR;
  70140. + }
  70141. +
  70142. +
  70143. + }
  70144. + }
  70145. +
  70146. + }
  70147. +
  70148. + }
  70149. +
  70150. + /* return the number of devices actually detected on the bus ! */
  70151. + *pPciAgentsNum = detectedDevNum;
  70152. +
  70153. + return MV_OK;
  70154. +
  70155. +}
  70156. +
  70157. +
  70158. +/*******************************************************************************
  70159. +* pciDetectDevice - Detect a pci device parameters
  70160. +*
  70161. +* DESCRIPTION:
  70162. +* This function detect if a pci agent exist on certain address !
  70163. +* and if exists then it fills all possible information on the
  70164. +* agent
  70165. +*
  70166. +* INPUT:
  70167. +* pciIf - PCI Interface
  70168. +* bus - Bus number
  70169. +* dev - Device number
  70170. +* func - Function number
  70171. +*
  70172. +*
  70173. +*
  70174. +* OUTPUT:
  70175. +* pPciAgent - pointer to the pci agent filled with its information
  70176. +*
  70177. +* RETURN:
  70178. +* MV_ERROR if no device , MV_OK otherwise
  70179. +*
  70180. +*******************************************************************************/
  70181. +
  70182. +static MV_STATUS pciDetectDevice(MV_U32 pciIf,
  70183. + MV_U32 bus,
  70184. + MV_U32 dev,
  70185. + MV_U32 func,
  70186. + MV_PCI_DEVICE *pPciAgent)
  70187. +{
  70188. + MV_U32 pciData;
  70189. +
  70190. + /* no Parameters checking ! because it is static function and it is assumed
  70191. + that all parameters were checked in the calling function */
  70192. +
  70193. +
  70194. + /* Try read the PCI Vendor ID and Device ID */
  70195. +
  70196. + /* We will scan only ourselves and the PCI slots that exist on the
  70197. + board, because we may have a case that we have one slot that has
  70198. + a Cardbus connector, and because CardBus answers all IDsels we want
  70199. + to scan only this slot and ourseleves.
  70200. +
  70201. + */
  70202. + #if defined(MV_INCLUDE_PCI)
  70203. + if ((PCI_IF_TYPE_CONVEN_PCIX == mvPciIfTypeGet(pciIf)) &&
  70204. + (DB_88F5181_DDR1_PRPMC != mvBoardIdGet()) &&
  70205. + (DB_88F5181_DDR1_PEXPCI != mvBoardIdGet()) &&
  70206. + (DB_88F5181_DDR1_MNG != mvBoardIdGet()))
  70207. + {
  70208. +
  70209. + if (mvBoardIsOurPciSlot(bus, dev) == MV_FALSE)
  70210. + {
  70211. + return MV_ERROR;
  70212. + }
  70213. + }
  70214. + #endif /* defined(MV_INCLUDE_PCI) */
  70215. +
  70216. + pciData = mvPciIfConfigRead(pciIf, bus,dev,func, PCI_DEVICE_AND_VENDOR_ID);
  70217. +
  70218. + if (PCI_ERROR_CODE == pciData)
  70219. + {
  70220. + /* no device exist */
  70221. + return MV_ERROR;
  70222. + }
  70223. +
  70224. + /* we are here ! means a device is detected */
  70225. +
  70226. + /* fill basic information */
  70227. + pPciAgent->busNumber=bus;
  70228. + pPciAgent->deviceNum=dev;
  70229. + pPciAgent->function=func;
  70230. +
  70231. + /* Fill the PCI Vendor ID and Device ID */
  70232. +
  70233. + pPciAgent->venID = (pciData & PDVIR_VEN_ID_MASK) >> PDVIR_VEN_ID_OFFS;
  70234. + pPciAgent->deviceID = (pciData & PDVIR_DEV_ID_MASK) >> PDVIR_DEV_ID_OFFS;
  70235. +
  70236. + /* Read Status and command */
  70237. + pciData = mvPciIfConfigRead(pciIf,
  70238. + bus,dev,func,
  70239. + PCI_STATUS_AND_COMMAND);
  70240. +
  70241. +
  70242. + /* Fill related Status and Command information*/
  70243. +
  70244. + if (pciData & PSCR_TAR_FAST_BB)
  70245. + {
  70246. + pPciAgent->isFastB2BCapable = MV_TRUE;
  70247. + }
  70248. + else
  70249. + {
  70250. + pPciAgent->isFastB2BCapable = MV_FALSE;
  70251. + }
  70252. +
  70253. + if (pciData & PSCR_CAP_LIST)
  70254. + {
  70255. + pPciAgent->isCapListSupport=MV_TRUE;
  70256. + }
  70257. + else
  70258. + {
  70259. + pPciAgent->isCapListSupport=MV_FALSE;
  70260. + }
  70261. +
  70262. + if (pciData & PSCR_66MHZ_EN)
  70263. + {
  70264. + pPciAgent->is66MHZCapable=MV_TRUE;
  70265. + }
  70266. + else
  70267. + {
  70268. + pPciAgent->is66MHZCapable=MV_FALSE;
  70269. + }
  70270. +
  70271. + /* Read Class Code and Revision */
  70272. + pciData = mvPciIfConfigRead(pciIf,
  70273. + bus,dev,func,
  70274. + PCI_CLASS_CODE_AND_REVISION_ID);
  70275. +
  70276. +
  70277. + pPciAgent->baseClassCode =
  70278. + (pciData & PCCRIR_BASE_CLASS_MASK) >> PCCRIR_BASE_CLASS_OFFS;
  70279. +
  70280. + pPciAgent->subClassCode =
  70281. + (pciData & PCCRIR_SUB_CLASS_MASK) >> PCCRIR_SUB_CLASS_OFFS;
  70282. +
  70283. + pPciAgent->progIf =
  70284. + (pciData & PCCRIR_PROGIF_MASK) >> PCCRIR_PROGIF_OFFS;
  70285. +
  70286. + pPciAgent->revisionID =
  70287. + (pciData & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS;
  70288. +
  70289. + /* Read PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE */
  70290. + pciData = mvPciIfConfigRead(pciIf,
  70291. + bus,dev,func,
  70292. + PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE);
  70293. +
  70294. +
  70295. +
  70296. + pPciAgent->pciCacheLine=
  70297. + (pciData & PBHTLTCLR_CACHELINE_MASK ) >> PBHTLTCLR_CACHELINE_OFFS;
  70298. + pPciAgent->pciLatencyTimer=
  70299. + (pciData & PBHTLTCLR_LATTIMER_MASK) >> PBHTLTCLR_LATTIMER_OFFS;
  70300. +
  70301. + switch (pciData & PBHTLTCLR_HEADER_MASK)
  70302. + {
  70303. + case PBHTLTCLR_HEADER_STANDARD:
  70304. +
  70305. + pPciAgent->pciHeader=MV_PCI_STANDARD;
  70306. + break;
  70307. + case PBHTLTCLR_HEADER_PCI2PCI_BRIDGE:
  70308. +
  70309. + pPciAgent->pciHeader=MV_PCI_PCI2PCI_BRIDGE;
  70310. + break;
  70311. +
  70312. + }
  70313. +
  70314. + if (pciData & PBHTLTCLR_MULTI_FUNC)
  70315. + {
  70316. + pPciAgent->isMultiFunction=MV_TRUE;
  70317. + }
  70318. + else
  70319. + {
  70320. + pPciAgent->isMultiFunction=MV_FALSE;
  70321. + }
  70322. +
  70323. + if (pciData & PBHTLTCLR_BISTCAP)
  70324. + {
  70325. + pPciAgent->isBISTCapable=MV_TRUE;
  70326. + }
  70327. + else
  70328. + {
  70329. + pPciAgent->isBISTCapable=MV_FALSE;
  70330. + }
  70331. +
  70332. +
  70333. + /* read this device pci bars */
  70334. +
  70335. + pciDetectDeviceBars(pciIf,
  70336. + bus,dev,func,
  70337. + pPciAgent);
  70338. +
  70339. +
  70340. + /* check if we are bridge*/
  70341. + if ((pPciAgent->baseClassCode == PCI_BRIDGE_CLASS)&&
  70342. + (pPciAgent->subClassCode == P2P_BRIDGE_SUB_CLASS_CODE))
  70343. + {
  70344. +
  70345. + /* Read P2P_BUSSES_NUM */
  70346. + pciData = mvPciIfConfigRead(pciIf,
  70347. + bus,dev,func,
  70348. + P2P_BUSSES_NUM);
  70349. +
  70350. + pPciAgent->p2pPrimBusNum =
  70351. + (pciData & PBM_PRIME_BUS_NUM_MASK) >> PBM_PRIME_BUS_NUM_OFFS;
  70352. +
  70353. + pPciAgent->p2pSecBusNum =
  70354. + (pciData & PBM_SEC_BUS_NUM_MASK) >> PBM_SEC_BUS_NUM_OFFS;
  70355. +
  70356. + pPciAgent->p2pSubBusNum =
  70357. + (pciData & PBM_SUB_BUS_NUM_MASK) >> PBM_SUB_BUS_NUM_OFFS;
  70358. +
  70359. + pPciAgent->p2pSecLatencyTimer =
  70360. + (pciData & PBM_SEC_LAT_TMR_MASK) >> PBM_SEC_LAT_TMR_OFFS;
  70361. +
  70362. + /* Read P2P_IO_BASE_LIMIT_SEC_STATUS */
  70363. + pciData = mvPciIfConfigRead(pciIf,
  70364. + bus,dev,func,
  70365. + P2P_IO_BASE_LIMIT_SEC_STATUS);
  70366. +
  70367. + pPciAgent->p2pSecStatus =
  70368. + (pciData & PIBLSS_SEC_STATUS_MASK) >> PIBLSS_SEC_STATUS_OFFS;
  70369. +
  70370. +
  70371. + pPciAgent->p2pIObase =
  70372. + (pciData & PIBLSS_IO_BASE_MASK) << PIBLSS_IO_LIMIT_OFFS;
  70373. +
  70374. + /* clear low address (should be zero)*/
  70375. + pPciAgent->p2pIObase &= PIBLSS_HIGH_ADDR_MASK;
  70376. +
  70377. + pPciAgent->p2pIOLimit =
  70378. + (pciData & PIBLSS_IO_LIMIT_MASK);
  70379. +
  70380. + /* fill low address with 0xfff */
  70381. + pPciAgent->p2pIOLimit |= PIBLSS_LOW_ADDR_MASK;
  70382. +
  70383. +
  70384. + switch ((pciData & PIBLSS_ADD_CAP_MASK) >> PIBLSS_ADD_CAP_OFFS)
  70385. + {
  70386. + case PIBLSS_ADD_CAP_16BIT:
  70387. +
  70388. + pPciAgent->bIO32 = MV_FALSE;
  70389. +
  70390. + break;
  70391. + case PIBLSS_ADD_CAP_32BIT:
  70392. +
  70393. + pPciAgent->bIO32 = MV_TRUE;
  70394. +
  70395. + /* Read P2P_IO_BASE_LIMIT_UPPER_16 */
  70396. + pciData = mvPciIfConfigRead(pciIf,
  70397. + bus,dev,func,
  70398. + P2P_IO_BASE_LIMIT_UPPER_16);
  70399. +
  70400. + pPciAgent->p2pIObase |=
  70401. + (pciData & PRBU_IO_UPP_BASE_MASK) << PRBU_IO_UPP_LIMIT_OFFS;
  70402. +
  70403. +
  70404. + pPciAgent->p2pIOLimit |=
  70405. + (pciData & PRBU_IO_UPP_LIMIT_MASK);
  70406. +
  70407. + break;
  70408. +
  70409. + }
  70410. +
  70411. +
  70412. + /* Read P2P_MEM_BASE_LIMIT */
  70413. + pciData = mvPciIfConfigRead(pciIf,
  70414. + bus,dev,func,
  70415. + P2P_MEM_BASE_LIMIT);
  70416. +
  70417. + pPciAgent->p2pMemBase =
  70418. + (pciData & PMBL_MEM_BASE_MASK) << PMBL_MEM_LIMIT_OFFS;
  70419. +
  70420. + /* clear low address */
  70421. + pPciAgent->p2pMemBase &= PMBL_HIGH_ADDR_MASK;
  70422. +
  70423. + pPciAgent->p2pMemLimit =
  70424. + (pciData & PMBL_MEM_LIMIT_MASK);
  70425. +
  70426. + /* add 0xfffff */
  70427. + pPciAgent->p2pMemLimit |= PMBL_LOW_ADDR_MASK;
  70428. +
  70429. +
  70430. + /* Read P2P_PREF_MEM_BASE_LIMIT */
  70431. + pciData = mvPciIfConfigRead(pciIf,
  70432. + bus,dev,func,
  70433. + P2P_PREF_MEM_BASE_LIMIT);
  70434. +
  70435. +
  70436. + pPciAgent->p2pPrefMemBase =
  70437. + (pciData & PRMBL_PREF_MEM_BASE_MASK) << PRMBL_PREF_MEM_LIMIT_OFFS;
  70438. +
  70439. + /* get high address only */
  70440. + pPciAgent->p2pPrefMemBase &= PRMBL_HIGH_ADDR_MASK;
  70441. +
  70442. +
  70443. +
  70444. + pPciAgent->p2pPrefMemLimit =
  70445. + (pciData & PRMBL_PREF_MEM_LIMIT_MASK);
  70446. +
  70447. + /* add 0xfffff */
  70448. + pPciAgent->p2pPrefMemLimit |= PRMBL_LOW_ADDR_MASK;
  70449. +
  70450. + switch (pciData & PRMBL_ADD_CAP_MASK)
  70451. + {
  70452. + case PRMBL_ADD_CAP_32BIT:
  70453. +
  70454. + pPciAgent->bPrefMem64 = MV_FALSE;
  70455. +
  70456. + /* Read P2P_PREF_BASE_UPPER_32 */
  70457. + pPciAgent->p2pPrefBaseUpper32Bits = 0;
  70458. +
  70459. + /* Read P2P_PREF_LIMIT_UPPER_32 */
  70460. + pPciAgent->p2pPrefLimitUpper32Bits = 0;
  70461. +
  70462. + break;
  70463. + case PRMBL_ADD_CAP_64BIT:
  70464. +
  70465. + pPciAgent->bPrefMem64 = MV_TRUE;
  70466. +
  70467. + /* Read P2P_PREF_BASE_UPPER_32 */
  70468. + pPciAgent->p2pPrefBaseUpper32Bits = mvPciIfConfigRead(pciIf,
  70469. + bus,dev,func,
  70470. + P2P_PREF_BASE_UPPER_32);
  70471. +
  70472. + /* Read P2P_PREF_LIMIT_UPPER_32 */
  70473. + pPciAgent->p2pPrefLimitUpper32Bits = mvPciIfConfigRead(pciIf,
  70474. + bus,dev,func,
  70475. + P2P_PREF_LIMIT_UPPER_32);
  70476. +
  70477. + break;
  70478. +
  70479. + }
  70480. +
  70481. + }
  70482. + else /* no bridge */
  70483. + {
  70484. + /* Read PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID */
  70485. + pciData = mvPciIfConfigRead(pciIf,
  70486. + bus,dev,func,
  70487. + PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID);
  70488. +
  70489. +
  70490. + pPciAgent->subSysVenID =
  70491. + (pciData & PSISVIR_VENID_MASK) >> PSISVIR_VENID_OFFS;
  70492. + pPciAgent->subSysID =
  70493. + (pciData & PSISVIR_DEVID_MASK) >> PSISVIR_DEVID_OFFS;
  70494. +
  70495. +
  70496. + /* Read PCI_EXPANSION_ROM_BASE_ADDR_REG */
  70497. + pciData = mvPciIfConfigRead(pciIf,
  70498. + bus,dev,func,
  70499. + PCI_EXPANSION_ROM_BASE_ADDR_REG);
  70500. +
  70501. +
  70502. + if (pciData & PERBAR_EXPROMEN)
  70503. + {
  70504. + pPciAgent->isExpRom = MV_TRUE;
  70505. + }
  70506. + else
  70507. + {
  70508. + pPciAgent->isExpRom = MV_FALSE;
  70509. + }
  70510. +
  70511. + pPciAgent->expRomAddr =
  70512. + (pciData & PERBAR_BASE_MASK) >> PERBAR_BASE_OFFS;
  70513. +
  70514. + }
  70515. +
  70516. +
  70517. + if (MV_TRUE == pPciAgent->isCapListSupport)
  70518. + {
  70519. + /* Read PCI_CAPABILTY_LIST_POINTER */
  70520. + pciData = mvPciIfConfigRead(pciIf,
  70521. + bus,dev,func,
  70522. + PCI_CAPABILTY_LIST_POINTER);
  70523. +
  70524. + pPciAgent->capListPointer =
  70525. + (pciData & PCLPR_CAPPTR_MASK) >> PCLPR_CAPPTR_OFFS;
  70526. +
  70527. + }
  70528. +
  70529. + /* Read PCI_INTERRUPT_PIN_AND_LINE */
  70530. + pciData = mvPciIfConfigRead(pciIf,
  70531. + bus,dev,func,
  70532. + PCI_INTERRUPT_PIN_AND_LINE);
  70533. +
  70534. +
  70535. + pPciAgent->irqLine=
  70536. + (pciData & PIPLR_INTLINE_MASK) >> PIPLR_INTLINE_OFFS;
  70537. +
  70538. + pPciAgent->intPin=
  70539. + (MV_PCI_INT_PIN)(pciData & PIPLR_INTPIN_MASK) >> PIPLR_INTPIN_OFFS;
  70540. +
  70541. + pPciAgent->minGrant=
  70542. + (pciData & PIPLR_MINGRANT_MASK) >> PIPLR_MINGRANT_OFFS;
  70543. + pPciAgent->maxLatency=
  70544. + (pciData & PIPLR_MAXLATEN_MASK) >> PIPLR_MAXLATEN_OFFS;
  70545. +
  70546. + mvPciClassNameGet(pPciAgent->baseClassCode,
  70547. + (MV_8 *)pPciAgent->type);
  70548. +
  70549. + return MV_OK;
  70550. +
  70551. +
  70552. +}
  70553. +
  70554. +/*******************************************************************************
  70555. +* pciDetectDeviceBars - Detect a pci device bars
  70556. +*
  70557. +* DESCRIPTION:
  70558. +* This function detects all pci agent bars
  70559. +*
  70560. +* INPUT:
  70561. +* pciIf - PCI Interface
  70562. +* bus - Bus number
  70563. +* dev - Device number
  70564. +* func - Function number
  70565. +*
  70566. +*
  70567. +*
  70568. +* OUTPUT:
  70569. +* pPciAgent - pointer to the pci agent filled with its information
  70570. +*
  70571. +* RETURN:
  70572. +* detected bars number
  70573. +*
  70574. +*******************************************************************************/
  70575. +static MV_U32 pciDetectDeviceBars(MV_U32 pciIf,
  70576. + MV_U32 bus,
  70577. + MV_U32 dev,
  70578. + MV_U32 func,
  70579. + MV_PCI_DEVICE *pPciAgent)
  70580. +{
  70581. + MV_U32 pciData,barIndex,detectedBar=0;
  70582. + MV_U32 tmpBaseHigh=0,tmpBaseLow=0;
  70583. + MV_U32 pciMaxBars=0;
  70584. +
  70585. + pPciAgent->barsNum=0;
  70586. +
  70587. + /* check if we are bridge*/
  70588. + if ((pPciAgent->baseClassCode == PCI_BRIDGE_CLASS)&&
  70589. + (pPciAgent->subClassCode == P2P_BRIDGE_SUB_CLASS_CODE))
  70590. + {
  70591. + pciMaxBars = 2;
  70592. + }
  70593. + else /* no bridge */
  70594. + {
  70595. + pciMaxBars = 6;
  70596. + }
  70597. +
  70598. + /* read this device pci bars */
  70599. + for (barIndex = 0 ; barIndex < pciMaxBars ; barIndex++ )
  70600. + {
  70601. + /* Read PCI_MEMORY_BAR_BASE_ADDR */
  70602. + tmpBaseLow = pciData = mvPciIfConfigRead(pciIf,
  70603. + bus,dev,func,
  70604. + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
  70605. +
  70606. + pPciAgent->pciBar[detectedBar].barOffset =
  70607. + PCI_MEMORY_BAR_BASE_ADDR(barIndex);
  70608. +
  70609. + /* check if the bar is 32bit or 64bit bar */
  70610. + switch (pciData & PBBLR_TYPE_MASK)
  70611. + {
  70612. + case PBBLR_TYPE_32BIT_ADDR:
  70613. + pPciAgent->pciBar[detectedBar].barType = PCI_32BIT_BAR;
  70614. + break;
  70615. + case PBBLR_TYPE_64BIT_ADDR:
  70616. + pPciAgent->pciBar[detectedBar].barType = PCI_64BIT_BAR;
  70617. + break;
  70618. +
  70619. + }
  70620. +
  70621. + /* check if it is memory or IO bar */
  70622. + if (pciData & PBBLR_IOSPACE)
  70623. + {
  70624. + pPciAgent->pciBar[detectedBar].barMapping=PCI_IO_BAR;
  70625. + }
  70626. + else
  70627. + {
  70628. + pPciAgent->pciBar[detectedBar].barMapping=PCI_MEMORY_BAR;
  70629. + }
  70630. +
  70631. + /* if it is memory bar then check if it is prefetchable */
  70632. + if (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping)
  70633. + {
  70634. + if (pciData & PBBLR_PREFETCH_EN)
  70635. + {
  70636. + pPciAgent->pciBar[detectedBar].isPrefetchable = MV_TRUE;
  70637. + }
  70638. + else
  70639. + {
  70640. + pPciAgent->pciBar[detectedBar].isPrefetchable = MV_FALSE;
  70641. + }
  70642. +
  70643. + pPciAgent->pciBar[detectedBar].barBaseLow =
  70644. + pciData & PBBLR_MEM_BASE_MASK;
  70645. +
  70646. +
  70647. + }
  70648. + else /* IO Bar */
  70649. + {
  70650. + pPciAgent->pciBar[detectedBar].barBaseLow =
  70651. + pciData & PBBLR_IO_BASE_MASK;
  70652. +
  70653. + }
  70654. +
  70655. + pPciAgent->pciBar[detectedBar].barBaseHigh=0;
  70656. +
  70657. + if (PCI_64BIT_BAR == pPciAgent->pciBar[detectedBar].barType)
  70658. + {
  70659. + barIndex++;
  70660. +
  70661. + tmpBaseHigh = pPciAgent->pciBar[detectedBar].barBaseHigh =
  70662. + mvPciIfConfigRead(pciIf,
  70663. + bus,dev,func,
  70664. + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
  70665. +
  70666. +
  70667. + }
  70668. +
  70669. + /* calculating full base address (64bit) */
  70670. + pPciAgent->pciBar[detectedBar].barBaseAddr =
  70671. + (MV_U64)pPciAgent->pciBar[detectedBar].barBaseHigh;
  70672. +
  70673. + pPciAgent->pciBar[detectedBar].barBaseAddr <<= 32;
  70674. +
  70675. + pPciAgent->pciBar[detectedBar].barBaseAddr |=
  70676. + (MV_U64)pPciAgent->pciBar[detectedBar].barBaseLow;
  70677. +
  70678. +
  70679. +
  70680. + /* get the sizes of the the bar */
  70681. +
  70682. + pPciAgent->pciBar[detectedBar].barSizeHigh=0;
  70683. +
  70684. + if ((PCI_64BIT_BAR == pPciAgent->pciBar[detectedBar].barType) &&
  70685. + (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping))
  70686. +
  70687. + {
  70688. + /* write oxffffffff to the bar to get the size */
  70689. + /* start with sizelow ( original value was saved in tmpBaseLow ) */
  70690. + mvPciIfConfigWrite(pciIf,
  70691. + bus,dev,func,
  70692. + PCI_MEMORY_BAR_BASE_ADDR(barIndex-1),
  70693. + 0xffffffff);
  70694. +
  70695. + /* read size */
  70696. + pPciAgent->pciBar[detectedBar].barSizeLow =
  70697. + mvPciIfConfigRead(pciIf,
  70698. + bus,dev,func,
  70699. + PCI_MEMORY_BAR_BASE_ADDR(barIndex-1));
  70700. +
  70701. +
  70702. +
  70703. + /* restore original value */
  70704. + mvPciIfConfigWrite(pciIf,
  70705. + bus,dev,func,
  70706. + PCI_MEMORY_BAR_BASE_ADDR(barIndex-1),
  70707. + tmpBaseLow);
  70708. +
  70709. +
  70710. + /* now do the same for BaseHigh */
  70711. +
  70712. + /* write oxffffffff to the bar to get the size */
  70713. + mvPciIfConfigWrite(pciIf,
  70714. + bus,dev,func,
  70715. + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
  70716. + 0xffffffff);
  70717. +
  70718. + /* read size */
  70719. + pPciAgent->pciBar[detectedBar].barSizeHigh =
  70720. + mvPciIfConfigRead(pciIf,
  70721. + bus,dev,func,
  70722. + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
  70723. +
  70724. + /* restore original value */
  70725. + mvPciIfConfigWrite(pciIf,
  70726. + bus,dev,func,
  70727. + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
  70728. + tmpBaseHigh);
  70729. +
  70730. + if ((0 == pPciAgent->pciBar[detectedBar].barSizeLow)&&
  70731. + (0 == pPciAgent->pciBar[detectedBar].barSizeHigh))
  70732. + {
  70733. + /* this bar is not applicable for this device,
  70734. + ignore all previous settings and check the next bar*/
  70735. +
  70736. + /* we though this was a 64bit bar , and it seems this
  70737. + was wrong ! so decrement barIndex */
  70738. + barIndex--;
  70739. + continue;
  70740. + }
  70741. +
  70742. + /* calculate the full 64 bit size */
  70743. +
  70744. + if (0 != pPciAgent->pciBar[detectedBar].barSizeHigh)
  70745. + {
  70746. + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
  70747. +
  70748. + pPciAgent->pciBar[detectedBar].barSizeLow =
  70749. + ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
  70750. +
  70751. + pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
  70752. +
  70753. + }
  70754. + else
  70755. + {
  70756. +
  70757. + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
  70758. +
  70759. + pPciAgent->pciBar[detectedBar].barSizeLow =
  70760. + ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
  70761. +
  70762. + pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
  70763. +
  70764. + }
  70765. +
  70766. +
  70767. +
  70768. + }
  70769. + else /* 32bit bar */
  70770. + {
  70771. + /* write oxffffffff to the bar to get the size */
  70772. + mvPciIfConfigWrite(pciIf,
  70773. + bus,dev,func,
  70774. + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
  70775. + 0xffffffff);
  70776. +
  70777. + /* read size */
  70778. + pPciAgent->pciBar[detectedBar].barSizeLow =
  70779. + mvPciIfConfigRead(pciIf,
  70780. + bus,dev,func,
  70781. + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
  70782. +
  70783. + if (0 == pPciAgent->pciBar[detectedBar].barSizeLow)
  70784. + {
  70785. + /* this bar is not applicable for this device,
  70786. + ignore all previous settings and check the next bar*/
  70787. + continue;
  70788. + }
  70789. +
  70790. +
  70791. + /* restore original value */
  70792. + mvPciIfConfigWrite(pciIf,
  70793. + bus,dev,func,
  70794. + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
  70795. + tmpBaseLow);
  70796. +
  70797. + /* calculate size low */
  70798. +
  70799. + if (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping)
  70800. + {
  70801. + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
  70802. + }
  70803. + else
  70804. + {
  70805. + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_IO_BASE_MASK;
  70806. + }
  70807. +
  70808. + pPciAgent->pciBar[detectedBar].barSizeLow =
  70809. + ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
  70810. +
  70811. + pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
  70812. + pPciAgent->pciBar[detectedBar].barSize =
  70813. + (MV_U64)pPciAgent->pciBar[detectedBar].barSizeLow;
  70814. +
  70815. +
  70816. + }
  70817. +
  70818. + /* we are here ! this means we have already detected a bar for
  70819. + this device , now move on */
  70820. +
  70821. + detectedBar++;
  70822. + pPciAgent->barsNum++;
  70823. + }
  70824. +
  70825. + return detectedBar;
  70826. +}
  70827. +
  70828. +
  70829. +/*******************************************************************************
  70830. +* mvPciClassNameGet - get PCI class name
  70831. +*
  70832. +* DESCRIPTION:
  70833. +* This function returns the PCI class name
  70834. +*
  70835. +* INPUT:
  70836. +* baseClassCode - Base Class Code.
  70837. +*
  70838. +* OUTPUT:
  70839. +* pType - the class name
  70840. +*
  70841. +* RETURN:
  70842. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  70843. +*
  70844. +*******************************************************************************/
  70845. +MV_STATUS mvPciClassNameGet(MV_U32 baseClassCode, MV_8 *pType)
  70846. +{
  70847. +
  70848. + switch(baseClassCode)
  70849. + {
  70850. + case 0x0:
  70851. + strcpy(pType,"Old generation device");
  70852. + break;
  70853. + case 0x1:
  70854. + strcpy(pType,"Mass storage controller");
  70855. + break;
  70856. + case 0x2:
  70857. + strcpy(pType,"Network controller");
  70858. + break;
  70859. + case 0x3:
  70860. + strcpy(pType,"Display controller");
  70861. + break;
  70862. + case 0x4:
  70863. + strcpy(pType,"Multimedia device");
  70864. + break;
  70865. + case 0x5:
  70866. + strcpy(pType,"Memory controller");
  70867. + break;
  70868. + case 0x6:
  70869. + strcpy(pType,"Bridge Device");
  70870. + break;
  70871. + case 0x7:
  70872. + strcpy(pType,"Simple Communication controllers");
  70873. + break;
  70874. + case 0x8:
  70875. + strcpy(pType,"Base system peripherals");
  70876. + break;
  70877. + case 0x9:
  70878. + strcpy(pType,"Input Devices");
  70879. + break;
  70880. + case 0xa:
  70881. + strcpy(pType,"Docking stations");
  70882. + break;
  70883. + case 0xb:
  70884. + strcpy(pType,"Processors");
  70885. + break;
  70886. + case 0xc:
  70887. + strcpy(pType,"Serial bus controllers");
  70888. + break;
  70889. + case 0xd:
  70890. + strcpy(pType,"Wireless controllers");
  70891. + break;
  70892. + case 0xe:
  70893. + strcpy(pType,"Intelligent I/O controllers");
  70894. + break;
  70895. + case 0xf:
  70896. + strcpy(pType,"Satellite communication controllers");
  70897. + break;
  70898. + case 0x10:
  70899. + strcpy(pType,"Encryption/Decryption controllers");
  70900. + break;
  70901. + case 0x11:
  70902. + strcpy(pType,"Data acquisition and signal processing controllers");
  70903. + break;
  70904. + default:
  70905. + strcpy(pType,"Unknown device");
  70906. + break;
  70907. + }
  70908. +
  70909. + return MV_OK;
  70910. +
  70911. +}
  70912. +
  70913. +
  70914. +
  70915. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h
  70916. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h 1970-01-01 01:00:00.000000000 +0100
  70917. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h 2010-08-05 22:02:25.174867964 +0200
  70918. @@ -0,0 +1,323 @@
  70919. +/*******************************************************************************
  70920. +Copyright (C) Marvell International Ltd. and its affiliates
  70921. +
  70922. +This software file (the "File") is owned and distributed by Marvell
  70923. +International Ltd. and/or its affiliates ("Marvell") under the following
  70924. +alternative licensing terms. Once you have made an election to distribute the
  70925. +File under one of the following license alternatives, please (i) delete this
  70926. +introductory statement regarding license alternatives, (ii) delete the two
  70927. +license alternatives that you have not elected to use and (iii) preserve the
  70928. +Marvell copyright notice above.
  70929. +
  70930. +********************************************************************************
  70931. +Marvell Commercial License Option
  70932. +
  70933. +If you received this File from Marvell and you have entered into a commercial
  70934. +license agreement (a "Commercial License") with Marvell, the File is licensed
  70935. +to you under the terms of the applicable Commercial License.
  70936. +
  70937. +********************************************************************************
  70938. +Marvell GPL License Option
  70939. +
  70940. +If you received this File from Marvell, you may opt to use, redistribute and/or
  70941. +modify this File in accordance with the terms and conditions of the General
  70942. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  70943. +available along with the File in the license.txt file or by writing to the Free
  70944. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  70945. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  70946. +
  70947. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  70948. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  70949. +DISCLAIMED. The GPL License provides additional details about this warranty
  70950. +disclaimer.
  70951. +********************************************************************************
  70952. +Marvell BSD License Option
  70953. +
  70954. +If you received this File from Marvell, you may opt to use, redistribute and/or
  70955. +modify this File under the following licensing terms.
  70956. +Redistribution and use in source and binary forms, with or without modification,
  70957. +are permitted provided that the following conditions are met:
  70958. +
  70959. + * Redistributions of source code must retain the above copyright notice,
  70960. + this list of conditions and the following disclaimer.
  70961. +
  70962. + * Redistributions in binary form must reproduce the above copyright
  70963. + notice, this list of conditions and the following disclaimer in the
  70964. + documentation and/or other materials provided with the distribution.
  70965. +
  70966. + * Neither the name of Marvell nor the names of its contributors may be
  70967. + used to endorse or promote products derived from this software without
  70968. + specific prior written permission.
  70969. +
  70970. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  70971. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  70972. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  70973. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  70974. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  70975. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  70976. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  70977. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  70978. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  70979. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  70980. +
  70981. +*******************************************************************************/
  70982. +
  70983. +#ifndef __INCmvPciUtilsh
  70984. +#define __INCmvPciUtilsh
  70985. +
  70986. +/*
  70987. +This module only support scanning of Header type 00h of pci devices
  70988. +There is no suppotr for Header type 01h of pci devices ( PCI bridges )
  70989. +*/
  70990. +
  70991. +/* includes */
  70992. +#include "mvSysHwConfig.h"
  70993. +#include "pci-if/mvPciIf.h"
  70994. +#include "pci/mvPciRegs.h"
  70995. +
  70996. +
  70997. +
  70998. +/* PCI base address low bar mask */
  70999. +#define PCI_ERROR_CODE 0xffffffff
  71000. +
  71001. +#define PCI_BRIDGE_CLASS 0x6
  71002. +#define P2P_BRIDGE_SUB_CLASS_CODE 0x4
  71003. +
  71004. +
  71005. +#define P2P_BUSSES_NUM 0x18
  71006. +#define P2P_IO_BASE_LIMIT_SEC_STATUS 0x1C
  71007. +#define P2P_MEM_BASE_LIMIT 0x20
  71008. +#define P2P_PREF_MEM_BASE_LIMIT 0x24
  71009. +#define P2P_PREF_BASE_UPPER_32 0x28
  71010. +#define P2P_PREF_LIMIT_UPPER_32 0x2C
  71011. +#define P2P_IO_BASE_LIMIT_UPPER_16 0x30
  71012. +#define P2P_EXP_ROM 0x38
  71013. +
  71014. +/* P2P_BUSSES_NUM (PBM) */
  71015. +
  71016. +#define PBM_PRIME_BUS_NUM_OFFS 0
  71017. +#define PBM_PRIME_BUS_NUM_MASK (0xff << PBM_PRIME_BUS_NUM_OFFS)
  71018. +
  71019. +#define PBM_SEC_BUS_NUM_OFFS 8
  71020. +#define PBM_SEC_BUS_NUM_MASK (0xff << PBM_SEC_BUS_NUM_OFFS)
  71021. +
  71022. +#define PBM_SUB_BUS_NUM_OFFS 16
  71023. +#define PBM_SUB_BUS_NUM_MASK (0xff << PBM_SUB_BUS_NUM_OFFS)
  71024. +
  71025. +#define PBM_SEC_LAT_TMR_OFFS 24
  71026. +#define PBM_SEC_LAT_TMR_MASK (0xff << PBM_SEC_LAT_TMR_OFFS)
  71027. +
  71028. +/* P2P_IO_BASE_LIMIT_SEC_STATUS (PIBLSS) */
  71029. +
  71030. +#define PIBLSS_IO_BASE_OFFS 0
  71031. +#define PIBLSS_IO_BASE_MASK (0xff << PIBLSS_IO_BASE_OFFS)
  71032. +
  71033. +#define PIBLSS_ADD_CAP_OFFS 0
  71034. +#define PIBLSS_ADD_CAP_MASK (0x3 << PIBLSS_ADD_CAP_OFFS)
  71035. +#define PIBLSS_ADD_CAP_16BIT (0x0 << PIBLSS_ADD_CAP_OFFS)
  71036. +#define PIBLSS_ADD_CAP_32BIT (0x1 << PIBLSS_ADD_CAP_OFFS)
  71037. +
  71038. +#define PIBLSS_LOW_ADDR_OFFS 0
  71039. +#define PIBLSS_LOW_ADDR_MASK (0xFFF << PIBLSS_LOW_ADDR_OFFS)
  71040. +
  71041. +#define PIBLSS_HIGH_ADDR_OFFS 12
  71042. +#define PIBLSS_HIGH_ADDR_MASK (0xF << PIBLSS_HIGH_ADDR_OFFS)
  71043. +
  71044. +#define PIBLSS_IO_LIMIT_OFFS 8
  71045. +#define PIBLSS_IO_LIMIT_MASK (0xff << PIBLSS_IO_LIMIT_OFFS)
  71046. +
  71047. +#define PIBLSS_SEC_STATUS_OFFS 16
  71048. +#define PIBLSS_SEC_STATUS_MASK (0xffff << PIBLSS_SEC_STATUS_OFFS)
  71049. +
  71050. +
  71051. +/* P2P_MEM_BASE_LIMIT (PMBL)*/
  71052. +
  71053. +#define PMBL_MEM_BASE_OFFS 0
  71054. +#define PMBL_MEM_BASE_MASK (0xffff << PMBL_MEM_BASE_OFFS)
  71055. +
  71056. +#define PMBL_MEM_LIMIT_OFFS 16
  71057. +#define PMBL_MEM_LIMIT_MASK (0xffff << PMBL_MEM_LIMIT_OFFS)
  71058. +
  71059. +
  71060. +#define PMBL_LOW_ADDR_OFFS 0
  71061. +#define PMBL_LOW_ADDR_MASK (0xFFFFF << PMBL_LOW_ADDR_OFFS)
  71062. +
  71063. +#define PMBL_HIGH_ADDR_OFFS 20
  71064. +#define PMBL_HIGH_ADDR_MASK (0xFFF << PMBL_HIGH_ADDR_OFFS)
  71065. +
  71066. +
  71067. +/* P2P_PREF_MEM_BASE_LIMIT (PRMBL) */
  71068. +
  71069. +#define PRMBL_PREF_MEM_BASE_OFFS 0
  71070. +#define PRMBL_PREF_MEM_BASE_MASK (0xffff << PRMBL_PREF_MEM_BASE_OFFS)
  71071. +
  71072. +#define PRMBL_PREF_MEM_LIMIT_OFFS 16
  71073. +#define PRMBL_PREF_MEM_LIMIT_MASK (0xffff<<PRMBL_PREF_MEM_LIMIT_OFFS)
  71074. +
  71075. +#define PRMBL_LOW_ADDR_OFFS 0
  71076. +#define PRMBL_LOW_ADDR_MASK (0xFFFFF << PRMBL_LOW_ADDR_OFFS)
  71077. +
  71078. +#define PRMBL_HIGH_ADDR_OFFS 20
  71079. +#define PRMBL_HIGH_ADDR_MASK (0xFFF << PRMBL_HIGH_ADDR_OFFS)
  71080. +
  71081. +#define PRMBL_ADD_CAP_OFFS 0
  71082. +#define PRMBL_ADD_CAP_MASK (0xf << PRMBL_ADD_CAP_OFFS)
  71083. +#define PRMBL_ADD_CAP_32BIT (0x0 << PRMBL_ADD_CAP_OFFS)
  71084. +#define PRMBL_ADD_CAP_64BIT (0x1 << PRMBL_ADD_CAP_OFFS)
  71085. +
  71086. +/* P2P_IO_BASE_LIMIT_UPPER_16 (PIBLU) */
  71087. +
  71088. +#define PRBU_IO_UPP_BASE_OFFS 0
  71089. +#define PRBU_IO_UPP_BASE_MASK (0xffff << PRBU_IO_UPP_BASE_OFFS)
  71090. +
  71091. +#define PRBU_IO_UPP_LIMIT_OFFS 16
  71092. +#define PRBU_IO_UPP_LIMIT_MASK (0xffff << PRBU_IO_UPP_LIMIT_OFFS)
  71093. +
  71094. +
  71095. +/* typedefs */
  71096. +
  71097. +typedef enum _mvPciBarMapping
  71098. +{
  71099. + PCI_MEMORY_BAR,
  71100. + PCI_IO_BAR,
  71101. + PCI_NO_MAPPING
  71102. +}MV_PCI_BAR_MAPPING;
  71103. +
  71104. +typedef enum _mvPciBarType
  71105. +{
  71106. + PCI_32BIT_BAR,
  71107. + PCI_64BIT_BAR
  71108. +}MV_PCI_BAR_TYPE;
  71109. +
  71110. +typedef enum _mvPciIntPin
  71111. +{
  71112. + MV_PCI_INTA = 1,
  71113. + MV_PCI_INTB = 2,
  71114. + MV_PCI_INTC = 3,
  71115. + MV_PCI_INTD = 4
  71116. +}MV_PCI_INT_PIN;
  71117. +
  71118. +typedef enum _mvPciHeader
  71119. +{
  71120. + MV_PCI_STANDARD,
  71121. + MV_PCI_PCI2PCI_BRIDGE
  71122. +
  71123. +}MV_PCI_HEADER;
  71124. +
  71125. +
  71126. +/* BAR structure */
  71127. +typedef struct _pciBar
  71128. +{
  71129. + MV_U32 barOffset;
  71130. + MV_U32 barBaseLow;
  71131. + MV_U32 barBaseHigh;
  71132. + MV_U32 barSizeLow;
  71133. + MV_U32 barSizeHigh;
  71134. + /* The 'barBaseAddr' is a 64-bit variable
  71135. + that will contain the TOTAL base address
  71136. + value achived by combining both the 'barBaseLow'
  71137. + and the 'barBaseHigh' parameters as follows:
  71138. +
  71139. + BIT: 63 31 0
  71140. + | | |
  71141. + barBaseHigh barBaseLow */
  71142. + MV_U64 barBaseAddr;
  71143. + /* The 'barSize' is a 64-bit variable
  71144. + that will contain the TOTAL size achived
  71145. + by combining both the 'barSizeLow' and
  71146. + the 'barSizeHigh' parameters as follows:
  71147. +
  71148. + BIT: 63 31 0
  71149. + | | |
  71150. + barSizeHigh barSizeLow
  71151. +
  71152. + NOTE: The total size described above
  71153. + is AFTER the size calculation as
  71154. + described in PCI spec rev2.2 */
  71155. + MV_U64 barSize;
  71156. + MV_BOOL isPrefetchable;
  71157. + MV_PCI_BAR_TYPE barType;
  71158. + MV_PCI_BAR_MAPPING barMapping;
  71159. +
  71160. +
  71161. +} PCI_BAR;
  71162. +
  71163. +/* Device information structure */
  71164. +typedef struct _mvPciDevice
  71165. +{
  71166. + /* Device specific information */
  71167. + MV_U32 busNumber; /* Pci agent bus number */
  71168. + MV_U32 deviceNum; /* Pci agent device number */
  71169. + MV_U32 function; /* Pci agent function number */
  71170. +
  71171. + MV_U32 venID; /* Pci agent Vendor ID */
  71172. + MV_U32 deviceID; /* Pci agent Device ID */
  71173. +
  71174. + MV_BOOL isFastB2BCapable; /* Capability of Fast Back to Back
  71175. + transactions */
  71176. + MV_BOOL isCapListSupport; /* Support of Capability list */
  71177. + MV_BOOL is66MHZCapable; /* 66MHZ support */
  71178. +
  71179. + MV_U32 baseClassCode; /* Pci agent base Class Code */
  71180. + MV_U32 subClassCode; /* Pci agent sub Class Code */
  71181. + MV_U32 progIf; /* Pci agent Programing interface */
  71182. + MV_U32 revisionID;
  71183. +
  71184. + PCI_BAR pciBar[6]; /* Pci agent bar list */
  71185. +
  71186. + MV_U32 p2pPrimBusNum; /* P2P Primary Bus number*/
  71187. + MV_U32 p2pSecBusNum; /* P2P Secondary Bus Number*/
  71188. + MV_U32 p2pSubBusNum; /* P2P Subordinate bus Number */
  71189. + MV_U32 p2pSecLatencyTimer; /* P2P Econdary Latency Timer*/
  71190. + MV_U32 p2pIObase; /* P2P IO Base */
  71191. + MV_U32 p2pIOLimit; /* P2P IO Linit */
  71192. + MV_BOOL bIO32;
  71193. + MV_U32 p2pSecStatus; /* P2P Secondary Status */
  71194. + MV_U32 p2pMemBase; /* P2P Memory Space */
  71195. + MV_U32 p2pMemLimit; /* P2P Memory Limit*/
  71196. + MV_U32 p2pPrefMemBase; /* P2P Prefetchable Mem Base*/
  71197. + MV_U32 p2pPrefMemLimit; /* P2P Prefetchable Memory Limit*/
  71198. + MV_BOOL bPrefMem64;
  71199. + MV_U32 p2pPrefBaseUpper32Bits;/* P2P Prefetchable upper 32 bits*/
  71200. + MV_U32 p2pPrefLimitUpper32Bits;/* P2P prefetchable limit upper 32*/
  71201. +
  71202. +
  71203. + MV_U32 pciCacheLine; /* Pci agent cache line */
  71204. + MV_U32 pciLatencyTimer; /* Pci agent Latency timer */
  71205. + MV_PCI_HEADER pciHeader; /* Pci agent header type*/
  71206. + MV_BOOL isMultiFunction; /* Multi function support */
  71207. + MV_BOOL isBISTCapable; /* Self test capable */
  71208. +
  71209. + MV_U32 subSysID; /* Sub System ID */
  71210. + MV_U32 subSysVenID; /* Sub System Vendor ID */
  71211. +
  71212. + MV_BOOL isExpRom; /* Expantion Rom support */
  71213. + MV_U32 expRomAddr; /* Expantion Rom pointer */
  71214. +
  71215. + MV_U32 capListPointer; /* Capability list pointer */
  71216. +
  71217. + MV_U32 irqLine; /* IRQ line */
  71218. + MV_PCI_INT_PIN intPin; /* Interrupt pin */
  71219. + MV_U32 minGrant; /* Minimum grant*/
  71220. + MV_U32 maxLatency; /* Maximum latency*/
  71221. +
  71222. + MV_U32 funtionsNum; /* pci agent total functions number */
  71223. +
  71224. + MV_U32 barsNum;
  71225. + MV_U8 type[60]; /* class name of the pci agent */
  71226. +
  71227. +
  71228. +} MV_PCI_DEVICE;
  71229. +
  71230. +/* PCI gloabl functions */
  71231. +MV_STATUS mvPciClassNameGet(MV_U32 classCode, MV_8 *pType);
  71232. +
  71233. +
  71234. +/* Performs a full scan on both PCIs and returns all possible details on the
  71235. + agents found on the bus. */
  71236. +MV_STATUS mvPciScan(MV_U32 pciIf,
  71237. + MV_PCI_DEVICE *pPciAgents,
  71238. + MV_U32 *pPciAgentsNum);
  71239. +
  71240. +
  71241. +#endif /* #ifndef __INCmvPciUtilsh */
  71242. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c
  71243. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c 1970-01-01 01:00:00.000000000 +0100
  71244. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c 2010-08-05 22:02:25.204038858 +0200
  71245. @@ -0,0 +1,1143 @@
  71246. +/*******************************************************************************
  71247. +Copyright (C) Marvell International Ltd. and its affiliates
  71248. +
  71249. +This software file (the "File") is owned and distributed by Marvell
  71250. +International Ltd. and/or its affiliates ("Marvell") under the following
  71251. +alternative licensing terms. Once you have made an election to distribute the
  71252. +File under one of the following license alternatives, please (i) delete this
  71253. +introductory statement regarding license alternatives, (ii) delete the two
  71254. +license alternatives that you have not elected to use and (iii) preserve the
  71255. +Marvell copyright notice above.
  71256. +
  71257. +********************************************************************************
  71258. +Marvell Commercial License Option
  71259. +
  71260. +If you received this File from Marvell and you have entered into a commercial
  71261. +license agreement (a "Commercial License") with Marvell, the File is licensed
  71262. +to you under the terms of the applicable Commercial License.
  71263. +
  71264. +********************************************************************************
  71265. +Marvell GPL License Option
  71266. +
  71267. +If you received this File from Marvell, you may opt to use, redistribute and/or
  71268. +modify this File in accordance with the terms and conditions of the General
  71269. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  71270. +available along with the File in the license.txt file or by writing to the Free
  71271. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  71272. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  71273. +
  71274. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  71275. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  71276. +DISCLAIMED. The GPL License provides additional details about this warranty
  71277. +disclaimer.
  71278. +********************************************************************************
  71279. +Marvell BSD License Option
  71280. +
  71281. +If you received this File from Marvell, you may opt to use, redistribute and/or
  71282. +modify this File under the following licensing terms.
  71283. +Redistribution and use in source and binary forms, with or without modification,
  71284. +are permitted provided that the following conditions are met:
  71285. +
  71286. + * Redistributions of source code must retain the above copyright notice,
  71287. + this list of conditions and the following disclaimer.
  71288. +
  71289. + * Redistributions in binary form must reproduce the above copyright
  71290. + notice, this list of conditions and the following disclaimer in the
  71291. + documentation and/or other materials provided with the distribution.
  71292. +
  71293. + * Neither the name of Marvell nor the names of its contributors may be
  71294. + used to endorse or promote products derived from this software without
  71295. + specific prior written permission.
  71296. +
  71297. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  71298. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  71299. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  71300. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  71301. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  71302. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  71303. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  71304. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  71305. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  71306. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  71307. +
  71308. +*******************************************************************************/
  71309. +
  71310. +#include "pex/mvPex.h"
  71311. +
  71312. +#include "ctrlEnv/mvCtrlEnvLib.h"
  71313. +
  71314. +/* defines */
  71315. +#ifdef MV_DEBUG
  71316. +#define DB(x) x
  71317. +#else
  71318. +#define DB(x)
  71319. +#endif
  71320. +
  71321. +MV_STATUS mvPexHalInit(MV_U32 pexIf, MV_PEX_TYPE pexType)
  71322. +{
  71323. + MV_PEX_MODE pexMode;
  71324. + MV_U32 regVal;
  71325. + MV_U32 status;
  71326. +
  71327. + /* First implement Guideline (GL# PCI Express-2) Wrong Default Value */
  71328. + /* to Transmitter Output Current (TXAMP) Relevant for: 88F5181-A1/B0/B1 */
  71329. + /* and 88F5281-B0 and above, 88F5182, 88F5082, 88F5181L, 88F6082/L */
  71330. +
  71331. + if ((mvCtrlModelGet() != MV_1281_DEV_ID) &&
  71332. + (mvCtrlModelGet() != MV_6281_DEV_ID) &&
  71333. + (mvCtrlModelGet() != MV_6192_DEV_ID) &&
  71334. + (mvCtrlModelGet() != MV_6190_DEV_ID) &&
  71335. + (mvCtrlModelGet() != MV_6180_DEV_ID) &&
  71336. + (mvCtrlModelGet() != MV_6183_DEV_ID) &&
  71337. + (mvCtrlModelGet() != MV_6183L_DEV_ID) &&
  71338. + (mvCtrlModelGet() != MV_78100_DEV_ID) &&
  71339. + (mvCtrlModelGet() != MV_78200_DEV_ID) &&
  71340. + (mvCtrlModelGet() != MV_76100_DEV_ID) &&
  71341. + (mvCtrlModelGet() != MV_78XX0_DEV_ID))
  71342. + {
  71343. +
  71344. + /* Read current value of TXAMP */
  71345. + MV_REG_WRITE(0x41b00, 0x80820000); /* Write the read command */
  71346. +
  71347. + regVal = MV_REG_READ(0x41b00); /* Extract the data */
  71348. +
  71349. + /* Prepare new data for write */
  71350. + regVal &= ~0x7; /* Clear bits [2:0] */
  71351. + regVal |= 0x4; /* Set the new value */
  71352. + regVal &= ~0x80000000; /* Set "write" command */
  71353. + MV_REG_WRITE(0x41b00, regVal); /* Write the write command */
  71354. +
  71355. + }
  71356. + else
  71357. + {
  71358. + /* Implement 1.0V termination GL for 88F1281 device only */
  71359. + /* BIT0 - Common mode feedback */
  71360. + /* BIT3 - TxBuf, extra drive for 1.0V termination */
  71361. + if (mvCtrlModelGet() == MV_1281_DEV_ID)
  71362. + {
  71363. + MV_REG_WRITE(0x41b00, 0x80860000); /* Write the read command */
  71364. + regVal = MV_REG_READ(0x41b00); /* Extract the data */
  71365. + regVal |= (BIT0 | BIT3);
  71366. + regVal &= ~0x80000000; /* Set "write" command */
  71367. + MV_REG_WRITE(0x41b00, regVal); /* Write the write command */
  71368. +
  71369. + MV_REG_WRITE(0x31b00, 0x80860000); /* Write the read command */
  71370. + regVal = MV_REG_READ(0x31b00); /* Extract the data */
  71371. + regVal |= (BIT0 | BIT3);
  71372. + regVal &= ~0x80000000; /* Set "write" command */
  71373. + MV_REG_WRITE(0x31b00, regVal); /* Write the write command */
  71374. + }
  71375. + }
  71376. +
  71377. + if( mvPexModeGet(pexIf, &pexMode) != MV_OK)
  71378. + {
  71379. + mvOsPrintf("PEX init ERR. mvPexModeGet failed (pexType=%d)\n",pexMode.pexType);
  71380. + return MV_ERROR;
  71381. + }
  71382. +
  71383. + /* Check that required PEX type is the one set in reset time */
  71384. + if (pexType != pexMode.pexType)
  71385. + {
  71386. + /* No Link. Shut down the Phy */
  71387. + mvPexPowerDown(pexIf);
  71388. + mvOsPrintf("PEX init ERR. PEX type sampled mismatch (%d,%d)\n",pexType,pexMode.pexType);
  71389. + return MV_ERROR;
  71390. + }
  71391. +
  71392. + if (MV_PEX_ROOT_COMPLEX == pexType)
  71393. + {
  71394. + mvPexLocalBusNumSet(pexIf, PEX_HOST_BUS_NUM(pexIf));
  71395. + mvPexLocalDevNumSet(pexIf, PEX_HOST_DEV_NUM(pexIf));
  71396. +
  71397. + /* Local device master Enable */
  71398. + mvPexMasterEnable(pexIf, MV_TRUE);
  71399. +
  71400. + /* Local device slave Enable */
  71401. + mvPexSlaveEnable(pexIf, mvPexLocalBusNumGet(pexIf),
  71402. + mvPexLocalDevNumGet(pexIf), MV_TRUE);
  71403. + /* Interrupt disable */
  71404. + status = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND));
  71405. + status |= PXSAC_INT_DIS;
  71406. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND), status);
  71407. + }
  71408. +
  71409. + /* now wait 500 ms to be sure the link is valid (spec compliant) */
  71410. + mvOsDelay(500);
  71411. + /* Check if we have link */
  71412. + if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)
  71413. + {
  71414. + mvOsPrintf("PEX%d interface detected no Link.\n",pexIf);
  71415. + return MV_NO_SUCH;
  71416. + }
  71417. +
  71418. + if (MV_PEX_WITDH_X1 == pexMode.pexWidth)
  71419. + {
  71420. + mvOsPrintf("PEX%d interface detected Link X1\n",pexIf);
  71421. + }
  71422. + else
  71423. + {
  71424. + mvOsPrintf("PEX%d interface detected Link X4\n",pexIf);
  71425. + }
  71426. +
  71427. +#ifdef PCIE_VIRTUAL_BRIDGE_SUPPORT
  71428. + mvPexVrtBrgInit(pexIf);
  71429. +#endif
  71430. + return MV_OK;
  71431. +}
  71432. +
  71433. +/*******************************************************************************
  71434. +* mvPexModeGet - Get Pex Mode
  71435. +*
  71436. +* DESCRIPTION:
  71437. +*
  71438. +* INPUT:
  71439. +* pexIf - PEX interface number.
  71440. +*
  71441. +* OUTPUT:
  71442. +* pexMode - Pex mode structure
  71443. +*
  71444. +* RETURN:
  71445. +* MV_OK on success , MV_ERROR otherwise
  71446. +*
  71447. +*******************************************************************************/
  71448. +MV_U32 mvPexModeGet(MV_U32 pexIf,MV_PEX_MODE *pexMode)
  71449. +{
  71450. + MV_U32 pexData;
  71451. +
  71452. + /* Parameter checking */
  71453. + if (PEX_DEFAULT_IF != pexIf)
  71454. + {
  71455. + if (pexIf >= mvCtrlPexMaxIfGet())
  71456. + {
  71457. + mvOsPrintf("mvPexModeGet: ERR. Invalid PEX interface %d\n",pexIf);
  71458. + return MV_ERROR;
  71459. + }
  71460. + }
  71461. +
  71462. + pexData = MV_REG_READ(PEX_CTRL_REG(pexIf));
  71463. +
  71464. + switch (pexData & PXCR_DEV_TYPE_CTRL_MASK)
  71465. + {
  71466. + case PXCR_DEV_TYPE_CTRL_CMPLX:
  71467. + pexMode->pexType = MV_PEX_ROOT_COMPLEX;
  71468. + break;
  71469. + case PXCR_DEV_TYPE_CTRL_POINT:
  71470. + pexMode->pexType = MV_PEX_END_POINT;
  71471. + break;
  71472. +
  71473. + }
  71474. +
  71475. + /* Check if we have link */
  71476. + if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)
  71477. + {
  71478. + pexMode->pexLinkUp = MV_FALSE;
  71479. +
  71480. + /* If there is no link, the auto negotiation data is worthless */
  71481. + pexMode->pexWidth = MV_PEX_WITDH_INVALID;
  71482. + }
  71483. + else
  71484. + {
  71485. + pexMode->pexLinkUp = MV_TRUE;
  71486. +
  71487. + /* We have link. The link width is now valid */
  71488. + pexData = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG));
  71489. + pexMode->pexWidth = ((pexData & PXLCSR_NEG_LNK_WDTH_MASK) >>
  71490. + PXLCSR_NEG_LNK_WDTH_OFFS);
  71491. + }
  71492. +
  71493. + return MV_OK;
  71494. +}
  71495. +
  71496. +
  71497. +/* PEX configuration space read write */
  71498. +
  71499. +/*******************************************************************************
  71500. +* mvPexConfigRead - Read from configuration space
  71501. +*
  71502. +* DESCRIPTION:
  71503. +* This function performs a 32 bit read from PEX configuration space.
  71504. +* It supports both type 0 and type 1 of Configuration Transactions
  71505. +* (local and over bridge). In order to read from local bus segment, use
  71506. +* bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers
  71507. +* will result configuration transaction of type 1 (over bridge).
  71508. +*
  71509. +* INPUT:
  71510. +* pexIf - PEX interface number.
  71511. +* bus - PEX segment bus number.
  71512. +* dev - PEX device number.
  71513. +* func - Function number.
  71514. +* regOffs - Register offset.
  71515. +*
  71516. +* OUTPUT:
  71517. +* None.
  71518. +*
  71519. +* RETURN:
  71520. +* 32bit register data, 0xffffffff on error
  71521. +*
  71522. +*******************************************************************************/
  71523. +MV_U32 mvPexConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  71524. + MV_U32 regOff)
  71525. +{
  71526. +#if defined(PCIE_VIRTUAL_BRIDGE_SUPPORT)
  71527. + return mvPexVrtBrgConfigRead (pexIf, bus, dev, func, regOff);
  71528. +}
  71529. +
  71530. +MV_U32 mvPexHwConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  71531. + MV_U32 regOff)
  71532. +{
  71533. +#endif
  71534. + MV_U32 pexData = 0;
  71535. + MV_U32 localDev,localBus;
  71536. +
  71537. + /* Parameter checking */
  71538. + if (PEX_DEFAULT_IF != pexIf)
  71539. + {
  71540. + if (pexIf >= mvCtrlPexMaxIfGet())
  71541. + {
  71542. + mvOsPrintf("mvPexConfigRead: ERR. Invalid PEX interface %d\n",pexIf);
  71543. + return 0xFFFFFFFF;
  71544. + }
  71545. + }
  71546. +
  71547. + if (dev >= MAX_PEX_DEVICES)
  71548. + {
  71549. + DB(mvOsPrintf("mvPexConfigRead: ERR. device number illigal %d\n", dev));
  71550. + return 0xFFFFFFFF;
  71551. + }
  71552. +
  71553. + if (func >= MAX_PEX_FUNCS)
  71554. + {
  71555. + DB(mvOsPrintf("mvPexConfigRead: ERR. function num illigal %d\n", func));
  71556. + return 0xFFFFFFFF;
  71557. + }
  71558. +
  71559. + if (bus >= MAX_PEX_BUSSES)
  71560. + {
  71561. + DB(mvOsPrintf("mvPexConfigRead: ERR. bus number illigal %d\n", bus));
  71562. + return MV_ERROR;
  71563. + }
  71564. +
  71565. + DB(mvOsPrintf("mvPexConfigRead: pexIf %d, bus %d, dev %d, func %d, regOff 0x%x\n",
  71566. + pexIf, bus, dev, func, regOff));
  71567. +
  71568. + localDev = mvPexLocalDevNumGet(pexIf);
  71569. + localBus = mvPexLocalBusNumGet(pexIf);
  71570. +
  71571. + /* Speed up the process. In case on no link, return MV_ERROR */
  71572. + if ((dev != localDev) || (bus != localBus))
  71573. + {
  71574. + pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));
  71575. +
  71576. + if ((pexData & PXSR_DL_DOWN))
  71577. + {
  71578. + return MV_ERROR;
  71579. + }
  71580. + }
  71581. +
  71582. + /* in PCI Express we have only one device number */
  71583. + /* and this number is the first number we encounter
  71584. + else that the localDev*/
  71585. + /* spec pex define return on config read/write on any device */
  71586. + if (bus == localBus)
  71587. + {
  71588. + if (localDev == 0)
  71589. + {
  71590. + /* if local dev is 0 then the first number we encounter
  71591. + after 0 is 1 */
  71592. + if ((dev != 1)&&(dev != localDev))
  71593. + {
  71594. + return MV_ERROR;
  71595. + }
  71596. + }
  71597. + else
  71598. + {
  71599. + /* if local dev is not 0 then the first number we encounter
  71600. + is 0 */
  71601. +
  71602. + if ((dev != 0)&&(dev != localDev))
  71603. + {
  71604. + return MV_ERROR;
  71605. + }
  71606. + }
  71607. + if(func != 0 ) /* i.e bridge */
  71608. + {
  71609. + return MV_ERROR;
  71610. + }
  71611. + }
  71612. +
  71613. +
  71614. + /* Creating PEX address to be passed */
  71615. + pexData = (bus << PXCAR_BUS_NUM_OFFS);
  71616. + pexData |= (dev << PXCAR_DEVICE_NUM_OFFS);
  71617. + pexData |= (func << PXCAR_FUNC_NUM_OFFS);
  71618. + pexData |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
  71619. + /* extended register space */
  71620. + pexData |=(((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >>
  71621. + PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
  71622. +
  71623. + pexData |= PXCAR_CONFIG_EN;
  71624. +
  71625. + /* Write the address to the PEX configuration address register */
  71626. + MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);
  71627. +
  71628. + DB(mvOsPrintf("mvPexConfigRead:address pexData=%x ",pexData));
  71629. +
  71630. +
  71631. + /* In order to let the PEX controller absorbed the address of the read */
  71632. + /* transaction we perform a validity check that the address was written */
  71633. + if(pexData != MV_REG_READ(PEX_CFG_ADDR_REG(pexIf)))
  71634. + {
  71635. + return MV_ERROR;
  71636. + }
  71637. +
  71638. + /* cleaning Master Abort */
  71639. + MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND),
  71640. + PXSAC_MABORT);
  71641. +#if 0
  71642. + /* Guideline (GL# PCI Express-1) Erroneous Read Data on Configuration */
  71643. + /* This guideline is relevant for all devices except of the following devices:
  71644. + 88F5281-BO and above, 88F5181L-A0 and above, 88F1281 A0 and above
  71645. + 88F6183 A0 and above, 88F6183L */
  71646. + if ( ( (dev != localDev) || (bus != localBus) ) &&
  71647. + (
  71648. + !(MV_5281_DEV_ID == mvCtrlModelGet())&&
  71649. + !((MV_5181_DEV_ID == mvCtrlModelGet())&& (mvCtrlRevGet() >= MV_5181L_A0_REV))&&
  71650. + !(MV_1281_DEV_ID == mvCtrlModelGet())&&
  71651. + !(MV_6183_DEV_ID == mvCtrlModelGet())&&
  71652. + !(MV_6183L_DEV_ID == mvCtrlModelGet())&&
  71653. + !(MV_6281_DEV_ID == mvCtrlModelGet())&&
  71654. + !(MV_6192_DEV_ID == mvCtrlModelGet())&&
  71655. + !(MV_6190_DEV_ID == mvCtrlModelGet())&&
  71656. + !(MV_6180_DEV_ID == mvCtrlModelGet())&&
  71657. + !(MV_78XX0_DEV_ID == mvCtrlModelGet())
  71658. + ))
  71659. + {
  71660. +
  71661. + /* PCI-Express configuration read work-around */
  71662. +
  71663. + /* we will use one of the Punit (AHBToMbus) windows to access the xbar
  71664. + and read the data from there */
  71665. + /*
  71666. + Need to configure the 2 free Punit (AHB to MBus bridge)
  71667. + address decoding windows:
  71668. + Configure the flash Window to handle Configuration space requests
  71669. + for PEX0/1:
  71670. + 1. write 0x7931/0x7941 to the flash window and the size,
  71671. + 79-xbar attr (pci cfg), 3/4-xbar target (pex0/1), 1-WinEn
  71672. + 2. write base to flash window
  71673. +
  71674. + Configuration transactions from the CPU should write/read the data
  71675. + to/from address of the form:
  71676. + addr[31:28] = 0x5 (for PEX0) or 0x6 (for PEX1)
  71677. + addr[27:24] = extended register number
  71678. + addr[23:16] = bus number
  71679. + addr[15:11] = device number
  71680. + addr[10:8] = function number
  71681. + addr[7:0] = register number
  71682. + */
  71683. +
  71684. + #include "ctrlEnv/sys/mvAhbToMbus.h"
  71685. + {
  71686. + MV_U32 winNum;
  71687. + MV_AHB_TO_MBUS_DEC_WIN originWin;
  71688. + MV_U32 pciAddr=0;
  71689. + MV_U32 remapLow=0,remapHigh=0;
  71690. +
  71691. + /*
  71692. + We will use DEV_CS2\Flash window for this workarround
  71693. + */
  71694. +
  71695. + winNum = mvAhbToMbusWinTargetGet(PEX_CONFIG_RW_WA_TARGET);
  71696. +
  71697. + /* save remap values if exist */
  71698. + if ((1 == winNum)||(0 == winNum))
  71699. + {
  71700. + remapLow = MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum));
  71701. + remapHigh = MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum));
  71702. +
  71703. + }
  71704. +
  71705. +
  71706. + /* save the original window values */
  71707. + mvAhbToMbusWinGet(winNum,&originWin);
  71708. +
  71709. + if (PEX_CONFIG_RW_WA_USE_ORIGINAL_WIN_VALUES)
  71710. + {
  71711. + /* set the window as xbar window */
  71712. + if (pexIf)
  71713. + {
  71714. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
  71715. + (0x7931 | (((originWin.addrWin.size >> 16)-1) ) << 16));
  71716. + }
  71717. + else
  71718. + {
  71719. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
  71720. + (0x7941 | (((originWin.addrWin.size >> 16)-1) ) << 16));
  71721. + }
  71722. +
  71723. + MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),
  71724. + originWin.addrWin.baseLow);
  71725. +
  71726. + /*pciAddr = originWin.addrWin.baseLow;*/
  71727. + pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(
  71728. + (MV_U32)originWin.addrWin.baseLow);
  71729. +
  71730. + }
  71731. + else
  71732. + {
  71733. + /* set the window as xbar window */
  71734. + if (pexIf)
  71735. + {
  71736. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
  71737. + (0x7931 | (((PEX_CONFIG_RW_WA_SIZE >> 16)-1) ) << 16));
  71738. + }
  71739. + else
  71740. + {
  71741. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
  71742. + (0x7941 | (((PEX_CONFIG_RW_WA_SIZE >> 16)-1) ) << 16));
  71743. + }
  71744. +
  71745. + MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),
  71746. + PEX_CONFIG_RW_WA_BASE);
  71747. +
  71748. + pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(PEX_CONFIG_RW_WA_BASE);
  71749. + }
  71750. +
  71751. +
  71752. + /* remap should be as base */
  71753. + if ((1 == winNum)||(0 == winNum))
  71754. + {
  71755. + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum),pciAddr);
  71756. + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum),0);
  71757. +
  71758. + }
  71759. +
  71760. + /* extended register space */
  71761. + pciAddr |= (bus << 16);
  71762. + pciAddr |= (dev << 11);
  71763. + pciAddr |= (func << 8);
  71764. + pciAddr |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
  71765. +
  71766. + pexData = *(MV_U32*)pciAddr;
  71767. + pexData = MV_32BIT_LE(pexData); /* Data always in LE */
  71768. +
  71769. + /* restore the original window values */
  71770. + mvAhbToMbusWinSet(winNum,&originWin);
  71771. +
  71772. + /* restore original remap values*/
  71773. + if ((1 == winNum)||(0 == winNum))
  71774. + {
  71775. + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum),remapLow);
  71776. + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum),remapHigh);
  71777. +
  71778. + }
  71779. + }
  71780. + }
  71781. + else
  71782. +#endif
  71783. + {
  71784. + /* Read the Data returned in the PEX Data register */
  71785. + pexData = MV_REG_READ(PEX_CFG_DATA_REG(pexIf));
  71786. +
  71787. + }
  71788. +
  71789. + DB(mvOsPrintf("mvPexConfigRead: got : %x \n",pexData));
  71790. +
  71791. + return pexData;
  71792. +
  71793. +}
  71794. +
  71795. +/*******************************************************************************
  71796. +* mvPexConfigWrite - Write to configuration space
  71797. +*
  71798. +* DESCRIPTION:
  71799. +* This function performs a 32 bit write to PEX configuration space.
  71800. +* It supports both type 0 and type 1 of Configuration Transactions
  71801. +* (local and over bridge). In order to write to local bus segment, use
  71802. +* bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers
  71803. +* will result configuration transaction of type 1 (over bridge).
  71804. +*
  71805. +* INPUT:
  71806. +* pexIf - PEX interface number.
  71807. +* bus - PEX segment bus number.
  71808. +* dev - PEX device number.
  71809. +* func - Function number.
  71810. +* regOffs - Register offset.
  71811. +* data - 32bit data.
  71812. +*
  71813. +* OUTPUT:
  71814. +* None.
  71815. +*
  71816. +* RETURN:
  71817. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  71818. +*
  71819. +*******************************************************************************/
  71820. +MV_STATUS mvPexConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  71821. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  71822. +{
  71823. +#if defined(PCIE_VIRTUAL_BRIDGE_SUPPORT)
  71824. + return mvPexVrtBrgConfigWrite (pexIf, bus, dev, func, regOff, data);
  71825. +}
  71826. +
  71827. +MV_STATUS mvPexHwConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  71828. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  71829. +{
  71830. +#endif
  71831. + MV_U32 pexData = 0;
  71832. + MV_U32 localDev,localBus;
  71833. +
  71834. + /* Parameter checking */
  71835. + if (PEX_DEFAULT_IF != pexIf)
  71836. + {
  71837. + if (pexIf >= mvCtrlPexMaxIfGet())
  71838. + {
  71839. + mvOsPrintf("mvPexConfigWrite: ERR. Invalid PEX interface %d\n",
  71840. + pexIf);
  71841. + return MV_ERROR;
  71842. + }
  71843. + }
  71844. +
  71845. + if (dev >= MAX_PEX_DEVICES)
  71846. + {
  71847. + mvOsPrintf("mvPexConfigWrite: ERR. device number illigal %d\n",dev);
  71848. + return MV_BAD_PARAM;
  71849. + }
  71850. +
  71851. + if (func >= MAX_PEX_FUNCS)
  71852. + {
  71853. + mvOsPrintf("mvPexConfigWrite: ERR. function number illigal %d\n", func);
  71854. + return MV_ERROR;
  71855. + }
  71856. +
  71857. + if (bus >= MAX_PEX_BUSSES)
  71858. + {
  71859. + mvOsPrintf("mvPexConfigWrite: ERR. bus number illigal %d\n", bus);
  71860. + return MV_ERROR;
  71861. + }
  71862. +
  71863. +
  71864. +
  71865. + localDev = mvPexLocalDevNumGet(pexIf);
  71866. + localBus = mvPexLocalBusNumGet(pexIf);
  71867. +
  71868. +
  71869. + /* in PCI Express we have only one device number other than ourselves*/
  71870. + /* and this number is the first number we encounter
  71871. + else than the localDev that can be any valid dev number*/
  71872. + /* pex spec define return on config read/write on any device */
  71873. + if (bus == localBus)
  71874. + {
  71875. +
  71876. + if (localDev == 0)
  71877. + {
  71878. + /* if local dev is 0 then the first number we encounter
  71879. + after 0 is 1 */
  71880. + if ((dev != 1)&&(dev != localDev))
  71881. + {
  71882. + return MV_ERROR;
  71883. + }
  71884. +
  71885. + }
  71886. + else
  71887. + {
  71888. + /* if local dev is not 0 then the first number we encounter
  71889. + is 0 */
  71890. +
  71891. + if ((dev != 0)&&(dev != localDev))
  71892. + {
  71893. + return MV_ERROR;
  71894. + }
  71895. + }
  71896. +
  71897. +
  71898. + }
  71899. +
  71900. + /* if we are not accessing ourselves , then check the link */
  71901. + if ((dev != localDev) || (bus != localBus) )
  71902. + {
  71903. + /* workarround */
  71904. + /* when no link return MV_ERROR */
  71905. +
  71906. + pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));
  71907. +
  71908. + if ((pexData & PXSR_DL_DOWN))
  71909. + {
  71910. + return MV_ERROR;
  71911. + }
  71912. +
  71913. + }
  71914. +
  71915. + pexData =0;
  71916. +
  71917. + /* Creating PEX address to be passed */
  71918. + pexData |= (bus << PXCAR_BUS_NUM_OFFS);
  71919. + pexData |= (dev << PXCAR_DEVICE_NUM_OFFS);
  71920. + pexData |= (func << PXCAR_FUNC_NUM_OFFS);
  71921. + pexData |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
  71922. + /* extended register space */
  71923. + pexData |=(((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >>
  71924. + PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
  71925. + pexData |= PXCAR_CONFIG_EN;
  71926. +
  71927. + DB(mvOsPrintf("mvPexConfigWrite: If=%x bus=%x func=%x dev=%x regOff=%x data=%x \n",
  71928. + pexIf,bus,func,dev,regOff,data,pexData) );
  71929. +
  71930. + /* Write the address to the PEX configuration address register */
  71931. + MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);
  71932. +
  71933. + /* Clear CPU pipe. Important where CPU can perform OOO execution */
  71934. + CPU_PIPE_FLUSH;
  71935. +
  71936. + /* In order to let the PEX controller absorbed the address of the read */
  71937. + /* transaction we perform a validity check that the address was written */
  71938. + if(pexData != MV_REG_READ(PEX_CFG_ADDR_REG(pexIf)))
  71939. + {
  71940. + return MV_ERROR;
  71941. + }
  71942. +
  71943. + /* Write the Data passed to the PEX Data register */
  71944. + MV_REG_WRITE(PEX_CFG_DATA_REG(pexIf), data);
  71945. +
  71946. + return MV_OK;
  71947. +
  71948. +}
  71949. +
  71950. +/*******************************************************************************
  71951. +* mvPexMasterEnable - Enable/disale PEX interface master transactions.
  71952. +*
  71953. +* DESCRIPTION:
  71954. +* This function performs read modified write to PEX command status
  71955. +* (offset 0x4) to set/reset bit 2. After this bit is set, the PEX
  71956. +* master is allowed to gain ownership on the bus, otherwise it is
  71957. +* incapable to do so.
  71958. +*
  71959. +* INPUT:
  71960. +* pexIf - PEX interface number.
  71961. +* enable - Enable/disable parameter.
  71962. +*
  71963. +* OUTPUT:
  71964. +* None.
  71965. +*
  71966. +* RETURN:
  71967. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  71968. +*
  71969. +*******************************************************************************/
  71970. +MV_STATUS mvPexMasterEnable(MV_U32 pexIf, MV_BOOL enable)
  71971. +{
  71972. + MV_U32 pexCommandStatus;
  71973. + MV_U32 localBus;
  71974. + MV_U32 localDev;
  71975. +
  71976. + /* Parameter checking */
  71977. + if (pexIf >= mvCtrlPexMaxIfGet())
  71978. + {
  71979. + mvOsPrintf("mvPexMasterEnable: ERR. Invalid PEX interface %d\n", pexIf);
  71980. + return MV_ERROR;
  71981. + }
  71982. +
  71983. + localBus = mvPexLocalBusNumGet(pexIf);
  71984. + localDev = mvPexLocalDevNumGet(pexIf);
  71985. +
  71986. + pexCommandStatus = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,
  71987. + PEX_STATUS_AND_COMMAND));
  71988. +
  71989. +
  71990. + if (MV_TRUE == enable)
  71991. + {
  71992. + pexCommandStatus |= PXSAC_MASTER_EN;
  71993. + }
  71994. + else
  71995. + {
  71996. + pexCommandStatus &= ~PXSAC_MASTER_EN;
  71997. + }
  71998. +
  71999. +
  72000. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND),
  72001. + pexCommandStatus);
  72002. +
  72003. + return MV_OK;
  72004. +}
  72005. +
  72006. +
  72007. +/*******************************************************************************
  72008. +* mvPexSlaveEnable - Enable/disale PEX interface slave transactions.
  72009. +*
  72010. +* DESCRIPTION:
  72011. +* This function performs read modified write to PEX command status
  72012. +* (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
  72013. +* the PEX slave is allowed to respond to PEX IO space access (bit 0)
  72014. +* and PEX memory space access (bit 1).
  72015. +*
  72016. +* INPUT:
  72017. +* pexIf - PEX interface number.
  72018. +* dev - PEX device number.
  72019. +* enable - Enable/disable parameter.
  72020. +*
  72021. +* OUTPUT:
  72022. +* None.
  72023. +*
  72024. +* RETURN:
  72025. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  72026. +*
  72027. +*******************************************************************************/
  72028. +MV_STATUS mvPexSlaveEnable(MV_U32 pexIf, MV_U32 bus,MV_U32 dev, MV_BOOL enable)
  72029. +{
  72030. + MV_U32 pexCommandStatus;
  72031. + MV_U32 RegOffs;
  72032. +
  72033. + /* Parameter checking */
  72034. + if (pexIf >= mvCtrlPexMaxIfGet())
  72035. + {
  72036. + mvOsPrintf("mvPexSlaveEnable: ERR. Invalid PEX interface %d\n", pexIf);
  72037. + return MV_BAD_PARAM;
  72038. + }
  72039. + if (dev >= MAX_PEX_DEVICES)
  72040. + {
  72041. + mvOsPrintf("mvPexLocalDevNumSet: ERR. device number illigal %d\n", dev);
  72042. + return MV_BAD_PARAM;
  72043. +
  72044. + }
  72045. +
  72046. +
  72047. + RegOffs = PEX_STATUS_AND_COMMAND;
  72048. +
  72049. + pexCommandStatus = mvPexConfigRead(pexIf, bus, dev, 0, RegOffs);
  72050. +
  72051. + if (MV_TRUE == enable)
  72052. + {
  72053. + pexCommandStatus |= (PXSAC_IO_EN | PXSAC_MEM_EN);
  72054. + }
  72055. + else
  72056. + {
  72057. + pexCommandStatus &= ~(PXSAC_IO_EN | PXSAC_MEM_EN);
  72058. + }
  72059. +
  72060. + mvPexConfigWrite(pexIf, bus, dev, 0, RegOffs, pexCommandStatus);
  72061. +
  72062. + return MV_OK;
  72063. +
  72064. +}
  72065. +
  72066. +/*******************************************************************************
  72067. +* mvPexLocalBusNumSet - Set PEX interface local bus number.
  72068. +*
  72069. +* DESCRIPTION:
  72070. +* This function sets given PEX interface its local bus number.
  72071. +* Note: In case the PEX interface is PEX-X, the information is read-only.
  72072. +*
  72073. +* INPUT:
  72074. +* pexIf - PEX interface number.
  72075. +* busNum - Bus number.
  72076. +*
  72077. +* OUTPUT:
  72078. +* None.
  72079. +*
  72080. +* RETURN:
  72081. +* MV_NOT_ALLOWED in case PEX interface is PEX-X.
  72082. +* MV_BAD_PARAM on bad parameters ,
  72083. +* otherwise MV_OK
  72084. +*
  72085. +*******************************************************************************/
  72086. +MV_STATUS mvPexLocalBusNumSet(MV_U32 pexIf, MV_U32 busNum)
  72087. +{
  72088. + MV_U32 pexStatus;
  72089. + MV_U32 localBus;
  72090. + MV_U32 localDev;
  72091. +
  72092. +
  72093. + /* Parameter checking */
  72094. + if (pexIf >= mvCtrlPexMaxIfGet())
  72095. + {
  72096. + mvOsPrintf("mvPexLocalBusNumSet: ERR. Invalid PEX interface %d\n",pexIf);
  72097. + return MV_BAD_PARAM;
  72098. + }
  72099. + if (busNum >= MAX_PEX_BUSSES)
  72100. + {
  72101. + mvOsPrintf("mvPexLocalBusNumSet: ERR. bus number illigal %d\n", busNum);
  72102. + return MV_ERROR;
  72103. +
  72104. + }
  72105. +
  72106. + localBus = mvPexLocalBusNumGet(pexIf);
  72107. + localDev = mvPexLocalDevNumGet(pexIf);
  72108. +
  72109. +
  72110. +
  72111. + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
  72112. +
  72113. + pexStatus &= ~PXSR_PEX_BUS_NUM_MASK;
  72114. +
  72115. + pexStatus |= (busNum << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK;
  72116. +
  72117. + MV_REG_WRITE(PEX_STATUS_REG(pexIf), pexStatus);
  72118. +
  72119. +
  72120. + return MV_OK;
  72121. +}
  72122. +
  72123. +
  72124. +/*******************************************************************************
  72125. +* mvPexLocalBusNumGet - Get PEX interface local bus number.
  72126. +*
  72127. +* DESCRIPTION:
  72128. +* This function gets the local bus number of a given PEX interface.
  72129. +*
  72130. +* INPUT:
  72131. +* pexIf - PEX interface number.
  72132. +*
  72133. +* OUTPUT:
  72134. +* None.
  72135. +*
  72136. +* RETURN:
  72137. +* Local bus number.0xffffffff on Error
  72138. +*
  72139. +*******************************************************************************/
  72140. +MV_U32 mvPexLocalBusNumGet(MV_U32 pexIf)
  72141. +{
  72142. + MV_U32 pexStatus;
  72143. +
  72144. + /* Parameter checking */
  72145. + if (PEX_DEFAULT_IF != pexIf)
  72146. + {
  72147. + if (pexIf >= mvCtrlPexMaxIfGet())
  72148. + {
  72149. + mvOsPrintf("mvPexLocalBusNumGet: ERR. Invalid PEX interface %d\n",pexIf);
  72150. + return 0xFFFFFFFF;
  72151. + }
  72152. + }
  72153. +
  72154. +
  72155. + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
  72156. +
  72157. + pexStatus &= PXSR_PEX_BUS_NUM_MASK;
  72158. +
  72159. + return (pexStatus >> PXSR_PEX_BUS_NUM_OFFS);
  72160. +
  72161. +}
  72162. +
  72163. +
  72164. +/*******************************************************************************
  72165. +* mvPexLocalDevNumSet - Set PEX interface local device number.
  72166. +*
  72167. +* DESCRIPTION:
  72168. +* This function sets given PEX interface its local device number.
  72169. +* Note: In case the PEX interface is PEX-X, the information is read-only.
  72170. +*
  72171. +* INPUT:
  72172. +* pexIf - PEX interface number.
  72173. +* devNum - Device number.
  72174. +*
  72175. +* OUTPUT:
  72176. +* None.
  72177. +*
  72178. +* RETURN:
  72179. +* MV_NOT_ALLOWED in case PEX interface is PEX-X.
  72180. +* MV_BAD_PARAM on bad parameters ,
  72181. +* otherwise MV_OK
  72182. +*
  72183. +*******************************************************************************/
  72184. +MV_STATUS mvPexLocalDevNumSet(MV_U32 pexIf, MV_U32 devNum)
  72185. +{
  72186. + MV_U32 pexStatus;
  72187. + MV_U32 localBus;
  72188. + MV_U32 localDev;
  72189. +
  72190. + /* Parameter checking */
  72191. + if (pexIf >= mvCtrlPexMaxIfGet())
  72192. + {
  72193. + mvOsPrintf("mvPexLocalDevNumSet: ERR. Invalid PEX interface %d\n",pexIf);
  72194. + return MV_BAD_PARAM;
  72195. + }
  72196. + if (devNum >= MAX_PEX_DEVICES)
  72197. + {
  72198. + mvOsPrintf("mvPexLocalDevNumSet: ERR. device number illigal %d\n",
  72199. + devNum);
  72200. + return MV_BAD_PARAM;
  72201. +
  72202. + }
  72203. +
  72204. + localBus = mvPexLocalBusNumGet(pexIf);
  72205. + localDev = mvPexLocalDevNumGet(pexIf);
  72206. +
  72207. +
  72208. + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
  72209. +
  72210. + pexStatus &= ~PXSR_PEX_DEV_NUM_MASK;
  72211. +
  72212. + pexStatus |= (devNum << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK;
  72213. +
  72214. + MV_REG_WRITE(PEX_STATUS_REG(pexIf), pexStatus);
  72215. +
  72216. +
  72217. + return MV_OK;
  72218. +}
  72219. +
  72220. +/*******************************************************************************
  72221. +* mvPexLocalDevNumGet - Get PEX interface local device number.
  72222. +*
  72223. +* DESCRIPTION:
  72224. +* This function gets the local device number of a given PEX interface.
  72225. +*
  72226. +* INPUT:
  72227. +* pexIf - PEX interface number.
  72228. +*
  72229. +* OUTPUT:
  72230. +* None.
  72231. +*
  72232. +* RETURN:
  72233. +* Local device number. 0xffffffff on Error
  72234. +*
  72235. +*******************************************************************************/
  72236. +MV_U32 mvPexLocalDevNumGet(MV_U32 pexIf)
  72237. +{
  72238. + MV_U32 pexStatus;
  72239. +
  72240. + /* Parameter checking */
  72241. +
  72242. + if (PEX_DEFAULT_IF != pexIf)
  72243. + {
  72244. + if (pexIf >= mvCtrlPexMaxIfGet())
  72245. + {
  72246. + mvOsPrintf("mvPexLocalDevNumGet: ERR. Invalid PEX interface %d\n",
  72247. + pexIf);
  72248. + return 0xFFFFFFFF;
  72249. + }
  72250. + }
  72251. +
  72252. + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
  72253. +
  72254. + pexStatus &= PXSR_PEX_DEV_NUM_MASK;
  72255. +
  72256. + return (pexStatus >> PXSR_PEX_DEV_NUM_OFFS);
  72257. +}
  72258. +
  72259. +MV_VOID mvPexPhyRegRead(MV_U32 pexIf, MV_U32 regOffset, MV_U16 *value)
  72260. +{
  72261. +
  72262. + MV_U32 regAddr;
  72263. + if (pexIf >= mvCtrlPexMaxIfGet())
  72264. + {
  72265. + mvOsPrintf("mvPexPhyRegRead: ERR. Invalid PEX interface %d\n", pexIf);
  72266. + return;
  72267. + }
  72268. + regAddr = (BIT31 | ((regOffset & 0x3fff) << 16));
  72269. + MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regAddr);
  72270. + *value = MV_REG_READ(PEX_PHY_ACCESS_REG(pexIf));
  72271. +}
  72272. +
  72273. +
  72274. +MV_VOID mvPexPhyRegWrite(MV_U32 pexIf, MV_U32 regOffset, MV_U16 value)
  72275. +{
  72276. +
  72277. + MV_U32 regAddr;
  72278. + if(pexIf >= mvCtrlPexMaxIfGet())
  72279. + {
  72280. + mvOsPrintf("mvPexPhyRegWrite: ERR. Invalid PEX interface %d\n", pexIf);
  72281. + return;
  72282. + }
  72283. + regAddr = (((regOffset & 0x3fff) << 16) | value);
  72284. + MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regAddr);
  72285. +}
  72286. +
  72287. +/*******************************************************************************
  72288. +* mvPexActiveStateLinkPMEnable
  72289. +*
  72290. +* DESCRIPTION:
  72291. +* Enable Active Link State Power Management
  72292. +*
  72293. +* INPUT:
  72294. +* pexIf - PEX interface number.
  72295. +* enable - MV_TRUE to enable ASPM, MV_FALSE to disable.
  72296. +*
  72297. +* OUTPUT:
  72298. +* None
  72299. +*
  72300. +* RETURN:
  72301. +* MV_OK on success , MV_ERROR otherwise
  72302. +*
  72303. +*******************************************************************************/
  72304. +MV_STATUS mvPexActiveStateLinkPMEnable(MV_U32 pexIf, MV_BOOL enable)
  72305. +{
  72306. + MV_U32 reg;
  72307. +
  72308. + if(pexIf >= mvCtrlPexMaxIfGet())
  72309. + {
  72310. + mvOsPrintf("mvPexActiveStateLinkPMEnable: ERR. Invalid PEX interface %d\n", pexIf);
  72311. + return MV_ERROR;
  72312. + }
  72313. +
  72314. + reg = MV_REG_READ(PEX_PWR_MNG_EXT_REG(pexIf)) & ~PXPMER_L1_ASPM_EN_MASK;
  72315. + if(enable == MV_TRUE)
  72316. + reg |= PXPMER_L1_ASPM_EN_MASK;
  72317. + MV_REG_WRITE(PEX_PWR_MNG_EXT_REG(pexIf), reg);
  72318. +
  72319. + /* Enable / Disable L0/1 entry */
  72320. + reg = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG))
  72321. + & ~PXLCSR_ASPM_CNT_MASK;
  72322. + if(enable == MV_TRUE)
  72323. + reg |= PXLCSR_ASPM_CNT_L0S_L1S_ENT_SUPP;
  72324. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG), reg);
  72325. +
  72326. + return MV_OK;
  72327. +}
  72328. +
  72329. +
  72330. +/*******************************************************************************
  72331. +* mvPexForceX1
  72332. +*
  72333. +* DESCRIPTION:
  72334. +* shut down lanes 1-3 if recognize that attached to an x1 end-point
  72335. +* INPUT:
  72336. +* pexIf - PEX interface number.
  72337. +*
  72338. +* OUTPUT:
  72339. +* None
  72340. +*
  72341. +* RETURN:
  72342. +* MV_OK on success , MV_ERROR otherwise
  72343. +*
  72344. +*******************************************************************************/
  72345. +MV_U32 mvPexForceX1(MV_U32 pexIf)
  72346. +{
  72347. + MV_U32 regData = 0;
  72348. + if(pexIf >= mvCtrlPexMaxIfGet())
  72349. + {
  72350. + mvOsPrintf("mvPexForceX1: ERR. Invalid PEX interface %d\n", pexIf);
  72351. + return MV_BAD_PARAM;
  72352. + }
  72353. +
  72354. + regData = MV_REG_READ(PEX_CTRL_REG(pexIf)) & ~(PXCR_CONF_LINK_MASK) ;
  72355. + regData |= PXCR_CONF_LINK_X1;
  72356. +
  72357. + MV_REG_WRITE(PEX_CTRL_REG(pexIf), regData);
  72358. + return MV_OK;
  72359. +}
  72360. +
  72361. +MV_BOOL mvPexIsPowerUp(MV_U32 pexIf)
  72362. +{
  72363. + if(pexIf >= mvCtrlPexMaxIfGet())
  72364. + {
  72365. + mvOsPrintf("mvPexIsPowerUp: ERR. Invalid PEX interface %d\n", pexIf);
  72366. + return MV_FALSE;
  72367. + }
  72368. + return mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf);
  72369. +}
  72370. +
  72371. +
  72372. +MV_VOID mvPexPowerDown(MV_U32 pexIf)
  72373. +{
  72374. + if ( (mvCtrlModelGet() == MV_78XX0_DEV_ID) ||
  72375. + (mvCtrlModelGet() == MV_76100_DEV_ID) ||
  72376. + (mvCtrlModelGet() == MV_78100_DEV_ID) ||
  72377. + (mvCtrlModelGet() == MV_78200_DEV_ID) )
  72378. + {
  72379. + mvCtrlPwrClckSet(PEX_UNIT_ID, pexIf, MV_FALSE);
  72380. + }
  72381. + else
  72382. + {
  72383. + MV_REG_WRITE((0x41B00 -(pexIf)*0x10000), 0x20800087);
  72384. + }
  72385. +}
  72386. +
  72387. +
  72388. +
  72389. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h
  72390. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h 1970-01-01 01:00:00.000000000 +0100
  72391. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h 2010-08-05 22:02:25.243731889 +0200
  72392. @@ -0,0 +1,168 @@
  72393. +/*******************************************************************************
  72394. +Copyright (C) Marvell International Ltd. and its affiliates
  72395. +
  72396. +This software file (the "File") is owned and distributed by Marvell
  72397. +International Ltd. and/or its affiliates ("Marvell") under the following
  72398. +alternative licensing terms. Once you have made an election to distribute the
  72399. +File under one of the following license alternatives, please (i) delete this
  72400. +introductory statement regarding license alternatives, (ii) delete the two
  72401. +license alternatives that you have not elected to use and (iii) preserve the
  72402. +Marvell copyright notice above.
  72403. +
  72404. +********************************************************************************
  72405. +Marvell Commercial License Option
  72406. +
  72407. +If you received this File from Marvell and you have entered into a commercial
  72408. +license agreement (a "Commercial License") with Marvell, the File is licensed
  72409. +to you under the terms of the applicable Commercial License.
  72410. +
  72411. +********************************************************************************
  72412. +Marvell GPL License Option
  72413. +
  72414. +If you received this File from Marvell, you may opt to use, redistribute and/or
  72415. +modify this File in accordance with the terms and conditions of the General
  72416. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  72417. +available along with the File in the license.txt file or by writing to the Free
  72418. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  72419. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  72420. +
  72421. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  72422. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  72423. +DISCLAIMED. The GPL License provides additional details about this warranty
  72424. +disclaimer.
  72425. +********************************************************************************
  72426. +Marvell BSD License Option
  72427. +
  72428. +If you received this File from Marvell, you may opt to use, redistribute and/or
  72429. +modify this File under the following licensing terms.
  72430. +Redistribution and use in source and binary forms, with or without modification,
  72431. +are permitted provided that the following conditions are met:
  72432. +
  72433. + * Redistributions of source code must retain the above copyright notice,
  72434. + this list of conditions and the following disclaimer.
  72435. +
  72436. + * Redistributions in binary form must reproduce the above copyright
  72437. + notice, this list of conditions and the following disclaimer in the
  72438. + documentation and/or other materials provided with the distribution.
  72439. +
  72440. + * Neither the name of Marvell nor the names of its contributors may be
  72441. + used to endorse or promote products derived from this software without
  72442. + specific prior written permission.
  72443. +
  72444. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  72445. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  72446. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  72447. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  72448. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  72449. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  72450. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  72451. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  72452. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  72453. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  72454. +
  72455. +*******************************************************************************/
  72456. +
  72457. +#ifndef __INCPEXH
  72458. +#define __INCPEXH
  72459. +
  72460. +#include "mvCommon.h"
  72461. +#include "mvOs.h"
  72462. +#include "pex/mvPexRegs.h"
  72463. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  72464. +
  72465. +
  72466. +
  72467. +/* NOTE not supported in this driver:*/
  72468. +
  72469. +
  72470. +/* defines */
  72471. +/* The number of supported PEX interfaces depend on Marvell controller */
  72472. +/* device number. This device number ID is located on the PEX unit */
  72473. +/* configuration header. This creates a loop where calling PEX */
  72474. +/* configuration read/write routine results a call to get PEX configuration */
  72475. +/* information etc. This macro defines a default PEX interface. This PEX */
  72476. +/* interface is sure to exist. */
  72477. +#define PEX_DEFAULT_IF 0
  72478. +
  72479. +
  72480. +/* typedefs */
  72481. +/* The Marvell controller supports both root complex and end point devices */
  72482. +/* This enumeration describes the PEX type. */
  72483. +typedef enum _mvPexType
  72484. +{
  72485. + MV_PEX_ROOT_COMPLEX, /* root complex device */
  72486. + MV_PEX_END_POINT /* end point device */
  72487. +}MV_PEX_TYPE;
  72488. +
  72489. +typedef enum _mvPexWidth
  72490. +{
  72491. + MV_PEX_WITDH_X1 = 1,
  72492. + MV_PEX_WITDH_X2,
  72493. + MV_PEX_WITDH_X3,
  72494. + MV_PEX_WITDH_X4,
  72495. + MV_PEX_WITDH_INVALID
  72496. +}MV_PEX_WIDTH;
  72497. +
  72498. +/* PEX Bar attributes */
  72499. +typedef struct _mvPexMode
  72500. +{
  72501. + MV_PEX_TYPE pexType;
  72502. + MV_PEX_WIDTH pexWidth;
  72503. + MV_BOOL pexLinkUp;
  72504. +}MV_PEX_MODE;
  72505. +
  72506. +
  72507. +
  72508. +/* Global Functions prototypes */
  72509. +/* mvPexInit - Initialize PEX interfaces*/
  72510. +MV_STATUS mvPexHalInit(MV_U32 pexIf, MV_PEX_TYPE pexType);
  72511. +
  72512. +/* mvPexModeGet - Get Pex If mode */
  72513. +MV_U32 mvPexModeGet(MV_U32 pexIf,MV_PEX_MODE *pexMode);
  72514. +
  72515. +/* mvPexConfigRead - Read from configuration space */
  72516. +MV_U32 mvPexConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  72517. + MV_U32 func,MV_U32 regOff);
  72518. +
  72519. +/* mvPexConfigWrite - Write to configuration space */
  72520. +MV_STATUS mvPexConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  72521. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  72522. +
  72523. +/* mvPexMasterEnable - Enable/disale PEX interface master transactions.*/
  72524. +MV_STATUS mvPexMasterEnable(MV_U32 pexIf, MV_BOOL enable);
  72525. +
  72526. +/* mvPexSlaveEnable - Enable/disale PEX interface slave transactions.*/
  72527. +MV_STATUS mvPexSlaveEnable(MV_U32 pexIf, MV_U32 bus,MV_U32 dev, MV_BOOL enable);
  72528. +
  72529. +/* mvPexLocalBusNumSet - Set PEX interface local bus number.*/
  72530. +MV_STATUS mvPexLocalBusNumSet(MV_U32 pexIf, MV_U32 busNum);
  72531. +
  72532. +/* mvPexLocalBusNumGet - Get PEX interface local bus number.*/
  72533. +MV_U32 mvPexLocalBusNumGet(MV_U32 pexIf);
  72534. +
  72535. +/* mvPexLocalDevNumSet - Set PEX interface local device number.*/
  72536. +MV_STATUS mvPexLocalDevNumSet(MV_U32 pexIf, MV_U32 devNum);
  72537. +
  72538. +/* mvPexLocalDevNumGet - Get PEX interface local device number.*/
  72539. +MV_U32 mvPexLocalDevNumGet(MV_U32 pexIf);
  72540. +/* mvPexForceX1 - Force PEX interface to X1 mode. */
  72541. +MV_U32 mvPexForceX1(MV_U32 pexIf);
  72542. +
  72543. +/* mvPexIsPowerUp - Is PEX interface Power up? */
  72544. +MV_BOOL mvPexIsPowerUp(MV_U32 pexIf);
  72545. +
  72546. +/* mvPexPowerDown - Power Down */
  72547. +MV_VOID mvPexPowerDown(MV_U32 pexIf);
  72548. +
  72549. +/* mvPexPowerUp - Power Up */
  72550. +MV_VOID mvPexPowerUp(MV_U32 pexIf);
  72551. +
  72552. +/* mvPexPhyRegRead - Pex phy read */
  72553. +MV_VOID mvPexPhyRegRead(MV_U32 pexIf, MV_U32 regOffset, MV_U16 *value);
  72554. +
  72555. +/* mvPexPhyRegWrite - Pex phy write */
  72556. +MV_VOID mvPexPhyRegWrite(MV_U32 pexIf, MV_U32 regOffset, MV_U16 value);
  72557. +
  72558. +MV_STATUS mvPexActiveStateLinkPMEnable(MV_U32 pexIf, MV_BOOL enable);
  72559. +
  72560. +#endif /* #ifndef __INCPEXH */
  72561. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h
  72562. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h 1970-01-01 01:00:00.000000000 +0100
  72563. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h 2010-08-05 22:02:25.283905116 +0200
  72564. @@ -0,0 +1,751 @@
  72565. +/*******************************************************************************
  72566. +Copyright (C) Marvell International Ltd. and its affiliates
  72567. +
  72568. +This software file (the "File") is owned and distributed by Marvell
  72569. +International Ltd. and/or its affiliates ("Marvell") under the following
  72570. +alternative licensing terms. Once you have made an election to distribute the
  72571. +File under one of the following license alternatives, please (i) delete this
  72572. +introductory statement regarding license alternatives, (ii) delete the two
  72573. +license alternatives that you have not elected to use and (iii) preserve the
  72574. +Marvell copyright notice above.
  72575. +
  72576. +********************************************************************************
  72577. +Marvell Commercial License Option
  72578. +
  72579. +If you received this File from Marvell and you have entered into a commercial
  72580. +license agreement (a "Commercial License") with Marvell, the File is licensed
  72581. +to you under the terms of the applicable Commercial License.
  72582. +
  72583. +********************************************************************************
  72584. +Marvell GPL License Option
  72585. +
  72586. +If you received this File from Marvell, you may opt to use, redistribute and/or
  72587. +modify this File in accordance with the terms and conditions of the General
  72588. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  72589. +available along with the File in the license.txt file or by writing to the Free
  72590. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  72591. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  72592. +
  72593. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  72594. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  72595. +DISCLAIMED. The GPL License provides additional details about this warranty
  72596. +disclaimer.
  72597. +********************************************************************************
  72598. +Marvell BSD License Option
  72599. +
  72600. +If you received this File from Marvell, you may opt to use, redistribute and/or
  72601. +modify this File under the following licensing terms.
  72602. +Redistribution and use in source and binary forms, with or without modification,
  72603. +are permitted provided that the following conditions are met:
  72604. +
  72605. + * Redistributions of source code must retain the above copyright notice,
  72606. + this list of conditions and the following disclaimer.
  72607. +
  72608. + * Redistributions in binary form must reproduce the above copyright
  72609. + notice, this list of conditions and the following disclaimer in the
  72610. + documentation and/or other materials provided with the distribution.
  72611. +
  72612. + * Neither the name of Marvell nor the names of its contributors may be
  72613. + used to endorse or promote products derived from this software without
  72614. + specific prior written permission.
  72615. +
  72616. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  72617. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  72618. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  72619. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  72620. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  72621. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  72622. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  72623. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  72624. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  72625. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  72626. +
  72627. +*******************************************************************************/
  72628. +
  72629. +#ifndef __INCPEXREGSH
  72630. +#define __INCPEXREGSH
  72631. +
  72632. +#ifdef __cplusplus
  72633. +extern "C" {
  72634. +#endif /* __cplusplus */
  72635. +
  72636. +/* defines */
  72637. +#define MAX_PEX_DEVICES 32
  72638. +#define MAX_PEX_FUNCS 8
  72639. +#define MAX_PEX_BUSSES 256
  72640. +
  72641. +
  72642. +
  72643. +/*********************************************************/
  72644. +/* PCI Express Configuration Cycles Generation Registers */
  72645. +/*********************************************************/
  72646. +
  72647. +#define PEX_CFG_ADDR_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x18F8)
  72648. +#define PEX_CFG_DATA_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x18FC)
  72649. +#define PEX_PHY_ACCESS_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1B00)
  72650. +/* PCI Express Configuration Address Register */
  72651. +/* PEX_CFG_ADDR_REG (PXCAR)*/
  72652. +
  72653. +#define PXCAR_REG_NUM_OFFS 2
  72654. +#define PXCAR_REG_NUM_MAX 0x3F
  72655. +#define PXCAR_REG_NUM_MASK (PXCAR_REG_NUM_MAX << PXCAR_REG_NUM_OFFS)
  72656. +#define PXCAR_FUNC_NUM_OFFS 8
  72657. +#define PXCAR_FUNC_NUM_MAX 0x7
  72658. +#define PXCAR_FUNC_NUM_MASK (PXCAR_FUNC_NUM_MAX << PXCAR_FUNC_NUM_OFFS)
  72659. +#define PXCAR_DEVICE_NUM_OFFS 11
  72660. +#define PXCAR_DEVICE_NUM_MAX 0x1F
  72661. +#define PXCAR_DEVICE_NUM_MASK (PXCAR_DEVICE_NUM_MAX << PXCAR_DEVICE_NUM_OFFS)
  72662. +#define PXCAR_BUS_NUM_OFFS 16
  72663. +#define PXCAR_BUS_NUM_MAX 0xFF
  72664. +#define PXCAR_BUS_NUM_MASK (PXCAR_BUS_NUM_MAX << PXCAR_BUS_NUM_OFFS)
  72665. +#define PXCAR_EXT_REG_NUM_OFFS 24
  72666. +#define PXCAR_EXT_REG_NUM_MAX 0xF
  72667. +
  72668. +/* in pci express register address is now the legacy register address (8 bits)
  72669. +with the new extended register address (more 4 bits) , below is the mask of
  72670. +the upper 4 bits of the full register address */
  72671. +
  72672. +#define PXCAR_REAL_EXT_REG_NUM_OFFS 8
  72673. +#define PXCAR_EXT_REG_NUM_MASK (PXCAR_EXT_REG_NUM_MAX << PXCAR_EXT_REG_NUM_OFFS)
  72674. +#define PXCAR_CONFIG_EN BIT31
  72675. +
  72676. +#define PXCAR_REAL_EXT_REG_NUM_OFFS 8
  72677. +#define PXCAR_REAL_EXT_REG_NUM_MASK (0xF << PXCAR_REAL_EXT_REG_NUM_OFFS)
  72678. +
  72679. +/* The traditional PCI spec defined 6-bit field to describe register offset.*/
  72680. +/* The new PCI Express extend the register offset by an extra 4-bits. */
  72681. +/* The below macro assign 10-bit register offset into the apprpreate */
  72682. +/* fields in the CFG_ADDR_REG */
  72683. +#define PXCAR_REG_OFFS_SET(regOffs) \
  72684. + ( (regOff & PXCAR_REG_NUM_MASK) | \
  72685. + ( ((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >> PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS) )
  72686. +
  72687. +/***********************************/
  72688. +/* PCI Express Interrupt registers */
  72689. +/***********************************/
  72690. +#define PEX_CAUSE_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1900)
  72691. +#define PEX_MASK_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1910)
  72692. +
  72693. +#define PXICR_TX_REQ_IN_DLDOWN_ERR BIT0 /* Transmit request while field */
  72694. + /* <DLDown> of the PCI Express */
  72695. +/* PCI Express Interrupt Cause */
  72696. +/* PEX_INT_CAUSE_REG (PXICR)*/
  72697. +/* PEX_INT_MASK_REG*/
  72698. +/*
  72699. +NOTE:All bits except bits[27:24] are Read/Write Clear only. A cause bit sets
  72700. +upon an error event occurrence. A write of 0 clears the bit. A write of 1 has
  72701. +no affect. Bits[24:27} are set and cleared upon reception of interrupt
  72702. +emulation messages.
  72703. +
  72704. +Mask bit per cause bit. If a bit is set to 1, the corresponding event is
  72705. +enabled. Mask does not affect setting of the Interrupt Cause register bits;
  72706. +it only affects the assertion of the interrupt .*/
  72707. +
  72708. +
  72709. +#define PXICR_MDIS_CAUSE BIT1 /* Attempt to generate PCI transaction
  72710. + while master is disabled */
  72711. +#define PXICR_ERR_WRTO_REG_CAUSE BIT3 /* Erroneous write attempt to
  72712. + PCI Express internal register*/
  72713. +#define PXICR_HIT_DFLT_WIN_ERR BIT4 /* Hit Default Window Error */
  72714. +#define PXICR_RX_RAM_PAR_ERR BIT6 /* Rx RAM Parity Error */
  72715. +#define PXICR_TX_RAM_PAR_ERR BIT7 /* Tx RAM Parity Error */
  72716. +#define PXICR_COR_ERR_DET BIT8 /* Correctable Error Detected*/
  72717. +#define PXICR_NF_ERR_DET BIT9 /* Non-Fatal Error Detected*/
  72718. +#define PXICR_FERR_DET BIT10 /* Fatal Error Detected*/
  72719. +#define PXICR_DSTATE_CHANGE BIT11 /* Dstate Change Indication*/
  72720. +#define PXICR_BIST BIT12 /* PCI-Express BIST activated*/
  72721. +#define PXICR_FLW_CTRL_PROT BIT14 /* Flow Control Protocol Error */
  72722. +
  72723. +#define PXICR_RCV_UR_CA_ERR BIT15 /* Received UR or CA status. */
  72724. +#define PXICR_RCV_ERR_FATAL BIT16 /* Received ERR_FATAL message.*/
  72725. +#define PXICR_RCV_ERR_NON_FATAL BIT17 /* Received ERR_NONFATAL message*/
  72726. +#define PXICR_RCV_ERR_COR BIT18 /* Received ERR_COR message.*/
  72727. +#define PXICR_RCV_CRS BIT19 /* Received CRS completion status*/
  72728. +#define PXICR_SLV_HOT_RESET BIT20 /* Received Hot Reset Indication*/
  72729. +#define PXICR_SLV_DIS_LINK BIT21 /* Slave Disable Link Indication*/
  72730. +#define PXICR_SLV_LB BIT22 /* Slave Loopback Indication*/
  72731. +#define PXICR_LINK_FAIL BIT23 /* Link Failure indication.*/
  72732. +#define PXICR_RCV_INTA BIT24 /* IntA status.*/
  72733. +#define PXICR_RCV_INTB BIT25 /* IntB status.*/
  72734. +#define PXICR_RCV_INTC BIT26 /* IntC status.*/
  72735. +#define PXICR_RCV_INTD BIT27 /* IntD status.*/
  72736. +#define PXICR_RCV_PM_PME BIT28 /* Received PM_PME message. */
  72737. +
  72738. +
  72739. +/********************************************/
  72740. +/* PCI Express Control and Status Registers */
  72741. +/********************************************/
  72742. +#define PEX_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A00)
  72743. +#define PEX_STATUS_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A04)
  72744. +#define PEX_COMPLT_TMEOUT_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A10)
  72745. +#define PEX_PWR_MNG_EXT_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A18)
  72746. +#define PEX_FLOW_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A20)
  72747. +#define PEX_ACK_TMR_4X_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A30)
  72748. +#define PEX_ACK_TMR_1X_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A40)
  72749. +#define PEX_TL_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1AB0)
  72750. +
  72751. +
  72752. +#define PEX_RAM_PARITY_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A50)
  72753. +/* PCI Express Control Register */
  72754. +/* PEX_CTRL_REG (PXCR) */
  72755. +
  72756. +#define PXCR_CONF_LINK_OFFS 0
  72757. +#define PXCR_CONF_LINK_MASK (1 << PXCR_CONF_LINK_OFFS)
  72758. +#define PXCR_CONF_LINK_X4 (0 << PXCR_CONF_LINK_OFFS)
  72759. +#define PXCR_CONF_LINK_X1 (1 << PXCR_CONF_LINK_OFFS)
  72760. +#define PXCR_DEV_TYPE_CTRL_OFFS 1 /*PCI ExpressDevice Type Control*/
  72761. +#define PXCR_DEV_TYPE_CTRL_MASK BIT1
  72762. +#define PXCR_DEV_TYPE_CTRL_CMPLX (1 << PXCR_DEV_TYPE_CTRL_OFFS)
  72763. +#define PXCR_DEV_TYPE_CTRL_POINT (0 << PXCR_DEV_TYPE_CTRL_OFFS)
  72764. +#define PXCR_CFG_MAP_TO_MEM_EN BIT2 /* Configuration Header Mapping
  72765. + to Memory Space Enable */
  72766. +
  72767. +#define PXCR_CFG_MAP_TO_MEM_EN BIT2 /* Configuration Header Mapping
  72768. + to Memory Space Enable*/
  72769. +
  72770. +#define PXCR_RSRV1_OFFS 5
  72771. +#define PXCR_RSRV1_MASK (0x7 << PXCR_RSRV1_OFFS)
  72772. +#define PXCR_RSRV1_VAL (0x0 << PXCR_RSRV1_OFFS)
  72773. +
  72774. +#define PXCR_CONF_MAX_OUTSTND_OFFS 8 /*Maximum outstanding NP requests as a master*/
  72775. +#define PXCR_CONF_MAX_OUTSTND_MASK (0x3 << PXCR_CONF_MAX_OUTSTND_OFFS)
  72776. +
  72777. +
  72778. +#define PXCR_CONF_NFTS_OFFS 16 /*number of FTS Ordered-Sets*/
  72779. +#define PXCR_CONF_NFTS_MASK (0xff << PXCR_CONF_NFTS_OFFS)
  72780. +
  72781. +#define PXCR_CONF_MSTR_HOT_RESET BIT24 /*Master Hot-Reset.*/
  72782. +#define PXCR_CONF_MSTR_LB BIT26 /* Master Loopback */
  72783. +#define PXCR_CONF_MSTR_DIS_SCRMB BIT27 /* Master Disable Scrambling*/
  72784. +#define PXCR_CONF_DIRECT_DIS_SCRMB BIT28 /* Direct Disable Scrambling*/
  72785. +
  72786. +/* PCI Express Status Register */
  72787. +/* PEX_STATUS_REG (PXSR) */
  72788. +
  72789. +#define PXSR_DL_DOWN BIT0 /* DL_Down indication.*/
  72790. +
  72791. +#define PXSR_PEX_BUS_NUM_OFFS 8 /* Bus Number Indication */
  72792. +#define PXSR_PEX_BUS_NUM_MASK (0xff << PXSR_PEX_BUS_NUM_OFFS)
  72793. +
  72794. +#define PXSR_PEX_DEV_NUM_OFFS 16 /* Device Number Indication */
  72795. +#define PXSR_PEX_DEV_NUM_MASK (0x1f << PXSR_PEX_DEV_NUM_OFFS)
  72796. +
  72797. +#define PXSR_PEX_SLV_HOT_RESET BIT24 /* Slave Hot Reset Indication*/
  72798. +#define PXSR_PEX_SLV_DIS_LINK BIT25 /* Slave Disable Link Indication*/
  72799. +#define PXSR_PEX_SLV_LB BIT26 /* Slave Loopback Indication*/
  72800. +#define PXSR_PEX_SLV_DIS_SCRMB BIT27 /* Slave Disable Scrambling Indication*/
  72801. +
  72802. +
  72803. +/* PCI Express Completion Timeout Register */
  72804. +/* PEX_COMPLT_TMEOUT_REG (PXCTR)*/
  72805. +
  72806. +#define PXCTR_CMP_TO_THRSHLD_OFFS 0 /* Completion Timeout Threshold */
  72807. +#define PXCTR_CMP_TO_THRSHLD_MASK (0xffff << PXCTR_CMP_TO_THRSHLD_OFFS)
  72808. +
  72809. +/* PCI Express Power Management Extended Register */
  72810. +/* PEX_PWR_MNG_EXT_REG (PXPMER) */
  72811. +
  72812. +#define PXPMER_L1_ASPM_EN_OFFS 1
  72813. +#define PXPMER_L1_ASPM_EN_MASK (0x1 << PXPMER_L1_ASPM_EN_OFFS)
  72814. +
  72815. +/* PCI Express Flow Control Register */
  72816. +/* PEX_FLOW_CTRL_REG (PXFCR)*/
  72817. +
  72818. +#define PXFCR_PH_INIT_FC_OFFS 0 /*Posted Headers Flow Control Credit
  72819. + Initial Value.*/
  72820. +#define PXFCR_PH_INIT_FC_MASK (0xff << PXFCR_PH_INIT_FC_OFFS)
  72821. +
  72822. +
  72823. +#define PXFCR_NPH_INIT_FC_OFFS 8 /* Classified Non-Posted Headers
  72824. + Flow Control Credit Initial Value*/
  72825. +#define PXFCR_NPH_INIT_FC_MASK (0xff << PXFCR_NPH_INIT_FC_OFFS)
  72826. +
  72827. +#define PXFCR_CH_INIT_FC_OFFS 16 /* Completion Headers Flow Control
  72828. + Credit Initial Value Infinite*/
  72829. +
  72830. +#define PXFCR_CH_INIT_FC_MASK (0xff << PXFCR_CH_INIT_FC_OFFS)
  72831. +
  72832. +#define PXFCR_FC_UPDATE_TO_OFFS 24 /* Flow Control Update Timeout */
  72833. +#define PXFCR_FC_UPDATE_TO_MASK (0xff << PXFCR_FC_UPDATE_TO_OFFS)
  72834. +
  72835. +/* PCI Express Acknowledge Timers (4X) Register */
  72836. +/* PEX_ACK_TMR_4X_REG (PXAT4R) */
  72837. +#define PXAT1R_ACK_LAT_TOX4_OFFS 0 /* Ack Latency Timer Timeout Value */
  72838. +#define PXAT1R_ACK_LAT_TOX4_MASK (0xffff << PXAT4R_ACK_LAT_TOX1_OFFS)
  72839. +#define PXAT1R_ACK_RPLY_TOX4_OFFS 16 /* Ack Replay Timer Timeout Value */
  72840. +#define PXAT1R_ACK_RPLY_TOX4_MASK (0xffff << PXAT1R_ACK_RPLY_TOX1_OFFS)
  72841. +
  72842. +/* PCI Express Acknowledge Timers (1X) Register */
  72843. +/* PEX_ACK_TMR_1X_REG (PXAT1R) */
  72844. +
  72845. +#define PXAT1R_ACK_LAT_TOX1_OFFS 0 /* Acknowledge Latency Timer Timeout
  72846. + Value for 1X Link*/
  72847. +#define PXAT1R_ACK_LAT_TOX1_MASK (0xffff << PXAT1R_ACK_LAT_TOX1_OFFS)
  72848. +
  72849. +#define PXAT1R_ACK_RPLY_TOX1_OFFS 16 /* Acknowledge Replay Timer Timeout
  72850. + Value for 1X*/
  72851. +#define PXAT1R_ACK_RPLY_TOX1_MASK (0xffff << PXAT1R_ACK_RPLY_TOX1_OFFS)
  72852. +
  72853. +
  72854. +/* PCI Express TL Control Register */
  72855. +/* PEX_TL_CTRL_REG (PXTCR) */
  72856. +
  72857. +#define PXTCR_TX_CMP_BUFF_NO_OFFS 8 /*Number of completion buffers in Tx*/
  72858. +#define PXTCR_TX_CMP_BUFF_NO_MASK (0xf << PXTCR_TX_CMP_BUFF_NO_OFFS)
  72859. +
  72860. +/* PCI Express Debug MAC Control Register */
  72861. +/* PEX_DEBUG_MAC_CTRL_REG (PXDMCR) */
  72862. +
  72863. +#define PXDMCR_LINKUP BIT4
  72864. +
  72865. +
  72866. +
  72867. +/**********************************************/
  72868. +/* PCI Express Configuration Header Registers */
  72869. +/**********************************************/
  72870. +#define PEX_CFG_DIRECT_ACCESS(pexIf,cfgReg) ((PEX_IF_BASE(pexIf)) + (cfgReg))
  72871. +
  72872. +#define PEX_DEVICE_AND_VENDOR_ID 0x000
  72873. +#define PEX_STATUS_AND_COMMAND 0x004
  72874. +#define PEX_CLASS_CODE_AND_REVISION_ID 0x008
  72875. +#define PEX_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE 0x00C
  72876. +#define PEX_MEMORY_BAR_BASE_ADDR(barNum) (0x010 + ((barNum) << 2))
  72877. +#define PEX_MV_BAR_BASE(barNum) (0x010 + (barNum) * 8)
  72878. +#define PEX_MV_BAR_BASE_HIGH(barNum) (0x014 + (barNum) * 8)
  72879. +#define PEX_BAR0_INTER_REG 0x010
  72880. +#define PEX_BAR0_INTER_REG_HIGH 0x014
  72881. +#define PEX_BAR1_REG 0x018
  72882. +#define PEX_BAR1_REG_HIGH 0x01C
  72883. +#define PEX_BAR2_REG 0x020
  72884. +#define PEX_BAR2_REG_HIGH 0x024
  72885. +
  72886. +#define PEX_SUBSYS_ID_AND_SUBSYS_VENDOR_ID 0x02C
  72887. +#define PEX_EXPANSION_ROM_BASE_ADDR_REG 0x030
  72888. +#define PEX_CAPABILTY_LIST_POINTER 0x034
  72889. +#define PEX_INTERRUPT_PIN_AND_LINE 0x03C
  72890. +
  72891. +/* capability list */
  72892. +#define PEX_POWER_MNG_CAPABILITY 0x040
  72893. +#define PEX_POWER_MNG_STATUS_CONTROL 0x044
  72894. +
  72895. +#define PEX_MSI_MESSAGE_CONTROL 0x050
  72896. +#define PEX_MSI_MESSAGE_ADDR 0x054
  72897. +#define PEX_MSI_MESSAGE_HIGH_ADDR 0x058
  72898. +#define PEX_MSI_MESSAGE_DATA 0x05C
  72899. +
  72900. +#define PEX_CAPABILITY_REG 0x60
  72901. +#define PEX_DEV_CAPABILITY_REG 0x64
  72902. +#define PEX_DEV_CTRL_STAT_REG 0x68
  72903. +#define PEX_LINK_CAPABILITY_REG 0x6C
  72904. +#define PEX_LINK_CTRL_STAT_REG 0x70
  72905. +
  72906. +#define PEX_ADV_ERR_RPRT_HDR_TRGT_REG 0x100
  72907. +#define PEX_UNCORRECT_ERR_STAT_REG 0x104
  72908. +#define PEX_UNCORRECT_ERR_MASK_REG 0x108
  72909. +#define PEX_UNCORRECT_ERR_SERVITY_REG 0x10C
  72910. +#define PEX_CORRECT_ERR_STAT_REG 0x110
  72911. +#define PEX_CORRECT_ERR_MASK_REG 0x114
  72912. +#define PEX_ADV_ERR_CAPABILITY_CTRL_REG 0x118
  72913. +#define PEX_HDR_LOG_FIRST_DWORD_REG 0x11C
  72914. +#define PEX_HDR_LOG_SECOND_DWORD_REG 0x120
  72915. +#define PEX_HDR_LOG_THIRD_DWORD_REG 0x124
  72916. +#define PEX_HDR_LOG_FOURTH_DWORD_REG 0x128
  72917. +
  72918. +
  72919. +
  72920. +/* PCI Express Device and Vendor ID Register*/
  72921. +/*PEX_DEVICE_AND_VENDOR_ID (PXDAVI)*/
  72922. +
  72923. +#define PXDAVI_VEN_ID_OFFS 0 /* Vendor ID */
  72924. +#define PXDAVI_VEN_ID_MASK (0xffff << PXDAVI_VEN_ID_OFFS)
  72925. +
  72926. +#define PXDAVI_DEV_ID_OFFS 16 /* Device ID */
  72927. +#define PXDAVI_DEV_ID_MASK (0xffff << PXDAVI_DEV_ID_OFFS)
  72928. +
  72929. +
  72930. +/* PCI Express Command and Status Register*/
  72931. +/*PEX_STATUS_AND_COMMAND (PXSAC)*/
  72932. +
  72933. +#define PXSAC_IO_EN BIT0 /* IO Enable */
  72934. +#define PXSAC_MEM_EN BIT1 /* Memory Enable */
  72935. +#define PXSAC_MASTER_EN BIT2 /* Master Enable */
  72936. +#define PXSAC_PERR_EN BIT6 /* Parity Errors Respond Enable */
  72937. +#define PXSAC_SERR_EN BIT8 /* Ability to assert SERR# line */
  72938. +#define PXSAC_INT_DIS BIT10 /* Interrupt Disable */
  72939. +#define PXSAC_INT_STAT BIT19 /* Interrupt Status */
  72940. +#define PXSAC_CAP_LIST BIT20 /* Capability List Support */
  72941. +#define PXSAC_MAS_DATA_PERR BIT24 /* Master Data Parity Error */
  72942. +#define PXSAC_SLAVE_TABORT BIT27 /* Signalled Target Abort */
  72943. +#define PXSAC_RT_ABORT BIT28 /* Recieved Target Abort */
  72944. +#define PXSAC_MABORT BIT29 /* Recieved Master Abort */
  72945. +#define PXSAC_SYSERR BIT30 /* Signalled system error */
  72946. +#define PXSAC_DET_PARERR BIT31 /* Detect Parity Error */
  72947. +
  72948. +
  72949. +/* PCI Express Class Code and Revision ID Register*/
  72950. +/*PEX_CLASS_CODE_AND_REVISION_ID (PXCCARI)*/
  72951. +
  72952. +#define PXCCARI_REVID_OFFS 0 /* Revision ID */
  72953. +#define PXCCARI_REVID_MASK (0xff << PXCCARI_REVID_OFFS)
  72954. +
  72955. +#define PXCCARI_FULL_CLASS_OFFS 8 /* Full Class Code */
  72956. +#define PXCCARI_FULL_CLASS_MASK (0xffffff << PXCCARI_FULL_CLASS_OFFS)
  72957. +
  72958. +#define PXCCARI_PROGIF_OFFS 8 /* Prog .I/F*/
  72959. +#define PXCCARI_PROGIF_MASK (0xff << PXCCARI_PROGIF_OFFS)
  72960. +
  72961. +#define PXCCARI_SUB_CLASS_OFFS 16 /* Sub Class*/
  72962. +#define PXCCARI_SUB_CLASS_MASK (0xff << PXCCARI_SUB_CLASS_OFFS)
  72963. +
  72964. +#define PXCCARI_BASE_CLASS_OFFS 24 /* Base Class*/
  72965. +#define PXCCARI_BASE_CLASS_MASK (0xff << PXCCARI_BASE_CLASS_OFFS)
  72966. +
  72967. +
  72968. +/* PCI Express BIST, Header Type and Cache Line Size Register*/
  72969. +/*PEX_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE (PXBHTLTCL)*/
  72970. +
  72971. +#define PXBHTLTCL_CACHELINE_OFFS 0 /* Specifies the cache line size */
  72972. +#define PXBHTLTCL_CACHELINE_MASK (0xff << PXBHTLTCL_CACHELINE_OFFS)
  72973. +
  72974. +#define PXBHTLTCL_HEADTYPE_FULL_OFFS 16 /* Full Header Type */
  72975. +#define PXBHTLTCL_HEADTYPE_FULL_MASK (0xff << PXBHTLTCL_HEADTYPE_FULL_OFFS)
  72976. +
  72977. +#define PXBHTLTCL_MULTI_FUNC BIT23 /* Multi/Single function */
  72978. +
  72979. +#define PXBHTLTCL_HEADER_OFFS 16 /* Header type */
  72980. +#define PXBHTLTCL_HEADER_MASK (0x7f << PXBHTLTCL_HEADER_OFFS)
  72981. +#define PXBHTLTCL_HEADER_STANDARD (0x0 << PXBHTLTCL_HEADER_OFFS)
  72982. +#define PXBHTLTCL_HEADER_PCI2PCI_BRIDGE (0x1 << PXBHTLTCL_HEADER_OFFS)
  72983. +
  72984. +
  72985. +#define PXBHTLTCL_BISTCOMP_OFFS 24 /* BIST Completion Code */
  72986. +#define PXBHTLTCL_BISTCOMP_MASK (0xf << PXBHTLTCL_BISTCOMP_OFFS)
  72987. +
  72988. +#define PXBHTLTCL_BISTACT BIT30 /* BIST Activate bit */
  72989. +#define PXBHTLTCL_BISTCAP BIT31 /* BIST Capable Bit */
  72990. +#define PXBHTLTCL_BISTCAP_OFFS 31
  72991. +#define PXBHTLTCL_BISTCAP_MASK BIT31
  72992. +#define PXBHTLTCL_BISTCAP_VAL 0
  72993. +
  72994. +
  72995. +/* PCI Express Subsystem Device and Vendor ID */
  72996. +/*PEX_SUBSYS_ID_AND_SUBSYS_VENDOR_ID (PXSIASVI)*/
  72997. +
  72998. +#define PXSIASVI_VENID_OFFS 0 /* Subsystem Manufacturer Vendor ID Number */
  72999. +#define PXSIASVI_VENID_MASK (0xffff << PXSIASVI_VENID_OFFS)
  73000. +
  73001. +#define PXSIASVI_DEVID_OFFS 16 /* Subsystem Device ID Number */
  73002. +#define PXSIASVI_DEVID_MASK (0xffff << PXSIASVI_DEVID_OFFS)
  73003. +
  73004. +
  73005. +/* PCI Express Capability List Pointer Register*/
  73006. +/*PEX_CAPABILTY_LIST_POINTER (PXCLP)*/
  73007. +
  73008. +#define PXCLP_CAPPTR_OFFS 0 /* Capability List Pointer */
  73009. +#define PXCLP_CAPPTR_MASK (0xff << PXCLP_CAPPTR_OFFS)
  73010. +
  73011. +/* PCI Express Interrupt Pin and Line Register */
  73012. +/*PEX_INTERRUPT_PIN_AND_LINE (PXIPAL)*/
  73013. +
  73014. +#define PXIPAL_INTLINE_OFFS 0 /* Interrupt line (IRQ) */
  73015. +#define PXIPAL_INTLINE_MASK (0xff << PXIPAL_INTLINE_OFFS)
  73016. +
  73017. +#define PXIPAL_INTPIN_OFFS 8 /* interrupt pin (A,B,C,D) */
  73018. +#define PXIPAL_INTPIN_MASK (0xff << PXIPAL_INTPIN_OFFS)
  73019. +
  73020. +
  73021. +/* PCI Express Power Management Capability Header Register*/
  73022. +/*PEX_POWER_MNG_CAPABILITY (PXPMC)*/
  73023. +
  73024. +#define PXPMC_CAP_ID_OFFS 0 /* Capability ID */
  73025. +#define PXPMC_CAP_ID_MASK (0xff << PXPMC_CAP_ID_OFFS)
  73026. +
  73027. +#define PXPMC_NEXT_PTR_OFFS 8 /* Next Item Pointer */
  73028. +#define PXPMC_NEXT_PTR_MASK (0xff << PXPMC_NEXT_PTR_OFFS)
  73029. +
  73030. +#define PXPMC_PMC_VER_OFFS 16 /* PCI Power Management Capability Version*/
  73031. +#define PXPMC_PMC_VER_MASK (0x7 << PXPMC_PMC_VER_OFFS)
  73032. +
  73033. +#define PXPMC_DSI BIT21/* Device Specific Initialization */
  73034. +
  73035. +#define PXPMC_AUX_CUR_OFFS 22 /* Auxiliary Current Requirements */
  73036. +#define PXPMC_AUX_CUR_MASK (0x7 << PXPMC_AUX_CUR_OFFS)
  73037. +
  73038. +#define PXPMC_D1_SUP BIT25 /* D1 Power Management support*/
  73039. +
  73040. +#define PXPMC_D2_SUP BIT26 /* D2 Power Management support*/
  73041. +
  73042. +#define PXPMC_PME_SUP_OFFS 27 /* PM Event generation support*/
  73043. +#define PXPMC_PME_SUP_MASK (0x1f << PXPMC_PME_SUP_OFFS)
  73044. +
  73045. +/* PCI Express Power Management Control and Status Register*/
  73046. +/*PEX_POWER_MNG_STATUS_CONTROL (PXPMSC)*/
  73047. +
  73048. +#define PXPMSC_PM_STATE_OFFS 0 /* Power State */
  73049. +#define PXPMSC_PM_STATE_MASK (0x3 << PXPMSC_PM_STATE_OFFS)
  73050. +#define PXPMSC_PM_STATE_D0 (0x0 << PXPMSC_PM_STATE_OFFS)
  73051. +#define PXPMSC_PM_STATE_D1 (0x1 << PXPMSC_PM_STATE_OFFS)
  73052. +#define PXPMSC_PM_STATE_D2 (0x2 << PXPMSC_PM_STATE_OFFS)
  73053. +#define PXPMSC_PM_STATE_D3 (0x3 << PXPMSC_PM_STATE_OFFS)
  73054. +
  73055. +#define PXPMSC_PME_EN BIT8/* PM_PME Message Generation Enable */
  73056. +
  73057. +#define PXPMSC_PM_DATA_SEL_OFFS 9 /* Data Select*/
  73058. +#define PXPMSC_PM_DATA_SEL_MASK (0xf << PXPMSC_PM_DATA_SEL_OFFS)
  73059. +
  73060. +#define PXPMSC_PM_DATA_SCALE_OFFS 13 /* Data Scale */
  73061. +#define PXPMSC_PM_DATA_SCALE_MASK (0x3 << PXPMSC_PM_DATA_SCALE_OFFS)
  73062. +
  73063. +#define PXPMSC_PME_STAT BIT15/* PME Status */
  73064. +
  73065. +#define PXPMSC_PM_DATA_OFFS 24 /* State Data */
  73066. +#define PXPMSC_PM_DATA_MASK (0xff << PXPMSC_PM_DATA_OFFS)
  73067. +
  73068. +
  73069. +/* PCI Express MSI Message Control Register*/
  73070. +/*PEX_MSI_MESSAGE_CONTROL (PXMMC)*/
  73071. +
  73072. +#define PXMMC_CAP_ID_OFFS 0 /* Capability ID */
  73073. +#define PXMMC_CAP_ID_MASK (0xff << PXMMC_CAP_ID_OFFS)
  73074. +
  73075. +#define PXMMC_NEXT_PTR_OFFS 8 /* Next Item Pointer */
  73076. +#define PXMMC_NEXT_PTR_MASK (0xff << PXMMC_NEXT_PTR_OFFS)
  73077. +
  73078. +#define PXMMC_MSI_EN BIT18 /* MSI Enable */
  73079. +
  73080. +#define PXMMC_MULTI_CAP_OFFS 17 /* Multiple Message Capable */
  73081. +#define PXMMC_MULTI_CAP_MASK (0x7 << PXMMC_MULTI_CAP_OFFS)
  73082. +
  73083. +#define PXMMC_MULTI_EN_OFFS 20 /* Multiple Messages Enable */
  73084. +#define PXMMC_MULTI_EN_MASK (0x7 << PXMMC_MULTI_EN_OFFS)
  73085. +
  73086. +#define PXMMC_ADDR64 BIT23 /* 64-bit Addressing Capable */
  73087. +
  73088. +
  73089. +/* PCI Express MSI Message Address Register*/
  73090. +/*PEX_MSI_MESSAGE_ADDR (PXMMA)*/
  73091. +
  73092. +#define PXMMA_MSI_ADDR_OFFS 2 /* Message Address corresponds to
  73093. + Address[31:2] of the MSI MWr TLP*/
  73094. +#define PXMMA_MSI_ADDR_MASK (0x3fffffff << PXMMA_MSI_ADDR_OFFS)
  73095. +
  73096. +
  73097. +/* PCI Express MSI Message Address (High) Register */
  73098. +/*PEX_MSI_MESSAGE_HIGH_ADDR (PXMMHA)*/
  73099. +
  73100. +#define PXMMA_MSI_ADDR_H_OFFS 0 /* Message Upper Address corresponds to
  73101. + Address[63:32] of the MSI MWr TLP*/
  73102. +#define PXMMA_MSI_ADDR_H_MASK (0xffffffff << PXMMA_MSI_ADDR_H_OFFS )
  73103. +
  73104. +
  73105. +/* PCI Express MSI Message Data Register*/
  73106. +/*PEX_MSI_MESSAGE_DATA (PXMMD)*/
  73107. +
  73108. +#define PXMMD_MSI_DATA_OFFS 0 /* Message Data */
  73109. +#define PXMMD_MSI_DATA_MASK (0xffff << PXMMD_MSI_DATA_OFFS )
  73110. +
  73111. +
  73112. +/* PCI Express Capability Register*/
  73113. +/*PEX_CAPABILITY_REG (PXCR)*/
  73114. +
  73115. +#define PXCR_CAP_ID_OFFS 0 /* Capability ID*/
  73116. +#define PXCR_CAP_ID_MASK (0xff << PXCR_CAP_ID_OFFS)
  73117. +
  73118. +#define PXCR_NEXT_PTR_OFFS 8 /* Next Item Pointer*/
  73119. +#define PXCR_NEXT_PTR_MASK (0xff << PXCR_NEXT_PTR_OFFS)
  73120. +
  73121. +#define PXCR_CAP_VER_OFFS 16 /* Capability Version*/
  73122. +#define PXCR_CAP_VER_MASK (0xf << PXCR_CAP_VER_OFFS)
  73123. +
  73124. +#define PXCR_DEV_TYPE_OFFS 20 /* Device/Port Type*/
  73125. +#define PXCR_DEV_TYPE_MASK (0xf << PXCR_DEV_TYPE_OFFS)
  73126. +
  73127. +#define PXCR_SLOT_IMP BIT24 /* Slot Implemented*/
  73128. +
  73129. +#define PXCR_INT_MSG_NUM_OFFS 25 /* Interrupt Message Number*/
  73130. +#define PXCR_INT_MSG_NUM_MASK (0x1f << PXCR_INT_MSG_NUM_OFFS)
  73131. +
  73132. +
  73133. +/* PCI Express Device Capabilities Register */
  73134. +/*PEX_DEV_CAPABILITY_REG (PXDCR)*/
  73135. +
  73136. +#define PXDCR_MAX_PLD_SIZE_SUP_OFFS 0 /* Maximum Payload Size Supported*/
  73137. +#define PXDCR_MAX_PLD_SIZE_SUP_MASK (0x7 << PXDCR_MAX_PLD_SIZE_SUP_OFFS)
  73138. +
  73139. +#define PXDCR_EP_L0S_ACC_LAT_OFFS 6/* Endpoint L0s Acceptable Latency*/
  73140. +#define PXDCR_EP_L0S_ACC_LAT_MASK (0x7 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  73141. +#define PXDCR_EP_L0S_ACC_LAT_64NS_LESS (0x0 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  73142. +#define PXDCR_EP_L0S_ACC_LAT_64NS_128NS (0x1 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  73143. +#define PXDCR_EP_L0S_ACC_LAT_128NS_256NS (0x2 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  73144. +#define PXDCR_EP_L0S_ACC_LAT_256NS_512NS (0x3 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  73145. +#define PXDCR_EP_L0S_ACC_LAT_512NS_1US (0x4 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  73146. +#define PXDCR_EP_L0S_ACC_LAT_1US_2US (0x5 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  73147. +#define PXDCR_EP_L0S_ACC_LAT_2US_4US (0x6 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  73148. +#define PXDCR_EP_L0S_ACC_LAT_4US_MORE (0x7 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  73149. +
  73150. +#define PXDCR_EP_L1_ACC_LAT_OFFS 9 /* Endpoint L1 Acceptable Latency*/
  73151. +#define PXDCR_EP_L1_ACC_LAT_MASK (0x7 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73152. +#define PXDCR_EP_L1_ACC_LAT_64NS_LESS (0x0 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73153. +#define PXDCR_EP_L1_ACC_LAT_64NS_128NS (0x1 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73154. +#define PXDCR_EP_L1_ACC_LAT_128NS_256NS (0x2 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73155. +#define PXDCR_EP_L1_ACC_LAT_256NS_512NS (0x3 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73156. +#define PXDCR_EP_L1_ACC_LAT_512NS_1US (0x4 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73157. +#define PXDCR_EP_L1_ACC_LAT_1US_2US (0x5 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73158. +#define PXDCR_EP_L1_ACC_LAT_2US_4US (0x6 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73159. +#define PXDCR_EP_L1_ACC_LAT_4US_MORE (0x7 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73160. +
  73161. +
  73162. +#define PXDCR_ATT_BUT_PRS_OFFS 12 /* Attention Button Present*/
  73163. +#define PXDCR_ATT_BUT_PRS_MASK BIT12
  73164. +#define PXDCR_ATT_BUT_PRS_IMPLEMENTED BIT12
  73165. +
  73166. +#define PXDCR_ATT_IND_PRS_OFFS 13 /* Attention Indicator Present*/
  73167. +#define PXDCR_ATT_IND_PRS_MASK BIT13
  73168. +#define PXDCR_ATT_IND_PRS_IMPLEMENTED BIT13
  73169. +
  73170. +#define PXDCR_PWR_IND_PRS_OFFS 14/* Power Indicator Present*/
  73171. +#define PXDCR_PWR_IND_PRS_MASK BIT14
  73172. +#define PXDCR_PWR_IND_PRS_IMPLEMENTED BIT14
  73173. +
  73174. +#define PXDCR_CAP_SPL_VAL_OFFS 18 /*Captured Slot Power Limit
  73175. + Value*/
  73176. +#define PXDCR_CAP_SPL_VAL_MASK (0xff << PXDCR_CAP_SPL_VAL_OFFS)
  73177. +
  73178. +#define PXDCR_CAP_SP_LSCL_OFFS 26 /* Captured Slot Power Limit
  73179. + Scale */
  73180. +#define PXDCR_CAP_SP_LSCL_MASK (0x3 << PXDCR_CAP_SP_LSCL_OFFS)
  73181. +
  73182. +/* PCI Express Device Control Status Register */
  73183. +/*PEX_DEV_CTRL_STAT_REG (PXDCSR)*/
  73184. +
  73185. +#define PXDCSR_COR_ERR_REP_EN BIT0 /* Correctable Error Reporting Enable*/
  73186. +#define PXDCSR_NF_ERR_REP_EN BIT1 /* Non-Fatal Error Reporting Enable*/
  73187. +#define PXDCSR_F_ERR_REP_EN BIT2 /* Fatal Error Reporting Enable*/
  73188. +#define PXDCSR_UR_REP_EN BIT3 /* Unsupported Request (UR)
  73189. + Reporting Enable*/
  73190. +#define PXDCSR_EN_RO BIT4 /* Enable Relaxed Ordering*/
  73191. +
  73192. +#define PXDCSR_MAX_PLD_SZ_OFFS 5 /* Maximum Payload Size*/
  73193. +#define PXDCSR_MAX_PLD_SZ_MASK (0x7 << PXDCSR_MAX_PLD_SZ_OFFS)
  73194. +#define PXDCSR_MAX_PLD_SZ_128B (0x0 << PXDCSR_MAX_PLD_SZ_OFFS)
  73195. +#define PXDCSR_EN_NS BIT11 /* Enable No Snoop*/
  73196. +
  73197. +#define PXDCSR_MAX_RD_RQ_SZ_OFFS 12 /* Maximum Read Request Size*/
  73198. +#define PXDCSR_MAX_RD_RQ_SZ_MASK (0x7 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  73199. +#define PXDCSR_MAX_RD_RQ_SZ_128B (0x0 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  73200. +#define PXDCSR_MAX_RD_RQ_SZ_256B (0x1 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  73201. +#define PXDCSR_MAX_RD_RQ_SZ_512B (0x2 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  73202. +#define PXDCSR_MAX_RD_RQ_SZ_1KB (0x3 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  73203. +#define PXDCSR_MAX_RD_RQ_SZ_2KB (0x4 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  73204. +#define PXDCSR_MAX_RD_RQ_SZ_4KB (0x5 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  73205. +
  73206. +#define PXDCSR_COR_ERR_DET BIT16 /* Correctable Error Detected*/
  73207. +#define PXDCSR_NF_ERR_DET BIT17 /* Non-Fatal Error Detected.*/
  73208. +#define PXDCSR_F_ERR_DET BIT18 /* Fatal Error Detected.*/
  73209. +#define PXDCSR_UR_DET BIT19 /* Unsupported Request Detected */
  73210. +#define PXDCSR_AUX_PWR_DET BIT20 /* Reserved*/
  73211. +
  73212. +#define PXDCSR_TRANS_PEND_OFFS 21 /* Transactions Pending*/
  73213. +#define PXDCSR_TRANS_PEND_MASK BIT21
  73214. +#define PXDCSR_TRANS_PEND_NOT_COMPLETED (0x1 << PXDCSR_TRANS_PEND_OFFS)
  73215. +
  73216. +
  73217. +/* PCI Express Link Capabilities Register*/
  73218. +/*PEX_LINK_CAPABILITY_REG (PXLCR)*/
  73219. +
  73220. +#define PXLCR_MAX_LINK_SPD_OFFS 0 /* Maximum Link Speed*/
  73221. +#define PXLCR_MAX_LINK_SPD_MASK (0xf << PXLCR_MAX_LINK_SPD_OFFS)
  73222. +
  73223. +#define PXLCR_MAX_LNK_WDTH_OFFS 3 /* Maximum Link Width*/
  73224. +#define PXLCR_MAX_LNK_WDTH_MASK (0x3f << PXLCR_MAX_LNK_WDTH_OFFS)
  73225. +
  73226. +#define PXLCR_ASPM_SUP_OFFS 10 /* Active State Link PM Support*/
  73227. +#define PXLCR_ASPM_SUP_MASK (0x3 << PXLCR_ASPM_SUP_OFFS)
  73228. +
  73229. +#define PXLCR_L0S_EXT_LAT_OFFS 12 /* L0s Exit Latency*/
  73230. +#define PXLCR_L0S_EXT_LAT_MASK (0x7 << PXLCR_L0S_EXT_LAT_OFFS)
  73231. +#define PXLCR_L0S_EXT_LAT_64NS_LESS (0x0 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73232. +#define PXLCR_L0S_EXT_LAT_64NS_128NS (0x1 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73233. +#define PXLCR_L0S_EXT_LAT_128NS_256NS (0x2 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73234. +#define PXLCR_L0S_EXT_LAT_256NS_512NS (0x3 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73235. +#define PXLCR_L0S_EXT_LAT_512NS_1US (0x4 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73236. +#define PXLCR_L0S_EXT_LAT_1US_2US (0x5 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73237. +#define PXLCR_L0S_EXT_LAT_2US_4US (0x6 << PXDCR_EP_L1_ACC_LAT_OFFS)
  73238. +
  73239. +#define PXLCR_POR_TNUM_OFFS 24 /* Port Number */
  73240. +#define PXLCR_POR_TNUM_MASK (0xff << PXLCR_POR_TNUM_OFFS)
  73241. +
  73242. +/* PCI Express Link Control Status Register */
  73243. +/*PEX_LINK_CTRL_STAT_REG (PXLCSR)*/
  73244. +
  73245. +#define PXLCSR_ASPM_CNT_OFFS 0 /* Active State Link PM Control */
  73246. +#define PXLCSR_ASPM_CNT_MASK (0x3 << PXLCSR_ASPM_CNT_OFFS)
  73247. +#define PXLCSR_ASPM_CNT_DISABLED (0x0 << PXLCSR_ASPM_CNT_OFFS)
  73248. +#define PXLCSR_ASPM_CNT_L0S_ENT_SUPP (0x1 << PXLCSR_ASPM_CNT_OFFS)
  73249. +#define PXLCSR_ASPM_CNT_L1S_ENT_SUPP (0x2 << PXLCSR_ASPM_CNT_OFFS)
  73250. +#define PXLCSR_ASPM_CNT_L0S_L1S_ENT_SUPP (0x3 << PXLCSR_ASPM_CNT_OFFS)
  73251. +
  73252. +#define PXLCSR_RCB_OFFS 3 /* Read Completion Boundary */
  73253. +#define PXLCSR_RCB_MASK BIT3
  73254. +#define PXLCSR_RCB_64B (0 << PXLCSR_RCB_OFFS)
  73255. +#define PXLCSR_RCB_128B (1 << PXLCSR_RCB_OFFS)
  73256. +
  73257. +#define PXLCSR_LNK_DIS BIT4 /* Link Disable */
  73258. +#define PXLCSR_RETRN_LNK BIT5 /* Retrain Link */
  73259. +#define PXLCSR_CMN_CLK_CFG BIT6 /* Common Clock Configuration */
  73260. +#define PXLCSR_EXTD_SNC BIT7 /* Extended Sync */
  73261. +
  73262. +#define PXLCSR_LNK_SPD_OFFS 16 /* Link Speed */
  73263. +#define PXLCSR_LNK_SPD_MASK (0xf << PXLCSR_LNK_SPD_OFFS)
  73264. +
  73265. +#define PXLCSR_NEG_LNK_WDTH_OFFS 20 /* Negotiated Link Width */
  73266. +#define PXLCSR_NEG_LNK_WDTH_MASK (0x3f << PXLCSR_NEG_LNK_WDTH_OFFS)
  73267. +#define PXLCSR_NEG_LNK_WDTH_X1 (0x1 << PXLCSR_NEG_LNK_WDTH_OFFS)
  73268. +
  73269. +#define PXLCSR_LNK_TRN BIT27 /* Link Training */
  73270. +
  73271. +#define PXLCSR_SLT_CLK_CFG_OFFS 28 /* Slot Clock Configuration */
  73272. +#define PXLCSR_SLT_CLK_CFG_MASK BIT28
  73273. +#define PXLCSR_SLT_CLK_CFG_INDPNT (0x0 << PXLCSR_SLT_CLK_CFG_OFFS)
  73274. +#define PXLCSR_SLT_CLK_CFG_REF (0x1 << PXLCSR_SLT_CLK_CFG_OFFS)
  73275. +
  73276. +/* PCI Express Advanced Error Report Header Register */
  73277. +/*PEX_ADV_ERR_RPRT_HDR_TRGT_REG (PXAERHTR)*/
  73278. +
  73279. +/* PCI Express Uncorrectable Error Status Register*/
  73280. +/*PEX_UNCORRECT_ERR_STAT_REG (PXUESR)*/
  73281. +
  73282. +/* PCI Express Uncorrectable Error Mask Register */
  73283. +/*PEX_UNCORRECT_ERR_MASK_REG (PXUEMR)*/
  73284. +
  73285. +/* PCI Express Uncorrectable Error Severity Register */
  73286. +/*PEX_UNCORRECT_ERR_SERVITY_REG (PXUESR)*/
  73287. +
  73288. +/* PCI Express Correctable Error Status Register */
  73289. +/*PEX_CORRECT_ERR_STAT_REG (PXCESR)*/
  73290. +
  73291. +/* PCI Express Correctable Error Mask Register */
  73292. +/*PEX_CORRECT_ERR_MASK_REG (PXCEMR)*/
  73293. +
  73294. +/* PCI Express Advanced Error Capability and Control Register*/
  73295. +/*PEX_ADV_ERR_CAPABILITY_CTRL_REG (PXAECCR)*/
  73296. +
  73297. +/* PCI Express Header Log First DWORD Register*/
  73298. +/*PEX_HDR_LOG_FIRST_DWORD_REG (PXHLFDR)*/
  73299. +
  73300. +/* PCI Express Header Log Second DWORD Register*/
  73301. +/*PEX_HDR_LOG_SECOND_DWORD_REG (PXHLSDR)*/
  73302. +
  73303. +/* PCI Express Header Log Third DWORD Register*/
  73304. +/*PEX_HDR_LOG_THIRD_DWORD_REG (PXHLTDR)*/
  73305. +
  73306. +/* PCI Express Header Log Fourth DWORD Register*/
  73307. +/*PEX_HDR_LOG_FOURTH_DWORD_REG (PXHLFDR)*/
  73308. +
  73309. +#ifdef __cplusplus
  73310. +}
  73311. +#endif /* __cplusplus */
  73312. +
  73313. +#endif /* #ifndef __INCPEXREGSH */
  73314. +
  73315. +
  73316. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c
  73317. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c 1970-01-01 01:00:00.000000000 +0100
  73318. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c 2010-08-05 22:02:25.324868151 +0200
  73319. @@ -0,0 +1,313 @@
  73320. +/*******************************************************************************
  73321. +Copyright (C) Marvell International Ltd. and its affiliates
  73322. +
  73323. +This software file (the "File") is owned and distributed by Marvell
  73324. +International Ltd. and/or its affiliates ("Marvell") under the following
  73325. +alternative licensing terms. Once you have made an election to distribute the
  73326. +File under one of the following license alternatives, please (i) delete this
  73327. +introductory statement regarding license alternatives, (ii) delete the two
  73328. +license alternatives that you have not elected to use and (iii) preserve the
  73329. +Marvell copyright notice above.
  73330. +
  73331. +********************************************************************************
  73332. +Marvell Commercial License Option
  73333. +
  73334. +If you received this File from Marvell and you have entered into a commercial
  73335. +license agreement (a "Commercial License") with Marvell, the File is licensed
  73336. +to you under the terms of the applicable Commercial License.
  73337. +
  73338. +********************************************************************************
  73339. +Marvell GPL License Option
  73340. +
  73341. +If you received this File from Marvell, you may opt to use, redistribute and/or
  73342. +modify this File in accordance with the terms and conditions of the General
  73343. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  73344. +available along with the File in the license.txt file or by writing to the Free
  73345. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  73346. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  73347. +
  73348. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  73349. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  73350. +DISCLAIMED. The GPL License provides additional details about this warranty
  73351. +disclaimer.
  73352. +********************************************************************************
  73353. +Marvell BSD License Option
  73354. +
  73355. +If you received this File from Marvell, you may opt to use, redistribute and/or
  73356. +modify this File under the following licensing terms.
  73357. +Redistribution and use in source and binary forms, with or without modification,
  73358. +are permitted provided that the following conditions are met:
  73359. +
  73360. + * Redistributions of source code must retain the above copyright notice,
  73361. + this list of conditions and the following disclaimer.
  73362. +
  73363. + * Redistributions in binary form must reproduce the above copyright
  73364. + notice, this list of conditions and the following disclaimer in the
  73365. + documentation and/or other materials provided with the distribution.
  73366. +
  73367. + * Neither the name of Marvell nor the names of its contributors may be
  73368. + used to endorse or promote products derived from this software without
  73369. + specific prior written permission.
  73370. +
  73371. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  73372. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  73373. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  73374. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  73375. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  73376. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  73377. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  73378. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  73379. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  73380. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  73381. +
  73382. +*******************************************************************************/
  73383. +
  73384. +#include "mvPex.h"
  73385. +
  73386. +//#define MV_DEBUG
  73387. +/* defines */
  73388. +#ifdef MV_DEBUG
  73389. + #define DB(x) x
  73390. +#else
  73391. + #define DB(x)
  73392. +#endif
  73393. +
  73394. +/* locals */
  73395. +typedef struct
  73396. +{
  73397. + MV_U32 data;
  73398. + MV_U32 mask;
  73399. +}PEX_HEADER_DATA;
  73400. +
  73401. +/* local function forwad decleration */
  73402. +MV_U32 mvPexHwConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  73403. + MV_U32 regOff);
  73404. +MV_STATUS mvPexHwConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  73405. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  73406. +void resetPexConfig(MV_U32 pexIf, MV_U32 bus, MV_U32 dev);
  73407. +
  73408. +
  73409. +PEX_HEADER_DATA configHdr[16] =
  73410. +{
  73411. +{0x888811ab, 0x00000000}, /*[device ID, vendor ID] */
  73412. +{0x00100007, 0x0000ffff}, /*[status register, command register] */
  73413. +{0x0604000e, 0x00000000}, /*[programming interface, sub class code, class code, revision ID] */
  73414. +{0x00010008, 0x00000000}, /*[BIST, header type, latency time, cache line] */
  73415. +{0x00000000, 0x00000000}, /*[base address 0] */
  73416. +{0x00000000, 0x00000000}, /*[base address 1] */
  73417. +{0x00000000, 0x00ffffff}, /*[secondary latency timersubordinate bus number, secondary bus number, primary bus number] */
  73418. +{0x0000f101, 0x00000000}, /*[secondary status ,IO limit, IO base] */
  73419. +{0x9ff0a000, 0x00000000}, /*[memory limit, memory base] */
  73420. +{0x0001fff1, 0x00000000}, /*[prefetch memory limit, prefetch memory base] */
  73421. +{0xffffffff, 0x00000000}, /*[prefetch memory base upper] */
  73422. +{0x00000000, 0x00000000}, /*[prefetch memory limit upper] */
  73423. +{0xeffff000, 0x00000000}, /*[IO limit upper 16 bits, IO base upper 16 bits] */
  73424. +{0x00000000, 0x00000000}, /*[reserved, capability pointer] */
  73425. +{0x00000000, 0x00000000}, /*[expansion ROM base address] */
  73426. +{0x00000000, 0x000000FF}, /*[bridge control, interrupt pin, interrupt line] */
  73427. +};
  73428. +
  73429. +
  73430. +#define HEADER_WRITE(data, offset) configHdr[offset/4].data = ((configHdr[offset/4].data & ~configHdr[offset/4].mask) | \
  73431. + (data & configHdr[offset/4].mask))
  73432. +#define HEADER_READ(offset) configHdr[offset/4].data
  73433. +
  73434. +/*******************************************************************************
  73435. +* mvVrtBrgPexInit - Initialize PEX interfaces
  73436. +*
  73437. +* DESCRIPTION:
  73438. +*
  73439. +* This function is responsible of intialization of the Pex Interface , It
  73440. +* configure the Pex Bars and Windows in the following manner:
  73441. +*
  73442. +* Assumptions :
  73443. +* Bar0 is always internal registers bar
  73444. +* Bar1 is always the DRAM bar
  73445. +* Bar2 is always the Device bar
  73446. +*
  73447. +* 1) Sets the Internal registers bar base by obtaining the base from
  73448. +* the CPU Interface
  73449. +* 2) Sets the DRAM bar base and size by getting the base and size from
  73450. +* the CPU Interface when the size is the sum of all enabled DRAM
  73451. +* chip selects and the base is the base of CS0 .
  73452. +* 3) Sets the Device bar base and size by getting these values from the
  73453. +* CPU Interface when the base is the base of the lowest base of the
  73454. +* Device chip selects, and the
  73455. +*
  73456. +*
  73457. +* INPUT:
  73458. +*
  73459. +* pexIf - PEX interface number.
  73460. +*
  73461. +*
  73462. +* OUTPUT:
  73463. +* None.
  73464. +*
  73465. +* RETURN:
  73466. +* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
  73467. +*
  73468. +*******************************************************************************/
  73469. +MV_STATUS mvPexVrtBrgInit(MV_U32 pexIf)
  73470. +{
  73471. + /* reset PEX tree to recover previous U-boot/Boot configurations */
  73472. + MV_U32 localBus = mvPexLocalBusNumGet(pexIf);
  73473. +
  73474. +
  73475. + resetPexConfig(pexIf, localBus, 1);
  73476. + return MV_OK;
  73477. +}
  73478. +
  73479. +
  73480. +MV_U32 mvPexVrtBrgConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  73481. + MV_U32 regOff)
  73482. +{
  73483. +
  73484. + MV_U32 localBus = mvPexLocalBusNumGet(pexIf);
  73485. + MV_U32 localDev = mvPexLocalDevNumGet(pexIf);
  73486. + MV_U32 val;
  73487. + if(bus == localBus)
  73488. + {
  73489. + if(dev > 1)
  73490. + {
  73491. +/* on the local device allow only device #0 & #1 */
  73492. + return 0xffffffff;
  73493. + }
  73494. + else
  73495. + if (dev == localDev)
  73496. + {
  73497. + /* read the memory controller registers */
  73498. + return mvPexHwConfigRead (pexIf, bus, dev, func, regOff);
  73499. + }
  73500. + else
  73501. + {
  73502. + /* access the virtual brg header */
  73503. + return HEADER_READ(regOff);
  73504. + }
  73505. + }
  73506. + else
  73507. + if(bus == (localBus + 1))
  73508. + {
  73509. + /* access the device behind the virtual bridge */
  73510. + if((dev == localDev) || (dev > 1))
  73511. + {
  73512. + return 0xffffffff;
  73513. + }
  73514. + else
  73515. + {
  73516. + /* access the device behind the virtual bridge, in this case
  73517. + * change the bus number to the local bus number in order to
  73518. + * generate type 0 config cycle
  73519. + */
  73520. + mvPexLocalBusNumSet(pexIf, bus);
  73521. + mvPexLocalDevNumSet(pexIf, 1);
  73522. + val = mvPexHwConfigRead (pexIf, bus, 0, func, regOff);
  73523. + mvPexLocalBusNumSet(pexIf, localBus);
  73524. + mvPexLocalDevNumSet(pexIf, localDev);
  73525. + return val;
  73526. + }
  73527. + }
  73528. + /* for all other devices use the HW function to get the
  73529. + * requested registers
  73530. + */
  73531. + mvPexLocalDevNumSet(pexIf, 1);
  73532. + val = mvPexHwConfigRead (pexIf, bus, dev, func, regOff);
  73533. + mvPexLocalDevNumSet(pexIf, localDev);
  73534. + return val;
  73535. +}
  73536. +
  73537. +
  73538. +MV_STATUS mvPexVrtBrgConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  73539. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  73540. +{
  73541. + MV_U32 localBus = mvPexLocalBusNumGet(pexIf);
  73542. + MV_U32 localDev = mvPexLocalDevNumGet(pexIf);
  73543. + MV_STATUS status;
  73544. +
  73545. + if(bus == localBus)
  73546. + {
  73547. + if(dev > 1)
  73548. + {
  73549. + /* on the local device allow only device #0 & #1 */
  73550. + return MV_ERROR;
  73551. + }
  73552. + else
  73553. + if (dev == localDev)
  73554. + {
  73555. + /* read the memory controller registers */
  73556. + return mvPexHwConfigWrite (pexIf, bus, dev, func, regOff, data);
  73557. + }
  73558. + else
  73559. + {
  73560. + /* access the virtual brg header */
  73561. + HEADER_WRITE(data, regOff);
  73562. + return MV_OK;
  73563. + }
  73564. + }
  73565. + else
  73566. + if(bus == (localBus + 1))
  73567. + {
  73568. + /* access the device behind the virtual bridge */
  73569. + if((dev == localDev) || (dev > 1))
  73570. + {
  73571. + return MV_ERROR;
  73572. + }
  73573. + else
  73574. + {
  73575. + /* access the device behind the virtual bridge, in this case
  73576. + * change the bus number to the local bus number in order to
  73577. + * generate type 0 config cycle
  73578. + */
  73579. + //return mvPexHwConfigWrite (pexIf, localBus, dev, func, regOff, data);
  73580. + mvPexLocalBusNumSet(pexIf, bus);
  73581. + mvPexLocalDevNumSet(pexIf, 1);
  73582. + status = mvPexHwConfigWrite (pexIf, bus, 0, func, regOff, data);
  73583. + mvPexLocalBusNumSet(pexIf, localBus);
  73584. + mvPexLocalDevNumSet(pexIf, localDev);
  73585. + return status;
  73586. +
  73587. + }
  73588. + }
  73589. + /* for all other devices use the HW function to get the
  73590. + * requested registers
  73591. + */
  73592. + mvPexLocalDevNumSet(pexIf, 1);
  73593. + status = mvPexHwConfigWrite (pexIf, bus, dev, func, regOff, data);
  73594. + mvPexLocalDevNumSet(pexIf, localDev);
  73595. + return status;
  73596. +}
  73597. +
  73598. +
  73599. +
  73600. +
  73601. +void resetPexConfig(MV_U32 pexIf, MV_U32 bus, MV_U32 dev)
  73602. +{
  73603. + MV_U32 tData;
  73604. + MV_U32 i;
  73605. +
  73606. + /* restore the PEX configuration to initialization state */
  73607. + /* in case PEX P2P call recursive and reset config */
  73608. + tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x0);
  73609. + if(tData != 0xffffffff)
  73610. + {
  73611. + /* agent had been found - check whether P2P */
  73612. + tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x8);
  73613. + if((tData & 0xffff0000) == 0x06040000)
  73614. + {/* P2P */
  73615. + /* get the sec bus and the subordinate */
  73616. + MV_U32 secBus;
  73617. + tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x18);
  73618. + secBus = ((tData >> 8) & 0xff);
  73619. + /* now scan on sec bus */
  73620. + for(i = 0;i < 0xff;i++)
  73621. + {
  73622. + resetPexConfig(pexIf, secBus, i);
  73623. + }
  73624. + /* now reset this device */
  73625. + DB(mvOsPrintf("Reset bus %d dev %d\n", bus, dev));
  73626. + mvPexHwConfigWrite(pexIf, bus, dev, 0x0, 0x18, 0x0);
  73627. + DB(mvOsPrintf("Reset bus %d dev %d\n", bus, dev));
  73628. + }
  73629. + }
  73630. +}
  73631. +
  73632. +
  73633. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h
  73634. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h 1970-01-01 01:00:00.000000000 +0100
  73635. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h 2010-08-05 22:02:25.364868308 +0200
  73636. @@ -0,0 +1,82 @@
  73637. +/*******************************************************************************
  73638. +Copyright (C) Marvell International Ltd. and its affiliates
  73639. +
  73640. +This software file (the "File") is owned and distributed by Marvell
  73641. +International Ltd. and/or its affiliates ("Marvell") under the following
  73642. +alternative licensing terms. Once you have made an election to distribute the
  73643. +File under one of the following license alternatives, please (i) delete this
  73644. +introductory statement regarding license alternatives, (ii) delete the two
  73645. +license alternatives that you have not elected to use and (iii) preserve the
  73646. +Marvell copyright notice above.
  73647. +
  73648. +********************************************************************************
  73649. +Marvell Commercial License Option
  73650. +
  73651. +If you received this File from Marvell and you have entered into a commercial
  73652. +license agreement (a "Commercial License") with Marvell, the File is licensed
  73653. +to you under the terms of the applicable Commercial License.
  73654. +
  73655. +********************************************************************************
  73656. +Marvell GPL License Option
  73657. +
  73658. +If you received this File from Marvell, you may opt to use, redistribute and/or
  73659. +modify this File in accordance with the terms and conditions of the General
  73660. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  73661. +available along with the File in the license.txt file or by writing to the Free
  73662. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  73663. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  73664. +
  73665. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  73666. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  73667. +DISCLAIMED. The GPL License provides additional details about this warranty
  73668. +disclaimer.
  73669. +********************************************************************************
  73670. +Marvell BSD License Option
  73671. +
  73672. +If you received this File from Marvell, you may opt to use, redistribute and/or
  73673. +modify this File under the following licensing terms.
  73674. +Redistribution and use in source and binary forms, with or without modification,
  73675. +are permitted provided that the following conditions are met:
  73676. +
  73677. + * Redistributions of source code must retain the above copyright notice,
  73678. + this list of conditions and the following disclaimer.
  73679. +
  73680. + * Redistributions in binary form must reproduce the above copyright
  73681. + notice, this list of conditions and the following disclaimer in the
  73682. + documentation and/or other materials provided with the distribution.
  73683. +
  73684. + * Neither the name of Marvell nor the names of its contributors may be
  73685. + used to endorse or promote products derived from this software without
  73686. + specific prior written permission.
  73687. +
  73688. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  73689. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  73690. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  73691. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  73692. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  73693. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  73694. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  73695. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  73696. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  73697. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  73698. +
  73699. +*******************************************************************************/
  73700. +
  73701. +#ifndef __INCVRTBRGPEXH
  73702. +#define __INCVRTBRGPEXH
  73703. +
  73704. +
  73705. +/* Global Functions prototypes */
  73706. +/* mvPexInit - Initialize PEX interfaces*/
  73707. +MV_STATUS mvPexVrtBrgInit(MV_U32 pexIf);
  73708. +
  73709. +/* mvPexConfigRead - Read from configuration space */
  73710. +MV_U32 mvPexVrtBrgConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  73711. + MV_U32 func,MV_U32 regOff);
  73712. +
  73713. +/* mvPexConfigWrite - Write to configuration space */
  73714. +MV_STATUS mvPexVrtBrgConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  73715. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  73716. +
  73717. +
  73718. +#endif /* #ifndef __INCPEXH */
  73719. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c
  73720. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c 1970-01-01 01:00:00.000000000 +0100
  73721. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c 2010-08-05 22:02:25.393793283 +0200
  73722. @@ -0,0 +1,1522 @@
  73723. +/*******************************************************************************
  73724. +Copyright (C) Marvell International Ltd. and its affiliates
  73725. +
  73726. +This software file (the "File") is owned and distributed by Marvell
  73727. +International Ltd. and/or its affiliates ("Marvell") under the following
  73728. +alternative licensing terms. Once you have made an election to distribute the
  73729. +File under one of the following license alternatives, please (i) delete this
  73730. +introductory statement regarding license alternatives, (ii) delete the two
  73731. +license alternatives that you have not elected to use and (iii) preserve the
  73732. +Marvell copyright notice above.
  73733. +
  73734. +********************************************************************************
  73735. +Marvell Commercial License Option
  73736. +
  73737. +If you received this File from Marvell and you have entered into a commercial
  73738. +license agreement (a "Commercial License") with Marvell, the File is licensed
  73739. +to you under the terms of the applicable Commercial License.
  73740. +
  73741. +********************************************************************************
  73742. +Marvell GPL License Option
  73743. +
  73744. +If you received this File from Marvell, you may opt to use, redistribute and/or
  73745. +modify this File in accordance with the terms and conditions of the General
  73746. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  73747. +available along with the File in the license.txt file or by writing to the Free
  73748. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  73749. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  73750. +
  73751. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  73752. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  73753. +DISCLAIMED. The GPL License provides additional details about this warranty
  73754. +disclaimer.
  73755. +********************************************************************************
  73756. +Marvell BSD License Option
  73757. +
  73758. +If you received this File from Marvell, you may opt to use, redistribute and/or
  73759. +modify this File under the following licensing terms.
  73760. +Redistribution and use in source and binary forms, with or without modification,
  73761. +are permitted provided that the following conditions are met:
  73762. +
  73763. + * Redistributions of source code must retain the above copyright notice,
  73764. + this list of conditions and the following disclaimer.
  73765. +
  73766. + * Redistributions in binary form must reproduce the above copyright
  73767. + notice, this list of conditions and the following disclaimer in the
  73768. + documentation and/or other materials provided with the distribution.
  73769. +
  73770. + * Neither the name of Marvell nor the names of its contributors may be
  73771. + used to endorse or promote products derived from this software without
  73772. + specific prior written permission.
  73773. +
  73774. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  73775. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  73776. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  73777. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  73778. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  73779. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  73780. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  73781. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  73782. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  73783. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  73784. +
  73785. +*******************************************************************************/
  73786. +#include "mvOs.h"
  73787. +#include "sflash/mvSFlash.h"
  73788. +#include "sflash/mvSFlashSpec.h"
  73789. +#include "spi/mvSpi.h"
  73790. +#include "spi/mvSpiCmnd.h"
  73791. +#include "ctrlEnv/mvCtrlEnvLib.h"
  73792. +
  73793. +/*#define MV_DEBUG*/
  73794. +#ifdef MV_DEBUG
  73795. +#define DB(x) x
  73796. +#else
  73797. +#define DB(x)
  73798. +#endif
  73799. +
  73800. +/* Globals */
  73801. +static MV_SFLASH_DEVICE_PARAMS sflash[] = {
  73802. + /* ST M25P32 SPI flash, 4MB, 64 sectors of 64K each */
  73803. + {
  73804. + MV_M25P_WREN_CMND_OPCD,
  73805. + MV_M25P_WRDI_CMND_OPCD,
  73806. + MV_M25P_RDID_CMND_OPCD,
  73807. + MV_M25P_RDSR_CMND_OPCD,
  73808. + MV_M25P_WRSR_CMND_OPCD,
  73809. + MV_M25P_READ_CMND_OPCD,
  73810. + MV_M25P_FAST_RD_CMND_OPCD,
  73811. + MV_M25P_PP_CMND_OPCD,
  73812. + MV_M25P_SE_CMND_OPCD,
  73813. + MV_M25P_BE_CMND_OPCD,
  73814. + MV_M25P_RES_CMND_OPCD,
  73815. + MV_SFLASH_NO_SPECIFIC_OPCD, /* power save not supported */
  73816. + MV_M25P32_SECTOR_SIZE,
  73817. + MV_M25P32_SECTOR_NUMBER,
  73818. + MV_M25P_PAGE_SIZE,
  73819. + "ST M25P32",
  73820. + MV_M25PXXX_ST_MANF_ID,
  73821. + MV_M25P32_DEVICE_ID,
  73822. + MV_M25P32_MAX_SPI_FREQ,
  73823. + MV_M25P32_MAX_FAST_SPI_FREQ,
  73824. + MV_M25P32_FAST_READ_DUMMY_BYTES
  73825. + },
  73826. + /* ST M25P64 SPI flash, 8MB, 128 sectors of 64K each */
  73827. + {
  73828. + MV_M25P_WREN_CMND_OPCD,
  73829. + MV_M25P_WRDI_CMND_OPCD,
  73830. + MV_M25P_RDID_CMND_OPCD,
  73831. + MV_M25P_RDSR_CMND_OPCD,
  73832. + MV_M25P_WRSR_CMND_OPCD,
  73833. + MV_M25P_READ_CMND_OPCD,
  73834. + MV_M25P_FAST_RD_CMND_OPCD,
  73835. + MV_M25P_PP_CMND_OPCD,
  73836. + MV_M25P_SE_CMND_OPCD,
  73837. + MV_M25P_BE_CMND_OPCD,
  73838. + MV_M25P_RES_CMND_OPCD,
  73839. + MV_SFLASH_NO_SPECIFIC_OPCD, /* power save not supported */
  73840. + MV_M25P64_SECTOR_SIZE,
  73841. + MV_M25P64_SECTOR_NUMBER,
  73842. + MV_M25P_PAGE_SIZE,
  73843. + "ST M25P64",
  73844. + MV_M25PXXX_ST_MANF_ID,
  73845. + MV_M25P64_DEVICE_ID,
  73846. + MV_M25P64_MAX_SPI_FREQ,
  73847. + MV_M25P64_MAX_FAST_SPI_FREQ,
  73848. + MV_M25P64_FAST_READ_DUMMY_BYTES
  73849. + },
  73850. + /* ST M25P128 SPI flash, 16MB, 64 sectors of 256K each */
  73851. + {
  73852. + MV_M25P_WREN_CMND_OPCD,
  73853. + MV_M25P_WRDI_CMND_OPCD,
  73854. + MV_M25P_RDID_CMND_OPCD,
  73855. + MV_M25P_RDSR_CMND_OPCD,
  73856. + MV_M25P_WRSR_CMND_OPCD,
  73857. + MV_M25P_READ_CMND_OPCD,
  73858. + MV_M25P_FAST_RD_CMND_OPCD,
  73859. + MV_M25P_PP_CMND_OPCD,
  73860. + MV_M25P_SE_CMND_OPCD,
  73861. + MV_M25P_BE_CMND_OPCD,
  73862. + MV_M25P_RES_CMND_OPCD,
  73863. + MV_SFLASH_NO_SPECIFIC_OPCD, /* power save not supported */
  73864. + MV_M25P128_SECTOR_SIZE,
  73865. + MV_M25P128_SECTOR_NUMBER,
  73866. + MV_M25P_PAGE_SIZE,
  73867. + "ST M25P128",
  73868. + MV_M25PXXX_ST_MANF_ID,
  73869. + MV_M25P128_DEVICE_ID,
  73870. + MV_M25P128_MAX_SPI_FREQ,
  73871. + MV_M25P128_MAX_FAST_SPI_FREQ,
  73872. + MV_M25P128_FAST_READ_DUMMY_BYTES
  73873. + },
  73874. + /* Macronix MXIC MX25L6405 SPI flash, 8MB, 128 sectors of 64K each */
  73875. + {
  73876. + MV_MX25L_WREN_CMND_OPCD,
  73877. + MV_MX25L_WRDI_CMND_OPCD,
  73878. + MV_MX25L_RDID_CMND_OPCD,
  73879. + MV_MX25L_RDSR_CMND_OPCD,
  73880. + MV_MX25L_WRSR_CMND_OPCD,
  73881. + MV_MX25L_READ_CMND_OPCD,
  73882. + MV_MX25L_FAST_RD_CMND_OPCD,
  73883. + MV_MX25L_PP_CMND_OPCD,
  73884. + MV_MX25L_SE_CMND_OPCD,
  73885. + MV_MX25L_BE_CMND_OPCD,
  73886. + MV_MX25L_RES_CMND_OPCD,
  73887. + MV_MX25L_DP_CMND_OPCD,
  73888. + MV_MX25L6405_SECTOR_SIZE,
  73889. + MV_MX25L6405_SECTOR_NUMBER,
  73890. + MV_MXIC_PAGE_SIZE,
  73891. + "MXIC MX25L6405",
  73892. + MV_MXIC_MANF_ID,
  73893. + MV_MX25L6405_DEVICE_ID,
  73894. + MV_MX25L6405_MAX_SPI_FREQ,
  73895. + MV_MX25L6405_MAX_FAST_SPI_FREQ,
  73896. + MV_MX25L6405_FAST_READ_DUMMY_BYTES
  73897. + },
  73898. + /* SPANSION S25FL128P SPI flash, 16MB, 64 sectors of 256K each */
  73899. + {
  73900. + MV_S25FL_WREN_CMND_OPCD,
  73901. + MV_S25FL_WRDI_CMND_OPCD,
  73902. + MV_S25FL_RDID_CMND_OPCD,
  73903. + MV_S25FL_RDSR_CMND_OPCD,
  73904. + MV_S25FL_WRSR_CMND_OPCD,
  73905. + MV_S25FL_READ_CMND_OPCD,
  73906. + MV_S25FL_FAST_RD_CMND_OPCD,
  73907. + MV_S25FL_PP_CMND_OPCD,
  73908. + MV_S25FL_SE_CMND_OPCD,
  73909. + MV_S25FL_BE_CMND_OPCD,
  73910. + MV_S25FL_RES_CMND_OPCD,
  73911. + MV_S25FL_DP_CMND_OPCD,
  73912. + MV_S25FL128_SECTOR_SIZE,
  73913. + MV_S25FL128_SECTOR_NUMBER,
  73914. + MV_S25FL_PAGE_SIZE,
  73915. + "SPANSION S25FL128",
  73916. + MV_SPANSION_MANF_ID,
  73917. + MV_S25FL128_DEVICE_ID,
  73918. + MV_S25FL128_MAX_SPI_FREQ,
  73919. + MV_M25P128_MAX_FAST_SPI_FREQ,
  73920. + MV_M25P128_FAST_READ_DUMMY_BYTES
  73921. + }
  73922. +};
  73923. +
  73924. +/* Static Functions */
  73925. +static MV_STATUS mvWriteEnable (MV_SFLASH_INFO * pFlinfo);
  73926. +static MV_STATUS mvStatusRegGet (MV_SFLASH_INFO * pFlinfo, MV_U8 * pStatReg);
  73927. +static MV_STATUS mvStatusRegSet (MV_SFLASH_INFO * pFlinfo, MV_U8 sr);
  73928. +static MV_STATUS mvWaitOnWipClear(MV_SFLASH_INFO * pFlinfo);
  73929. +static MV_STATUS mvSFlashPageWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset, \
  73930. + MV_U8* pPageBuff, MV_U32 buffSize);
  73931. +static MV_STATUS mvSFlashWithDefaultsIdGet (MV_SFLASH_INFO * pFlinfo, \
  73932. + MV_U8* manId, MV_U16* devId);
  73933. +
  73934. +/*******************************************************************************
  73935. +* mvWriteEnable - serialize the write enable sequence
  73936. +*
  73937. +* DESCRIPTION:
  73938. +* transmit the sequence for write enable
  73939. +*
  73940. +********************************************************************************/
  73941. +static MV_STATUS mvWriteEnable(MV_SFLASH_INFO * pFlinfo)
  73942. +{
  73943. + MV_U8 cmd[MV_SFLASH_WREN_CMND_LENGTH];
  73944. +
  73945. +
  73946. + cmd[0] = sflash[pFlinfo->index].opcdWREN;
  73947. +
  73948. + return mvSpiWriteThenRead(cmd, MV_SFLASH_WREN_CMND_LENGTH, NULL, 0, 0);
  73949. +}
  73950. +
  73951. +/*******************************************************************************
  73952. +* mvStatusRegGet - Retrieve the value of the status register
  73953. +*
  73954. +* DESCRIPTION:
  73955. +* perform the RDSR sequence to get the 8bit status register
  73956. +*
  73957. +********************************************************************************/
  73958. +static MV_STATUS mvStatusRegGet(MV_SFLASH_INFO * pFlinfo, MV_U8 * pStatReg)
  73959. +{
  73960. + MV_STATUS ret;
  73961. + MV_U8 cmd[MV_SFLASH_RDSR_CMND_LENGTH];
  73962. + MV_U8 sr[MV_SFLASH_RDSR_REPLY_LENGTH];
  73963. +
  73964. +
  73965. +
  73966. +
  73967. + cmd[0] = sflash[pFlinfo->index].opcdRDSR;
  73968. +
  73969. + if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_RDSR_CMND_LENGTH, sr,
  73970. + MV_SFLASH_RDSR_REPLY_LENGTH,0)) != MV_OK)
  73971. + return ret;
  73972. +
  73973. + *pStatReg = sr[0];
  73974. +
  73975. + return MV_OK;
  73976. +}
  73977. +
  73978. +/*******************************************************************************
  73979. +* mvWaitOnWipClear - Block waiting for the WIP (write in progress) to be cleared
  73980. +*
  73981. +* DESCRIPTION:
  73982. +* Block waiting for the WIP (write in progress) to be cleared
  73983. +*
  73984. +********************************************************************************/
  73985. +static MV_STATUS mvWaitOnWipClear(MV_SFLASH_INFO * pFlinfo)
  73986. +{
  73987. + MV_STATUS ret;
  73988. + MV_U32 i;
  73989. + MV_U8 stat;
  73990. +
  73991. + for (i=0; i<MV_SFLASH_MAX_WAIT_LOOP; i++)
  73992. + {
  73993. + if ((ret = mvStatusRegGet(pFlinfo, &stat)) != MV_OK)
  73994. + return ret;
  73995. +
  73996. + if ((stat & MV_SFLASH_STATUS_REG_WIP_MASK) == 0)
  73997. + return MV_OK;
  73998. + }
  73999. +
  74000. + DB(mvOsPrintf("%s WARNING: Write Timeout!\n", __FUNCTION__);)
  74001. + return MV_TIMEOUT;
  74002. +}
  74003. +
  74004. +/*******************************************************************************
  74005. +* mvWaitOnChipEraseDone - Block waiting for the WIP (write in progress) to be
  74006. +* cleared after a chip erase command which is supposed
  74007. +* to take about 2:30 minutes
  74008. +*
  74009. +* DESCRIPTION:
  74010. +* Block waiting for the WIP (write in progress) to be cleared
  74011. +*
  74012. +********************************************************************************/
  74013. +static MV_STATUS mvWaitOnChipEraseDone(MV_SFLASH_INFO * pFlinfo)
  74014. +{
  74015. + MV_STATUS ret;
  74016. + MV_U32 i;
  74017. + MV_U8 stat;
  74018. +
  74019. + for (i=0; i<MV_SFLASH_CHIP_ERASE_MAX_WAIT_LOOP; i++)
  74020. + {
  74021. + if ((ret = mvStatusRegGet(pFlinfo, &stat)) != MV_OK)
  74022. + return ret;
  74023. +
  74024. + if ((stat & MV_SFLASH_STATUS_REG_WIP_MASK) == 0)
  74025. + return MV_OK;
  74026. + }
  74027. +
  74028. + DB(mvOsPrintf("%s WARNING: Write Timeout!\n", __FUNCTION__);)
  74029. + return MV_TIMEOUT;
  74030. +}
  74031. +
  74032. +/*******************************************************************************
  74033. +* mvStatusRegSet - Set the value of the 8bit status register
  74034. +*
  74035. +* DESCRIPTION:
  74036. +* Set the value of the 8bit status register
  74037. +*
  74038. +********************************************************************************/
  74039. +static MV_STATUS mvStatusRegSet(MV_SFLASH_INFO * pFlinfo, MV_U8 sr)
  74040. +{
  74041. + MV_STATUS ret;
  74042. + MV_U8 cmd[MV_SFLASH_WRSR_CMND_LENGTH];
  74043. +
  74044. +
  74045. + /* Issue the Write enable command prior the WRSR command */
  74046. + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
  74047. + return ret;
  74048. +
  74049. + /* Write the SR with the new values */
  74050. + cmd[0] = sflash[pFlinfo->index].opcdWRSR;
  74051. + cmd[1] = sr;
  74052. +
  74053. + if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_WRSR_CMND_LENGTH, NULL, 0, 0)) != MV_OK)
  74054. + return ret;
  74055. +
  74056. + if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)
  74057. + return ret;
  74058. +
  74059. + mvOsDelay(1);
  74060. +
  74061. + return MV_OK;
  74062. +}
  74063. +
  74064. +/*******************************************************************************
  74065. +* mvSFlashPageWr - Write up to 256 Bytes in the same page
  74066. +*
  74067. +* DESCRIPTION:
  74068. +* Write a buffer up to the page size in length provided that the whole address
  74069. +* range is within the same page (alligned to page bounderies)
  74070. +*
  74071. +*******************************************************************************/
  74072. +static MV_STATUS mvSFlashPageWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  74073. + MV_U8* pPageBuff, MV_U32 buffSize)
  74074. +{
  74075. + MV_STATUS ret;
  74076. + MV_U8 cmd[MV_SFLASH_PP_CMND_LENGTH];
  74077. +
  74078. +
  74079. + /* Protection - check if the model was detected */
  74080. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  74081. + {
  74082. + DB(mvOsPrintf("%s WARNING: Invalid parameter device index!\n", __FUNCTION__);)
  74083. + return MV_BAD_PARAM;
  74084. + }
  74085. +
  74086. + /* check that we do not cross the page bounderies */
  74087. + if (((offset & (sflash[pFlinfo->index].pageSize - 1)) + buffSize) >
  74088. + sflash[pFlinfo->index].pageSize)
  74089. + {
  74090. + DB(mvOsPrintf("%s WARNING: Page allignment problem!\n", __FUNCTION__);)
  74091. + return MV_OUT_OF_RANGE;
  74092. + }
  74093. +
  74094. + /* Issue the Write enable command prior the page program command */
  74095. + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
  74096. + return ret;
  74097. +
  74098. + cmd[0] = sflash[pFlinfo->index].opcdPP;
  74099. + cmd[1] = ((offset >> 16) & 0xFF);
  74100. + cmd[2] = ((offset >> 8) & 0xFF);
  74101. + cmd[3] = (offset & 0xFF);
  74102. +
  74103. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_PP_CMND_LENGTH, pPageBuff, buffSize)) != MV_OK)
  74104. + return ret;
  74105. +
  74106. + if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)
  74107. + return ret;
  74108. +
  74109. + return MV_OK;
  74110. +}
  74111. +
  74112. +/*******************************************************************************
  74113. +* mvSFlashWithDefaultsIdGet - Try to read the manufacturer and Device IDs from
  74114. +* the device using the default RDID opcode and the default WREN opcode.
  74115. +*
  74116. +* DESCRIPTION:
  74117. +* This is used to detect a generic device that uses the default opcodes
  74118. +* for the WREN and RDID.
  74119. +*
  74120. +********************************************************************************/
  74121. +static MV_STATUS mvSFlashWithDefaultsIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* manId, MV_U16* devId)
  74122. +{
  74123. + MV_STATUS ret;
  74124. + MV_U8 cmdRDID[MV_SFLASH_RDID_CMND_LENGTH];
  74125. + MV_U8 id[MV_SFLASH_RDID_REPLY_LENGTH];
  74126. +
  74127. +
  74128. +
  74129. + /* Use the default RDID opcode to read the IDs */
  74130. + cmdRDID[0] = MV_SFLASH_DEFAULT_RDID_OPCD; /* unknown model try default */
  74131. + if ((ret = mvSpiWriteThenRead(cmdRDID, MV_SFLASH_RDID_CMND_LENGTH, id, MV_SFLASH_RDID_REPLY_LENGTH, 0)) != MV_OK)
  74132. + return ret;
  74133. +
  74134. + *manId = id[0];
  74135. + *devId = 0;
  74136. + *devId |= (id[1] << 8);
  74137. + *devId |= id[2];
  74138. +
  74139. + return MV_OK;
  74140. +}
  74141. +
  74142. +/*
  74143. +#####################################################################################
  74144. +#####################################################################################
  74145. +*/
  74146. +
  74147. +/*******************************************************************************
  74148. +* mvSFlashInit - Initialize the serial flash device
  74149. +*
  74150. +* DESCRIPTION:
  74151. +* Perform the neccessary initialization and configuration
  74152. +*
  74153. +* INPUT:
  74154. +* pFlinfo: pointer to the Flash information structure
  74155. +* pFlinfo->baseAddr: base address in fast mode.
  74156. +* pFlinfo->index: Index of the flash in the sflash tabel. If the SPI
  74157. +* flash device does not support read Id command with
  74158. +* the standard opcode, then the user should supply this
  74159. +* as an input to skip the autodetection process!!!!
  74160. +*
  74161. +* OUTPUT:
  74162. +* pFlinfo: pointer to the Flash information structure after detection
  74163. +* pFlinfo->manufacturerId: Manufacturer ID
  74164. +* pFlinfo->deviceId: Device ID
  74165. +* pFlinfo->sectorSize: size of the sector (all sectors are the same).
  74166. +* pFlinfo->sectorNumber: number of sectors.
  74167. +* pFlinfo->pageSize: size of the page.
  74168. +* pFlinfo->index: Index of the detected flash in the sflash tabel
  74169. +*
  74170. +* RETURN:
  74171. +* Success or Error code.
  74172. +*
  74173. +*
  74174. +*******************************************************************************/
  74175. +MV_STATUS mvSFlashInit (MV_SFLASH_INFO * pFlinfo)
  74176. +{
  74177. + MV_STATUS ret;
  74178. + MV_U8 manf;
  74179. + MV_U16 dev;
  74180. + MV_U32 indx;
  74181. + MV_BOOL detectFlag = MV_FALSE;
  74182. +
  74183. + /* check for NULL pointer */
  74184. + if (pFlinfo == NULL)
  74185. + {
  74186. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74187. + return MV_BAD_PARAM;
  74188. + }
  74189. +
  74190. + /* Initialize the SPI interface with low frequency to make sure that the read ID succeeds */
  74191. + if ((ret = mvSpiInit(MV_SFLASH_BASIC_SPI_FREQ)) != MV_OK)
  74192. + {
  74193. + mvOsPrintf("%s ERROR: Failed to initialize the SPI interface!\n", __FUNCTION__);
  74194. + return ret;
  74195. + }
  74196. +
  74197. + /* First try to read the Manufacturer and Device IDs */
  74198. + if ((ret = mvSFlashIdGet(pFlinfo, &manf, &dev)) != MV_OK)
  74199. + {
  74200. + mvOsPrintf("%s ERROR: Failed to get the SFlash ID!\n", __FUNCTION__);
  74201. + return ret;
  74202. + }
  74203. +
  74204. + /* loop over the whole table and look for the appropriate SFLASH */
  74205. + for (indx=0; indx<MV_ARRAY_SIZE(sflash); indx++)
  74206. + {
  74207. + if ((manf == sflash[indx].manufacturerId) && (dev == sflash[indx].deviceId))
  74208. + {
  74209. + pFlinfo->manufacturerId = manf;
  74210. + pFlinfo->deviceId = dev;
  74211. + pFlinfo->index = indx;
  74212. + detectFlag = MV_TRUE;
  74213. + }
  74214. + }
  74215. +
  74216. + if(!detectFlag)
  74217. + {
  74218. + mvOsPrintf("%s ERROR: Unknown SPI flash device!\n", __FUNCTION__);
  74219. + return MV_FAIL;
  74220. + }
  74221. +
  74222. + /* fill the info based on the model detected */
  74223. + pFlinfo->sectorSize = sflash[pFlinfo->index].sectorSize;
  74224. + pFlinfo->sectorNumber = sflash[pFlinfo->index].sectorNumber;
  74225. + pFlinfo->pageSize = sflash[pFlinfo->index].pageSize;
  74226. +
  74227. + /* Set the SPI frequency to the MAX allowed for the device for best performance */
  74228. + if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFreq)) != MV_OK)
  74229. + {
  74230. + mvOsPrintf("%s ERROR: Failed to set the SPI frequency!\n", __FUNCTION__);
  74231. + return ret;
  74232. + }
  74233. +
  74234. + /* As default lock the SR */
  74235. + if ((ret = mvSFlashStatRegLock(pFlinfo, MV_TRUE)) != MV_OK)
  74236. + return ret;
  74237. +
  74238. + return MV_OK;
  74239. +}
  74240. +
  74241. +/*******************************************************************************
  74242. +* mvSFlashSectorErase - Erasse a single sector of the serial flash
  74243. +*
  74244. +* DESCRIPTION:
  74245. +* Issue the erase sector command and address
  74246. +*
  74247. +* INPUT:
  74248. +* pFlinfo: pointer to the Flash information structure
  74249. +* secNumber: sector Number to erase (0 -> (sectorNumber-1))
  74250. +*
  74251. +* OUTPUT:
  74252. +* None
  74253. +*
  74254. +* RETURN:
  74255. +* Success or Error code.
  74256. +*
  74257. +*
  74258. +*******************************************************************************/
  74259. +MV_STATUS mvSFlashSectorErase (MV_SFLASH_INFO * pFlinfo, MV_U32 secNumber)
  74260. +{
  74261. + MV_STATUS ret;
  74262. + MV_U8 cmd[MV_SFLASH_SE_CMND_LENGTH];
  74263. +
  74264. + MV_U32 secAddr = (secNumber * pFlinfo->sectorSize);
  74265. +#if 0
  74266. + MV_U32 i;
  74267. + MV_U32 * pW = (MV_U32*) (secAddr + pFlinfo->baseAddr);
  74268. + MV_U32 erasedWord = 0xFFFFFFFF;
  74269. + MV_U32 wordsPerSector = (pFlinfo->sectorSize / sizeof(MV_U32));
  74270. + MV_BOOL eraseNeeded = MV_FALSE;
  74271. +#endif
  74272. + /* check for NULL pointer */
  74273. + if (pFlinfo == NULL)
  74274. + {
  74275. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74276. + return MV_BAD_PARAM;
  74277. + }
  74278. +
  74279. + /* Protection - check if the model was detected */
  74280. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  74281. + {
  74282. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  74283. + return MV_BAD_PARAM;
  74284. + }
  74285. +
  74286. + /* check that the sector number is valid */
  74287. + if (secNumber >= pFlinfo->sectorNumber)
  74288. + {
  74289. + DB(mvOsPrintf("%s WARNING: Invaild parameter sector number!\n", __FUNCTION__);)
  74290. + return MV_BAD_PARAM;
  74291. + }
  74292. +
  74293. + /* we don't want to access SPI in direct mode from in-direct API,
  74294. + becasue of timing issue between CS asserts. */
  74295. +#if 0
  74296. + /* First compare to FF and check if erase is needed */
  74297. + for (i=0; i<wordsPerSector; i++)
  74298. + {
  74299. + if (memcmp(pW, &erasedWord, sizeof(MV_U32)) != 0)
  74300. + {
  74301. + eraseNeeded = MV_TRUE;
  74302. + break;
  74303. + }
  74304. +
  74305. + ++pW;
  74306. + }
  74307. + if (!eraseNeeded)
  74308. + return MV_OK;
  74309. +#endif
  74310. +
  74311. + cmd[0] = sflash[pFlinfo->index].opcdSE;
  74312. + cmd[1] = ((secAddr >> 16) & 0xFF);
  74313. + cmd[2] = ((secAddr >> 8) & 0xFF);
  74314. + cmd[3] = (secAddr & 0xFF);
  74315. +
  74316. + /* Issue the Write enable command prior the sector erase command */
  74317. + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
  74318. + return ret;
  74319. +
  74320. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_SE_CMND_LENGTH, NULL, 0)) != MV_OK)
  74321. + return ret;
  74322. +
  74323. + if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)
  74324. + return ret;
  74325. +
  74326. + return MV_OK;
  74327. +}
  74328. +
  74329. +/*******************************************************************************
  74330. +* mvSFlashChipErase - Erasse the whole serial flash
  74331. +*
  74332. +* DESCRIPTION:
  74333. +* Issue the bulk (chip) erase command
  74334. +*
  74335. +* INPUT:
  74336. +* pFlinfo: pointer to the Flash information structure
  74337. +*
  74338. +* OUTPUT:
  74339. +* None
  74340. +*
  74341. +* RETURN:
  74342. +* Success or Error code.
  74343. +*
  74344. +*
  74345. +*******************************************************************************/
  74346. +MV_STATUS mvSFlashChipErase (MV_SFLASH_INFO * pFlinfo)
  74347. +{
  74348. + MV_STATUS ret;
  74349. + MV_U8 cmd[MV_SFLASH_BE_CMND_LENGTH];
  74350. +
  74351. +
  74352. + /* check for NULL pointer */
  74353. + if (pFlinfo == NULL)
  74354. + {
  74355. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74356. + return MV_BAD_PARAM;
  74357. + }
  74358. +
  74359. + /* Protection - check if the model was detected */
  74360. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  74361. + {
  74362. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  74363. + return MV_BAD_PARAM;
  74364. + }
  74365. +
  74366. + cmd[0] = sflash[pFlinfo->index].opcdBE;
  74367. +
  74368. + /* Issue the Write enable command prior the Bulk erase command */
  74369. + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
  74370. + return ret;
  74371. +
  74372. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_BE_CMND_LENGTH, NULL, 0)) != MV_OK)
  74373. + return ret;
  74374. +
  74375. + if ((ret = mvWaitOnChipEraseDone(pFlinfo)) != MV_OK)
  74376. + return ret;
  74377. +
  74378. + return MV_OK;
  74379. +}
  74380. +
  74381. +/*******************************************************************************
  74382. +* mvSFlashBlockRd - Read from the serial flash
  74383. +*
  74384. +* DESCRIPTION:
  74385. +* Issue the read command and address then perfom the needed read
  74386. +*
  74387. +* INPUT:
  74388. +* pFlinfo: pointer to the Flash information structure
  74389. +* offset: byte offset with the flash to start reading from
  74390. +* pReadBuff: pointer to the buffer to read the data in
  74391. +* buffSize: size of the buffer to read.
  74392. +*
  74393. +* OUTPUT:
  74394. +* pReadBuff: pointer to the buffer containing the read data
  74395. +*
  74396. +* RETURN:
  74397. +* Success or Error code.
  74398. +*
  74399. +*
  74400. +*******************************************************************************/
  74401. +MV_STATUS mvSFlashBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  74402. + MV_U8* pReadBuff, MV_U32 buffSize)
  74403. +{
  74404. + MV_U8 cmd[MV_SFLASH_READ_CMND_LENGTH];
  74405. +
  74406. +
  74407. + /* check for NULL pointer */
  74408. + if ((pFlinfo == NULL) || (pReadBuff == NULL))
  74409. + {
  74410. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74411. + return MV_BAD_PARAM;
  74412. + }
  74413. +
  74414. + /* Protection - check if the model was detected */
  74415. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  74416. + {
  74417. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  74418. + return MV_BAD_PARAM;
  74419. + }
  74420. +
  74421. + cmd[0] = sflash[pFlinfo->index].opcdREAD;
  74422. + cmd[1] = ((offset >> 16) & 0xFF);
  74423. + cmd[2] = ((offset >> 8) & 0xFF);
  74424. + cmd[3] = (offset & 0xFF);
  74425. +
  74426. + return mvSpiWriteThenRead(cmd, MV_SFLASH_READ_CMND_LENGTH, pReadBuff, buffSize, 0);
  74427. +}
  74428. +
  74429. +/*******************************************************************************
  74430. +* mvSFlashFastBlockRd - Fast read from the serial flash
  74431. +*
  74432. +* DESCRIPTION:
  74433. +* Issue the fast read command and address then perfom the needed read
  74434. +*
  74435. +* INPUT:
  74436. +* pFlinfo: pointer to the Flash information structure
  74437. +* offset: byte offset with the flash to start reading from
  74438. +* pReadBuff: pointer to the buffer to read the data in
  74439. +* buffSize: size of the buffer to read.
  74440. +*
  74441. +* OUTPUT:
  74442. +* pReadBuff: pointer to the buffer containing the read data
  74443. +*
  74444. +* RETURN:
  74445. +* Success or Error code.
  74446. +*
  74447. +*
  74448. +*******************************************************************************/
  74449. +MV_STATUS mvSFlashFastBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  74450. + MV_U8* pReadBuff, MV_U32 buffSize)
  74451. +{
  74452. + MV_U8 cmd[MV_SFLASH_READ_CMND_LENGTH];
  74453. + MV_STATUS ret;
  74454. +
  74455. + /* check for NULL pointer */
  74456. + if ((pFlinfo == NULL) || (pReadBuff == NULL))
  74457. + {
  74458. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74459. + return MV_BAD_PARAM;
  74460. + }
  74461. +
  74462. + /* Protection - check if the model was detected */
  74463. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  74464. + {
  74465. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  74466. + return MV_BAD_PARAM;
  74467. + }
  74468. +
  74469. + /* Set the SPI frequency to the MAX allowed for fast-read operations */
  74470. + mvOsPrintf("Setting freq to %d.\n",sflash[pFlinfo->index].spiMaxFastFreq);
  74471. + if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFastFreq)) != MV_OK)
  74472. + {
  74473. + mvOsPrintf("%s ERROR: Failed to set the SPI fast frequency!\n", __FUNCTION__);
  74474. + return ret;
  74475. + }
  74476. +
  74477. + cmd[0] = sflash[pFlinfo->index].opcdFSTRD;
  74478. + cmd[1] = ((offset >> 16) & 0xFF);
  74479. + cmd[2] = ((offset >> 8) & 0xFF);
  74480. + cmd[3] = (offset & 0xFF);
  74481. +
  74482. +
  74483. + ret = mvSpiWriteThenRead(cmd, MV_SFLASH_READ_CMND_LENGTH, pReadBuff, buffSize,
  74484. + sflash[pFlinfo->index].spiFastRdDummyBytes);
  74485. +
  74486. + /* Reset the SPI frequency to the MAX allowed for the device for best performance */
  74487. + if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFreq)) != MV_OK)
  74488. + {
  74489. + mvOsPrintf("%s ERROR: Failed to set the SPI frequency!\n", __FUNCTION__);
  74490. + return ret;
  74491. + }
  74492. +
  74493. + return ret;
  74494. +}
  74495. +
  74496. +
  74497. +/*******************************************************************************
  74498. +* mvSFlashBlockWr - Write a buffer with any size
  74499. +*
  74500. +* DESCRIPTION:
  74501. +* write regardless of the page boundaries and size limit per Page
  74502. +* program command
  74503. +*
  74504. +* INPUT:
  74505. +* pFlinfo: pointer to the Flash information structure
  74506. +* offset: byte offset within the flash region
  74507. +* pWriteBuff: pointer to the buffer holding the data to program
  74508. +* buffSize: size of the buffer to write
  74509. +*
  74510. +* OUTPUT:
  74511. +* None
  74512. +*
  74513. +* RETURN:
  74514. +* Success or Error code.
  74515. +*
  74516. +*
  74517. +*******************************************************************************/
  74518. +MV_STATUS mvSFlashBlockWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  74519. + MV_U8* pWriteBuff, MV_U32 buffSize)
  74520. +{
  74521. + MV_STATUS ret;
  74522. + MV_U32 data2write = buffSize;
  74523. + MV_U32 preAllOffset = (offset & MV_SFLASH_PAGE_ALLIGN_MASK(MV_M25P_PAGE_SIZE));
  74524. + MV_U32 preAllSz = (preAllOffset ? (MV_M25P_PAGE_SIZE - preAllOffset) : 0);
  74525. + MV_U32 writeOffset = offset;
  74526. +
  74527. + /* check for NULL pointer */
  74528. +#ifndef CONFIG_MARVELL
  74529. + if(NULL == pWriteBuff)
  74530. + {
  74531. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74532. + return MV_BAD_PARAM;
  74533. + }
  74534. +#endif
  74535. +
  74536. + if (pFlinfo == NULL)
  74537. + {
  74538. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74539. + return MV_BAD_PARAM;
  74540. + }
  74541. +
  74542. + /* Protection - check if the model was detected */
  74543. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  74544. + {
  74545. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  74546. + return MV_BAD_PARAM;
  74547. + }
  74548. +
  74549. + /* check that the buffer size does not exceed the flash size */
  74550. + if ((offset + buffSize) > mvSFlashSizeGet(pFlinfo))
  74551. + {
  74552. + DB(mvOsPrintf("%s WARNING: Write exceeds flash size!\n", __FUNCTION__);)
  74553. + return MV_OUT_OF_RANGE;
  74554. + }
  74555. +
  74556. + /* check if the total block size is less than the first chunk remainder */
  74557. + if (data2write < preAllSz)
  74558. + preAllSz = data2write;
  74559. +
  74560. + /* check if programing does not start at a 64byte alligned offset */
  74561. + if (preAllSz)
  74562. + {
  74563. + if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, preAllSz)) != MV_OK)
  74564. + return ret;
  74565. +
  74566. + /* increment pointers and counters */
  74567. + writeOffset += preAllSz;
  74568. + data2write -= preAllSz;
  74569. + pWriteBuff += preAllSz;
  74570. + }
  74571. +
  74572. + /* program the data that fits in complete page chunks */
  74573. + while (data2write >= sflash[pFlinfo->index].pageSize)
  74574. + {
  74575. + if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, sflash[pFlinfo->index].pageSize)) != MV_OK)
  74576. + return ret;
  74577. +
  74578. + /* increment pointers and counters */
  74579. + writeOffset += sflash[pFlinfo->index].pageSize;
  74580. + data2write -= sflash[pFlinfo->index].pageSize;
  74581. + pWriteBuff += sflash[pFlinfo->index].pageSize;
  74582. + }
  74583. +
  74584. + /* program the last partial chunk */
  74585. + if (data2write)
  74586. + {
  74587. + if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, data2write)) != MV_OK)
  74588. + return ret;
  74589. + }
  74590. +
  74591. + return MV_OK;
  74592. +}
  74593. +
  74594. +/*******************************************************************************
  74595. +* mvSFlashIdGet - Get the manufacturer and device IDs.
  74596. +*
  74597. +* DESCRIPTION:
  74598. +* Get the Manufacturer and device IDs from the serial flash through
  74599. +* writing the RDID command then reading 3 bytes of data. In case that
  74600. +* this command was called for the first time in order to detect the
  74601. +* manufacturer and device IDs, then the default RDID opcode will be used
  74602. +* unless the device index is indicated by the user (in case the SPI flash
  74603. +* does not use the default RDID opcode).
  74604. +*
  74605. +* INPUT:
  74606. +* pFlinfo: pointer to the Flash information structure
  74607. +* pManId: pointer to the 8bit variable to hold the manufacturing ID
  74608. +* pDevId: pointer to the 16bit variable to hold the device ID
  74609. +*
  74610. +* OUTPUT:
  74611. +* pManId: pointer to the 8bit variable holding the manufacturing ID
  74612. +* pDevId: pointer to the 16bit variable holding the device ID
  74613. +*
  74614. +* RETURN:
  74615. +* Success or Error code.
  74616. +*
  74617. +*
  74618. +*******************************************************************************/
  74619. +MV_STATUS mvSFlashIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* pManId, MV_U16* pDevId)
  74620. +{
  74621. + MV_STATUS ret;
  74622. + MV_U8 cmd[MV_SFLASH_RDID_CMND_LENGTH];
  74623. + MV_U8 id[MV_SFLASH_RDID_REPLY_LENGTH];
  74624. +
  74625. +
  74626. +
  74627. + /* check for NULL pointer */
  74628. + if ((pFlinfo == NULL) || (pManId == NULL) || (pDevId == NULL))
  74629. + {
  74630. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74631. + return MV_BAD_PARAM;
  74632. + }
  74633. +
  74634. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  74635. + return mvSFlashWithDefaultsIdGet(pFlinfo, pManId, pDevId);
  74636. + else
  74637. + cmd[0] = sflash[pFlinfo->index].opcdRDID;
  74638. +
  74639. + if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_RDID_CMND_LENGTH, id, MV_SFLASH_RDID_REPLY_LENGTH, 0)) != MV_OK)
  74640. + return ret;
  74641. +
  74642. + *pManId = id[0];
  74643. + *pDevId = 0;
  74644. + *pDevId |= (id[1] << 8);
  74645. + *pDevId |= id[2];
  74646. +
  74647. + return MV_OK;
  74648. +}
  74649. +
  74650. +/*******************************************************************************
  74651. +* mvSFlashWpRegionSet - Set the Write-Protected region
  74652. +*
  74653. +* DESCRIPTION:
  74654. +* Set the Write-Protected region
  74655. +*
  74656. +* INPUT:
  74657. +* pFlinfo: pointer to the Flash information structure
  74658. +* wpRegion: which region will be protected
  74659. +*
  74660. +* OUTPUT:
  74661. +* None
  74662. +*
  74663. +* RETURN:
  74664. +* Success or Error code.
  74665. +*
  74666. +*
  74667. +*******************************************************************************/
  74668. +MV_STATUS mvSFlashWpRegionSet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION wpRegion)
  74669. +{
  74670. + MV_U8 wpMask;
  74671. +
  74672. + /* check for NULL pointer */
  74673. + if (pFlinfo == NULL)
  74674. + {
  74675. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74676. + return MV_BAD_PARAM;
  74677. + }
  74678. +
  74679. + /* Protection - check if the model was detected */
  74680. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  74681. + {
  74682. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  74683. + return MV_BAD_PARAM;
  74684. + }
  74685. +
  74686. + /* Check if the chip is an ST flash; then WP supports only 3 bits */
  74687. + if (pFlinfo->manufacturerId == MV_M25PXXX_ST_MANF_ID)
  74688. + {
  74689. + switch (wpRegion)
  74690. + {
  74691. + case MV_WP_NONE:
  74692. + wpMask = MV_M25P_STATUS_BP_NONE;
  74693. + break;
  74694. +
  74695. + case MV_WP_UPR_1OF128:
  74696. + DB(mvOsPrintf("%s WARNING: Invaild option for this flash chip!\n", __FUNCTION__);)
  74697. + return MV_NOT_SUPPORTED;
  74698. +
  74699. + case MV_WP_UPR_1OF64:
  74700. + wpMask = MV_M25P_STATUS_BP_1_OF_64;
  74701. + break;
  74702. +
  74703. + case MV_WP_UPR_1OF32:
  74704. + wpMask = MV_M25P_STATUS_BP_1_OF_32;
  74705. + break;
  74706. +
  74707. + case MV_WP_UPR_1OF16:
  74708. + wpMask = MV_M25P_STATUS_BP_1_OF_16;
  74709. + break;
  74710. +
  74711. + case MV_WP_UPR_1OF8:
  74712. + wpMask = MV_M25P_STATUS_BP_1_OF_8;
  74713. + break;
  74714. +
  74715. + case MV_WP_UPR_1OF4:
  74716. + wpMask = MV_M25P_STATUS_BP_1_OF_4;
  74717. + break;
  74718. +
  74719. + case MV_WP_UPR_1OF2:
  74720. + wpMask = MV_M25P_STATUS_BP_1_OF_2;
  74721. + break;
  74722. +
  74723. + case MV_WP_ALL:
  74724. + wpMask = MV_M25P_STATUS_BP_ALL;
  74725. + break;
  74726. +
  74727. + default:
  74728. + DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)
  74729. + return MV_BAD_PARAM;
  74730. + }
  74731. + }
  74732. + /* check if the manufacturer is MXIC then the WP is 4bits */
  74733. + else if (pFlinfo->manufacturerId == MV_MXIC_MANF_ID)
  74734. + {
  74735. + switch (wpRegion)
  74736. + {
  74737. + case MV_WP_NONE:
  74738. + wpMask = MV_MX25L_STATUS_BP_NONE;
  74739. + break;
  74740. +
  74741. + case MV_WP_UPR_1OF128:
  74742. + wpMask = MV_MX25L_STATUS_BP_1_OF_128;
  74743. + break;
  74744. +
  74745. + case MV_WP_UPR_1OF64:
  74746. + wpMask = MV_MX25L_STATUS_BP_1_OF_64;
  74747. + break;
  74748. +
  74749. + case MV_WP_UPR_1OF32:
  74750. + wpMask = MV_MX25L_STATUS_BP_1_OF_32;
  74751. + break;
  74752. +
  74753. + case MV_WP_UPR_1OF16:
  74754. + wpMask = MV_MX25L_STATUS_BP_1_OF_16;
  74755. + break;
  74756. +
  74757. + case MV_WP_UPR_1OF8:
  74758. + wpMask = MV_MX25L_STATUS_BP_1_OF_8;
  74759. + break;
  74760. +
  74761. + case MV_WP_UPR_1OF4:
  74762. + wpMask = MV_MX25L_STATUS_BP_1_OF_4;
  74763. + break;
  74764. +
  74765. + case MV_WP_UPR_1OF2:
  74766. + wpMask = MV_MX25L_STATUS_BP_1_OF_2;
  74767. + break;
  74768. +
  74769. + case MV_WP_ALL:
  74770. + wpMask = MV_MX25L_STATUS_BP_ALL;
  74771. + break;
  74772. +
  74773. + default:
  74774. + DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)
  74775. + return MV_BAD_PARAM;
  74776. + }
  74777. + }
  74778. + /* check if the manufacturer is SPANSION then the WP is 4bits */
  74779. + else if (pFlinfo->manufacturerId == MV_SPANSION_MANF_ID)
  74780. + {
  74781. + switch (wpRegion)
  74782. + {
  74783. + case MV_WP_NONE:
  74784. + wpMask = MV_S25FL_STATUS_BP_NONE;
  74785. + break;
  74786. +
  74787. + case MV_WP_UPR_1OF128:
  74788. + DB(mvOsPrintf("%s WARNING: Invaild option for this flash chip!\n", __FUNCTION__);)
  74789. + return MV_NOT_SUPPORTED;
  74790. +
  74791. + case MV_WP_UPR_1OF64:
  74792. + wpMask = MV_S25FL_STATUS_BP_1_OF_64;
  74793. + break;
  74794. +
  74795. + case MV_WP_UPR_1OF32:
  74796. + wpMask = MV_S25FL_STATUS_BP_1_OF_32;
  74797. + break;
  74798. +
  74799. + case MV_WP_UPR_1OF16:
  74800. + wpMask = MV_S25FL_STATUS_BP_1_OF_16;
  74801. + break;
  74802. +
  74803. + case MV_WP_UPR_1OF8:
  74804. + wpMask = MV_S25FL_STATUS_BP_1_OF_8;
  74805. + break;
  74806. +
  74807. + case MV_WP_UPR_1OF4:
  74808. + wpMask = MV_S25FL_STATUS_BP_1_OF_4;
  74809. + break;
  74810. +
  74811. + case MV_WP_UPR_1OF2:
  74812. + wpMask = MV_S25FL_STATUS_BP_1_OF_2;
  74813. + break;
  74814. +
  74815. + case MV_WP_ALL:
  74816. + wpMask = MV_S25FL_STATUS_BP_ALL;
  74817. + break;
  74818. +
  74819. +
  74820. + default:
  74821. + DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)
  74822. + return MV_BAD_PARAM;
  74823. + }
  74824. + }
  74825. + else
  74826. + {
  74827. + DB(mvOsPrintf("%s WARNING: Invaild parameter Manufacturer ID!\n", __FUNCTION__);)
  74828. + return MV_BAD_PARAM;
  74829. + }
  74830. +
  74831. + /* Verify that the SRWD bit is always set - register is s/w locked */
  74832. + wpMask |= MV_SFLASH_STATUS_REG_SRWD_MASK;
  74833. +
  74834. + return mvStatusRegSet(pFlinfo, wpMask);
  74835. +}
  74836. +
  74837. +/*******************************************************************************
  74838. +* mvSFlashWpRegionGet - Get the Write-Protected region configured
  74839. +*
  74840. +* DESCRIPTION:
  74841. +* Get from the chip the Write-Protected region configured
  74842. +*
  74843. +* INPUT:
  74844. +* pFlinfo: pointer to the Flash information structure
  74845. +* pWpRegion: pointer to the variable to return the WP region in
  74846. +*
  74847. +* OUTPUT:
  74848. +* wpRegion: pointer to the variable holding the WP region configured
  74849. +*
  74850. +* RETURN:
  74851. +* Success or Error code.
  74852. +*
  74853. +*
  74854. +*******************************************************************************/
  74855. +MV_STATUS mvSFlashWpRegionGet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION * pWpRegion)
  74856. +{
  74857. + MV_STATUS ret;
  74858. + MV_U8 reg;
  74859. +
  74860. + /* check for NULL pointer */
  74861. + if ((pFlinfo == NULL) || (pWpRegion == NULL))
  74862. + {
  74863. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  74864. + return MV_BAD_PARAM;
  74865. + }
  74866. +
  74867. + /* Protection - check if the model was detected */
  74868. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  74869. + {
  74870. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  74871. + return MV_BAD_PARAM;
  74872. + }
  74873. +
  74874. + if ((ret = mvStatusRegGet(pFlinfo, &reg)) != MV_OK)
  74875. + return ret;
  74876. +
  74877. + /* Check if the chip is an ST flash; then WP supports only 3 bits */
  74878. + if (pFlinfo->manufacturerId == MV_M25PXXX_ST_MANF_ID)
  74879. + {
  74880. + switch ((reg & MV_M25P_STATUS_REG_WP_MASK))
  74881. + {
  74882. + case MV_M25P_STATUS_BP_NONE:
  74883. + *pWpRegion = MV_WP_NONE;
  74884. + break;
  74885. +
  74886. + case MV_M25P_STATUS_BP_1_OF_64:
  74887. + *pWpRegion = MV_WP_UPR_1OF64;
  74888. + break;
  74889. +
  74890. + case MV_M25P_STATUS_BP_1_OF_32:
  74891. + *pWpRegion = MV_WP_UPR_1OF32;
  74892. + break;
  74893. +
  74894. + case MV_M25P_STATUS_BP_1_OF_16:
  74895. + *pWpRegion = MV_WP_UPR_1OF16;
  74896. + break;
  74897. +
  74898. + case MV_M25P_STATUS_BP_1_OF_8:
  74899. + *pWpRegion = MV_WP_UPR_1OF8;
  74900. + break;
  74901. +
  74902. + case MV_M25P_STATUS_BP_1_OF_4:
  74903. + *pWpRegion = MV_WP_UPR_1OF4;
  74904. + break;
  74905. +
  74906. + case MV_M25P_STATUS_BP_1_OF_2:
  74907. + *pWpRegion = MV_WP_UPR_1OF2;
  74908. + break;
  74909. +
  74910. + case MV_M25P_STATUS_BP_ALL:
  74911. + *pWpRegion = MV_WP_ALL;
  74912. + break;
  74913. +
  74914. + default:
  74915. + DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)
  74916. + return MV_BAD_VALUE;
  74917. + }
  74918. + }
  74919. + /* check if the manufacturer is MXIC then the WP is 4bits */
  74920. + else if (pFlinfo->manufacturerId == MV_MXIC_MANF_ID)
  74921. + {
  74922. + switch ((reg & MV_MX25L_STATUS_REG_WP_MASK))
  74923. + {
  74924. + case MV_MX25L_STATUS_BP_NONE:
  74925. + *pWpRegion = MV_WP_NONE;
  74926. + break;
  74927. +
  74928. + case MV_MX25L_STATUS_BP_1_OF_128:
  74929. + *pWpRegion = MV_WP_UPR_1OF128;
  74930. + break;
  74931. +
  74932. + case MV_MX25L_STATUS_BP_1_OF_64:
  74933. + *pWpRegion = MV_WP_UPR_1OF64;
  74934. + break;
  74935. +
  74936. + case MV_MX25L_STATUS_BP_1_OF_32:
  74937. + *pWpRegion = MV_WP_UPR_1OF32;
  74938. + break;
  74939. +
  74940. + case MV_MX25L_STATUS_BP_1_OF_16:
  74941. + *pWpRegion = MV_WP_UPR_1OF16;
  74942. + break;
  74943. +
  74944. + case MV_MX25L_STATUS_BP_1_OF_8:
  74945. + *pWpRegion = MV_WP_UPR_1OF8;
  74946. + break;
  74947. +
  74948. + case MV_MX25L_STATUS_BP_1_OF_4:
  74949. + *pWpRegion = MV_WP_UPR_1OF4;
  74950. + break;
  74951. +
  74952. + case MV_MX25L_STATUS_BP_1_OF_2:
  74953. + *pWpRegion = MV_WP_UPR_1OF2;
  74954. + break;
  74955. +
  74956. + case MV_MX25L_STATUS_BP_ALL:
  74957. + *pWpRegion = MV_WP_ALL;
  74958. + break;
  74959. +
  74960. + default:
  74961. + DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)
  74962. + return MV_BAD_VALUE;
  74963. + }
  74964. + }
  74965. + /* Check if the chip is an SPANSION flash; then WP supports only 3 bits */
  74966. + else if (pFlinfo->manufacturerId == MV_SPANSION_MANF_ID)
  74967. + {
  74968. + switch ((reg & MV_S25FL_STATUS_REG_WP_MASK))
  74969. + {
  74970. + case MV_S25FL_STATUS_BP_NONE:
  74971. + *pWpRegion = MV_WP_NONE;
  74972. + break;
  74973. +
  74974. + case MV_S25FL_STATUS_BP_1_OF_64:
  74975. + *pWpRegion = MV_WP_UPR_1OF64;
  74976. + break;
  74977. +
  74978. + case MV_S25FL_STATUS_BP_1_OF_32:
  74979. + *pWpRegion = MV_WP_UPR_1OF32;
  74980. + break;
  74981. +
  74982. + case MV_S25FL_STATUS_BP_1_OF_16:
  74983. + *pWpRegion = MV_WP_UPR_1OF16;
  74984. + break;
  74985. +
  74986. + case MV_S25FL_STATUS_BP_1_OF_8:
  74987. + *pWpRegion = MV_WP_UPR_1OF8;
  74988. + break;
  74989. +
  74990. + case MV_S25FL_STATUS_BP_1_OF_4:
  74991. + *pWpRegion = MV_WP_UPR_1OF4;
  74992. + break;
  74993. +
  74994. + case MV_S25FL_STATUS_BP_1_OF_2:
  74995. + *pWpRegion = MV_WP_UPR_1OF2;
  74996. + break;
  74997. +
  74998. + case MV_S25FL_STATUS_BP_ALL:
  74999. + *pWpRegion = MV_WP_ALL;
  75000. + break;
  75001. +
  75002. + default:
  75003. + DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)
  75004. + return MV_BAD_VALUE;
  75005. + }
  75006. + }
  75007. + else
  75008. + {
  75009. + DB(mvOsPrintf("%s WARNING: Invaild parameter Manufacturer ID!\n", __FUNCTION__);)
  75010. + return MV_BAD_PARAM;
  75011. + }
  75012. +
  75013. + return MV_OK;
  75014. +}
  75015. +
  75016. +/*******************************************************************************
  75017. +* mvSFlashStatRegLock - Lock the status register for writing - W/Vpp
  75018. +* pin should be low to take effect
  75019. +*
  75020. +* DESCRIPTION:
  75021. +* Lock the access to the Status Register for writing. This will
  75022. +* cause the flash to enter the hardware protection mode if the W/Vpp
  75023. +* is low. If the W/Vpp is hi, the chip will be in soft protection mode, but
  75024. +* the register will continue to be writable if WREN sequence was used.
  75025. +*
  75026. +* INPUT:
  75027. +* pFlinfo: pointer to the Flash information structure
  75028. +* srLock: enable/disable (MV_TRUE/MV_FALSE) status registor lock mechanism
  75029. +*
  75030. +* OUTPUT:
  75031. +* None
  75032. +*
  75033. +* RETURN:
  75034. +* Success or Error code.
  75035. +*
  75036. +*
  75037. +*******************************************************************************/
  75038. +MV_STATUS mvSFlashStatRegLock (MV_SFLASH_INFO * pFlinfo, MV_BOOL srLock)
  75039. +{
  75040. + MV_STATUS ret;
  75041. + MV_U8 reg;
  75042. +
  75043. + /* check for NULL pointer */
  75044. + if (pFlinfo == NULL)
  75045. + {
  75046. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75047. + return MV_BAD_PARAM;
  75048. + }
  75049. +
  75050. + /* Protection - check if the model was detected */
  75051. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75052. + {
  75053. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  75054. + return MV_BAD_PARAM;
  75055. + }
  75056. +
  75057. + if ((ret = mvStatusRegGet(pFlinfo, &reg)) != MV_OK)
  75058. + return ret;
  75059. +
  75060. + if (srLock)
  75061. + reg |= MV_SFLASH_STATUS_REG_SRWD_MASK;
  75062. + else
  75063. + reg &= ~MV_SFLASH_STATUS_REG_SRWD_MASK;
  75064. +
  75065. + return mvStatusRegSet(pFlinfo, reg);
  75066. +}
  75067. +
  75068. +/*******************************************************************************
  75069. +* mvSFlashSizeGet - Get the size of the SPI flash
  75070. +*
  75071. +* DESCRIPTION:
  75072. +* based on the sector number and size of each sector calculate the total
  75073. +* size of the flash memory.
  75074. +*
  75075. +* INPUT:
  75076. +* pFlinfo: pointer to the Flash information structure
  75077. +*
  75078. +* OUTPUT:
  75079. +* None.
  75080. +*
  75081. +* RETURN:
  75082. +* Size of the flash in bytes.
  75083. +*
  75084. +*
  75085. +*******************************************************************************/
  75086. +MV_U32 mvSFlashSizeGet (MV_SFLASH_INFO * pFlinfo)
  75087. +{
  75088. + /* check for NULL pointer */
  75089. + if (pFlinfo == NULL)
  75090. + {
  75091. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75092. + return 0;
  75093. + }
  75094. +
  75095. + return (pFlinfo->sectorSize * pFlinfo->sectorNumber);
  75096. +}
  75097. +
  75098. +/*******************************************************************************
  75099. +* mvSFlashPowerSaveEnter - Cause the falsh device to go into power save mode
  75100. +*
  75101. +* DESCRIPTION:
  75102. +* Enter a special power save mode.
  75103. +*
  75104. +* INPUT:
  75105. +* pFlinfo: pointer to the Flash information structure
  75106. +*
  75107. +* OUTPUT:
  75108. +* None.
  75109. +*
  75110. +* RETURN:
  75111. +* Size of the flash in bytes.
  75112. +*
  75113. +*
  75114. +*******************************************************************************/
  75115. +MV_STATUS mvSFlashPowerSaveEnter(MV_SFLASH_INFO * pFlinfo)
  75116. +{
  75117. + MV_STATUS ret;
  75118. + MV_U8 cmd[MV_SFLASH_DP_CMND_LENGTH];
  75119. +
  75120. +
  75121. + /* check for NULL pointer */
  75122. + if (pFlinfo == NULL)
  75123. + {
  75124. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75125. + return 0;
  75126. + }
  75127. +
  75128. + /* Protection - check if the model was detected */
  75129. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75130. + {
  75131. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  75132. + return MV_BAD_PARAM;
  75133. + }
  75134. +
  75135. + /* check that power save mode is supported in the specific device */
  75136. + if (sflash[pFlinfo->index].opcdPwrSave == MV_SFLASH_NO_SPECIFIC_OPCD)
  75137. + {
  75138. + DB(mvOsPrintf("%s WARNING: Power save not supported for this device!\n", __FUNCTION__);)
  75139. + return MV_NOT_SUPPORTED;
  75140. + }
  75141. +
  75142. + cmd[0] = sflash[pFlinfo->index].opcdPwrSave;
  75143. +
  75144. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_DP_CMND_LENGTH, NULL, 0)) != MV_OK)
  75145. + return ret;
  75146. +
  75147. + return MV_OK;
  75148. +
  75149. +}
  75150. +
  75151. +/*******************************************************************************
  75152. +* mvSFlashPowerSaveExit - Cause the falsh device to exit the power save mode
  75153. +*
  75154. +* DESCRIPTION:
  75155. +* Exit the deep power save mode.
  75156. +*
  75157. +* INPUT:
  75158. +* pFlinfo: pointer to the Flash information structure
  75159. +*
  75160. +* OUTPUT:
  75161. +* None.
  75162. +*
  75163. +* RETURN:
  75164. +* Size of the flash in bytes.
  75165. +*
  75166. +*
  75167. +*******************************************************************************/
  75168. +MV_STATUS mvSFlashPowerSaveExit (MV_SFLASH_INFO * pFlinfo)
  75169. +{
  75170. + MV_STATUS ret;
  75171. + MV_U8 cmd[MV_SFLASH_RES_CMND_LENGTH];
  75172. +
  75173. +
  75174. + /* check for NULL pointer */
  75175. + if (pFlinfo == NULL)
  75176. + {
  75177. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75178. + return 0;
  75179. + }
  75180. +
  75181. + /* Protection - check if the model was detected */
  75182. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75183. + {
  75184. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  75185. + return MV_BAD_PARAM;
  75186. + }
  75187. +
  75188. + /* check that power save mode is supported in the specific device */
  75189. + if (sflash[pFlinfo->index].opcdRES == MV_SFLASH_NO_SPECIFIC_OPCD)
  75190. + {
  75191. + DB(mvOsPrintf("%s WARNING: Read Electronic Signature not supported for this device!\n", __FUNCTION__);)
  75192. + return MV_NOT_SUPPORTED;
  75193. + }
  75194. +
  75195. + cmd[0] = sflash[pFlinfo->index].opcdRES;
  75196. +
  75197. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_RES_CMND_LENGTH, NULL, 0)) != MV_OK)
  75198. + return ret;
  75199. +
  75200. + /* add the delay needed for the device to wake up */
  75201. + mvOsDelay(MV_MXIC_DP_EXIT_DELAY); /* 30 ms */
  75202. +
  75203. + return MV_OK;
  75204. +
  75205. +}
  75206. +
  75207. +/*******************************************************************************
  75208. +* mvSFlashModelGet - Retreive the string with the device manufacturer and model
  75209. +*
  75210. +* DESCRIPTION:
  75211. +* Retreive the string with the device manufacturer and model
  75212. +*
  75213. +* INPUT:
  75214. +* pFlinfo: pointer to the Flash information structure
  75215. +*
  75216. +* OUTPUT:
  75217. +* None.
  75218. +*
  75219. +* RETURN:
  75220. +* pointer to the string indicating the device manufacturer and model
  75221. +*
  75222. +*
  75223. +*******************************************************************************/
  75224. +const MV_8 * mvSFlashModelGet (MV_SFLASH_INFO * pFlinfo)
  75225. +{
  75226. + static const MV_8 * unknModel = (const MV_8 *)"Unknown";
  75227. +
  75228. + /* check for NULL pointer */
  75229. + if (pFlinfo == NULL)
  75230. + {
  75231. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75232. + return 0;
  75233. + }
  75234. +
  75235. + /* Protection - check if the model was detected */
  75236. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75237. + {
  75238. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  75239. + return unknModel;
  75240. + }
  75241. +
  75242. + return sflash[pFlinfo->index].deviceModel;
  75243. +}
  75244. +
  75245. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h
  75246. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h 1970-01-01 01:00:00.000000000 +0100
  75247. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h 2010-08-05 22:02:25.433667700 +0200
  75248. @@ -0,0 +1,166 @@
  75249. +/*******************************************************************************
  75250. +Copyright (C) Marvell International Ltd. and its affiliates
  75251. +
  75252. +This software file (the "File") is owned and distributed by Marvell
  75253. +International Ltd. and/or its affiliates ("Marvell") under the following
  75254. +alternative licensing terms. Once you have made an election to distribute the
  75255. +File under one of the following license alternatives, please (i) delete this
  75256. +introductory statement regarding license alternatives, (ii) delete the two
  75257. +license alternatives that you have not elected to use and (iii) preserve the
  75258. +Marvell copyright notice above.
  75259. +
  75260. +********************************************************************************
  75261. +Marvell Commercial License Option
  75262. +
  75263. +If you received this File from Marvell and you have entered into a commercial
  75264. +license agreement (a "Commercial License") with Marvell, the File is licensed
  75265. +to you under the terms of the applicable Commercial License.
  75266. +
  75267. +********************************************************************************
  75268. +Marvell GPL License Option
  75269. +
  75270. +If you received this File from Marvell, you may opt to use, redistribute and/or
  75271. +modify this File in accordance with the terms and conditions of the General
  75272. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  75273. +available along with the File in the license.txt file or by writing to the Free
  75274. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  75275. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  75276. +
  75277. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  75278. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  75279. +DISCLAIMED. The GPL License provides additional details about this warranty
  75280. +disclaimer.
  75281. +********************************************************************************
  75282. +Marvell BSD License Option
  75283. +
  75284. +If you received this File from Marvell, you may opt to use, redistribute and/or
  75285. +modify this File under the following licensing terms.
  75286. +Redistribution and use in source and binary forms, with or without modification,
  75287. +are permitted provided that the following conditions are met:
  75288. +
  75289. + * Redistributions of source code must retain the above copyright notice,
  75290. + this list of conditions and the following disclaimer.
  75291. +
  75292. + * Redistributions in binary form must reproduce the above copyright
  75293. + notice, this list of conditions and the following disclaimer in the
  75294. + documentation and/or other materials provided with the distribution.
  75295. +
  75296. + * Neither the name of Marvell nor the names of its contributors may be
  75297. + used to endorse or promote products derived from this software without
  75298. + specific prior written permission.
  75299. +
  75300. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  75301. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  75302. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  75303. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  75304. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  75305. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  75306. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  75307. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  75308. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  75309. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  75310. +
  75311. +*******************************************************************************/
  75312. +
  75313. +#ifndef __INCmvSFlashH
  75314. +#define __INCmvSFlashH
  75315. +
  75316. +#include "mvTypes.h"
  75317. +
  75318. +/* MCAROS */
  75319. +#define MV_SFLASH_PAGE_ALLIGN_MASK(pgSz) (pgSz-1)
  75320. +#define MV_ARRAY_SIZE(a) ((sizeof(a)) / (sizeof(a[0])))
  75321. +
  75322. +/* Constants */
  75323. +#define MV_INVALID_DEVICE_NUMBER 0xFFFFFFFF
  75324. +/* 10 MHz is the minimum possible SPI frequency when tclk is set 200MHz*/
  75325. +#define MV_SFLASH_BASIC_SPI_FREQ 10000000
  75326. +/* enumerations */
  75327. +typedef enum
  75328. +{
  75329. + MV_WP_NONE, /* Unprotect the whole chip */
  75330. + MV_WP_UPR_1OF128, /* Write protect the upper 1/128 part */
  75331. + MV_WP_UPR_1OF64, /* Write protect the upper 1/64 part */
  75332. + MV_WP_UPR_1OF32, /* Write protect the upper 1/32 part */
  75333. + MV_WP_UPR_1OF16, /* Write protect the upper 1/16 part */
  75334. + MV_WP_UPR_1OF8, /* Write protect the upper 1/8 part */
  75335. + MV_WP_UPR_1OF4, /* Write protect the upper 1/4 part */
  75336. + MV_WP_UPR_1OF2, /* Write protect the upper 1/2 part */
  75337. + MV_WP_ALL /* Write protect the whole chip */
  75338. +} MV_SFLASH_WP_REGION;
  75339. +
  75340. +/* Type Definitions */
  75341. +typedef struct
  75342. +{
  75343. + MV_U8 opcdWREN; /* Write enable opcode */
  75344. + MV_U8 opcdWRDI; /* Write disable opcode */
  75345. + MV_U8 opcdRDID; /* Read ID opcode */
  75346. + MV_U8 opcdRDSR; /* Read Status Register opcode */
  75347. + MV_U8 opcdWRSR; /* Write Status register opcode */
  75348. + MV_U8 opcdREAD; /* Read opcode */
  75349. + MV_U8 opcdFSTRD; /* Fast Read opcode */
  75350. + MV_U8 opcdPP; /* Page program opcode */
  75351. + MV_U8 opcdSE; /* Sector erase opcode */
  75352. + MV_U8 opcdBE; /* Bulk erase opcode */
  75353. + MV_U8 opcdRES; /* Read electronic signature */
  75354. + MV_U8 opcdPwrSave; /* Go into power save mode */
  75355. + MV_U32 sectorSize; /* Size of each sector */
  75356. + MV_U32 sectorNumber; /* Number of sectors */
  75357. + MV_U32 pageSize; /* size of each page */
  75358. + const char * deviceModel; /* string with the device model */
  75359. + MV_U32 manufacturerId; /* The manufacturer ID */
  75360. + MV_U32 deviceId; /* Device ID */
  75361. + MV_U32 spiMaxFreq; /* The MAX frequency that can be used with the device */
  75362. + MV_U32 spiMaxFastFreq; /* The MAX frequency that can be used with the device for fast reads */
  75363. + MV_U32 spiFastRdDummyBytes; /* Number of dumy bytes to read before real data when working in fast read mode. */
  75364. +} MV_SFLASH_DEVICE_PARAMS;
  75365. +
  75366. +typedef struct
  75367. +{
  75368. + MV_U32 baseAddr; /* Flash Base Address used in fast mode */
  75369. + MV_U8 manufacturerId; /* Manufacturer ID */
  75370. + MV_U16 deviceId; /* Device ID */
  75371. + MV_U32 sectorSize; /* Size of each sector - all the same */
  75372. + MV_U32 sectorNumber; /* Number of sectors */
  75373. + MV_U32 pageSize; /* Page size - affect allignment */
  75374. + MV_U32 index; /* index of the device in the sflash table (internal parameter) */
  75375. +} MV_SFLASH_INFO;
  75376. +
  75377. +/* Function Prototypes */
  75378. +/* Init */
  75379. +MV_STATUS mvSFlashInit (MV_SFLASH_INFO * pFlinfo);
  75380. +
  75381. +/* erase */
  75382. +MV_STATUS mvSFlashSectorErase (MV_SFLASH_INFO * pFlinfo, MV_U32 secNumber);
  75383. +MV_STATUS mvSFlashChipErase (MV_SFLASH_INFO * pFlinfo);
  75384. +
  75385. +/* Read */
  75386. +MV_STATUS mvSFlashBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  75387. + MV_U8* pReadBuff, MV_U32 buffSize);
  75388. +MV_STATUS mvSFlashFastBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  75389. + MV_U8* pReadBuff, MV_U32 buffSize);
  75390. +
  75391. +/* write regardless of the page boundaries and size limit per Page program command */
  75392. +MV_STATUS mvSFlashBlockWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  75393. + MV_U8* pWriteBuff, MV_U32 buffSize);
  75394. +/* Get IDs */
  75395. +MV_STATUS mvSFlashIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* pManId, MV_U16* pDevId);
  75396. +
  75397. +/* Set and Get the Write Protection region - if the Status register is not locked */
  75398. +MV_STATUS mvSFlashWpRegionSet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION wpRegion);
  75399. +MV_STATUS mvSFlashWpRegionGet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION * pWpRegion);
  75400. +
  75401. +/* Lock the status register for writing - W/Vpp pin should be low to take effect */
  75402. +MV_STATUS mvSFlashStatRegLock (MV_SFLASH_INFO * pFlinfo, MV_BOOL srLock);
  75403. +
  75404. +/* Get the regions sizes */
  75405. +MV_U32 mvSFlashSizeGet (MV_SFLASH_INFO * pFlinfo);
  75406. +
  75407. +/* Cause the falsh device to go into power save mode */
  75408. +MV_STATUS mvSFlashPowerSaveEnter(MV_SFLASH_INFO * pFlinfo);
  75409. +MV_STATUS mvSFlashPowerSaveExit (MV_SFLASH_INFO * pFlinfo);
  75410. +
  75411. +/* Retreive the string with the device manufacturer and model */
  75412. +const MV_8 * mvSFlashModelGet (MV_SFLASH_INFO * pFlinfo);
  75413. +
  75414. +#endif /* __INCmvSFlashH */
  75415. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h
  75416. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h 1970-01-01 01:00:00.000000000 +0100
  75417. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h 2010-08-05 22:02:25.474103319 +0200
  75418. @@ -0,0 +1,233 @@
  75419. +/*******************************************************************************
  75420. +Copyright (C) Marvell International Ltd. and its affiliates
  75421. +
  75422. +This software file (the "File") is owned and distributed by Marvell
  75423. +International Ltd. and/or its affiliates ("Marvell") under the following
  75424. +alternative licensing terms. Once you have made an election to distribute the
  75425. +File under one of the following license alternatives, please (i) delete this
  75426. +introductory statement regarding license alternatives, (ii) delete the two
  75427. +license alternatives that you have not elected to use and (iii) preserve the
  75428. +Marvell copyright notice above.
  75429. +
  75430. +********************************************************************************
  75431. +Marvell Commercial License Option
  75432. +
  75433. +If you received this File from Marvell and you have entered into a commercial
  75434. +license agreement (a "Commercial License") with Marvell, the File is licensed
  75435. +to you under the terms of the applicable Commercial License.
  75436. +
  75437. +********************************************************************************
  75438. +Marvell GPL License Option
  75439. +
  75440. +If you received this File from Marvell, you may opt to use, redistribute and/or
  75441. +modify this File in accordance with the terms and conditions of the General
  75442. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  75443. +available along with the File in the license.txt file or by writing to the Free
  75444. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  75445. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  75446. +
  75447. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  75448. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  75449. +DISCLAIMED. The GPL License provides additional details about this warranty
  75450. +disclaimer.
  75451. +********************************************************************************
  75452. +Marvell BSD License Option
  75453. +
  75454. +If you received this File from Marvell, you may opt to use, redistribute and/or
  75455. +modify this File under the following licensing terms.
  75456. +Redistribution and use in source and binary forms, with or without modification,
  75457. +are permitted provided that the following conditions are met:
  75458. +
  75459. + * Redistributions of source code must retain the above copyright notice,
  75460. + this list of conditions and the following disclaimer.
  75461. +
  75462. + * Redistributions in binary form must reproduce the above copyright
  75463. + notice, this list of conditions and the following disclaimer in the
  75464. + documentation and/or other materials provided with the distribution.
  75465. +
  75466. + * Neither the name of Marvell nor the names of its contributors may be
  75467. + used to endorse or promote products derived from this software without
  75468. + specific prior written permission.
  75469. +
  75470. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  75471. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  75472. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  75473. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  75474. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  75475. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  75476. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  75477. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  75478. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  75479. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  75480. +
  75481. +*******************************************************************************/
  75482. +
  75483. +#ifndef __INCmvSFlashSpecH
  75484. +#define __INCmvSFlashSpecH
  75485. +
  75486. +/* Constants */
  75487. +#define MV_SFLASH_READ_CMND_LENGTH 4 /* 1B opcode + 3B address */
  75488. +#define MV_SFLASH_SE_CMND_LENGTH 4 /* 1B opcode + 3B address */
  75489. +#define MV_SFLASH_BE_CMND_LENGTH 1 /* 1B opcode */
  75490. +#define MV_SFLASH_PP_CMND_LENGTH 4 /* 1B opcode + 3B address */
  75491. +#define MV_SFLASH_WREN_CMND_LENGTH 1 /* 1B opcode */
  75492. +#define MV_SFLASH_WRDI_CMND_LENGTH 1 /* 1B opcode */
  75493. +#define MV_SFLASH_RDID_CMND_LENGTH 1 /* 1B opcode */
  75494. +#define MV_SFLASH_RDID_REPLY_LENGTH 3 /* 1B manf ID and 2B device ID */
  75495. +#define MV_SFLASH_RDSR_CMND_LENGTH 1 /* 1B opcode */
  75496. +#define MV_SFLASH_RDSR_REPLY_LENGTH 1 /* 1B status */
  75497. +#define MV_SFLASH_WRSR_CMND_LENGTH 2 /* 1B opcode + 1B status value */
  75498. +#define MV_SFLASH_DP_CMND_LENGTH 1 /* 1B opcode */
  75499. +#define MV_SFLASH_RES_CMND_LENGTH 1 /* 1B opcode */
  75500. +
  75501. +/* Status Register Bit Masks */
  75502. +#define MV_SFLASH_STATUS_REG_WIP_OFFSET 0 /* bit 0; write in progress */
  75503. +#define MV_SFLASH_STATUS_REG_WP_OFFSET 2 /* bit 2-4; write protect option */
  75504. +#define MV_SFLASH_STATUS_REG_SRWD_OFFSET 7 /* bit 7; lock status register write */
  75505. +#define MV_SFLASH_STATUS_REG_WIP_MASK (0x1 << MV_SFLASH_STATUS_REG_WIP_OFFSET)
  75506. +#define MV_SFLASH_STATUS_REG_SRWD_MASK (0x1 << MV_SFLASH_STATUS_REG_SRWD_OFFSET)
  75507. +
  75508. +#define MV_SFLASH_MAX_WAIT_LOOP 1000000
  75509. +#define MV_SFLASH_CHIP_ERASE_MAX_WAIT_LOOP 0x50000000
  75510. +
  75511. +#define MV_SFLASH_DEFAULT_RDID_OPCD 0x9F /* Default Read ID */
  75512. +#define MV_SFLASH_DEFAULT_WREN_OPCD 0x06 /* Default Write Enable */
  75513. +#define MV_SFLASH_NO_SPECIFIC_OPCD 0x00
  75514. +
  75515. +/********************************/
  75516. +/* ST M25Pxxx Device Specific */
  75517. +/********************************/
  75518. +
  75519. +/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */
  75520. +#define MV_M25PXXX_ST_MANF_ID 0x20
  75521. +#define MV_M25P32_DEVICE_ID 0x2016
  75522. +#define MV_M25P32_MAX_SPI_FREQ 20000000 /* 20MHz */
  75523. +#define MV_M25P32_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
  75524. +#define MV_M25P32_FAST_READ_DUMMY_BYTES 1
  75525. +#define MV_M25P64_DEVICE_ID 0x2017
  75526. +#define MV_M25P64_MAX_SPI_FREQ 20000000 /* 20MHz */
  75527. +#define MV_M25P64_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
  75528. +#define MV_M25P64_FAST_READ_DUMMY_BYTES 1
  75529. +#define MV_M25P128_DEVICE_ID 0x2018
  75530. +#define MV_M25P128_MAX_SPI_FREQ 20000000 /* 20MHz */
  75531. +#define MV_M25P128_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
  75532. +#define MV_M25P128_FAST_READ_DUMMY_BYTES 1
  75533. +
  75534. +
  75535. +/* Sector Sizes and population per device model*/
  75536. +#define MV_M25P32_SECTOR_SIZE 0x10000 /* 64K */
  75537. +#define MV_M25P64_SECTOR_SIZE 0x10000 /* 64K */
  75538. +#define MV_M25P128_SECTOR_SIZE 0x40000 /* 256K */
  75539. +#define MV_M25P32_SECTOR_NUMBER 64
  75540. +#define MV_M25P64_SECTOR_NUMBER 128
  75541. +#define MV_M25P128_SECTOR_NUMBER 64
  75542. +#define MV_M25P_PAGE_SIZE 0x100 /* 256 byte */
  75543. +
  75544. +#define MV_M25P_WREN_CMND_OPCD 0x06 /* Write Enable */
  75545. +#define MV_M25P_WRDI_CMND_OPCD 0x04 /* Write Disable */
  75546. +#define MV_M25P_RDID_CMND_OPCD 0x9F /* Read ID */
  75547. +#define MV_M25P_RDSR_CMND_OPCD 0x05 /* Read Status Register */
  75548. +#define MV_M25P_WRSR_CMND_OPCD 0x01 /* Write Status Register */
  75549. +#define MV_M25P_READ_CMND_OPCD 0x03 /* Sequential Read */
  75550. +#define MV_M25P_FAST_RD_CMND_OPCD 0x0B /* Fast Read */
  75551. +#define MV_M25P_PP_CMND_OPCD 0x02 /* Page Program */
  75552. +#define MV_M25P_SE_CMND_OPCD 0xD8 /* Sector Erase */
  75553. +#define MV_M25P_BE_CMND_OPCD 0xC7 /* Bulk Erase */
  75554. +#define MV_M25P_RES_CMND_OPCD 0xAB /* Read Electronic Signature */
  75555. +
  75556. +/* Status Register Write Protect Bit Masks - 3bits */
  75557. +#define MV_M25P_STATUS_REG_WP_MASK (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75558. +#define MV_M25P_STATUS_BP_NONE (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75559. +#define MV_M25P_STATUS_BP_1_OF_64 (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75560. +#define MV_M25P_STATUS_BP_1_OF_32 (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75561. +#define MV_M25P_STATUS_BP_1_OF_16 (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75562. +#define MV_M25P_STATUS_BP_1_OF_8 (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75563. +#define MV_M25P_STATUS_BP_1_OF_4 (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75564. +#define MV_M25P_STATUS_BP_1_OF_2 (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75565. +#define MV_M25P_STATUS_BP_ALL (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75566. +
  75567. +/************************************/
  75568. +/* MXIC MX25L6405 Device Specific */
  75569. +/************************************/
  75570. +
  75571. +/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */
  75572. +#define MV_MXIC_MANF_ID 0xC2
  75573. +#define MV_MX25L6405_DEVICE_ID 0x2017
  75574. +#define MV_MX25L6405_MAX_SPI_FREQ 20000000 /* 20MHz */
  75575. +#define MV_MX25L6405_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
  75576. +#define MV_MX25L6405_FAST_READ_DUMMY_BYTES 1
  75577. +#define MV_MXIC_DP_EXIT_DELAY 30 /* 30 ms */
  75578. +
  75579. +/* Sector Sizes and population per device model*/
  75580. +#define MV_MX25L6405_SECTOR_SIZE 0x10000 /* 64K */
  75581. +#define MV_MX25L6405_SECTOR_NUMBER 128
  75582. +#define MV_MXIC_PAGE_SIZE 0x100 /* 256 byte */
  75583. +
  75584. +#define MV_MX25L_WREN_CMND_OPCD 0x06 /* Write Enable */
  75585. +#define MV_MX25L_WRDI_CMND_OPCD 0x04 /* Write Disable */
  75586. +#define MV_MX25L_RDID_CMND_OPCD 0x9F /* Read ID */
  75587. +#define MV_MX25L_RDSR_CMND_OPCD 0x05 /* Read Status Register */
  75588. +#define MV_MX25L_WRSR_CMND_OPCD 0x01 /* Write Status Register */
  75589. +#define MV_MX25L_READ_CMND_OPCD 0x03 /* Sequential Read */
  75590. +#define MV_MX25L_FAST_RD_CMND_OPCD 0x0B /* Fast Read */
  75591. +#define MV_MX25L_PP_CMND_OPCD 0x02 /* Page Program */
  75592. +#define MV_MX25L_SE_CMND_OPCD 0xD8 /* Sector Erase */
  75593. +#define MV_MX25L_BE_CMND_OPCD 0xC7 /* Bulk Erase */
  75594. +#define MV_MX25L_DP_CMND_OPCD 0xB9 /* Deep Power Down */
  75595. +#define MV_MX25L_RES_CMND_OPCD 0xAB /* Read Electronic Signature */
  75596. +
  75597. +/* Status Register Write Protect Bit Masks - 4bits */
  75598. +#define MV_MX25L_STATUS_REG_WP_MASK (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75599. +#define MV_MX25L_STATUS_BP_NONE (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75600. +#define MV_MX25L_STATUS_BP_1_OF_128 (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75601. +#define MV_MX25L_STATUS_BP_1_OF_64 (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75602. +#define MV_MX25L_STATUS_BP_1_OF_32 (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75603. +#define MV_MX25L_STATUS_BP_1_OF_16 (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75604. +#define MV_MX25L_STATUS_BP_1_OF_8 (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75605. +#define MV_MX25L_STATUS_BP_1_OF_4 (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75606. +#define MV_MX25L_STATUS_BP_1_OF_2 (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75607. +#define MV_MX25L_STATUS_BP_ALL (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75608. +
  75609. +/************************************/
  75610. +/* SPANSION S25FL128P Device Specific */
  75611. +/************************************/
  75612. +
  75613. +/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */
  75614. +#define MV_SPANSION_MANF_ID 0x01
  75615. +#define MV_S25FL128_DEVICE_ID 0x2018
  75616. +#define MV_S25FL128_MAX_SPI_FREQ 33000000 /* 33MHz */
  75617. +#define MV_S25FL128_MAX_FAST_SPI_FREQ 104000000 /* 104MHz */
  75618. +#define MV_S25FL128_FAST_READ_DUMMY_BYTES 1
  75619. +
  75620. +/* Sector Sizes and population per device model*/
  75621. +#define MV_S25FL128_SECTOR_SIZE 0x40000 /* 256K */
  75622. +#define MV_S25FL128_SECTOR_NUMBER 64
  75623. +#define MV_S25FL_PAGE_SIZE 0x100 /* 256 byte */
  75624. +
  75625. +#define MV_S25FL_WREN_CMND_OPCD 0x06 /* Write Enable */
  75626. +#define MV_S25FL_WRDI_CMND_OPCD 0x04 /* Write Disable */
  75627. +#define MV_S25FL_RDID_CMND_OPCD 0x9F /* Read ID */
  75628. +#define MV_S25FL_RDSR_CMND_OPCD 0x05 /* Read Status Register */
  75629. +#define MV_S25FL_WRSR_CMND_OPCD 0x01 /* Write Status Register */
  75630. +#define MV_S25FL_READ_CMND_OPCD 0x03 /* Sequential Read */
  75631. +#define MV_S25FL_FAST_RD_CMND_OPCD 0x0B /* Fast Read */
  75632. +#define MV_S25FL_PP_CMND_OPCD 0x02 /* Page Program */
  75633. +#define MV_S25FL_SE_CMND_OPCD 0xD8 /* Sector Erase */
  75634. +#define MV_S25FL_BE_CMND_OPCD 0xC7 /* Bulk Erase */
  75635. +#define MV_S25FL_DP_CMND_OPCD 0xB9 /* Deep Power Down */
  75636. +#define MV_S25FL_RES_CMND_OPCD 0xAB /* Read Electronic Signature */
  75637. +
  75638. +/* Status Register Write Protect Bit Masks - 4bits */
  75639. +#define MV_S25FL_STATUS_REG_WP_MASK (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75640. +#define MV_S25FL_STATUS_BP_NONE (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75641. +#define MV_S25FL_STATUS_BP_1_OF_128 (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75642. +#define MV_S25FL_STATUS_BP_1_OF_64 (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75643. +#define MV_S25FL_STATUS_BP_1_OF_32 (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75644. +#define MV_S25FL_STATUS_BP_1_OF_16 (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75645. +#define MV_S25FL_STATUS_BP_1_OF_8 (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75646. +#define MV_S25FL_STATUS_BP_1_OF_4 (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75647. +#define MV_S25FL_STATUS_BP_1_OF_2 (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75648. +#define MV_S25FL_STATUS_BP_ALL (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
  75649. +
  75650. +#endif /* __INCmvSFlashSpecH */
  75651. +
  75652. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c
  75653. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c 1970-01-01 01:00:00.000000000 +0100
  75654. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c 2010-08-05 22:02:25.514868225 +0200
  75655. @@ -0,0 +1,576 @@
  75656. +/*******************************************************************************
  75657. +Copyright (C) Marvell International Ltd. and its affiliates
  75658. +
  75659. +This software file (the "File") is owned and distributed by Marvell
  75660. +International Ltd. and/or its affiliates ("Marvell") under the following
  75661. +alternative licensing terms. Once you have made an election to distribute the
  75662. +File under one of the following license alternatives, please (i) delete this
  75663. +introductory statement regarding license alternatives, (ii) delete the two
  75664. +license alternatives that you have not elected to use and (iii) preserve the
  75665. +Marvell copyright notice above.
  75666. +
  75667. +********************************************************************************
  75668. +Marvell Commercial License Option
  75669. +
  75670. +If you received this File from Marvell and you have entered into a commercial
  75671. +license agreement (a "Commercial License") with Marvell, the File is licensed
  75672. +to you under the terms of the applicable Commercial License.
  75673. +
  75674. +********************************************************************************
  75675. +Marvell GPL License Option
  75676. +
  75677. +If you received this File from Marvell, you may opt to use, redistribute and/or
  75678. +modify this File in accordance with the terms and conditions of the General
  75679. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  75680. +available along with the File in the license.txt file or by writing to the Free
  75681. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  75682. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  75683. +
  75684. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  75685. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  75686. +DISCLAIMED. The GPL License provides additional details about this warranty
  75687. +disclaimer.
  75688. +********************************************************************************
  75689. +Marvell BSD License Option
  75690. +
  75691. +If you received this File from Marvell, you may opt to use, redistribute and/or
  75692. +modify this File under the following licensing terms.
  75693. +Redistribution and use in source and binary forms, with or without modification,
  75694. +are permitted provided that the following conditions are met:
  75695. +
  75696. + * Redistributions of source code must retain the above copyright notice,
  75697. + this list of conditions and the following disclaimer.
  75698. +
  75699. + * Redistributions in binary form must reproduce the above copyright
  75700. + notice, this list of conditions and the following disclaimer in the
  75701. + documentation and/or other materials provided with the distribution.
  75702. +
  75703. + * Neither the name of Marvell nor the names of its contributors may be
  75704. + used to endorse or promote products derived from this software without
  75705. + specific prior written permission.
  75706. +
  75707. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  75708. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  75709. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  75710. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  75711. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  75712. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  75713. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  75714. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  75715. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  75716. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  75717. +
  75718. +*******************************************************************************/
  75719. +
  75720. +#include "spi/mvSpi.h"
  75721. +#include "spi/mvSpiSpec.h"
  75722. +
  75723. +#include "ctrlEnv/mvCtrlEnvLib.h"
  75724. +
  75725. +/* #define MV_DEBUG */
  75726. +#ifdef MV_DEBUG
  75727. +#define DB(x) x
  75728. +#define mvOsPrintf printf
  75729. +#else
  75730. +#define DB(x)
  75731. +#endif
  75732. +
  75733. +
  75734. +/*******************************************************************************
  75735. +* mvSpi16bitDataTxRx - Transmt and receive data
  75736. +*
  75737. +* DESCRIPTION:
  75738. +* Tx data and block waiting for data to be transmitted
  75739. +*
  75740. +********************************************************************************/
  75741. +static MV_STATUS mvSpi16bitDataTxRx (MV_U16 txData, MV_U16 * pRxData)
  75742. +{
  75743. + MV_U32 i;
  75744. + MV_BOOL ready = MV_FALSE;
  75745. +
  75746. + /* First clear the bit in the interrupt cause register */
  75747. + MV_REG_WRITE(MV_SPI_INT_CAUSE_REG, 0x0);
  75748. +
  75749. + /* Transmit data */
  75750. + MV_REG_WRITE(MV_SPI_DATA_OUT_REG, MV_16BIT_LE(txData));
  75751. +
  75752. + /* wait with timeout for memory ready */
  75753. + for (i=0; i<MV_SPI_WAIT_RDY_MAX_LOOP; i++)
  75754. + {
  75755. + if (MV_REG_READ(MV_SPI_INT_CAUSE_REG))
  75756. + {
  75757. + ready = MV_TRUE;
  75758. + break;
  75759. + }
  75760. +#ifdef MV_SPI_SLEEP_ON_WAIT
  75761. + mvOsSleep(1);
  75762. +#endif /* MV_SPI_SLEEP_ON_WAIT */
  75763. + }
  75764. +
  75765. + if (!ready)
  75766. + return MV_TIMEOUT;
  75767. +
  75768. + /* check that the RX data is needed */
  75769. + if (pRxData)
  75770. + {
  75771. + if ((MV_U32)pRxData & 0x1) /* check if address is not alligned to 16bit */
  75772. + {
  75773. +#if defined(MV_CPU_LE)
  75774. + /* perform the data write to the buffer in two stages with 8bit each */
  75775. + MV_U8 * bptr = (MV_U8*)pRxData;
  75776. + MV_U16 data = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));
  75777. + *bptr = (data & 0xFF);
  75778. + ++bptr;
  75779. + *bptr = ((data >> 8) & 0xFF);
  75780. +
  75781. +#elif defined(MV_CPU_BE)
  75782. +
  75783. + /* perform the data write to the buffer in two stages with 8bit each */
  75784. + MV_U8 * bptr = (MV_U8 *)pRxData;
  75785. + MV_U16 data = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));
  75786. + *bptr = ((data >> 8) & 0xFF);
  75787. + ++bptr;
  75788. + *bptr = (data & 0xFF);
  75789. +
  75790. +#else
  75791. + #error "CPU endianess isn't defined!\n"
  75792. +#endif
  75793. +
  75794. + }
  75795. + else
  75796. + *pRxData = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));
  75797. + }
  75798. +
  75799. + return MV_OK;
  75800. +}
  75801. +
  75802. +
  75803. +/*******************************************************************************
  75804. +* mvSpi8bitDataTxRx - Transmt and receive data (8bits)
  75805. +*
  75806. +* DESCRIPTION:
  75807. +* Tx data and block waiting for data to be transmitted
  75808. +*
  75809. +********************************************************************************/
  75810. +static MV_STATUS mvSpi8bitDataTxRx (MV_U8 txData, MV_U8 * pRxData)
  75811. +{
  75812. + MV_U32 i;
  75813. + MV_BOOL ready = MV_FALSE;
  75814. +
  75815. + /* First clear the bit in the interrupt cause register */
  75816. + MV_REG_WRITE(MV_SPI_INT_CAUSE_REG, 0x0);
  75817. +
  75818. + /* Transmit data */
  75819. + MV_REG_WRITE(MV_SPI_DATA_OUT_REG, txData);
  75820. +
  75821. + /* wait with timeout for memory ready */
  75822. + for (i=0; i<MV_SPI_WAIT_RDY_MAX_LOOP; i++)
  75823. + {
  75824. + if (MV_REG_READ(MV_SPI_INT_CAUSE_REG))
  75825. + {
  75826. + ready = MV_TRUE;
  75827. + break;
  75828. + }
  75829. +#ifdef MV_SPI_SLEEP_ON_WAIT
  75830. + mvOsSleep(1);
  75831. +#endif /* MV_SPI_SLEEP_ON_WAIT */
  75832. + }
  75833. +
  75834. + if (!ready)
  75835. + return MV_TIMEOUT;
  75836. +
  75837. + /* check that the RX data is needed */
  75838. + if (pRxData)
  75839. + *pRxData = MV_REG_READ(MV_SPI_DATA_IN_REG);
  75840. +
  75841. + return MV_OK;
  75842. +}
  75843. +
  75844. +/*
  75845. +#####################################################################################
  75846. +#####################################################################################
  75847. +*/
  75848. +
  75849. +/*******************************************************************************
  75850. +* mvSpiInit - Initialize the SPI controller
  75851. +*
  75852. +* DESCRIPTION:
  75853. +* Perform the neccessary initialization in order to be able to send an
  75854. +* receive over the SPI interface.
  75855. +*
  75856. +* INPUT:
  75857. +* serialBaudRate: Baud rate (SPI clock frequency)
  75858. +* use16BitMode: Whether to use 2bytes (MV_TRUE) or 1bytes (MV_FALSE)
  75859. +*
  75860. +* OUTPUT:
  75861. +* None.
  75862. +*
  75863. +* RETURN:
  75864. +* Success or Error code.
  75865. +*
  75866. +*
  75867. +*******************************************************************************/
  75868. +MV_STATUS mvSpiInit (MV_U32 serialBaudRate)
  75869. +{
  75870. + MV_STATUS ret;
  75871. +
  75872. + /* Set the serial clock */
  75873. + if ((ret = mvSpiBaudRateSet(serialBaudRate)) != MV_OK)
  75874. + return ret;
  75875. +
  75876. + /* For devices in which the SPI is muxed on the MPP with other interfaces*/
  75877. + mvMPPConfigToSPI();
  75878. +
  75879. + /* Configure the default SPI mode to be 16bit */
  75880. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  75881. +
  75882. + /* Fix ac timing on SPI in 6183, 6183L and 78x00 only */
  75883. + if ( (mvCtrlModelGet() == MV_6183_DEV_ID) ||
  75884. + (mvCtrlModelGet() == MV_6183L_DEV_ID) ||
  75885. + (mvCtrlModelGet() == MV_78100_DEV_ID) ||
  75886. + (mvCtrlModelGet() == MV_78200_DEV_ID) ||
  75887. + (mvCtrlModelGet() == MV_76100_DEV_ID))
  75888. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, BIT14);
  75889. +
  75890. + /* Verify that the CS is deasserted */
  75891. + mvSpiCsDeassert();
  75892. +
  75893. + return MV_OK;
  75894. +}
  75895. +
  75896. +/*******************************************************************************
  75897. +* mvSpiBaudRateSet - Set the Frequency of the SPI clock
  75898. +*
  75899. +* DESCRIPTION:
  75900. +* Set the Prescale bits to adapt to the requested baud rate (the clock
  75901. +* used for thr SPI).
  75902. +*
  75903. +* INPUT:
  75904. +* serialBaudRate: Baud rate (SPI clock frequency)
  75905. +*
  75906. +* OUTPUT:
  75907. +* None.
  75908. +*
  75909. +* RETURN:
  75910. +* Success or Error code.
  75911. +*
  75912. +*
  75913. +*******************************************************************************/
  75914. +MV_STATUS mvSpiBaudRateSet (MV_U32 serialBaudRate)
  75915. +{
  75916. + MV_U8 i;
  75917. + /* MV_U8 preScale[32] = {1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  75918. + 2, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
  75919. + */
  75920. + MV_U8 preScale[14] = { 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
  75921. + MV_U8 bestPrescaleIndx = 100;
  75922. + MV_U32 minBaudOffset = 0xFFFFFFFF;
  75923. + MV_U32 cpuClk = mvBoardTclkGet(); /*mvCpuPclkGet();*/
  75924. + MV_U32 tempReg;
  75925. +
  75926. + /* Find the best prescale configuration - less or equal */
  75927. + for (i=0; i<14; i++)
  75928. + {
  75929. + /* check for higher - irrelevent */
  75930. + if ((cpuClk / preScale[i]) > serialBaudRate)
  75931. + continue;
  75932. +
  75933. + /* check for exact fit */
  75934. + if ((cpuClk / preScale[i]) == serialBaudRate)
  75935. + {
  75936. + bestPrescaleIndx = i;
  75937. + break;
  75938. + }
  75939. +
  75940. + /* check if this is better than the previous one */
  75941. + if ((serialBaudRate - (cpuClk / preScale[i])) < minBaudOffset)
  75942. + {
  75943. + minBaudOffset = (serialBaudRate - (cpuClk / preScale[i]));
  75944. + bestPrescaleIndx = i;
  75945. + }
  75946. + }
  75947. +
  75948. + if (bestPrescaleIndx > 14)
  75949. + {
  75950. + mvOsPrintf("%s ERROR: SPI baud rate prescale error!\n", __FUNCTION__);
  75951. + return MV_OUT_OF_RANGE;
  75952. + }
  75953. +
  75954. + /* configure the Prescale */
  75955. + tempReg = MV_REG_READ(MV_SPI_IF_CONFIG_REG);
  75956. + tempReg = ((tempReg & ~MV_SPI_CLK_PRESCALE_MASK) | (bestPrescaleIndx + 0x12));
  75957. + MV_REG_WRITE(MV_SPI_IF_CONFIG_REG, tempReg);
  75958. +
  75959. + return MV_OK;
  75960. +}
  75961. +
  75962. +/*******************************************************************************
  75963. +* mvSpiCsAssert - Assert the Chip Select pin indicating a new transfer
  75964. +*
  75965. +* DESCRIPTION:
  75966. +* Assert The chip select - used to select an external SPI device
  75967. +*
  75968. +* INPUT:
  75969. +* None.
  75970. +*
  75971. +* OUTPUT:
  75972. +* None.
  75973. +*
  75974. +* RETURN:
  75975. +* Success or Error code.
  75976. +*
  75977. +********************************************************************************/
  75978. +MV_VOID mvSpiCsAssert(MV_VOID)
  75979. +{
  75980. + /* For devices in which the SPI is muxed on the MPP with other interfaces*/
  75981. + mvMPPConfigToSPI();
  75982. + mvOsUDelay(1);
  75983. + MV_REG_BIT_SET(MV_SPI_IF_CTRL_REG, MV_SPI_CS_ENABLE_MASK);
  75984. +}
  75985. +
  75986. +/*******************************************************************************
  75987. +* mvSpiCsDeassert - DeAssert the Chip Select pin indicating the end of a
  75988. +* SPI transfer sequence
  75989. +*
  75990. +* DESCRIPTION:
  75991. +* DeAssert the chip select pin
  75992. +*
  75993. +* INPUT:
  75994. +* None.
  75995. +*
  75996. +* OUTPUT:
  75997. +* None.
  75998. +*
  75999. +* RETURN:
  76000. +* Success or Error code.
  76001. +*
  76002. +********************************************************************************/
  76003. +MV_VOID mvSpiCsDeassert(MV_VOID)
  76004. +{
  76005. + MV_REG_BIT_RESET(MV_SPI_IF_CTRL_REG, MV_SPI_CS_ENABLE_MASK);
  76006. +
  76007. + /* For devices in which the SPI is muxed on the MPP with other interfaces*/
  76008. + mvMPPConfigToDefault();
  76009. +}
  76010. +
  76011. +/*******************************************************************************
  76012. +* mvSpiRead - Read a buffer over the SPI interface
  76013. +*
  76014. +* DESCRIPTION:
  76015. +* Receive (read) a buffer over the SPI interface in 16bit chunks. If the
  76016. +* buffer size is odd, then the last chunk will be 8bits. Chip select is not
  76017. +* handled at this level.
  76018. +*
  76019. +* INPUT:
  76020. +* pRxBuff: Pointer to the buffer to hold the received data
  76021. +* buffSize: length of the pRxBuff
  76022. +*
  76023. +* OUTPUT:
  76024. +* pRxBuff: Pointer to the buffer with the received data
  76025. +*
  76026. +* RETURN:
  76027. +* Success or Error code.
  76028. +*
  76029. +*
  76030. +*******************************************************************************/
  76031. +MV_STATUS mvSpiRead (MV_U8* pRxBuff, MV_U32 buffSize)
  76032. +{
  76033. + MV_STATUS ret;
  76034. + MV_U32 bytesLeft = buffSize;
  76035. + MV_U16* rxPtr = (MV_U16*)pRxBuff;
  76036. +
  76037. + /* check for null parameters */
  76038. + if (pRxBuff == NULL)
  76039. + {
  76040. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76041. + return MV_BAD_PARAM;
  76042. + }
  76043. +
  76044. + /* Check that the buffer pointer and the buffer size are 16bit aligned */
  76045. + if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pRxBuff & 1) == 0))
  76046. + {
  76047. + /* Verify that the SPI mode is in 16bit mode */
  76048. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  76049. +
  76050. + /* TX/RX as long we have complete 16bit chunks */
  76051. + while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)
  76052. + {
  76053. + /* Transmitted and wait for the transfer to be completed */
  76054. + if ((ret = mvSpi16bitDataTxRx(MV_SPI_DUMMY_WRITE_16BITS, rxPtr)) != MV_OK)
  76055. + return ret;
  76056. +
  76057. + /* increment the pointers */
  76058. + rxPtr++;
  76059. + bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;
  76060. + }
  76061. +
  76062. + }
  76063. + else
  76064. + {
  76065. + /* Verify that the SPI mode is in 8bit mode */
  76066. + MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  76067. +
  76068. + /* TX/RX in 8bit chanks */
  76069. + while (bytesLeft > 0)
  76070. + {
  76071. + /* Transmitted and wait for the transfer to be completed */
  76072. + if ((ret = mvSpi8bitDataTxRx(MV_SPI_DUMMY_WRITE_8BITS, pRxBuff)) != MV_OK)
  76073. + return ret;
  76074. + /* increment the pointers */
  76075. + pRxBuff++;
  76076. + bytesLeft--;
  76077. + }
  76078. + }
  76079. +
  76080. + return MV_OK;
  76081. +}
  76082. +
  76083. +/*******************************************************************************
  76084. +* mvSpiWrite - Transmit a buffer over the SPI interface
  76085. +*
  76086. +* DESCRIPTION:
  76087. +* Transmit a buffer over the SPI interface in 16bit chunks. If the
  76088. +* buffer size is odd, then the last chunk will be 8bits. No chip select
  76089. +* action is taken.
  76090. +*
  76091. +* INPUT:
  76092. +* pTxBuff: Pointer to the buffer holding the TX data
  76093. +* buffSize: length of the pTxBuff
  76094. +*
  76095. +* OUTPUT:
  76096. +* None.
  76097. +*
  76098. +* RETURN:
  76099. +* Success or Error code.
  76100. +*
  76101. +*
  76102. +*******************************************************************************/
  76103. +MV_STATUS mvSpiWrite(MV_U8* pTxBuff, MV_U32 buffSize)
  76104. +{
  76105. + MV_STATUS ret;
  76106. + MV_U32 bytesLeft = buffSize;
  76107. + MV_U16* txPtr = (MV_U16*)pTxBuff;
  76108. +
  76109. + /* check for null parameters */
  76110. + if (pTxBuff == NULL)
  76111. + {
  76112. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76113. + return MV_BAD_PARAM;
  76114. + }
  76115. +
  76116. + /* Check that the buffer pointer and the buffer size are 16bit aligned */
  76117. + if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pTxBuff & 1) == 0))
  76118. + {
  76119. + /* Verify that the SPI mode is in 16bit mode */
  76120. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  76121. +
  76122. + /* TX/RX as long we have complete 16bit chunks */
  76123. + while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)
  76124. + {
  76125. + /* Transmitted and wait for the transfer to be completed */
  76126. + if ((ret = mvSpi16bitDataTxRx(*txPtr, NULL)) != MV_OK)
  76127. + return ret;
  76128. +
  76129. + /* increment the pointers */
  76130. + txPtr++;
  76131. + bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;
  76132. + }
  76133. + }
  76134. + else
  76135. + {
  76136. +
  76137. + /* Verify that the SPI mode is in 8bit mode */
  76138. + MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  76139. +
  76140. + /* TX/RX in 8bit chanks */
  76141. + while (bytesLeft > 0)
  76142. + {
  76143. + /* Transmitted and wait for the transfer to be completed */
  76144. + if ((ret = mvSpi8bitDataTxRx(*pTxBuff, NULL)) != MV_OK)
  76145. + return ret;
  76146. +
  76147. + /* increment the pointers */
  76148. + pTxBuff++;
  76149. + bytesLeft--;
  76150. + }
  76151. + }
  76152. +
  76153. + return MV_OK;
  76154. +}
  76155. +
  76156. +
  76157. +/*******************************************************************************
  76158. +* mvSpiReadWrite - Read and Write a buffer simultanuosely
  76159. +*
  76160. +* DESCRIPTION:
  76161. +* Transmit and receive a buffer over the SPI in 16bit chunks. If the
  76162. +* buffer size is odd, then the last chunk will be 8bits. The SPI chip
  76163. +* select is not handled implicitely.
  76164. +*
  76165. +* INPUT:
  76166. +* pRxBuff: Pointer to the buffer to write the RX info in
  76167. +* pTxBuff: Pointer to the buffer holding the TX info
  76168. +* buffSize: length of both the pTxBuff and pRxBuff
  76169. +*
  76170. +* OUTPUT:
  76171. +* pRxBuff: Pointer of the buffer holding the RX data
  76172. +*
  76173. +* RETURN:
  76174. +* Success or Error code.
  76175. +*
  76176. +*
  76177. +*******************************************************************************/
  76178. +MV_STATUS mvSpiReadWrite(MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize)
  76179. +{
  76180. + MV_STATUS ret;
  76181. + MV_U32 bytesLeft = buffSize;
  76182. + MV_U16* txPtr = (MV_U16*)pTxBuff;
  76183. + MV_U16* rxPtr = (MV_U16*)pRxBuff;
  76184. +
  76185. + /* check for null parameters */
  76186. + if ((pRxBuff == NULL) || (pTxBuff == NULL))
  76187. + {
  76188. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76189. + return MV_BAD_PARAM;
  76190. + }
  76191. +
  76192. + /* Check that the buffer pointer and the buffer size are 16bit aligned */
  76193. + if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pTxBuff & 1) == 0) && (((MV_U32)pRxBuff & 1) == 0))
  76194. + {
  76195. + /* Verify that the SPI mode is in 16bit mode */
  76196. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  76197. +
  76198. + /* TX/RX as long we have complete 16bit chunks */
  76199. + while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)
  76200. + {
  76201. + /* Transmitted and wait for the transfer to be completed */
  76202. + if ((ret = mvSpi16bitDataTxRx(*txPtr, rxPtr)) != MV_OK)
  76203. + return ret;
  76204. +
  76205. + /* increment the pointers */
  76206. + txPtr++;
  76207. + rxPtr++;
  76208. + bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;
  76209. + }
  76210. + }
  76211. + else
  76212. + {
  76213. + /* Verify that the SPI mode is in 8bit mode */
  76214. + MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  76215. +
  76216. + /* TX/RX in 8bit chanks */
  76217. + while (bytesLeft > 0)
  76218. + {
  76219. + /* Transmitted and wait for the transfer to be completed */
  76220. + if ( (ret = mvSpi8bitDataTxRx(*pTxBuff, pRxBuff) ) != MV_OK)
  76221. + return ret;
  76222. + pRxBuff++;
  76223. + pTxBuff++;
  76224. + bytesLeft--;
  76225. + }
  76226. + }
  76227. +
  76228. + return MV_OK;
  76229. +}
  76230. +
  76231. +
  76232. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c
  76233. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c 1970-01-01 01:00:00.000000000 +0100
  76234. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c 2010-08-05 22:02:25.583632308 +0200
  76235. @@ -0,0 +1,249 @@
  76236. +/*******************************************************************************
  76237. +Copyright (C) Marvell International Ltd. and its affiliates
  76238. +
  76239. +This software file (the "File") is owned and distributed by Marvell
  76240. +International Ltd. and/or its affiliates ("Marvell") under the following
  76241. +alternative licensing terms. Once you have made an election to distribute the
  76242. +File under one of the following license alternatives, please (i) delete this
  76243. +introductory statement regarding license alternatives, (ii) delete the two
  76244. +license alternatives that you have not elected to use and (iii) preserve the
  76245. +Marvell copyright notice above.
  76246. +
  76247. +********************************************************************************
  76248. +Marvell Commercial License Option
  76249. +
  76250. +If you received this File from Marvell and you have entered into a commercial
  76251. +license agreement (a "Commercial License") with Marvell, the File is licensed
  76252. +to you under the terms of the applicable Commercial License.
  76253. +
  76254. +********************************************************************************
  76255. +Marvell GPL License Option
  76256. +
  76257. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76258. +modify this File in accordance with the terms and conditions of the General
  76259. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  76260. +available along with the File in the license.txt file or by writing to the Free
  76261. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  76262. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  76263. +
  76264. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  76265. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  76266. +DISCLAIMED. The GPL License provides additional details about this warranty
  76267. +disclaimer.
  76268. +********************************************************************************
  76269. +Marvell BSD License Option
  76270. +
  76271. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76272. +modify this File under the following licensing terms.
  76273. +Redistribution and use in source and binary forms, with or without modification,
  76274. +are permitted provided that the following conditions are met:
  76275. +
  76276. + * Redistributions of source code must retain the above copyright notice,
  76277. + this list of conditions and the following disclaimer.
  76278. +
  76279. + * Redistributions in binary form must reproduce the above copyright
  76280. + notice, this list of conditions and the following disclaimer in the
  76281. + documentation and/or other materials provided with the distribution.
  76282. +
  76283. + * Neither the name of Marvell nor the names of its contributors may be
  76284. + used to endorse or promote products derived from this software without
  76285. + specific prior written permission.
  76286. +
  76287. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  76288. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  76289. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  76290. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  76291. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  76292. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  76293. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  76294. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  76295. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  76296. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  76297. +
  76298. +*******************************************************************************/
  76299. +
  76300. +#include "spi/mvSpi.h"
  76301. +#include "spi/mvSpiSpec.h"
  76302. +
  76303. +/*#define MV_DEBUG*/
  76304. +#ifdef MV_DEBUG
  76305. +#define DB(x) x
  76306. +#else
  76307. +#define DB(x)
  76308. +#endif
  76309. +
  76310. +
  76311. +/*******************************************************************************
  76312. +* mvSpiReadAndWrite - Read and Write a buffer simultanuousely
  76313. +*
  76314. +* DESCRIPTION:
  76315. +* Transmit and receive a buffer over the SPI in 16bit chunks. If the
  76316. +* buffer size is odd, then the last chunk will be 8bits.
  76317. +*
  76318. +* INPUT:
  76319. +* pRxBuff: Pointer to the buffer to write the RX info in
  76320. +* pTxBuff: Pointer to the buffer holding the TX info
  76321. +* buffSize: length of both the pTxBuff and pRxBuff
  76322. +*
  76323. +* OUTPUT:
  76324. +* pRxBuff: Pointer of the buffer holding the RX data
  76325. +*
  76326. +* RETURN:
  76327. +* Success or Error code.
  76328. +*
  76329. +*
  76330. +*******************************************************************************/
  76331. +MV_STATUS mvSpiReadAndWrite(MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize)
  76332. +{
  76333. + MV_STATUS ret;
  76334. +
  76335. + /* check for null parameters */
  76336. + if ((pRxBuff == NULL) || (pTxBuff == NULL) || (buffSize == 0))
  76337. + {
  76338. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76339. + return MV_BAD_PARAM;
  76340. + }
  76341. +
  76342. + /* First assert the chip select */
  76343. + mvSpiCsAssert();
  76344. +
  76345. + ret = mvSpiReadWrite(pRxBuff, pTxBuff, buffSize);
  76346. +
  76347. + /* Finally deassert the chip select */
  76348. + mvSpiCsDeassert();
  76349. +
  76350. + return ret;
  76351. +}
  76352. +
  76353. +/*******************************************************************************
  76354. +* mvSpiWriteThenWrite - Serialize a command followed by the data over the TX line
  76355. +*
  76356. +* DESCRIPTION:
  76357. +* Assert the chip select line. Transmit the command buffer followed by
  76358. +* the data buffer. Then deassert the CS line.
  76359. +*
  76360. +* INPUT:
  76361. +* pCmndBuff: Pointer to the command buffer to transmit
  76362. +* cmndSize: length of the command size
  76363. +* pTxDataBuff: Pointer to the data buffer to transmit
  76364. +* txDataSize: length of the data buffer
  76365. +*
  76366. +* OUTPUT:
  76367. +* None.
  76368. +*
  76369. +* RETURN:
  76370. +* Success or Error code.
  76371. +*
  76372. +*
  76373. +*******************************************************************************/
  76374. +MV_STATUS mvSpiWriteThenWrite (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pTxDataBuff,
  76375. + MV_U32 txDataSize)
  76376. +{
  76377. + MV_STATUS ret = MV_OK, tempRet;
  76378. +
  76379. + /* check for null parameters */
  76380. +#ifndef CONFIG_MARVELL
  76381. + if(NULL == pTxDataBuff)
  76382. + {
  76383. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76384. + return MV_BAD_PARAM;
  76385. + }
  76386. +#endif
  76387. +
  76388. + if (pCmndBuff == NULL)
  76389. + {
  76390. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76391. + return MV_BAD_PARAM;
  76392. + }
  76393. +
  76394. + /* First assert the chip select */
  76395. + mvSpiCsAssert();
  76396. +
  76397. + /* first write the command */
  76398. + if ((cmndSize) && (pCmndBuff != NULL))
  76399. + {
  76400. + if ((tempRet = mvSpiWrite(pCmndBuff, cmndSize)) != MV_OK)
  76401. + ret = tempRet;
  76402. + }
  76403. +
  76404. + /* Then write the data buffer */
  76405. +#ifndef CONFIG_MARVELL
  76406. + if (txDataSize)
  76407. +#else
  76408. + if ((txDataSize) && (pTxDataBuff != NULL))
  76409. +#endif
  76410. + {
  76411. + if ((tempRet = mvSpiWrite(pTxDataBuff, txDataSize)) != MV_OK)
  76412. + ret = tempRet;
  76413. + }
  76414. +
  76415. + /* Finally deassert the chip select */
  76416. + mvSpiCsDeassert();
  76417. +
  76418. + return ret;
  76419. +}
  76420. +
  76421. +/*******************************************************************************
  76422. +* mvSpiWriteThenRead - Serialize a command then read a data buffer
  76423. +*
  76424. +* DESCRIPTION:
  76425. +* Assert the chip select line. Transmit the command buffer then read
  76426. +* the data buffer. Then deassert the CS line.
  76427. +*
  76428. +* INPUT:
  76429. +* pCmndBuff: Pointer to the command buffer to transmit
  76430. +* cmndSize: length of the command size
  76431. +* pRxDataBuff: Pointer to the buffer to read the data in
  76432. +* txDataSize: length of the data buffer
  76433. +*
  76434. +* OUTPUT:
  76435. +* pRxDataBuff: Pointer to the buffer holding the data
  76436. +*
  76437. +* RETURN:
  76438. +* Success or Error code.
  76439. +*
  76440. +*
  76441. +*******************************************************************************/
  76442. +MV_STATUS mvSpiWriteThenRead (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pRxDataBuff,
  76443. + MV_U32 rxDataSize,MV_U32 dummyBytesToRead)
  76444. +{
  76445. + MV_STATUS ret = MV_OK, tempRet;
  76446. + MV_U8 dummyByte;
  76447. +
  76448. + /* check for null parameters */
  76449. + if ((pCmndBuff == NULL) && (pRxDataBuff == NULL))
  76450. + {
  76451. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76452. + return MV_BAD_PARAM;
  76453. + }
  76454. +
  76455. + /* First assert the chip select */
  76456. + mvSpiCsAssert();
  76457. +
  76458. + /* first write the command */
  76459. + if ((cmndSize) && (pCmndBuff != NULL))
  76460. + {
  76461. + if ((tempRet = mvSpiWrite(pCmndBuff, cmndSize)) != MV_OK)
  76462. + ret = tempRet;
  76463. + }
  76464. +
  76465. + /* Read dummy bytes before real data. */
  76466. + while(dummyBytesToRead)
  76467. + {
  76468. + mvSpiRead(&dummyByte,1);
  76469. + dummyBytesToRead--;
  76470. + }
  76471. +
  76472. + /* Then write the data buffer */
  76473. + if ((rxDataSize) && (pRxDataBuff != NULL))
  76474. + {
  76475. + if ((tempRet = mvSpiRead(pRxDataBuff, rxDataSize)) != MV_OK)
  76476. + ret = tempRet;
  76477. + }
  76478. +
  76479. + /* Finally deassert the chip select */
  76480. + mvSpiCsDeassert();
  76481. +
  76482. + return ret;
  76483. +}
  76484. +
  76485. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h
  76486. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h 1970-01-01 01:00:00.000000000 +0100
  76487. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h 2010-08-05 22:02:25.623680645 +0200
  76488. @@ -0,0 +1,82 @@
  76489. +/*******************************************************************************
  76490. +Copyright (C) Marvell International Ltd. and its affiliates
  76491. +
  76492. +This software file (the "File") is owned and distributed by Marvell
  76493. +International Ltd. and/or its affiliates ("Marvell") under the following
  76494. +alternative licensing terms. Once you have made an election to distribute the
  76495. +File under one of the following license alternatives, please (i) delete this
  76496. +introductory statement regarding license alternatives, (ii) delete the two
  76497. +license alternatives that you have not elected to use and (iii) preserve the
  76498. +Marvell copyright notice above.
  76499. +
  76500. +********************************************************************************
  76501. +Marvell Commercial License Option
  76502. +
  76503. +If you received this File from Marvell and you have entered into a commercial
  76504. +license agreement (a "Commercial License") with Marvell, the File is licensed
  76505. +to you under the terms of the applicable Commercial License.
  76506. +
  76507. +********************************************************************************
  76508. +Marvell GPL License Option
  76509. +
  76510. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76511. +modify this File in accordance with the terms and conditions of the General
  76512. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  76513. +available along with the File in the license.txt file or by writing to the Free
  76514. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  76515. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  76516. +
  76517. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  76518. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  76519. +DISCLAIMED. The GPL License provides additional details about this warranty
  76520. +disclaimer.
  76521. +********************************************************************************
  76522. +Marvell BSD License Option
  76523. +
  76524. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76525. +modify this File under the following licensing terms.
  76526. +Redistribution and use in source and binary forms, with or without modification,
  76527. +are permitted provided that the following conditions are met:
  76528. +
  76529. + * Redistributions of source code must retain the above copyright notice,
  76530. + this list of conditions and the following disclaimer.
  76531. +
  76532. + * Redistributions in binary form must reproduce the above copyright
  76533. + notice, this list of conditions and the following disclaimer in the
  76534. + documentation and/or other materials provided with the distribution.
  76535. +
  76536. + * Neither the name of Marvell nor the names of its contributors may be
  76537. + used to endorse or promote products derived from this software without
  76538. + specific prior written permission.
  76539. +
  76540. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  76541. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  76542. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  76543. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  76544. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  76545. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  76546. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  76547. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  76548. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  76549. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  76550. +
  76551. +*******************************************************************************/
  76552. +
  76553. +#ifndef __INCmvSpiCmndhH
  76554. +#define __INCmvSpiCmndhH
  76555. +
  76556. +#include "mvTypes.h"
  76557. +
  76558. +/* Function Prototypes */
  76559. +
  76560. +/* Simultanuous Read and write */
  76561. +MV_STATUS mvSpiReadAndWrite (MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize);
  76562. +
  76563. +/* write command - write a command and then write data */
  76564. +MV_STATUS mvSpiWriteThenWrite (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pTxDataBuff, MV_U32 txDataSize);
  76565. +
  76566. +/* read command - write a command and then read data by writing dummy data */
  76567. +MV_STATUS mvSpiWriteThenRead (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pRxDataBuff,
  76568. + MV_U32 rxDataSize,MV_U32 dummyBytesToRead);
  76569. +
  76570. +#endif /* __INCmvSpiCmndhH */
  76571. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h
  76572. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h 1970-01-01 01:00:00.000000000 +0100
  76573. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h 2010-08-05 22:02:25.664867995 +0200
  76574. @@ -0,0 +1,94 @@
  76575. +/*******************************************************************************
  76576. +Copyright (C) Marvell International Ltd. and its affiliates
  76577. +
  76578. +This software file (the "File") is owned and distributed by Marvell
  76579. +International Ltd. and/or its affiliates ("Marvell") under the following
  76580. +alternative licensing terms. Once you have made an election to distribute the
  76581. +File under one of the following license alternatives, please (i) delete this
  76582. +introductory statement regarding license alternatives, (ii) delete the two
  76583. +license alternatives that you have not elected to use and (iii) preserve the
  76584. +Marvell copyright notice above.
  76585. +
  76586. +********************************************************************************
  76587. +Marvell Commercial License Option
  76588. +
  76589. +If you received this File from Marvell and you have entered into a commercial
  76590. +license agreement (a "Commercial License") with Marvell, the File is licensed
  76591. +to you under the terms of the applicable Commercial License.
  76592. +
  76593. +********************************************************************************
  76594. +Marvell GPL License Option
  76595. +
  76596. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76597. +modify this File in accordance with the terms and conditions of the General
  76598. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  76599. +available along with the File in the license.txt file or by writing to the Free
  76600. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  76601. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  76602. +
  76603. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  76604. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  76605. +DISCLAIMED. The GPL License provides additional details about this warranty
  76606. +disclaimer.
  76607. +********************************************************************************
  76608. +Marvell BSD License Option
  76609. +
  76610. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76611. +modify this File under the following licensing terms.
  76612. +Redistribution and use in source and binary forms, with or without modification,
  76613. +are permitted provided that the following conditions are met:
  76614. +
  76615. + * Redistributions of source code must retain the above copyright notice,
  76616. + this list of conditions and the following disclaimer.
  76617. +
  76618. + * Redistributions in binary form must reproduce the above copyright
  76619. + notice, this list of conditions and the following disclaimer in the
  76620. + documentation and/or other materials provided with the distribution.
  76621. +
  76622. + * Neither the name of Marvell nor the names of its contributors may be
  76623. + used to endorse or promote products derived from this software without
  76624. + specific prior written permission.
  76625. +
  76626. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  76627. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  76628. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  76629. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  76630. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  76631. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  76632. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  76633. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  76634. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  76635. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  76636. +
  76637. +*******************************************************************************/
  76638. +
  76639. +#ifndef __INCmvSpihH
  76640. +#define __INCmvSpihH
  76641. +
  76642. +#include "mvCommon.h"
  76643. +#include "mvOs.h"
  76644. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  76645. +
  76646. +/* Function Prototypes */
  76647. +/* Init */
  76648. +MV_STATUS mvSpiInit (MV_U32 serialBaudRate);
  76649. +
  76650. +/* Set the Frequency of the Spi clock */
  76651. +MV_STATUS mvSpiBaudRateSet(MV_U32 serialBaudRate);
  76652. +
  76653. +/* Assert the SPI chip select */
  76654. +MV_VOID mvSpiCsAssert (MV_VOID);
  76655. +
  76656. +/* De-assert the SPI chip select */
  76657. +MV_VOID mvSpiCsDeassert (MV_VOID);
  76658. +
  76659. +/* Simultanuous Read and write */
  76660. +MV_STATUS mvSpiReadWrite (MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize);
  76661. +
  76662. +/* serialize a buffer on the TX line - Rx is ignored */
  76663. +MV_STATUS mvSpiWrite (MV_U8* pTxBuff, MV_U32 buffSize);
  76664. +
  76665. +/* read from the RX line by writing dummy values to the TX line */
  76666. +MV_STATUS mvSpiRead (MV_U8* pRxBuff, MV_U32 buffSize);
  76667. +
  76668. +#endif /* __INCmvSpihH */
  76669. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h
  76670. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h 1970-01-01 01:00:00.000000000 +0100
  76671. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h 2010-08-05 22:02:25.704868395 +0200
  76672. @@ -0,0 +1,98 @@
  76673. +/*******************************************************************************
  76674. +Copyright (C) Marvell International Ltd. and its affiliates
  76675. +
  76676. +This software file (the "File") is owned and distributed by Marvell
  76677. +International Ltd. and/or its affiliates ("Marvell") under the following
  76678. +alternative licensing terms. Once you have made an election to distribute the
  76679. +File under one of the following license alternatives, please (i) delete this
  76680. +introductory statement regarding license alternatives, (ii) delete the two
  76681. +license alternatives that you have not elected to use and (iii) preserve the
  76682. +Marvell copyright notice above.
  76683. +
  76684. +********************************************************************************
  76685. +Marvell Commercial License Option
  76686. +
  76687. +If you received this File from Marvell and you have entered into a commercial
  76688. +license agreement (a "Commercial License") with Marvell, the File is licensed
  76689. +to you under the terms of the applicable Commercial License.
  76690. +
  76691. +********************************************************************************
  76692. +Marvell GPL License Option
  76693. +
  76694. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76695. +modify this File in accordance with the terms and conditions of the General
  76696. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  76697. +available along with the File in the license.txt file or by writing to the Free
  76698. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  76699. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  76700. +
  76701. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  76702. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  76703. +DISCLAIMED. The GPL License provides additional details about this warranty
  76704. +disclaimer.
  76705. +********************************************************************************
  76706. +Marvell BSD License Option
  76707. +
  76708. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76709. +modify this File under the following licensing terms.
  76710. +Redistribution and use in source and binary forms, with or without modification,
  76711. +are permitted provided that the following conditions are met:
  76712. +
  76713. + * Redistributions of source code must retain the above copyright notice,
  76714. + this list of conditions and the following disclaimer.
  76715. +
  76716. + * Redistributions in binary form must reproduce the above copyright
  76717. + notice, this list of conditions and the following disclaimer in the
  76718. + documentation and/or other materials provided with the distribution.
  76719. +
  76720. + * Neither the name of Marvell nor the names of its contributors may be
  76721. + used to endorse or promote products derived from this software without
  76722. + specific prior written permission.
  76723. +
  76724. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  76725. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  76726. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  76727. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  76728. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  76729. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  76730. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  76731. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  76732. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  76733. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  76734. +
  76735. +*******************************************************************************/
  76736. +
  76737. +#ifndef __INCmvSpiSpecH
  76738. +#define __INCmvSpiSpecH
  76739. +
  76740. +/* Constants */
  76741. +#define MV_SPI_WAIT_RDY_MAX_LOOP 100000
  76742. +#define MV_SPI_16_BIT_CHUNK_SIZE 2
  76743. +#define MV_SPI_DUMMY_WRITE_16BITS 0xFFFF
  76744. +#define MV_SPI_DUMMY_WRITE_8BITS 0xFF
  76745. +
  76746. +/* Marvell Flash Device Controller Registers */
  76747. +#define MV_SPI_CTRLR_OFST 0x10600
  76748. +#define MV_SPI_IF_CTRL_REG (MV_SPI_CTRLR_OFST + 0x00)
  76749. +#define MV_SPI_IF_CONFIG_REG (MV_SPI_CTRLR_OFST + 0x04)
  76750. +#define MV_SPI_DATA_OUT_REG (MV_SPI_CTRLR_OFST + 0x08)
  76751. +#define MV_SPI_DATA_IN_REG (MV_SPI_CTRLR_OFST + 0x0c)
  76752. +#define MV_SPI_INT_CAUSE_REG (MV_SPI_CTRLR_OFST + 0x10)
  76753. +#define MV_SPI_INT_CAUSE_MASK_REG (MV_SPI_CTRLR_OFST + 0x14)
  76754. +
  76755. +/* Serial Memory Interface Control Register Masks */
  76756. +#define MV_SPI_CS_ENABLE_OFFSET 0 /* bit 0 */
  76757. +#define MV_SPI_MEMORY_READY_OFFSET 1 /* bit 1 */
  76758. +#define MV_SPI_CS_ENABLE_MASK (0x1 << MV_SPI_CS_ENABLE_OFFSET)
  76759. +#define MV_SPI_MEMORY_READY_MASK (0x1 << MV_SPI_MEMORY_READY_OFFSET)
  76760. +
  76761. +/* Serial Memory Interface Configuration Register Masks */
  76762. +#define MV_SPI_CLK_PRESCALE_OFFSET 0 /* bit 0-4 */
  76763. +#define MV_SPI_BYTE_LENGTH_OFFSET 5 /* bit 5 */
  76764. +#define MV_SPI_ADDRESS_BURST_LENGTH_OFFSET 8 /* bit 8-9 */
  76765. +#define MV_SPI_CLK_PRESCALE_MASK (0x1F << MV_SPI_CLK_PRESCALE_OFFSET)
  76766. +#define MV_SPI_BYTE_LENGTH_MASK (0x1 << MV_SPI_BYTE_LENGTH_OFFSET)
  76767. +#define MV_SPI_ADDRESS_BURST_LENGTH_MASK (0x3 << MV_SPI_ADDRESS_BURST_LENGTH_OFFSET)
  76768. +
  76769. +#endif /* __INCmvSpiSpecH */
  76770. +
  76771. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c
  76772. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c 1970-01-01 01:00:00.000000000 +0100
  76773. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c 2010-08-05 22:02:25.733688516 +0200
  76774. @@ -0,0 +1,1023 @@
  76775. +/*******************************************************************************
  76776. +Copyright (C) Marvell International Ltd. and its affiliates
  76777. +
  76778. +This software file (the "File") is owned and distributed by Marvell
  76779. +International Ltd. and/or its affiliates ("Marvell") under the following
  76780. +alternative licensing terms. Once you have made an election to distribute the
  76781. +File under one of the following license alternatives, please (i) delete this
  76782. +introductory statement regarding license alternatives, (ii) delete the two
  76783. +license alternatives that you have not elected to use and (iii) preserve the
  76784. +Marvell copyright notice above.
  76785. +
  76786. +********************************************************************************
  76787. +Marvell Commercial License Option
  76788. +
  76789. +If you received this File from Marvell and you have entered into a commercial
  76790. +license agreement (a "Commercial License") with Marvell, the File is licensed
  76791. +to you under the terms of the applicable Commercial License.
  76792. +
  76793. +********************************************************************************
  76794. +Marvell GPL License Option
  76795. +
  76796. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76797. +modify this File in accordance with the terms and conditions of the General
  76798. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  76799. +available along with the File in the license.txt file or by writing to the Free
  76800. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  76801. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  76802. +
  76803. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  76804. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  76805. +DISCLAIMED. The GPL License provides additional details about this warranty
  76806. +disclaimer.
  76807. +********************************************************************************
  76808. +Marvell BSD License Option
  76809. +
  76810. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76811. +modify this File under the following licensing terms.
  76812. +Redistribution and use in source and binary forms, with or without modification,
  76813. +are permitted provided that the following conditions are met:
  76814. +
  76815. + * Redistributions of source code must retain the above copyright notice,
  76816. + this list of conditions and the following disclaimer.
  76817. +
  76818. + * Redistributions in binary form must reproduce the above copyright
  76819. + notice, this list of conditions and the following disclaimer in the
  76820. + documentation and/or other materials provided with the distribution.
  76821. +
  76822. + * Neither the name of Marvell nor the names of its contributors may be
  76823. + used to endorse or promote products derived from this software without
  76824. + specific prior written permission.
  76825. +
  76826. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  76827. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  76828. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  76829. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  76830. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  76831. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  76832. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  76833. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  76834. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  76835. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  76836. +
  76837. +*******************************************************************************/
  76838. +
  76839. +
  76840. +#include "mvTwsi.h"
  76841. +#include "mvTwsiSpec.h"
  76842. +#include "cpu/mvCpu.h"
  76843. +
  76844. +
  76845. +/*#define MV_DEBUG*/
  76846. +#ifdef MV_DEBUG
  76847. +#define DB(x) x
  76848. +#else
  76849. +#define DB(x)
  76850. +#endif
  76851. +
  76852. +static MV_VOID twsiIntFlgClr(MV_U8 chanNum);
  76853. +static MV_BOOL twsiMainIntGet(MV_U8 chanNum);
  76854. +static MV_VOID twsiAckBitSet(MV_U8 chanNum);
  76855. +static MV_U32 twsiStsGet(MV_U8 chanNum);
  76856. +static MV_VOID twsiReset(MV_U8 chanNum);
  76857. +static MV_STATUS twsiAddr7BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command);
  76858. +static MV_STATUS twsiAddr10BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command);
  76859. +static MV_STATUS twsiDataTransmit(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize);
  76860. +static MV_STATUS twsiDataReceive(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize);
  76861. +static MV_STATUS twsiTargetOffsSet(MV_U8 chanNum, MV_U32 offset,MV_BOOL moreThen256);
  76862. +
  76863. +
  76864. +static MV_BOOL twsiTimeoutChk(MV_U32 timeout, const MV_8 *pString)
  76865. +{
  76866. + if(timeout >= TWSI_TIMEOUT_VALUE)
  76867. + {
  76868. + DB(mvOsPrintf("%s",pString));
  76869. + return MV_TRUE;
  76870. + }
  76871. + return MV_FALSE;
  76872. +
  76873. +}
  76874. +/*******************************************************************************
  76875. +* mvTwsiStartBitSet - Set start bit on the bus
  76876. +*
  76877. +* DESCRIPTION:
  76878. +* This routine sets the start bit on the TWSI bus.
  76879. +* The routine first checks for interrupt flag condition, then it sets
  76880. +* the start bit in the TWSI Control register.
  76881. +* If the interrupt flag condition check previously was set, the function
  76882. +* will clear it.
  76883. +* The function then wait for the start bit to be cleared by the HW.
  76884. +* Then it waits for the interrupt flag to be set and eventually, the
  76885. +* TWSI status is checked to be 0x8 or 0x10(repeated start bit).
  76886. +*
  76887. +* INPUT:
  76888. +* chanNum - TWSI channel.
  76889. +*
  76890. +* OUTPUT:
  76891. +* None.
  76892. +*
  76893. +* RETURN:
  76894. +* MV_OK is start bit was set successfuly on the bus.
  76895. +* MV_FAIL if interrupt flag was set before setting start bit.
  76896. +*
  76897. +*******************************************************************************/
  76898. +MV_STATUS mvTwsiStartBitSet(MV_U8 chanNum)
  76899. +{
  76900. + MV_BOOL isIntFlag = MV_FALSE;
  76901. + MV_U32 timeout, temp;
  76902. +
  76903. + DB(mvOsPrintf("TWSI: mvTwsiStartBitSet \n"));
  76904. + /* check Int flag */
  76905. + if(twsiMainIntGet(chanNum))
  76906. + isIntFlag = MV_TRUE;
  76907. + /* set start Bit */
  76908. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  76909. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_START_BIT);
  76910. +
  76911. + /* in case that the int flag was set before i.e. repeated start bit */
  76912. + if(isIntFlag){
  76913. + DB(mvOsPrintf("TWSI: mvTwsiStartBitSet repeated start Bit\n"));
  76914. + twsiIntFlgClr(chanNum);
  76915. + }
  76916. +
  76917. + /* wait for interrupt */
  76918. + timeout = 0;
  76919. + while(!twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  76920. +
  76921. + /* check for timeout */
  76922. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: mvTwsiStartBitSet ERROR - Start Clear bit TimeOut .\n"))
  76923. + return MV_TIMEOUT;
  76924. +
  76925. +
  76926. + /* check that start bit went down */
  76927. + if((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_START_BIT) != 0)
  76928. + {
  76929. + mvOsPrintf("TWSI: mvTwsiStartBitSet ERROR - start bit didn't went down\n");
  76930. + return MV_FAIL;
  76931. + }
  76932. +
  76933. + /* check the status */
  76934. + temp = twsiStsGet(chanNum);
  76935. + if(( temp != TWSI_START_CON_TRA ) && ( temp != TWSI_REPEATED_START_CON_TRA ))
  76936. + {
  76937. + mvOsPrintf("TWSI: mvTwsiStartBitSet ERROR - status %x after Set Start Bit. \n",temp);
  76938. + return MV_FAIL;
  76939. + }
  76940. +
  76941. + return MV_OK;
  76942. +
  76943. +}
  76944. +
  76945. +/*******************************************************************************
  76946. +* mvTwsiStopBitSet - Set stop bit on the bus
  76947. +*
  76948. +* DESCRIPTION:
  76949. +* This routine set the stop bit on the TWSI bus.
  76950. +* The function then wait for the stop bit to be cleared by the HW.
  76951. +* Finally the function checks for status of 0xF8.
  76952. +*
  76953. +* INPUT:
  76954. +* chanNum - TWSI channel
  76955. +*
  76956. +* OUTPUT:
  76957. +* None.
  76958. +*
  76959. +* RETURN:
  76960. +* MV_TRUE is stop bit was set successfuly on the bus.
  76961. +*
  76962. +*******************************************************************************/
  76963. +MV_STATUS mvTwsiStopBitSet(MV_U8 chanNum)
  76964. +{
  76965. + MV_U32 timeout, temp;
  76966. +
  76967. + /* Generate stop bit */
  76968. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  76969. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_STOP_BIT);
  76970. +
  76971. + twsiIntFlgClr(chanNum);
  76972. +
  76973. + /* wait for stop bit to come down */
  76974. + timeout = 0;
  76975. + while( ((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_STOP_BIT) != 0) && (timeout++ < TWSI_TIMEOUT_VALUE));
  76976. +
  76977. + /* check for timeout */
  76978. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: mvTwsiStopBitSet ERROR - Stop bit TimeOut .\n"))
  76979. + return MV_TIMEOUT;
  76980. +
  76981. + /* check that the stop bit went down */
  76982. + if((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_STOP_BIT) != 0)
  76983. + {
  76984. + mvOsPrintf("TWSI: mvTwsiStopBitSet ERROR - stop bit didn't went down. \n");
  76985. + return MV_FAIL;
  76986. + }
  76987. +
  76988. + /* check the status */
  76989. + temp = twsiStsGet(chanNum);
  76990. + if( temp != TWSI_NO_REL_STS_INT_FLAG_IS_KEPT_0){
  76991. + mvOsPrintf("TWSI: mvTwsiStopBitSet ERROR - status %x after Stop Bit. \n", temp);
  76992. + return MV_FAIL;
  76993. + }
  76994. +
  76995. + return MV_OK;
  76996. +}
  76997. +
  76998. +/*******************************************************************************
  76999. +* twsiMainIntGet - Get twsi bit from main Interrupt cause.
  77000. +*
  77001. +* DESCRIPTION:
  77002. +* This routine returns the twsi interrupt flag value.
  77003. +*
  77004. +* INPUT:
  77005. +* None.
  77006. +*
  77007. +* OUTPUT:
  77008. +* None.
  77009. +*
  77010. +* RETURN:
  77011. +* MV_TRUE is interrupt flag is set, MV_FALSE otherwise.
  77012. +*
  77013. +*******************************************************************************/
  77014. +static MV_BOOL twsiMainIntGet(MV_U8 chanNum)
  77015. +{
  77016. + MV_U32 temp;
  77017. +
  77018. + /* get the int flag bit */
  77019. +
  77020. + temp = MV_REG_READ(TWSI_CPU_MAIN_INT_CAUSE_REG);
  77021. + if (temp & (TWSI0_CPU_MAIN_INT_BIT << chanNum))
  77022. + return MV_TRUE;
  77023. +
  77024. + return MV_FALSE;
  77025. +}
  77026. +/*******************************************************************************
  77027. +* twsiIntFlgClr - Clear Interrupt flag.
  77028. +*
  77029. +* DESCRIPTION:
  77030. +* This routine clears the interrupt flag. It does NOT poll the interrupt
  77031. +* to make sure the clear. After clearing the interrupt, it waits for at
  77032. +* least 1 miliseconds.
  77033. +*
  77034. +* INPUT:
  77035. +* chanNum - TWSI channel
  77036. +*
  77037. +* OUTPUT:
  77038. +* None.
  77039. +*
  77040. +* RETURN:
  77041. +* None.
  77042. +*
  77043. +*******************************************************************************/
  77044. +static MV_VOID twsiIntFlgClr(MV_U8 chanNum)
  77045. +{
  77046. + MV_U32 temp;
  77047. +
  77048. + /* wait for 1 mili to prevent TWSI register write after write problems */
  77049. + mvOsDelay(1);
  77050. + /* clear the int flag bit */
  77051. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  77052. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum),temp & ~(TWSI_CONTROL_INT_FLAG_SET));
  77053. +
  77054. + /* wait for 1 mili sec for the clear to take effect */
  77055. + mvOsDelay(1);
  77056. +
  77057. + return;
  77058. +}
  77059. +
  77060. +
  77061. +/*******************************************************************************
  77062. +* twsiAckBitSet - Set acknowledge bit on the bus
  77063. +*
  77064. +* DESCRIPTION:
  77065. +* This routine set the acknowledge bit on the TWSI bus.
  77066. +*
  77067. +* INPUT:
  77068. +* None.
  77069. +*
  77070. +* OUTPUT:
  77071. +* None.
  77072. +*
  77073. +* RETURN:
  77074. +* None.
  77075. +*
  77076. +*******************************************************************************/
  77077. +static MV_VOID twsiAckBitSet(MV_U8 chanNum)
  77078. +{
  77079. + MV_U32 temp;
  77080. +
  77081. + /*Set the Ack bit */
  77082. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  77083. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_ACK);
  77084. +
  77085. + /* Add delay of 1ms */
  77086. + mvOsDelay(1);
  77087. + return;
  77088. +}
  77089. +
  77090. +
  77091. +/*******************************************************************************
  77092. +* twsiInit - Initialize TWSI interface
  77093. +*
  77094. +* DESCRIPTION:
  77095. +* This routine:
  77096. +* -Reset the TWSI.
  77097. +* -Initialize the TWSI clock baud rate according to given frequancy
  77098. +* parameter based on Tclk frequancy and enables TWSI slave.
  77099. +* -Set the ack bit.
  77100. +* -Assign the TWSI slave address according to the TWSI address Type.
  77101. +*
  77102. +*
  77103. +* INPUT:
  77104. +* chanNum - TWSI channel
  77105. +* frequancy - TWSI frequancy in KHz. (up to 100KHZ)
  77106. +*
  77107. +* OUTPUT:
  77108. +* None.
  77109. +*
  77110. +* RETURN:
  77111. +* Actual frequancy.
  77112. +*
  77113. +*******************************************************************************/
  77114. +MV_U32 mvTwsiInit(MV_U8 chanNum, MV_HZ frequancy, MV_U32 Tclk, MV_TWSI_ADDR *pTwsiAddr, MV_BOOL generalCallEnable)
  77115. +{
  77116. + MV_U32 n,m,freq,margin,minMargin = 0xffffffff;
  77117. + MV_U32 power;
  77118. + MV_U32 actualFreq = 0,actualN = 0,actualM = 0,val;
  77119. +
  77120. + if(frequancy > 100000)
  77121. + {
  77122. + mvOsPrintf("Warning TWSI frequancy is too high, please use up tp 100Khz. \n");
  77123. + }
  77124. +
  77125. + DB(mvOsPrintf("TWSI: mvTwsiInit - Tclk = %d freq = %d\n",Tclk,frequancy));
  77126. + /* Calucalte N and M for the TWSI clock baud rate */
  77127. + for(n = 0 ; n < 8 ; n++)
  77128. + {
  77129. + for(m = 0 ; m < 16 ; m++)
  77130. + {
  77131. + power = 2 << n; /* power = 2^(n+1) */
  77132. + freq = Tclk/(10*(m+1)*power);
  77133. + margin = MV_ABS(frequancy - freq);
  77134. + if(margin < minMargin)
  77135. + {
  77136. + minMargin = margin;
  77137. + actualFreq = freq;
  77138. + actualN = n;
  77139. + actualM = m;
  77140. + }
  77141. + }
  77142. + }
  77143. + DB(mvOsPrintf("TWSI: mvTwsiInit - actN %d actM %d actFreq %d\n",actualN , actualM, actualFreq));
  77144. + /* Reset the TWSI logic */
  77145. + twsiReset(chanNum);
  77146. +
  77147. + /* Set the baud rate */
  77148. + val = ((actualM<< TWSI_BAUD_RATE_M_OFFS) | actualN << TWSI_BAUD_RATE_N_OFFS);
  77149. + MV_REG_WRITE(TWSI_STATUS_BAUDE_RATE_REG(chanNum),val);
  77150. +
  77151. + /* Enable the TWSI and slave */
  77152. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), TWSI_CONTROL_ENA | TWSI_CONTROL_ACK);
  77153. +
  77154. + /* set the TWSI slave address */
  77155. + if( pTwsiAddr->type == ADDR10_BIT )/* 10 Bit deviceAddress */
  77156. + {
  77157. + /* writing the 2 most significant bits of the 10 bit address*/
  77158. + val = ((pTwsiAddr->address & TWSI_SLAVE_ADDR_10BIT_MASK) >> TWSI_SLAVE_ADDR_10BIT_OFFS );
  77159. + /* bits 7:3 must be 0x11110 */
  77160. + val |= TWSI_SLAVE_ADDR_10BIT_CONST;
  77161. + /* set GCE bit */
  77162. + if(generalCallEnable)
  77163. + val |= TWSI_SLAVE_ADDR_GCE_ENA;
  77164. + /* write slave address */
  77165. + MV_REG_WRITE(TWSI_SLAVE_ADDR_REG(chanNum),val);
  77166. +
  77167. + /* writing the 8 least significant bits of the 10 bit address*/
  77168. + val = (pTwsiAddr->address << TWSI_EXTENDED_SLAVE_OFFS) & TWSI_EXTENDED_SLAVE_MASK;
  77169. + MV_REG_WRITE(TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum), val);
  77170. + }
  77171. + else /*7 bit address*/
  77172. + {
  77173. + /* set the 7 Bits address */
  77174. + MV_REG_WRITE(TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum),0x0);
  77175. + val = (pTwsiAddr->address << TWSI_SLAVE_ADDR_7BIT_OFFS) & TWSI_SLAVE_ADDR_7BIT_MASK;
  77176. + MV_REG_WRITE(TWSI_SLAVE_ADDR_REG(chanNum), val);
  77177. + }
  77178. +
  77179. + /* unmask twsi int */
  77180. + val = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  77181. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), val | TWSI_CONTROL_INT_ENA);
  77182. + /* Add delay of 1ms */
  77183. + mvOsDelay(1);
  77184. +
  77185. + return actualFreq;
  77186. +}
  77187. +
  77188. +
  77189. +/*******************************************************************************
  77190. +* twsiStsGet - Get the TWSI status value.
  77191. +*
  77192. +* DESCRIPTION:
  77193. +* This routine returns the TWSI status value.
  77194. +*
  77195. +* INPUT:
  77196. +* chanNum - TWSI channel
  77197. +*
  77198. +* OUTPUT:
  77199. +* None.
  77200. +*
  77201. +* RETURN:
  77202. +* MV_U32 - the TWSI status.
  77203. +*
  77204. +*******************************************************************************/
  77205. +static MV_U32 twsiStsGet(MV_U8 chanNum)
  77206. +{
  77207. + return MV_REG_READ(TWSI_STATUS_BAUDE_RATE_REG(chanNum));
  77208. +
  77209. +}
  77210. +
  77211. +/*******************************************************************************
  77212. +* twsiReset - Reset the TWSI.
  77213. +*
  77214. +* DESCRIPTION:
  77215. +* Resets the TWSI logic and sets all TWSI registers to their reset values.
  77216. +*
  77217. +* INPUT:
  77218. +* chanNum - TWSI channel
  77219. +*
  77220. +* OUTPUT:
  77221. +* None.
  77222. +*
  77223. +* RETURN:
  77224. +* None
  77225. +*
  77226. +*******************************************************************************/
  77227. +static MV_VOID twsiReset(MV_U8 chanNum)
  77228. +{
  77229. + /* Reset the TWSI logic */
  77230. + MV_REG_WRITE(TWSI_SOFT_RESET_REG(chanNum),0);
  77231. +
  77232. + /* wait for 2 mili sec */
  77233. + mvOsDelay(2);
  77234. +
  77235. + return;
  77236. +}
  77237. +
  77238. +
  77239. +
  77240. +
  77241. +/******************************* POLICY ****************************************/
  77242. +
  77243. +
  77244. +
  77245. +/*******************************************************************************
  77246. +* mvTwsiAddrSet - Set address on TWSI bus.
  77247. +*
  77248. +* DESCRIPTION:
  77249. +* This function Set address (7 or 10 Bit address) on the Twsi Bus.
  77250. +*
  77251. +* INPUT:
  77252. +* chanNum - TWSI channel
  77253. +* pTwsiAddr - twsi address.
  77254. +* command - read / write .
  77255. +*
  77256. +* OUTPUT:
  77257. +* None.
  77258. +*
  77259. +* RETURN:
  77260. +* MV_OK - if setting the address completed succesfully.
  77261. +* MV_FAIL otherwmise.
  77262. +*
  77263. +*******************************************************************************/
  77264. +MV_STATUS mvTwsiAddrSet(MV_U8 chanNum, MV_TWSI_ADDR *pTwsiAddr, MV_TWSI_CMD command)
  77265. +{
  77266. + DB(mvOsPrintf("TWSI: mvTwsiAddr7BitSet addr %x , type %d, cmd is %s\n",pTwsiAddr->address,\
  77267. + pTwsiAddr->type, ((command==MV_TWSI_WRITE)?"Write":"Read") ));
  77268. + /* 10 Bit address */
  77269. + if(pTwsiAddr->type == ADDR10_BIT)
  77270. + {
  77271. + return twsiAddr10BitSet(chanNum, pTwsiAddr->address,command);
  77272. + }
  77273. + /* 7 Bit address */
  77274. + else
  77275. + {
  77276. + return twsiAddr7BitSet(chanNum, pTwsiAddr->address,command);
  77277. + }
  77278. +
  77279. +}
  77280. +
  77281. +/*******************************************************************************
  77282. +* twsiAddr10BitSet - Set 10 Bit address on TWSI bus.
  77283. +*
  77284. +* DESCRIPTION:
  77285. +* There are two address phases:
  77286. +* 1) Write '11110' to data register bits [7:3] and 10-bit address MSB
  77287. +* (bits [9:8]) to data register bits [2:1] plus a write(0) or read(1) bit
  77288. +* to the Data register. Then it clears interrupt flag which drive
  77289. +* the address on the TWSI bus. The function then waits for interrupt
  77290. +* flag to be active and status 0x18 (write) or 0x40 (read) to be set.
  77291. +* 2) write the rest of 10-bit address to data register and clears
  77292. +* interrupt flag which drive the address on the TWSI bus. The
  77293. +* function then waits for interrupt flag to be active and status
  77294. +* 0xD0 (write) or 0xE0 (read) to be set.
  77295. +*
  77296. +* INPUT:
  77297. +* chanNum - TWSI channel
  77298. +* deviceAddress - twsi address.
  77299. +* command - read / write .
  77300. +*
  77301. +* OUTPUT:
  77302. +* None.
  77303. +*
  77304. +* RETURN:
  77305. +* MV_OK - if setting the address completed succesfully.
  77306. +* MV_FAIL otherwmise.
  77307. +*
  77308. +*******************************************************************************/
  77309. +static MV_STATUS twsiAddr10BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command)
  77310. +{
  77311. + MV_U32 val,timeout;
  77312. +
  77313. + /* writing the 2 most significant bits of the 10 bit address*/
  77314. + val = ((deviceAddress & TWSI_DATA_ADDR_10BIT_MASK) >> TWSI_DATA_ADDR_10BIT_OFFS );
  77315. + /* bits 7:3 must be 0x11110 */
  77316. + val |= TWSI_DATA_ADDR_10BIT_CONST;
  77317. + /* set command */
  77318. + val |= command;
  77319. + MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);
  77320. + /* WA add a delay */
  77321. + mvOsDelay(1);
  77322. +
  77323. + /* clear Int flag */
  77324. + twsiIntFlgClr(chanNum);
  77325. +
  77326. + /* wait for Int to be Set */
  77327. + timeout = 0;
  77328. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  77329. +
  77330. + /* check for timeout */
  77331. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr10BitSet ERROR - 1st addr (10Bit) Int TimeOut.\n"))
  77332. + return MV_TIMEOUT;
  77333. +
  77334. + /* check the status */
  77335. + val = twsiStsGet(chanNum);
  77336. + if(( (val != TWSI_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) ||
  77337. + ( (val != TWSI_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))
  77338. + {
  77339. + mvOsPrintf("TWSI: twsiAddr10BitSet ERROR - status %x 1st addr (10 Bit) in %s mode.\n"\
  77340. + ,val, ((command==MV_TWSI_WRITE)?"Write":"Read") );
  77341. + return MV_FAIL;
  77342. + }
  77343. +
  77344. + /* set 8 LSB of the address */
  77345. + val = (deviceAddress << TWSI_DATA_ADDR_7BIT_OFFS) & TWSI_DATA_ADDR_7BIT_MASK;
  77346. + MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);
  77347. +
  77348. + /* clear Int flag */
  77349. + twsiIntFlgClr(chanNum);
  77350. +
  77351. + /* wait for Int to be Set */
  77352. + timeout = 0;
  77353. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  77354. +
  77355. + /* check for timeout */
  77356. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr10BitSet ERROR - 2nd (10 Bit) Int TimOut.\n"))
  77357. + return MV_TIMEOUT;
  77358. +
  77359. + /* check the status */
  77360. + val = twsiStsGet(chanNum);
  77361. + if(( (val != TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) ||
  77362. + ( (val != TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))
  77363. + {
  77364. + mvOsPrintf("TWSI: twsiAddr10BitSet ERROR - status %x 2nd addr(10 Bit) in %s mode.\n"\
  77365. + ,val, ((command==MV_TWSI_WRITE)?"Write":"Read") );
  77366. + return MV_FAIL;
  77367. + }
  77368. +
  77369. + return MV_OK;
  77370. +}
  77371. +
  77372. +/*******************************************************************************
  77373. +* twsiAddr7BitSet - Set 7 Bit address on TWSI bus.
  77374. +*
  77375. +* DESCRIPTION:
  77376. +* This function writes 7 bit address plus a write or read bit to the
  77377. +* Data register. Then it clears interrupt flag which drive the address on
  77378. +* the TWSI bus. The function then waits for interrupt flag to be active
  77379. +* and status 0x18 (write) or 0x40 (read) to be set.
  77380. +*
  77381. +* INPUT:
  77382. +* chanNum - TWSI channel
  77383. +* deviceAddress - twsi address.
  77384. +* command - read / write .
  77385. +*
  77386. +* OUTPUT:
  77387. +* None.
  77388. +*
  77389. +* RETURN:
  77390. +* MV_OK - if setting the address completed succesfully.
  77391. +* MV_FAIL otherwmise.
  77392. +*
  77393. +*******************************************************************************/
  77394. +static MV_STATUS twsiAddr7BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command)
  77395. +{
  77396. + MV_U32 val,timeout;
  77397. +
  77398. + /* set the address */
  77399. + val = (deviceAddress << TWSI_DATA_ADDR_7BIT_OFFS) & TWSI_DATA_ADDR_7BIT_MASK;
  77400. + /* set command */
  77401. + val |= command;
  77402. + MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);
  77403. + /* WA add a delay */
  77404. + mvOsDelay(1);
  77405. +
  77406. + /* clear Int flag */
  77407. + twsiIntFlgClr(chanNum);
  77408. +
  77409. + /* wait for Int to be Set */
  77410. + timeout = 0;
  77411. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  77412. +
  77413. + /* check for timeout */
  77414. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr7BitSet ERROR - Addr (7 Bit) int TimeOut.\n"))
  77415. + return MV_TIMEOUT;
  77416. +
  77417. + /* check the status */
  77418. + val = twsiStsGet(chanNum);
  77419. + if(( (val != TWSI_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) ||
  77420. + ( (val != TWSI_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))
  77421. + {
  77422. + /* only in debug, since in boot we try to read the SPD of both DRAM, and we don't
  77423. + want error messeges in case DIMM doesn't exist. */
  77424. + DB(mvOsPrintf("TWSI: twsiAddr7BitSet ERROR - status %x addr (7 Bit) in %s mode.\n"\
  77425. + ,val,((command==MV_TWSI_WRITE)?"Write":"Read") ));
  77426. + return MV_FAIL;
  77427. + }
  77428. +
  77429. + return MV_OK;
  77430. +}
  77431. +
  77432. +/*******************************************************************************
  77433. +* twsiDataWrite - Trnasmit a data block over TWSI bus.
  77434. +*
  77435. +* DESCRIPTION:
  77436. +* This function writes a given data block to TWSI bus in 8 bit granularity.
  77437. +* first The function waits for interrupt flag to be active then
  77438. +* For each 8-bit data:
  77439. +* The function writes data to data register. It then clears
  77440. +* interrupt flag which drives the data on the TWSI bus.
  77441. +* The function then waits for interrupt flag to be active and status
  77442. +* 0x28 to be set.
  77443. +*
  77444. +*
  77445. +* INPUT:
  77446. +* chanNum - TWSI channel
  77447. +* pBlock - Data block.
  77448. +* blockSize - number of chars in pBlock.
  77449. +*
  77450. +* OUTPUT:
  77451. +* None.
  77452. +*
  77453. +* RETURN:
  77454. +* MV_OK - if transmiting the block completed succesfully,
  77455. +* MV_BAD_PARAM - if pBlock is NULL,
  77456. +* MV_FAIL otherwmise.
  77457. +*
  77458. +*******************************************************************************/
  77459. +static MV_STATUS twsiDataTransmit(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize)
  77460. +{
  77461. + MV_U32 timeout, temp, blockSizeWr = blockSize;
  77462. +
  77463. + if(NULL == pBlock)
  77464. + return MV_BAD_PARAM;
  77465. +
  77466. + /* wait for Int to be Set */
  77467. + timeout = 0;
  77468. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  77469. +
  77470. + /* check for timeout */
  77471. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataTransmit ERROR - Read Data Int TimeOut.\n"))
  77472. + return MV_TIMEOUT;
  77473. +
  77474. + while(blockSizeWr)
  77475. + {
  77476. + /* write the data*/
  77477. + MV_REG_WRITE(TWSI_DATA_REG(chanNum),(MV_U32)*pBlock);
  77478. + DB(mvOsPrintf("TWSI: twsiDataTransmit place = %d write %x \n",\
  77479. + blockSize - blockSizeWr, *pBlock));
  77480. + pBlock++;
  77481. + blockSizeWr--;
  77482. +
  77483. + twsiIntFlgClr(chanNum);
  77484. +
  77485. + /* wait for Int to be Set */
  77486. + timeout = 0;
  77487. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  77488. +
  77489. + /* check for timeout */
  77490. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataTransmit ERROR - Read Data Int TimeOut.\n"))
  77491. + return MV_TIMEOUT;
  77492. +
  77493. + /* check the status */
  77494. + temp = twsiStsGet(chanNum);
  77495. + if(temp != TWSI_M_TRAN_DATA_BYTE_ACK_REC)
  77496. + {
  77497. + mvOsPrintf("TWSI: twsiDataTransmit ERROR - status %x in write trans\n",temp);
  77498. + return MV_FAIL;
  77499. + }
  77500. +
  77501. + }
  77502. +
  77503. + return MV_OK;
  77504. +}
  77505. +
  77506. +/*******************************************************************************
  77507. +* twsiDataReceive - Receive data block from TWSI bus.
  77508. +*
  77509. +* DESCRIPTION:
  77510. +* This function receive data block from TWSI bus in 8bit granularity
  77511. +* into pBlock buffer.
  77512. +* first The function waits for interrupt flag to be active then
  77513. +* For each 8-bit data:
  77514. +* It clears the interrupt flag which allows the next data to be
  77515. +* received from TWSI bus.
  77516. +* The function waits for interrupt flag to be active,
  77517. +* and status reg is 0x50.
  77518. +* Then the function reads data from data register, and copies it to
  77519. +* the given buffer.
  77520. +*
  77521. +* INPUT:
  77522. +* chanNum - TWSI channel
  77523. +* blockSize - number of bytes to read.
  77524. +*
  77525. +* OUTPUT:
  77526. +* pBlock - Data block.
  77527. +*
  77528. +* RETURN:
  77529. +* MV_OK - if receive transaction completed succesfully,
  77530. +* MV_BAD_PARAM - if pBlock is NULL,
  77531. +* MV_FAIL otherwmise.
  77532. +*
  77533. +*******************************************************************************/
  77534. +static MV_STATUS twsiDataReceive(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize)
  77535. +{
  77536. + MV_U32 timeout, temp, blockSizeRd = blockSize;
  77537. + if(NULL == pBlock)
  77538. + return MV_BAD_PARAM;
  77539. +
  77540. + /* wait for Int to be Set */
  77541. + timeout = 0;
  77542. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  77543. +
  77544. + /* check for timeout */
  77545. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataReceive ERROR - Read Data int Time out .\n"))
  77546. + return MV_TIMEOUT;
  77547. +
  77548. + while(blockSizeRd)
  77549. + {
  77550. + if(blockSizeRd == 1)
  77551. + {
  77552. + /* clear ack and Int flag */
  77553. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  77554. + temp &= ~(TWSI_CONTROL_ACK);
  77555. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp);
  77556. + }
  77557. + twsiIntFlgClr(chanNum);
  77558. + /* wait for Int to be Set */
  77559. + timeout = 0;
  77560. + while( (!twsiMainIntGet(chanNum)) && (timeout++ < TWSI_TIMEOUT_VALUE));
  77561. +
  77562. + /* check for timeout */
  77563. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataReceive ERROR - Read Data Int Time out .\n"))
  77564. + return MV_TIMEOUT;
  77565. +
  77566. + /* check the status */
  77567. + temp = twsiStsGet(chanNum);
  77568. + if((temp != TWSI_M_REC_RD_DATA_ACK_TRA) && (blockSizeRd !=1))
  77569. + {
  77570. + mvOsPrintf("TWSI: twsiDataReceive ERROR - status %x in read trans \n",temp);
  77571. + return MV_FAIL;
  77572. + }
  77573. + else if((temp != TWSI_M_REC_RD_DATA_ACK_NOT_TRA) && (blockSizeRd ==1))
  77574. + {
  77575. + mvOsPrintf("TWSI: twsiDataReceive ERROR - status %x in Rd Terminate\n",temp);
  77576. + return MV_FAIL;
  77577. + }
  77578. +
  77579. + /* read the data*/
  77580. + *pBlock = (MV_U8)MV_REG_READ(TWSI_DATA_REG(chanNum));
  77581. + DB(mvOsPrintf("TWSI: twsiDataReceive place %d read %x \n",\
  77582. + blockSize - blockSizeRd,*pBlock));
  77583. + pBlock++;
  77584. + blockSizeRd--;
  77585. + }
  77586. +
  77587. + return MV_OK;
  77588. +}
  77589. +
  77590. +
  77591. +
  77592. +/*******************************************************************************
  77593. +* twsiTargetOffsSet - Set TWST target offset on TWSI bus.
  77594. +*
  77595. +* DESCRIPTION:
  77596. +* The function support TWSI targets that have inside address space (for
  77597. +* example EEPROMs). The function:
  77598. +* 1) Convert the given offset into pBlock and size.
  77599. +* in case the offset should be set to a TWSI slave which support
  77600. +* more then 256 bytes offset, the offset setting will be done
  77601. +* in 2 transactions.
  77602. +* 2) Use twsiDataTransmit to place those on the bus.
  77603. +*
  77604. +* INPUT:
  77605. +* chanNum - TWSI channel
  77606. +* offset - offset to be set on the EEPROM device.
  77607. +* moreThen256 - whether the EEPROM device support more then 256 byte offset.
  77608. +*
  77609. +* OUTPUT:
  77610. +* None.
  77611. +*
  77612. +* RETURN:
  77613. +* MV_OK - if setting the offset completed succesfully.
  77614. +* MV_FAIL otherwmise.
  77615. +*
  77616. +*******************************************************************************/
  77617. +static MV_STATUS twsiTargetOffsSet(MV_U8 chanNum, MV_U32 offset, MV_BOOL moreThen256)
  77618. +{
  77619. + MV_U8 offBlock[2];
  77620. + MV_U32 offSize;
  77621. +
  77622. + if(moreThen256 == MV_TRUE)
  77623. + {
  77624. + offBlock[0] = (offset >> 8) & 0xff;
  77625. + offBlock[1] = offset & 0xff;
  77626. + offSize = 2;
  77627. + }
  77628. + else
  77629. + {
  77630. + offBlock[0] = offset & 0xff;
  77631. + offSize = 1;
  77632. + }
  77633. + DB(mvOsPrintf("TWSI: twsiTargetOffsSet offSize = %x addr1 = %x addr2 = %x\n",\
  77634. + offSize,offBlock[0],offBlock[1]));
  77635. + return twsiDataTransmit(chanNum, offBlock, offSize);
  77636. +
  77637. +}
  77638. +
  77639. +/*******************************************************************************
  77640. +* mvTwsiRead - Read data block from a TWSI Slave.
  77641. +*
  77642. +* DESCRIPTION:
  77643. +* The function calls the following functions:
  77644. +* -) mvTwsiStartBitSet();
  77645. +* if(EEPROM device)
  77646. +* -) mvTwsiAddrSet(w);
  77647. +* -) twsiTargetOffsSet();
  77648. +* -) mvTwsiStartBitSet();
  77649. +* -) mvTwsiAddrSet(r);
  77650. +* -) twsiDataReceive();
  77651. +* -) mvTwsiStopBitSet();
  77652. +*
  77653. +* INPUT:
  77654. +* chanNum - TWSI channel
  77655. +* pTwsiSlave - Twsi Slave structure.
  77656. +* blockSize - number of bytes to read.
  77657. +*
  77658. +* OUTPUT:
  77659. +* pBlock - Data block.
  77660. +*
  77661. +* RETURN:
  77662. +* MV_OK - if EEPROM read transaction completed succesfully,
  77663. +* MV_BAD_PARAM - if pBlock is NULL,
  77664. +* MV_FAIL otherwmise.
  77665. +*
  77666. +*******************************************************************************/
  77667. +MV_STATUS mvTwsiRead(MV_U8 chanNum, MV_TWSI_SLAVE *pTwsiSlave, MV_U8 *pBlock, MV_U32 blockSize)
  77668. +{
  77669. + if((NULL == pBlock) || (NULL == pTwsiSlave))
  77670. + return MV_BAD_PARAM;
  77671. + if(MV_OK != mvTwsiStartBitSet(chanNum))
  77672. + {
  77673. + mvTwsiStopBitSet(chanNum);
  77674. + return MV_FAIL;
  77675. + }
  77676. +
  77677. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStartBitSet\n"));
  77678. +
  77679. + /* in case offset exsist (i.e. eeprom ) */
  77680. + if(MV_TRUE == pTwsiSlave->validOffset)
  77681. + {
  77682. + if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_WRITE))
  77683. + {
  77684. + mvTwsiStopBitSet(chanNum);
  77685. + return MV_FAIL;
  77686. + }
  77687. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiAddrSet\n"));
  77688. + if(MV_OK != twsiTargetOffsSet(chanNum, pTwsiSlave->offset, pTwsiSlave->moreThen256))
  77689. + {
  77690. + mvTwsiStopBitSet(chanNum);
  77691. + return MV_FAIL;
  77692. + }
  77693. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after twsiTargetOffsSet\n"));
  77694. + if(MV_OK != mvTwsiStartBitSet(chanNum))
  77695. + {
  77696. + mvTwsiStopBitSet(chanNum);
  77697. + return MV_FAIL;
  77698. + }
  77699. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStartBitSet\n"));
  77700. + }
  77701. + if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_READ))
  77702. + {
  77703. + mvTwsiStopBitSet(chanNum);
  77704. + return MV_FAIL;
  77705. + }
  77706. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiAddrSet\n"));
  77707. + if(MV_OK != twsiDataReceive(chanNum, pBlock, blockSize))
  77708. + {
  77709. + mvTwsiStopBitSet(chanNum);
  77710. + return MV_FAIL;
  77711. + }
  77712. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after twsiDataReceive\n"));
  77713. +
  77714. + if(MV_OK != mvTwsiStopBitSet(chanNum))
  77715. + {
  77716. + return MV_FAIL;
  77717. + }
  77718. +
  77719. + twsiAckBitSet(chanNum);
  77720. +
  77721. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStopBitSet\n"));
  77722. +
  77723. + return MV_OK;
  77724. +}
  77725. +
  77726. +/*******************************************************************************
  77727. +* mvTwsiWrite - Write data block to a TWSI Slave.
  77728. +*
  77729. +* DESCRIPTION:
  77730. +* The function calls the following functions:
  77731. +* -) mvTwsiStartBitSet();
  77732. +* -) mvTwsiAddrSet();
  77733. +* -)if(EEPROM device)
  77734. +* -) twsiTargetOffsSet();
  77735. +* -) twsiDataTransmit();
  77736. +* -) mvTwsiStopBitSet();
  77737. +*
  77738. +* INPUT:
  77739. +* chanNum - TWSI channel
  77740. +* eepromAddress - eeprom address.
  77741. +* blockSize - number of bytes to write.
  77742. +* pBlock - Data block.
  77743. +*
  77744. +* OUTPUT:
  77745. +* None
  77746. +*
  77747. +* RETURN:
  77748. +* MV_OK - if EEPROM read transaction completed succesfully.
  77749. +* MV_BAD_PARAM - if pBlock is NULL,
  77750. +* MV_FAIL otherwmise.
  77751. +*
  77752. +* NOTE: Part of the EEPROM, required that the offset will be aligned to the
  77753. +* max write burst supported.
  77754. +*******************************************************************************/
  77755. +MV_STATUS mvTwsiWrite(MV_U8 chanNum, MV_TWSI_SLAVE *pTwsiSlave, MV_U8 *pBlock, MV_U32 blockSize)
  77756. +{
  77757. + if((NULL == pBlock) || (NULL == pTwsiSlave))
  77758. + return MV_BAD_PARAM;
  77759. +
  77760. + if(MV_OK != mvTwsiStartBitSet(chanNum))
  77761. + {
  77762. + mvTwsiStopBitSet(chanNum);
  77763. + return MV_FAIL;
  77764. + }
  77765. +
  77766. + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after mvTwsiStartBitSet\n"));
  77767. + if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_WRITE))
  77768. + {
  77769. + mvTwsiStopBitSet(chanNum);
  77770. + return MV_FAIL;
  77771. + }
  77772. + DB(mvOsPrintf("TWSI :mvTwsiEepromWrite after mvTwsiAddrSet\n"));
  77773. +
  77774. + /* in case offset exsist (i.e. eeprom ) */
  77775. + if(MV_TRUE == pTwsiSlave->validOffset)
  77776. + {
  77777. + if(MV_OK != twsiTargetOffsSet(chanNum, pTwsiSlave->offset, pTwsiSlave->moreThen256))
  77778. + {
  77779. + mvTwsiStopBitSet(chanNum);
  77780. + return MV_FAIL;
  77781. + }
  77782. + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after twsiTargetOffsSet\n"));
  77783. + }
  77784. + if(MV_OK != twsiDataTransmit(chanNum, pBlock, blockSize))
  77785. + {
  77786. + mvTwsiStopBitSet(chanNum);
  77787. + return MV_FAIL;
  77788. + }
  77789. + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after twsiDataTransmit\n"));
  77790. + if(MV_OK != mvTwsiStopBitSet(chanNum))
  77791. + {
  77792. + return MV_FAIL;
  77793. + }
  77794. + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after mvTwsiStopBitSet\n"));
  77795. +
  77796. + return MV_OK;
  77797. +}
  77798. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h
  77799. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h 1970-01-01 01:00:00.000000000 +0100
  77800. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h 2010-08-05 22:02:25.774565015 +0200
  77801. @@ -0,0 +1,121 @@
  77802. +/*******************************************************************************
  77803. +Copyright (C) Marvell International Ltd. and its affiliates
  77804. +
  77805. +This software file (the "File") is owned and distributed by Marvell
  77806. +International Ltd. and/or its affiliates ("Marvell") under the following
  77807. +alternative licensing terms. Once you have made an election to distribute the
  77808. +File under one of the following license alternatives, please (i) delete this
  77809. +introductory statement regarding license alternatives, (ii) delete the two
  77810. +license alternatives that you have not elected to use and (iii) preserve the
  77811. +Marvell copyright notice above.
  77812. +
  77813. +********************************************************************************
  77814. +Marvell Commercial License Option
  77815. +
  77816. +If you received this File from Marvell and you have entered into a commercial
  77817. +license agreement (a "Commercial License") with Marvell, the File is licensed
  77818. +to you under the terms of the applicable Commercial License.
  77819. +
  77820. +********************************************************************************
  77821. +Marvell GPL License Option
  77822. +
  77823. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77824. +modify this File in accordance with the terms and conditions of the General
  77825. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  77826. +available along with the File in the license.txt file or by writing to the Free
  77827. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  77828. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  77829. +
  77830. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  77831. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  77832. +DISCLAIMED. The GPL License provides additional details about this warranty
  77833. +disclaimer.
  77834. +********************************************************************************
  77835. +Marvell BSD License Option
  77836. +
  77837. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77838. +modify this File under the following licensing terms.
  77839. +Redistribution and use in source and binary forms, with or without modification,
  77840. +are permitted provided that the following conditions are met:
  77841. +
  77842. + * Redistributions of source code must retain the above copyright notice,
  77843. + this list of conditions and the following disclaimer.
  77844. +
  77845. + * Redistributions in binary form must reproduce the above copyright
  77846. + notice, this list of conditions and the following disclaimer in the
  77847. + documentation and/or other materials provided with the distribution.
  77848. +
  77849. + * Neither the name of Marvell nor the names of its contributors may be
  77850. + used to endorse or promote products derived from this software without
  77851. + specific prior written permission.
  77852. +
  77853. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  77854. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  77855. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  77856. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  77857. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  77858. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  77859. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  77860. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  77861. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  77862. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  77863. +
  77864. +*******************************************************************************/
  77865. +#ifndef __INCmvTwsiH
  77866. +#define __INCmvTwsiH
  77867. +
  77868. +#ifdef __cplusplus
  77869. +extern "C" {
  77870. +#endif /* __cplusplus */
  77871. +
  77872. +/* need to update this includes */
  77873. +#include "twsi/mvTwsiSpec.h"
  77874. +#include "ctrlEnv/mvCtrlEnvLib.h"
  77875. +
  77876. +
  77877. +/* The TWSI interface supports both 7-bit and 10-bit addressing. */
  77878. +/* This enumerator describes addressing type. */
  77879. +typedef enum _mvTwsiAddrType
  77880. +{
  77881. + ADDR7_BIT, /* 7 bit address */
  77882. + ADDR10_BIT /* 10 bit address */
  77883. +}MV_TWSI_ADDR_TYPE;
  77884. +
  77885. +/* This structure describes TWSI address. */
  77886. +typedef struct _mvTwsiAddr
  77887. +{
  77888. + MV_U32 address; /* address */
  77889. + MV_TWSI_ADDR_TYPE type; /* Address type */
  77890. +}MV_TWSI_ADDR;
  77891. +
  77892. +/* This structure describes a TWSI slave. */
  77893. +typedef struct _mvTwsiSlave
  77894. +{
  77895. + MV_TWSI_ADDR slaveAddr;
  77896. + MV_BOOL validOffset; /* whether the slave has offset (i.e. Eeprom etc.) */
  77897. + MV_U32 offset; /* offset in the slave. */
  77898. + MV_BOOL moreThen256; /* whether the ofset is bigger then 256 */
  77899. +}MV_TWSI_SLAVE;
  77900. +
  77901. +/* This enumerator describes TWSI protocol commands. */
  77902. +typedef enum _mvTwsiCmd
  77903. +{
  77904. + MV_TWSI_WRITE, /* TWSI write command - 0 according to spec */
  77905. + MV_TWSI_READ /* TWSI read command - 1 according to spec */
  77906. +}MV_TWSI_CMD;
  77907. +
  77908. +MV_STATUS mvTwsiStartBitSet(MV_U8 chanNum);
  77909. +MV_STATUS mvTwsiStopBitSet(MV_U8 chanNum);
  77910. +MV_STATUS mvTwsiAddrSet(MV_U8 chanNum, MV_TWSI_ADDR *twsiAddr, MV_TWSI_CMD command);
  77911. +
  77912. +MV_U32 mvTwsiInit(MV_U8 chanNum, MV_KHZ frequancy, MV_U32 Tclk, MV_TWSI_ADDR *twsiAddr, MV_BOOL generalCallEnable);
  77913. +MV_STATUS mvTwsiRead (MV_U8 chanNum, MV_TWSI_SLAVE *twsiSlave, MV_U8 *pBlock, MV_U32 blockSize);
  77914. +MV_STATUS mvTwsiWrite(MV_U8 chanNum, MV_TWSI_SLAVE *twsiSlave, MV_U8 *pBlock, MV_U32 blockSize);
  77915. +
  77916. +
  77917. +#ifdef __cplusplus
  77918. +}
  77919. +#endif /* __cplusplus */
  77920. +
  77921. +#endif /* __INCmvTwsiH */
  77922. +
  77923. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h
  77924. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h 1970-01-01 01:00:00.000000000 +0100
  77925. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h 2010-08-05 22:02:25.814868152 +0200
  77926. @@ -0,0 +1,160 @@
  77927. +/*******************************************************************************
  77928. +Copyright (C) Marvell International Ltd. and its affiliates
  77929. +
  77930. +This software file (the "File") is owned and distributed by Marvell
  77931. +International Ltd. and/or its affiliates ("Marvell") under the following
  77932. +alternative licensing terms. Once you have made an election to distribute the
  77933. +File under one of the following license alternatives, please (i) delete this
  77934. +introductory statement regarding license alternatives, (ii) delete the two
  77935. +license alternatives that you have not elected to use and (iii) preserve the
  77936. +Marvell copyright notice above.
  77937. +
  77938. +********************************************************************************
  77939. +Marvell Commercial License Option
  77940. +
  77941. +If you received this File from Marvell and you have entered into a commercial
  77942. +license agreement (a "Commercial License") with Marvell, the File is licensed
  77943. +to you under the terms of the applicable Commercial License.
  77944. +
  77945. +********************************************************************************
  77946. +Marvell GPL License Option
  77947. +
  77948. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77949. +modify this File in accordance with the terms and conditions of the General
  77950. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  77951. +available along with the File in the license.txt file or by writing to the Free
  77952. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  77953. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  77954. +
  77955. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  77956. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  77957. +DISCLAIMED. The GPL License provides additional details about this warranty
  77958. +disclaimer.
  77959. +********************************************************************************
  77960. +Marvell BSD License Option
  77961. +
  77962. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77963. +modify this File under the following licensing terms.
  77964. +Redistribution and use in source and binary forms, with or without modification,
  77965. +are permitted provided that the following conditions are met:
  77966. +
  77967. + * Redistributions of source code must retain the above copyright notice,
  77968. + this list of conditions and the following disclaimer.
  77969. +
  77970. + * Redistributions in binary form must reproduce the above copyright
  77971. + notice, this list of conditions and the following disclaimer in the
  77972. + documentation and/or other materials provided with the distribution.
  77973. +
  77974. + * Neither the name of Marvell nor the names of its contributors may be
  77975. + used to endorse or promote products derived from this software without
  77976. + specific prior written permission.
  77977. +
  77978. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  77979. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  77980. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  77981. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  77982. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  77983. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  77984. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  77985. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  77986. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  77987. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  77988. +
  77989. +*******************************************************************************/
  77990. +/****************************************/
  77991. +/* TWSI Registers */
  77992. +/****************************************/
  77993. +#ifndef __INCmvTwsiSpech
  77994. +#define __INCmvTwsiSpech
  77995. +
  77996. +#ifdef __cplusplus
  77997. +extern "C" {
  77998. +#endif /* __cplusplus */
  77999. +
  78000. +/* defines */
  78001. +#define TWSI_SLAVE_ADDR_REG(chanNum) (TWSI_SLAVE_BASE(chanNum)+ 0x00)
  78002. +
  78003. +#define TWSI_SLAVE_ADDR_GCE_ENA BIT0
  78004. +#define TWSI_SLAVE_ADDR_7BIT_OFFS 0x1
  78005. +#define TWSI_SLAVE_ADDR_7BIT_MASK (0xFF << TWSI_SLAVE_ADDR_7BIT_OFFS)
  78006. +#define TWSI_SLAVE_ADDR_10BIT_OFFS 0x7
  78007. +#define TWSI_SLAVE_ADDR_10BIT_MASK 0x300
  78008. +#define TWSI_SLAVE_ADDR_10BIT_CONST 0xF0
  78009. +
  78010. +
  78011. +#define TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x10)
  78012. +#define TWSI_EXTENDED_SLAVE_OFFS 0
  78013. +#define TWSI_EXTENDED_SLAVE_MASK (0xFF << TWSI_EXTENDED_SLAVE_OFFS)
  78014. +
  78015. +
  78016. +#define TWSI_DATA_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x04)
  78017. +#define TWSI_DATA_COMMAND_OFFS 0x0
  78018. +#define TWSI_DATA_COMMAND_MASK (0x1 << TWSI_DATA_COMMAND_OFFS)
  78019. +#define TWSI_DATA_COMMAND_WR (0x1 << TWSI_DATA_COMMAND_OFFS)
  78020. +#define TWSI_DATA_COMMAND_RD (0x0 << TWSI_DATA_COMMAND_OFFS)
  78021. +#define TWSI_DATA_ADDR_7BIT_OFFS 0x1
  78022. +#define TWSI_DATA_ADDR_7BIT_MASK (0xFF << TWSI_DATA_ADDR_7BIT_OFFS)
  78023. +#define TWSI_DATA_ADDR_10BIT_OFFS 0x7
  78024. +#define TWSI_DATA_ADDR_10BIT_MASK 0x300
  78025. +#define TWSI_DATA_ADDR_10BIT_CONST 0xF0
  78026. +
  78027. +
  78028. +#define TWSI_CONTROL_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x08)
  78029. +#define TWSI_CONTROL_ACK BIT2
  78030. +#define TWSI_CONTROL_INT_FLAG_SET BIT3
  78031. +#define TWSI_CONTROL_STOP_BIT BIT4
  78032. +#define TWSI_CONTROL_START_BIT BIT5
  78033. +#define TWSI_CONTROL_ENA BIT6
  78034. +#define TWSI_CONTROL_INT_ENA BIT7
  78035. +
  78036. +
  78037. +#define TWSI_STATUS_BAUDE_RATE_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x0c)
  78038. +#define TWSI_BAUD_RATE_N_OFFS 0
  78039. +#define TWSI_BAUD_RATE_N_MASK (0x7 << TWSI_BAUD_RATE_N_OFFS)
  78040. +#define TWSI_BAUD_RATE_M_OFFS 3
  78041. +#define TWSI_BAUD_RATE_M_MASK (0xF << TWSI_BAUD_RATE_M_OFFS)
  78042. +
  78043. +#define TWSI_SOFT_RESET_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x1c)
  78044. +
  78045. +/* defines */
  78046. +#define TWSI_TIMEOUT_VALUE 0x500
  78047. +
  78048. +/* TWSI status codes */
  78049. +#define TWSI_BUS_ERROR 0x00
  78050. +#define TWSI_START_CON_TRA 0x08
  78051. +#define TWSI_REPEATED_START_CON_TRA 0x10
  78052. +#define TWSI_AD_PLS_WR_BIT_TRA_ACK_REC 0x18
  78053. +#define TWSI_AD_PLS_WR_BIT_TRA_ACK_NOT_REC 0x20
  78054. +#define TWSI_M_TRAN_DATA_BYTE_ACK_REC 0x28
  78055. +#define TWSI_M_TRAN_DATA_BYTE_ACK_NOT_REC 0x30
  78056. +#define TWSI_M_LOST_ARB_DUR_AD_OR_DATA_TRA 0x38
  78057. +#define TWSI_AD_PLS_RD_BIT_TRA_ACK_REC 0x40
  78058. +#define TWSI_AD_PLS_RD_BIT_TRA_ACK_NOT_REC 0x48
  78059. +#define TWSI_M_REC_RD_DATA_ACK_TRA 0x50
  78060. +#define TWSI_M_REC_RD_DATA_ACK_NOT_TRA 0x58
  78061. +#define TWSI_SLA_REC_AD_PLS_WR_BIT_ACK_TRA 0x60
  78062. +#define TWSI_M_LOST_ARB_DUR_AD_TRA_AD_IS_TRGT_TO_SLA_ACK_TRA_W 0x68
  78063. +#define TWSI_GNL_CALL_REC_ACK_TRA 0x70
  78064. +#define TWSI_M_LOST_ARB_DUR_AD_TRA_GNL_CALL_AD_REC_ACK_TRA 0x78
  78065. +#define TWSI_SLA_REC_WR_DATA_AF_REC_SLA_AD_ACK_TRAN 0x80
  78066. +#define TWSI_SLA_REC_WR_DATA_AF_REC_SLA_AD_ACK_NOT_TRAN 0x88
  78067. +#define TWSI_SLA_REC_WR_DATA_AF_REC_GNL_CALL_ACK_TRAN 0x90
  78068. +#define TWSI_SLA_REC_WR_DATA_AF_REC_GNL_CALL_ACK_NOT_TRAN 0x98
  78069. +#define TWSI_SLA_REC_STOP_OR_REPEATED_STRT_CON 0xA0
  78070. +#define TWSI_SLA_REC_AD_PLS_RD_BIT_ACK_TRA 0xA8
  78071. +#define TWSI_M_LOST_ARB_DUR_AD_TRA_AD_IS_TRGT_TO_SLA_ACK_TRA_R 0xB0
  78072. +#define TWSI_SLA_TRA_RD_DATA_ACK_REC 0xB8
  78073. +#define TWSI_SLA_TRA_RD_DATA_ACK_NOT_REC 0xC0
  78074. +#define TWSI_SLA_TRA_LAST_RD_DATA_ACK_REC 0xC8
  78075. +#define TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_REC 0xD0
  78076. +#define TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_NOT_REC 0xD8
  78077. +#define TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_REC 0xE0
  78078. +#define TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_NOT_REC 0xE8
  78079. +#define TWSI_NO_REL_STS_INT_FLAG_IS_KEPT_0 0xF8
  78080. +
  78081. +
  78082. +#ifdef __cplusplus
  78083. +}
  78084. +#endif /* __cplusplus */
  78085. +
  78086. +#endif /* __INCmvTwsiSpech */
  78087. diff -Nur linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h linux-2.6.35/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h
  78088. --- linux-2.6.35.orig/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h 1970-01-01 01:00:00.000000000 +0100
  78089. +++ linux-2.6.35/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h 2010-08-05 22:02:25.854868014 +0200
  78090. @@ -0,0 +1,375 @@
  78091. +/*******************************************************************************
  78092. +Copyright (C) Marvell International Ltd. and its affiliates
  78093. +
  78094. +********************************************************************************
  78095. +Marvell GPL License Option
  78096. +
  78097. +If you received this File from Marvell, you may opt to use, redistribute and/or
  78098. +modify this File in accordance with the terms and conditions of the General
  78099. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  78100. +available along with the File in the license.txt file or by writing to the Free
  78101. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  78102. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  78103. +
  78104. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  78105. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  78106. +DISCLAIMED. The GPL License provides additional details about this warranty
  78107. +disclaimer.
  78108. +
  78109. +*******************************************************************************/
  78110. +/*******************************************************************************
  78111. +* mvSysHwCfg.h - Marvell system HW configuration file
  78112. +*
  78113. +* DESCRIPTION:
  78114. +* None.
  78115. +*
  78116. +* DEPENDENCIES:
  78117. +* None.
  78118. +*
  78119. +*******************************************************************************/
  78120. +
  78121. +#ifndef __INCmvSysHwConfigh
  78122. +#define __INCmvSysHwConfigh
  78123. +
  78124. +#include "../../../../include/linux/autoconf.h"
  78125. +
  78126. +#define CONFIG_MARVELL 1
  78127. +
  78128. +/* includes */
  78129. +#define _1K 0x00000400
  78130. +#define _4K 0x00001000
  78131. +#define _8K 0x00002000
  78132. +#define _16K 0x00004000
  78133. +#define _32K 0x00008000
  78134. +#define _64K 0x00010000
  78135. +#define _128K 0x00020000
  78136. +#define _256K 0x00040000
  78137. +#define _512K 0x00080000
  78138. +
  78139. +#define _1M 0x00100000
  78140. +#define _2M 0x00200000
  78141. +#define _4M 0x00400000
  78142. +#define _8M 0x00800000
  78143. +#define _16M 0x01000000
  78144. +#define _32M 0x02000000
  78145. +#define _64M 0x04000000
  78146. +#define _128M 0x08000000
  78147. +#define _256M 0x10000000
  78148. +#define _512M 0x20000000
  78149. +
  78150. +#define _1G 0x40000000
  78151. +#define _2G 0x80000000
  78152. +
  78153. +/****************************************/
  78154. +/* Soc supporeted Units definitions */
  78155. +/****************************************/
  78156. +
  78157. +#ifdef CONFIG_MV_INCLUDE_PEX
  78158. +#define MV_INCLUDE_PEX
  78159. +#endif
  78160. +#ifdef CONFIG_MV_INCLUDE_TWSI
  78161. +#define MV_INCLUDE_TWSI
  78162. +#endif
  78163. +#ifdef CONFIG_MV_INCLUDE_CESA
  78164. +#define MV_INCLUDE_CESA
  78165. +#endif
  78166. +#ifdef CONFIG_MV_INCLUDE_GIG_ETH
  78167. +#define MV_INCLUDE_GIG_ETH
  78168. +#endif
  78169. +#ifdef CONFIG_MV_INCLUDE_INTEG_SATA
  78170. +#define MV_INCLUDE_INTEG_SATA
  78171. +#define MV_INCLUDE_SATA
  78172. +#endif
  78173. +#ifdef CONFIG_MV_INCLUDE_USB
  78174. +#define MV_INCLUDE_USB
  78175. +#define MV_USB_VOLTAGE_FIX
  78176. +#endif
  78177. +#ifdef CONFIG_MV_INCLUDE_NAND
  78178. +#define MV_INCLUDE_NAND
  78179. +#endif
  78180. +#ifdef CONFIG_MV_INCLUDE_TDM
  78181. +#define MV_INCLUDE_TDM
  78182. +#endif
  78183. +#ifdef CONFIG_MV_INCLUDE_XOR
  78184. +#define MV_INCLUDE_XOR
  78185. +#endif
  78186. +#ifdef CONFIG_MV_INCLUDE_TWSI
  78187. +#define MV_INCLUDE_TWSI
  78188. +#endif
  78189. +#ifdef CONFIG_MV_INCLUDE_UART
  78190. +#define MV_INCLUDE_UART
  78191. +#endif
  78192. +#ifdef CONFIG_MV_INCLUDE_SPI
  78193. +#define MV_INCLUDE_SPI
  78194. +#endif
  78195. +#ifdef CONFIG_MV_INCLUDE_SFLASH_MTD
  78196. +#define MV_INCLUDE_SFLASH_MTD
  78197. +#endif
  78198. +#ifdef CONFIG_MV_INCLUDE_AUDIO
  78199. +#define MV_INCLUDE_AUDIO
  78200. +#endif
  78201. +#ifdef CONFIG_MV_INCLUDE_TS
  78202. +#define MV_INCLUDE_TS
  78203. +#endif
  78204. +#ifdef CONFIG_MV_INCLUDE_SDIO
  78205. +#define MV_INCLUDE_SDIO
  78206. +#endif
  78207. +
  78208. +
  78209. +/* NAND flash stuff */
  78210. +#ifdef CONFIG_MV_NAND_BOOT
  78211. +#define MV_NAND_BOOT
  78212. +#endif
  78213. +#ifdef CONFIG_MV_NAND
  78214. +#define MV_NAND
  78215. +#endif
  78216. +
  78217. +/* SPI flash stuff */
  78218. +#ifdef CONFIG_MV_SPI_BOOT
  78219. +#define MV_SPI_BOOT
  78220. +#endif
  78221. +
  78222. +
  78223. +/****************************************************************/
  78224. +/************* General configuration ********************/
  78225. +/****************************************************************/
  78226. +
  78227. +/* Enable Clock Power Control */
  78228. +#define MV_INCLUDE_CLK_PWR_CNTRL
  78229. +
  78230. +/* Disable the DEVICE BAR in the PEX */
  78231. +#define MV_DISABLE_PEX_DEVICE_BAR
  78232. +
  78233. +/* Allow the usage of early printings during initialization */
  78234. +#define MV_INCLUDE_EARLY_PRINTK
  78235. +
  78236. +/****************************************************************/
  78237. +/************* NFP configuration ********************************/
  78238. +/****************************************************************/
  78239. +#define MV_NFP_SEC_Q_SIZE 64
  78240. +#define MV_NFP_SEC_REQ_Q_SIZE 1000
  78241. +
  78242. +
  78243. +
  78244. +/****************************************************************/
  78245. +/************* CESA configuration ********************/
  78246. +/****************************************************************/
  78247. +
  78248. +#ifdef MV_INCLUDE_CESA
  78249. +
  78250. +#define MV_CESA_MAX_CHAN 4
  78251. +
  78252. +/* Use 2K of SRAM */
  78253. +#define MV_CESA_MAX_BUF_SIZE 1600
  78254. +
  78255. +#endif /* MV_INCLUDE_CESA */
  78256. +
  78257. +#if defined(CONFIG_MV_INCLUDE_GIG_ETH)
  78258. +
  78259. +#ifdef CONFIG_MV_NFP_STATS
  78260. +#define MV_FP_STATISTICS
  78261. +#else
  78262. +#undef MV_FP_STATISTICS
  78263. +#endif
  78264. +/* Default configuration for SKB_REUSE: 0 - Disabled, 1 - Enabled */
  78265. +#define MV_ETH_SKB_REUSE_DEFAULT 1
  78266. +/* Default configuration for TX_EN workaround: 0 - Disabled, 1 - Enabled */
  78267. +#define MV_ETH_TX_EN_DEFAULT 0
  78268. +
  78269. +/* un-comment if you want to perform tx_done from within the poll function */
  78270. +/* #define ETH_TX_DONE_ISR */
  78271. +
  78272. +/* put descriptors in uncached memory */
  78273. +/* #define ETH_DESCR_UNCACHED */
  78274. +
  78275. +/* Descriptors location: DRAM/internal-SRAM */
  78276. +#define ETH_DESCR_IN_SDRAM
  78277. +#undef ETH_DESCR_IN_SRAM /* No integrated SRAM in 88Fxx81 devices */
  78278. +
  78279. +#if defined(ETH_DESCR_IN_SRAM)
  78280. +#if defined(ETH_DESCR_UNCACHED)
  78281. + #define ETH_DESCR_CONFIG_STR "Uncached descriptors in integrated SRAM"
  78282. +#else
  78283. + #define ETH_DESCR_CONFIG_STR "Cached descriptors in integrated SRAM"
  78284. +#endif
  78285. +#elif defined(ETH_DESCR_IN_SDRAM)
  78286. +#if defined(ETH_DESCR_UNCACHED)
  78287. + #define ETH_DESCR_CONFIG_STR "Uncached descriptors in DRAM"
  78288. +#else
  78289. + #define ETH_DESCR_CONFIG_STR "Cached descriptors in DRAM"
  78290. +#endif
  78291. +#else
  78292. + #error "Ethernet descriptors location undefined"
  78293. +#endif /* ETH_DESCR_IN_SRAM or ETH_DESCR_IN_SDRAM*/
  78294. +
  78295. +/* SW Sync-Barrier: not relevant for 88fxx81*/
  78296. +/* Reasnable to define this macro when descriptors in SRAM and buffers in DRAM */
  78297. +/* In RX the CPU theoretically might see himself as the descriptor owner, */
  78298. +/* although the buffer hadn't been written to DRAM yet. Performance cost. */
  78299. +/* #define INCLUDE_SYNC_BARR */
  78300. +
  78301. +/* Buffers cache coherency method (buffers in DRAM) */
  78302. +#ifndef MV_CACHE_COHER_SW
  78303. +/* Taken from mvCommon.h */
  78304. +/* Memory uncached, HW or SW cache coherency is not needed */
  78305. +#define MV_UNCACHED 0
  78306. +/* Memory cached, HW cache coherency supported in WriteThrough mode */
  78307. +#define MV_CACHE_COHER_HW_WT 1
  78308. +/* Memory cached, HW cache coherency supported in WriteBack mode */
  78309. +#define MV_CACHE_COHER_HW_WB 2
  78310. +/* Memory cached, No HW cache coherency, Cache coherency must be in SW */
  78311. +#define MV_CACHE_COHER_SW 3
  78312. +
  78313. +#endif
  78314. +
  78315. +/* DRAM cache coherency configuration */
  78316. +#define MV_CACHE_COHERENCY MV_CACHE_COHER_SW
  78317. +
  78318. +
  78319. +#define ETHER_DRAM_COHER MV_CACHE_COHER_SW /* No HW coherency in 88Fxx81 devices */
  78320. +
  78321. +#if (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WB)
  78322. + #define ETH_SDRAM_CONFIG_STR "DRAM HW cache coherency (write-back)"
  78323. +#elif (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WT)
  78324. + #define ETH_SDRAM_CONFIG_STR "DRAM HW cache coherency (write-through)"
  78325. +#elif (ETHER_DRAM_COHER == MV_CACHE_COHER_SW)
  78326. + #define ETH_SDRAM_CONFIG_STR "DRAM SW cache-coherency"
  78327. +#elif (ETHER_DRAM_COHER == MV_UNCACHED)
  78328. +# define ETH_SDRAM_CONFIG_STR "DRAM uncached"
  78329. +#else
  78330. + #error "Ethernet-DRAM undefined"
  78331. +#endif /* ETHER_DRAM_COHER */
  78332. +
  78333. +
  78334. +/****************************************************************/
  78335. +/************* Ethernet driver configuration ********************/
  78336. +/****************************************************************/
  78337. +
  78338. +/* port's default queueus */
  78339. +#define ETH_DEF_TXQ 0
  78340. +#define ETH_DEF_RXQ 0
  78341. +
  78342. +#define MV_ETH_RX_Q_NUM CONFIG_MV_ETH_RX_Q_NUM
  78343. +#define MV_ETH_TX_Q_NUM CONFIG_MV_ETH_TX_Q_NUM
  78344. +
  78345. +/* interrupt coalescing setting */
  78346. +#define ETH_TX_COAL 200
  78347. +#define ETH_RX_COAL 200
  78348. +
  78349. +/* Checksum offloading */
  78350. +#define TX_CSUM_OFFLOAD
  78351. +#define RX_CSUM_OFFLOAD
  78352. +
  78353. +#endif /* CONFIG_MV_INCLUDE_GIG_ETH */
  78354. +
  78355. +/****************************************************************/
  78356. +/*************** Telephony configuration ************************/
  78357. +/****************************************************************/
  78358. +#if defined(CONFIG_MV_TDM_LINEAR_MODE)
  78359. + #define MV_TDM_LINEAR_MODE
  78360. +#elif defined(CONFIG_MV_TDM_ULAW_MODE)
  78361. + #define MV_TDM_ULAW_MODE
  78362. +#endif
  78363. +
  78364. +#if defined(CONFIG_MV_TDM_5CHANNELS)
  78365. + #define MV_TDM_5CHANNELS
  78366. +#endif
  78367. +
  78368. +#if defined(CONFIG_MV_TDM_USE_EXTERNAL_PCLK_SOURCE)
  78369. + #define MV_TDM_USE_EXTERNAL_PCLK_SOURCE
  78370. +#endif
  78371. +
  78372. +/* We use the following registers to store DRAM interface pre configuration */
  78373. +/* auto-detection results */
  78374. +/* IMPORTANT: We are using mask register for that purpose. Before writing */
  78375. +/* to units mask register, make sure main maks register is set to disable */
  78376. +/* all interrupts. */
  78377. +#define DRAM_BUF_REG0 0x30810 /* sdram bank 0 size */
  78378. +#define DRAM_BUF_REG1 0x30820 /* sdram config */
  78379. +#define DRAM_BUF_REG2 0x30830 /* sdram mode */
  78380. +#define DRAM_BUF_REG3 0x308c4 /* dunit control low */
  78381. +#define DRAM_BUF_REG4 0x60a90 /* sdram address control */
  78382. +#define DRAM_BUF_REG5 0x60a94 /* sdram timing control low */
  78383. +#define DRAM_BUF_REG6 0x60a98 /* sdram timing control high */
  78384. +#define DRAM_BUF_REG7 0x60a9c /* sdram ODT control low */
  78385. +#define DRAM_BUF_REG8 0x60b90 /* sdram ODT control high */
  78386. +#define DRAM_BUF_REG9 0x60b94 /* sdram Dunit ODT control */
  78387. +#define DRAM_BUF_REG10 0x60b98 /* sdram Extended Mode */
  78388. +#define DRAM_BUF_REG11 0x60b9c /* sdram Ddr2 Time Low Reg */
  78389. +#define DRAM_BUF_REG12 0x60a00 /* sdram Ddr2 Time High Reg */
  78390. +#define DRAM_BUF_REG13 0x60a04 /* dunit Ctrl High */
  78391. +#define DRAM_BUF_REG14 0x60b00 /* sdram second DIMM exist */
  78392. +
  78393. +/* Following the pre-configuration registers default values restored after */
  78394. +/* auto-detection is done */
  78395. +#define DRAM_BUF_REG_DV 0
  78396. +
  78397. +/* System Mapping */
  78398. +#define SDRAM_CS0_BASE 0x00000000
  78399. +#define SDRAM_CS0_SIZE _256M
  78400. +
  78401. +#define SDRAM_CS1_BASE 0x10000000
  78402. +#define SDRAM_CS1_SIZE _256M
  78403. +
  78404. +#define SDRAM_CS2_BASE 0x20000000
  78405. +#define SDRAM_CS2_SIZE _256M
  78406. +
  78407. +#define SDRAM_CS3_BASE 0x30000000
  78408. +#define SDRAM_CS3_SIZE _256M
  78409. +
  78410. +/* PEX */
  78411. +#define PEX0_MEM_BASE 0xe8000000
  78412. +#define PEX0_MEM_SIZE _128M
  78413. +
  78414. +#define PEX0_IO_BASE 0xf2000000
  78415. +#define PEX0_IO_SIZE _1M
  78416. +
  78417. +/* Device Chip Selects */
  78418. +#define NFLASH_CS_BASE 0xfa000000
  78419. +#define NFLASH_CS_SIZE _2M
  78420. +
  78421. +#define SPI_CS_BASE 0xf4000000
  78422. +#define SPI_CS_SIZE _16M
  78423. +
  78424. +#define CRYPT_ENG_BASE 0xf0000000
  78425. +#define CRYPT_ENG_SIZE _2M
  78426. +
  78427. +#define BOOTDEV_CS_BASE 0xff800000
  78428. +#define BOOTDEV_CS_SIZE _8M
  78429. +
  78430. +/* CS2 - BOOTROM */
  78431. +#define DEVICE_CS2_BASE 0xff900000
  78432. +#define DEVICE_CS2_SIZE _1M
  78433. +
  78434. +/* PEX Work arround */
  78435. +/* the target we will use for the workarround */
  78436. +#define PEX_CONFIG_RW_WA_TARGET PEX0_MEM
  78437. +/*a flag that indicates if we are going to use the
  78438. +size and base of the target we using for the workarround
  78439. +window */
  78440. +#define PEX_CONFIG_RW_WA_USE_ORIGINAL_WIN_VALUES 1
  78441. +/* if the above flag is 0 then the following values
  78442. +will be used for the workarround window base and size,
  78443. +otherwise the following defines will be ignored */
  78444. +#define PEX_CONFIG_RW_WA_BASE 0xF3000000
  78445. +#define PEX_CONFIG_RW_WA_SIZE _16M
  78446. +
  78447. +/* Internal registers: size is defined in Controllerenvironment */
  78448. +#define INTER_REGS_BASE 0xFEE00000
  78449. +
  78450. +/* DRAM detection stuff */
  78451. +#define MV_DRAM_AUTO_SIZE
  78452. +
  78453. +/* Board clock detection */
  78454. +#define TCLK_AUTO_DETECT /* Use Tclk auto detection */
  78455. +#define SYSCLK_AUTO_DETECT /* Use SysClk auto detection */
  78456. +#define PCLCK_AUTO_DETECT /* Use PClk auto detection */
  78457. +#define L2CLK_AUTO_DETECT /* Use L2Clk auto detection */
  78458. +
  78459. +/* PEX-PCI\PCI-PCI Bridge*/
  78460. +#define PCI0_IF_PTP 0 /* Bridge exist on pciIf0*/
  78461. +
  78462. +
  78463. +
  78464. +#endif /* __INCmvSysHwConfigh */
  78465. +
  78466. diff -Nur linux-2.6.35.orig/crypto/ocf/Makefile linux-2.6.35/crypto/ocf/Makefile
  78467. --- linux-2.6.35.orig/crypto/ocf/Makefile 1970-01-01 01:00:00.000000000 +0100
  78468. +++ linux-2.6.35/crypto/ocf/Makefile 2010-08-05 22:02:25.894868239 +0200
  78469. @@ -0,0 +1,124 @@
  78470. +# for SGlinux builds
  78471. +-include $(ROOTDIR)/modules/.config
  78472. +
  78473. +OCF_OBJS = crypto.o criov.o
  78474. +
  78475. +ifdef CONFIG_OCF_RANDOMHARVEST
  78476. + OCF_OBJS += random.o
  78477. +endif
  78478. +
  78479. +ifdef CONFIG_OCF_FIPS
  78480. + OCF_OBJS += rndtest.o
  78481. +endif
  78482. +
  78483. +# Add in autoconf.h to get #defines for CONFIG_xxx
  78484. +AUTOCONF_H=$(ROOTDIR)/modules/autoconf.h
  78485. +ifeq ($(AUTOCONF_H), $(wildcard $(AUTOCONF_H)))
  78486. + EXTRA_CFLAGS += -include $(AUTOCONF_H)
  78487. + export EXTRA_CFLAGS
  78488. +endif
  78489. +
  78490. +ifndef obj
  78491. + obj ?= .
  78492. + _obj = subdir
  78493. + mod-subdirs := safe hifn ixp4xx talitos ocfnull
  78494. + export-objs += crypto.o criov.o random.o
  78495. + list-multi += ocf.o
  78496. + _slash :=
  78497. +else
  78498. + _obj = obj
  78499. + _slash := /
  78500. +endif
  78501. +
  78502. +EXTRA_CFLAGS += -I$(obj)/.
  78503. +
  78504. +obj-$(CONFIG_OCF_OCF) += ocf.o
  78505. +obj-$(CONFIG_OCF_CRYPTODEV) += cryptodev.o
  78506. +obj-$(CONFIG_OCF_CRYPTOSOFT) += cryptosoft.o
  78507. +obj-$(CONFIG_OCF_BENCH) += ocf-bench.o
  78508. +
  78509. +$(_obj)-$(CONFIG_OCF_SAFE) += safe$(_slash)
  78510. +$(_obj)-$(CONFIG_OCF_HIFN) += hifn$(_slash)
  78511. +$(_obj)-$(CONFIG_OCF_IXP4XX) += ixp4xx$(_slash)
  78512. +$(_obj)-$(CONFIG_OCF_TALITOS) += talitos$(_slash)
  78513. +$(_obj)-$(CONFIG_OCF_PASEMI) += pasemi$(_slash)
  78514. +$(_obj)-$(CONFIG_OCF_EP80579) += ep80579$(_slash)
  78515. +$(_obj)-$(CONFIG_OCF_CRYPTOCTEON) += cryptocteon$(_slash)
  78516. +$(_obj)-$(CONFIG_OCF_KIRKWOOD) += kirkwood$(_slash)
  78517. +$(_obj)-$(CONFIG_OCF_OCFNULL) += ocfnull$(_slash)
  78518. +$(_obj)-$(CONFIG_OCF_C7108) += c7108$(_slash)
  78519. +
  78520. +ocf-objs := $(OCF_OBJS)
  78521. +
  78522. +$(list-multi) dummy1: $(ocf-objs)
  78523. + $(LD) -r -o $@ $(ocf-objs)
  78524. +
  78525. +.PHONY:
  78526. +clean:
  78527. + rm -f *.o *.ko .*.o.flags .*.ko.cmd .*.o.cmd .*.mod.o.cmd *.mod.c
  78528. + rm -f */*.o */*.ko */.*.o.cmd */.*.ko.cmd */.*.mod.o.cmd */*.mod.c */.*.o.flags
  78529. +
  78530. +ifdef TOPDIR
  78531. +-include $(TOPDIR)/Rules.make
  78532. +endif
  78533. +
  78534. +#
  78535. +# release gen targets
  78536. +#
  78537. +
  78538. +.PHONY: patch
  78539. +patch:
  78540. + REL=`date +%Y%m%d`; \
  78541. + patch=ocf-linux-$$REL.patch; \
  78542. + patch24=ocf-linux-24-$$REL.patch; \
  78543. + patch26=ocf-linux-26-$$REL.patch; \
  78544. + ( \
  78545. + find . -name Makefile; \
  78546. + find . -name Config.in; \
  78547. + find . -name Kconfig; \
  78548. + find . -name README; \
  78549. + find . -name '*.[ch]' | grep -v '.mod.c'; \
  78550. + ) | while read t; do \
  78551. + diff -Nau /dev/null $$t | sed 's?^+++ \./?+++ linux/crypto/ocf/?'; \
  78552. + done > $$patch; \
  78553. + cat patches/linux-2.4.35-ocf.patch $$patch > $$patch24; \
  78554. + cat patches/linux-2.6.33-ocf.patch $$patch > $$patch26
  78555. +
  78556. +.PHONY: tarball
  78557. +tarball:
  78558. + REL=`date +%Y%m%d`; RELDIR=/tmp/ocf-linux-$$REL; \
  78559. + CURDIR=`pwd`; \
  78560. + rm -rf /tmp/ocf-linux-$$REL*; \
  78561. + mkdir -p $$RELDIR/tools; \
  78562. + cp README* $$RELDIR; \
  78563. + cp patches/openss*.patch $$RELDIR; \
  78564. + cp patches/crypto-tools.patch $$RELDIR; \
  78565. + cp tools/[!C]* $$RELDIR/tools; \
  78566. + cd ..; \
  78567. + tar cvf $$RELDIR/ocf-linux.tar \
  78568. + --exclude=CVS \
  78569. + --exclude=.* \
  78570. + --exclude=*.o \
  78571. + --exclude=*.ko \
  78572. + --exclude=*.mod.* \
  78573. + --exclude=README* \
  78574. + --exclude=ocf-*.patch \
  78575. + --exclude=ocf/patches/openss*.patch \
  78576. + --exclude=ocf/patches/crypto-tools.patch \
  78577. + --exclude=ocf/tools \
  78578. + ocf; \
  78579. + gzip -9 $$RELDIR/ocf-linux.tar; \
  78580. + cd /tmp; \
  78581. + tar cvf ocf-linux-$$REL.tar ocf-linux-$$REL; \
  78582. + gzip -9 ocf-linux-$$REL.tar; \
  78583. + cd $$CURDIR/../../user; \
  78584. + rm -rf /tmp/crypto-tools-$$REL*; \
  78585. + tar cvf /tmp/crypto-tools-$$REL.tar \
  78586. + --exclude=CVS \
  78587. + --exclude=.* \
  78588. + --exclude=*.o \
  78589. + --exclude=cryptotest \
  78590. + --exclude=cryptokeytest \
  78591. + crypto-tools; \
  78592. + gzip -9 /tmp/crypto-tools-$$REL.tar
  78593. +
  78594. diff -Nur linux-2.6.35.orig/crypto/ocf/ocf-bench.c linux-2.6.35/crypto/ocf/ocf-bench.c
  78595. --- linux-2.6.35.orig/crypto/ocf/ocf-bench.c 1970-01-01 01:00:00.000000000 +0100
  78596. +++ linux-2.6.35/crypto/ocf/ocf-bench.c 2010-08-05 22:02:25.933861800 +0200
  78597. @@ -0,0 +1,436 @@
  78598. +/*
  78599. + * A loadable module that benchmarks the OCF crypto speed from kernel space.
  78600. + *
  78601. + * Copyright (C) 2004-2010 David McCullough <david_mccullough@mcafee.com>
  78602. + *
  78603. + * LICENSE TERMS
  78604. + *
  78605. + * The free distribution and use of this software in both source and binary
  78606. + * form is allowed (with or without changes) provided that:
  78607. + *
  78608. + * 1. distributions of this source code include the above copyright
  78609. + * notice, this list of conditions and the following disclaimer;
  78610. + *
  78611. + * 2. distributions in binary form include the above copyright
  78612. + * notice, this list of conditions and the following disclaimer
  78613. + * in the documentation and/or other associated materials;
  78614. + *
  78615. + * 3. the copyright holder's name is not used to endorse products
  78616. + * built using this software without specific written permission.
  78617. + *
  78618. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  78619. + * may be distributed under the terms of the GNU General Public License (GPL),
  78620. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  78621. + *
  78622. + * DISCLAIMER
  78623. + *
  78624. + * This software is provided 'as is' with no explicit or implied warranties
  78625. + * in respect of its properties, including, but not limited to, correctness
  78626. + * and/or fitness for purpose.
  78627. + */
  78628. +
  78629. +
  78630. +#ifndef AUTOCONF_INCLUDED
  78631. +#include <linux/config.h>
  78632. +#endif
  78633. +#include <linux/module.h>
  78634. +#include <linux/init.h>
  78635. +#include <linux/list.h>
  78636. +#include <linux/slab.h>
  78637. +#include <linux/wait.h>
  78638. +#include <linux/sched.h>
  78639. +#include <linux/spinlock.h>
  78640. +#include <linux/version.h>
  78641. +#include <linux/interrupt.h>
  78642. +#include <cryptodev.h>
  78643. +
  78644. +#ifdef I_HAVE_AN_XSCALE_WITH_INTEL_SDK
  78645. +#define BENCH_IXP_ACCESS_LIB 1
  78646. +#endif
  78647. +#ifdef BENCH_IXP_ACCESS_LIB
  78648. +#include <IxTypes.h>
  78649. +#include <IxOsBuffMgt.h>
  78650. +#include <IxNpeDl.h>
  78651. +#include <IxCryptoAcc.h>
  78652. +#include <IxQMgr.h>
  78653. +#include <IxOsServices.h>
  78654. +#include <IxOsCacheMMU.h>
  78655. +#endif
  78656. +
  78657. +/*
  78658. + * support for access lib version 1.4
  78659. + */
  78660. +#ifndef IX_MBUF_PRIV
  78661. +#define IX_MBUF_PRIV(x) ((x)->priv)
  78662. +#endif
  78663. +
  78664. +/*
  78665. + * the number of simultaneously active requests
  78666. + */
  78667. +static int request_q_len = 20;
  78668. +module_param(request_q_len, int, 0);
  78669. +MODULE_PARM_DESC(request_q_len, "Number of outstanding requests");
  78670. +/*
  78671. + * how many requests we want to have processed
  78672. + */
  78673. +static int request_num = 1024;
  78674. +module_param(request_num, int, 0);
  78675. +MODULE_PARM_DESC(request_num, "run for at least this many requests");
  78676. +/*
  78677. + * the size of each request
  78678. + */
  78679. +static int request_size = 1500;
  78680. +module_param(request_size, int, 0);
  78681. +MODULE_PARM_DESC(request_size, "size of each request");
  78682. +
  78683. +/*
  78684. + * a structure for each request
  78685. + */
  78686. +typedef struct {
  78687. + struct work_struct work;
  78688. +#ifdef BENCH_IXP_ACCESS_LIB
  78689. + IX_MBUF mbuf;
  78690. +#endif
  78691. + unsigned char *buffer;
  78692. +} request_t;
  78693. +
  78694. +static request_t *requests;
  78695. +
  78696. +static int outstanding;
  78697. +static int total;
  78698. +
  78699. +/*************************************************************************/
  78700. +/*
  78701. + * OCF benchmark routines
  78702. + */
  78703. +
  78704. +static uint64_t ocf_cryptoid;
  78705. +static int ocf_init(void);
  78706. +static int ocf_cb(struct cryptop *crp);
  78707. +static void ocf_request(void *arg);
  78708. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  78709. +static void ocf_request_wq(struct work_struct *work);
  78710. +#endif
  78711. +
  78712. +static int
  78713. +ocf_init(void)
  78714. +{
  78715. + int error;
  78716. + struct cryptoini crie, cria;
  78717. + struct cryptodesc crda, crde;
  78718. +
  78719. + memset(&crie, 0, sizeof(crie));
  78720. + memset(&cria, 0, sizeof(cria));
  78721. + memset(&crde, 0, sizeof(crde));
  78722. + memset(&crda, 0, sizeof(crda));
  78723. +
  78724. + cria.cri_alg = CRYPTO_SHA1_HMAC;
  78725. + cria.cri_klen = 20 * 8;
  78726. + cria.cri_key = "0123456789abcdefghij";
  78727. +
  78728. + crie.cri_alg = CRYPTO_3DES_CBC;
  78729. + crie.cri_klen = 24 * 8;
  78730. + crie.cri_key = "0123456789abcdefghijklmn";
  78731. +
  78732. + crie.cri_next = &cria;
  78733. +
  78734. + error = crypto_newsession(&ocf_cryptoid, &crie, 0);
  78735. + if (error) {
  78736. + printk("crypto_newsession failed %d\n", error);
  78737. + return -1;
  78738. + }
  78739. + return 0;
  78740. +}
  78741. +
  78742. +static int
  78743. +ocf_cb(struct cryptop *crp)
  78744. +{
  78745. + request_t *r = (request_t *) crp->crp_opaque;
  78746. +
  78747. + if (crp->crp_etype)
  78748. + printk("Error in OCF processing: %d\n", crp->crp_etype);
  78749. + total++;
  78750. + crypto_freereq(crp);
  78751. + crp = NULL;
  78752. +
  78753. + if (total > request_num) {
  78754. + outstanding--;
  78755. + return 0;
  78756. + }
  78757. +
  78758. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  78759. + INIT_WORK(&r->work, ocf_request_wq);
  78760. +#else
  78761. + INIT_WORK(&r->work, ocf_request, r);
  78762. +#endif
  78763. + schedule_work(&r->work);
  78764. + return 0;
  78765. +}
  78766. +
  78767. +
  78768. +static void
  78769. +ocf_request(void *arg)
  78770. +{
  78771. + request_t *r = arg;
  78772. + struct cryptop *crp = crypto_getreq(2);
  78773. + struct cryptodesc *crde, *crda;
  78774. +
  78775. + if (!crp) {
  78776. + outstanding--;
  78777. + return;
  78778. + }
  78779. +
  78780. + crde = crp->crp_desc;
  78781. + crda = crde->crd_next;
  78782. +
  78783. + crda->crd_skip = 0;
  78784. + crda->crd_flags = 0;
  78785. + crda->crd_len = request_size;
  78786. + crda->crd_inject = request_size;
  78787. + crda->crd_alg = CRYPTO_SHA1_HMAC;
  78788. + crda->crd_key = "0123456789abcdefghij";
  78789. + crda->crd_klen = 20 * 8;
  78790. +
  78791. + crde->crd_skip = 0;
  78792. + crde->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_ENCRYPT;
  78793. + crde->crd_len = request_size;
  78794. + crde->crd_inject = request_size;
  78795. + crde->crd_alg = CRYPTO_3DES_CBC;
  78796. + crde->crd_key = "0123456789abcdefghijklmn";
  78797. + crde->crd_klen = 24 * 8;
  78798. +
  78799. + crp->crp_ilen = request_size + 64;
  78800. + crp->crp_flags = CRYPTO_F_CBIMM;
  78801. + crp->crp_buf = (caddr_t) r->buffer;
  78802. + crp->crp_callback = ocf_cb;
  78803. + crp->crp_sid = ocf_cryptoid;
  78804. + crp->crp_opaque = (caddr_t) r;
  78805. + crypto_dispatch(crp);
  78806. +}
  78807. +
  78808. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  78809. +static void
  78810. +ocf_request_wq(struct work_struct *work)
  78811. +{
  78812. + request_t *r = container_of(work, request_t, work);
  78813. + ocf_request(r);
  78814. +}
  78815. +#endif
  78816. +
  78817. +/*************************************************************************/
  78818. +#ifdef BENCH_IXP_ACCESS_LIB
  78819. +/*************************************************************************/
  78820. +/*
  78821. + * CryptoAcc benchmark routines
  78822. + */
  78823. +
  78824. +static IxCryptoAccCtx ixp_ctx;
  78825. +static UINT32 ixp_ctx_id;
  78826. +static IX_MBUF ixp_pri;
  78827. +static IX_MBUF ixp_sec;
  78828. +static int ixp_registered = 0;
  78829. +
  78830. +static void ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp,
  78831. + IxCryptoAccStatus status);
  78832. +static void ixp_perform_cb(UINT32 ctx_id, IX_MBUF *sbufp, IX_MBUF *dbufp,
  78833. + IxCryptoAccStatus status);
  78834. +static void ixp_request(void *arg);
  78835. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  78836. +static void ixp_request_wq(struct work_struct *work);
  78837. +#endif
  78838. +
  78839. +static int
  78840. +ixp_init(void)
  78841. +{
  78842. + IxCryptoAccStatus status;
  78843. +
  78844. + ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
  78845. + ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  78846. + ixp_ctx.cipherCtx.cipherKeyLen = 24;
  78847. + ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
  78848. + ixp_ctx.cipherCtx.cipherInitialVectorLen = IX_CRYPTO_ACC_DES_IV_64;
  78849. + memcpy(ixp_ctx.cipherCtx.key.cipherKey, "0123456789abcdefghijklmn", 24);
  78850. +
  78851. + ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
  78852. + ixp_ctx.authCtx.authDigestLen = 12;
  78853. + ixp_ctx.authCtx.aadLen = 0;
  78854. + ixp_ctx.authCtx.authKeyLen = 20;
  78855. + memcpy(ixp_ctx.authCtx.key.authKey, "0123456789abcdefghij", 20);
  78856. +
  78857. + ixp_ctx.useDifferentSrcAndDestMbufs = 0;
  78858. + ixp_ctx.operation = IX_CRYPTO_ACC_OP_ENCRYPT_AUTH ;
  78859. +
  78860. + IX_MBUF_MLEN(&ixp_pri) = IX_MBUF_PKT_LEN(&ixp_pri) = 128;
  78861. + IX_MBUF_MDATA(&ixp_pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  78862. + IX_MBUF_MLEN(&ixp_sec) = IX_MBUF_PKT_LEN(&ixp_sec) = 128;
  78863. + IX_MBUF_MDATA(&ixp_sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  78864. +
  78865. + status = ixCryptoAccCtxRegister(&ixp_ctx, &ixp_pri, &ixp_sec,
  78866. + ixp_register_cb, ixp_perform_cb, &ixp_ctx_id);
  78867. +
  78868. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status) {
  78869. + while (!ixp_registered)
  78870. + schedule();
  78871. + return ixp_registered < 0 ? -1 : 0;
  78872. + }
  78873. +
  78874. + printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
  78875. + return -1;
  78876. +}
  78877. +
  78878. +static void
  78879. +ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
  78880. +{
  78881. + if (bufp) {
  78882. + IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
  78883. + kfree(IX_MBUF_MDATA(bufp));
  78884. + IX_MBUF_MDATA(bufp) = NULL;
  78885. + }
  78886. +
  78887. + if (IX_CRYPTO_ACC_STATUS_WAIT == status)
  78888. + return;
  78889. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  78890. + ixp_registered = 1;
  78891. + else
  78892. + ixp_registered = -1;
  78893. +}
  78894. +
  78895. +static void
  78896. +ixp_perform_cb(
  78897. + UINT32 ctx_id,
  78898. + IX_MBUF *sbufp,
  78899. + IX_MBUF *dbufp,
  78900. + IxCryptoAccStatus status)
  78901. +{
  78902. + request_t *r = NULL;
  78903. +
  78904. + total++;
  78905. + if (total > request_num) {
  78906. + outstanding--;
  78907. + return;
  78908. + }
  78909. +
  78910. + if (!sbufp || !(r = IX_MBUF_PRIV(sbufp))) {
  78911. + printk("crappo %p %p\n", sbufp, r);
  78912. + outstanding--;
  78913. + return;
  78914. + }
  78915. +
  78916. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  78917. + INIT_WORK(&r->work, ixp_request_wq);
  78918. +#else
  78919. + INIT_WORK(&r->work, ixp_request, r);
  78920. +#endif
  78921. + schedule_work(&r->work);
  78922. +}
  78923. +
  78924. +static void
  78925. +ixp_request(void *arg)
  78926. +{
  78927. + request_t *r = arg;
  78928. + IxCryptoAccStatus status;
  78929. +
  78930. + memset(&r->mbuf, 0, sizeof(r->mbuf));
  78931. + IX_MBUF_MLEN(&r->mbuf) = IX_MBUF_PKT_LEN(&r->mbuf) = request_size + 64;
  78932. + IX_MBUF_MDATA(&r->mbuf) = r->buffer;
  78933. + IX_MBUF_PRIV(&r->mbuf) = r;
  78934. + status = ixCryptoAccAuthCryptPerform(ixp_ctx_id, &r->mbuf, NULL,
  78935. + 0, request_size, 0, request_size, request_size, r->buffer);
  78936. + if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
  78937. + printk("status1 = %d\n", status);
  78938. + outstanding--;
  78939. + return;
  78940. + }
  78941. + return;
  78942. +}
  78943. +
  78944. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  78945. +static void
  78946. +ixp_request_wq(struct work_struct *work)
  78947. +{
  78948. + request_t *r = container_of(work, request_t, work);
  78949. + ixp_request(r);
  78950. +}
  78951. +#endif
  78952. +
  78953. +/*************************************************************************/
  78954. +#endif /* BENCH_IXP_ACCESS_LIB */
  78955. +/*************************************************************************/
  78956. +
  78957. +int
  78958. +ocfbench_init(void)
  78959. +{
  78960. + int i, jstart, jstop;
  78961. +
  78962. + printk("Crypto Speed tests\n");
  78963. +
  78964. + requests = kmalloc(sizeof(request_t) * request_q_len, GFP_KERNEL);
  78965. + if (!requests) {
  78966. + printk("malloc failed\n");
  78967. + return -EINVAL;
  78968. + }
  78969. +
  78970. + for (i = 0; i < request_q_len; i++) {
  78971. + /* +64 for return data */
  78972. + requests[i].buffer = kmalloc(request_size + 128, GFP_DMA);
  78973. + if (!requests[i].buffer) {
  78974. + printk("malloc failed\n");
  78975. + return -EINVAL;
  78976. + }
  78977. + memset(requests[i].buffer, '0' + i, request_size + 128);
  78978. + }
  78979. +
  78980. + /*
  78981. + * OCF benchmark
  78982. + */
  78983. + printk("OCF: testing ...\n");
  78984. + ocf_init();
  78985. + total = outstanding = 0;
  78986. + jstart = jiffies;
  78987. + for (i = 0; i < request_q_len; i++) {
  78988. + outstanding++;
  78989. + ocf_request(&requests[i]);
  78990. + }
  78991. + while (outstanding > 0)
  78992. + schedule();
  78993. + jstop = jiffies;
  78994. +
  78995. + printk("OCF: %d requests of %d bytes in %d jiffies\n", total, request_size,
  78996. + jstop - jstart);
  78997. +
  78998. +#ifdef BENCH_IXP_ACCESS_LIB
  78999. + /*
  79000. + * IXP benchmark
  79001. + */
  79002. + printk("IXP: testing ...\n");
  79003. + ixp_init();
  79004. + total = outstanding = 0;
  79005. + jstart = jiffies;
  79006. + for (i = 0; i < request_q_len; i++) {
  79007. + outstanding++;
  79008. + ixp_request(&requests[i]);
  79009. + }
  79010. + while (outstanding > 0)
  79011. + schedule();
  79012. + jstop = jiffies;
  79013. +
  79014. + printk("IXP: %d requests of %d bytes in %d jiffies\n", total, request_size,
  79015. + jstop - jstart);
  79016. +#endif /* BENCH_IXP_ACCESS_LIB */
  79017. +
  79018. + for (i = 0; i < request_q_len; i++)
  79019. + kfree(requests[i].buffer);
  79020. + kfree(requests);
  79021. + return -EINVAL; /* always fail to load so it can be re-run quickly ;-) */
  79022. +}
  79023. +
  79024. +static void __exit ocfbench_exit(void)
  79025. +{
  79026. +}
  79027. +
  79028. +module_init(ocfbench_init);
  79029. +module_exit(ocfbench_exit);
  79030. +
  79031. +MODULE_LICENSE("BSD");
  79032. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  79033. +MODULE_DESCRIPTION("Benchmark various in-kernel crypto speeds");
  79034. diff -Nur linux-2.6.35.orig/crypto/ocf/ocf-compat.h linux-2.6.35/crypto/ocf/ocf-compat.h
  79035. --- linux-2.6.35.orig/crypto/ocf/ocf-compat.h 1970-01-01 01:00:00.000000000 +0100
  79036. +++ linux-2.6.35/crypto/ocf/ocf-compat.h 2010-08-05 22:02:25.974123209 +0200
  79037. @@ -0,0 +1,294 @@
  79038. +#ifndef _BSD_COMPAT_H_
  79039. +#define _BSD_COMPAT_H_ 1
  79040. +/****************************************************************************/
  79041. +/*
  79042. + * Provide compat routines for older linux kernels and BSD kernels
  79043. + *
  79044. + * Written by David McCullough <david_mccullough@mcafee.com>
  79045. + * Copyright (C) 2010 David McCullough <david_mccullough@mcafee.com>
  79046. + *
  79047. + * LICENSE TERMS
  79048. + *
  79049. + * The free distribution and use of this software in both source and binary
  79050. + * form is allowed (with or without changes) provided that:
  79051. + *
  79052. + * 1. distributions of this source code include the above copyright
  79053. + * notice, this list of conditions and the following disclaimer;
  79054. + *
  79055. + * 2. distributions in binary form include the above copyright
  79056. + * notice, this list of conditions and the following disclaimer
  79057. + * in the documentation and/or other associated materials;
  79058. + *
  79059. + * 3. the copyright holder's name is not used to endorse products
  79060. + * built using this software without specific written permission.
  79061. + *
  79062. + * ALTERNATIVELY, provided that this notice is retained in full, this file
  79063. + * may be distributed under the terms of the GNU General Public License (GPL),
  79064. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  79065. + *
  79066. + * DISCLAIMER
  79067. + *
  79068. + * This software is provided 'as is' with no explicit or implied warranties
  79069. + * in respect of its properties, including, but not limited to, correctness
  79070. + * and/or fitness for purpose.
  79071. + */
  79072. +/****************************************************************************/
  79073. +#ifdef __KERNEL__
  79074. +/*
  79075. + * fake some BSD driver interface stuff specifically for OCF use
  79076. + */
  79077. +
  79078. +typedef struct ocf_device *device_t;
  79079. +
  79080. +typedef struct {
  79081. + int (*cryptodev_newsession)(device_t dev, u_int32_t *sidp, struct cryptoini *cri);
  79082. + int (*cryptodev_freesession)(device_t dev, u_int64_t tid);
  79083. + int (*cryptodev_process)(device_t dev, struct cryptop *crp, int hint);
  79084. + int (*cryptodev_kprocess)(device_t dev, struct cryptkop *krp, int hint);
  79085. +} device_method_t;
  79086. +#define DEVMETHOD(id, func) id: func
  79087. +
  79088. +struct ocf_device {
  79089. + char name[32]; /* the driver name */
  79090. + char nameunit[32]; /* the driver name + HW instance */
  79091. + int unit;
  79092. + device_method_t methods;
  79093. + void *softc;
  79094. +};
  79095. +
  79096. +#define CRYPTODEV_NEWSESSION(dev, sid, cri) \
  79097. + ((*(dev)->methods.cryptodev_newsession)(dev,sid,cri))
  79098. +#define CRYPTODEV_FREESESSION(dev, sid) \
  79099. + ((*(dev)->methods.cryptodev_freesession)(dev, sid))
  79100. +#define CRYPTODEV_PROCESS(dev, crp, hint) \
  79101. + ((*(dev)->methods.cryptodev_process)(dev, crp, hint))
  79102. +#define CRYPTODEV_KPROCESS(dev, krp, hint) \
  79103. + ((*(dev)->methods.cryptodev_kprocess)(dev, krp, hint))
  79104. +
  79105. +#define device_get_name(dev) ((dev)->name)
  79106. +#define device_get_nameunit(dev) ((dev)->nameunit)
  79107. +#define device_get_unit(dev) ((dev)->unit)
  79108. +#define device_get_softc(dev) ((dev)->softc)
  79109. +
  79110. +#define softc_device_decl \
  79111. + struct ocf_device _device; \
  79112. + device_t
  79113. +
  79114. +#define softc_device_init(_sc, _name, _unit, _methods) \
  79115. + if (1) {\
  79116. + strncpy((_sc)->_device.name, _name, sizeof((_sc)->_device.name) - 1); \
  79117. + snprintf((_sc)->_device.nameunit, sizeof((_sc)->_device.name), "%s%d", _name, _unit); \
  79118. + (_sc)->_device.unit = _unit; \
  79119. + (_sc)->_device.methods = _methods; \
  79120. + (_sc)->_device.softc = (void *) _sc; \
  79121. + *(device_t *)((softc_get_device(_sc))+1) = &(_sc)->_device; \
  79122. + } else
  79123. +
  79124. +#define softc_get_device(_sc) (&(_sc)->_device)
  79125. +
  79126. +/*
  79127. + * iomem support for 2.4 and 2.6 kernels
  79128. + */
  79129. +#include <linux/version.h>
  79130. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  79131. +#define ocf_iomem_t unsigned long
  79132. +
  79133. +/*
  79134. + * implement simple workqueue like support for older kernels
  79135. + */
  79136. +
  79137. +#include <linux/tqueue.h>
  79138. +
  79139. +#define work_struct tq_struct
  79140. +
  79141. +#define INIT_WORK(wp, fp, ap) \
  79142. + do { \
  79143. + (wp)->sync = 0; \
  79144. + (wp)->routine = (fp); \
  79145. + (wp)->data = (ap); \
  79146. + } while (0)
  79147. +
  79148. +#define schedule_work(wp) \
  79149. + do { \
  79150. + queue_task((wp), &tq_immediate); \
  79151. + mark_bh(IMMEDIATE_BH); \
  79152. + } while (0)
  79153. +
  79154. +#define flush_scheduled_work() run_task_queue(&tq_immediate)
  79155. +
  79156. +#else
  79157. +#define ocf_iomem_t void __iomem *
  79158. +
  79159. +#include <linux/workqueue.h>
  79160. +
  79161. +#endif
  79162. +
  79163. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
  79164. +#include <linux/fdtable.h>
  79165. +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
  79166. +#define files_fdtable(files) (files)
  79167. +#endif
  79168. +
  79169. +#ifdef MODULE_PARM
  79170. +#undef module_param /* just in case */
  79171. +#define module_param(a,b,c) MODULE_PARM(a,"i")
  79172. +#endif
  79173. +
  79174. +#define bzero(s,l) memset(s,0,l)
  79175. +#define bcopy(s,d,l) memcpy(d,s,l)
  79176. +#define bcmp(x, y, l) memcmp(x,y,l)
  79177. +
  79178. +#define MIN(x,y) ((x) < (y) ? (x) : (y))
  79179. +
  79180. +#define device_printf(dev, a...) ({ \
  79181. + printk("%s: ", device_get_nameunit(dev)); printk(a); \
  79182. + })
  79183. +
  79184. +#undef printf
  79185. +#define printf(fmt...) printk(fmt)
  79186. +
  79187. +#define KASSERT(c,p) if (!(c)) { printk p ; } else
  79188. +
  79189. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  79190. +#define ocf_daemonize(str) \
  79191. + daemonize(); \
  79192. + spin_lock_irq(&current->sigmask_lock); \
  79193. + sigemptyset(&current->blocked); \
  79194. + recalc_sigpending(current); \
  79195. + spin_unlock_irq(&current->sigmask_lock); \
  79196. + sprintf(current->comm, str);
  79197. +#else
  79198. +#define ocf_daemonize(str) daemonize(str);
  79199. +#endif
  79200. +
  79201. +#define TAILQ_INSERT_TAIL(q,d,m) list_add_tail(&(d)->m, (q))
  79202. +#define TAILQ_EMPTY(q) list_empty(q)
  79203. +#define TAILQ_FOREACH(v, q, m) list_for_each_entry(v, q, m)
  79204. +
  79205. +#define read_random(p,l) get_random_bytes(p,l)
  79206. +
  79207. +#define DELAY(x) ((x) > 2000 ? mdelay((x)/1000) : udelay(x))
  79208. +#define strtoul simple_strtoul
  79209. +
  79210. +#define pci_get_vendor(dev) ((dev)->vendor)
  79211. +#define pci_get_device(dev) ((dev)->device)
  79212. +
  79213. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  79214. +#define pci_set_consistent_dma_mask(dev, mask) (0)
  79215. +#endif
  79216. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
  79217. +#define pci_dma_sync_single_for_cpu pci_dma_sync_single
  79218. +#endif
  79219. +
  79220. +#ifndef DMA_32BIT_MASK
  79221. +#define DMA_32BIT_MASK 0x00000000ffffffffULL
  79222. +#endif
  79223. +
  79224. +#ifndef htole32
  79225. +#define htole32(x) cpu_to_le32(x)
  79226. +#endif
  79227. +#ifndef htobe32
  79228. +#define htobe32(x) cpu_to_be32(x)
  79229. +#endif
  79230. +#ifndef htole16
  79231. +#define htole16(x) cpu_to_le16(x)
  79232. +#endif
  79233. +#ifndef htobe16
  79234. +#define htobe16(x) cpu_to_be16(x)
  79235. +#endif
  79236. +
  79237. +/* older kernels don't have these */
  79238. +
  79239. +#include <asm/irq.h>
  79240. +#if !defined(IRQ_NONE) && !defined(IRQ_RETVAL)
  79241. +#define IRQ_NONE
  79242. +#define IRQ_HANDLED
  79243. +#define IRQ_WAKE_THREAD
  79244. +#define IRQ_RETVAL
  79245. +#define irqreturn_t void
  79246. +typedef irqreturn_t (*irq_handler_t)(int irq, void *arg, struct pt_regs *regs);
  79247. +#endif
  79248. +#ifndef IRQF_SHARED
  79249. +#define IRQF_SHARED SA_SHIRQ
  79250. +#endif
  79251. +
  79252. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
  79253. +# define strlcpy(dest,src,len) \
  79254. + ({strncpy(dest,src,(len)-1); ((char *)dest)[(len)-1] = '\0'; })
  79255. +#endif
  79256. +
  79257. +#ifndef MAX_ERRNO
  79258. +#define MAX_ERRNO 4095
  79259. +#endif
  79260. +#ifndef IS_ERR_VALUE
  79261. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,5)
  79262. +#include <linux/err.h>
  79263. +#endif
  79264. +#ifndef IS_ERR_VALUE
  79265. +#define IS_ERR_VALUE(x) ((unsigned long)(x) >= (unsigned long)-MAX_ERRNO)
  79266. +#endif
  79267. +#endif
  79268. +
  79269. +/*
  79270. + * common debug for all
  79271. + */
  79272. +#if 1
  79273. +#define dprintk(a...) do { if (debug) printk(a); } while(0)
  79274. +#else
  79275. +#define dprintk(a...)
  79276. +#endif
  79277. +
  79278. +#ifndef SLAB_ATOMIC
  79279. +/* Changed in 2.6.20, must use GFP_ATOMIC now */
  79280. +#define SLAB_ATOMIC GFP_ATOMIC
  79281. +#endif
  79282. +
  79283. +/*
  79284. + * need some additional support for older kernels */
  79285. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,2)
  79286. +#define pci_register_driver_compat(driver, rc) \
  79287. + do { \
  79288. + if ((rc) > 0) { \
  79289. + (rc) = 0; \
  79290. + } else if (rc == 0) { \
  79291. + (rc) = -ENODEV; \
  79292. + } else { \
  79293. + pci_unregister_driver(driver); \
  79294. + } \
  79295. + } while (0)
  79296. +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
  79297. +#define pci_register_driver_compat(driver,rc) ((rc) = (rc) < 0 ? (rc) : 0)
  79298. +#else
  79299. +#define pci_register_driver_compat(driver,rc)
  79300. +#endif
  79301. +
  79302. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
  79303. +
  79304. +#include <linux/mm.h>
  79305. +#include <asm/scatterlist.h>
  79306. +
  79307. +static inline void sg_set_page(struct scatterlist *sg, struct page *page,
  79308. + unsigned int len, unsigned int offset)
  79309. +{
  79310. + sg->page = page;
  79311. + sg->offset = offset;
  79312. + sg->length = len;
  79313. +}
  79314. +
  79315. +static inline void *sg_virt(struct scatterlist *sg)
  79316. +{
  79317. + return page_address(sg->page) + sg->offset;
  79318. +}
  79319. +
  79320. +#define sg_init_table(sg, n)
  79321. +
  79322. +#endif
  79323. +
  79324. +#ifndef late_initcall
  79325. +#define late_initcall(init) module_init(init)
  79326. +#endif
  79327. +
  79328. +#endif /* __KERNEL__ */
  79329. +
  79330. +/****************************************************************************/
  79331. +#endif /* _BSD_COMPAT_H_ */
  79332. diff -Nur linux-2.6.35.orig/crypto/ocf/ocfnull/Makefile linux-2.6.35/crypto/ocf/ocfnull/Makefile
  79333. --- linux-2.6.35.orig/crypto/ocf/ocfnull/Makefile 1970-01-01 01:00:00.000000000 +0100
  79334. +++ linux-2.6.35/crypto/ocf/ocfnull/Makefile 2010-08-05 22:02:26.013723070 +0200
  79335. @@ -0,0 +1,12 @@
  79336. +# for SGlinux builds
  79337. +-include $(ROOTDIR)/modules/.config
  79338. +
  79339. +obj-$(CONFIG_OCF_OCFNULL) += ocfnull.o
  79340. +
  79341. +obj ?= .
  79342. +EXTRA_CFLAGS += -I$(obj)/..
  79343. +
  79344. +ifdef TOPDIR
  79345. +-include $(TOPDIR)/Rules.make
  79346. +endif
  79347. +
  79348. diff -Nur linux-2.6.35.orig/crypto/ocf/ocfnull/ocfnull.c linux-2.6.35/crypto/ocf/ocfnull/ocfnull.c
  79349. --- linux-2.6.35.orig/crypto/ocf/ocfnull/ocfnull.c 1970-01-01 01:00:00.000000000 +0100
  79350. +++ linux-2.6.35/crypto/ocf/ocfnull/ocfnull.c 2010-08-05 22:02:26.054125640 +0200
  79351. @@ -0,0 +1,203 @@
  79352. +/*
  79353. + * An OCF module for determining the cost of crypto versus the cost of
  79354. + * IPSec processing outside of OCF. This modules gives us the effect of
  79355. + * zero cost encryption, of course you will need to run it at both ends
  79356. + * since it does no crypto at all.
  79357. + *
  79358. + * Written by David McCullough <david_mccullough@mcafee.com>
  79359. + * Copyright (C) 2006-2010 David McCullough
  79360. + *
  79361. + * LICENSE TERMS
  79362. + *
  79363. + * The free distribution and use of this software in both source and binary
  79364. + * form is allowed (with or without changes) provided that:
  79365. + *
  79366. + * 1. distributions of this source code include the above copyright
  79367. + * notice, this list of conditions and the following disclaimer;
  79368. + *
  79369. + * 2. distributions in binary form include the above copyright
  79370. + * notice, this list of conditions and the following disclaimer
  79371. + * in the documentation and/or other associated materials;
  79372. + *
  79373. + * 3. the copyright holder's name is not used to endorse products
  79374. + * built using this software without specific written permission.
  79375. + *
  79376. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  79377. + * may be distributed under the terms of the GNU General Public License (GPL),
  79378. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  79379. + *
  79380. + * DISCLAIMER
  79381. + *
  79382. + * This software is provided 'as is' with no explicit or implied warranties
  79383. + * in respect of its properties, including, but not limited to, correctness
  79384. + * and/or fitness for purpose.
  79385. + */
  79386. +
  79387. +#ifndef AUTOCONF_INCLUDED
  79388. +#include <linux/config.h>
  79389. +#endif
  79390. +#include <linux/module.h>
  79391. +#include <linux/init.h>
  79392. +#include <linux/list.h>
  79393. +#include <linux/slab.h>
  79394. +#include <linux/sched.h>
  79395. +#include <linux/wait.h>
  79396. +#include <linux/crypto.h>
  79397. +#include <linux/interrupt.h>
  79398. +
  79399. +#include <cryptodev.h>
  79400. +#include <uio.h>
  79401. +
  79402. +static int32_t null_id = -1;
  79403. +static u_int32_t null_sesnum = 0;
  79404. +
  79405. +static int null_process(device_t, struct cryptop *, int);
  79406. +static int null_newsession(device_t, u_int32_t *, struct cryptoini *);
  79407. +static int null_freesession(device_t, u_int64_t);
  79408. +
  79409. +#define debug ocfnull_debug
  79410. +int ocfnull_debug = 0;
  79411. +module_param(ocfnull_debug, int, 0644);
  79412. +MODULE_PARM_DESC(ocfnull_debug, "Enable debug");
  79413. +
  79414. +/*
  79415. + * dummy device structure
  79416. + */
  79417. +
  79418. +static struct {
  79419. + softc_device_decl sc_dev;
  79420. +} nulldev;
  79421. +
  79422. +static device_method_t null_methods = {
  79423. + /* crypto device methods */
  79424. + DEVMETHOD(cryptodev_newsession, null_newsession),
  79425. + DEVMETHOD(cryptodev_freesession,null_freesession),
  79426. + DEVMETHOD(cryptodev_process, null_process),
  79427. +};
  79428. +
  79429. +/*
  79430. + * Generate a new software session.
  79431. + */
  79432. +static int
  79433. +null_newsession(device_t arg, u_int32_t *sid, struct cryptoini *cri)
  79434. +{
  79435. + dprintk("%s()\n", __FUNCTION__);
  79436. + if (sid == NULL || cri == NULL) {
  79437. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  79438. + return EINVAL;
  79439. + }
  79440. +
  79441. + if (null_sesnum == 0)
  79442. + null_sesnum++;
  79443. + *sid = null_sesnum++;
  79444. + return 0;
  79445. +}
  79446. +
  79447. +
  79448. +/*
  79449. + * Free a session.
  79450. + */
  79451. +static int
  79452. +null_freesession(device_t arg, u_int64_t tid)
  79453. +{
  79454. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  79455. +
  79456. + dprintk("%s()\n", __FUNCTION__);
  79457. + if (sid > null_sesnum) {
  79458. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  79459. + return EINVAL;
  79460. + }
  79461. +
  79462. + /* Silently accept and return */
  79463. + if (sid == 0)
  79464. + return 0;
  79465. + return 0;
  79466. +}
  79467. +
  79468. +
  79469. +/*
  79470. + * Process a request.
  79471. + */
  79472. +static int
  79473. +null_process(device_t arg, struct cryptop *crp, int hint)
  79474. +{
  79475. + unsigned int lid;
  79476. +
  79477. + dprintk("%s()\n", __FUNCTION__);
  79478. +
  79479. + /* Sanity check */
  79480. + if (crp == NULL) {
  79481. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  79482. + return EINVAL;
  79483. + }
  79484. +
  79485. + crp->crp_etype = 0;
  79486. +
  79487. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  79488. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  79489. + crp->crp_etype = EINVAL;
  79490. + goto done;
  79491. + }
  79492. +
  79493. + /*
  79494. + * find the session we are using
  79495. + */
  79496. +
  79497. + lid = crp->crp_sid & 0xffffffff;
  79498. + if (lid >= null_sesnum || lid == 0) {
  79499. + crp->crp_etype = ENOENT;
  79500. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  79501. + goto done;
  79502. + }
  79503. +
  79504. +done:
  79505. + crypto_done(crp);
  79506. + return 0;
  79507. +}
  79508. +
  79509. +
  79510. +/*
  79511. + * our driver startup and shutdown routines
  79512. + */
  79513. +
  79514. +static int
  79515. +null_init(void)
  79516. +{
  79517. + dprintk("%s(%p)\n", __FUNCTION__, null_init);
  79518. +
  79519. + memset(&nulldev, 0, sizeof(nulldev));
  79520. + softc_device_init(&nulldev, "ocfnull", 0, null_methods);
  79521. +
  79522. + null_id = crypto_get_driverid(softc_get_device(&nulldev),
  79523. + CRYPTOCAP_F_HARDWARE);
  79524. + if (null_id < 0)
  79525. + panic("ocfnull: crypto device cannot initialize!");
  79526. +
  79527. +#define REGISTER(alg) \
  79528. + crypto_register(null_id,alg,0,0)
  79529. + REGISTER(CRYPTO_DES_CBC);
  79530. + REGISTER(CRYPTO_3DES_CBC);
  79531. + REGISTER(CRYPTO_RIJNDAEL128_CBC);
  79532. + REGISTER(CRYPTO_MD5);
  79533. + REGISTER(CRYPTO_SHA1);
  79534. + REGISTER(CRYPTO_MD5_HMAC);
  79535. + REGISTER(CRYPTO_SHA1_HMAC);
  79536. +#undef REGISTER
  79537. +
  79538. + return 0;
  79539. +}
  79540. +
  79541. +static void
  79542. +null_exit(void)
  79543. +{
  79544. + dprintk("%s()\n", __FUNCTION__);
  79545. + crypto_unregister_all(null_id);
  79546. + null_id = -1;
  79547. +}
  79548. +
  79549. +module_init(null_init);
  79550. +module_exit(null_exit);
  79551. +
  79552. +MODULE_LICENSE("Dual BSD/GPL");
  79553. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  79554. +MODULE_DESCRIPTION("ocfnull - claims a lot but does nothing");
  79555. diff -Nur linux-2.6.35.orig/crypto/ocf/pasemi/Makefile linux-2.6.35/crypto/ocf/pasemi/Makefile
  79556. --- linux-2.6.35.orig/crypto/ocf/pasemi/Makefile 1970-01-01 01:00:00.000000000 +0100
  79557. +++ linux-2.6.35/crypto/ocf/pasemi/Makefile 2010-08-05 22:02:26.094867962 +0200
  79558. @@ -0,0 +1,12 @@
  79559. +# for SGlinux builds
  79560. +-include $(ROOTDIR)/modules/.config
  79561. +
  79562. +obj-$(CONFIG_OCF_PASEMI) += pasemi.o
  79563. +
  79564. +obj ?= .
  79565. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  79566. +
  79567. +ifdef TOPDIR
  79568. +-include $(TOPDIR)/Rules.make
  79569. +endif
  79570. +
  79571. diff -Nur linux-2.6.35.orig/crypto/ocf/pasemi/pasemi.c linux-2.6.35/crypto/ocf/pasemi/pasemi.c
  79572. --- linux-2.6.35.orig/crypto/ocf/pasemi/pasemi.c 1970-01-01 01:00:00.000000000 +0100
  79573. +++ linux-2.6.35/crypto/ocf/pasemi/pasemi.c 2010-08-05 22:02:26.133923748 +0200
  79574. @@ -0,0 +1,1009 @@
  79575. +/*
  79576. + * Copyright (C) 2007 PA Semi, Inc
  79577. + *
  79578. + * Driver for the PA Semi PWRficient DMA Crypto Engine
  79579. + *
  79580. + * This program is free software; you can redistribute it and/or modify
  79581. + * it under the terms of the GNU General Public License version 2 as
  79582. + * published by the Free Software Foundation.
  79583. + *
  79584. + * This program is distributed in the hope that it will be useful,
  79585. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  79586. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  79587. + * GNU General Public License for more details.
  79588. + *
  79589. + * You should have received a copy of the GNU General Public License
  79590. + * along with this program; if not, write to the Free Software
  79591. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  79592. + */
  79593. +
  79594. +#ifndef AUTOCONF_INCLUDED
  79595. +#include <linux/config.h>
  79596. +#endif
  79597. +#include <linux/module.h>
  79598. +#include <linux/init.h>
  79599. +#include <linux/interrupt.h>
  79600. +#include <linux/timer.h>
  79601. +#include <linux/random.h>
  79602. +#include <linux/skbuff.h>
  79603. +#include <asm/scatterlist.h>
  79604. +#include <linux/moduleparam.h>
  79605. +#include <linux/pci.h>
  79606. +#include <cryptodev.h>
  79607. +#include <uio.h>
  79608. +#include "pasemi_fnu.h"
  79609. +
  79610. +#define DRV_NAME "pasemi"
  79611. +
  79612. +#define TIMER_INTERVAL 1000
  79613. +
  79614. +static void __devexit pasemi_dma_remove(struct pci_dev *pdev);
  79615. +static struct pasdma_status volatile * dma_status;
  79616. +
  79617. +static int debug;
  79618. +module_param(debug, int, 0644);
  79619. +MODULE_PARM_DESC(debug, "Enable debug");
  79620. +
  79621. +static void pasemi_desc_start(struct pasemi_desc *desc, u64 hdr)
  79622. +{
  79623. + desc->postop = 0;
  79624. + desc->quad[0] = hdr;
  79625. + desc->quad_cnt = 1;
  79626. + desc->size = 1;
  79627. +}
  79628. +
  79629. +static void pasemi_desc_build(struct pasemi_desc *desc, u64 val)
  79630. +{
  79631. + desc->quad[desc->quad_cnt++] = val;
  79632. + desc->size = (desc->quad_cnt + 1) / 2;
  79633. +}
  79634. +
  79635. +static void pasemi_desc_hdr(struct pasemi_desc *desc, u64 hdr)
  79636. +{
  79637. + desc->quad[0] |= hdr;
  79638. +}
  79639. +
  79640. +static int pasemi_desc_size(struct pasemi_desc *desc)
  79641. +{
  79642. + return desc->size;
  79643. +}
  79644. +
  79645. +static void pasemi_ring_add_desc(
  79646. + struct pasemi_fnu_txring *ring,
  79647. + struct pasemi_desc *desc,
  79648. + struct cryptop *crp) {
  79649. + int i;
  79650. + int ring_index = 2 * (ring->next_to_fill & (TX_RING_SIZE-1));
  79651. +
  79652. + TX_DESC_INFO(ring, ring->next_to_fill).desc_size = desc->size;
  79653. + TX_DESC_INFO(ring, ring->next_to_fill).desc_postop = desc->postop;
  79654. + TX_DESC_INFO(ring, ring->next_to_fill).cf_crp = crp;
  79655. +
  79656. + for (i = 0; i < desc->quad_cnt; i += 2) {
  79657. + ring_index = 2 * (ring->next_to_fill & (TX_RING_SIZE-1));
  79658. + ring->desc[ring_index] = desc->quad[i];
  79659. + ring->desc[ring_index + 1] = desc->quad[i + 1];
  79660. + ring->next_to_fill++;
  79661. + }
  79662. +
  79663. + if (desc->quad_cnt & 1)
  79664. + ring->desc[ring_index + 1] = 0;
  79665. +}
  79666. +
  79667. +static void pasemi_ring_incr(struct pasemi_softc *sc, int chan_index, int incr)
  79668. +{
  79669. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_INCR(sc->base_chan + chan_index),
  79670. + incr);
  79671. +}
  79672. +
  79673. +/*
  79674. + * Generate a new software session.
  79675. + */
  79676. +static int
  79677. +pasemi_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  79678. +{
  79679. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  79680. + struct pasemi_softc *sc = device_get_softc(dev);
  79681. + struct pasemi_session *ses = NULL, **sespp;
  79682. + int sesn, blksz = 0;
  79683. + u64 ccmd = 0;
  79684. + unsigned long flags;
  79685. + struct pasemi_desc init_desc;
  79686. + struct pasemi_fnu_txring *txring;
  79687. +
  79688. + DPRINTF("%s()\n", __FUNCTION__);
  79689. + if (sidp == NULL || cri == NULL || sc == NULL) {
  79690. + DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);
  79691. + return -EINVAL;
  79692. + }
  79693. + for (c = cri; c != NULL; c = c->cri_next) {
  79694. + if (ALG_IS_SIG(c->cri_alg)) {
  79695. + if (macini)
  79696. + return -EINVAL;
  79697. + macini = c;
  79698. + } else if (ALG_IS_CIPHER(c->cri_alg)) {
  79699. + if (encini)
  79700. + return -EINVAL;
  79701. + encini = c;
  79702. + } else {
  79703. + DPRINTF("UNKNOWN c->cri_alg %d\n", c->cri_alg);
  79704. + return -EINVAL;
  79705. + }
  79706. + }
  79707. + if (encini == NULL && macini == NULL)
  79708. + return -EINVAL;
  79709. + if (encini) {
  79710. + /* validate key length */
  79711. + switch (encini->cri_alg) {
  79712. + case CRYPTO_DES_CBC:
  79713. + if (encini->cri_klen != 64)
  79714. + return -EINVAL;
  79715. + ccmd = DMA_CALGO_DES;
  79716. + break;
  79717. + case CRYPTO_3DES_CBC:
  79718. + if (encini->cri_klen != 192)
  79719. + return -EINVAL;
  79720. + ccmd = DMA_CALGO_3DES;
  79721. + break;
  79722. + case CRYPTO_AES_CBC:
  79723. + if (encini->cri_klen != 128 &&
  79724. + encini->cri_klen != 192 &&
  79725. + encini->cri_klen != 256)
  79726. + return -EINVAL;
  79727. + ccmd = DMA_CALGO_AES;
  79728. + break;
  79729. + case CRYPTO_ARC4:
  79730. + if (encini->cri_klen != 128)
  79731. + return -EINVAL;
  79732. + ccmd = DMA_CALGO_ARC;
  79733. + break;
  79734. + default:
  79735. + DPRINTF("UNKNOWN encini->cri_alg %d\n",
  79736. + encini->cri_alg);
  79737. + return -EINVAL;
  79738. + }
  79739. + }
  79740. +
  79741. + if (macini) {
  79742. + switch (macini->cri_alg) {
  79743. + case CRYPTO_MD5:
  79744. + case CRYPTO_MD5_HMAC:
  79745. + blksz = 16;
  79746. + break;
  79747. + case CRYPTO_SHA1:
  79748. + case CRYPTO_SHA1_HMAC:
  79749. + blksz = 20;
  79750. + break;
  79751. + default:
  79752. + DPRINTF("UNKNOWN macini->cri_alg %d\n",
  79753. + macini->cri_alg);
  79754. + return -EINVAL;
  79755. + }
  79756. + if (((macini->cri_klen + 7) / 8) > blksz) {
  79757. + DPRINTF("key length %d bigger than blksize %d not supported\n",
  79758. + ((macini->cri_klen + 7) / 8), blksz);
  79759. + return -EINVAL;
  79760. + }
  79761. + }
  79762. +
  79763. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  79764. + if (sc->sc_sessions[sesn] == NULL) {
  79765. + sc->sc_sessions[sesn] = (struct pasemi_session *)
  79766. + kzalloc(sizeof(struct pasemi_session), GFP_ATOMIC);
  79767. + ses = sc->sc_sessions[sesn];
  79768. + break;
  79769. + } else if (sc->sc_sessions[sesn]->used == 0) {
  79770. + ses = sc->sc_sessions[sesn];
  79771. + break;
  79772. + }
  79773. + }
  79774. +
  79775. + if (ses == NULL) {
  79776. + sespp = (struct pasemi_session **)
  79777. + kzalloc(sc->sc_nsessions * 2 *
  79778. + sizeof(struct pasemi_session *), GFP_ATOMIC);
  79779. + if (sespp == NULL)
  79780. + return -ENOMEM;
  79781. + memcpy(sespp, sc->sc_sessions,
  79782. + sc->sc_nsessions * sizeof(struct pasemi_session *));
  79783. + kfree(sc->sc_sessions);
  79784. + sc->sc_sessions = sespp;
  79785. + sesn = sc->sc_nsessions;
  79786. + ses = sc->sc_sessions[sesn] = (struct pasemi_session *)
  79787. + kzalloc(sizeof(struct pasemi_session), GFP_ATOMIC);
  79788. + if (ses == NULL)
  79789. + return -ENOMEM;
  79790. + sc->sc_nsessions *= 2;
  79791. + }
  79792. +
  79793. + ses->used = 1;
  79794. +
  79795. + ses->dma_addr = pci_map_single(sc->dma_pdev, (void *) ses->civ,
  79796. + sizeof(struct pasemi_session), DMA_TO_DEVICE);
  79797. +
  79798. + /* enter the channel scheduler */
  79799. + spin_lock_irqsave(&sc->sc_chnlock, flags);
  79800. +
  79801. + /* ARC4 has to be processed by the even channel */
  79802. + if (encini && (encini->cri_alg == CRYPTO_ARC4))
  79803. + ses->chan = sc->sc_lastchn & ~1;
  79804. + else
  79805. + ses->chan = sc->sc_lastchn;
  79806. + sc->sc_lastchn = (sc->sc_lastchn + 1) % sc->sc_num_channels;
  79807. +
  79808. + spin_unlock_irqrestore(&sc->sc_chnlock, flags);
  79809. +
  79810. + txring = &sc->tx[ses->chan];
  79811. +
  79812. + if (encini) {
  79813. + ses->ccmd = ccmd;
  79814. +
  79815. + /* get an IV */
  79816. + /* XXX may read fewer than requested */
  79817. + get_random_bytes(ses->civ, sizeof(ses->civ));
  79818. +
  79819. + ses->keysz = (encini->cri_klen - 63) / 64;
  79820. + memcpy(ses->key, encini->cri_key, (ses->keysz + 1) * 8);
  79821. +
  79822. + pasemi_desc_start(&init_desc,
  79823. + XCT_CTRL_HDR(ses->chan, (encini && macini) ? 0x68 : 0x40, DMA_FN_CIV0));
  79824. + pasemi_desc_build(&init_desc,
  79825. + XCT_FUN_SRC_PTR((encini && macini) ? 0x68 : 0x40, ses->dma_addr));
  79826. + }
  79827. + if (macini) {
  79828. + if (macini->cri_alg == CRYPTO_MD5_HMAC ||
  79829. + macini->cri_alg == CRYPTO_SHA1_HMAC)
  79830. + memcpy(ses->hkey, macini->cri_key, blksz);
  79831. + else {
  79832. + /* Load initialization constants(RFC 1321, 3174) */
  79833. + ses->hiv[0] = 0x67452301efcdab89ULL;
  79834. + ses->hiv[1] = 0x98badcfe10325476ULL;
  79835. + ses->hiv[2] = 0xc3d2e1f000000000ULL;
  79836. + }
  79837. + ses->hseq = 0ULL;
  79838. + }
  79839. +
  79840. + spin_lock_irqsave(&txring->fill_lock, flags);
  79841. +
  79842. + if (((txring->next_to_fill + pasemi_desc_size(&init_desc)) -
  79843. + txring->next_to_clean) > TX_RING_SIZE) {
  79844. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  79845. + return ERESTART;
  79846. + }
  79847. +
  79848. + if (encini) {
  79849. + pasemi_ring_add_desc(txring, &init_desc, NULL);
  79850. + pasemi_ring_incr(sc, ses->chan,
  79851. + pasemi_desc_size(&init_desc));
  79852. + }
  79853. +
  79854. + txring->sesn = sesn;
  79855. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  79856. +
  79857. + *sidp = PASEMI_SID(sesn);
  79858. + return 0;
  79859. +}
  79860. +
  79861. +/*
  79862. + * Deallocate a session.
  79863. + */
  79864. +static int
  79865. +pasemi_freesession(device_t dev, u_int64_t tid)
  79866. +{
  79867. + struct pasemi_softc *sc = device_get_softc(dev);
  79868. + int session;
  79869. + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
  79870. +
  79871. + DPRINTF("%s()\n", __FUNCTION__);
  79872. +
  79873. + if (sc == NULL)
  79874. + return -EINVAL;
  79875. + session = PASEMI_SESSION(sid);
  79876. + if (session >= sc->sc_nsessions || !sc->sc_sessions[session])
  79877. + return -EINVAL;
  79878. +
  79879. + pci_unmap_single(sc->dma_pdev,
  79880. + sc->sc_sessions[session]->dma_addr,
  79881. + sizeof(struct pasemi_session), DMA_TO_DEVICE);
  79882. + memset(sc->sc_sessions[session], 0,
  79883. + sizeof(struct pasemi_session));
  79884. +
  79885. + return 0;
  79886. +}
  79887. +
  79888. +static int
  79889. +pasemi_process(device_t dev, struct cryptop *crp, int hint)
  79890. +{
  79891. +
  79892. + int err = 0, ivsize, srclen = 0, reinit = 0, reinit_size = 0, chsel;
  79893. + struct pasemi_softc *sc = device_get_softc(dev);
  79894. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  79895. + caddr_t ivp;
  79896. + struct pasemi_desc init_desc, work_desc;
  79897. + struct pasemi_session *ses;
  79898. + struct sk_buff *skb;
  79899. + struct uio *uiop;
  79900. + unsigned long flags;
  79901. + struct pasemi_fnu_txring *txring;
  79902. +
  79903. + DPRINTF("%s()\n", __FUNCTION__);
  79904. +
  79905. + if (crp == NULL || crp->crp_callback == NULL || sc == NULL)
  79906. + return -EINVAL;
  79907. +
  79908. + crp->crp_etype = 0;
  79909. + if (PASEMI_SESSION(crp->crp_sid) >= sc->sc_nsessions)
  79910. + return -EINVAL;
  79911. +
  79912. + ses = sc->sc_sessions[PASEMI_SESSION(crp->crp_sid)];
  79913. +
  79914. + crd1 = crp->crp_desc;
  79915. + if (crd1 == NULL) {
  79916. + err = -EINVAL;
  79917. + goto errout;
  79918. + }
  79919. + crd2 = crd1->crd_next;
  79920. +
  79921. + if (ALG_IS_SIG(crd1->crd_alg)) {
  79922. + maccrd = crd1;
  79923. + if (crd2 == NULL)
  79924. + enccrd = NULL;
  79925. + else if (ALG_IS_CIPHER(crd2->crd_alg) &&
  79926. + (crd2->crd_flags & CRD_F_ENCRYPT) == 0)
  79927. + enccrd = crd2;
  79928. + else
  79929. + goto erralg;
  79930. + } else if (ALG_IS_CIPHER(crd1->crd_alg)) {
  79931. + enccrd = crd1;
  79932. + if (crd2 == NULL)
  79933. + maccrd = NULL;
  79934. + else if (ALG_IS_SIG(crd2->crd_alg) &&
  79935. + (crd1->crd_flags & CRD_F_ENCRYPT))
  79936. + maccrd = crd2;
  79937. + else
  79938. + goto erralg;
  79939. + } else
  79940. + goto erralg;
  79941. +
  79942. + chsel = ses->chan;
  79943. +
  79944. + txring = &sc->tx[chsel];
  79945. +
  79946. + if (enccrd && !maccrd) {
  79947. + if (enccrd->crd_alg == CRYPTO_ARC4)
  79948. + reinit = 1;
  79949. + reinit_size = 0x40;
  79950. + srclen = crp->crp_ilen;
  79951. +
  79952. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I
  79953. + | XCT_FUN_FUN(chsel));
  79954. + if (enccrd->crd_flags & CRD_F_ENCRYPT)
  79955. + pasemi_desc_hdr(&work_desc, XCT_FUN_CRM_ENC);
  79956. + else
  79957. + pasemi_desc_hdr(&work_desc, XCT_FUN_CRM_DEC);
  79958. + } else if (enccrd && maccrd) {
  79959. + if (enccrd->crd_alg == CRYPTO_ARC4)
  79960. + reinit = 1;
  79961. + reinit_size = 0x68;
  79962. +
  79963. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  79964. + /* Encrypt -> Authenticate */
  79965. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_ENC_SIG
  79966. + | XCT_FUN_A | XCT_FUN_FUN(chsel));
  79967. + srclen = maccrd->crd_skip + maccrd->crd_len;
  79968. + } else {
  79969. + /* Authenticate -> Decrypt */
  79970. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_SIG_DEC
  79971. + | XCT_FUN_24BRES | XCT_FUN_FUN(chsel));
  79972. + pasemi_desc_build(&work_desc, 0);
  79973. + pasemi_desc_build(&work_desc, 0);
  79974. + pasemi_desc_build(&work_desc, 0);
  79975. + work_desc.postop = PASEMI_CHECK_SIG;
  79976. + srclen = crp->crp_ilen;
  79977. + }
  79978. +
  79979. + pasemi_desc_hdr(&work_desc, XCT_FUN_SHL(maccrd->crd_skip / 4));
  79980. + pasemi_desc_hdr(&work_desc, XCT_FUN_CHL(enccrd->crd_skip - maccrd->crd_skip));
  79981. + } else if (!enccrd && maccrd) {
  79982. + srclen = maccrd->crd_len;
  79983. +
  79984. + pasemi_desc_start(&init_desc,
  79985. + XCT_CTRL_HDR(chsel, 0x58, DMA_FN_HKEY0));
  79986. + pasemi_desc_build(&init_desc,
  79987. + XCT_FUN_SRC_PTR(0x58, ((struct pasemi_session *)ses->dma_addr)->hkey));
  79988. +
  79989. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_SIG
  79990. + | XCT_FUN_A | XCT_FUN_FUN(chsel));
  79991. + }
  79992. +
  79993. + if (enccrd) {
  79994. + switch (enccrd->crd_alg) {
  79995. + case CRYPTO_3DES_CBC:
  79996. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_3DES |
  79997. + XCT_FUN_BCM_CBC);
  79998. + ivsize = sizeof(u64);
  79999. + break;
  80000. + case CRYPTO_DES_CBC:
  80001. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_DES |
  80002. + XCT_FUN_BCM_CBC);
  80003. + ivsize = sizeof(u64);
  80004. + break;
  80005. + case CRYPTO_AES_CBC:
  80006. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_AES |
  80007. + XCT_FUN_BCM_CBC);
  80008. + ivsize = 2 * sizeof(u64);
  80009. + break;
  80010. + case CRYPTO_ARC4:
  80011. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_ARC);
  80012. + ivsize = 0;
  80013. + break;
  80014. + default:
  80015. + printk(DRV_NAME ": unimplemented enccrd->crd_alg %d\n",
  80016. + enccrd->crd_alg);
  80017. + err = -EINVAL;
  80018. + goto errout;
  80019. + }
  80020. +
  80021. + ivp = (ivsize == sizeof(u64)) ? (caddr_t) &ses->civ[1] : (caddr_t) &ses->civ[0];
  80022. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  80023. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  80024. + memcpy(ivp, enccrd->crd_iv, ivsize);
  80025. + /* If IV is not present in the buffer already, it has to be copied there */
  80026. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0)
  80027. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  80028. + enccrd->crd_inject, ivsize, ivp);
  80029. + } else {
  80030. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  80031. + /* IV is provided expicitly in descriptor */
  80032. + memcpy(ivp, enccrd->crd_iv, ivsize);
  80033. + else
  80034. + /* IV is provided in the packet */
  80035. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  80036. + enccrd->crd_inject, ivsize,
  80037. + ivp);
  80038. + }
  80039. + }
  80040. +
  80041. + if (maccrd) {
  80042. + switch (maccrd->crd_alg) {
  80043. + case CRYPTO_MD5:
  80044. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_MD5 |
  80045. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  80046. + break;
  80047. + case CRYPTO_SHA1:
  80048. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_SHA1 |
  80049. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  80050. + break;
  80051. + case CRYPTO_MD5_HMAC:
  80052. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_HMAC_MD5 |
  80053. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  80054. + break;
  80055. + case CRYPTO_SHA1_HMAC:
  80056. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_HMAC_SHA1 |
  80057. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  80058. + break;
  80059. + default:
  80060. + printk(DRV_NAME ": unimplemented maccrd->crd_alg %d\n",
  80061. + maccrd->crd_alg);
  80062. + err = -EINVAL;
  80063. + goto errout;
  80064. + }
  80065. + }
  80066. +
  80067. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  80068. + /* using SKB buffers */
  80069. + skb = (struct sk_buff *)crp->crp_buf;
  80070. + if (skb_shinfo(skb)->nr_frags) {
  80071. + printk(DRV_NAME ": skb frags unimplemented\n");
  80072. + err = -EINVAL;
  80073. + goto errout;
  80074. + }
  80075. + pasemi_desc_build(
  80076. + &work_desc,
  80077. + XCT_FUN_DST_PTR(skb->len, pci_map_single(
  80078. + sc->dma_pdev, skb->data,
  80079. + skb->len, DMA_TO_DEVICE)));
  80080. + pasemi_desc_build(
  80081. + &work_desc,
  80082. + XCT_FUN_SRC_PTR(
  80083. + srclen, pci_map_single(
  80084. + sc->dma_pdev, skb->data,
  80085. + srclen, DMA_TO_DEVICE)));
  80086. + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
  80087. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  80088. + /* using IOV buffers */
  80089. + uiop = (struct uio *)crp->crp_buf;
  80090. + if (uiop->uio_iovcnt > 1) {
  80091. + printk(DRV_NAME ": iov frags unimplemented\n");
  80092. + err = -EINVAL;
  80093. + goto errout;
  80094. + }
  80095. +
  80096. + /* crp_olen is never set; always use crp_ilen */
  80097. + pasemi_desc_build(
  80098. + &work_desc,
  80099. + XCT_FUN_DST_PTR(crp->crp_ilen, pci_map_single(
  80100. + sc->dma_pdev,
  80101. + uiop->uio_iov->iov_base,
  80102. + crp->crp_ilen, DMA_TO_DEVICE)));
  80103. + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
  80104. +
  80105. + pasemi_desc_build(
  80106. + &work_desc,
  80107. + XCT_FUN_SRC_PTR(srclen, pci_map_single(
  80108. + sc->dma_pdev,
  80109. + uiop->uio_iov->iov_base,
  80110. + srclen, DMA_TO_DEVICE)));
  80111. + } else {
  80112. + /* using contig buffers */
  80113. + pasemi_desc_build(
  80114. + &work_desc,
  80115. + XCT_FUN_DST_PTR(crp->crp_ilen, pci_map_single(
  80116. + sc->dma_pdev,
  80117. + crp->crp_buf,
  80118. + crp->crp_ilen, DMA_TO_DEVICE)));
  80119. + pasemi_desc_build(
  80120. + &work_desc,
  80121. + XCT_FUN_SRC_PTR(srclen, pci_map_single(
  80122. + sc->dma_pdev,
  80123. + crp->crp_buf, srclen,
  80124. + DMA_TO_DEVICE)));
  80125. + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
  80126. + }
  80127. +
  80128. + spin_lock_irqsave(&txring->fill_lock, flags);
  80129. +
  80130. + if (txring->sesn != PASEMI_SESSION(crp->crp_sid)) {
  80131. + txring->sesn = PASEMI_SESSION(crp->crp_sid);
  80132. + reinit = 1;
  80133. + }
  80134. +
  80135. + if (enccrd) {
  80136. + pasemi_desc_start(&init_desc,
  80137. + XCT_CTRL_HDR(chsel, reinit ? reinit_size : 0x10, DMA_FN_CIV0));
  80138. + pasemi_desc_build(&init_desc,
  80139. + XCT_FUN_SRC_PTR(reinit ? reinit_size : 0x10, ses->dma_addr));
  80140. + }
  80141. +
  80142. + if (((txring->next_to_fill + pasemi_desc_size(&init_desc) +
  80143. + pasemi_desc_size(&work_desc)) -
  80144. + txring->next_to_clean) > TX_RING_SIZE) {
  80145. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  80146. + err = ERESTART;
  80147. + goto errout;
  80148. + }
  80149. +
  80150. + pasemi_ring_add_desc(txring, &init_desc, NULL);
  80151. + pasemi_ring_add_desc(txring, &work_desc, crp);
  80152. +
  80153. + pasemi_ring_incr(sc, chsel,
  80154. + pasemi_desc_size(&init_desc) +
  80155. + pasemi_desc_size(&work_desc));
  80156. +
  80157. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  80158. +
  80159. + mod_timer(&txring->crypto_timer, jiffies + TIMER_INTERVAL);
  80160. +
  80161. + return 0;
  80162. +
  80163. +erralg:
  80164. + printk(DRV_NAME ": unsupported algorithm or algorithm order alg1 %d alg2 %d\n",
  80165. + crd1->crd_alg, crd2->crd_alg);
  80166. + err = -EINVAL;
  80167. +
  80168. +errout:
  80169. + if (err != ERESTART) {
  80170. + crp->crp_etype = err;
  80171. + crypto_done(crp);
  80172. + }
  80173. + return err;
  80174. +}
  80175. +
  80176. +static int pasemi_clean_tx(struct pasemi_softc *sc, int chan)
  80177. +{
  80178. + int i, j, ring_idx;
  80179. + struct pasemi_fnu_txring *ring = &sc->tx[chan];
  80180. + u16 delta_cnt;
  80181. + int flags, loops = 10;
  80182. + int desc_size;
  80183. + struct cryptop *crp;
  80184. +
  80185. + spin_lock_irqsave(&ring->clean_lock, flags);
  80186. +
  80187. + while ((delta_cnt = (dma_status->tx_sta[sc->base_chan + chan]
  80188. + & PAS_STATUS_PCNT_M) - ring->total_pktcnt)
  80189. + && loops--) {
  80190. +
  80191. + for (i = 0; i < delta_cnt; i++) {
  80192. + desc_size = TX_DESC_INFO(ring, ring->next_to_clean).desc_size;
  80193. + crp = TX_DESC_INFO(ring, ring->next_to_clean).cf_crp;
  80194. + if (crp) {
  80195. + ring_idx = 2 * (ring->next_to_clean & (TX_RING_SIZE-1));
  80196. + if (TX_DESC_INFO(ring, ring->next_to_clean).desc_postop & PASEMI_CHECK_SIG) {
  80197. + /* Need to make sure signature matched,
  80198. + * if not - return error */
  80199. + if (!(ring->desc[ring_idx + 1] & (1ULL << 63)))
  80200. + crp->crp_etype = -EINVAL;
  80201. + }
  80202. + crypto_done(TX_DESC_INFO(ring,
  80203. + ring->next_to_clean).cf_crp);
  80204. + TX_DESC_INFO(ring, ring->next_to_clean).cf_crp = NULL;
  80205. + pci_unmap_single(
  80206. + sc->dma_pdev,
  80207. + XCT_PTR_ADDR_LEN(ring->desc[ring_idx + 1]),
  80208. + PCI_DMA_TODEVICE);
  80209. +
  80210. + ring->desc[ring_idx] = ring->desc[ring_idx + 1] = 0;
  80211. +
  80212. + ring->next_to_clean++;
  80213. + for (j = 1; j < desc_size; j++) {
  80214. + ring_idx = 2 *
  80215. + (ring->next_to_clean &
  80216. + (TX_RING_SIZE-1));
  80217. + pci_unmap_single(
  80218. + sc->dma_pdev,
  80219. + XCT_PTR_ADDR_LEN(ring->desc[ring_idx]),
  80220. + PCI_DMA_TODEVICE);
  80221. + if (ring->desc[ring_idx + 1])
  80222. + pci_unmap_single(
  80223. + sc->dma_pdev,
  80224. + XCT_PTR_ADDR_LEN(
  80225. + ring->desc[
  80226. + ring_idx + 1]),
  80227. + PCI_DMA_TODEVICE);
  80228. + ring->desc[ring_idx] =
  80229. + ring->desc[ring_idx + 1] = 0;
  80230. + ring->next_to_clean++;
  80231. + }
  80232. + } else {
  80233. + for (j = 0; j < desc_size; j++) {
  80234. + ring_idx = 2 * (ring->next_to_clean & (TX_RING_SIZE-1));
  80235. + ring->desc[ring_idx] =
  80236. + ring->desc[ring_idx + 1] = 0;
  80237. + ring->next_to_clean++;
  80238. + }
  80239. + }
  80240. + }
  80241. +
  80242. + ring->total_pktcnt += delta_cnt;
  80243. + }
  80244. + spin_unlock_irqrestore(&ring->clean_lock, flags);
  80245. +
  80246. + return 0;
  80247. +}
  80248. +
  80249. +static void sweepup_tx(struct pasemi_softc *sc)
  80250. +{
  80251. + int i;
  80252. +
  80253. + for (i = 0; i < sc->sc_num_channels; i++)
  80254. + pasemi_clean_tx(sc, i);
  80255. +}
  80256. +
  80257. +static irqreturn_t pasemi_intr(int irq, void *arg, struct pt_regs *regs)
  80258. +{
  80259. + struct pasemi_softc *sc = arg;
  80260. + unsigned int reg;
  80261. + int chan = irq - sc->base_irq;
  80262. + int chan_index = sc->base_chan + chan;
  80263. + u64 stat = dma_status->tx_sta[chan_index];
  80264. +
  80265. + DPRINTF("%s()\n", __FUNCTION__);
  80266. +
  80267. + if (!(stat & PAS_STATUS_CAUSE_M))
  80268. + return IRQ_NONE;
  80269. +
  80270. + pasemi_clean_tx(sc, chan);
  80271. +
  80272. + stat = dma_status->tx_sta[chan_index];
  80273. +
  80274. + reg = PAS_IOB_DMA_TXCH_RESET_PINTC |
  80275. + PAS_IOB_DMA_TXCH_RESET_PCNT(sc->tx[chan].total_pktcnt);
  80276. +
  80277. + if (stat & PAS_STATUS_SOFT)
  80278. + reg |= PAS_IOB_DMA_RXCH_RESET_SINTC;
  80279. +
  80280. + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), reg);
  80281. +
  80282. +
  80283. + return IRQ_HANDLED;
  80284. +}
  80285. +
  80286. +static int pasemi_dma_setup_tx_resources(struct pasemi_softc *sc, int chan)
  80287. +{
  80288. + u32 val;
  80289. + int chan_index = chan + sc->base_chan;
  80290. + int ret;
  80291. + struct pasemi_fnu_txring *ring;
  80292. +
  80293. + ring = &sc->tx[chan];
  80294. +
  80295. + spin_lock_init(&ring->fill_lock);
  80296. + spin_lock_init(&ring->clean_lock);
  80297. +
  80298. + ring->desc_info = kzalloc(sizeof(struct pasemi_desc_info) *
  80299. + TX_RING_SIZE, GFP_KERNEL);
  80300. + if (!ring->desc_info)
  80301. + return -ENOMEM;
  80302. +
  80303. + /* Allocate descriptors */
  80304. + ring->desc = dma_alloc_coherent(&sc->dma_pdev->dev,
  80305. + TX_RING_SIZE *
  80306. + 2 * sizeof(u64),
  80307. + &ring->dma, GFP_KERNEL);
  80308. + if (!ring->desc)
  80309. + return -ENOMEM;
  80310. +
  80311. + memset((void *) ring->desc, 0, TX_RING_SIZE * 2 * sizeof(u64));
  80312. +
  80313. + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), 0x30);
  80314. +
  80315. + ring->total_pktcnt = 0;
  80316. +
  80317. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEL(chan_index),
  80318. + PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma));
  80319. +
  80320. + val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32);
  80321. + val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 2);
  80322. +
  80323. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEU(chan_index), val);
  80324. +
  80325. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_CFG(chan_index),
  80326. + PAS_DMA_TXCHAN_CFG_TY_FUNC |
  80327. + PAS_DMA_TXCHAN_CFG_TATTR(chan) |
  80328. + PAS_DMA_TXCHAN_CFG_WT(2));
  80329. +
  80330. + /* enable tx channel */
  80331. + out_le32(sc->dma_regs +
  80332. + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
  80333. + PAS_DMA_TXCHAN_TCMDSTA_EN);
  80334. +
  80335. + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_CFG(chan_index),
  80336. + PAS_IOB_DMA_TXCH_CFG_CNTTH(1000));
  80337. +
  80338. + ring->next_to_fill = 0;
  80339. + ring->next_to_clean = 0;
  80340. +
  80341. + snprintf(ring->irq_name, sizeof(ring->irq_name),
  80342. + "%s%d", "crypto", chan);
  80343. +
  80344. + ring->irq = irq_create_mapping(NULL, sc->base_irq + chan);
  80345. + ret = request_irq(ring->irq, (irq_handler_t)
  80346. + pasemi_intr, IRQF_DISABLED, ring->irq_name, sc);
  80347. + if (ret) {
  80348. + printk(KERN_ERR DRV_NAME ": failed to hook irq %d ret %d\n",
  80349. + ring->irq, ret);
  80350. + ring->irq = -1;
  80351. + return ret;
  80352. + }
  80353. +
  80354. + setup_timer(&ring->crypto_timer, (void *) sweepup_tx, (unsigned long) sc);
  80355. +
  80356. + return 0;
  80357. +}
  80358. +
  80359. +static device_method_t pasemi_methods = {
  80360. + /* crypto device methods */
  80361. + DEVMETHOD(cryptodev_newsession, pasemi_newsession),
  80362. + DEVMETHOD(cryptodev_freesession, pasemi_freesession),
  80363. + DEVMETHOD(cryptodev_process, pasemi_process),
  80364. +};
  80365. +
  80366. +/* Set up the crypto device structure, private data,
  80367. + * and anything else we need before we start */
  80368. +
  80369. +static int __devinit
  80370. +pasemi_dma_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  80371. +{
  80372. + struct pasemi_softc *sc;
  80373. + int ret, i;
  80374. +
  80375. + DPRINTF(KERN_ERR "%s()\n", __FUNCTION__);
  80376. +
  80377. + sc = kzalloc(sizeof(*sc), GFP_KERNEL);
  80378. + if (!sc)
  80379. + return -ENOMEM;
  80380. +
  80381. + softc_device_init(sc, DRV_NAME, 1, pasemi_methods);
  80382. +
  80383. + pci_set_drvdata(pdev, sc);
  80384. +
  80385. + spin_lock_init(&sc->sc_chnlock);
  80386. +
  80387. + sc->sc_sessions = (struct pasemi_session **)
  80388. + kzalloc(PASEMI_INITIAL_SESSIONS *
  80389. + sizeof(struct pasemi_session *), GFP_ATOMIC);
  80390. + if (sc->sc_sessions == NULL) {
  80391. + ret = -ENOMEM;
  80392. + goto out;
  80393. + }
  80394. +
  80395. + sc->sc_nsessions = PASEMI_INITIAL_SESSIONS;
  80396. + sc->sc_lastchn = 0;
  80397. + sc->base_irq = pdev->irq + 6;
  80398. + sc->base_chan = 6;
  80399. + sc->sc_cid = -1;
  80400. + sc->dma_pdev = pdev;
  80401. +
  80402. + sc->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
  80403. + if (!sc->iob_pdev) {
  80404. + dev_err(&pdev->dev, "Can't find I/O Bridge\n");
  80405. + ret = -ENODEV;
  80406. + goto out;
  80407. + }
  80408. +
  80409. + /* This is hardcoded and ugly, but we have some firmware versions
  80410. + * who don't provide the register space in the device tree. Luckily
  80411. + * they are at well-known locations so we can just do the math here.
  80412. + */
  80413. + sc->dma_regs =
  80414. + ioremap(0xe0000000 + (sc->dma_pdev->devfn << 12), 0x2000);
  80415. + sc->iob_regs =
  80416. + ioremap(0xe0000000 + (sc->iob_pdev->devfn << 12), 0x2000);
  80417. + if (!sc->dma_regs || !sc->iob_regs) {
  80418. + dev_err(&pdev->dev, "Can't map registers\n");
  80419. + ret = -ENODEV;
  80420. + goto out;
  80421. + }
  80422. +
  80423. + dma_status = __ioremap(0xfd800000, 0x1000, 0);
  80424. + if (!dma_status) {
  80425. + ret = -ENODEV;
  80426. + dev_err(&pdev->dev, "Can't map dmastatus space\n");
  80427. + goto out;
  80428. + }
  80429. +
  80430. + sc->tx = (struct pasemi_fnu_txring *)
  80431. + kzalloc(sizeof(struct pasemi_fnu_txring)
  80432. + * 8, GFP_KERNEL);
  80433. + if (!sc->tx) {
  80434. + ret = -ENOMEM;
  80435. + goto out;
  80436. + }
  80437. +
  80438. + /* Initialize the h/w */
  80439. + out_le32(sc->dma_regs + PAS_DMA_COM_CFG,
  80440. + (in_le32(sc->dma_regs + PAS_DMA_COM_CFG) |
  80441. + PAS_DMA_COM_CFG_FWF));
  80442. + out_le32(sc->dma_regs + PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN);
  80443. +
  80444. + for (i = 0; i < PASEMI_FNU_CHANNELS; i++) {
  80445. + sc->sc_num_channels++;
  80446. + ret = pasemi_dma_setup_tx_resources(sc, i);
  80447. + if (ret)
  80448. + goto out;
  80449. + }
  80450. +
  80451. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),
  80452. + CRYPTOCAP_F_HARDWARE);
  80453. + if (sc->sc_cid < 0) {
  80454. + printk(KERN_ERR DRV_NAME ": could not get crypto driver id\n");
  80455. + ret = -ENXIO;
  80456. + goto out;
  80457. + }
  80458. +
  80459. + /* register algorithms with the framework */
  80460. + printk(DRV_NAME ":");
  80461. +
  80462. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  80463. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  80464. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  80465. + crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
  80466. + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
  80467. + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
  80468. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  80469. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  80470. +
  80471. + return 0;
  80472. +
  80473. +out:
  80474. + pasemi_dma_remove(pdev);
  80475. + return ret;
  80476. +}
  80477. +
  80478. +#define MAX_RETRIES 5000
  80479. +
  80480. +static void pasemi_free_tx_resources(struct pasemi_softc *sc, int chan)
  80481. +{
  80482. + struct pasemi_fnu_txring *ring = &sc->tx[chan];
  80483. + int chan_index = chan + sc->base_chan;
  80484. + int retries;
  80485. + u32 stat;
  80486. +
  80487. + /* Stop the channel */
  80488. + out_le32(sc->dma_regs +
  80489. + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
  80490. + PAS_DMA_TXCHAN_TCMDSTA_ST);
  80491. +
  80492. + for (retries = 0; retries < MAX_RETRIES; retries++) {
  80493. + stat = in_le32(sc->dma_regs +
  80494. + PAS_DMA_TXCHAN_TCMDSTA(chan_index));
  80495. + if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT))
  80496. + break;
  80497. + cond_resched();
  80498. + }
  80499. +
  80500. + if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)
  80501. + dev_err(&sc->dma_pdev->dev, "Failed to stop tx channel %d\n",
  80502. + chan_index);
  80503. +
  80504. + /* Disable the channel */
  80505. + out_le32(sc->dma_regs +
  80506. + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
  80507. + 0);
  80508. +
  80509. + if (ring->desc_info)
  80510. + kfree((void *) ring->desc_info);
  80511. + if (ring->desc)
  80512. + dma_free_coherent(&sc->dma_pdev->dev,
  80513. + TX_RING_SIZE *
  80514. + 2 * sizeof(u64),
  80515. + (void *) ring->desc, ring->dma);
  80516. + if (ring->irq != -1)
  80517. + free_irq(ring->irq, sc);
  80518. +
  80519. + del_timer(&ring->crypto_timer);
  80520. +}
  80521. +
  80522. +static void __devexit pasemi_dma_remove(struct pci_dev *pdev)
  80523. +{
  80524. + struct pasemi_softc *sc = pci_get_drvdata(pdev);
  80525. + int i;
  80526. +
  80527. + DPRINTF("%s()\n", __FUNCTION__);
  80528. +
  80529. + if (sc->sc_cid >= 0) {
  80530. + crypto_unregister_all(sc->sc_cid);
  80531. + }
  80532. +
  80533. + if (sc->tx) {
  80534. + for (i = 0; i < sc->sc_num_channels; i++)
  80535. + pasemi_free_tx_resources(sc, i);
  80536. +
  80537. + kfree(sc->tx);
  80538. + }
  80539. + if (sc->sc_sessions) {
  80540. + for (i = 0; i < sc->sc_nsessions; i++)
  80541. + kfree(sc->sc_sessions[i]);
  80542. + kfree(sc->sc_sessions);
  80543. + }
  80544. + if (sc->iob_pdev)
  80545. + pci_dev_put(sc->iob_pdev);
  80546. + if (sc->dma_regs)
  80547. + iounmap(sc->dma_regs);
  80548. + if (sc->iob_regs)
  80549. + iounmap(sc->iob_regs);
  80550. + kfree(sc);
  80551. +}
  80552. +
  80553. +static struct pci_device_id pasemi_dma_pci_tbl[] = {
  80554. + { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa007) },
  80555. +};
  80556. +
  80557. +MODULE_DEVICE_TABLE(pci, pasemi_dma_pci_tbl);
  80558. +
  80559. +static struct pci_driver pasemi_dma_driver = {
  80560. + .name = "pasemi_dma",
  80561. + .id_table = pasemi_dma_pci_tbl,
  80562. + .probe = pasemi_dma_probe,
  80563. + .remove = __devexit_p(pasemi_dma_remove),
  80564. +};
  80565. +
  80566. +static void __exit pasemi_dma_cleanup_module(void)
  80567. +{
  80568. + pci_unregister_driver(&pasemi_dma_driver);
  80569. + __iounmap(dma_status);
  80570. + dma_status = NULL;
  80571. +}
  80572. +
  80573. +int pasemi_dma_init_module(void)
  80574. +{
  80575. + return pci_register_driver(&pasemi_dma_driver);
  80576. +}
  80577. +
  80578. +module_init(pasemi_dma_init_module);
  80579. +module_exit(pasemi_dma_cleanup_module);
  80580. +
  80581. +MODULE_LICENSE("Dual BSD/GPL");
  80582. +MODULE_AUTHOR("Egor Martovetsky egor@pasemi.com");
  80583. +MODULE_DESCRIPTION("OCF driver for PA Semi PWRficient DMA Crypto Engine");
  80584. diff -Nur linux-2.6.35.orig/crypto/ocf/pasemi/pasemi_fnu.h linux-2.6.35/crypto/ocf/pasemi/pasemi_fnu.h
  80585. --- linux-2.6.35.orig/crypto/ocf/pasemi/pasemi_fnu.h 1970-01-01 01:00:00.000000000 +0100
  80586. +++ linux-2.6.35/crypto/ocf/pasemi/pasemi_fnu.h 2010-08-05 22:02:26.174868275 +0200
  80587. @@ -0,0 +1,410 @@
  80588. +/*
  80589. + * Copyright (C) 2007 PA Semi, Inc
  80590. + *
  80591. + * Driver for the PA Semi PWRficient DMA Crypto Engine, soft state and
  80592. + * hardware register layouts.
  80593. + *
  80594. + * This program is free software; you can redistribute it and/or modify
  80595. + * it under the terms of the GNU General Public License version 2 as
  80596. + * published by the Free Software Foundation.
  80597. + *
  80598. + * This program is distributed in the hope that it will be useful,
  80599. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  80600. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  80601. + * GNU General Public License for more details.
  80602. + *
  80603. + * You should have received a copy of the GNU General Public License
  80604. + * along with this program; if not, write to the Free Software
  80605. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  80606. + */
  80607. +
  80608. +#ifndef PASEMI_FNU_H
  80609. +#define PASEMI_FNU_H
  80610. +
  80611. +#include <linux/spinlock.h>
  80612. +
  80613. +#define PASEMI_SESSION(sid) ((sid) & 0xffffffff)
  80614. +#define PASEMI_SID(sesn) ((sesn) & 0xffffffff)
  80615. +#define DPRINTF(a...) if (debug) { printk(DRV_NAME ": " a); }
  80616. +
  80617. +/* Must be a power of two */
  80618. +#define RX_RING_SIZE 512
  80619. +#define TX_RING_SIZE 512
  80620. +#define TX_DESC(ring, num) ((ring)->desc[2 * (num & (TX_RING_SIZE-1))])
  80621. +#define TX_DESC_INFO(ring, num) ((ring)->desc_info[(num) & (TX_RING_SIZE-1)])
  80622. +#define MAX_DESC_SIZE 8
  80623. +#define PASEMI_INITIAL_SESSIONS 10
  80624. +#define PASEMI_FNU_CHANNELS 8
  80625. +
  80626. +/* DMA descriptor */
  80627. +struct pasemi_desc {
  80628. + u64 quad[2*MAX_DESC_SIZE];
  80629. + int quad_cnt;
  80630. + int size;
  80631. + int postop;
  80632. +};
  80633. +
  80634. +/*
  80635. + * Holds per descriptor data
  80636. + */
  80637. +struct pasemi_desc_info {
  80638. + int desc_size;
  80639. + int desc_postop;
  80640. +#define PASEMI_CHECK_SIG 0x1
  80641. +
  80642. + struct cryptop *cf_crp;
  80643. +};
  80644. +
  80645. +/*
  80646. + * Holds per channel data
  80647. + */
  80648. +struct pasemi_fnu_txring {
  80649. + volatile u64 *desc;
  80650. + volatile struct
  80651. + pasemi_desc_info *desc_info;
  80652. + dma_addr_t dma;
  80653. + struct timer_list crypto_timer;
  80654. + spinlock_t fill_lock;
  80655. + spinlock_t clean_lock;
  80656. + unsigned int next_to_fill;
  80657. + unsigned int next_to_clean;
  80658. + u16 total_pktcnt;
  80659. + int irq;
  80660. + int sesn;
  80661. + char irq_name[10];
  80662. +};
  80663. +
  80664. +/*
  80665. + * Holds data specific to a single pasemi device.
  80666. + */
  80667. +struct pasemi_softc {
  80668. + softc_device_decl sc_cdev;
  80669. + struct pci_dev *dma_pdev; /* device backpointer */
  80670. + struct pci_dev *iob_pdev; /* device backpointer */
  80671. + void __iomem *dma_regs;
  80672. + void __iomem *iob_regs;
  80673. + int base_irq;
  80674. + int base_chan;
  80675. + int32_t sc_cid; /* crypto tag */
  80676. + int sc_nsessions;
  80677. + struct pasemi_session **sc_sessions;
  80678. + int sc_num_channels;/* number of crypto channels */
  80679. +
  80680. + /* pointer to the array of txring datastructures, one txring per channel */
  80681. + struct pasemi_fnu_txring *tx;
  80682. +
  80683. + /*
  80684. + * mutual exclusion for the channel scheduler
  80685. + */
  80686. + spinlock_t sc_chnlock;
  80687. + /* last channel used, for now use round-robin to allocate channels */
  80688. + int sc_lastchn;
  80689. +};
  80690. +
  80691. +struct pasemi_session {
  80692. + u64 civ[2];
  80693. + u64 keysz;
  80694. + u64 key[4];
  80695. + u64 ccmd;
  80696. + u64 hkey[4];
  80697. + u64 hseq;
  80698. + u64 giv[2];
  80699. + u64 hiv[4];
  80700. +
  80701. + int used;
  80702. + dma_addr_t dma_addr;
  80703. + int chan;
  80704. +};
  80705. +
  80706. +/* status register layout in IOB region, at 0xfd800000 */
  80707. +struct pasdma_status {
  80708. + u64 rx_sta[64];
  80709. + u64 tx_sta[20];
  80710. +};
  80711. +
  80712. +#define ALG_IS_CIPHER(alg) ((alg == CRYPTO_DES_CBC) || \
  80713. + (alg == CRYPTO_3DES_CBC) || \
  80714. + (alg == CRYPTO_AES_CBC) || \
  80715. + (alg == CRYPTO_ARC4) || \
  80716. + (alg == CRYPTO_NULL_CBC))
  80717. +
  80718. +#define ALG_IS_SIG(alg) ((alg == CRYPTO_MD5) || \
  80719. + (alg == CRYPTO_MD5_HMAC) || \
  80720. + (alg == CRYPTO_SHA1) || \
  80721. + (alg == CRYPTO_SHA1_HMAC) || \
  80722. + (alg == CRYPTO_NULL_HMAC))
  80723. +
  80724. +enum {
  80725. + PAS_DMA_COM_TXCMD = 0x100, /* Transmit Command Register */
  80726. + PAS_DMA_COM_TXSTA = 0x104, /* Transmit Status Register */
  80727. + PAS_DMA_COM_RXCMD = 0x108, /* Receive Command Register */
  80728. + PAS_DMA_COM_RXSTA = 0x10c, /* Receive Status Register */
  80729. + PAS_DMA_COM_CFG = 0x114, /* DMA Configuration Register */
  80730. +};
  80731. +
  80732. +/* All these registers live in the PCI configuration space for the DMA PCI
  80733. + * device. Use the normal PCI config access functions for them.
  80734. + */
  80735. +
  80736. +#define PAS_DMA_COM_CFG_FWF 0x18000000
  80737. +
  80738. +#define PAS_DMA_COM_TXCMD_EN 0x00000001 /* enable */
  80739. +#define PAS_DMA_COM_TXSTA_ACT 0x00000001 /* active */
  80740. +#define PAS_DMA_COM_RXCMD_EN 0x00000001 /* enable */
  80741. +#define PAS_DMA_COM_RXSTA_ACT 0x00000001 /* active */
  80742. +
  80743. +#define _PAS_DMA_TXCHAN_STRIDE 0x20 /* Size per channel */
  80744. +#define _PAS_DMA_TXCHAN_TCMDSTA 0x300 /* Command / Status */
  80745. +#define _PAS_DMA_TXCHAN_CFG 0x304 /* Configuration */
  80746. +#define _PAS_DMA_TXCHAN_DSCRBU 0x308 /* Descriptor BU Allocation */
  80747. +#define _PAS_DMA_TXCHAN_INCR 0x310 /* Descriptor increment */
  80748. +#define _PAS_DMA_TXCHAN_CNT 0x314 /* Descriptor count/offset */
  80749. +#define _PAS_DMA_TXCHAN_BASEL 0x318 /* Descriptor ring base (low) */
  80750. +#define _PAS_DMA_TXCHAN_BASEU 0x31c /* (high) */
  80751. +#define PAS_DMA_TXCHAN_TCMDSTA(c) (0x300+(c)*_PAS_DMA_TXCHAN_STRIDE)
  80752. +#define PAS_DMA_TXCHAN_TCMDSTA_EN 0x00000001 /* Enabled */
  80753. +#define PAS_DMA_TXCHAN_TCMDSTA_ST 0x00000002 /* Stop interface */
  80754. +#define PAS_DMA_TXCHAN_TCMDSTA_ACT 0x00010000 /* Active */
  80755. +#define PAS_DMA_TXCHAN_CFG(c) (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE)
  80756. +#define PAS_DMA_TXCHAN_CFG_TY_FUNC 0x00000002 /* Type = interface */
  80757. +#define PAS_DMA_TXCHAN_CFG_TY_IFACE 0x00000000 /* Type = interface */
  80758. +#define PAS_DMA_TXCHAN_CFG_TATTR_M 0x0000003c
  80759. +#define PAS_DMA_TXCHAN_CFG_TATTR_S 2
  80760. +#define PAS_DMA_TXCHAN_CFG_TATTR(x) (((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \
  80761. + PAS_DMA_TXCHAN_CFG_TATTR_M)
  80762. +#define PAS_DMA_TXCHAN_CFG_WT_M 0x000001c0
  80763. +#define PAS_DMA_TXCHAN_CFG_WT_S 6
  80764. +#define PAS_DMA_TXCHAN_CFG_WT(x) (((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \
  80765. + PAS_DMA_TXCHAN_CFG_WT_M)
  80766. +#define PAS_DMA_TXCHAN_CFG_LPSQ_FAST 0x00000400
  80767. +#define PAS_DMA_TXCHAN_CFG_LPDQ_FAST 0x00000800
  80768. +#define PAS_DMA_TXCHAN_CFG_CF 0x00001000 /* Clean first line */
  80769. +#define PAS_DMA_TXCHAN_CFG_CL 0x00002000 /* Clean last line */
  80770. +#define PAS_DMA_TXCHAN_CFG_UP 0x00004000 /* update tx descr when sent */
  80771. +#define PAS_DMA_TXCHAN_INCR(c) (0x310+(c)*_PAS_DMA_TXCHAN_STRIDE)
  80772. +#define PAS_DMA_TXCHAN_BASEL(c) (0x318+(c)*_PAS_DMA_TXCHAN_STRIDE)
  80773. +#define PAS_DMA_TXCHAN_BASEL_BRBL_M 0xffffffc0
  80774. +#define PAS_DMA_TXCHAN_BASEL_BRBL_S 0
  80775. +#define PAS_DMA_TXCHAN_BASEL_BRBL(x) (((x) << PAS_DMA_TXCHAN_BASEL_BRBL_S) & \
  80776. + PAS_DMA_TXCHAN_BASEL_BRBL_M)
  80777. +#define PAS_DMA_TXCHAN_BASEU(c) (0x31c+(c)*_PAS_DMA_TXCHAN_STRIDE)
  80778. +#define PAS_DMA_TXCHAN_BASEU_BRBH_M 0x00000fff
  80779. +#define PAS_DMA_TXCHAN_BASEU_BRBH_S 0
  80780. +#define PAS_DMA_TXCHAN_BASEU_BRBH(x) (((x) << PAS_DMA_TXCHAN_BASEU_BRBH_S) & \
  80781. + PAS_DMA_TXCHAN_BASEU_BRBH_M)
  80782. +/* # of cache lines worth of buffer ring */
  80783. +#define PAS_DMA_TXCHAN_BASEU_SIZ_M 0x3fff0000
  80784. +#define PAS_DMA_TXCHAN_BASEU_SIZ_S 16 /* 0 = 16K */
  80785. +#define PAS_DMA_TXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_TXCHAN_BASEU_SIZ_S) & \
  80786. + PAS_DMA_TXCHAN_BASEU_SIZ_M)
  80787. +
  80788. +#define PAS_STATUS_PCNT_M 0x000000000000ffffull
  80789. +#define PAS_STATUS_PCNT_S 0
  80790. +#define PAS_STATUS_DCNT_M 0x00000000ffff0000ull
  80791. +#define PAS_STATUS_DCNT_S 16
  80792. +#define PAS_STATUS_BPCNT_M 0x0000ffff00000000ull
  80793. +#define PAS_STATUS_BPCNT_S 32
  80794. +#define PAS_STATUS_CAUSE_M 0xf000000000000000ull
  80795. +#define PAS_STATUS_TIMER 0x1000000000000000ull
  80796. +#define PAS_STATUS_ERROR 0x2000000000000000ull
  80797. +#define PAS_STATUS_SOFT 0x4000000000000000ull
  80798. +#define PAS_STATUS_INT 0x8000000000000000ull
  80799. +
  80800. +#define PAS_IOB_DMA_RXCH_CFG(i) (0x1100 + (i)*4)
  80801. +#define PAS_IOB_DMA_RXCH_CFG_CNTTH_M 0x00000fff
  80802. +#define PAS_IOB_DMA_RXCH_CFG_CNTTH_S 0
  80803. +#define PAS_IOB_DMA_RXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_RXCH_CFG_CNTTH_S) & \
  80804. + PAS_IOB_DMA_RXCH_CFG_CNTTH_M)
  80805. +#define PAS_IOB_DMA_TXCH_CFG(i) (0x1200 + (i)*4)
  80806. +#define PAS_IOB_DMA_TXCH_CFG_CNTTH_M 0x00000fff
  80807. +#define PAS_IOB_DMA_TXCH_CFG_CNTTH_S 0
  80808. +#define PAS_IOB_DMA_TXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_TXCH_CFG_CNTTH_S) & \
  80809. + PAS_IOB_DMA_TXCH_CFG_CNTTH_M)
  80810. +#define PAS_IOB_DMA_RXCH_STAT(i) (0x1300 + (i)*4)
  80811. +#define PAS_IOB_DMA_RXCH_STAT_INTGEN 0x00001000
  80812. +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_M 0x00000fff
  80813. +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_S 0
  80814. +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_RXCH_STAT_CNTDEL_S) &\
  80815. + PAS_IOB_DMA_RXCH_STAT_CNTDEL_M)
  80816. +#define PAS_IOB_DMA_TXCH_STAT(i) (0x1400 + (i)*4)
  80817. +#define PAS_IOB_DMA_TXCH_STAT_INTGEN 0x00001000
  80818. +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_M 0x00000fff
  80819. +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_S 0
  80820. +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_TXCH_STAT_CNTDEL_S) &\
  80821. + PAS_IOB_DMA_TXCH_STAT_CNTDEL_M)
  80822. +#define PAS_IOB_DMA_RXCH_RESET(i) (0x1500 + (i)*4)
  80823. +#define PAS_IOB_DMA_RXCH_RESET_PCNT_M 0xffff0000
  80824. +#define PAS_IOB_DMA_RXCH_RESET_PCNT_S 16
  80825. +#define PAS_IOB_DMA_RXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_RXCH_RESET_PCNT_S) & \
  80826. + PAS_IOB_DMA_RXCH_RESET_PCNT_M)
  80827. +#define PAS_IOB_DMA_RXCH_RESET_PCNTRST 0x00000020
  80828. +#define PAS_IOB_DMA_RXCH_RESET_DCNTRST 0x00000010
  80829. +#define PAS_IOB_DMA_RXCH_RESET_TINTC 0x00000008
  80830. +#define PAS_IOB_DMA_RXCH_RESET_DINTC 0x00000004
  80831. +#define PAS_IOB_DMA_RXCH_RESET_SINTC 0x00000002
  80832. +#define PAS_IOB_DMA_RXCH_RESET_PINTC 0x00000001
  80833. +#define PAS_IOB_DMA_TXCH_RESET(i) (0x1600 + (i)*4)
  80834. +#define PAS_IOB_DMA_TXCH_RESET_PCNT_M 0xffff0000
  80835. +#define PAS_IOB_DMA_TXCH_RESET_PCNT_S 16
  80836. +#define PAS_IOB_DMA_TXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_TXCH_RESET_PCNT_S) & \
  80837. + PAS_IOB_DMA_TXCH_RESET_PCNT_M)
  80838. +#define PAS_IOB_DMA_TXCH_RESET_PCNTRST 0x00000020
  80839. +#define PAS_IOB_DMA_TXCH_RESET_DCNTRST 0x00000010
  80840. +#define PAS_IOB_DMA_TXCH_RESET_TINTC 0x00000008
  80841. +#define PAS_IOB_DMA_TXCH_RESET_DINTC 0x00000004
  80842. +#define PAS_IOB_DMA_TXCH_RESET_SINTC 0x00000002
  80843. +#define PAS_IOB_DMA_TXCH_RESET_PINTC 0x00000001
  80844. +
  80845. +#define PAS_IOB_DMA_COM_TIMEOUTCFG 0x1700
  80846. +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M 0x00ffffff
  80847. +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S 0
  80848. +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(x) (((x) << PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S) & \
  80849. + PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M)
  80850. +
  80851. +/* Transmit descriptor fields */
  80852. +#define XCT_MACTX_T 0x8000000000000000ull
  80853. +#define XCT_MACTX_ST 0x4000000000000000ull
  80854. +#define XCT_MACTX_NORES 0x0000000000000000ull
  80855. +#define XCT_MACTX_8BRES 0x1000000000000000ull
  80856. +#define XCT_MACTX_24BRES 0x2000000000000000ull
  80857. +#define XCT_MACTX_40BRES 0x3000000000000000ull
  80858. +#define XCT_MACTX_I 0x0800000000000000ull
  80859. +#define XCT_MACTX_O 0x0400000000000000ull
  80860. +#define XCT_MACTX_E 0x0200000000000000ull
  80861. +#define XCT_MACTX_VLAN_M 0x0180000000000000ull
  80862. +#define XCT_MACTX_VLAN_NOP 0x0000000000000000ull
  80863. +#define XCT_MACTX_VLAN_REMOVE 0x0080000000000000ull
  80864. +#define XCT_MACTX_VLAN_INSERT 0x0100000000000000ull
  80865. +#define XCT_MACTX_VLAN_REPLACE 0x0180000000000000ull
  80866. +#define XCT_MACTX_CRC_M 0x0060000000000000ull
  80867. +#define XCT_MACTX_CRC_NOP 0x0000000000000000ull
  80868. +#define XCT_MACTX_CRC_INSERT 0x0020000000000000ull
  80869. +#define XCT_MACTX_CRC_PAD 0x0040000000000000ull
  80870. +#define XCT_MACTX_CRC_REPLACE 0x0060000000000000ull
  80871. +#define XCT_MACTX_SS 0x0010000000000000ull
  80872. +#define XCT_MACTX_LLEN_M 0x00007fff00000000ull
  80873. +#define XCT_MACTX_LLEN_S 32ull
  80874. +#define XCT_MACTX_LLEN(x) ((((long)(x)) << XCT_MACTX_LLEN_S) & \
  80875. + XCT_MACTX_LLEN_M)
  80876. +#define XCT_MACTX_IPH_M 0x00000000f8000000ull
  80877. +#define XCT_MACTX_IPH_S 27ull
  80878. +#define XCT_MACTX_IPH(x) ((((long)(x)) << XCT_MACTX_IPH_S) & \
  80879. + XCT_MACTX_IPH_M)
  80880. +#define XCT_MACTX_IPO_M 0x0000000007c00000ull
  80881. +#define XCT_MACTX_IPO_S 22ull
  80882. +#define XCT_MACTX_IPO(x) ((((long)(x)) << XCT_MACTX_IPO_S) & \
  80883. + XCT_MACTX_IPO_M)
  80884. +#define XCT_MACTX_CSUM_M 0x0000000000000060ull
  80885. +#define XCT_MACTX_CSUM_NOP 0x0000000000000000ull
  80886. +#define XCT_MACTX_CSUM_TCP 0x0000000000000040ull
  80887. +#define XCT_MACTX_CSUM_UDP 0x0000000000000060ull
  80888. +#define XCT_MACTX_V6 0x0000000000000010ull
  80889. +#define XCT_MACTX_C 0x0000000000000004ull
  80890. +#define XCT_MACTX_AL2 0x0000000000000002ull
  80891. +
  80892. +#define XCT_PTR_T 0x8000000000000000ull
  80893. +#define XCT_PTR_LEN_M 0x7ffff00000000000ull
  80894. +#define XCT_PTR_LEN_S 44
  80895. +#define XCT_PTR_LEN(x) ((((long)(x)) << XCT_PTR_LEN_S) & \
  80896. + XCT_PTR_LEN_M)
  80897. +#define XCT_PTR_ADDR_M 0x00000fffffffffffull
  80898. +#define XCT_PTR_ADDR_S 0
  80899. +#define XCT_PTR_ADDR(x) ((((long)(x)) << XCT_PTR_ADDR_S) & \
  80900. + XCT_PTR_ADDR_M)
  80901. +
  80902. +/* Function descriptor fields */
  80903. +#define XCT_FUN_T 0x8000000000000000ull
  80904. +#define XCT_FUN_ST 0x4000000000000000ull
  80905. +#define XCT_FUN_NORES 0x0000000000000000ull
  80906. +#define XCT_FUN_8BRES 0x1000000000000000ull
  80907. +#define XCT_FUN_24BRES 0x2000000000000000ull
  80908. +#define XCT_FUN_40BRES 0x3000000000000000ull
  80909. +#define XCT_FUN_I 0x0800000000000000ull
  80910. +#define XCT_FUN_O 0x0400000000000000ull
  80911. +#define XCT_FUN_E 0x0200000000000000ull
  80912. +#define XCT_FUN_FUN_S 54
  80913. +#define XCT_FUN_FUN_M 0x01c0000000000000ull
  80914. +#define XCT_FUN_FUN(num) ((((long)(num)) << XCT_FUN_FUN_S) & \
  80915. + XCT_FUN_FUN_M)
  80916. +#define XCT_FUN_CRM_NOP 0x0000000000000000ull
  80917. +#define XCT_FUN_CRM_SIG 0x0008000000000000ull
  80918. +#define XCT_FUN_CRM_ENC 0x0010000000000000ull
  80919. +#define XCT_FUN_CRM_DEC 0x0018000000000000ull
  80920. +#define XCT_FUN_CRM_SIG_ENC 0x0020000000000000ull
  80921. +#define XCT_FUN_CRM_ENC_SIG 0x0028000000000000ull
  80922. +#define XCT_FUN_CRM_SIG_DEC 0x0030000000000000ull
  80923. +#define XCT_FUN_CRM_DEC_SIG 0x0038000000000000ull
  80924. +#define XCT_FUN_LLEN_M 0x0007ffff00000000ull
  80925. +#define XCT_FUN_LLEN_S 32ULL
  80926. +#define XCT_FUN_LLEN(x) ((((long)(x)) << XCT_FUN_LLEN_S) & \
  80927. + XCT_FUN_LLEN_M)
  80928. +#define XCT_FUN_SHL_M 0x00000000f8000000ull
  80929. +#define XCT_FUN_SHL_S 27ull
  80930. +#define XCT_FUN_SHL(x) ((((long)(x)) << XCT_FUN_SHL_S) & \
  80931. + XCT_FUN_SHL_M)
  80932. +#define XCT_FUN_CHL_M 0x0000000007c00000ull
  80933. +#define XCT_FUN_CHL_S 22ull
  80934. +#define XCT_FUN_CHL(x) ((((long)(x)) << XCT_FUN_CHL_S) & \
  80935. + XCT_FUN_CHL_M)
  80936. +#define XCT_FUN_HSZ_M 0x00000000003c0000ull
  80937. +#define XCT_FUN_HSZ_S 18ull
  80938. +#define XCT_FUN_HSZ(x) ((((long)(x)) << XCT_FUN_HSZ_S) & \
  80939. + XCT_FUN_HSZ_M)
  80940. +#define XCT_FUN_ALG_DES 0x0000000000000000ull
  80941. +#define XCT_FUN_ALG_3DES 0x0000000000008000ull
  80942. +#define XCT_FUN_ALG_AES 0x0000000000010000ull
  80943. +#define XCT_FUN_ALG_ARC 0x0000000000018000ull
  80944. +#define XCT_FUN_ALG_KASUMI 0x0000000000020000ull
  80945. +#define XCT_FUN_BCM_ECB 0x0000000000000000ull
  80946. +#define XCT_FUN_BCM_CBC 0x0000000000001000ull
  80947. +#define XCT_FUN_BCM_CFB 0x0000000000002000ull
  80948. +#define XCT_FUN_BCM_OFB 0x0000000000003000ull
  80949. +#define XCT_FUN_BCM_CNT 0x0000000000003800ull
  80950. +#define XCT_FUN_BCM_KAS_F8 0x0000000000002800ull
  80951. +#define XCT_FUN_BCM_KAS_F9 0x0000000000001800ull
  80952. +#define XCT_FUN_BCP_NO_PAD 0x0000000000000000ull
  80953. +#define XCT_FUN_BCP_ZRO 0x0000000000000200ull
  80954. +#define XCT_FUN_BCP_PL 0x0000000000000400ull
  80955. +#define XCT_FUN_BCP_INCR 0x0000000000000600ull
  80956. +#define XCT_FUN_SIG_MD5 (0ull << 4)
  80957. +#define XCT_FUN_SIG_SHA1 (2ull << 4)
  80958. +#define XCT_FUN_SIG_HMAC_MD5 (8ull << 4)
  80959. +#define XCT_FUN_SIG_HMAC_SHA1 (10ull << 4)
  80960. +#define XCT_FUN_A 0x0000000000000008ull
  80961. +#define XCT_FUN_C 0x0000000000000004ull
  80962. +#define XCT_FUN_AL2 0x0000000000000002ull
  80963. +#define XCT_FUN_SE 0x0000000000000001ull
  80964. +
  80965. +#define XCT_FUN_SRC_PTR(len, addr) (XCT_PTR_LEN(len) | XCT_PTR_ADDR(addr))
  80966. +#define XCT_FUN_DST_PTR(len, addr) (XCT_FUN_SRC_PTR(len, addr) | \
  80967. + 0x8000000000000000ull)
  80968. +
  80969. +#define XCT_CTRL_HDR_FUN_NUM_M 0x01c0000000000000ull
  80970. +#define XCT_CTRL_HDR_FUN_NUM_S 54
  80971. +#define XCT_CTRL_HDR_LEN_M 0x0007ffff00000000ull
  80972. +#define XCT_CTRL_HDR_LEN_S 32
  80973. +#define XCT_CTRL_HDR_REG_M 0x00000000000000ffull
  80974. +#define XCT_CTRL_HDR_REG_S 0
  80975. +
  80976. +#define XCT_CTRL_HDR(funcN,len,reg) (0x9400000000000000ull | \
  80977. + ((((long)(funcN)) << XCT_CTRL_HDR_FUN_NUM_S) \
  80978. + & XCT_CTRL_HDR_FUN_NUM_M) | \
  80979. + ((((long)(len)) << \
  80980. + XCT_CTRL_HDR_LEN_S) & XCT_CTRL_HDR_LEN_M) | \
  80981. + ((((long)(reg)) << \
  80982. + XCT_CTRL_HDR_REG_S) & XCT_CTRL_HDR_REG_M))
  80983. +
  80984. +/* Function config command options */
  80985. +#define DMA_CALGO_DES 0x00
  80986. +#define DMA_CALGO_3DES 0x01
  80987. +#define DMA_CALGO_AES 0x02
  80988. +#define DMA_CALGO_ARC 0x03
  80989. +
  80990. +#define DMA_FN_CIV0 0x02
  80991. +#define DMA_FN_CIV1 0x03
  80992. +#define DMA_FN_HKEY0 0x0a
  80993. +
  80994. +#define XCT_PTR_ADDR_LEN(ptr) ((ptr) & XCT_PTR_ADDR_M), \
  80995. + (((ptr) & XCT_PTR_LEN_M) >> XCT_PTR_LEN_S)
  80996. +
  80997. +#endif /* PASEMI_FNU_H */
  80998. diff -Nur linux-2.6.35.orig/crypto/ocf/random.c linux-2.6.35/crypto/ocf/random.c
  80999. --- linux-2.6.35.orig/crypto/ocf/random.c 1970-01-01 01:00:00.000000000 +0100
  81000. +++ linux-2.6.35/crypto/ocf/random.c 2010-08-05 22:02:26.204477275 +0200
  81001. @@ -0,0 +1,322 @@
  81002. +/*
  81003. + * A system independant way of adding entropy to the kernels pool
  81004. + * this way the drivers can focus on the real work and we can take
  81005. + * care of pushing it to the appropriate place in the kernel.
  81006. + *
  81007. + * This should be fast and callable from timers/interrupts
  81008. + *
  81009. + * Written by David McCullough <david_mccullough@mcafee.com>
  81010. + * Copyright (C) 2006-2010 David McCullough
  81011. + * Copyright (C) 2004-2005 Intel Corporation.
  81012. + *
  81013. + * LICENSE TERMS
  81014. + *
  81015. + * The free distribution and use of this software in both source and binary
  81016. + * form is allowed (with or without changes) provided that:
  81017. + *
  81018. + * 1. distributions of this source code include the above copyright
  81019. + * notice, this list of conditions and the following disclaimer;
  81020. + *
  81021. + * 2. distributions in binary form include the above copyright
  81022. + * notice, this list of conditions and the following disclaimer
  81023. + * in the documentation and/or other associated materials;
  81024. + *
  81025. + * 3. the copyright holder's name is not used to endorse products
  81026. + * built using this software without specific written permission.
  81027. + *
  81028. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  81029. + * may be distributed under the terms of the GNU General Public License (GPL),
  81030. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  81031. + *
  81032. + * DISCLAIMER
  81033. + *
  81034. + * This software is provided 'as is' with no explicit or implied warranties
  81035. + * in respect of its properties, including, but not limited to, correctness
  81036. + * and/or fitness for purpose.
  81037. + */
  81038. +
  81039. +#ifndef AUTOCONF_INCLUDED
  81040. +#include <linux/config.h>
  81041. +#endif
  81042. +#include <linux/module.h>
  81043. +#include <linux/init.h>
  81044. +#include <linux/list.h>
  81045. +#include <linux/slab.h>
  81046. +#include <linux/wait.h>
  81047. +#include <linux/sched.h>
  81048. +#include <linux/spinlock.h>
  81049. +#include <linux/version.h>
  81050. +#include <linux/unistd.h>
  81051. +#include <linux/poll.h>
  81052. +#include <linux/random.h>
  81053. +#include <cryptodev.h>
  81054. +
  81055. +#ifdef CONFIG_OCF_FIPS
  81056. +#include "rndtest.h"
  81057. +#endif
  81058. +
  81059. +#ifndef HAS_RANDOM_INPUT_WAIT
  81060. +#error "Please do not enable OCF_RANDOMHARVEST unless you have applied patches"
  81061. +#endif
  81062. +
  81063. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
  81064. +#include <linux/sched.h>
  81065. +#define kill_proc(p,s,v) send_sig(s,find_task_by_vpid(p),0)
  81066. +#endif
  81067. +
  81068. +/*
  81069. + * a hack to access the debug levels from the crypto driver
  81070. + */
  81071. +extern int crypto_debug;
  81072. +#define debug crypto_debug
  81073. +
  81074. +/*
  81075. + * a list of all registered random providers
  81076. + */
  81077. +static LIST_HEAD(random_ops);
  81078. +static int started = 0;
  81079. +static int initted = 0;
  81080. +
  81081. +struct random_op {
  81082. + struct list_head random_list;
  81083. + u_int32_t driverid;
  81084. + int (*read_random)(void *arg, u_int32_t *buf, int len);
  81085. + void *arg;
  81086. +};
  81087. +
  81088. +static int random_proc(void *arg);
  81089. +
  81090. +static pid_t randomproc = (pid_t) -1;
  81091. +static spinlock_t random_lock;
  81092. +
  81093. +/*
  81094. + * just init the spin locks
  81095. + */
  81096. +static int
  81097. +crypto_random_init(void)
  81098. +{
  81099. + spin_lock_init(&random_lock);
  81100. + initted = 1;
  81101. + return(0);
  81102. +}
  81103. +
  81104. +/*
  81105. + * Add the given random reader to our list (if not present)
  81106. + * and start the thread (if not already started)
  81107. + *
  81108. + * we have to assume that driver id is ok for now
  81109. + */
  81110. +int
  81111. +crypto_rregister(
  81112. + u_int32_t driverid,
  81113. + int (*read_random)(void *arg, u_int32_t *buf, int len),
  81114. + void *arg)
  81115. +{
  81116. + unsigned long flags;
  81117. + int ret = 0;
  81118. + struct random_op *rops, *tmp;
  81119. +
  81120. + dprintk("%s,%d: %s(0x%x, %p, %p)\n", __FILE__, __LINE__,
  81121. + __FUNCTION__, driverid, read_random, arg);
  81122. +
  81123. + if (!initted)
  81124. + crypto_random_init();
  81125. +
  81126. +#if 0
  81127. + struct cryptocap *cap;
  81128. +
  81129. + cap = crypto_checkdriver(driverid);
  81130. + if (!cap)
  81131. + return EINVAL;
  81132. +#endif
  81133. +
  81134. + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
  81135. + if (rops->driverid == driverid && rops->read_random == read_random)
  81136. + return EEXIST;
  81137. + }
  81138. +
  81139. + rops = (struct random_op *) kmalloc(sizeof(*rops), GFP_KERNEL);
  81140. + if (!rops)
  81141. + return ENOMEM;
  81142. +
  81143. + rops->driverid = driverid;
  81144. + rops->read_random = read_random;
  81145. + rops->arg = arg;
  81146. +
  81147. + spin_lock_irqsave(&random_lock, flags);
  81148. + list_add_tail(&rops->random_list, &random_ops);
  81149. + if (!started) {
  81150. + randomproc = kernel_thread(random_proc, NULL, CLONE_FS|CLONE_FILES);
  81151. + if (randomproc < 0) {
  81152. + ret = randomproc;
  81153. + printk("crypto: crypto_rregister cannot start random thread; "
  81154. + "error %d", ret);
  81155. + } else
  81156. + started = 1;
  81157. + }
  81158. + spin_unlock_irqrestore(&random_lock, flags);
  81159. +
  81160. + return ret;
  81161. +}
  81162. +EXPORT_SYMBOL(crypto_rregister);
  81163. +
  81164. +int
  81165. +crypto_runregister_all(u_int32_t driverid)
  81166. +{
  81167. + struct random_op *rops, *tmp;
  81168. + unsigned long flags;
  81169. +
  81170. + dprintk("%s,%d: %s(0x%x)\n", __FILE__, __LINE__, __FUNCTION__, driverid);
  81171. +
  81172. + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
  81173. + if (rops->driverid == driverid) {
  81174. + list_del(&rops->random_list);
  81175. + kfree(rops);
  81176. + }
  81177. + }
  81178. +
  81179. + spin_lock_irqsave(&random_lock, flags);
  81180. + if (list_empty(&random_ops) && started)
  81181. + kill_proc(randomproc, SIGKILL, 1);
  81182. + spin_unlock_irqrestore(&random_lock, flags);
  81183. + return(0);
  81184. +}
  81185. +EXPORT_SYMBOL(crypto_runregister_all);
  81186. +
  81187. +/*
  81188. + * while we can add entropy to random.c continue to read random data from
  81189. + * the drivers and push it to random.
  81190. + */
  81191. +static int
  81192. +random_proc(void *arg)
  81193. +{
  81194. + int n;
  81195. + int wantcnt;
  81196. + int bufcnt = 0;
  81197. + int retval = 0;
  81198. + int *buf = NULL;
  81199. +
  81200. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  81201. + daemonize();
  81202. + spin_lock_irq(&current->sigmask_lock);
  81203. + sigemptyset(&current->blocked);
  81204. + recalc_sigpending(current);
  81205. + spin_unlock_irq(&current->sigmask_lock);
  81206. + sprintf(current->comm, "ocf-random");
  81207. +#else
  81208. + daemonize("ocf-random");
  81209. + allow_signal(SIGKILL);
  81210. +#endif
  81211. +
  81212. + (void) get_fs();
  81213. + set_fs(get_ds());
  81214. +
  81215. +#ifdef CONFIG_OCF_FIPS
  81216. +#define NUM_INT (RNDTEST_NBYTES/sizeof(int))
  81217. +#else
  81218. +#define NUM_INT 32
  81219. +#endif
  81220. +
  81221. + /*
  81222. + * some devices can transferr their RNG data direct into memory,
  81223. + * so make sure it is device friendly
  81224. + */
  81225. + buf = kmalloc(NUM_INT * sizeof(int), GFP_DMA);
  81226. + if (NULL == buf) {
  81227. + printk("crypto: RNG could not allocate memory\n");
  81228. + retval = -ENOMEM;
  81229. + goto bad_alloc;
  81230. + }
  81231. +
  81232. + wantcnt = NUM_INT; /* start by adding some entropy */
  81233. +
  81234. + /*
  81235. + * its possible due to errors or driver removal that we no longer
  81236. + * have anything to do, if so exit or we will consume all the CPU
  81237. + * doing nothing
  81238. + */
  81239. + while (!list_empty(&random_ops)) {
  81240. + struct random_op *rops, *tmp;
  81241. +
  81242. +#ifdef CONFIG_OCF_FIPS
  81243. + if (wantcnt)
  81244. + wantcnt = NUM_INT; /* FIPs mode can do 20000 bits or none */
  81245. +#endif
  81246. +
  81247. + /* see if we can get enough entropy to make the world
  81248. + * a better place.
  81249. + */
  81250. + while (bufcnt < wantcnt && bufcnt < NUM_INT) {
  81251. + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
  81252. +
  81253. + n = (*rops->read_random)(rops->arg, &buf[bufcnt],
  81254. + NUM_INT - bufcnt);
  81255. +
  81256. + /* on failure remove the random number generator */
  81257. + if (n == -1) {
  81258. + list_del(&rops->random_list);
  81259. + printk("crypto: RNG (driverid=0x%x) failed, disabling\n",
  81260. + rops->driverid);
  81261. + kfree(rops);
  81262. + } else if (n > 0)
  81263. + bufcnt += n;
  81264. + }
  81265. + /* give up CPU for a bit, just in case as this is a loop */
  81266. + schedule();
  81267. + }
  81268. +
  81269. +
  81270. +#ifdef CONFIG_OCF_FIPS
  81271. + if (bufcnt > 0 && rndtest_buf((unsigned char *) &buf[0])) {
  81272. + dprintk("crypto: buffer had fips errors, discarding\n");
  81273. + bufcnt = 0;
  81274. + }
  81275. +#endif
  81276. +
  81277. + /*
  81278. + * if we have a certified buffer, we can send some data
  81279. + * to /dev/random and move along
  81280. + */
  81281. + if (bufcnt > 0) {
  81282. + /* add what we have */
  81283. + random_input_words(buf, bufcnt, bufcnt*sizeof(int)*8);
  81284. + bufcnt = 0;
  81285. + }
  81286. +
  81287. + /* give up CPU for a bit so we don't hog while filling */
  81288. + schedule();
  81289. +
  81290. + /* wait for needing more */
  81291. + wantcnt = random_input_wait();
  81292. +
  81293. + if (wantcnt <= 0)
  81294. + wantcnt = 0; /* try to get some info again */
  81295. + else
  81296. + /* round up to one word or we can loop forever */
  81297. + wantcnt = (wantcnt + (sizeof(int)*8)) / (sizeof(int)*8);
  81298. + if (wantcnt > NUM_INT) {
  81299. + wantcnt = NUM_INT;
  81300. + }
  81301. +
  81302. + if (signal_pending(current)) {
  81303. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  81304. + spin_lock_irq(&current->sigmask_lock);
  81305. +#endif
  81306. + flush_signals(current);
  81307. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  81308. + spin_unlock_irq(&current->sigmask_lock);
  81309. +#endif
  81310. + }
  81311. + }
  81312. +
  81313. + kfree(buf);
  81314. +
  81315. +bad_alloc:
  81316. + spin_lock_irq(&random_lock);
  81317. + randomproc = (pid_t) -1;
  81318. + started = 0;
  81319. + spin_unlock_irq(&random_lock);
  81320. +
  81321. + return retval;
  81322. +}
  81323. +
  81324. diff -Nur linux-2.6.35.orig/crypto/ocf/README linux-2.6.35/crypto/ocf/README
  81325. --- linux-2.6.35.orig/crypto/ocf/README 1970-01-01 01:00:00.000000000 +0100
  81326. +++ linux-2.6.35/crypto/ocf/README 2010-08-05 22:02:26.244868048 +0200
  81327. @@ -0,0 +1,167 @@
  81328. +README - ocf-linux-20100325
  81329. +---------------------------
  81330. +
  81331. +This README provides instructions for getting ocf-linux compiled and
  81332. +operating in a generic linux environment. For other information you
  81333. +might like to visit the home page for this project:
  81334. +
  81335. + http://ocf-linux.sourceforge.net/
  81336. +
  81337. +Adding OCF to linux
  81338. +-------------------
  81339. +
  81340. + Not much in this file for now, just some notes. I usually build
  81341. + the ocf support as modules but it can be built into the kernel as
  81342. + well. To use it:
  81343. +
  81344. + * mknod /dev/crypto c 10 70
  81345. +
  81346. + * to add OCF to your kernel source, you have two options. Apply
  81347. + the kernel specific patch:
  81348. +
  81349. + cd linux-2.4*; gunzip < ocf-linux-24-XXXXXXXX.patch.gz | patch -p1
  81350. + cd linux-2.6*; gunzip < ocf-linux-26-XXXXXXXX.patch.gz | patch -p1
  81351. +
  81352. + if you do one of the above, then you can proceed to the next step,
  81353. + or you can do the above process by hand with using the patches against
  81354. + linux-2.4.35 and 2.6.33 to include the ocf code under crypto/ocf.
  81355. + Here's how to add it:
  81356. +
  81357. + for 2.4.35 (and later)
  81358. +
  81359. + cd linux-2.4.35/crypto
  81360. + tar xvzf ocf-linux.tar.gz
  81361. + cd ..
  81362. + patch -p1 < crypto/ocf/patches/linux-2.4.35-ocf.patch
  81363. +
  81364. + for 2.6.23 (and later), find the kernel patch specific (or nearest)
  81365. + to your kernel versions and then:
  81366. +
  81367. + cd linux-2.6.NN/crypto
  81368. + tar xvzf ocf-linux.tar.gz
  81369. + cd ..
  81370. + patch -p1 < crypto/ocf/patches/linux-2.6.NN-ocf.patch
  81371. +
  81372. + It should be easy to take this patch and apply it to other more
  81373. + recent versions of the kernels. The same patches should also work
  81374. + relatively easily on kernels as old as 2.6.11 and 2.4.18.
  81375. +
  81376. + * under 2.4 if you are on a non-x86 platform, you may need to:
  81377. +
  81378. + cp linux-2.X.x/include/asm-i386/kmap_types.h linux-2.X.x/include/asm-YYY
  81379. +
  81380. + so that you can build the kernel crypto support needed for the cryptosoft
  81381. + driver.
  81382. +
  81383. + * For simplicity you should enable all the crypto support in your kernel
  81384. + except for the test driver. Likewise for the OCF options. Do not
  81385. + enable OCF crypto drivers for HW that you do not have (for example
  81386. + ixp4xx will not compile on non-Xscale systems).
  81387. +
  81388. + * make sure that cryptodev.h (from ocf-linux.tar.gz) is installed as
  81389. + crypto/cryptodev.h in an include directory that is used for building
  81390. + applications for your platform. For example on a host system that
  81391. + might be:
  81392. +
  81393. + /usr/include/crypto/cryptodev.h
  81394. +
  81395. + * patch your openssl-0.9.8n code with the openssl-0.9.8n.patch.
  81396. + (NOTE: there is no longer a need to patch ssh). The patch is against:
  81397. + openssl-0_9_8e
  81398. +
  81399. + If you need a patch for an older version of openssl, you should look
  81400. + to older OCF releases. This patch is unlikely to work on older
  81401. + openssl versions.
  81402. +
  81403. + openssl-0.9.8n.patch
  81404. + - enables --with-cryptodev for non BSD systems
  81405. + - adds -cpu option to openssl speed for calculating CPU load
  81406. + under linux
  81407. + - fixes null pointer in openssl speed multi thread output.
  81408. + - fixes test keys to work with linux crypto's more stringent
  81409. + key checking.
  81410. + - adds MD5/SHA acceleration (Ronen Shitrit), only enabled
  81411. + with the --with-cryptodev-digests option
  81412. + - fixes bug in engine code caching.
  81413. +
  81414. + * build crypto-tools-XXXXXXXX.tar.gz if you want to try some of the BSD
  81415. + tools for testing OCF (ie., cryptotest).
  81416. +
  81417. +How to load the OCF drivers
  81418. +---------------------------
  81419. +
  81420. + First insert the base modules:
  81421. +
  81422. + insmod ocf
  81423. + insmod cryptodev
  81424. +
  81425. + You can then install the software OCF driver with:
  81426. +
  81427. + insmod cryptosoft
  81428. +
  81429. + and one or more of the OCF HW drivers with:
  81430. +
  81431. + insmod safe
  81432. + insmod hifn7751
  81433. + insmod ixp4xx
  81434. + ...
  81435. +
  81436. + all the drivers take a debug option to enable verbose debug so that
  81437. + you can see what is going on. For debug you load them as:
  81438. +
  81439. + insmod ocf crypto_debug=1
  81440. + insmod cryptodev cryptodev_debug=1
  81441. + insmod cryptosoft swcr_debug=1
  81442. +
  81443. + You may load more than one OCF crypto driver but then there is no guarantee
  81444. + as to which will be used.
  81445. +
  81446. + You can also enable debug at run time on 2.6 systems with the following:
  81447. +
  81448. + echo 1 > /sys/module/ocf/parameters/crypto_debug
  81449. + echo 1 > /sys/module/cryptodev/parameters/cryptodev_debug
  81450. + echo 1 > /sys/module/cryptosoft/parameters/swcr_debug
  81451. + echo 1 > /sys/module/hifn7751/parameters/hifn_debug
  81452. + echo 1 > /sys/module/safe/parameters/safe_debug
  81453. + echo 1 > /sys/module/ixp4xx/parameters/ixp_debug
  81454. + ...
  81455. +
  81456. +Testing the OCF support
  81457. +-----------------------
  81458. +
  81459. + run "cryptotest", it should do a short test for a couple of
  81460. + des packets. If it does everything is working.
  81461. +
  81462. + If this works, then ssh will use the driver when invoked as:
  81463. +
  81464. + ssh -c 3des username@host
  81465. +
  81466. + to see for sure that it is operating, enable debug as defined above.
  81467. +
  81468. + To get a better idea of performance run:
  81469. +
  81470. + cryptotest 100 4096
  81471. +
  81472. + There are more options to cryptotest, see the help.
  81473. +
  81474. + It is also possible to use openssl to test the speed of the crypto
  81475. + drivers.
  81476. +
  81477. + openssl speed -evp des -engine cryptodev -elapsed
  81478. + openssl speed -evp des3 -engine cryptodev -elapsed
  81479. + openssl speed -evp aes128 -engine cryptodev -elapsed
  81480. +
  81481. + and multiple threads (10) with:
  81482. +
  81483. + openssl speed -evp des -engine cryptodev -elapsed -multi 10
  81484. + openssl speed -evp des3 -engine cryptodev -elapsed -multi 10
  81485. + openssl speed -evp aes128 -engine cryptodev -elapsed -multi 10
  81486. +
  81487. + for public key testing you can try:
  81488. +
  81489. + cryptokeytest
  81490. + openssl speed -engine cryptodev rsa -elapsed
  81491. + openssl speed -engine cryptodev dsa -elapsed
  81492. +
  81493. +David McCullough
  81494. +david_mccullough@mcafee.com
  81495. diff -Nur linux-2.6.35.orig/crypto/ocf/rndtest.c linux-2.6.35/crypto/ocf/rndtest.c
  81496. --- linux-2.6.35.orig/crypto/ocf/rndtest.c 1970-01-01 01:00:00.000000000 +0100
  81497. +++ linux-2.6.35/crypto/ocf/rndtest.c 2010-08-05 22:02:26.284868112 +0200
  81498. @@ -0,0 +1,300 @@
  81499. +/* $OpenBSD$ */
  81500. +
  81501. +/*
  81502. + * OCF/Linux port done by David McCullough <david_mccullough@mcafee.com>
  81503. + * Copyright (C) 2006-2010 David McCullough
  81504. + * Copyright (C) 2004-2005 Intel Corporation.
  81505. + * The license and original author are listed below.
  81506. + *
  81507. + * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
  81508. + * All rights reserved.
  81509. + *
  81510. + * Redistribution and use in source and binary forms, with or without
  81511. + * modification, are permitted provided that the following conditions
  81512. + * are met:
  81513. + * 1. Redistributions of source code must retain the above copyright
  81514. + * notice, this list of conditions and the following disclaimer.
  81515. + * 2. Redistributions in binary form must reproduce the above copyright
  81516. + * notice, this list of conditions and the following disclaimer in the
  81517. + * documentation and/or other materials provided with the distribution.
  81518. + * 3. All advertising materials mentioning features or use of this software
  81519. + * must display the following acknowledgement:
  81520. + * This product includes software developed by Jason L. Wright
  81521. + * 4. The name of the author may not be used to endorse or promote products
  81522. + * derived from this software without specific prior written permission.
  81523. + *
  81524. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  81525. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  81526. + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  81527. + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  81528. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  81529. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  81530. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  81531. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  81532. + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  81533. + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  81534. + * POSSIBILITY OF SUCH DAMAGE.
  81535. + */
  81536. +
  81537. +#ifndef AUTOCONF_INCLUDED
  81538. +#include <linux/config.h>
  81539. +#endif
  81540. +#include <linux/module.h>
  81541. +#include <linux/list.h>
  81542. +#include <linux/wait.h>
  81543. +#include <linux/time.h>
  81544. +#include <linux/version.h>
  81545. +#include <linux/unistd.h>
  81546. +#include <linux/kernel.h>
  81547. +#include <linux/string.h>
  81548. +#include <linux/time.h>
  81549. +#include <cryptodev.h>
  81550. +#include "rndtest.h"
  81551. +
  81552. +static struct rndtest_stats rndstats;
  81553. +
  81554. +static void rndtest_test(struct rndtest_state *);
  81555. +
  81556. +/* The tests themselves */
  81557. +static int rndtest_monobit(struct rndtest_state *);
  81558. +static int rndtest_runs(struct rndtest_state *);
  81559. +static int rndtest_longruns(struct rndtest_state *);
  81560. +static int rndtest_chi_4(struct rndtest_state *);
  81561. +
  81562. +static int rndtest_runs_check(struct rndtest_state *, int, int *);
  81563. +static void rndtest_runs_record(struct rndtest_state *, int, int *);
  81564. +
  81565. +static const struct rndtest_testfunc {
  81566. + int (*test)(struct rndtest_state *);
  81567. +} rndtest_funcs[] = {
  81568. + { rndtest_monobit },
  81569. + { rndtest_runs },
  81570. + { rndtest_chi_4 },
  81571. + { rndtest_longruns },
  81572. +};
  81573. +
  81574. +#define RNDTEST_NTESTS (sizeof(rndtest_funcs)/sizeof(rndtest_funcs[0]))
  81575. +
  81576. +static void
  81577. +rndtest_test(struct rndtest_state *rsp)
  81578. +{
  81579. + int i, rv = 0;
  81580. +
  81581. + rndstats.rst_tests++;
  81582. + for (i = 0; i < RNDTEST_NTESTS; i++)
  81583. + rv |= (*rndtest_funcs[i].test)(rsp);
  81584. + rsp->rs_discard = (rv != 0);
  81585. +}
  81586. +
  81587. +
  81588. +extern int crypto_debug;
  81589. +#define rndtest_verbose 2
  81590. +#define rndtest_report(rsp, failure, fmt, a...) \
  81591. + { if (failure || crypto_debug) { printk("rng_test: " fmt "\n", a); } else; }
  81592. +
  81593. +#define RNDTEST_MONOBIT_MINONES 9725
  81594. +#define RNDTEST_MONOBIT_MAXONES 10275
  81595. +
  81596. +static int
  81597. +rndtest_monobit(struct rndtest_state *rsp)
  81598. +{
  81599. + int i, ones = 0, j;
  81600. + u_int8_t r;
  81601. +
  81602. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  81603. + r = rsp->rs_buf[i];
  81604. + for (j = 0; j < 8; j++, r <<= 1)
  81605. + if (r & 0x80)
  81606. + ones++;
  81607. + }
  81608. + if (ones > RNDTEST_MONOBIT_MINONES &&
  81609. + ones < RNDTEST_MONOBIT_MAXONES) {
  81610. + if (rndtest_verbose > 1)
  81611. + rndtest_report(rsp, 0, "monobit pass (%d < %d < %d)",
  81612. + RNDTEST_MONOBIT_MINONES, ones,
  81613. + RNDTEST_MONOBIT_MAXONES);
  81614. + return (0);
  81615. + } else {
  81616. + if (rndtest_verbose)
  81617. + rndtest_report(rsp, 1,
  81618. + "monobit failed (%d ones)", ones);
  81619. + rndstats.rst_monobit++;
  81620. + return (-1);
  81621. + }
  81622. +}
  81623. +
  81624. +#define RNDTEST_RUNS_NINTERVAL 6
  81625. +
  81626. +static const struct rndtest_runs_tabs {
  81627. + u_int16_t min, max;
  81628. +} rndtest_runs_tab[] = {
  81629. + { 2343, 2657 },
  81630. + { 1135, 1365 },
  81631. + { 542, 708 },
  81632. + { 251, 373 },
  81633. + { 111, 201 },
  81634. + { 111, 201 },
  81635. +};
  81636. +
  81637. +static int
  81638. +rndtest_runs(struct rndtest_state *rsp)
  81639. +{
  81640. + int i, j, ones, zeros, rv = 0;
  81641. + int onei[RNDTEST_RUNS_NINTERVAL], zeroi[RNDTEST_RUNS_NINTERVAL];
  81642. + u_int8_t c;
  81643. +
  81644. + bzero(onei, sizeof(onei));
  81645. + bzero(zeroi, sizeof(zeroi));
  81646. + ones = zeros = 0;
  81647. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  81648. + c = rsp->rs_buf[i];
  81649. + for (j = 0; j < 8; j++, c <<= 1) {
  81650. + if (c & 0x80) {
  81651. + ones++;
  81652. + rndtest_runs_record(rsp, zeros, zeroi);
  81653. + zeros = 0;
  81654. + } else {
  81655. + zeros++;
  81656. + rndtest_runs_record(rsp, ones, onei);
  81657. + ones = 0;
  81658. + }
  81659. + }
  81660. + }
  81661. + rndtest_runs_record(rsp, ones, onei);
  81662. + rndtest_runs_record(rsp, zeros, zeroi);
  81663. +
  81664. + rv |= rndtest_runs_check(rsp, 0, zeroi);
  81665. + rv |= rndtest_runs_check(rsp, 1, onei);
  81666. +
  81667. + if (rv)
  81668. + rndstats.rst_runs++;
  81669. +
  81670. + return (rv);
  81671. +}
  81672. +
  81673. +static void
  81674. +rndtest_runs_record(struct rndtest_state *rsp, int len, int *intrv)
  81675. +{
  81676. + if (len == 0)
  81677. + return;
  81678. + if (len > RNDTEST_RUNS_NINTERVAL)
  81679. + len = RNDTEST_RUNS_NINTERVAL;
  81680. + len -= 1;
  81681. + intrv[len]++;
  81682. +}
  81683. +
  81684. +static int
  81685. +rndtest_runs_check(struct rndtest_state *rsp, int val, int *src)
  81686. +{
  81687. + int i, rv = 0;
  81688. +
  81689. + for (i = 0; i < RNDTEST_RUNS_NINTERVAL; i++) {
  81690. + if (src[i] < rndtest_runs_tab[i].min ||
  81691. + src[i] > rndtest_runs_tab[i].max) {
  81692. + rndtest_report(rsp, 1,
  81693. + "%s interval %d failed (%d, %d-%d)",
  81694. + val ? "ones" : "zeros",
  81695. + i + 1, src[i], rndtest_runs_tab[i].min,
  81696. + rndtest_runs_tab[i].max);
  81697. + rv = -1;
  81698. + } else {
  81699. + rndtest_report(rsp, 0,
  81700. + "runs pass %s interval %d (%d < %d < %d)",
  81701. + val ? "ones" : "zeros",
  81702. + i + 1, rndtest_runs_tab[i].min, src[i],
  81703. + rndtest_runs_tab[i].max);
  81704. + }
  81705. + }
  81706. + return (rv);
  81707. +}
  81708. +
  81709. +static int
  81710. +rndtest_longruns(struct rndtest_state *rsp)
  81711. +{
  81712. + int i, j, ones = 0, zeros = 0, maxones = 0, maxzeros = 0;
  81713. + u_int8_t c;
  81714. +
  81715. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  81716. + c = rsp->rs_buf[i];
  81717. + for (j = 0; j < 8; j++, c <<= 1) {
  81718. + if (c & 0x80) {
  81719. + zeros = 0;
  81720. + ones++;
  81721. + if (ones > maxones)
  81722. + maxones = ones;
  81723. + } else {
  81724. + ones = 0;
  81725. + zeros++;
  81726. + if (zeros > maxzeros)
  81727. + maxzeros = zeros;
  81728. + }
  81729. + }
  81730. + }
  81731. +
  81732. + if (maxones < 26 && maxzeros < 26) {
  81733. + rndtest_report(rsp, 0, "longruns pass (%d ones, %d zeros)",
  81734. + maxones, maxzeros);
  81735. + return (0);
  81736. + } else {
  81737. + rndtest_report(rsp, 1, "longruns fail (%d ones, %d zeros)",
  81738. + maxones, maxzeros);
  81739. + rndstats.rst_longruns++;
  81740. + return (-1);
  81741. + }
  81742. +}
  81743. +
  81744. +/*
  81745. + * chi^2 test over 4 bits: (this is called the poker test in FIPS 140-2,
  81746. + * but it is really the chi^2 test over 4 bits (the poker test as described
  81747. + * by Knuth vol 2 is something different, and I take him as authoritative
  81748. + * on nomenclature over NIST).
  81749. + */
  81750. +#define RNDTEST_CHI4_K 16
  81751. +#define RNDTEST_CHI4_K_MASK (RNDTEST_CHI4_K - 1)
  81752. +
  81753. +/*
  81754. + * The unnormalized values are used so that we don't have to worry about
  81755. + * fractional precision. The "real" value is found by:
  81756. + * (V - 1562500) * (16 / 5000) = Vn (where V is the unnormalized value)
  81757. + */
  81758. +#define RNDTEST_CHI4_VMIN 1563181 /* 2.1792 */
  81759. +#define RNDTEST_CHI4_VMAX 1576929 /* 46.1728 */
  81760. +
  81761. +static int
  81762. +rndtest_chi_4(struct rndtest_state *rsp)
  81763. +{
  81764. + unsigned int freq[RNDTEST_CHI4_K], i, sum;
  81765. +
  81766. + for (i = 0; i < RNDTEST_CHI4_K; i++)
  81767. + freq[i] = 0;
  81768. +
  81769. + /* Get number of occurances of each 4 bit pattern */
  81770. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  81771. + freq[(rsp->rs_buf[i] >> 4) & RNDTEST_CHI4_K_MASK]++;
  81772. + freq[(rsp->rs_buf[i] >> 0) & RNDTEST_CHI4_K_MASK]++;
  81773. + }
  81774. +
  81775. + for (i = 0, sum = 0; i < RNDTEST_CHI4_K; i++)
  81776. + sum += freq[i] * freq[i];
  81777. +
  81778. + if (sum >= 1563181 && sum <= 1576929) {
  81779. + rndtest_report(rsp, 0, "chi^2(4): pass (sum %u)", sum);
  81780. + return (0);
  81781. + } else {
  81782. + rndtest_report(rsp, 1, "chi^2(4): failed (sum %u)", sum);
  81783. + rndstats.rst_chi++;
  81784. + return (-1);
  81785. + }
  81786. +}
  81787. +
  81788. +int
  81789. +rndtest_buf(unsigned char *buf)
  81790. +{
  81791. + struct rndtest_state rsp;
  81792. +
  81793. + memset(&rsp, 0, sizeof(rsp));
  81794. + rsp.rs_buf = buf;
  81795. + rndtest_test(&rsp);
  81796. + return(rsp.rs_discard);
  81797. +}
  81798. +
  81799. diff -Nur linux-2.6.35.orig/crypto/ocf/rndtest.h linux-2.6.35/crypto/ocf/rndtest.h
  81800. --- linux-2.6.35.orig/crypto/ocf/rndtest.h 1970-01-01 01:00:00.000000000 +0100
  81801. +++ linux-2.6.35/crypto/ocf/rndtest.h 2010-08-05 22:02:26.343715171 +0200
  81802. @@ -0,0 +1,54 @@
  81803. +/* $FreeBSD: src/sys/dev/rndtest/rndtest.h,v 1.1 2003/03/11 22:54:44 sam Exp $ */
  81804. +/* $OpenBSD$ */
  81805. +
  81806. +/*
  81807. + * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
  81808. + * All rights reserved.
  81809. + *
  81810. + * Redistribution and use in source and binary forms, with or without
  81811. + * modification, are permitted provided that the following conditions
  81812. + * are met:
  81813. + * 1. Redistributions of source code must retain the above copyright
  81814. + * notice, this list of conditions and the following disclaimer.
  81815. + * 2. Redistributions in binary form must reproduce the above copyright
  81816. + * notice, this list of conditions and the following disclaimer in the
  81817. + * documentation and/or other materials provided with the distribution.
  81818. + * 3. All advertising materials mentioning features or use of this software
  81819. + * must display the following acknowledgement:
  81820. + * This product includes software developed by Jason L. Wright
  81821. + * 4. The name of the author may not be used to endorse or promote products
  81822. + * derived from this software without specific prior written permission.
  81823. + *
  81824. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  81825. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  81826. + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  81827. + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  81828. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  81829. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  81830. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  81831. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  81832. + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  81833. + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  81834. + * POSSIBILITY OF SUCH DAMAGE.
  81835. + */
  81836. +
  81837. +
  81838. +/* Some of the tests depend on these values */
  81839. +#define RNDTEST_NBYTES 2500
  81840. +#define RNDTEST_NBITS (8 * RNDTEST_NBYTES)
  81841. +
  81842. +struct rndtest_state {
  81843. + int rs_discard; /* discard/accept random data */
  81844. + u_int8_t *rs_buf;
  81845. +};
  81846. +
  81847. +struct rndtest_stats {
  81848. + u_int32_t rst_discard; /* number of bytes discarded */
  81849. + u_int32_t rst_tests; /* number of test runs */
  81850. + u_int32_t rst_monobit; /* monobit test failures */
  81851. + u_int32_t rst_runs; /* 0/1 runs failures */
  81852. + u_int32_t rst_longruns; /* longruns failures */
  81853. + u_int32_t rst_chi; /* chi^2 failures */
  81854. +};
  81855. +
  81856. +extern int rndtest_buf(unsigned char *buf);
  81857. diff -Nur linux-2.6.35.orig/crypto/ocf/safe/Makefile linux-2.6.35/crypto/ocf/safe/Makefile
  81858. --- linux-2.6.35.orig/crypto/ocf/safe/Makefile 1970-01-01 01:00:00.000000000 +0100
  81859. +++ linux-2.6.35/crypto/ocf/safe/Makefile 2010-08-05 22:02:26.383883397 +0200
  81860. @@ -0,0 +1,12 @@
  81861. +# for SGlinux builds
  81862. +-include $(ROOTDIR)/modules/.config
  81863. +
  81864. +obj-$(CONFIG_OCF_SAFE) += safe.o
  81865. +
  81866. +obj ?= .
  81867. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  81868. +
  81869. +ifdef TOPDIR
  81870. +-include $(TOPDIR)/Rules.make
  81871. +endif
  81872. +
  81873. diff -Nur linux-2.6.35.orig/crypto/ocf/safe/md5.c linux-2.6.35/crypto/ocf/safe/md5.c
  81874. --- linux-2.6.35.orig/crypto/ocf/safe/md5.c 1970-01-01 01:00:00.000000000 +0100
  81875. +++ linux-2.6.35/crypto/ocf/safe/md5.c 2010-08-05 22:02:26.423813289 +0200
  81876. @@ -0,0 +1,308 @@
  81877. +/* $KAME: md5.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
  81878. +/*
  81879. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  81880. + * All rights reserved.
  81881. + *
  81882. + * Redistribution and use in source and binary forms, with or without
  81883. + * modification, are permitted provided that the following conditions
  81884. + * are met:
  81885. + * 1. Redistributions of source code must retain the above copyright
  81886. + * notice, this list of conditions and the following disclaimer.
  81887. + * 2. Redistributions in binary form must reproduce the above copyright
  81888. + * notice, this list of conditions and the following disclaimer in the
  81889. + * documentation and/or other materials provided with the distribution.
  81890. + * 3. Neither the name of the project nor the names of its contributors
  81891. + * may be used to endorse or promote products derived from this software
  81892. + * without specific prior written permission.
  81893. + *
  81894. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  81895. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  81896. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  81897. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  81898. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  81899. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  81900. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  81901. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  81902. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  81903. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  81904. + * SUCH DAMAGE.
  81905. + */
  81906. +
  81907. +#if 0
  81908. +#include <sys/cdefs.h>
  81909. +__FBSDID("$FreeBSD: src/sys/crypto/md5.c,v 1.9 2004/01/27 19:49:19 des Exp $");
  81910. +
  81911. +#include <sys/types.h>
  81912. +#include <sys/cdefs.h>
  81913. +#include <sys/time.h>
  81914. +#include <sys/systm.h>
  81915. +#include <crypto/md5.h>
  81916. +#endif
  81917. +
  81918. +#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
  81919. +
  81920. +#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
  81921. +#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
  81922. +#define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
  81923. +#define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
  81924. +
  81925. +#define ROUND1(a, b, c, d, k, s, i) { \
  81926. + (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
  81927. + (a) = SHIFT((a), (s)); \
  81928. + (a) = (b) + (a); \
  81929. +}
  81930. +
  81931. +#define ROUND2(a, b, c, d, k, s, i) { \
  81932. + (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
  81933. + (a) = SHIFT((a), (s)); \
  81934. + (a) = (b) + (a); \
  81935. +}
  81936. +
  81937. +#define ROUND3(a, b, c, d, k, s, i) { \
  81938. + (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
  81939. + (a) = SHIFT((a), (s)); \
  81940. + (a) = (b) + (a); \
  81941. +}
  81942. +
  81943. +#define ROUND4(a, b, c, d, k, s, i) { \
  81944. + (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
  81945. + (a) = SHIFT((a), (s)); \
  81946. + (a) = (b) + (a); \
  81947. +}
  81948. +
  81949. +#define Sa 7
  81950. +#define Sb 12
  81951. +#define Sc 17
  81952. +#define Sd 22
  81953. +
  81954. +#define Se 5
  81955. +#define Sf 9
  81956. +#define Sg 14
  81957. +#define Sh 20
  81958. +
  81959. +#define Si 4
  81960. +#define Sj 11
  81961. +#define Sk 16
  81962. +#define Sl 23
  81963. +
  81964. +#define Sm 6
  81965. +#define Sn 10
  81966. +#define So 15
  81967. +#define Sp 21
  81968. +
  81969. +#define MD5_A0 0x67452301
  81970. +#define MD5_B0 0xefcdab89
  81971. +#define MD5_C0 0x98badcfe
  81972. +#define MD5_D0 0x10325476
  81973. +
  81974. +/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
  81975. +static const u_int32_t T[65] = {
  81976. + 0,
  81977. + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
  81978. + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
  81979. + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
  81980. + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
  81981. +
  81982. + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
  81983. + 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
  81984. + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
  81985. + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
  81986. +
  81987. + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
  81988. + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
  81989. + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
  81990. + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
  81991. +
  81992. + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
  81993. + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
  81994. + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
  81995. + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
  81996. +};
  81997. +
  81998. +static const u_int8_t md5_paddat[MD5_BUFLEN] = {
  81999. + 0x80, 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. + 0, 0, 0, 0, 0, 0, 0, 0,
  82007. +};
  82008. +
  82009. +static void md5_calc(u_int8_t *, md5_ctxt *);
  82010. +
  82011. +void md5_init(ctxt)
  82012. + md5_ctxt *ctxt;
  82013. +{
  82014. + ctxt->md5_n = 0;
  82015. + ctxt->md5_i = 0;
  82016. + ctxt->md5_sta = MD5_A0;
  82017. + ctxt->md5_stb = MD5_B0;
  82018. + ctxt->md5_stc = MD5_C0;
  82019. + ctxt->md5_std = MD5_D0;
  82020. + bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf));
  82021. +}
  82022. +
  82023. +void md5_loop(ctxt, input, len)
  82024. + md5_ctxt *ctxt;
  82025. + u_int8_t *input;
  82026. + u_int len; /* number of bytes */
  82027. +{
  82028. + u_int gap, i;
  82029. +
  82030. + ctxt->md5_n += len * 8; /* byte to bit */
  82031. + gap = MD5_BUFLEN - ctxt->md5_i;
  82032. +
  82033. + if (len >= gap) {
  82034. + bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
  82035. + gap);
  82036. + md5_calc(ctxt->md5_buf, ctxt);
  82037. +
  82038. + for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
  82039. + md5_calc((u_int8_t *)(input + i), ctxt);
  82040. + }
  82041. +
  82042. + ctxt->md5_i = len - i;
  82043. + bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i);
  82044. + } else {
  82045. + bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
  82046. + len);
  82047. + ctxt->md5_i += len;
  82048. + }
  82049. +}
  82050. +
  82051. +void md5_pad(ctxt)
  82052. + md5_ctxt *ctxt;
  82053. +{
  82054. + u_int gap;
  82055. +
  82056. + /* Don't count up padding. Keep md5_n. */
  82057. + gap = MD5_BUFLEN - ctxt->md5_i;
  82058. + if (gap > 8) {
  82059. + bcopy(md5_paddat,
  82060. + (void *)(ctxt->md5_buf + ctxt->md5_i),
  82061. + gap - sizeof(ctxt->md5_n));
  82062. + } else {
  82063. + /* including gap == 8 */
  82064. + bcopy(md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i),
  82065. + gap);
  82066. + md5_calc(ctxt->md5_buf, ctxt);
  82067. + bcopy((md5_paddat + gap),
  82068. + (void *)ctxt->md5_buf,
  82069. + MD5_BUFLEN - sizeof(ctxt->md5_n));
  82070. + }
  82071. +
  82072. + /* 8 byte word */
  82073. +#if BYTE_ORDER == LITTLE_ENDIAN
  82074. + bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8);
  82075. +#endif
  82076. +#if BYTE_ORDER == BIG_ENDIAN
  82077. + ctxt->md5_buf[56] = ctxt->md5_n8[7];
  82078. + ctxt->md5_buf[57] = ctxt->md5_n8[6];
  82079. + ctxt->md5_buf[58] = ctxt->md5_n8[5];
  82080. + ctxt->md5_buf[59] = ctxt->md5_n8[4];
  82081. + ctxt->md5_buf[60] = ctxt->md5_n8[3];
  82082. + ctxt->md5_buf[61] = ctxt->md5_n8[2];
  82083. + ctxt->md5_buf[62] = ctxt->md5_n8[1];
  82084. + ctxt->md5_buf[63] = ctxt->md5_n8[0];
  82085. +#endif
  82086. +
  82087. + md5_calc(ctxt->md5_buf, ctxt);
  82088. +}
  82089. +
  82090. +void md5_result(digest, ctxt)
  82091. + u_int8_t *digest;
  82092. + md5_ctxt *ctxt;
  82093. +{
  82094. + /* 4 byte words */
  82095. +#if BYTE_ORDER == LITTLE_ENDIAN
  82096. + bcopy(&ctxt->md5_st8[0], digest, 16);
  82097. +#endif
  82098. +#if BYTE_ORDER == BIG_ENDIAN
  82099. + digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];
  82100. + digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];
  82101. + digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];
  82102. + digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];
  82103. + digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];
  82104. + digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];
  82105. + digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];
  82106. + digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];
  82107. +#endif
  82108. +}
  82109. +
  82110. +static void md5_calc(b64, ctxt)
  82111. + u_int8_t *b64;
  82112. + md5_ctxt *ctxt;
  82113. +{
  82114. + u_int32_t A = ctxt->md5_sta;
  82115. + u_int32_t B = ctxt->md5_stb;
  82116. + u_int32_t C = ctxt->md5_stc;
  82117. + u_int32_t D = ctxt->md5_std;
  82118. +#if BYTE_ORDER == LITTLE_ENDIAN
  82119. + u_int32_t *X = (u_int32_t *)b64;
  82120. +#endif
  82121. +#if BYTE_ORDER == BIG_ENDIAN
  82122. + /* 4 byte words */
  82123. + /* what a brute force but fast! */
  82124. + u_int32_t X[16];
  82125. + u_int8_t *y = (u_int8_t *)X;
  82126. + y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];
  82127. + y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];
  82128. + y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];
  82129. + y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];
  82130. + y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];
  82131. + y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];
  82132. + y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];
  82133. + y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];
  82134. + y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];
  82135. + y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];
  82136. + y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];
  82137. + y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];
  82138. + y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];
  82139. + y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];
  82140. + y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];
  82141. + y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];
  82142. +#endif
  82143. +
  82144. + ROUND1(A, B, C, D, 0, Sa, 1); ROUND1(D, A, B, C, 1, Sb, 2);
  82145. + ROUND1(C, D, A, B, 2, Sc, 3); ROUND1(B, C, D, A, 3, Sd, 4);
  82146. + ROUND1(A, B, C, D, 4, Sa, 5); ROUND1(D, A, B, C, 5, Sb, 6);
  82147. + ROUND1(C, D, A, B, 6, Sc, 7); ROUND1(B, C, D, A, 7, Sd, 8);
  82148. + ROUND1(A, B, C, D, 8, Sa, 9); ROUND1(D, A, B, C, 9, Sb, 10);
  82149. + ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
  82150. + ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
  82151. + ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
  82152. +
  82153. + ROUND2(A, B, C, D, 1, Se, 17); ROUND2(D, A, B, C, 6, Sf, 18);
  82154. + ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A, 0, Sh, 20);
  82155. + ROUND2(A, B, C, D, 5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
  82156. + ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A, 4, Sh, 24);
  82157. + ROUND2(A, B, C, D, 9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);
  82158. + ROUND2(C, D, A, B, 3, Sg, 27); ROUND2(B, C, D, A, 8, Sh, 28);
  82159. + ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C, 2, Sf, 30);
  82160. + ROUND2(C, D, A, B, 7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);
  82161. +
  82162. + ROUND3(A, B, C, D, 5, Si, 33); ROUND3(D, A, B, C, 8, Sj, 34);
  82163. + ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);
  82164. + ROUND3(A, B, C, D, 1, Si, 37); ROUND3(D, A, B, C, 4, Sj, 38);
  82165. + ROUND3(C, D, A, B, 7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);
  82166. + ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C, 0, Sj, 42);
  82167. + ROUND3(C, D, A, B, 3, Sk, 43); ROUND3(B, C, D, A, 6, Sl, 44);
  82168. + ROUND3(A, B, C, D, 9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
  82169. + ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A, 2, Sl, 48);
  82170. +
  82171. + ROUND4(A, B, C, D, 0, Sm, 49); ROUND4(D, A, B, C, 7, Sn, 50);
  82172. + ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A, 5, Sp, 52);
  82173. + ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C, 3, Sn, 54);
  82174. + ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A, 1, Sp, 56);
  82175. + ROUND4(A, B, C, D, 8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);
  82176. + ROUND4(C, D, A, B, 6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);
  82177. + ROUND4(A, B, C, D, 4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);
  82178. + ROUND4(C, D, A, B, 2, So, 63); ROUND4(B, C, D, A, 9, Sp, 64);
  82179. +
  82180. + ctxt->md5_sta += A;
  82181. + ctxt->md5_stb += B;
  82182. + ctxt->md5_stc += C;
  82183. + ctxt->md5_std += D;
  82184. +}
  82185. diff -Nur linux-2.6.35.orig/crypto/ocf/safe/md5.h linux-2.6.35/crypto/ocf/safe/md5.h
  82186. --- linux-2.6.35.orig/crypto/ocf/safe/md5.h 1970-01-01 01:00:00.000000000 +0100
  82187. +++ linux-2.6.35/crypto/ocf/safe/md5.h 2010-08-05 22:02:26.464868322 +0200
  82188. @@ -0,0 +1,76 @@
  82189. +/* $FreeBSD: src/sys/crypto/md5.h,v 1.4 2002/03/20 05:13:50 alfred Exp $ */
  82190. +/* $KAME: md5.h,v 1.4 2000/03/27 04:36:22 sumikawa Exp $ */
  82191. +
  82192. +/*
  82193. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  82194. + * All rights reserved.
  82195. + *
  82196. + * Redistribution and use in source and binary forms, with or without
  82197. + * modification, are permitted provided that the following conditions
  82198. + * are met:
  82199. + * 1. Redistributions of source code must retain the above copyright
  82200. + * notice, this list of conditions and the following disclaimer.
  82201. + * 2. Redistributions in binary form must reproduce the above copyright
  82202. + * notice, this list of conditions and the following disclaimer in the
  82203. + * documentation and/or other materials provided with the distribution.
  82204. + * 3. Neither the name of the project nor the names of its contributors
  82205. + * may be used to endorse or promote products derived from this software
  82206. + * without specific prior written permission.
  82207. + *
  82208. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  82209. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  82210. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  82211. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  82212. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  82213. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  82214. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  82215. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  82216. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  82217. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  82218. + * SUCH DAMAGE.
  82219. + */
  82220. +
  82221. +#ifndef _NETINET6_MD5_H_
  82222. +#define _NETINET6_MD5_H_
  82223. +
  82224. +#define MD5_BUFLEN 64
  82225. +
  82226. +typedef struct {
  82227. + union {
  82228. + u_int32_t md5_state32[4];
  82229. + u_int8_t md5_state8[16];
  82230. + } md5_st;
  82231. +
  82232. +#define md5_sta md5_st.md5_state32[0]
  82233. +#define md5_stb md5_st.md5_state32[1]
  82234. +#define md5_stc md5_st.md5_state32[2]
  82235. +#define md5_std md5_st.md5_state32[3]
  82236. +#define md5_st8 md5_st.md5_state8
  82237. +
  82238. + union {
  82239. + u_int64_t md5_count64;
  82240. + u_int8_t md5_count8[8];
  82241. + } md5_count;
  82242. +#define md5_n md5_count.md5_count64
  82243. +#define md5_n8 md5_count.md5_count8
  82244. +
  82245. + u_int md5_i;
  82246. + u_int8_t md5_buf[MD5_BUFLEN];
  82247. +} md5_ctxt;
  82248. +
  82249. +extern void md5_init(md5_ctxt *);
  82250. +extern void md5_loop(md5_ctxt *, u_int8_t *, u_int);
  82251. +extern void md5_pad(md5_ctxt *);
  82252. +extern void md5_result(u_int8_t *, md5_ctxt *);
  82253. +
  82254. +/* compatibility */
  82255. +#define MD5_CTX md5_ctxt
  82256. +#define MD5Init(x) md5_init((x))
  82257. +#define MD5Update(x, y, z) md5_loop((x), (y), (z))
  82258. +#define MD5Final(x, y) \
  82259. +do { \
  82260. + md5_pad((y)); \
  82261. + md5_result((x), (y)); \
  82262. +} while (0)
  82263. +
  82264. +#endif /* ! _NETINET6_MD5_H_*/
  82265. diff -Nur linux-2.6.35.orig/crypto/ocf/safe/safe.c linux-2.6.35/crypto/ocf/safe/safe.c
  82266. --- linux-2.6.35.orig/crypto/ocf/safe/safe.c 1970-01-01 01:00:00.000000000 +0100
  82267. +++ linux-2.6.35/crypto/ocf/safe/safe.c 2010-08-05 22:02:26.503759607 +0200
  82268. @@ -0,0 +1,2288 @@
  82269. +/*-
  82270. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  82271. + * Copyright (C) 2004-2010 David McCullough
  82272. + * The license and original author are listed below.
  82273. + *
  82274. + * Copyright (c) 2003 Sam Leffler, Errno Consulting
  82275. + * Copyright (c) 2003 Global Technology Associates, Inc.
  82276. + * All rights reserved.
  82277. + *
  82278. + * Redistribution and use in source and binary forms, with or without
  82279. + * modification, are permitted provided that the following conditions
  82280. + * are met:
  82281. + * 1. Redistributions of source code must retain the above copyright
  82282. + * notice, this list of conditions and the following disclaimer.
  82283. + * 2. Redistributions in binary form must reproduce the above copyright
  82284. + * notice, this list of conditions and the following disclaimer in the
  82285. + * documentation and/or other materials provided with the distribution.
  82286. + *
  82287. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  82288. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  82289. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  82290. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  82291. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  82292. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  82293. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  82294. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  82295. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  82296. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  82297. + * SUCH DAMAGE.
  82298. + *
  82299. +__FBSDID("$FreeBSD: src/sys/dev/safe/safe.c,v 1.18 2007/03/21 03:42:50 sam Exp $");
  82300. + */
  82301. +
  82302. +#ifndef AUTOCONF_INCLUDED
  82303. +#include <linux/config.h>
  82304. +#endif
  82305. +#include <linux/module.h>
  82306. +#include <linux/kernel.h>
  82307. +#include <linux/init.h>
  82308. +#include <linux/list.h>
  82309. +#include <linux/slab.h>
  82310. +#include <linux/wait.h>
  82311. +#include <linux/sched.h>
  82312. +#include <linux/pci.h>
  82313. +#include <linux/delay.h>
  82314. +#include <linux/interrupt.h>
  82315. +#include <linux/spinlock.h>
  82316. +#include <linux/random.h>
  82317. +#include <linux/version.h>
  82318. +#include <linux/skbuff.h>
  82319. +#include <asm/io.h>
  82320. +
  82321. +/*
  82322. + * SafeNet SafeXcel-1141 hardware crypto accelerator
  82323. + */
  82324. +
  82325. +#include <cryptodev.h>
  82326. +#include <uio.h>
  82327. +#include <safe/safereg.h>
  82328. +#include <safe/safevar.h>
  82329. +
  82330. +#if 1
  82331. +#define DPRINTF(a) do { \
  82332. + if (debug) { \
  82333. + printk("%s: ", sc ? \
  82334. + device_get_nameunit(sc->sc_dev) : "safe"); \
  82335. + printk a; \
  82336. + } \
  82337. + } while (0)
  82338. +#else
  82339. +#define DPRINTF(a)
  82340. +#endif
  82341. +
  82342. +/*
  82343. + * until we find a cleaner way, include the BSD md5/sha1 code
  82344. + * here
  82345. + */
  82346. +#define HMAC_HACK 1
  82347. +#ifdef HMAC_HACK
  82348. +#define LITTLE_ENDIAN 1234
  82349. +#define BIG_ENDIAN 4321
  82350. +#ifdef __LITTLE_ENDIAN
  82351. +#define BYTE_ORDER LITTLE_ENDIAN
  82352. +#endif
  82353. +#ifdef __BIG_ENDIAN
  82354. +#define BYTE_ORDER BIG_ENDIAN
  82355. +#endif
  82356. +#include <safe/md5.h>
  82357. +#include <safe/md5.c>
  82358. +#include <safe/sha1.h>
  82359. +#include <safe/sha1.c>
  82360. +
  82361. +u_int8_t hmac_ipad_buffer[64] = {
  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. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
  82370. +};
  82371. +
  82372. +u_int8_t hmac_opad_buffer[64] = {
  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. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
  82381. +};
  82382. +#endif /* HMAC_HACK */
  82383. +
  82384. +/* add proc entry for this */
  82385. +struct safe_stats safestats;
  82386. +
  82387. +#define debug safe_debug
  82388. +int safe_debug = 0;
  82389. +module_param(safe_debug, int, 0644);
  82390. +MODULE_PARM_DESC(safe_debug, "Enable debug");
  82391. +
  82392. +static void safe_callback(struct safe_softc *, struct safe_ringentry *);
  82393. +static void safe_feed(struct safe_softc *, struct safe_ringentry *);
  82394. +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
  82395. +static void safe_rng_init(struct safe_softc *);
  82396. +int safe_rngbufsize = 8; /* 32 bytes each read */
  82397. +module_param(safe_rngbufsize, int, 0644);
  82398. +MODULE_PARM_DESC(safe_rngbufsize, "RNG polling buffer size (32-bit words)");
  82399. +int safe_rngmaxalarm = 8; /* max alarms before reset */
  82400. +module_param(safe_rngmaxalarm, int, 0644);
  82401. +MODULE_PARM_DESC(safe_rngmaxalarm, "RNG max alarms before reset");
  82402. +#endif /* SAFE_NO_RNG */
  82403. +
  82404. +static void safe_totalreset(struct safe_softc *sc);
  82405. +static int safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op);
  82406. +static int safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op);
  82407. +static int safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re);
  82408. +static int safe_kprocess(device_t dev, struct cryptkop *krp, int hint);
  82409. +static int safe_kstart(struct safe_softc *sc);
  82410. +static int safe_ksigbits(struct safe_softc *sc, struct crparam *cr);
  82411. +static void safe_kfeed(struct safe_softc *sc);
  82412. +static void safe_kpoll(unsigned long arg);
  82413. +static void safe_kload_reg(struct safe_softc *sc, u_int32_t off,
  82414. + u_int32_t len, struct crparam *n);
  82415. +
  82416. +static int safe_newsession(device_t, u_int32_t *, struct cryptoini *);
  82417. +static int safe_freesession(device_t, u_int64_t);
  82418. +static int safe_process(device_t, struct cryptop *, int);
  82419. +
  82420. +static device_method_t safe_methods = {
  82421. + /* crypto device methods */
  82422. + DEVMETHOD(cryptodev_newsession, safe_newsession),
  82423. + DEVMETHOD(cryptodev_freesession,safe_freesession),
  82424. + DEVMETHOD(cryptodev_process, safe_process),
  82425. + DEVMETHOD(cryptodev_kprocess, safe_kprocess),
  82426. +};
  82427. +
  82428. +#define READ_REG(sc,r) readl((sc)->sc_base_addr + (r))
  82429. +#define WRITE_REG(sc,r,val) writel((val), (sc)->sc_base_addr + (r))
  82430. +
  82431. +#define SAFE_MAX_CHIPS 8
  82432. +static struct safe_softc *safe_chip_idx[SAFE_MAX_CHIPS];
  82433. +
  82434. +/*
  82435. + * split our buffers up into safe DMAable byte fragments to avoid lockup
  82436. + * bug in 1141 HW on rev 1.0.
  82437. + */
  82438. +
  82439. +static int
  82440. +pci_map_linear(
  82441. + struct safe_softc *sc,
  82442. + struct safe_operand *buf,
  82443. + void *addr,
  82444. + int len)
  82445. +{
  82446. + dma_addr_t tmp;
  82447. + int chunk, tlen = len;
  82448. +
  82449. + tmp = pci_map_single(sc->sc_pcidev, addr, len, PCI_DMA_BIDIRECTIONAL);
  82450. +
  82451. + buf->mapsize += len;
  82452. + while (len > 0) {
  82453. + chunk = (len > sc->sc_max_dsize) ? sc->sc_max_dsize : len;
  82454. + buf->segs[buf->nsegs].ds_addr = tmp;
  82455. + buf->segs[buf->nsegs].ds_len = chunk;
  82456. + buf->segs[buf->nsegs].ds_tlen = tlen;
  82457. + buf->nsegs++;
  82458. + tmp += chunk;
  82459. + len -= chunk;
  82460. + tlen = 0;
  82461. + }
  82462. + return 0;
  82463. +}
  82464. +
  82465. +/*
  82466. + * map in a given uio buffer (great on some arches :-)
  82467. + */
  82468. +
  82469. +static int
  82470. +pci_map_uio(struct safe_softc *sc, struct safe_operand *buf, struct uio *uio)
  82471. +{
  82472. + struct iovec *iov = uio->uio_iov;
  82473. + int n;
  82474. +
  82475. + DPRINTF(("%s()\n", __FUNCTION__));
  82476. +
  82477. + buf->mapsize = 0;
  82478. + buf->nsegs = 0;
  82479. +
  82480. + for (n = 0; n < uio->uio_iovcnt; n++) {
  82481. + pci_map_linear(sc, buf, iov->iov_base, iov->iov_len);
  82482. + iov++;
  82483. + }
  82484. +
  82485. + /* identify this buffer by the first segment */
  82486. + buf->map = (void *) buf->segs[0].ds_addr;
  82487. + return(0);
  82488. +}
  82489. +
  82490. +/*
  82491. + * map in a given sk_buff
  82492. + */
  82493. +
  82494. +static int
  82495. +pci_map_skb(struct safe_softc *sc,struct safe_operand *buf,struct sk_buff *skb)
  82496. +{
  82497. + int i;
  82498. +
  82499. + DPRINTF(("%s()\n", __FUNCTION__));
  82500. +
  82501. + buf->mapsize = 0;
  82502. + buf->nsegs = 0;
  82503. +
  82504. + pci_map_linear(sc, buf, skb->data, skb_headlen(skb));
  82505. +
  82506. + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
  82507. + pci_map_linear(sc, buf,
  82508. + page_address(skb_shinfo(skb)->frags[i].page) +
  82509. + skb_shinfo(skb)->frags[i].page_offset,
  82510. + skb_shinfo(skb)->frags[i].size);
  82511. + }
  82512. +
  82513. + /* identify this buffer by the first segment */
  82514. + buf->map = (void *) buf->segs[0].ds_addr;
  82515. + return(0);
  82516. +}
  82517. +
  82518. +
  82519. +#if 0 /* not needed at this time */
  82520. +static void
  82521. +pci_sync_operand(struct safe_softc *sc, struct safe_operand *buf)
  82522. +{
  82523. + int i;
  82524. +
  82525. + DPRINTF(("%s()\n", __FUNCTION__));
  82526. + for (i = 0; i < buf->nsegs; i++)
  82527. + pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
  82528. + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
  82529. +}
  82530. +#endif
  82531. +
  82532. +static void
  82533. +pci_unmap_operand(struct safe_softc *sc, struct safe_operand *buf)
  82534. +{
  82535. + int i;
  82536. + DPRINTF(("%s()\n", __FUNCTION__));
  82537. + for (i = 0; i < buf->nsegs; i++) {
  82538. + if (buf->segs[i].ds_tlen) {
  82539. + DPRINTF(("%s - unmap %d 0x%x %d\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));
  82540. + pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
  82541. + buf->segs[i].ds_tlen, PCI_DMA_BIDIRECTIONAL);
  82542. + DPRINTF(("%s - unmap %d 0x%x %d done\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));
  82543. + }
  82544. + buf->segs[i].ds_addr = 0;
  82545. + buf->segs[i].ds_len = 0;
  82546. + buf->segs[i].ds_tlen = 0;
  82547. + }
  82548. + buf->nsegs = 0;
  82549. + buf->mapsize = 0;
  82550. + buf->map = 0;
  82551. +}
  82552. +
  82553. +
  82554. +/*
  82555. + * SafeXcel Interrupt routine
  82556. + */
  82557. +static irqreturn_t
  82558. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  82559. +safe_intr(int irq, void *arg)
  82560. +#else
  82561. +safe_intr(int irq, void *arg, struct pt_regs *regs)
  82562. +#endif
  82563. +{
  82564. + struct safe_softc *sc = arg;
  82565. + int stat;
  82566. + unsigned long flags;
  82567. +
  82568. + stat = READ_REG(sc, SAFE_HM_STAT);
  82569. +
  82570. + DPRINTF(("%s(stat=0x%x)\n", __FUNCTION__, stat));
  82571. +
  82572. + if (stat == 0) /* shared irq, not for us */
  82573. + return IRQ_NONE;
  82574. +
  82575. + WRITE_REG(sc, SAFE_HI_CLR, stat); /* IACK */
  82576. +
  82577. + if ((stat & SAFE_INT_PE_DDONE)) {
  82578. + /*
  82579. + * Descriptor(s) done; scan the ring and
  82580. + * process completed operations.
  82581. + */
  82582. + spin_lock_irqsave(&sc->sc_ringmtx, flags);
  82583. + while (sc->sc_back != sc->sc_front) {
  82584. + struct safe_ringentry *re = sc->sc_back;
  82585. +
  82586. +#ifdef SAFE_DEBUG
  82587. + if (debug) {
  82588. + safe_dump_ringstate(sc, __func__);
  82589. + safe_dump_request(sc, __func__, re);
  82590. + }
  82591. +#endif
  82592. + /*
  82593. + * safe_process marks ring entries that were allocated
  82594. + * but not used with a csr of zero. This insures the
  82595. + * ring front pointer never needs to be set backwards
  82596. + * in the event that an entry is allocated but not used
  82597. + * because of a setup error.
  82598. + */
  82599. + DPRINTF(("%s re->re_desc.d_csr=0x%x\n", __FUNCTION__, re->re_desc.d_csr));
  82600. + if (re->re_desc.d_csr != 0) {
  82601. + if (!SAFE_PE_CSR_IS_DONE(re->re_desc.d_csr)) {
  82602. + DPRINTF(("%s !CSR_IS_DONE\n", __FUNCTION__));
  82603. + break;
  82604. + }
  82605. + if (!SAFE_PE_LEN_IS_DONE(re->re_desc.d_len)) {
  82606. + DPRINTF(("%s !LEN_IS_DONE\n", __FUNCTION__));
  82607. + break;
  82608. + }
  82609. + sc->sc_nqchip--;
  82610. + safe_callback(sc, re);
  82611. + }
  82612. + if (++(sc->sc_back) == sc->sc_ringtop)
  82613. + sc->sc_back = sc->sc_ring;
  82614. + }
  82615. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  82616. + }
  82617. +
  82618. + /*
  82619. + * Check to see if we got any DMA Error
  82620. + */
  82621. + if (stat & SAFE_INT_PE_ERROR) {
  82622. + printk("%s: dmaerr dmastat %08x\n", device_get_nameunit(sc->sc_dev),
  82623. + (int)READ_REG(sc, SAFE_PE_DMASTAT));
  82624. + safestats.st_dmaerr++;
  82625. + safe_totalreset(sc);
  82626. +#if 0
  82627. + safe_feed(sc);
  82628. +#endif
  82629. + }
  82630. +
  82631. + if (sc->sc_needwakeup) { /* XXX check high watermark */
  82632. + int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
  82633. + DPRINTF(("%s: wakeup crypto %x\n", __func__,
  82634. + sc->sc_needwakeup));
  82635. + sc->sc_needwakeup &= ~wakeup;
  82636. + crypto_unblock(sc->sc_cid, wakeup);
  82637. + }
  82638. +
  82639. + return IRQ_HANDLED;
  82640. +}
  82641. +
  82642. +/*
  82643. + * safe_feed() - post a request to chip
  82644. + */
  82645. +static void
  82646. +safe_feed(struct safe_softc *sc, struct safe_ringentry *re)
  82647. +{
  82648. + DPRINTF(("%s()\n", __FUNCTION__));
  82649. +#ifdef SAFE_DEBUG
  82650. + if (debug) {
  82651. + safe_dump_ringstate(sc, __func__);
  82652. + safe_dump_request(sc, __func__, re);
  82653. + }
  82654. +#endif
  82655. + sc->sc_nqchip++;
  82656. + if (sc->sc_nqchip > safestats.st_maxqchip)
  82657. + safestats.st_maxqchip = sc->sc_nqchip;
  82658. + /* poke h/w to check descriptor ring, any value can be written */
  82659. + WRITE_REG(sc, SAFE_HI_RD_DESCR, 0);
  82660. +}
  82661. +
  82662. +#define N(a) (sizeof(a) / sizeof (a[0]))
  82663. +static void
  82664. +safe_setup_enckey(struct safe_session *ses, caddr_t key)
  82665. +{
  82666. + int i;
  82667. +
  82668. + bcopy(key, ses->ses_key, ses->ses_klen / 8);
  82669. +
  82670. + /* PE is little-endian, insure proper byte order */
  82671. + for (i = 0; i < N(ses->ses_key); i++)
  82672. + ses->ses_key[i] = htole32(ses->ses_key[i]);
  82673. +}
  82674. +
  82675. +static void
  82676. +safe_setup_mackey(struct safe_session *ses, int algo, caddr_t key, int klen)
  82677. +{
  82678. +#ifdef HMAC_HACK
  82679. + MD5_CTX md5ctx;
  82680. + SHA1_CTX sha1ctx;
  82681. + int i;
  82682. +
  82683. +
  82684. + for (i = 0; i < klen; i++)
  82685. + key[i] ^= HMAC_IPAD_VAL;
  82686. +
  82687. + if (algo == CRYPTO_MD5_HMAC) {
  82688. + MD5Init(&md5ctx);
  82689. + MD5Update(&md5ctx, key, klen);
  82690. + MD5Update(&md5ctx, hmac_ipad_buffer, MD5_HMAC_BLOCK_LEN - klen);
  82691. + bcopy(md5ctx.md5_st8, ses->ses_hminner, sizeof(md5ctx.md5_st8));
  82692. + } else {
  82693. + SHA1Init(&sha1ctx);
  82694. + SHA1Update(&sha1ctx, key, klen);
  82695. + SHA1Update(&sha1ctx, hmac_ipad_buffer,
  82696. + SHA1_HMAC_BLOCK_LEN - klen);
  82697. + bcopy(sha1ctx.h.b32, ses->ses_hminner, sizeof(sha1ctx.h.b32));
  82698. + }
  82699. +
  82700. + for (i = 0; i < klen; i++)
  82701. + key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
  82702. +
  82703. + if (algo == CRYPTO_MD5_HMAC) {
  82704. + MD5Init(&md5ctx);
  82705. + MD5Update(&md5ctx, key, klen);
  82706. + MD5Update(&md5ctx, hmac_opad_buffer, MD5_HMAC_BLOCK_LEN - klen);
  82707. + bcopy(md5ctx.md5_st8, ses->ses_hmouter, sizeof(md5ctx.md5_st8));
  82708. + } else {
  82709. + SHA1Init(&sha1ctx);
  82710. + SHA1Update(&sha1ctx, key, klen);
  82711. + SHA1Update(&sha1ctx, hmac_opad_buffer,
  82712. + SHA1_HMAC_BLOCK_LEN - klen);
  82713. + bcopy(sha1ctx.h.b32, ses->ses_hmouter, sizeof(sha1ctx.h.b32));
  82714. + }
  82715. +
  82716. + for (i = 0; i < klen; i++)
  82717. + key[i] ^= HMAC_OPAD_VAL;
  82718. +
  82719. +#if 0
  82720. + /*
  82721. + * this code prevents SHA working on a BE host,
  82722. + * so it is obviously wrong. I think the byte
  82723. + * swap setup we do with the chip fixes this for us
  82724. + */
  82725. +
  82726. + /* PE is little-endian, insure proper byte order */
  82727. + for (i = 0; i < N(ses->ses_hminner); i++) {
  82728. + ses->ses_hminner[i] = htole32(ses->ses_hminner[i]);
  82729. + ses->ses_hmouter[i] = htole32(ses->ses_hmouter[i]);
  82730. + }
  82731. +#endif
  82732. +#else /* HMAC_HACK */
  82733. + printk("safe: md5/sha not implemented\n");
  82734. +#endif /* HMAC_HACK */
  82735. +}
  82736. +#undef N
  82737. +
  82738. +/*
  82739. + * Allocate a new 'session' and return an encoded session id. 'sidp'
  82740. + * contains our registration id, and should contain an encoded session
  82741. + * id on successful allocation.
  82742. + */
  82743. +static int
  82744. +safe_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  82745. +{
  82746. + struct safe_softc *sc = device_get_softc(dev);
  82747. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  82748. + struct safe_session *ses = NULL;
  82749. + int sesn;
  82750. +
  82751. + DPRINTF(("%s()\n", __FUNCTION__));
  82752. +
  82753. + if (sidp == NULL || cri == NULL || sc == NULL)
  82754. + return (EINVAL);
  82755. +
  82756. + for (c = cri; c != NULL; c = c->cri_next) {
  82757. + if (c->cri_alg == CRYPTO_MD5_HMAC ||
  82758. + c->cri_alg == CRYPTO_SHA1_HMAC ||
  82759. + c->cri_alg == CRYPTO_NULL_HMAC) {
  82760. + if (macini)
  82761. + return (EINVAL);
  82762. + macini = c;
  82763. + } else if (c->cri_alg == CRYPTO_DES_CBC ||
  82764. + c->cri_alg == CRYPTO_3DES_CBC ||
  82765. + c->cri_alg == CRYPTO_AES_CBC ||
  82766. + c->cri_alg == CRYPTO_NULL_CBC) {
  82767. + if (encini)
  82768. + return (EINVAL);
  82769. + encini = c;
  82770. + } else
  82771. + return (EINVAL);
  82772. + }
  82773. + if (encini == NULL && macini == NULL)
  82774. + return (EINVAL);
  82775. + if (encini) { /* validate key length */
  82776. + switch (encini->cri_alg) {
  82777. + case CRYPTO_DES_CBC:
  82778. + if (encini->cri_klen != 64)
  82779. + return (EINVAL);
  82780. + break;
  82781. + case CRYPTO_3DES_CBC:
  82782. + if (encini->cri_klen != 192)
  82783. + return (EINVAL);
  82784. + break;
  82785. + case CRYPTO_AES_CBC:
  82786. + if (encini->cri_klen != 128 &&
  82787. + encini->cri_klen != 192 &&
  82788. + encini->cri_klen != 256)
  82789. + return (EINVAL);
  82790. + break;
  82791. + }
  82792. + }
  82793. +
  82794. + if (sc->sc_sessions == NULL) {
  82795. + ses = sc->sc_sessions = (struct safe_session *)
  82796. + kmalloc(sizeof(struct safe_session), SLAB_ATOMIC);
  82797. + if (ses == NULL)
  82798. + return (ENOMEM);
  82799. + memset(ses, 0, sizeof(struct safe_session));
  82800. + sesn = 0;
  82801. + sc->sc_nsessions = 1;
  82802. + } else {
  82803. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  82804. + if (sc->sc_sessions[sesn].ses_used == 0) {
  82805. + ses = &sc->sc_sessions[sesn];
  82806. + break;
  82807. + }
  82808. + }
  82809. +
  82810. + if (ses == NULL) {
  82811. + sesn = sc->sc_nsessions;
  82812. + ses = (struct safe_session *)
  82813. + kmalloc((sesn + 1) * sizeof(struct safe_session), SLAB_ATOMIC);
  82814. + if (ses == NULL)
  82815. + return (ENOMEM);
  82816. + memset(ses, 0, (sesn + 1) * sizeof(struct safe_session));
  82817. + bcopy(sc->sc_sessions, ses, sesn *
  82818. + sizeof(struct safe_session));
  82819. + bzero(sc->sc_sessions, sesn *
  82820. + sizeof(struct safe_session));
  82821. + kfree(sc->sc_sessions);
  82822. + sc->sc_sessions = ses;
  82823. + ses = &sc->sc_sessions[sesn];
  82824. + sc->sc_nsessions++;
  82825. + }
  82826. + }
  82827. +
  82828. + bzero(ses, sizeof(struct safe_session));
  82829. + ses->ses_used = 1;
  82830. +
  82831. + if (encini) {
  82832. + /* get an IV */
  82833. + /* XXX may read fewer than requested */
  82834. + read_random(ses->ses_iv, sizeof(ses->ses_iv));
  82835. +
  82836. + ses->ses_klen = encini->cri_klen;
  82837. + if (encini->cri_key != NULL)
  82838. + safe_setup_enckey(ses, encini->cri_key);
  82839. + }
  82840. +
  82841. + if (macini) {
  82842. + ses->ses_mlen = macini->cri_mlen;
  82843. + if (ses->ses_mlen == 0) {
  82844. + if (macini->cri_alg == CRYPTO_MD5_HMAC)
  82845. + ses->ses_mlen = MD5_HASH_LEN;
  82846. + else
  82847. + ses->ses_mlen = SHA1_HASH_LEN;
  82848. + }
  82849. +
  82850. + if (macini->cri_key != NULL) {
  82851. + safe_setup_mackey(ses, macini->cri_alg, macini->cri_key,
  82852. + macini->cri_klen / 8);
  82853. + }
  82854. + }
  82855. +
  82856. + *sidp = SAFE_SID(device_get_unit(sc->sc_dev), sesn);
  82857. + return (0);
  82858. +}
  82859. +
  82860. +/*
  82861. + * Deallocate a session.
  82862. + */
  82863. +static int
  82864. +safe_freesession(device_t dev, u_int64_t tid)
  82865. +{
  82866. + struct safe_softc *sc = device_get_softc(dev);
  82867. + int session, ret;
  82868. + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
  82869. +
  82870. + DPRINTF(("%s()\n", __FUNCTION__));
  82871. +
  82872. + if (sc == NULL)
  82873. + return (EINVAL);
  82874. +
  82875. + session = SAFE_SESSION(sid);
  82876. + if (session < sc->sc_nsessions) {
  82877. + bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session]));
  82878. + ret = 0;
  82879. + } else
  82880. + ret = EINVAL;
  82881. + return (ret);
  82882. +}
  82883. +
  82884. +
  82885. +static int
  82886. +safe_process(device_t dev, struct cryptop *crp, int hint)
  82887. +{
  82888. + struct safe_softc *sc = device_get_softc(dev);
  82889. + int err = 0, i, nicealign, uniform;
  82890. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  82891. + int bypass, oplen, ivsize;
  82892. + caddr_t iv;
  82893. + int16_t coffset;
  82894. + struct safe_session *ses;
  82895. + struct safe_ringentry *re;
  82896. + struct safe_sarec *sa;
  82897. + struct safe_pdesc *pd;
  82898. + u_int32_t cmd0, cmd1, staterec;
  82899. + unsigned long flags;
  82900. +
  82901. + DPRINTF(("%s()\n", __FUNCTION__));
  82902. +
  82903. + if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
  82904. + safestats.st_invalid++;
  82905. + return (EINVAL);
  82906. + }
  82907. + if (SAFE_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
  82908. + safestats.st_badsession++;
  82909. + return (EINVAL);
  82910. + }
  82911. +
  82912. + spin_lock_irqsave(&sc->sc_ringmtx, flags);
  82913. + if (sc->sc_front == sc->sc_back && sc->sc_nqchip != 0) {
  82914. + safestats.st_ringfull++;
  82915. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  82916. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  82917. + return (ERESTART);
  82918. + }
  82919. + re = sc->sc_front;
  82920. +
  82921. + staterec = re->re_sa.sa_staterec; /* save */
  82922. + /* NB: zero everything but the PE descriptor */
  82923. + bzero(&re->re_sa, sizeof(struct safe_ringentry) - sizeof(re->re_desc));
  82924. + re->re_sa.sa_staterec = staterec; /* restore */
  82925. +
  82926. + re->re_crp = crp;
  82927. + re->re_sesn = SAFE_SESSION(crp->crp_sid);
  82928. +
  82929. + re->re_src.nsegs = 0;
  82930. + re->re_dst.nsegs = 0;
  82931. +
  82932. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  82933. + re->re_src_skb = (struct sk_buff *)crp->crp_buf;
  82934. + re->re_dst_skb = (struct sk_buff *)crp->crp_buf;
  82935. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  82936. + re->re_src_io = (struct uio *)crp->crp_buf;
  82937. + re->re_dst_io = (struct uio *)crp->crp_buf;
  82938. + } else {
  82939. + safestats.st_badflags++;
  82940. + err = EINVAL;
  82941. + goto errout; /* XXX we don't handle contiguous blocks! */
  82942. + }
  82943. +
  82944. + sa = &re->re_sa;
  82945. + ses = &sc->sc_sessions[re->re_sesn];
  82946. +
  82947. + crd1 = crp->crp_desc;
  82948. + if (crd1 == NULL) {
  82949. + safestats.st_nodesc++;
  82950. + err = EINVAL;
  82951. + goto errout;
  82952. + }
  82953. + crd2 = crd1->crd_next;
  82954. +
  82955. + cmd0 = SAFE_SA_CMD0_BASIC; /* basic group operation */
  82956. + cmd1 = 0;
  82957. + if (crd2 == NULL) {
  82958. + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
  82959. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  82960. + crd1->crd_alg == CRYPTO_NULL_HMAC) {
  82961. + maccrd = crd1;
  82962. + enccrd = NULL;
  82963. + cmd0 |= SAFE_SA_CMD0_OP_HASH;
  82964. + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
  82965. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  82966. + crd1->crd_alg == CRYPTO_AES_CBC ||
  82967. + crd1->crd_alg == CRYPTO_NULL_CBC) {
  82968. + maccrd = NULL;
  82969. + enccrd = crd1;
  82970. + cmd0 |= SAFE_SA_CMD0_OP_CRYPT;
  82971. + } else {
  82972. + safestats.st_badalg++;
  82973. + err = EINVAL;
  82974. + goto errout;
  82975. + }
  82976. + } else {
  82977. + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
  82978. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  82979. + crd1->crd_alg == CRYPTO_NULL_HMAC) &&
  82980. + (crd2->crd_alg == CRYPTO_DES_CBC ||
  82981. + crd2->crd_alg == CRYPTO_3DES_CBC ||
  82982. + crd2->crd_alg == CRYPTO_AES_CBC ||
  82983. + crd2->crd_alg == CRYPTO_NULL_CBC) &&
  82984. + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
  82985. + maccrd = crd1;
  82986. + enccrd = crd2;
  82987. + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
  82988. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  82989. + crd1->crd_alg == CRYPTO_AES_CBC ||
  82990. + crd1->crd_alg == CRYPTO_NULL_CBC) &&
  82991. + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
  82992. + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
  82993. + crd2->crd_alg == CRYPTO_NULL_HMAC) &&
  82994. + (crd1->crd_flags & CRD_F_ENCRYPT)) {
  82995. + enccrd = crd1;
  82996. + maccrd = crd2;
  82997. + } else {
  82998. + safestats.st_badalg++;
  82999. + err = EINVAL;
  83000. + goto errout;
  83001. + }
  83002. + cmd0 |= SAFE_SA_CMD0_OP_BOTH;
  83003. + }
  83004. +
  83005. + if (enccrd) {
  83006. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
  83007. + safe_setup_enckey(ses, enccrd->crd_key);
  83008. +
  83009. + if (enccrd->crd_alg == CRYPTO_DES_CBC) {
  83010. + cmd0 |= SAFE_SA_CMD0_DES;
  83011. + cmd1 |= SAFE_SA_CMD1_CBC;
  83012. + ivsize = 2*sizeof(u_int32_t);
  83013. + } else if (enccrd->crd_alg == CRYPTO_3DES_CBC) {
  83014. + cmd0 |= SAFE_SA_CMD0_3DES;
  83015. + cmd1 |= SAFE_SA_CMD1_CBC;
  83016. + ivsize = 2*sizeof(u_int32_t);
  83017. + } else if (enccrd->crd_alg == CRYPTO_AES_CBC) {
  83018. + cmd0 |= SAFE_SA_CMD0_AES;
  83019. + cmd1 |= SAFE_SA_CMD1_CBC;
  83020. + if (ses->ses_klen == 128)
  83021. + cmd1 |= SAFE_SA_CMD1_AES128;
  83022. + else if (ses->ses_klen == 192)
  83023. + cmd1 |= SAFE_SA_CMD1_AES192;
  83024. + else
  83025. + cmd1 |= SAFE_SA_CMD1_AES256;
  83026. + ivsize = 4*sizeof(u_int32_t);
  83027. + } else {
  83028. + cmd0 |= SAFE_SA_CMD0_CRYPT_NULL;
  83029. + ivsize = 0;
  83030. + }
  83031. +
  83032. + /*
  83033. + * Setup encrypt/decrypt state. When using basic ops
  83034. + * we can't use an inline IV because hash/crypt offset
  83035. + * must be from the end of the IV to the start of the
  83036. + * crypt data and this leaves out the preceding header
  83037. + * from the hash calculation. Instead we place the IV
  83038. + * in the state record and set the hash/crypt offset to
  83039. + * copy both the header+IV.
  83040. + */
  83041. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  83042. + cmd0 |= SAFE_SA_CMD0_OUTBOUND;
  83043. +
  83044. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  83045. + iv = enccrd->crd_iv;
  83046. + else
  83047. + iv = (caddr_t) ses->ses_iv;
  83048. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  83049. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  83050. + enccrd->crd_inject, ivsize, iv);
  83051. + }
  83052. + bcopy(iv, re->re_sastate.sa_saved_iv, ivsize);
  83053. + /* make iv LE */
  83054. + for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)
  83055. + re->re_sastate.sa_saved_iv[i] =
  83056. + cpu_to_le32(re->re_sastate.sa_saved_iv[i]);
  83057. + cmd0 |= SAFE_SA_CMD0_IVLD_STATE | SAFE_SA_CMD0_SAVEIV;
  83058. + re->re_flags |= SAFE_QFLAGS_COPYOUTIV;
  83059. + } else {
  83060. + cmd0 |= SAFE_SA_CMD0_INBOUND;
  83061. +
  83062. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  83063. + bcopy(enccrd->crd_iv,
  83064. + re->re_sastate.sa_saved_iv, ivsize);
  83065. + } else {
  83066. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  83067. + enccrd->crd_inject, ivsize,
  83068. + (caddr_t)re->re_sastate.sa_saved_iv);
  83069. + }
  83070. + /* make iv LE */
  83071. + for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)
  83072. + re->re_sastate.sa_saved_iv[i] =
  83073. + cpu_to_le32(re->re_sastate.sa_saved_iv[i]);
  83074. + cmd0 |= SAFE_SA_CMD0_IVLD_STATE;
  83075. + }
  83076. + /*
  83077. + * For basic encryption use the zero pad algorithm.
  83078. + * This pads results to an 8-byte boundary and
  83079. + * suppresses padding verification for inbound (i.e.
  83080. + * decrypt) operations.
  83081. + *
  83082. + * NB: Not sure if the 8-byte pad boundary is a problem.
  83083. + */
  83084. + cmd0 |= SAFE_SA_CMD0_PAD_ZERO;
  83085. +
  83086. + /* XXX assert key bufs have the same size */
  83087. + bcopy(ses->ses_key, sa->sa_key, sizeof(sa->sa_key));
  83088. + }
  83089. +
  83090. + if (maccrd) {
  83091. + if (maccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
  83092. + safe_setup_mackey(ses, maccrd->crd_alg,
  83093. + maccrd->crd_key, maccrd->crd_klen / 8);
  83094. + }
  83095. +
  83096. + if (maccrd->crd_alg == CRYPTO_MD5_HMAC) {
  83097. + cmd0 |= SAFE_SA_CMD0_MD5;
  83098. + cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */
  83099. + } else if (maccrd->crd_alg == CRYPTO_SHA1_HMAC) {
  83100. + cmd0 |= SAFE_SA_CMD0_SHA1;
  83101. + cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */
  83102. + } else {
  83103. + cmd0 |= SAFE_SA_CMD0_HASH_NULL;
  83104. + }
  83105. + /*
  83106. + * Digest data is loaded from the SA and the hash
  83107. + * result is saved to the state block where we
  83108. + * retrieve it for return to the caller.
  83109. + */
  83110. + /* XXX assert digest bufs have the same size */
  83111. + bcopy(ses->ses_hminner, sa->sa_indigest,
  83112. + sizeof(sa->sa_indigest));
  83113. + bcopy(ses->ses_hmouter, sa->sa_outdigest,
  83114. + sizeof(sa->sa_outdigest));
  83115. +
  83116. + cmd0 |= SAFE_SA_CMD0_HSLD_SA | SAFE_SA_CMD0_SAVEHASH;
  83117. + re->re_flags |= SAFE_QFLAGS_COPYOUTICV;
  83118. + }
  83119. +
  83120. + if (enccrd && maccrd) {
  83121. + /*
  83122. + * The offset from hash data to the start of
  83123. + * crypt data is the difference in the skips.
  83124. + */
  83125. + bypass = maccrd->crd_skip;
  83126. + coffset = enccrd->crd_skip - maccrd->crd_skip;
  83127. + if (coffset < 0) {
  83128. + DPRINTF(("%s: hash does not precede crypt; "
  83129. + "mac skip %u enc skip %u\n",
  83130. + __func__, maccrd->crd_skip, enccrd->crd_skip));
  83131. + safestats.st_skipmismatch++;
  83132. + err = EINVAL;
  83133. + goto errout;
  83134. + }
  83135. + oplen = enccrd->crd_skip + enccrd->crd_len;
  83136. + if (maccrd->crd_skip + maccrd->crd_len != oplen) {
  83137. + DPRINTF(("%s: hash amount %u != crypt amount %u\n",
  83138. + __func__, maccrd->crd_skip + maccrd->crd_len,
  83139. + oplen));
  83140. + safestats.st_lenmismatch++;
  83141. + err = EINVAL;
  83142. + goto errout;
  83143. + }
  83144. +#ifdef SAFE_DEBUG
  83145. + if (debug) {
  83146. + printf("mac: skip %d, len %d, inject %d\n",
  83147. + maccrd->crd_skip, maccrd->crd_len,
  83148. + maccrd->crd_inject);
  83149. + printf("enc: skip %d, len %d, inject %d\n",
  83150. + enccrd->crd_skip, enccrd->crd_len,
  83151. + enccrd->crd_inject);
  83152. + printf("bypass %d coffset %d oplen %d\n",
  83153. + bypass, coffset, oplen);
  83154. + }
  83155. +#endif
  83156. + if (coffset & 3) { /* offset must be 32-bit aligned */
  83157. + DPRINTF(("%s: coffset %u misaligned\n",
  83158. + __func__, coffset));
  83159. + safestats.st_coffmisaligned++;
  83160. + err = EINVAL;
  83161. + goto errout;
  83162. + }
  83163. + coffset >>= 2;
  83164. + if (coffset > 255) { /* offset must be <256 dwords */
  83165. + DPRINTF(("%s: coffset %u too big\n",
  83166. + __func__, coffset));
  83167. + safestats.st_cofftoobig++;
  83168. + err = EINVAL;
  83169. + goto errout;
  83170. + }
  83171. + /*
  83172. + * Tell the hardware to copy the header to the output.
  83173. + * The header is defined as the data from the end of
  83174. + * the bypass to the start of data to be encrypted.
  83175. + * Typically this is the inline IV. Note that you need
  83176. + * to do this even if src+dst are the same; it appears
  83177. + * that w/o this bit the crypted data is written
  83178. + * immediately after the bypass data.
  83179. + */
  83180. + cmd1 |= SAFE_SA_CMD1_HDRCOPY;
  83181. + /*
  83182. + * Disable IP header mutable bit handling. This is
  83183. + * needed to get correct HMAC calculations.
  83184. + */
  83185. + cmd1 |= SAFE_SA_CMD1_MUTABLE;
  83186. + } else {
  83187. + if (enccrd) {
  83188. + bypass = enccrd->crd_skip;
  83189. + oplen = bypass + enccrd->crd_len;
  83190. + } else {
  83191. + bypass = maccrd->crd_skip;
  83192. + oplen = bypass + maccrd->crd_len;
  83193. + }
  83194. + coffset = 0;
  83195. + }
  83196. + /* XXX verify multiple of 4 when using s/g */
  83197. + if (bypass > 96) { /* bypass offset must be <= 96 bytes */
  83198. + DPRINTF(("%s: bypass %u too big\n", __func__, bypass));
  83199. + safestats.st_bypasstoobig++;
  83200. + err = EINVAL;
  83201. + goto errout;
  83202. + }
  83203. +
  83204. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  83205. + if (pci_map_skb(sc, &re->re_src, re->re_src_skb)) {
  83206. + safestats.st_noload++;
  83207. + err = ENOMEM;
  83208. + goto errout;
  83209. + }
  83210. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  83211. + if (pci_map_uio(sc, &re->re_src, re->re_src_io)) {
  83212. + safestats.st_noload++;
  83213. + err = ENOMEM;
  83214. + goto errout;
  83215. + }
  83216. + }
  83217. + nicealign = safe_dmamap_aligned(sc, &re->re_src);
  83218. + uniform = safe_dmamap_uniform(sc, &re->re_src);
  83219. +
  83220. + DPRINTF(("src nicealign %u uniform %u nsegs %u\n",
  83221. + nicealign, uniform, re->re_src.nsegs));
  83222. + if (re->re_src.nsegs > 1) {
  83223. + re->re_desc.d_src = sc->sc_spalloc.dma_paddr +
  83224. + ((caddr_t) sc->sc_spfree - (caddr_t) sc->sc_spring);
  83225. + for (i = 0; i < re->re_src_nsegs; i++) {
  83226. + /* NB: no need to check if there's space */
  83227. + pd = sc->sc_spfree;
  83228. + if (++(sc->sc_spfree) == sc->sc_springtop)
  83229. + sc->sc_spfree = sc->sc_spring;
  83230. +
  83231. + KASSERT((pd->pd_flags&3) == 0 ||
  83232. + (pd->pd_flags&3) == SAFE_PD_DONE,
  83233. + ("bogus source particle descriptor; flags %x",
  83234. + pd->pd_flags));
  83235. + pd->pd_addr = re->re_src_segs[i].ds_addr;
  83236. + pd->pd_size = re->re_src_segs[i].ds_len;
  83237. + pd->pd_flags = SAFE_PD_READY;
  83238. + }
  83239. + cmd0 |= SAFE_SA_CMD0_IGATHER;
  83240. + } else {
  83241. + /*
  83242. + * No need for gather, reference the operand directly.
  83243. + */
  83244. + re->re_desc.d_src = re->re_src_segs[0].ds_addr;
  83245. + }
  83246. +
  83247. + if (enccrd == NULL && maccrd != NULL) {
  83248. + /*
  83249. + * Hash op; no destination needed.
  83250. + */
  83251. + } else {
  83252. + if (crp->crp_flags & (CRYPTO_F_IOV|CRYPTO_F_SKBUF)) {
  83253. + if (!nicealign) {
  83254. + safestats.st_iovmisaligned++;
  83255. + err = EINVAL;
  83256. + goto errout;
  83257. + }
  83258. + if (uniform != 1) {
  83259. + device_printf(sc->sc_dev, "!uniform source\n");
  83260. + if (!uniform) {
  83261. + /*
  83262. + * There's no way to handle the DMA
  83263. + * requirements with this uio. We
  83264. + * could create a separate DMA area for
  83265. + * the result and then copy it back,
  83266. + * but for now we just bail and return
  83267. + * an error. Note that uio requests
  83268. + * > SAFE_MAX_DSIZE are handled because
  83269. + * the DMA map and segment list for the
  83270. + * destination wil result in a
  83271. + * destination particle list that does
  83272. + * the necessary scatter DMA.
  83273. + */
  83274. + safestats.st_iovnotuniform++;
  83275. + err = EINVAL;
  83276. + goto errout;
  83277. + }
  83278. + } else
  83279. + re->re_dst = re->re_src;
  83280. + } else {
  83281. + safestats.st_badflags++;
  83282. + err = EINVAL;
  83283. + goto errout;
  83284. + }
  83285. +
  83286. + if (re->re_dst.nsegs > 1) {
  83287. + re->re_desc.d_dst = sc->sc_dpalloc.dma_paddr +
  83288. + ((caddr_t) sc->sc_dpfree - (caddr_t) sc->sc_dpring);
  83289. + for (i = 0; i < re->re_dst_nsegs; i++) {
  83290. + pd = sc->sc_dpfree;
  83291. + KASSERT((pd->pd_flags&3) == 0 ||
  83292. + (pd->pd_flags&3) == SAFE_PD_DONE,
  83293. + ("bogus dest particle descriptor; flags %x",
  83294. + pd->pd_flags));
  83295. + if (++(sc->sc_dpfree) == sc->sc_dpringtop)
  83296. + sc->sc_dpfree = sc->sc_dpring;
  83297. + pd->pd_addr = re->re_dst_segs[i].ds_addr;
  83298. + pd->pd_flags = SAFE_PD_READY;
  83299. + }
  83300. + cmd0 |= SAFE_SA_CMD0_OSCATTER;
  83301. + } else {
  83302. + /*
  83303. + * No need for scatter, reference the operand directly.
  83304. + */
  83305. + re->re_desc.d_dst = re->re_dst_segs[0].ds_addr;
  83306. + }
  83307. + }
  83308. +
  83309. + /*
  83310. + * All done with setup; fillin the SA command words
  83311. + * and the packet engine descriptor. The operation
  83312. + * is now ready for submission to the hardware.
  83313. + */
  83314. + sa->sa_cmd0 = cmd0 | SAFE_SA_CMD0_IPCI | SAFE_SA_CMD0_OPCI;
  83315. + sa->sa_cmd1 = cmd1
  83316. + | (coffset << SAFE_SA_CMD1_OFFSET_S)
  83317. + | SAFE_SA_CMD1_SAREV1 /* Rev 1 SA data structure */
  83318. + | SAFE_SA_CMD1_SRPCI
  83319. + ;
  83320. + /*
  83321. + * NB: the order of writes is important here. In case the
  83322. + * chip is scanning the ring because of an outstanding request
  83323. + * it might nab this one too. In that case we need to make
  83324. + * sure the setup is complete before we write the length
  83325. + * field of the descriptor as it signals the descriptor is
  83326. + * ready for processing.
  83327. + */
  83328. + re->re_desc.d_csr = SAFE_PE_CSR_READY | SAFE_PE_CSR_SAPCI;
  83329. + if (maccrd)
  83330. + re->re_desc.d_csr |= SAFE_PE_CSR_LOADSA | SAFE_PE_CSR_HASHFINAL;
  83331. + wmb();
  83332. + re->re_desc.d_len = oplen
  83333. + | SAFE_PE_LEN_READY
  83334. + | (bypass << SAFE_PE_LEN_BYPASS_S)
  83335. + ;
  83336. +
  83337. + safestats.st_ipackets++;
  83338. + safestats.st_ibytes += oplen;
  83339. +
  83340. + if (++(sc->sc_front) == sc->sc_ringtop)
  83341. + sc->sc_front = sc->sc_ring;
  83342. +
  83343. + /* XXX honor batching */
  83344. + safe_feed(sc, re);
  83345. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  83346. + return (0);
  83347. +
  83348. +errout:
  83349. + if (re->re_src.map != re->re_dst.map)
  83350. + pci_unmap_operand(sc, &re->re_dst);
  83351. + if (re->re_src.map)
  83352. + pci_unmap_operand(sc, &re->re_src);
  83353. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  83354. + if (err != ERESTART) {
  83355. + crp->crp_etype = err;
  83356. + crypto_done(crp);
  83357. + } else {
  83358. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  83359. + }
  83360. + return (err);
  83361. +}
  83362. +
  83363. +static void
  83364. +safe_callback(struct safe_softc *sc, struct safe_ringentry *re)
  83365. +{
  83366. + struct cryptop *crp = (struct cryptop *)re->re_crp;
  83367. + struct cryptodesc *crd;
  83368. +
  83369. + DPRINTF(("%s()\n", __FUNCTION__));
  83370. +
  83371. + safestats.st_opackets++;
  83372. + safestats.st_obytes += re->re_dst.mapsize;
  83373. +
  83374. + if (re->re_desc.d_csr & SAFE_PE_CSR_STATUS) {
  83375. + device_printf(sc->sc_dev, "csr 0x%x cmd0 0x%x cmd1 0x%x\n",
  83376. + re->re_desc.d_csr,
  83377. + re->re_sa.sa_cmd0, re->re_sa.sa_cmd1);
  83378. + safestats.st_peoperr++;
  83379. + crp->crp_etype = EIO; /* something more meaningful? */
  83380. + }
  83381. +
  83382. + if (re->re_dst.map != NULL && re->re_dst.map != re->re_src.map)
  83383. + pci_unmap_operand(sc, &re->re_dst);
  83384. + pci_unmap_operand(sc, &re->re_src);
  83385. +
  83386. + /*
  83387. + * If result was written to a differet mbuf chain, swap
  83388. + * it in as the return value and reclaim the original.
  83389. + */
  83390. + if ((crp->crp_flags & CRYPTO_F_SKBUF) && re->re_src_skb != re->re_dst_skb) {
  83391. + device_printf(sc->sc_dev, "no CRYPTO_F_SKBUF swapping support\n");
  83392. + /* kfree_skb(skb) */
  83393. + /* crp->crp_buf = (caddr_t)re->re_dst_skb */
  83394. + return;
  83395. + }
  83396. +
  83397. + if (re->re_flags & SAFE_QFLAGS_COPYOUTIV) {
  83398. + /* copy out IV for future use */
  83399. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  83400. + int i;
  83401. + int ivsize;
  83402. +
  83403. + if (crd->crd_alg == CRYPTO_DES_CBC ||
  83404. + crd->crd_alg == CRYPTO_3DES_CBC) {
  83405. + ivsize = 2*sizeof(u_int32_t);
  83406. + } else if (crd->crd_alg == CRYPTO_AES_CBC) {
  83407. + ivsize = 4*sizeof(u_int32_t);
  83408. + } else
  83409. + continue;
  83410. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  83411. + crd->crd_skip + crd->crd_len - ivsize, ivsize,
  83412. + (caddr_t)sc->sc_sessions[re->re_sesn].ses_iv);
  83413. + for (i = 0;
  83414. + i < ivsize/sizeof(sc->sc_sessions[re->re_sesn].ses_iv[0]);
  83415. + i++)
  83416. + sc->sc_sessions[re->re_sesn].ses_iv[i] =
  83417. + cpu_to_le32(sc->sc_sessions[re->re_sesn].ses_iv[i]);
  83418. + break;
  83419. + }
  83420. + }
  83421. +
  83422. + if (re->re_flags & SAFE_QFLAGS_COPYOUTICV) {
  83423. + /* copy out ICV result */
  83424. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  83425. + if (!(crd->crd_alg == CRYPTO_MD5_HMAC ||
  83426. + crd->crd_alg == CRYPTO_SHA1_HMAC ||
  83427. + crd->crd_alg == CRYPTO_NULL_HMAC))
  83428. + continue;
  83429. + if (crd->crd_alg == CRYPTO_SHA1_HMAC) {
  83430. + /*
  83431. + * SHA-1 ICV's are byte-swapped; fix 'em up
  83432. + * before copy them to their destination.
  83433. + */
  83434. + re->re_sastate.sa_saved_indigest[0] =
  83435. + cpu_to_be32(re->re_sastate.sa_saved_indigest[0]);
  83436. + re->re_sastate.sa_saved_indigest[1] =
  83437. + cpu_to_be32(re->re_sastate.sa_saved_indigest[1]);
  83438. + re->re_sastate.sa_saved_indigest[2] =
  83439. + cpu_to_be32(re->re_sastate.sa_saved_indigest[2]);
  83440. + } else {
  83441. + re->re_sastate.sa_saved_indigest[0] =
  83442. + cpu_to_le32(re->re_sastate.sa_saved_indigest[0]);
  83443. + re->re_sastate.sa_saved_indigest[1] =
  83444. + cpu_to_le32(re->re_sastate.sa_saved_indigest[1]);
  83445. + re->re_sastate.sa_saved_indigest[2] =
  83446. + cpu_to_le32(re->re_sastate.sa_saved_indigest[2]);
  83447. + }
  83448. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  83449. + crd->crd_inject,
  83450. + sc->sc_sessions[re->re_sesn].ses_mlen,
  83451. + (caddr_t)re->re_sastate.sa_saved_indigest);
  83452. + break;
  83453. + }
  83454. + }
  83455. + crypto_done(crp);
  83456. +}
  83457. +
  83458. +
  83459. +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
  83460. +#define SAFE_RNG_MAXWAIT 1000
  83461. +
  83462. +static void
  83463. +safe_rng_init(struct safe_softc *sc)
  83464. +{
  83465. + u_int32_t w, v;
  83466. + int i;
  83467. +
  83468. + DPRINTF(("%s()\n", __FUNCTION__));
  83469. +
  83470. + WRITE_REG(sc, SAFE_RNG_CTRL, 0);
  83471. + /* use default value according to the manual */
  83472. + WRITE_REG(sc, SAFE_RNG_CNFG, 0x834); /* magic from SafeNet */
  83473. + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
  83474. +
  83475. + /*
  83476. + * There is a bug in rev 1.0 of the 1140 that when the RNG
  83477. + * is brought out of reset the ready status flag does not
  83478. + * work until the RNG has finished its internal initialization.
  83479. + *
  83480. + * So in order to determine the device is through its
  83481. + * initialization we must read the data register, using the
  83482. + * status reg in the read in case it is initialized. Then read
  83483. + * the data register until it changes from the first read.
  83484. + * Once it changes read the data register until it changes
  83485. + * again. At this time the RNG is considered initialized.
  83486. + * This could take between 750ms - 1000ms in time.
  83487. + */
  83488. + i = 0;
  83489. + w = READ_REG(sc, SAFE_RNG_OUT);
  83490. + do {
  83491. + v = READ_REG(sc, SAFE_RNG_OUT);
  83492. + if (v != w) {
  83493. + w = v;
  83494. + break;
  83495. + }
  83496. + DELAY(10);
  83497. + } while (++i < SAFE_RNG_MAXWAIT);
  83498. +
  83499. + /* Wait Until data changes again */
  83500. + i = 0;
  83501. + do {
  83502. + v = READ_REG(sc, SAFE_RNG_OUT);
  83503. + if (v != w)
  83504. + break;
  83505. + DELAY(10);
  83506. + } while (++i < SAFE_RNG_MAXWAIT);
  83507. +}
  83508. +
  83509. +static __inline void
  83510. +safe_rng_disable_short_cycle(struct safe_softc *sc)
  83511. +{
  83512. + DPRINTF(("%s()\n", __FUNCTION__));
  83513. +
  83514. + WRITE_REG(sc, SAFE_RNG_CTRL,
  83515. + READ_REG(sc, SAFE_RNG_CTRL) &~ SAFE_RNG_CTRL_SHORTEN);
  83516. +}
  83517. +
  83518. +static __inline void
  83519. +safe_rng_enable_short_cycle(struct safe_softc *sc)
  83520. +{
  83521. + DPRINTF(("%s()\n", __FUNCTION__));
  83522. +
  83523. + WRITE_REG(sc, SAFE_RNG_CTRL,
  83524. + READ_REG(sc, SAFE_RNG_CTRL) | SAFE_RNG_CTRL_SHORTEN);
  83525. +}
  83526. +
  83527. +static __inline u_int32_t
  83528. +safe_rng_read(struct safe_softc *sc)
  83529. +{
  83530. + int i;
  83531. +
  83532. + i = 0;
  83533. + while (READ_REG(sc, SAFE_RNG_STAT) != 0 && ++i < SAFE_RNG_MAXWAIT)
  83534. + ;
  83535. + return READ_REG(sc, SAFE_RNG_OUT);
  83536. +}
  83537. +
  83538. +static int
  83539. +safe_read_random(void *arg, u_int32_t *buf, int maxwords)
  83540. +{
  83541. + struct safe_softc *sc = (struct safe_softc *) arg;
  83542. + int i, rc;
  83543. +
  83544. + DPRINTF(("%s()\n", __FUNCTION__));
  83545. +
  83546. + safestats.st_rng++;
  83547. + /*
  83548. + * Fetch the next block of data.
  83549. + */
  83550. + if (maxwords > safe_rngbufsize)
  83551. + maxwords = safe_rngbufsize;
  83552. + if (maxwords > SAFE_RNG_MAXBUFSIZ)
  83553. + maxwords = SAFE_RNG_MAXBUFSIZ;
  83554. +retry:
  83555. + /* read as much as we can */
  83556. + for (rc = 0; rc < maxwords; rc++) {
  83557. + if (READ_REG(sc, SAFE_RNG_STAT) != 0)
  83558. + break;
  83559. + buf[rc] = READ_REG(sc, SAFE_RNG_OUT);
  83560. + }
  83561. + if (rc == 0)
  83562. + return 0;
  83563. + /*
  83564. + * Check the comparator alarm count and reset the h/w if
  83565. + * it exceeds our threshold. This guards against the
  83566. + * hardware oscillators resonating with external signals.
  83567. + */
  83568. + if (READ_REG(sc, SAFE_RNG_ALM_CNT) > safe_rngmaxalarm) {
  83569. + u_int32_t freq_inc, w;
  83570. +
  83571. + DPRINTF(("%s: alarm count %u exceeds threshold %u\n", __func__,
  83572. + (unsigned)READ_REG(sc, SAFE_RNG_ALM_CNT), safe_rngmaxalarm));
  83573. + safestats.st_rngalarm++;
  83574. + safe_rng_enable_short_cycle(sc);
  83575. + freq_inc = 18;
  83576. + for (i = 0; i < 64; i++) {
  83577. + w = READ_REG(sc, SAFE_RNG_CNFG);
  83578. + freq_inc = ((w + freq_inc) & 0x3fL);
  83579. + w = ((w & ~0x3fL) | freq_inc);
  83580. + WRITE_REG(sc, SAFE_RNG_CNFG, w);
  83581. +
  83582. + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
  83583. +
  83584. + (void) safe_rng_read(sc);
  83585. + DELAY(25);
  83586. +
  83587. + if (READ_REG(sc, SAFE_RNG_ALM_CNT) == 0) {
  83588. + safe_rng_disable_short_cycle(sc);
  83589. + goto retry;
  83590. + }
  83591. + freq_inc = 1;
  83592. + }
  83593. + safe_rng_disable_short_cycle(sc);
  83594. + } else
  83595. + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
  83596. +
  83597. + return(rc);
  83598. +}
  83599. +#endif /* defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG) */
  83600. +
  83601. +
  83602. +/*
  83603. + * Resets the board. Values in the regesters are left as is
  83604. + * from the reset (i.e. initial values are assigned elsewhere).
  83605. + */
  83606. +static void
  83607. +safe_reset_board(struct safe_softc *sc)
  83608. +{
  83609. + u_int32_t v;
  83610. + /*
  83611. + * Reset the device. The manual says no delay
  83612. + * is needed between marking and clearing reset.
  83613. + */
  83614. + DPRINTF(("%s()\n", __FUNCTION__));
  83615. +
  83616. + v = READ_REG(sc, SAFE_PE_DMACFG) &~
  83617. + (SAFE_PE_DMACFG_PERESET | SAFE_PE_DMACFG_PDRRESET |
  83618. + SAFE_PE_DMACFG_SGRESET);
  83619. + WRITE_REG(sc, SAFE_PE_DMACFG, v
  83620. + | SAFE_PE_DMACFG_PERESET
  83621. + | SAFE_PE_DMACFG_PDRRESET
  83622. + | SAFE_PE_DMACFG_SGRESET);
  83623. + WRITE_REG(sc, SAFE_PE_DMACFG, v);
  83624. +}
  83625. +
  83626. +/*
  83627. + * Initialize registers we need to touch only once.
  83628. + */
  83629. +static void
  83630. +safe_init_board(struct safe_softc *sc)
  83631. +{
  83632. + u_int32_t v, dwords;
  83633. +
  83634. + DPRINTF(("%s()\n", __FUNCTION__));
  83635. +
  83636. + v = READ_REG(sc, SAFE_PE_DMACFG);
  83637. + v &=~ ( SAFE_PE_DMACFG_PEMODE
  83638. + | SAFE_PE_DMACFG_FSENA /* failsafe enable */
  83639. + | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */
  83640. + | SAFE_PE_DMACFG_SPRPCI /* scatter ring on PCI */
  83641. + | SAFE_PE_DMACFG_ESDESC /* endian-swap descriptors */
  83642. + | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */
  83643. + | SAFE_PE_DMACFG_ESSA /* endian-swap SA's */
  83644. + | SAFE_PE_DMACFG_ESPACKET /* swap the packet data */
  83645. + );
  83646. + v |= SAFE_PE_DMACFG_FSENA /* failsafe enable */
  83647. + | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */
  83648. + | SAFE_PE_DMACFG_SPRPCI /* scatter ring on PCI */
  83649. + | SAFE_PE_DMACFG_ESDESC /* endian-swap descriptors */
  83650. + | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */
  83651. + | SAFE_PE_DMACFG_ESSA /* endian-swap SA's */
  83652. +#if 0
  83653. + | SAFE_PE_DMACFG_ESPACKET /* swap the packet data */
  83654. +#endif
  83655. + ;
  83656. + WRITE_REG(sc, SAFE_PE_DMACFG, v);
  83657. +
  83658. +#ifdef __BIG_ENDIAN
  83659. + /* tell the safenet that we are 4321 and not 1234 */
  83660. + WRITE_REG(sc, SAFE_ENDIAN, 0xe4e41b1b);
  83661. +#endif
  83662. +
  83663. + if (sc->sc_chiprev == SAFE_REV(1,0)) {
  83664. + /*
  83665. + * Avoid large PCI DMA transfers. Rev 1.0 has a bug where
  83666. + * "target mode transfers" done while the chip is DMA'ing
  83667. + * >1020 bytes cause the hardware to lockup. To avoid this
  83668. + * we reduce the max PCI transfer size and use small source
  83669. + * particle descriptors (<= 256 bytes).
  83670. + */
  83671. + WRITE_REG(sc, SAFE_DMA_CFG, 256);
  83672. + device_printf(sc->sc_dev,
  83673. + "Reduce max DMA size to %u words for rev %u.%u WAR\n",
  83674. + (unsigned) ((READ_REG(sc, SAFE_DMA_CFG)>>2) & 0xff),
  83675. + (unsigned) SAFE_REV_MAJ(sc->sc_chiprev),
  83676. + (unsigned) SAFE_REV_MIN(sc->sc_chiprev));
  83677. + sc->sc_max_dsize = 256;
  83678. + } else {
  83679. + sc->sc_max_dsize = SAFE_MAX_DSIZE;
  83680. + }
  83681. +
  83682. + /* NB: operands+results are overlaid */
  83683. + WRITE_REG(sc, SAFE_PE_PDRBASE, sc->sc_ringalloc.dma_paddr);
  83684. + WRITE_REG(sc, SAFE_PE_RDRBASE, sc->sc_ringalloc.dma_paddr);
  83685. + /*
  83686. + * Configure ring entry size and number of items in the ring.
  83687. + */
  83688. + KASSERT((sizeof(struct safe_ringentry) % sizeof(u_int32_t)) == 0,
  83689. + ("PE ring entry not 32-bit aligned!"));
  83690. + dwords = sizeof(struct safe_ringentry) / sizeof(u_int32_t);
  83691. + WRITE_REG(sc, SAFE_PE_RINGCFG,
  83692. + (dwords << SAFE_PE_RINGCFG_OFFSET_S) | SAFE_MAX_NQUEUE);
  83693. + WRITE_REG(sc, SAFE_PE_RINGPOLL, 0); /* disable polling */
  83694. +
  83695. + WRITE_REG(sc, SAFE_PE_GRNGBASE, sc->sc_spalloc.dma_paddr);
  83696. + WRITE_REG(sc, SAFE_PE_SRNGBASE, sc->sc_dpalloc.dma_paddr);
  83697. + WRITE_REG(sc, SAFE_PE_PARTSIZE,
  83698. + (SAFE_TOTAL_DPART<<16) | SAFE_TOTAL_SPART);
  83699. + /*
  83700. + * NB: destination particles are fixed size. We use
  83701. + * an mbuf cluster and require all results go to
  83702. + * clusters or smaller.
  83703. + */
  83704. + WRITE_REG(sc, SAFE_PE_PARTCFG, sc->sc_max_dsize);
  83705. +
  83706. + /* it's now safe to enable PE mode, do it */
  83707. + WRITE_REG(sc, SAFE_PE_DMACFG, v | SAFE_PE_DMACFG_PEMODE);
  83708. +
  83709. + /*
  83710. + * Configure hardware to use level-triggered interrupts and
  83711. + * to interrupt after each descriptor is processed.
  83712. + */
  83713. + WRITE_REG(sc, SAFE_HI_CFG, SAFE_HI_CFG_LEVEL);
  83714. + WRITE_REG(sc, SAFE_HI_CLR, 0xffffffff);
  83715. + WRITE_REG(sc, SAFE_HI_DESC_CNT, 1);
  83716. + WRITE_REG(sc, SAFE_HI_MASK, SAFE_INT_PE_DDONE | SAFE_INT_PE_ERROR);
  83717. +}
  83718. +
  83719. +
  83720. +/*
  83721. + * Clean up after a chip crash.
  83722. + * It is assumed that the caller in splimp()
  83723. + */
  83724. +static void
  83725. +safe_cleanchip(struct safe_softc *sc)
  83726. +{
  83727. + DPRINTF(("%s()\n", __FUNCTION__));
  83728. +
  83729. + if (sc->sc_nqchip != 0) {
  83730. + struct safe_ringentry *re = sc->sc_back;
  83731. +
  83732. + while (re != sc->sc_front) {
  83733. + if (re->re_desc.d_csr != 0)
  83734. + safe_free_entry(sc, re);
  83735. + if (++re == sc->sc_ringtop)
  83736. + re = sc->sc_ring;
  83737. + }
  83738. + sc->sc_back = re;
  83739. + sc->sc_nqchip = 0;
  83740. + }
  83741. +}
  83742. +
  83743. +/*
  83744. + * free a safe_q
  83745. + * It is assumed that the caller is within splimp().
  83746. + */
  83747. +static int
  83748. +safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re)
  83749. +{
  83750. + struct cryptop *crp;
  83751. +
  83752. + DPRINTF(("%s()\n", __FUNCTION__));
  83753. +
  83754. + /*
  83755. + * Free header MCR
  83756. + */
  83757. + if ((re->re_dst_skb != NULL) && (re->re_src_skb != re->re_dst_skb))
  83758. +#ifdef NOTYET
  83759. + m_freem(re->re_dst_m);
  83760. +#else
  83761. + printk("%s,%d: SKB not supported\n", __FILE__, __LINE__);
  83762. +#endif
  83763. +
  83764. + crp = (struct cryptop *)re->re_crp;
  83765. +
  83766. + re->re_desc.d_csr = 0;
  83767. +
  83768. + crp->crp_etype = EFAULT;
  83769. + crypto_done(crp);
  83770. + return(0);
  83771. +}
  83772. +
  83773. +/*
  83774. + * Routine to reset the chip and clean up.
  83775. + * It is assumed that the caller is in splimp()
  83776. + */
  83777. +static void
  83778. +safe_totalreset(struct safe_softc *sc)
  83779. +{
  83780. + DPRINTF(("%s()\n", __FUNCTION__));
  83781. +
  83782. + safe_reset_board(sc);
  83783. + safe_init_board(sc);
  83784. + safe_cleanchip(sc);
  83785. +}
  83786. +
  83787. +/*
  83788. + * Is the operand suitable aligned for direct DMA. Each
  83789. + * segment must be aligned on a 32-bit boundary and all
  83790. + * but the last segment must be a multiple of 4 bytes.
  83791. + */
  83792. +static int
  83793. +safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op)
  83794. +{
  83795. + int i;
  83796. +
  83797. + DPRINTF(("%s()\n", __FUNCTION__));
  83798. +
  83799. + for (i = 0; i < op->nsegs; i++) {
  83800. + if (op->segs[i].ds_addr & 3)
  83801. + return (0);
  83802. + if (i != (op->nsegs - 1) && (op->segs[i].ds_len & 3))
  83803. + return (0);
  83804. + }
  83805. + return (1);
  83806. +}
  83807. +
  83808. +/*
  83809. + * Is the operand suitable for direct DMA as the destination
  83810. + * of an operation. The hardware requires that each ``particle''
  83811. + * but the last in an operation result have the same size. We
  83812. + * fix that size at SAFE_MAX_DSIZE bytes. This routine returns
  83813. + * 0 if some segment is not a multiple of of this size, 1 if all
  83814. + * segments are exactly this size, or 2 if segments are at worst
  83815. + * a multple of this size.
  83816. + */
  83817. +static int
  83818. +safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op)
  83819. +{
  83820. + int result = 1;
  83821. +
  83822. + DPRINTF(("%s()\n", __FUNCTION__));
  83823. +
  83824. + if (op->nsegs > 0) {
  83825. + int i;
  83826. +
  83827. + for (i = 0; i < op->nsegs-1; i++) {
  83828. + if (op->segs[i].ds_len % sc->sc_max_dsize)
  83829. + return (0);
  83830. + if (op->segs[i].ds_len != sc->sc_max_dsize)
  83831. + result = 2;
  83832. + }
  83833. + }
  83834. + return (result);
  83835. +}
  83836. +
  83837. +static int
  83838. +safe_kprocess(device_t dev, struct cryptkop *krp, int hint)
  83839. +{
  83840. + struct safe_softc *sc = device_get_softc(dev);
  83841. + struct safe_pkq *q;
  83842. + unsigned long flags;
  83843. +
  83844. + DPRINTF(("%s()\n", __FUNCTION__));
  83845. +
  83846. + if (sc == NULL) {
  83847. + krp->krp_status = EINVAL;
  83848. + goto err;
  83849. + }
  83850. +
  83851. + if (krp->krp_op != CRK_MOD_EXP) {
  83852. + krp->krp_status = EOPNOTSUPP;
  83853. + goto err;
  83854. + }
  83855. +
  83856. + q = (struct safe_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);
  83857. + if (q == NULL) {
  83858. + krp->krp_status = ENOMEM;
  83859. + goto err;
  83860. + }
  83861. + memset(q, 0, sizeof(*q));
  83862. + q->pkq_krp = krp;
  83863. + INIT_LIST_HEAD(&q->pkq_list);
  83864. +
  83865. + spin_lock_irqsave(&sc->sc_pkmtx, flags);
  83866. + list_add_tail(&q->pkq_list, &sc->sc_pkq);
  83867. + safe_kfeed(sc);
  83868. + spin_unlock_irqrestore(&sc->sc_pkmtx, flags);
  83869. + return (0);
  83870. +
  83871. +err:
  83872. + crypto_kdone(krp);
  83873. + return (0);
  83874. +}
  83875. +
  83876. +#define SAFE_CRK_PARAM_BASE 0
  83877. +#define SAFE_CRK_PARAM_EXP 1
  83878. +#define SAFE_CRK_PARAM_MOD 2
  83879. +
  83880. +static int
  83881. +safe_kstart(struct safe_softc *sc)
  83882. +{
  83883. + struct cryptkop *krp = sc->sc_pkq_cur->pkq_krp;
  83884. + int exp_bits, mod_bits, base_bits;
  83885. + u_int32_t op, a_off, b_off, c_off, d_off;
  83886. +
  83887. + DPRINTF(("%s()\n", __FUNCTION__));
  83888. +
  83889. + if (krp->krp_iparams < 3 || krp->krp_oparams != 1) {
  83890. + krp->krp_status = EINVAL;
  83891. + return (1);
  83892. + }
  83893. +
  83894. + base_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_BASE]);
  83895. + if (base_bits > 2048)
  83896. + goto too_big;
  83897. + if (base_bits <= 0) /* 5. base not zero */
  83898. + goto too_small;
  83899. +
  83900. + exp_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_EXP]);
  83901. + if (exp_bits > 2048)
  83902. + goto too_big;
  83903. + if (exp_bits <= 0) /* 1. exponent word length > 0 */
  83904. + goto too_small; /* 4. exponent not zero */
  83905. +
  83906. + mod_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_MOD]);
  83907. + if (mod_bits > 2048)
  83908. + goto too_big;
  83909. + if (mod_bits <= 32) /* 2. modulus word length > 1 */
  83910. + goto too_small; /* 8. MSW of modulus != zero */
  83911. + if (mod_bits < exp_bits) /* 3 modulus len >= exponent len */
  83912. + goto too_small;
  83913. + if ((krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p[0] & 1) == 0)
  83914. + goto bad_domain; /* 6. modulus is odd */
  83915. + if (mod_bits > krp->krp_param[krp->krp_iparams].crp_nbits)
  83916. + goto too_small; /* make sure result will fit */
  83917. +
  83918. + /* 7. modulus > base */
  83919. + if (mod_bits < base_bits)
  83920. + goto too_small;
  83921. + if (mod_bits == base_bits) {
  83922. + u_int8_t *basep, *modp;
  83923. + int i;
  83924. +
  83925. + basep = krp->krp_param[SAFE_CRK_PARAM_BASE].crp_p +
  83926. + ((base_bits + 7) / 8) - 1;
  83927. + modp = krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p +
  83928. + ((mod_bits + 7) / 8) - 1;
  83929. +
  83930. + for (i = 0; i < (mod_bits + 7) / 8; i++, basep--, modp--) {
  83931. + if (*modp < *basep)
  83932. + goto too_small;
  83933. + if (*modp > *basep)
  83934. + break;
  83935. + }
  83936. + }
  83937. +
  83938. + /* And on the 9th step, he rested. */
  83939. +
  83940. + WRITE_REG(sc, SAFE_PK_A_LEN, (exp_bits + 31) / 32);
  83941. + WRITE_REG(sc, SAFE_PK_B_LEN, (mod_bits + 31) / 32);
  83942. + if (mod_bits > 1024) {
  83943. + op = SAFE_PK_FUNC_EXP4;
  83944. + a_off = 0x000;
  83945. + b_off = 0x100;
  83946. + c_off = 0x200;
  83947. + d_off = 0x300;
  83948. + } else {
  83949. + op = SAFE_PK_FUNC_EXP16;
  83950. + a_off = 0x000;
  83951. + b_off = 0x080;
  83952. + c_off = 0x100;
  83953. + d_off = 0x180;
  83954. + }
  83955. + sc->sc_pk_reslen = b_off - a_off;
  83956. + sc->sc_pk_resoff = d_off;
  83957. +
  83958. + /* A is exponent, B is modulus, C is base, D is result */
  83959. + safe_kload_reg(sc, a_off, b_off - a_off,
  83960. + &krp->krp_param[SAFE_CRK_PARAM_EXP]);
  83961. + WRITE_REG(sc, SAFE_PK_A_ADDR, a_off >> 2);
  83962. + safe_kload_reg(sc, b_off, b_off - a_off,
  83963. + &krp->krp_param[SAFE_CRK_PARAM_MOD]);
  83964. + WRITE_REG(sc, SAFE_PK_B_ADDR, b_off >> 2);
  83965. + safe_kload_reg(sc, c_off, b_off - a_off,
  83966. + &krp->krp_param[SAFE_CRK_PARAM_BASE]);
  83967. + WRITE_REG(sc, SAFE_PK_C_ADDR, c_off >> 2);
  83968. + WRITE_REG(sc, SAFE_PK_D_ADDR, d_off >> 2);
  83969. +
  83970. + WRITE_REG(sc, SAFE_PK_FUNC, op | SAFE_PK_FUNC_RUN);
  83971. +
  83972. + return (0);
  83973. +
  83974. +too_big:
  83975. + krp->krp_status = E2BIG;
  83976. + return (1);
  83977. +too_small:
  83978. + krp->krp_status = ERANGE;
  83979. + return (1);
  83980. +bad_domain:
  83981. + krp->krp_status = EDOM;
  83982. + return (1);
  83983. +}
  83984. +
  83985. +static int
  83986. +safe_ksigbits(struct safe_softc *sc, struct crparam *cr)
  83987. +{
  83988. + u_int plen = (cr->crp_nbits + 7) / 8;
  83989. + int i, sig = plen * 8;
  83990. + u_int8_t c, *p = cr->crp_p;
  83991. +
  83992. + DPRINTF(("%s()\n", __FUNCTION__));
  83993. +
  83994. + for (i = plen - 1; i >= 0; i--) {
  83995. + c = p[i];
  83996. + if (c != 0) {
  83997. + while ((c & 0x80) == 0) {
  83998. + sig--;
  83999. + c <<= 1;
  84000. + }
  84001. + break;
  84002. + }
  84003. + sig -= 8;
  84004. + }
  84005. + return (sig);
  84006. +}
  84007. +
  84008. +static void
  84009. +safe_kfeed(struct safe_softc *sc)
  84010. +{
  84011. + struct safe_pkq *q, *tmp;
  84012. +
  84013. + DPRINTF(("%s()\n", __FUNCTION__));
  84014. +
  84015. + if (list_empty(&sc->sc_pkq) && sc->sc_pkq_cur == NULL)
  84016. + return;
  84017. + if (sc->sc_pkq_cur != NULL)
  84018. + return;
  84019. + list_for_each_entry_safe(q, tmp, &sc->sc_pkq, pkq_list) {
  84020. + sc->sc_pkq_cur = q;
  84021. + list_del(&q->pkq_list);
  84022. + if (safe_kstart(sc) != 0) {
  84023. + crypto_kdone(q->pkq_krp);
  84024. + kfree(q);
  84025. + sc->sc_pkq_cur = NULL;
  84026. + } else {
  84027. + /* op started, start polling */
  84028. + mod_timer(&sc->sc_pkto, jiffies + 1);
  84029. + break;
  84030. + }
  84031. + }
  84032. +}
  84033. +
  84034. +static void
  84035. +safe_kpoll(unsigned long arg)
  84036. +{
  84037. + struct safe_softc *sc = NULL;
  84038. + struct safe_pkq *q;
  84039. + struct crparam *res;
  84040. + int i;
  84041. + u_int32_t buf[64];
  84042. + unsigned long flags;
  84043. +
  84044. + DPRINTF(("%s()\n", __FUNCTION__));
  84045. +
  84046. + if (arg >= SAFE_MAX_CHIPS)
  84047. + return;
  84048. + sc = safe_chip_idx[arg];
  84049. + if (!sc) {
  84050. + DPRINTF(("%s() - bad callback\n", __FUNCTION__));
  84051. + return;
  84052. + }
  84053. +
  84054. + spin_lock_irqsave(&sc->sc_pkmtx, flags);
  84055. + if (sc->sc_pkq_cur == NULL)
  84056. + goto out;
  84057. + if (READ_REG(sc, SAFE_PK_FUNC) & SAFE_PK_FUNC_RUN) {
  84058. + /* still running, check back later */
  84059. + mod_timer(&sc->sc_pkto, jiffies + 1);
  84060. + goto out;
  84061. + }
  84062. +
  84063. + q = sc->sc_pkq_cur;
  84064. + res = &q->pkq_krp->krp_param[q->pkq_krp->krp_iparams];
  84065. + bzero(buf, sizeof(buf));
  84066. + bzero(res->crp_p, (res->crp_nbits + 7) / 8);
  84067. + for (i = 0; i < sc->sc_pk_reslen >> 2; i++)
  84068. + buf[i] = le32_to_cpu(READ_REG(sc, SAFE_PK_RAM_START +
  84069. + sc->sc_pk_resoff + (i << 2)));
  84070. + bcopy(buf, res->crp_p, (res->crp_nbits + 7) / 8);
  84071. + /*
  84072. + * reduce the bits that need copying if possible
  84073. + */
  84074. + res->crp_nbits = min(res->crp_nbits,sc->sc_pk_reslen * 8);
  84075. + res->crp_nbits = safe_ksigbits(sc, res);
  84076. +
  84077. + for (i = SAFE_PK_RAM_START; i < SAFE_PK_RAM_END; i += 4)
  84078. + WRITE_REG(sc, i, 0);
  84079. +
  84080. + crypto_kdone(q->pkq_krp);
  84081. + kfree(q);
  84082. + sc->sc_pkq_cur = NULL;
  84083. +
  84084. + safe_kfeed(sc);
  84085. +out:
  84086. + spin_unlock_irqrestore(&sc->sc_pkmtx, flags);
  84087. +}
  84088. +
  84089. +static void
  84090. +safe_kload_reg(struct safe_softc *sc, u_int32_t off, u_int32_t len,
  84091. + struct crparam *n)
  84092. +{
  84093. + u_int32_t buf[64], i;
  84094. +
  84095. + DPRINTF(("%s()\n", __FUNCTION__));
  84096. +
  84097. + bzero(buf, sizeof(buf));
  84098. + bcopy(n->crp_p, buf, (n->crp_nbits + 7) / 8);
  84099. +
  84100. + for (i = 0; i < len >> 2; i++)
  84101. + WRITE_REG(sc, SAFE_PK_RAM_START + off + (i << 2),
  84102. + cpu_to_le32(buf[i]));
  84103. +}
  84104. +
  84105. +#ifdef SAFE_DEBUG
  84106. +static void
  84107. +safe_dump_dmastatus(struct safe_softc *sc, const char *tag)
  84108. +{
  84109. + printf("%s: ENDIAN 0x%x SRC 0x%x DST 0x%x STAT 0x%x\n"
  84110. + , tag
  84111. + , READ_REG(sc, SAFE_DMA_ENDIAN)
  84112. + , READ_REG(sc, SAFE_DMA_SRCADDR)
  84113. + , READ_REG(sc, SAFE_DMA_DSTADDR)
  84114. + , READ_REG(sc, SAFE_DMA_STAT)
  84115. + );
  84116. +}
  84117. +
  84118. +static void
  84119. +safe_dump_intrstate(struct safe_softc *sc, const char *tag)
  84120. +{
  84121. + printf("%s: HI_CFG 0x%x HI_MASK 0x%x HI_DESC_CNT 0x%x HU_STAT 0x%x HM_STAT 0x%x\n"
  84122. + , tag
  84123. + , READ_REG(sc, SAFE_HI_CFG)
  84124. + , READ_REG(sc, SAFE_HI_MASK)
  84125. + , READ_REG(sc, SAFE_HI_DESC_CNT)
  84126. + , READ_REG(sc, SAFE_HU_STAT)
  84127. + , READ_REG(sc, SAFE_HM_STAT)
  84128. + );
  84129. +}
  84130. +
  84131. +static void
  84132. +safe_dump_ringstate(struct safe_softc *sc, const char *tag)
  84133. +{
  84134. + u_int32_t estat = READ_REG(sc, SAFE_PE_ERNGSTAT);
  84135. +
  84136. + /* NB: assume caller has lock on ring */
  84137. + printf("%s: ERNGSTAT %x (next %u) back %lu front %lu\n",
  84138. + tag,
  84139. + estat, (estat >> SAFE_PE_ERNGSTAT_NEXT_S),
  84140. + (unsigned long)(sc->sc_back - sc->sc_ring),
  84141. + (unsigned long)(sc->sc_front - sc->sc_ring));
  84142. +}
  84143. +
  84144. +static void
  84145. +safe_dump_request(struct safe_softc *sc, const char* tag, struct safe_ringentry *re)
  84146. +{
  84147. + int ix, nsegs;
  84148. +
  84149. + ix = re - sc->sc_ring;
  84150. + printf("%s: %p (%u): csr %x src %x dst %x sa %x len %x\n"
  84151. + , tag
  84152. + , re, ix
  84153. + , re->re_desc.d_csr
  84154. + , re->re_desc.d_src
  84155. + , re->re_desc.d_dst
  84156. + , re->re_desc.d_sa
  84157. + , re->re_desc.d_len
  84158. + );
  84159. + if (re->re_src.nsegs > 1) {
  84160. + ix = (re->re_desc.d_src - sc->sc_spalloc.dma_paddr) /
  84161. + sizeof(struct safe_pdesc);
  84162. + for (nsegs = re->re_src.nsegs; nsegs; nsegs--) {
  84163. + printf(" spd[%u] %p: %p size %u flags %x"
  84164. + , ix, &sc->sc_spring[ix]
  84165. + , (caddr_t)(uintptr_t) sc->sc_spring[ix].pd_addr
  84166. + , sc->sc_spring[ix].pd_size
  84167. + , sc->sc_spring[ix].pd_flags
  84168. + );
  84169. + if (sc->sc_spring[ix].pd_size == 0)
  84170. + printf(" (zero!)");
  84171. + printf("\n");
  84172. + if (++ix == SAFE_TOTAL_SPART)
  84173. + ix = 0;
  84174. + }
  84175. + }
  84176. + if (re->re_dst.nsegs > 1) {
  84177. + ix = (re->re_desc.d_dst - sc->sc_dpalloc.dma_paddr) /
  84178. + sizeof(struct safe_pdesc);
  84179. + for (nsegs = re->re_dst.nsegs; nsegs; nsegs--) {
  84180. + printf(" dpd[%u] %p: %p flags %x\n"
  84181. + , ix, &sc->sc_dpring[ix]
  84182. + , (caddr_t)(uintptr_t) sc->sc_dpring[ix].pd_addr
  84183. + , sc->sc_dpring[ix].pd_flags
  84184. + );
  84185. + if (++ix == SAFE_TOTAL_DPART)
  84186. + ix = 0;
  84187. + }
  84188. + }
  84189. + printf("sa: cmd0 %08x cmd1 %08x staterec %x\n",
  84190. + re->re_sa.sa_cmd0, re->re_sa.sa_cmd1, re->re_sa.sa_staterec);
  84191. + printf("sa: key %x %x %x %x %x %x %x %x\n"
  84192. + , re->re_sa.sa_key[0]
  84193. + , re->re_sa.sa_key[1]
  84194. + , re->re_sa.sa_key[2]
  84195. + , re->re_sa.sa_key[3]
  84196. + , re->re_sa.sa_key[4]
  84197. + , re->re_sa.sa_key[5]
  84198. + , re->re_sa.sa_key[6]
  84199. + , re->re_sa.sa_key[7]
  84200. + );
  84201. + printf("sa: indigest %x %x %x %x %x\n"
  84202. + , re->re_sa.sa_indigest[0]
  84203. + , re->re_sa.sa_indigest[1]
  84204. + , re->re_sa.sa_indigest[2]
  84205. + , re->re_sa.sa_indigest[3]
  84206. + , re->re_sa.sa_indigest[4]
  84207. + );
  84208. + printf("sa: outdigest %x %x %x %x %x\n"
  84209. + , re->re_sa.sa_outdigest[0]
  84210. + , re->re_sa.sa_outdigest[1]
  84211. + , re->re_sa.sa_outdigest[2]
  84212. + , re->re_sa.sa_outdigest[3]
  84213. + , re->re_sa.sa_outdigest[4]
  84214. + );
  84215. + printf("sr: iv %x %x %x %x\n"
  84216. + , re->re_sastate.sa_saved_iv[0]
  84217. + , re->re_sastate.sa_saved_iv[1]
  84218. + , re->re_sastate.sa_saved_iv[2]
  84219. + , re->re_sastate.sa_saved_iv[3]
  84220. + );
  84221. + printf("sr: hashbc %u indigest %x %x %x %x %x\n"
  84222. + , re->re_sastate.sa_saved_hashbc
  84223. + , re->re_sastate.sa_saved_indigest[0]
  84224. + , re->re_sastate.sa_saved_indigest[1]
  84225. + , re->re_sastate.sa_saved_indigest[2]
  84226. + , re->re_sastate.sa_saved_indigest[3]
  84227. + , re->re_sastate.sa_saved_indigest[4]
  84228. + );
  84229. +}
  84230. +
  84231. +static void
  84232. +safe_dump_ring(struct safe_softc *sc, const char *tag)
  84233. +{
  84234. + unsigned long flags;
  84235. +
  84236. + spin_lock_irqsave(&sc->sc_ringmtx, flags);
  84237. + printf("\nSafeNet Ring State:\n");
  84238. + safe_dump_intrstate(sc, tag);
  84239. + safe_dump_dmastatus(sc, tag);
  84240. + safe_dump_ringstate(sc, tag);
  84241. + if (sc->sc_nqchip) {
  84242. + struct safe_ringentry *re = sc->sc_back;
  84243. + do {
  84244. + safe_dump_request(sc, tag, re);
  84245. + if (++re == sc->sc_ringtop)
  84246. + re = sc->sc_ring;
  84247. + } while (re != sc->sc_front);
  84248. + }
  84249. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  84250. +}
  84251. +#endif /* SAFE_DEBUG */
  84252. +
  84253. +
  84254. +static int safe_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  84255. +{
  84256. + struct safe_softc *sc = NULL;
  84257. + u32 mem_start, mem_len, cmd;
  84258. + int i, rc, devinfo;
  84259. + dma_addr_t raddr;
  84260. + static int num_chips = 0;
  84261. +
  84262. + DPRINTF(("%s()\n", __FUNCTION__));
  84263. +
  84264. + if (pci_enable_device(dev) < 0)
  84265. + return(-ENODEV);
  84266. +
  84267. + if (!dev->irq) {
  84268. + printk("safe: found device with no IRQ assigned. check BIOS settings!");
  84269. + pci_disable_device(dev);
  84270. + return(-ENODEV);
  84271. + }
  84272. +
  84273. + if (pci_set_mwi(dev)) {
  84274. + printk("safe: pci_set_mwi failed!");
  84275. + return(-ENODEV);
  84276. + }
  84277. +
  84278. + sc = (struct safe_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  84279. + if (!sc)
  84280. + return(-ENOMEM);
  84281. + memset(sc, 0, sizeof(*sc));
  84282. +
  84283. + softc_device_init(sc, "safe", num_chips, safe_methods);
  84284. +
  84285. + sc->sc_irq = -1;
  84286. + sc->sc_cid = -1;
  84287. + sc->sc_pcidev = dev;
  84288. + if (num_chips < SAFE_MAX_CHIPS) {
  84289. + safe_chip_idx[device_get_unit(sc->sc_dev)] = sc;
  84290. + num_chips++;
  84291. + }
  84292. +
  84293. + INIT_LIST_HEAD(&sc->sc_pkq);
  84294. + spin_lock_init(&sc->sc_pkmtx);
  84295. +
  84296. + pci_set_drvdata(sc->sc_pcidev, sc);
  84297. +
  84298. + /* we read its hardware registers as memory */
  84299. + mem_start = pci_resource_start(sc->sc_pcidev, 0);
  84300. + mem_len = pci_resource_len(sc->sc_pcidev, 0);
  84301. +
  84302. + sc->sc_base_addr = (ocf_iomem_t) ioremap(mem_start, mem_len);
  84303. + if (!sc->sc_base_addr) {
  84304. + device_printf(sc->sc_dev, "failed to ioremap 0x%x-0x%x\n",
  84305. + mem_start, mem_start + mem_len - 1);
  84306. + goto out;
  84307. + }
  84308. +
  84309. + /* fix up the bus size */
  84310. + if (pci_set_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {
  84311. + device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
  84312. + goto out;
  84313. + }
  84314. + if (pci_set_consistent_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {
  84315. + device_printf(sc->sc_dev, "No usable consistent DMA configuration, aborting.\n");
  84316. + goto out;
  84317. + }
  84318. +
  84319. + pci_set_master(sc->sc_pcidev);
  84320. +
  84321. + pci_read_config_dword(sc->sc_pcidev, PCI_COMMAND, &cmd);
  84322. +
  84323. + if (!(cmd & PCI_COMMAND_MEMORY)) {
  84324. + device_printf(sc->sc_dev, "failed to enable memory mapping\n");
  84325. + goto out;
  84326. + }
  84327. +
  84328. + if (!(cmd & PCI_COMMAND_MASTER)) {
  84329. + device_printf(sc->sc_dev, "failed to enable bus mastering\n");
  84330. + goto out;
  84331. + }
  84332. +
  84333. + rc = request_irq(dev->irq, safe_intr, IRQF_SHARED, "safe", sc);
  84334. + if (rc) {
  84335. + device_printf(sc->sc_dev, "failed to hook irq %d\n", sc->sc_irq);
  84336. + goto out;
  84337. + }
  84338. + sc->sc_irq = dev->irq;
  84339. +
  84340. + sc->sc_chiprev = READ_REG(sc, SAFE_DEVINFO) &
  84341. + (SAFE_DEVINFO_REV_MAJ | SAFE_DEVINFO_REV_MIN);
  84342. +
  84343. + /*
  84344. + * Allocate packet engine descriptors.
  84345. + */
  84346. + sc->sc_ringalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
  84347. + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
  84348. + &sc->sc_ringalloc.dma_paddr);
  84349. + if (!sc->sc_ringalloc.dma_vaddr) {
  84350. + device_printf(sc->sc_dev, "cannot allocate PE descriptor ring\n");
  84351. + goto out;
  84352. + }
  84353. +
  84354. + /*
  84355. + * Hookup the static portion of all our data structures.
  84356. + */
  84357. + sc->sc_ring = (struct safe_ringentry *) sc->sc_ringalloc.dma_vaddr;
  84358. + sc->sc_ringtop = sc->sc_ring + SAFE_MAX_NQUEUE;
  84359. + sc->sc_front = sc->sc_ring;
  84360. + sc->sc_back = sc->sc_ring;
  84361. + raddr = sc->sc_ringalloc.dma_paddr;
  84362. + bzero(sc->sc_ring, SAFE_MAX_NQUEUE * sizeof(struct safe_ringentry));
  84363. + for (i = 0; i < SAFE_MAX_NQUEUE; i++) {
  84364. + struct safe_ringentry *re = &sc->sc_ring[i];
  84365. +
  84366. + re->re_desc.d_sa = raddr +
  84367. + offsetof(struct safe_ringentry, re_sa);
  84368. + re->re_sa.sa_staterec = raddr +
  84369. + offsetof(struct safe_ringentry, re_sastate);
  84370. +
  84371. + raddr += sizeof (struct safe_ringentry);
  84372. + }
  84373. + spin_lock_init(&sc->sc_ringmtx);
  84374. +
  84375. + /*
  84376. + * Allocate scatter and gather particle descriptors.
  84377. + */
  84378. + sc->sc_spalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
  84379. + SAFE_TOTAL_SPART * sizeof (struct safe_pdesc),
  84380. + &sc->sc_spalloc.dma_paddr);
  84381. + if (!sc->sc_spalloc.dma_vaddr) {
  84382. + device_printf(sc->sc_dev, "cannot allocate source particle descriptor ring\n");
  84383. + goto out;
  84384. + }
  84385. + sc->sc_spring = (struct safe_pdesc *) sc->sc_spalloc.dma_vaddr;
  84386. + sc->sc_springtop = sc->sc_spring + SAFE_TOTAL_SPART;
  84387. + sc->sc_spfree = sc->sc_spring;
  84388. + bzero(sc->sc_spring, SAFE_TOTAL_SPART * sizeof(struct safe_pdesc));
  84389. +
  84390. + sc->sc_dpalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
  84391. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  84392. + &sc->sc_dpalloc.dma_paddr);
  84393. + if (!sc->sc_dpalloc.dma_vaddr) {
  84394. + device_printf(sc->sc_dev, "cannot allocate destination particle descriptor ring\n");
  84395. + goto out;
  84396. + }
  84397. + sc->sc_dpring = (struct safe_pdesc *) sc->sc_dpalloc.dma_vaddr;
  84398. + sc->sc_dpringtop = sc->sc_dpring + SAFE_TOTAL_DPART;
  84399. + sc->sc_dpfree = sc->sc_dpring;
  84400. + bzero(sc->sc_dpring, SAFE_TOTAL_DPART * sizeof(struct safe_pdesc));
  84401. +
  84402. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc), CRYPTOCAP_F_HARDWARE);
  84403. + if (sc->sc_cid < 0) {
  84404. + device_printf(sc->sc_dev, "could not get crypto driver id\n");
  84405. + goto out;
  84406. + }
  84407. +
  84408. + printf("%s:", device_get_nameunit(sc->sc_dev));
  84409. +
  84410. + devinfo = READ_REG(sc, SAFE_DEVINFO);
  84411. + if (devinfo & SAFE_DEVINFO_RNG) {
  84412. + sc->sc_flags |= SAFE_FLAGS_RNG;
  84413. + printf(" rng");
  84414. + }
  84415. + if (devinfo & SAFE_DEVINFO_PKEY) {
  84416. + printf(" key");
  84417. + sc->sc_flags |= SAFE_FLAGS_KEY;
  84418. + crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0);
  84419. +#if 0
  84420. + crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0);
  84421. +#endif
  84422. + init_timer(&sc->sc_pkto);
  84423. + sc->sc_pkto.function = safe_kpoll;
  84424. + sc->sc_pkto.data = (unsigned long) device_get_unit(sc->sc_dev);
  84425. + }
  84426. + if (devinfo & SAFE_DEVINFO_DES) {
  84427. + printf(" des/3des");
  84428. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  84429. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  84430. + }
  84431. + if (devinfo & SAFE_DEVINFO_AES) {
  84432. + printf(" aes");
  84433. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  84434. + }
  84435. + if (devinfo & SAFE_DEVINFO_MD5) {
  84436. + printf(" md5");
  84437. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  84438. + }
  84439. + if (devinfo & SAFE_DEVINFO_SHA1) {
  84440. + printf(" sha1");
  84441. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  84442. + }
  84443. + printf(" null");
  84444. + crypto_register(sc->sc_cid, CRYPTO_NULL_CBC, 0, 0);
  84445. + crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0);
  84446. + /* XXX other supported algorithms */
  84447. + printf("\n");
  84448. +
  84449. + safe_reset_board(sc); /* reset h/w */
  84450. + safe_init_board(sc); /* init h/w */
  84451. +
  84452. +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
  84453. + if (sc->sc_flags & SAFE_FLAGS_RNG) {
  84454. + safe_rng_init(sc);
  84455. + crypto_rregister(sc->sc_cid, safe_read_random, sc);
  84456. + }
  84457. +#endif /* SAFE_NO_RNG */
  84458. +
  84459. + return (0);
  84460. +
  84461. +out:
  84462. + if (sc->sc_cid >= 0)
  84463. + crypto_unregister_all(sc->sc_cid);
  84464. + if (sc->sc_irq != -1)
  84465. + free_irq(sc->sc_irq, sc);
  84466. + if (sc->sc_ringalloc.dma_vaddr)
  84467. + pci_free_consistent(sc->sc_pcidev,
  84468. + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
  84469. + sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);
  84470. + if (sc->sc_spalloc.dma_vaddr)
  84471. + pci_free_consistent(sc->sc_pcidev,
  84472. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  84473. + sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);
  84474. + if (sc->sc_dpalloc.dma_vaddr)
  84475. + pci_free_consistent(sc->sc_pcidev,
  84476. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  84477. + sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);
  84478. + kfree(sc);
  84479. + return(-ENODEV);
  84480. +}
  84481. +
  84482. +static void safe_remove(struct pci_dev *dev)
  84483. +{
  84484. + struct safe_softc *sc = pci_get_drvdata(dev);
  84485. +
  84486. + DPRINTF(("%s()\n", __FUNCTION__));
  84487. +
  84488. + /* XXX wait/abort active ops */
  84489. +
  84490. + WRITE_REG(sc, SAFE_HI_MASK, 0); /* disable interrupts */
  84491. +
  84492. + del_timer_sync(&sc->sc_pkto);
  84493. +
  84494. + crypto_unregister_all(sc->sc_cid);
  84495. +
  84496. + safe_cleanchip(sc);
  84497. +
  84498. + if (sc->sc_irq != -1)
  84499. + free_irq(sc->sc_irq, sc);
  84500. + if (sc->sc_ringalloc.dma_vaddr)
  84501. + pci_free_consistent(sc->sc_pcidev,
  84502. + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
  84503. + sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);
  84504. + if (sc->sc_spalloc.dma_vaddr)
  84505. + pci_free_consistent(sc->sc_pcidev,
  84506. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  84507. + sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);
  84508. + if (sc->sc_dpalloc.dma_vaddr)
  84509. + pci_free_consistent(sc->sc_pcidev,
  84510. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  84511. + sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);
  84512. + sc->sc_irq = -1;
  84513. + sc->sc_ringalloc.dma_vaddr = NULL;
  84514. + sc->sc_spalloc.dma_vaddr = NULL;
  84515. + sc->sc_dpalloc.dma_vaddr = NULL;
  84516. +}
  84517. +
  84518. +static struct pci_device_id safe_pci_tbl[] = {
  84519. + { PCI_VENDOR_SAFENET, PCI_PRODUCT_SAFEXCEL,
  84520. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  84521. + { },
  84522. +};
  84523. +MODULE_DEVICE_TABLE(pci, safe_pci_tbl);
  84524. +
  84525. +static struct pci_driver safe_driver = {
  84526. + .name = "safe",
  84527. + .id_table = safe_pci_tbl,
  84528. + .probe = safe_probe,
  84529. + .remove = safe_remove,
  84530. + /* add PM stuff here one day */
  84531. +};
  84532. +
  84533. +static int __init safe_init (void)
  84534. +{
  84535. + struct safe_softc *sc = NULL;
  84536. + int rc;
  84537. +
  84538. + DPRINTF(("%s(%p)\n", __FUNCTION__, safe_init));
  84539. +
  84540. + rc = pci_register_driver(&safe_driver);
  84541. + pci_register_driver_compat(&safe_driver, rc);
  84542. +
  84543. + return rc;
  84544. +}
  84545. +
  84546. +static void __exit safe_exit (void)
  84547. +{
  84548. + pci_unregister_driver(&safe_driver);
  84549. +}
  84550. +
  84551. +module_init(safe_init);
  84552. +module_exit(safe_exit);
  84553. +
  84554. +MODULE_LICENSE("BSD");
  84555. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  84556. +MODULE_DESCRIPTION("OCF driver for safenet PCI crypto devices");
  84557. diff -Nur linux-2.6.35.orig/crypto/ocf/safe/safereg.h linux-2.6.35/crypto/ocf/safe/safereg.h
  84558. --- linux-2.6.35.orig/crypto/ocf/safe/safereg.h 1970-01-01 01:00:00.000000000 +0100
  84559. +++ linux-2.6.35/crypto/ocf/safe/safereg.h 2010-08-05 22:02:26.554867957 +0200
  84560. @@ -0,0 +1,421 @@
  84561. +/*-
  84562. + * Copyright (c) 2003 Sam Leffler, Errno Consulting
  84563. + * Copyright (c) 2003 Global Technology Associates, Inc.
  84564. + * All rights reserved.
  84565. + *
  84566. + * Redistribution and use in source and binary forms, with or without
  84567. + * modification, are permitted provided that the following conditions
  84568. + * are met:
  84569. + * 1. Redistributions of source code must retain the above copyright
  84570. + * notice, this list of conditions and the following disclaimer.
  84571. + * 2. Redistributions in binary form must reproduce the above copyright
  84572. + * notice, this list of conditions and the following disclaimer in the
  84573. + * documentation and/or other materials provided with the distribution.
  84574. + *
  84575. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  84576. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  84577. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  84578. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  84579. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  84580. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  84581. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  84582. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  84583. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  84584. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  84585. + * SUCH DAMAGE.
  84586. + *
  84587. + * $FreeBSD: src/sys/dev/safe/safereg.h,v 1.1 2003/07/21 21:46:07 sam Exp $
  84588. + */
  84589. +#ifndef _SAFE_SAFEREG_H_
  84590. +#define _SAFE_SAFEREG_H_
  84591. +
  84592. +/*
  84593. + * Register definitions for SafeNet SafeXcel-1141 crypto device.
  84594. + * Definitions from revision 1.3 (Nov 6 2002) of the User's Manual.
  84595. + */
  84596. +
  84597. +#define BS_BAR 0x10 /* DMA base address register */
  84598. +#define BS_TRDY_TIMEOUT 0x40 /* TRDY timeout */
  84599. +#define BS_RETRY_TIMEOUT 0x41 /* DMA retry timeout */
  84600. +
  84601. +#define PCI_VENDOR_SAFENET 0x16ae /* SafeNet, Inc. */
  84602. +
  84603. +/* SafeNet */
  84604. +#define PCI_PRODUCT_SAFEXCEL 0x1141 /* 1141 */
  84605. +
  84606. +#define SAFE_PE_CSR 0x0000 /* Packet Enginge Ctrl/Status */
  84607. +#define SAFE_PE_SRC 0x0004 /* Packet Engine Source */
  84608. +#define SAFE_PE_DST 0x0008 /* Packet Engine Destination */
  84609. +#define SAFE_PE_SA 0x000c /* Packet Engine SA */
  84610. +#define SAFE_PE_LEN 0x0010 /* Packet Engine Length */
  84611. +#define SAFE_PE_DMACFG 0x0040 /* Packet Engine DMA Configuration */
  84612. +#define SAFE_PE_DMASTAT 0x0044 /* Packet Engine DMA Status */
  84613. +#define SAFE_PE_PDRBASE 0x0048 /* Packet Engine Descriptor Ring Base */
  84614. +#define SAFE_PE_RDRBASE 0x004c /* Packet Engine Result Ring Base */
  84615. +#define SAFE_PE_RINGCFG 0x0050 /* Packet Engine Ring Configuration */
  84616. +#define SAFE_PE_RINGPOLL 0x0054 /* Packet Engine Ring Poll */
  84617. +#define SAFE_PE_IRNGSTAT 0x0058 /* Packet Engine Internal Ring Status */
  84618. +#define SAFE_PE_ERNGSTAT 0x005c /* Packet Engine External Ring Status */
  84619. +#define SAFE_PE_IOTHRESH 0x0060 /* Packet Engine I/O Threshold */
  84620. +#define SAFE_PE_GRNGBASE 0x0064 /* Packet Engine Gather Ring Base */
  84621. +#define SAFE_PE_SRNGBASE 0x0068 /* Packet Engine Scatter Ring Base */
  84622. +#define SAFE_PE_PARTSIZE 0x006c /* Packet Engine Particlar Ring Size */
  84623. +#define SAFE_PE_PARTCFG 0x0070 /* Packet Engine Particle Ring Config */
  84624. +#define SAFE_CRYPTO_CTRL 0x0080 /* Crypto Control */
  84625. +#define SAFE_DEVID 0x0084 /* Device ID */
  84626. +#define SAFE_DEVINFO 0x0088 /* Device Info */
  84627. +#define SAFE_HU_STAT 0x00a0 /* Host Unmasked Status */
  84628. +#define SAFE_HM_STAT 0x00a4 /* Host Masked Status (read-only) */
  84629. +#define SAFE_HI_CLR 0x00a4 /* Host Clear Interrupt (write-only) */
  84630. +#define SAFE_HI_MASK 0x00a8 /* Host Mask Control */
  84631. +#define SAFE_HI_CFG 0x00ac /* Interrupt Configuration */
  84632. +#define SAFE_HI_RD_DESCR 0x00b4 /* Force Descriptor Read */
  84633. +#define SAFE_HI_DESC_CNT 0x00b8 /* Host Descriptor Done Count */
  84634. +#define SAFE_DMA_ENDIAN 0x00c0 /* Master Endian Status */
  84635. +#define SAFE_DMA_SRCADDR 0x00c4 /* DMA Source Address Status */
  84636. +#define SAFE_DMA_DSTADDR 0x00c8 /* DMA Destination Address Status */
  84637. +#define SAFE_DMA_STAT 0x00cc /* DMA Current Status */
  84638. +#define SAFE_DMA_CFG 0x00d4 /* DMA Configuration/Status */
  84639. +#define SAFE_ENDIAN 0x00e0 /* Endian Configuration */
  84640. +#define SAFE_PK_A_ADDR 0x0800 /* Public Key A Address */
  84641. +#define SAFE_PK_B_ADDR 0x0804 /* Public Key B Address */
  84642. +#define SAFE_PK_C_ADDR 0x0808 /* Public Key C Address */
  84643. +#define SAFE_PK_D_ADDR 0x080c /* Public Key D Address */
  84644. +#define SAFE_PK_A_LEN 0x0810 /* Public Key A Length */
  84645. +#define SAFE_PK_B_LEN 0x0814 /* Public Key B Length */
  84646. +#define SAFE_PK_SHIFT 0x0818 /* Public Key Shift */
  84647. +#define SAFE_PK_FUNC 0x081c /* Public Key Function */
  84648. +#define SAFE_PK_RAM_START 0x1000 /* Public Key RAM start address */
  84649. +#define SAFE_PK_RAM_END 0x1fff /* Public Key RAM end address */
  84650. +
  84651. +#define SAFE_RNG_OUT 0x0100 /* RNG Output */
  84652. +#define SAFE_RNG_STAT 0x0104 /* RNG Status */
  84653. +#define SAFE_RNG_CTRL 0x0108 /* RNG Control */
  84654. +#define SAFE_RNG_A 0x010c /* RNG A */
  84655. +#define SAFE_RNG_B 0x0110 /* RNG B */
  84656. +#define SAFE_RNG_X_LO 0x0114 /* RNG X [31:0] */
  84657. +#define SAFE_RNG_X_MID 0x0118 /* RNG X [63:32] */
  84658. +#define SAFE_RNG_X_HI 0x011c /* RNG X [80:64] */
  84659. +#define SAFE_RNG_X_CNTR 0x0120 /* RNG Counter */
  84660. +#define SAFE_RNG_ALM_CNT 0x0124 /* RNG Alarm Count */
  84661. +#define SAFE_RNG_CNFG 0x0128 /* RNG Configuration */
  84662. +#define SAFE_RNG_LFSR1_LO 0x012c /* RNG LFSR1 [31:0] */
  84663. +#define SAFE_RNG_LFSR1_HI 0x0130 /* RNG LFSR1 [47:32] */
  84664. +#define SAFE_RNG_LFSR2_LO 0x0134 /* RNG LFSR1 [31:0] */
  84665. +#define SAFE_RNG_LFSR2_HI 0x0138 /* RNG LFSR1 [47:32] */
  84666. +
  84667. +#define SAFE_PE_CSR_READY 0x00000001 /* ready for processing */
  84668. +#define SAFE_PE_CSR_DONE 0x00000002 /* h/w completed processing */
  84669. +#define SAFE_PE_CSR_LOADSA 0x00000004 /* load SA digests */
  84670. +#define SAFE_PE_CSR_HASHFINAL 0x00000010 /* do hash pad & write result */
  84671. +#define SAFE_PE_CSR_SABUSID 0x000000c0 /* bus id for SA */
  84672. +#define SAFE_PE_CSR_SAPCI 0x00000040 /* PCI bus id for SA */
  84673. +#define SAFE_PE_CSR_NXTHDR 0x0000ff00 /* next hdr value for IPsec */
  84674. +#define SAFE_PE_CSR_FPAD 0x0000ff00 /* fixed pad for basic ops */
  84675. +#define SAFE_PE_CSR_STATUS 0x00ff0000 /* operation result status */
  84676. +#define SAFE_PE_CSR_AUTH_FAIL 0x00010000 /* ICV mismatch (inbound) */
  84677. +#define SAFE_PE_CSR_PAD_FAIL 0x00020000 /* pad verify fail (inbound) */
  84678. +#define SAFE_PE_CSR_SEQ_FAIL 0x00040000 /* sequence number (inbound) */
  84679. +#define SAFE_PE_CSR_XERROR 0x00080000 /* extended error follows */
  84680. +#define SAFE_PE_CSR_XECODE 0x00f00000 /* extended error code */
  84681. +#define SAFE_PE_CSR_XECODE_S 20
  84682. +#define SAFE_PE_CSR_XECODE_BADCMD 0 /* invalid command */
  84683. +#define SAFE_PE_CSR_XECODE_BADALG 1 /* invalid algorithm */
  84684. +#define SAFE_PE_CSR_XECODE_ALGDIS 2 /* algorithm disabled */
  84685. +#define SAFE_PE_CSR_XECODE_ZEROLEN 3 /* zero packet length */
  84686. +#define SAFE_PE_CSR_XECODE_DMAERR 4 /* bus DMA error */
  84687. +#define SAFE_PE_CSR_XECODE_PIPEABORT 5 /* secondary bus DMA error */
  84688. +#define SAFE_PE_CSR_XECODE_BADSPI 6 /* IPsec SPI mismatch */
  84689. +#define SAFE_PE_CSR_XECODE_TIMEOUT 10 /* failsafe timeout */
  84690. +#define SAFE_PE_CSR_PAD 0xff000000 /* ESP padding control/status */
  84691. +#define SAFE_PE_CSR_PAD_MIN 0x00000000 /* minimum IPsec padding */
  84692. +#define SAFE_PE_CSR_PAD_16 0x08000000 /* pad to 16-byte boundary */
  84693. +#define SAFE_PE_CSR_PAD_32 0x10000000 /* pad to 32-byte boundary */
  84694. +#define SAFE_PE_CSR_PAD_64 0x20000000 /* pad to 64-byte boundary */
  84695. +#define SAFE_PE_CSR_PAD_128 0x40000000 /* pad to 128-byte boundary */
  84696. +#define SAFE_PE_CSR_PAD_256 0x80000000 /* pad to 256-byte boundary */
  84697. +
  84698. +/*
  84699. + * Check the CSR to see if the PE has returned ownership to
  84700. + * the host. Note that before processing a descriptor this
  84701. + * must be done followed by a check of the SAFE_PE_LEN register
  84702. + * status bits to avoid premature processing of a descriptor
  84703. + * on its way back to the host.
  84704. + */
  84705. +#define SAFE_PE_CSR_IS_DONE(_csr) \
  84706. + (((_csr) & (SAFE_PE_CSR_READY | SAFE_PE_CSR_DONE)) == SAFE_PE_CSR_DONE)
  84707. +
  84708. +#define SAFE_PE_LEN_LENGTH 0x000fffff /* total length (bytes) */
  84709. +#define SAFE_PE_LEN_READY 0x00400000 /* ready for processing */
  84710. +#define SAFE_PE_LEN_DONE 0x00800000 /* h/w completed processing */
  84711. +#define SAFE_PE_LEN_BYPASS 0xff000000 /* bypass offset (bytes) */
  84712. +#define SAFE_PE_LEN_BYPASS_S 24
  84713. +
  84714. +#define SAFE_PE_LEN_IS_DONE(_len) \
  84715. + (((_len) & (SAFE_PE_LEN_READY | SAFE_PE_LEN_DONE)) == SAFE_PE_LEN_DONE)
  84716. +
  84717. +/* NB: these apply to HU_STAT, HM_STAT, HI_CLR, and HI_MASK */
  84718. +#define SAFE_INT_PE_CDONE 0x00000002 /* PE context done */
  84719. +#define SAFE_INT_PE_DDONE 0x00000008 /* PE descriptor done */
  84720. +#define SAFE_INT_PE_ERROR 0x00000010 /* PE error */
  84721. +#define SAFE_INT_PE_ODONE 0x00000020 /* PE operation done */
  84722. +
  84723. +#define SAFE_HI_CFG_PULSE 0x00000001 /* use pulse interrupt */
  84724. +#define SAFE_HI_CFG_LEVEL 0x00000000 /* use level interrupt */
  84725. +#define SAFE_HI_CFG_AUTOCLR 0x00000002 /* auto-clear pulse interrupt */
  84726. +
  84727. +#define SAFE_ENDIAN_PASS 0x000000e4 /* straight pass-thru */
  84728. +#define SAFE_ENDIAN_SWAB 0x0000001b /* swap bytes in 32-bit word */
  84729. +
  84730. +#define SAFE_PE_DMACFG_PERESET 0x00000001 /* reset packet engine */
  84731. +#define SAFE_PE_DMACFG_PDRRESET 0x00000002 /* reset PDR counters/ptrs */
  84732. +#define SAFE_PE_DMACFG_SGRESET 0x00000004 /* reset scatter/gather cache */
  84733. +#define SAFE_PE_DMACFG_FSENA 0x00000008 /* enable failsafe reset */
  84734. +#define SAFE_PE_DMACFG_PEMODE 0x00000100 /* packet engine mode */
  84735. +#define SAFE_PE_DMACFG_SAPREC 0x00000200 /* SA precedes packet */
  84736. +#define SAFE_PE_DMACFG_PKFOLL 0x00000400 /* packet follows descriptor */
  84737. +#define SAFE_PE_DMACFG_GPRBID 0x00003000 /* gather particle ring busid */
  84738. +#define SAFE_PE_DMACFG_GPRPCI 0x00001000 /* PCI gather particle ring */
  84739. +#define SAFE_PE_DMACFG_SPRBID 0x0000c000 /* scatter part. ring busid */
  84740. +#define SAFE_PE_DMACFG_SPRPCI 0x00004000 /* PCI scatter part. ring */
  84741. +#define SAFE_PE_DMACFG_ESDESC 0x00010000 /* endian swap descriptors */
  84742. +#define SAFE_PE_DMACFG_ESSA 0x00020000 /* endian swap SA data */
  84743. +#define SAFE_PE_DMACFG_ESPACKET 0x00040000 /* endian swap packet data */
  84744. +#define SAFE_PE_DMACFG_ESPDESC 0x00080000 /* endian swap particle desc. */
  84745. +#define SAFE_PE_DMACFG_NOPDRUP 0x00100000 /* supp. PDR ownership update */
  84746. +#define SAFE_PD_EDMACFG_PCIMODE 0x01000000 /* PCI target mode */
  84747. +
  84748. +#define SAFE_PE_DMASTAT_PEIDONE 0x00000001 /* PE core input done */
  84749. +#define SAFE_PE_DMASTAT_PEODONE 0x00000002 /* PE core output done */
  84750. +#define SAFE_PE_DMASTAT_ENCDONE 0x00000004 /* encryption done */
  84751. +#define SAFE_PE_DMASTAT_IHDONE 0x00000008 /* inner hash done */
  84752. +#define SAFE_PE_DMASTAT_OHDONE 0x00000010 /* outer hash (HMAC) done */
  84753. +#define SAFE_PE_DMASTAT_PADFLT 0x00000020 /* crypto pad fault */
  84754. +#define SAFE_PE_DMASTAT_ICVFLT 0x00000040 /* ICV fault */
  84755. +#define SAFE_PE_DMASTAT_SPIMIS 0x00000080 /* SPI mismatch */
  84756. +#define SAFE_PE_DMASTAT_CRYPTO 0x00000100 /* crypto engine timeout */
  84757. +#define SAFE_PE_DMASTAT_CQACT 0x00000200 /* command queue active */
  84758. +#define SAFE_PE_DMASTAT_IRACT 0x00000400 /* input request active */
  84759. +#define SAFE_PE_DMASTAT_ORACT 0x00000800 /* output request active */
  84760. +#define SAFE_PE_DMASTAT_PEISIZE 0x003ff000 /* PE input size:32-bit words */
  84761. +#define SAFE_PE_DMASTAT_PEOSIZE 0xffc00000 /* PE out. size:32-bit words */
  84762. +
  84763. +#define SAFE_PE_RINGCFG_SIZE 0x000003ff /* ring size (descriptors) */
  84764. +#define SAFE_PE_RINGCFG_OFFSET 0xffff0000 /* offset btw desc's (dwords) */
  84765. +#define SAFE_PE_RINGCFG_OFFSET_S 16
  84766. +
  84767. +#define SAFE_PE_RINGPOLL_POLL 0x00000fff /* polling frequency/divisor */
  84768. +#define SAFE_PE_RINGPOLL_RETRY 0x03ff0000 /* polling frequency/divisor */
  84769. +#define SAFE_PE_RINGPOLL_CONT 0x80000000 /* continuously poll */
  84770. +
  84771. +#define SAFE_PE_IRNGSTAT_CQAVAIL 0x00000001 /* command queue available */
  84772. +
  84773. +#define SAFE_PE_ERNGSTAT_NEXT 0x03ff0000 /* index of next packet desc. */
  84774. +#define SAFE_PE_ERNGSTAT_NEXT_S 16
  84775. +
  84776. +#define SAFE_PE_IOTHRESH_INPUT 0x000003ff /* input threshold (dwords) */
  84777. +#define SAFE_PE_IOTHRESH_OUTPUT 0x03ff0000 /* output threshold (dwords) */
  84778. +
  84779. +#define SAFE_PE_PARTCFG_SIZE 0x0000ffff /* scatter particle size */
  84780. +#define SAFE_PE_PARTCFG_GBURST 0x00030000 /* gather particle burst */
  84781. +#define SAFE_PE_PARTCFG_GBURST_2 0x00000000
  84782. +#define SAFE_PE_PARTCFG_GBURST_4 0x00010000
  84783. +#define SAFE_PE_PARTCFG_GBURST_8 0x00020000
  84784. +#define SAFE_PE_PARTCFG_GBURST_16 0x00030000
  84785. +#define SAFE_PE_PARTCFG_SBURST 0x000c0000 /* scatter particle burst */
  84786. +#define SAFE_PE_PARTCFG_SBURST_2 0x00000000
  84787. +#define SAFE_PE_PARTCFG_SBURST_4 0x00040000
  84788. +#define SAFE_PE_PARTCFG_SBURST_8 0x00080000
  84789. +#define SAFE_PE_PARTCFG_SBURST_16 0x000c0000
  84790. +
  84791. +#define SAFE_PE_PARTSIZE_SCAT 0xffff0000 /* scatter particle ring size */
  84792. +#define SAFE_PE_PARTSIZE_GATH 0x0000ffff /* gather particle ring size */
  84793. +
  84794. +#define SAFE_CRYPTO_CTRL_3DES 0x00000001 /* enable 3DES support */
  84795. +#define SAFE_CRYPTO_CTRL_PKEY 0x00010000 /* enable public key support */
  84796. +#define SAFE_CRYPTO_CTRL_RNG 0x00020000 /* enable RNG support */
  84797. +
  84798. +#define SAFE_DEVINFO_REV_MIN 0x0000000f /* minor rev for chip */
  84799. +#define SAFE_DEVINFO_REV_MAJ 0x000000f0 /* major rev for chip */
  84800. +#define SAFE_DEVINFO_REV_MAJ_S 4
  84801. +#define SAFE_DEVINFO_DES 0x00000100 /* DES/3DES support present */
  84802. +#define SAFE_DEVINFO_ARC4 0x00000200 /* ARC4 support present */
  84803. +#define SAFE_DEVINFO_AES 0x00000400 /* AES support present */
  84804. +#define SAFE_DEVINFO_MD5 0x00001000 /* MD5 support present */
  84805. +#define SAFE_DEVINFO_SHA1 0x00002000 /* SHA-1 support present */
  84806. +#define SAFE_DEVINFO_RIPEMD 0x00004000 /* RIPEMD support present */
  84807. +#define SAFE_DEVINFO_DEFLATE 0x00010000 /* Deflate support present */
  84808. +#define SAFE_DEVINFO_SARAM 0x00100000 /* on-chip SA RAM present */
  84809. +#define SAFE_DEVINFO_EMIBUS 0x00200000 /* EMI bus present */
  84810. +#define SAFE_DEVINFO_PKEY 0x00400000 /* public key support present */
  84811. +#define SAFE_DEVINFO_RNG 0x00800000 /* RNG present */
  84812. +
  84813. +#define SAFE_REV(_maj, _min) (((_maj) << SAFE_DEVINFO_REV_MAJ_S) | (_min))
  84814. +#define SAFE_REV_MAJ(_chiprev) \
  84815. + (((_chiprev) & SAFE_DEVINFO_REV_MAJ) >> SAFE_DEVINFO_REV_MAJ_S)
  84816. +#define SAFE_REV_MIN(_chiprev) ((_chiprev) & SAFE_DEVINFO_REV_MIN)
  84817. +
  84818. +#define SAFE_PK_FUNC_MULT 0x00000001 /* Multiply function */
  84819. +#define SAFE_PK_FUNC_SQUARE 0x00000004 /* Square function */
  84820. +#define SAFE_PK_FUNC_ADD 0x00000010 /* Add function */
  84821. +#define SAFE_PK_FUNC_SUB 0x00000020 /* Subtract function */
  84822. +#define SAFE_PK_FUNC_LSHIFT 0x00000040 /* Left-shift function */
  84823. +#define SAFE_PK_FUNC_RSHIFT 0x00000080 /* Right-shift function */
  84824. +#define SAFE_PK_FUNC_DIV 0x00000100 /* Divide function */
  84825. +#define SAFE_PK_FUNC_CMP 0x00000400 /* Compare function */
  84826. +#define SAFE_PK_FUNC_COPY 0x00000800 /* Copy function */
  84827. +#define SAFE_PK_FUNC_EXP16 0x00002000 /* Exponentiate (4-bit ACT) */
  84828. +#define SAFE_PK_FUNC_EXP4 0x00004000 /* Exponentiate (2-bit ACT) */
  84829. +#define SAFE_PK_FUNC_RUN 0x00008000 /* start/status */
  84830. +
  84831. +#define SAFE_RNG_STAT_BUSY 0x00000001 /* busy, data not valid */
  84832. +
  84833. +#define SAFE_RNG_CTRL_PRE_LFSR 0x00000001 /* enable output pre-LFSR */
  84834. +#define SAFE_RNG_CTRL_TST_MODE 0x00000002 /* enable test mode */
  84835. +#define SAFE_RNG_CTRL_TST_RUN 0x00000004 /* start test state machine */
  84836. +#define SAFE_RNG_CTRL_ENA_RING1 0x00000008 /* test entropy oscillator #1 */
  84837. +#define SAFE_RNG_CTRL_ENA_RING2 0x00000010 /* test entropy oscillator #2 */
  84838. +#define SAFE_RNG_CTRL_DIS_ALARM 0x00000020 /* disable RNG alarm reports */
  84839. +#define SAFE_RNG_CTRL_TST_CLOCK 0x00000040 /* enable test clock */
  84840. +#define SAFE_RNG_CTRL_SHORTEN 0x00000080 /* shorten state timers */
  84841. +#define SAFE_RNG_CTRL_TST_ALARM 0x00000100 /* simulate alarm state */
  84842. +#define SAFE_RNG_CTRL_RST_LFSR 0x00000200 /* reset LFSR */
  84843. +
  84844. +/*
  84845. + * Packet engine descriptor. Note that d_csr is a copy of the
  84846. + * SAFE_PE_CSR register and all definitions apply, and d_len
  84847. + * is a copy of the SAFE_PE_LEN register and all definitions apply.
  84848. + * d_src and d_len may point directly to contiguous data or to a
  84849. + * list of ``particle descriptors'' when using scatter/gather i/o.
  84850. + */
  84851. +struct safe_desc {
  84852. + u_int32_t d_csr; /* per-packet control/status */
  84853. + u_int32_t d_src; /* source address */
  84854. + u_int32_t d_dst; /* destination address */
  84855. + u_int32_t d_sa; /* SA address */
  84856. + u_int32_t d_len; /* length, bypass, status */
  84857. +};
  84858. +
  84859. +/*
  84860. + * Scatter/Gather particle descriptor.
  84861. + *
  84862. + * NB: scatter descriptors do not specify a size; this is fixed
  84863. + * by the setting of the SAFE_PE_PARTCFG register.
  84864. + */
  84865. +struct safe_pdesc {
  84866. + u_int32_t pd_addr; /* particle address */
  84867. +#ifdef __BIG_ENDIAN
  84868. + u_int16_t pd_flags; /* control word */
  84869. + u_int16_t pd_size; /* particle size (bytes) */
  84870. +#else
  84871. + u_int16_t pd_flags; /* control word */
  84872. + u_int16_t pd_size; /* particle size (bytes) */
  84873. +#endif
  84874. +};
  84875. +
  84876. +#define SAFE_PD_READY 0x0001 /* ready for processing */
  84877. +#define SAFE_PD_DONE 0x0002 /* h/w completed processing */
  84878. +
  84879. +/*
  84880. + * Security Association (SA) Record (Rev 1). One of these is
  84881. + * required for each operation processed by the packet engine.
  84882. + */
  84883. +struct safe_sarec {
  84884. + u_int32_t sa_cmd0;
  84885. + u_int32_t sa_cmd1;
  84886. + u_int32_t sa_resv0;
  84887. + u_int32_t sa_resv1;
  84888. + u_int32_t sa_key[8]; /* DES/3DES/AES key */
  84889. + u_int32_t sa_indigest[5]; /* inner digest */
  84890. + u_int32_t sa_outdigest[5]; /* outer digest */
  84891. + u_int32_t sa_spi; /* SPI */
  84892. + u_int32_t sa_seqnum; /* sequence number */
  84893. + u_int32_t sa_seqmask[2]; /* sequence number mask */
  84894. + u_int32_t sa_resv2;
  84895. + u_int32_t sa_staterec; /* address of state record */
  84896. + u_int32_t sa_resv3[2];
  84897. + u_int32_t sa_samgmt0; /* SA management field 0 */
  84898. + u_int32_t sa_samgmt1; /* SA management field 0 */
  84899. +};
  84900. +
  84901. +#define SAFE_SA_CMD0_OP 0x00000007 /* operation code */
  84902. +#define SAFE_SA_CMD0_OP_CRYPT 0x00000000 /* encrypt/decrypt (basic) */
  84903. +#define SAFE_SA_CMD0_OP_BOTH 0x00000001 /* encrypt-hash/hash-decrypto */
  84904. +#define SAFE_SA_CMD0_OP_HASH 0x00000003 /* hash (outbound-only) */
  84905. +#define SAFE_SA_CMD0_OP_ESP 0x00000000 /* ESP in/out (proto) */
  84906. +#define SAFE_SA_CMD0_OP_AH 0x00000001 /* AH in/out (proto) */
  84907. +#define SAFE_SA_CMD0_INBOUND 0x00000008 /* inbound operation */
  84908. +#define SAFE_SA_CMD0_OUTBOUND 0x00000000 /* outbound operation */
  84909. +#define SAFE_SA_CMD0_GROUP 0x00000030 /* operation group */
  84910. +#define SAFE_SA_CMD0_BASIC 0x00000000 /* basic operation */
  84911. +#define SAFE_SA_CMD0_PROTO 0x00000010 /* protocol/packet operation */
  84912. +#define SAFE_SA_CMD0_BUNDLE 0x00000020 /* bundled operation (resvd) */
  84913. +#define SAFE_SA_CMD0_PAD 0x000000c0 /* crypto pad method */
  84914. +#define SAFE_SA_CMD0_PAD_IPSEC 0x00000000 /* IPsec padding */
  84915. +#define SAFE_SA_CMD0_PAD_PKCS7 0x00000040 /* PKCS#7 padding */
  84916. +#define SAFE_SA_CMD0_PAD_CONS 0x00000080 /* constant padding */
  84917. +#define SAFE_SA_CMD0_PAD_ZERO 0x000000c0 /* zero padding */
  84918. +#define SAFE_SA_CMD0_CRYPT_ALG 0x00000f00 /* symmetric crypto algorithm */
  84919. +#define SAFE_SA_CMD0_DES 0x00000000 /* DES crypto algorithm */
  84920. +#define SAFE_SA_CMD0_3DES 0x00000100 /* 3DES crypto algorithm */
  84921. +#define SAFE_SA_CMD0_AES 0x00000300 /* AES crypto algorithm */
  84922. +#define SAFE_SA_CMD0_CRYPT_NULL 0x00000f00 /* null crypto algorithm */
  84923. +#define SAFE_SA_CMD0_HASH_ALG 0x0000f000 /* hash algorithm */
  84924. +#define SAFE_SA_CMD0_MD5 0x00000000 /* MD5 hash algorithm */
  84925. +#define SAFE_SA_CMD0_SHA1 0x00001000 /* SHA-1 hash algorithm */
  84926. +#define SAFE_SA_CMD0_HASH_NULL 0x0000f000 /* null hash algorithm */
  84927. +#define SAFE_SA_CMD0_HDR_PROC 0x00080000 /* header processing */
  84928. +#define SAFE_SA_CMD0_IBUSID 0x00300000 /* input bus id */
  84929. +#define SAFE_SA_CMD0_IPCI 0x00100000 /* PCI input bus id */
  84930. +#define SAFE_SA_CMD0_OBUSID 0x00c00000 /* output bus id */
  84931. +#define SAFE_SA_CMD0_OPCI 0x00400000 /* PCI output bus id */
  84932. +#define SAFE_SA_CMD0_IVLD 0x03000000 /* IV loading */
  84933. +#define SAFE_SA_CMD0_IVLD_NONE 0x00000000 /* IV no load (reuse) */
  84934. +#define SAFE_SA_CMD0_IVLD_IBUF 0x01000000 /* IV load from input buffer */
  84935. +#define SAFE_SA_CMD0_IVLD_STATE 0x02000000 /* IV load from state */
  84936. +#define SAFE_SA_CMD0_HSLD 0x0c000000 /* hash state loading */
  84937. +#define SAFE_SA_CMD0_HSLD_SA 0x00000000 /* hash state load from SA */
  84938. +#define SAFE_SA_CMD0_HSLD_STATE 0x08000000 /* hash state load from state */
  84939. +#define SAFE_SA_CMD0_HSLD_NONE 0x0c000000 /* hash state no load */
  84940. +#define SAFE_SA_CMD0_SAVEIV 0x10000000 /* save IV */
  84941. +#define SAFE_SA_CMD0_SAVEHASH 0x20000000 /* save hash state */
  84942. +#define SAFE_SA_CMD0_IGATHER 0x40000000 /* input gather */
  84943. +#define SAFE_SA_CMD0_OSCATTER 0x80000000 /* output scatter */
  84944. +
  84945. +#define SAFE_SA_CMD1_HDRCOPY 0x00000002 /* copy header to output */
  84946. +#define SAFE_SA_CMD1_PAYCOPY 0x00000004 /* copy payload to output */
  84947. +#define SAFE_SA_CMD1_PADCOPY 0x00000008 /* copy pad to output */
  84948. +#define SAFE_SA_CMD1_IPV4 0x00000000 /* IPv4 protocol */
  84949. +#define SAFE_SA_CMD1_IPV6 0x00000010 /* IPv6 protocol */
  84950. +#define SAFE_SA_CMD1_MUTABLE 0x00000020 /* mutable bit processing */
  84951. +#define SAFE_SA_CMD1_SRBUSID 0x000000c0 /* state record bus id */
  84952. +#define SAFE_SA_CMD1_SRPCI 0x00000040 /* state record from PCI */
  84953. +#define SAFE_SA_CMD1_CRMODE 0x00000300 /* crypto mode */
  84954. +#define SAFE_SA_CMD1_ECB 0x00000000 /* ECB crypto mode */
  84955. +#define SAFE_SA_CMD1_CBC 0x00000100 /* CBC crypto mode */
  84956. +#define SAFE_SA_CMD1_OFB 0x00000200 /* OFB crypto mode */
  84957. +#define SAFE_SA_CMD1_CFB 0x00000300 /* CFB crypto mode */
  84958. +#define SAFE_SA_CMD1_CRFEEDBACK 0x00000c00 /* crypto feedback mode */
  84959. +#define SAFE_SA_CMD1_64BIT 0x00000000 /* 64-bit crypto feedback */
  84960. +#define SAFE_SA_CMD1_8BIT 0x00000400 /* 8-bit crypto feedback */
  84961. +#define SAFE_SA_CMD1_1BIT 0x00000800 /* 1-bit crypto feedback */
  84962. +#define SAFE_SA_CMD1_128BIT 0x00000c00 /* 128-bit crypto feedback */
  84963. +#define SAFE_SA_CMD1_OPTIONS 0x00001000 /* HMAC/options mutable bit */
  84964. +#define SAFE_SA_CMD1_HMAC SAFE_SA_CMD1_OPTIONS
  84965. +#define SAFE_SA_CMD1_SAREV1 0x00008000 /* SA Revision 1 */
  84966. +#define SAFE_SA_CMD1_OFFSET 0x00ff0000 /* hash/crypto offset(dwords) */
  84967. +#define SAFE_SA_CMD1_OFFSET_S 16
  84968. +#define SAFE_SA_CMD1_AESKEYLEN 0x0f000000 /* AES key length */
  84969. +#define SAFE_SA_CMD1_AES128 0x02000000 /* 128-bit AES key */
  84970. +#define SAFE_SA_CMD1_AES192 0x03000000 /* 192-bit AES key */
  84971. +#define SAFE_SA_CMD1_AES256 0x04000000 /* 256-bit AES key */
  84972. +
  84973. +/*
  84974. + * Security Associate State Record (Rev 1).
  84975. + */
  84976. +struct safe_sastate {
  84977. + u_int32_t sa_saved_iv[4]; /* saved IV (DES/3DES/AES) */
  84978. + u_int32_t sa_saved_hashbc; /* saved hash byte count */
  84979. + u_int32_t sa_saved_indigest[5]; /* saved inner digest */
  84980. +};
  84981. +#endif /* _SAFE_SAFEREG_H_ */
  84982. diff -Nur linux-2.6.35.orig/crypto/ocf/safe/safevar.h linux-2.6.35/crypto/ocf/safe/safevar.h
  84983. --- linux-2.6.35.orig/crypto/ocf/safe/safevar.h 1970-01-01 01:00:00.000000000 +0100
  84984. +++ linux-2.6.35/crypto/ocf/safe/safevar.h 2010-08-05 22:02:26.594867962 +0200
  84985. @@ -0,0 +1,230 @@
  84986. +/*-
  84987. + * The linux port of this code done by David McCullough
  84988. + * Copyright (C) 2004-2010 David McCullough <david_mccullough@mcafee.com>
  84989. + * The license and original author are listed below.
  84990. + *
  84991. + * Copyright (c) 2003 Sam Leffler, Errno Consulting
  84992. + * Copyright (c) 2003 Global Technology Associates, Inc.
  84993. + * All rights reserved.
  84994. + *
  84995. + * Redistribution and use in source and binary forms, with or without
  84996. + * modification, are permitted provided that the following conditions
  84997. + * are met:
  84998. + * 1. Redistributions of source code must retain the above copyright
  84999. + * notice, this list of conditions and the following disclaimer.
  85000. + * 2. Redistributions in binary form must reproduce the above copyright
  85001. + * notice, this list of conditions and the following disclaimer in the
  85002. + * documentation and/or other materials provided with the distribution.
  85003. + *
  85004. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  85005. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  85006. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  85007. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  85008. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  85009. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  85010. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  85011. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  85012. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  85013. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  85014. + * SUCH DAMAGE.
  85015. + *
  85016. + * $FreeBSD: src/sys/dev/safe/safevar.h,v 1.2 2006/05/17 18:34:26 pjd Exp $
  85017. + */
  85018. +#ifndef _SAFE_SAFEVAR_H_
  85019. +#define _SAFE_SAFEVAR_H_
  85020. +
  85021. +/* Maximum queue length */
  85022. +#ifndef SAFE_MAX_NQUEUE
  85023. +#define SAFE_MAX_NQUEUE 60
  85024. +#endif
  85025. +
  85026. +#define SAFE_MAX_PART 64 /* Maximum scatter/gather depth */
  85027. +#define SAFE_DMA_BOUNDARY 0 /* No boundary for source DMA ops */
  85028. +#define SAFE_MAX_DSIZE 2048 /* MCLBYTES Fixed scatter particle size */
  85029. +#define SAFE_MAX_SSIZE 0x0ffff /* Maximum gather particle size */
  85030. +#define SAFE_MAX_DMA 0xfffff /* Maximum PE operand size (20 bits) */
  85031. +/* total src+dst particle descriptors */
  85032. +#define SAFE_TOTAL_DPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART)
  85033. +#define SAFE_TOTAL_SPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART)
  85034. +
  85035. +#define SAFE_RNG_MAXBUFSIZ 128 /* 32-bit words */
  85036. +
  85037. +#define SAFE_CARD(sid) (((sid) & 0xf0000000) >> 28)
  85038. +#define SAFE_SESSION(sid) ( (sid) & 0x0fffffff)
  85039. +#define SAFE_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))
  85040. +
  85041. +#define SAFE_DEF_RTY 0xff /* PCI Retry Timeout */
  85042. +#define SAFE_DEF_TOUT 0xff /* PCI TRDY Timeout */
  85043. +#define SAFE_DEF_CACHELINE 0x01 /* Cache Line setting */
  85044. +
  85045. +#ifdef __KERNEL__
  85046. +/*
  85047. + * State associated with the allocation of each chunk
  85048. + * of memory setup for DMA.
  85049. + */
  85050. +struct safe_dma_alloc {
  85051. + dma_addr_t dma_paddr;
  85052. + void *dma_vaddr;
  85053. +};
  85054. +
  85055. +/*
  85056. + * Cryptographic operand state. One of these exists for each
  85057. + * source and destination operand passed in from the crypto
  85058. + * subsystem. When possible source and destination operands
  85059. + * refer to the same memory. More often they are distinct.
  85060. + * We track the virtual address of each operand as well as
  85061. + * where each is mapped for DMA.
  85062. + */
  85063. +struct safe_operand {
  85064. + union {
  85065. + struct sk_buff *skb;
  85066. + struct uio *io;
  85067. + } u;
  85068. + void *map;
  85069. + int mapsize; /* total number of bytes in segs */
  85070. + struct {
  85071. + dma_addr_t ds_addr;
  85072. + int ds_len;
  85073. + int ds_tlen;
  85074. + } segs[SAFE_MAX_PART];
  85075. + int nsegs;
  85076. +};
  85077. +
  85078. +/*
  85079. + * Packet engine ring entry and cryptographic operation state.
  85080. + * The packet engine requires a ring of descriptors that contain
  85081. + * pointers to various cryptographic state. However the ring
  85082. + * configuration register allows you to specify an arbitrary size
  85083. + * for ring entries. We use this feature to collect most of the
  85084. + * state for each cryptographic request into one spot. Other than
  85085. + * ring entries only the ``particle descriptors'' (scatter/gather
  85086. + * lists) and the actual operand data are kept separate. The
  85087. + * particle descriptors must also be organized in rings. The
  85088. + * operand data can be located aribtrarily (modulo alignment constraints).
  85089. + *
  85090. + * Note that the descriptor ring is mapped onto the PCI bus so
  85091. + * the hardware can DMA data. This means the entire ring must be
  85092. + * contiguous.
  85093. + */
  85094. +struct safe_ringentry {
  85095. + struct safe_desc re_desc; /* command descriptor */
  85096. + struct safe_sarec re_sa; /* SA record */
  85097. + struct safe_sastate re_sastate; /* SA state record */
  85098. +
  85099. + struct cryptop *re_crp; /* crypto operation */
  85100. +
  85101. + struct safe_operand re_src; /* source operand */
  85102. + struct safe_operand re_dst; /* destination operand */
  85103. +
  85104. + int re_sesn; /* crypto session ID */
  85105. + int re_flags;
  85106. +#define SAFE_QFLAGS_COPYOUTIV 0x1 /* copy back on completion */
  85107. +#define SAFE_QFLAGS_COPYOUTICV 0x2 /* copy back on completion */
  85108. +};
  85109. +
  85110. +#define re_src_skb re_src.u.skb
  85111. +#define re_src_io re_src.u.io
  85112. +#define re_src_map re_src.map
  85113. +#define re_src_nsegs re_src.nsegs
  85114. +#define re_src_segs re_src.segs
  85115. +#define re_src_mapsize re_src.mapsize
  85116. +
  85117. +#define re_dst_skb re_dst.u.skb
  85118. +#define re_dst_io re_dst.u.io
  85119. +#define re_dst_map re_dst.map
  85120. +#define re_dst_nsegs re_dst.nsegs
  85121. +#define re_dst_segs re_dst.segs
  85122. +#define re_dst_mapsize re_dst.mapsize
  85123. +
  85124. +struct rndstate_test;
  85125. +
  85126. +struct safe_session {
  85127. + u_int32_t ses_used;
  85128. + u_int32_t ses_klen; /* key length in bits */
  85129. + u_int32_t ses_key[8]; /* DES/3DES/AES key */
  85130. + u_int32_t ses_mlen; /* hmac length in bytes */
  85131. + u_int32_t ses_hminner[5]; /* hmac inner state */
  85132. + u_int32_t ses_hmouter[5]; /* hmac outer state */
  85133. + u_int32_t ses_iv[4]; /* DES/3DES/AES iv */
  85134. +};
  85135. +
  85136. +struct safe_pkq {
  85137. + struct list_head pkq_list;
  85138. + struct cryptkop *pkq_krp;
  85139. +};
  85140. +
  85141. +struct safe_softc {
  85142. + softc_device_decl sc_dev;
  85143. + u32 sc_irq;
  85144. +
  85145. + struct pci_dev *sc_pcidev;
  85146. + ocf_iomem_t sc_base_addr;
  85147. +
  85148. + u_int sc_chiprev; /* major/minor chip revision */
  85149. + int sc_flags; /* device specific flags */
  85150. +#define SAFE_FLAGS_KEY 0x01 /* has key accelerator */
  85151. +#define SAFE_FLAGS_RNG 0x02 /* hardware rng */
  85152. + int sc_suspended;
  85153. + int sc_needwakeup; /* notify crypto layer */
  85154. + int32_t sc_cid; /* crypto tag */
  85155. +
  85156. + struct safe_dma_alloc sc_ringalloc; /* PE ring allocation state */
  85157. + struct safe_ringentry *sc_ring; /* PE ring */
  85158. + struct safe_ringentry *sc_ringtop; /* PE ring top */
  85159. + struct safe_ringentry *sc_front; /* next free entry */
  85160. + struct safe_ringentry *sc_back; /* next pending entry */
  85161. + int sc_nqchip; /* # passed to chip */
  85162. + spinlock_t sc_ringmtx; /* PE ring lock */
  85163. + struct safe_pdesc *sc_spring; /* src particle ring */
  85164. + struct safe_pdesc *sc_springtop; /* src particle ring top */
  85165. + struct safe_pdesc *sc_spfree; /* next free src particle */
  85166. + struct safe_dma_alloc sc_spalloc; /* src particle ring state */
  85167. + struct safe_pdesc *sc_dpring; /* dest particle ring */
  85168. + struct safe_pdesc *sc_dpringtop; /* dest particle ring top */
  85169. + struct safe_pdesc *sc_dpfree; /* next free dest particle */
  85170. + struct safe_dma_alloc sc_dpalloc; /* dst particle ring state */
  85171. + int sc_nsessions; /* # of sessions */
  85172. + struct safe_session *sc_sessions; /* sessions */
  85173. +
  85174. + struct timer_list sc_pkto; /* PK polling */
  85175. + spinlock_t sc_pkmtx; /* PK lock */
  85176. + struct list_head sc_pkq; /* queue of PK requests */
  85177. + struct safe_pkq *sc_pkq_cur; /* current processing request */
  85178. + u_int32_t sc_pk_reslen, sc_pk_resoff;
  85179. +
  85180. + int sc_max_dsize; /* maximum safe DMA size */
  85181. +};
  85182. +#endif /* __KERNEL__ */
  85183. +
  85184. +struct safe_stats {
  85185. + u_int64_t st_ibytes;
  85186. + u_int64_t st_obytes;
  85187. + u_int32_t st_ipackets;
  85188. + u_int32_t st_opackets;
  85189. + u_int32_t st_invalid; /* invalid argument */
  85190. + u_int32_t st_badsession; /* invalid session id */
  85191. + u_int32_t st_badflags; /* flags indicate !(mbuf | uio) */
  85192. + u_int32_t st_nodesc; /* op submitted w/o descriptors */
  85193. + u_int32_t st_badalg; /* unsupported algorithm */
  85194. + u_int32_t st_ringfull; /* PE descriptor ring full */
  85195. + u_int32_t st_peoperr; /* PE marked error */
  85196. + u_int32_t st_dmaerr; /* PE DMA error */
  85197. + u_int32_t st_bypasstoobig; /* bypass > 96 bytes */
  85198. + u_int32_t st_skipmismatch; /* enc part begins before auth part */
  85199. + u_int32_t st_lenmismatch; /* enc length different auth length */
  85200. + u_int32_t st_coffmisaligned; /* crypto offset not 32-bit aligned */
  85201. + u_int32_t st_cofftoobig; /* crypto offset > 255 words */
  85202. + u_int32_t st_iovmisaligned; /* iov op not aligned */
  85203. + u_int32_t st_iovnotuniform; /* iov op not suitable */
  85204. + u_int32_t st_unaligned; /* unaligned src caused copy */
  85205. + u_int32_t st_notuniform; /* non-uniform src caused copy */
  85206. + u_int32_t st_nomap; /* bus_dmamap_create failed */
  85207. + u_int32_t st_noload; /* bus_dmamap_load_* failed */
  85208. + u_int32_t st_nombuf; /* MGET* failed */
  85209. + u_int32_t st_nomcl; /* MCLGET* failed */
  85210. + u_int32_t st_maxqchip; /* max mcr1 ops out for processing */
  85211. + u_int32_t st_rng; /* RNG requests */
  85212. + u_int32_t st_rngalarm; /* RNG alarm requests */
  85213. + u_int32_t st_noicvcopy; /* ICV data copies suppressed */
  85214. +};
  85215. +#endif /* _SAFE_SAFEVAR_H_ */
  85216. diff -Nur linux-2.6.35.orig/crypto/ocf/safe/sha1.c linux-2.6.35/crypto/ocf/safe/sha1.c
  85217. --- linux-2.6.35.orig/crypto/ocf/safe/sha1.c 1970-01-01 01:00:00.000000000 +0100
  85218. +++ linux-2.6.35/crypto/ocf/safe/sha1.c 2010-08-05 22:02:26.634868513 +0200
  85219. @@ -0,0 +1,279 @@
  85220. +/* $KAME: sha1.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
  85221. +/*
  85222. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  85223. + * All rights reserved.
  85224. + *
  85225. + * Redistribution and use in source and binary forms, with or without
  85226. + * modification, are permitted provided that the following conditions
  85227. + * are met:
  85228. + * 1. Redistributions of source code must retain the above copyright
  85229. + * notice, this list of conditions and the following disclaimer.
  85230. + * 2. Redistributions in binary form must reproduce the above copyright
  85231. + * notice, this list of conditions and the following disclaimer in the
  85232. + * documentation and/or other materials provided with the distribution.
  85233. + * 3. Neither the name of the project nor the names of its contributors
  85234. + * may be used to endorse or promote products derived from this software
  85235. + * without specific prior written permission.
  85236. + *
  85237. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  85238. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  85239. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  85240. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  85241. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  85242. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  85243. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  85244. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  85245. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  85246. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  85247. + * SUCH DAMAGE.
  85248. + */
  85249. +
  85250. +/*
  85251. + * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
  85252. + * based on: http://csrc.nist.gov/fips/fip180-1.txt
  85253. + * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
  85254. + */
  85255. +
  85256. +#if 0
  85257. +#include <sys/cdefs.h>
  85258. +__FBSDID("$FreeBSD: src/sys/crypto/sha1.c,v 1.9 2003/06/10 21:36:57 obrien Exp $");
  85259. +
  85260. +#include <sys/types.h>
  85261. +#include <sys/cdefs.h>
  85262. +#include <sys/time.h>
  85263. +#include <sys/systm.h>
  85264. +
  85265. +#include <crypto/sha1.h>
  85266. +#endif
  85267. +
  85268. +/* sanity check */
  85269. +#if BYTE_ORDER != BIG_ENDIAN
  85270. +# if BYTE_ORDER != LITTLE_ENDIAN
  85271. +# define unsupported 1
  85272. +# endif
  85273. +#endif
  85274. +
  85275. +#ifndef unsupported
  85276. +
  85277. +/* constant table */
  85278. +static u_int32_t _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
  85279. +#define K(t) _K[(t) / 20]
  85280. +
  85281. +#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
  85282. +#define F1(b, c, d) (((b) ^ (c)) ^ (d))
  85283. +#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
  85284. +#define F3(b, c, d) (((b) ^ (c)) ^ (d))
  85285. +
  85286. +#define S(n, x) (((x) << (n)) | ((x) >> (32 - n)))
  85287. +
  85288. +#undef H
  85289. +#define H(n) (ctxt->h.b32[(n)])
  85290. +#define COUNT (ctxt->count)
  85291. +#define BCOUNT (ctxt->c.b64[0] / 8)
  85292. +#define W(n) (ctxt->m.b32[(n)])
  85293. +
  85294. +#define PUTBYTE(x) { \
  85295. + ctxt->m.b8[(COUNT % 64)] = (x); \
  85296. + COUNT++; \
  85297. + COUNT %= 64; \
  85298. + ctxt->c.b64[0] += 8; \
  85299. + if (COUNT % 64 == 0) \
  85300. + sha1_step(ctxt); \
  85301. + }
  85302. +
  85303. +#define PUTPAD(x) { \
  85304. + ctxt->m.b8[(COUNT % 64)] = (x); \
  85305. + COUNT++; \
  85306. + COUNT %= 64; \
  85307. + if (COUNT % 64 == 0) \
  85308. + sha1_step(ctxt); \
  85309. + }
  85310. +
  85311. +static void sha1_step(struct sha1_ctxt *);
  85312. +
  85313. +static void
  85314. +sha1_step(ctxt)
  85315. + struct sha1_ctxt *ctxt;
  85316. +{
  85317. + u_int32_t a, b, c, d, e;
  85318. + size_t t, s;
  85319. + u_int32_t tmp;
  85320. +
  85321. +#if BYTE_ORDER == LITTLE_ENDIAN
  85322. + struct sha1_ctxt tctxt;
  85323. + bcopy(&ctxt->m.b8[0], &tctxt.m.b8[0], 64);
  85324. + ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2];
  85325. + ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0];
  85326. + ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6];
  85327. + ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4];
  85328. + ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10];
  85329. + ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8];
  85330. + ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14];
  85331. + ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12];
  85332. + ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18];
  85333. + ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16];
  85334. + ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22];
  85335. + ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20];
  85336. + ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26];
  85337. + ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24];
  85338. + ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30];
  85339. + ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28];
  85340. + ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34];
  85341. + ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32];
  85342. + ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38];
  85343. + ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36];
  85344. + ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42];
  85345. + ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40];
  85346. + ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46];
  85347. + ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44];
  85348. + ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50];
  85349. + ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48];
  85350. + ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54];
  85351. + ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52];
  85352. + ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58];
  85353. + ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56];
  85354. + ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62];
  85355. + ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60];
  85356. +#endif
  85357. +
  85358. + a = H(0); b = H(1); c = H(2); d = H(3); e = H(4);
  85359. +
  85360. + for (t = 0; t < 20; t++) {
  85361. + s = t & 0x0f;
  85362. + if (t >= 16) {
  85363. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  85364. + }
  85365. + tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
  85366. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  85367. + }
  85368. + for (t = 20; t < 40; t++) {
  85369. + s = t & 0x0f;
  85370. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  85371. + tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
  85372. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  85373. + }
  85374. + for (t = 40; t < 60; t++) {
  85375. + s = t & 0x0f;
  85376. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  85377. + tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
  85378. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  85379. + }
  85380. + for (t = 60; t < 80; t++) {
  85381. + s = t & 0x0f;
  85382. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  85383. + tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
  85384. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  85385. + }
  85386. +
  85387. + H(0) = H(0) + a;
  85388. + H(1) = H(1) + b;
  85389. + H(2) = H(2) + c;
  85390. + H(3) = H(3) + d;
  85391. + H(4) = H(4) + e;
  85392. +
  85393. + bzero(&ctxt->m.b8[0], 64);
  85394. +}
  85395. +
  85396. +/*------------------------------------------------------------*/
  85397. +
  85398. +void
  85399. +sha1_init(ctxt)
  85400. + struct sha1_ctxt *ctxt;
  85401. +{
  85402. + bzero(ctxt, sizeof(struct sha1_ctxt));
  85403. + H(0) = 0x67452301;
  85404. + H(1) = 0xefcdab89;
  85405. + H(2) = 0x98badcfe;
  85406. + H(3) = 0x10325476;
  85407. + H(4) = 0xc3d2e1f0;
  85408. +}
  85409. +
  85410. +void
  85411. +sha1_pad(ctxt)
  85412. + struct sha1_ctxt *ctxt;
  85413. +{
  85414. + size_t padlen; /*pad length in bytes*/
  85415. + size_t padstart;
  85416. +
  85417. + PUTPAD(0x80);
  85418. +
  85419. + padstart = COUNT % 64;
  85420. + padlen = 64 - padstart;
  85421. + if (padlen < 8) {
  85422. + bzero(&ctxt->m.b8[padstart], padlen);
  85423. + COUNT += padlen;
  85424. + COUNT %= 64;
  85425. + sha1_step(ctxt);
  85426. + padstart = COUNT % 64; /* should be 0 */
  85427. + padlen = 64 - padstart; /* should be 64 */
  85428. + }
  85429. + bzero(&ctxt->m.b8[padstart], padlen - 8);
  85430. + COUNT += (padlen - 8);
  85431. + COUNT %= 64;
  85432. +#if BYTE_ORDER == BIG_ENDIAN
  85433. + PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]);
  85434. + PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]);
  85435. + PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]);
  85436. + PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]);
  85437. +#else
  85438. + PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]);
  85439. + PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]);
  85440. + PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]);
  85441. + PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]);
  85442. +#endif
  85443. +}
  85444. +
  85445. +void
  85446. +sha1_loop(ctxt, input, len)
  85447. + struct sha1_ctxt *ctxt;
  85448. + const u_int8_t *input;
  85449. + size_t len;
  85450. +{
  85451. + size_t gaplen;
  85452. + size_t gapstart;
  85453. + size_t off;
  85454. + size_t copysiz;
  85455. +
  85456. + off = 0;
  85457. +
  85458. + while (off < len) {
  85459. + gapstart = COUNT % 64;
  85460. + gaplen = 64 - gapstart;
  85461. +
  85462. + copysiz = (gaplen < len - off) ? gaplen : len - off;
  85463. + bcopy(&input[off], &ctxt->m.b8[gapstart], copysiz);
  85464. + COUNT += copysiz;
  85465. + COUNT %= 64;
  85466. + ctxt->c.b64[0] += copysiz * 8;
  85467. + if (COUNT % 64 == 0)
  85468. + sha1_step(ctxt);
  85469. + off += copysiz;
  85470. + }
  85471. +}
  85472. +
  85473. +void
  85474. +sha1_result(ctxt, digest0)
  85475. + struct sha1_ctxt *ctxt;
  85476. + caddr_t digest0;
  85477. +{
  85478. + u_int8_t *digest;
  85479. +
  85480. + digest = (u_int8_t *)digest0;
  85481. + sha1_pad(ctxt);
  85482. +#if BYTE_ORDER == BIG_ENDIAN
  85483. + bcopy(&ctxt->h.b8[0], digest, 20);
  85484. +#else
  85485. + digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2];
  85486. + digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0];
  85487. + digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6];
  85488. + digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4];
  85489. + digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10];
  85490. + digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8];
  85491. + digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14];
  85492. + digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12];
  85493. + digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18];
  85494. + digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16];
  85495. +#endif
  85496. +}
  85497. +
  85498. +#endif /*unsupported*/
  85499. diff -Nur linux-2.6.35.orig/crypto/ocf/safe/sha1.h linux-2.6.35/crypto/ocf/safe/sha1.h
  85500. --- linux-2.6.35.orig/crypto/ocf/safe/sha1.h 1970-01-01 01:00:00.000000000 +0100
  85501. +++ linux-2.6.35/crypto/ocf/safe/sha1.h 2010-08-05 22:02:26.674868320 +0200
  85502. @@ -0,0 +1,72 @@
  85503. +/* $FreeBSD: src/sys/crypto/sha1.h,v 1.8 2002/03/20 05:13:50 alfred Exp $ */
  85504. +/* $KAME: sha1.h,v 1.5 2000/03/27 04:36:23 sumikawa Exp $ */
  85505. +
  85506. +/*
  85507. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  85508. + * All rights reserved.
  85509. + *
  85510. + * Redistribution and use in source and binary forms, with or without
  85511. + * modification, are permitted provided that the following conditions
  85512. + * are met:
  85513. + * 1. Redistributions of source code must retain the above copyright
  85514. + * notice, this list of conditions and the following disclaimer.
  85515. + * 2. Redistributions in binary form must reproduce the above copyright
  85516. + * notice, this list of conditions and the following disclaimer in the
  85517. + * documentation and/or other materials provided with the distribution.
  85518. + * 3. Neither the name of the project nor the names of its contributors
  85519. + * may be used to endorse or promote products derived from this software
  85520. + * without specific prior written permission.
  85521. + *
  85522. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  85523. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  85524. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  85525. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  85526. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  85527. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  85528. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  85529. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  85530. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  85531. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  85532. + * SUCH DAMAGE.
  85533. + */
  85534. +/*
  85535. + * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
  85536. + * based on: http://csrc.nist.gov/fips/fip180-1.txt
  85537. + * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
  85538. + */
  85539. +
  85540. +#ifndef _NETINET6_SHA1_H_
  85541. +#define _NETINET6_SHA1_H_
  85542. +
  85543. +struct sha1_ctxt {
  85544. + union {
  85545. + u_int8_t b8[20];
  85546. + u_int32_t b32[5];
  85547. + } h;
  85548. + union {
  85549. + u_int8_t b8[8];
  85550. + u_int64_t b64[1];
  85551. + } c;
  85552. + union {
  85553. + u_int8_t b8[64];
  85554. + u_int32_t b32[16];
  85555. + } m;
  85556. + u_int8_t count;
  85557. +};
  85558. +
  85559. +#ifdef __KERNEL__
  85560. +extern void sha1_init(struct sha1_ctxt *);
  85561. +extern void sha1_pad(struct sha1_ctxt *);
  85562. +extern void sha1_loop(struct sha1_ctxt *, const u_int8_t *, size_t);
  85563. +extern void sha1_result(struct sha1_ctxt *, caddr_t);
  85564. +
  85565. +/* compatibilty with other SHA1 source codes */
  85566. +typedef struct sha1_ctxt SHA1_CTX;
  85567. +#define SHA1Init(x) sha1_init((x))
  85568. +#define SHA1Update(x, y, z) sha1_loop((x), (y), (z))
  85569. +#define SHA1Final(x, y) sha1_result((y), (x))
  85570. +#endif /* __KERNEL__ */
  85571. +
  85572. +#define SHA1_RESULTLEN (160/8)
  85573. +
  85574. +#endif /*_NETINET6_SHA1_H_*/
  85575. diff -Nur linux-2.6.35.orig/crypto/ocf/talitos/Makefile linux-2.6.35/crypto/ocf/talitos/Makefile
  85576. --- linux-2.6.35.orig/crypto/ocf/talitos/Makefile 1970-01-01 01:00:00.000000000 +0100
  85577. +++ linux-2.6.35/crypto/ocf/talitos/Makefile 2010-08-05 22:02:26.713655979 +0200
  85578. @@ -0,0 +1,12 @@
  85579. +# for SGlinux builds
  85580. +-include $(ROOTDIR)/modules/.config
  85581. +
  85582. +obj-$(CONFIG_OCF_TALITOS) += talitos.o
  85583. +
  85584. +obj ?= .
  85585. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  85586. +
  85587. +ifdef TOPDIR
  85588. +-include $(TOPDIR)/Rules.make
  85589. +endif
  85590. +
  85591. diff -Nur linux-2.6.35.orig/crypto/ocf/talitos/talitos.c linux-2.6.35/crypto/ocf/talitos/talitos.c
  85592. --- linux-2.6.35.orig/crypto/ocf/talitos/talitos.c 1970-01-01 01:00:00.000000000 +0100
  85593. +++ linux-2.6.35/crypto/ocf/talitos/talitos.c 2010-08-05 22:02:26.753643795 +0200
  85594. @@ -0,0 +1,1359 @@
  85595. +/*
  85596. + * crypto/ocf/talitos/talitos.c
  85597. + *
  85598. + * An OCF-Linux module that uses Freescale's SEC to do the crypto.
  85599. + * Based on crypto/ocf/hifn and crypto/ocf/safe OCF drivers
  85600. + *
  85601. + * Copyright (c) 2006 Freescale Semiconductor, Inc.
  85602. + *
  85603. + * This code written by Kim A. B. Phillips <kim.phillips@freescale.com>
  85604. + * some code copied from files with the following:
  85605. + * Copyright (C) 2004-2007 David McCullough <david_mccullough@mcafee.com>
  85606. + *
  85607. + * Redistribution and use in source and binary forms, with or without
  85608. + * modification, are permitted provided that the following conditions
  85609. + * are met:
  85610. + *
  85611. + * 1. Redistributions of source code must retain the above copyright
  85612. + * notice, this list of conditions and the following disclaimer.
  85613. + * 2. Redistributions in binary form must reproduce the above copyright
  85614. + * notice, this list of conditions and the following disclaimer in the
  85615. + * documentation and/or other materials provided with the distribution.
  85616. + * 3. The name of the author may not be used to endorse or promote products
  85617. + * derived from this software without specific prior written permission.
  85618. + *
  85619. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  85620. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  85621. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  85622. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  85623. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  85624. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  85625. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  85626. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  85627. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  85628. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  85629. + *
  85630. + * ---------------------------------------------------------------------------
  85631. + *
  85632. + * NOTES:
  85633. + *
  85634. + * The Freescale SEC (also known as 'talitos') resides on the
  85635. + * internal bus, and runs asynchronous to the processor core. It has
  85636. + * a wide gamut of cryptographic acceleration features, including single-
  85637. + * pass IPsec (also known as algorithm chaining). To properly utilize
  85638. + * all of the SEC's performance enhancing features, further reworking
  85639. + * of higher level code (framework, applications) will be necessary.
  85640. + *
  85641. + * The following table shows which SEC version is present in which devices:
  85642. + *
  85643. + * Devices SEC version
  85644. + *
  85645. + * 8272, 8248 SEC 1.0
  85646. + * 885, 875 SEC 1.2
  85647. + * 8555E, 8541E SEC 2.0
  85648. + * 8349E SEC 2.01
  85649. + * 8548E SEC 2.1
  85650. + *
  85651. + * The following table shows the features offered by each SEC version:
  85652. + *
  85653. + * Max. chan-
  85654. + * version Bus I/F Clock nels DEU AESU AFEU MDEU PKEU RNG KEU
  85655. + *
  85656. + * SEC 1.0 internal 64b 100MHz 4 1 1 1 1 1 1 0
  85657. + * SEC 1.2 internal 32b 66MHz 1 1 1 0 1 0 0 0
  85658. + * SEC 2.0 internal 64b 166MHz 4 1 1 1 1 1 1 0
  85659. + * SEC 2.01 internal 64b 166MHz 4 1 1 1 1 1 1 0
  85660. + * SEC 2.1 internal 64b 333MHz 4 1 1 1 1 1 1 1
  85661. + *
  85662. + * Each execution unit in the SEC has two modes of execution; channel and
  85663. + * slave/debug. This driver employs the channel infrastructure in the
  85664. + * device for convenience. Only the RNG is directly accessed due to the
  85665. + * convenience of its random fifo pool. The relationship between the
  85666. + * channels and execution units is depicted in the following diagram:
  85667. + *
  85668. + * ------- ------------
  85669. + * ---| ch0 |---| |
  85670. + * ------- | |
  85671. + * | |------+-------+-------+-------+------------
  85672. + * ------- | | | | | | |
  85673. + * ---| ch1 |---| | | | | | |
  85674. + * ------- | | ------ ------ ------ ------ ------
  85675. + * |controller| |DEU | |AESU| |MDEU| |PKEU| ... |RNG |
  85676. + * ------- | | ------ ------ ------ ------ ------
  85677. + * ---| ch2 |---| | | | | | |
  85678. + * ------- | | | | | | |
  85679. + * | |------+-------+-------+-------+------------
  85680. + * ------- | |
  85681. + * ---| ch3 |---| |
  85682. + * ------- ------------
  85683. + *
  85684. + * Channel ch0 may drive an aes operation to the aes unit (AESU),
  85685. + * and, at the same time, ch1 may drive a message digest operation
  85686. + * to the mdeu. Each channel has an input descriptor FIFO, and the
  85687. + * FIFO can contain, e.g. on the 8541E, up to 24 entries, before a
  85688. + * a buffer overrun error is triggered. The controller is responsible
  85689. + * for fetching the data from descriptor pointers, and passing the
  85690. + * data to the appropriate EUs. The controller also writes the
  85691. + * cryptographic operation's result to memory. The SEC notifies
  85692. + * completion by triggering an interrupt and/or setting the 1st byte
  85693. + * of the hdr field to 0xff.
  85694. + *
  85695. + * TODO:
  85696. + * o support more algorithms
  85697. + * o support more versions of the SEC
  85698. + * o add support for linux 2.4
  85699. + * o scatter-gather (sg) support
  85700. + * o add support for public key ops (PKEU)
  85701. + * o add statistics
  85702. + */
  85703. +
  85704. +#ifndef AUTOCONF_INCLUDED
  85705. +#include <linux/config.h>
  85706. +#endif
  85707. +#include <linux/module.h>
  85708. +#include <linux/init.h>
  85709. +#include <linux/interrupt.h>
  85710. +#include <linux/spinlock.h>
  85711. +#include <linux/random.h>
  85712. +#include <linux/skbuff.h>
  85713. +#include <asm/scatterlist.h>
  85714. +#include <linux/dma-mapping.h> /* dma_map_single() */
  85715. +#include <linux/moduleparam.h>
  85716. +
  85717. +#include <linux/version.h>
  85718. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
  85719. +#include <linux/platform_device.h>
  85720. +#endif
  85721. +
  85722. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  85723. +#include <linux/of_platform.h>
  85724. +#endif
  85725. +
  85726. +#include <cryptodev.h>
  85727. +#include <uio.h>
  85728. +
  85729. +#define DRV_NAME "talitos"
  85730. +
  85731. +#include "talitos_dev.h"
  85732. +#include "talitos_soft.h"
  85733. +
  85734. +#define read_random(p,l) get_random_bytes(p,l)
  85735. +
  85736. +const char talitos_driver_name[] = "Talitos OCF";
  85737. +const char talitos_driver_version[] = "0.2";
  85738. +
  85739. +static int talitos_newsession(device_t dev, u_int32_t *sidp,
  85740. + struct cryptoini *cri);
  85741. +static int talitos_freesession(device_t dev, u_int64_t tid);
  85742. +static int talitos_process(device_t dev, struct cryptop *crp, int hint);
  85743. +static void dump_talitos_status(struct talitos_softc *sc);
  85744. +static int talitos_submit(struct talitos_softc *sc, struct talitos_desc *td,
  85745. + int chsel);
  85746. +static void talitos_doneprocessing(struct talitos_softc *sc);
  85747. +static void talitos_init_device(struct talitos_softc *sc);
  85748. +static void talitos_reset_device_master(struct talitos_softc *sc);
  85749. +static void talitos_reset_device(struct talitos_softc *sc);
  85750. +static void talitos_errorprocessing(struct talitos_softc *sc);
  85751. +#ifdef CONFIG_PPC_MERGE
  85752. +static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match);
  85753. +static int talitos_remove(struct of_device *ofdev);
  85754. +#else
  85755. +static int talitos_probe(struct platform_device *pdev);
  85756. +static int talitos_remove(struct platform_device *pdev);
  85757. +#endif
  85758. +#ifdef CONFIG_OCF_RANDOMHARVEST
  85759. +static int talitos_read_random(void *arg, u_int32_t *buf, int maxwords);
  85760. +static void talitos_rng_init(struct talitos_softc *sc);
  85761. +#endif
  85762. +
  85763. +static device_method_t talitos_methods = {
  85764. + /* crypto device methods */
  85765. + DEVMETHOD(cryptodev_newsession, talitos_newsession),
  85766. + DEVMETHOD(cryptodev_freesession,talitos_freesession),
  85767. + DEVMETHOD(cryptodev_process, talitos_process),
  85768. +};
  85769. +
  85770. +#define debug talitos_debug
  85771. +int talitos_debug = 0;
  85772. +module_param(talitos_debug, int, 0644);
  85773. +MODULE_PARM_DESC(talitos_debug, "Enable debug");
  85774. +
  85775. +static inline void talitos_write(volatile unsigned *addr, u32 val)
  85776. +{
  85777. + out_be32(addr, val);
  85778. +}
  85779. +
  85780. +static inline u32 talitos_read(volatile unsigned *addr)
  85781. +{
  85782. + u32 val;
  85783. + val = in_be32(addr);
  85784. + return val;
  85785. +}
  85786. +
  85787. +static void dump_talitos_status(struct talitos_softc *sc)
  85788. +{
  85789. + unsigned int v, v_hi, i, *ptr;
  85790. + v = talitos_read(sc->sc_base_addr + TALITOS_MCR);
  85791. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_MCR_HI);
  85792. + printk(KERN_INFO "%s: MCR 0x%08x_%08x\n",
  85793. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  85794. + v = talitos_read(sc->sc_base_addr + TALITOS_IMR);
  85795. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);
  85796. + printk(KERN_INFO "%s: IMR 0x%08x_%08x\n",
  85797. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  85798. + v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
  85799. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
  85800. + printk(KERN_INFO "%s: ISR 0x%08x_%08x\n",
  85801. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  85802. + for (i = 0; i < sc->sc_num_channels; i++) {
  85803. + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  85804. + TALITOS_CH_CDPR);
  85805. + v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  85806. + TALITOS_CH_CDPR_HI);
  85807. + printk(KERN_INFO "%s: CDPR ch%d 0x%08x_%08x\n",
  85808. + device_get_nameunit(sc->sc_cdev), i, v, v_hi);
  85809. + }
  85810. + for (i = 0; i < sc->sc_num_channels; i++) {
  85811. + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  85812. + TALITOS_CH_CCPSR);
  85813. + v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  85814. + TALITOS_CH_CCPSR_HI);
  85815. + printk(KERN_INFO "%s: CCPSR ch%d 0x%08x_%08x\n",
  85816. + device_get_nameunit(sc->sc_cdev), i, v, v_hi);
  85817. + }
  85818. + ptr = sc->sc_base_addr + TALITOS_CH_DESCBUF;
  85819. + for (i = 0; i < 16; i++) {
  85820. + v = talitos_read(ptr++); v_hi = talitos_read(ptr++);
  85821. + printk(KERN_INFO "%s: DESCBUF ch0 0x%08x_%08x (tdp%02d)\n",
  85822. + device_get_nameunit(sc->sc_cdev), v, v_hi, i);
  85823. + }
  85824. + return;
  85825. +}
  85826. +
  85827. +
  85828. +#ifdef CONFIG_OCF_RANDOMHARVEST
  85829. +/*
  85830. + * pull random numbers off the RNG FIFO, not exceeding amount available
  85831. + */
  85832. +static int
  85833. +talitos_read_random(void *arg, u_int32_t *buf, int maxwords)
  85834. +{
  85835. + struct talitos_softc *sc = (struct talitos_softc *) arg;
  85836. + int rc;
  85837. + u_int32_t v;
  85838. +
  85839. + DPRINTF("%s()\n", __FUNCTION__);
  85840. +
  85841. + /* check for things like FIFO underflow */
  85842. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
  85843. + if (unlikely(v)) {
  85844. + printk(KERN_ERR "%s: RNGISR_HI error %08x\n",
  85845. + device_get_nameunit(sc->sc_cdev), v);
  85846. + return 0;
  85847. + }
  85848. + /*
  85849. + * OFL is number of available 64-bit words,
  85850. + * shift and convert to a 32-bit word count
  85851. + */
  85852. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI);
  85853. + v = (v & TALITOS_RNGSR_HI_OFL) >> (16 - 1);
  85854. + if (maxwords > v)
  85855. + maxwords = v;
  85856. + for (rc = 0; rc < maxwords; rc++) {
  85857. + buf[rc] = talitos_read(sc->sc_base_addr +
  85858. + TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
  85859. + }
  85860. + if (maxwords & 1) {
  85861. + /*
  85862. + * RNG will complain with an AE in the RNGISR
  85863. + * if we don't complete the pairs of 32-bit reads
  85864. + * to its 64-bit register based FIFO
  85865. + */
  85866. + v = talitos_read(sc->sc_base_addr +
  85867. + TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
  85868. + }
  85869. +
  85870. + return rc;
  85871. +}
  85872. +
  85873. +static void
  85874. +talitos_rng_init(struct talitos_softc *sc)
  85875. +{
  85876. + u_int32_t v;
  85877. +
  85878. + DPRINTF("%s()\n", __FUNCTION__);
  85879. + /* reset RNG EU */
  85880. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGRCR_HI);
  85881. + v |= TALITOS_RNGRCR_HI_SR;
  85882. + talitos_write(sc->sc_base_addr + TALITOS_RNGRCR_HI, v);
  85883. + while ((talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI)
  85884. + & TALITOS_RNGSR_HI_RD) == 0)
  85885. + cpu_relax();
  85886. + /*
  85887. + * we tell the RNG to start filling the RNG FIFO
  85888. + * by writing the RNGDSR
  85889. + */
  85890. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGDSR_HI);
  85891. + talitos_write(sc->sc_base_addr + TALITOS_RNGDSR_HI, v);
  85892. + /*
  85893. + * 64 bits of data will be pushed onto the FIFO every
  85894. + * 256 SEC cycles until the FIFO is full. The RNG then
  85895. + * attempts to keep the FIFO full.
  85896. + */
  85897. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
  85898. + if (v) {
  85899. + printk(KERN_ERR "%s: RNGISR_HI error %08x\n",
  85900. + device_get_nameunit(sc->sc_cdev), v);
  85901. + return;
  85902. + }
  85903. + /*
  85904. + * n.b. we need to add a FIPS test here - if the RNG is going
  85905. + * to fail, it's going to fail at reset time
  85906. + */
  85907. + return;
  85908. +}
  85909. +#endif /* CONFIG_OCF_RANDOMHARVEST */
  85910. +
  85911. +/*
  85912. + * Generate a new software session.
  85913. + */
  85914. +static int
  85915. +talitos_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  85916. +{
  85917. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  85918. + struct talitos_softc *sc = device_get_softc(dev);
  85919. + struct talitos_session *ses = NULL;
  85920. + int sesn;
  85921. +
  85922. + DPRINTF("%s()\n", __FUNCTION__);
  85923. + if (sidp == NULL || cri == NULL || sc == NULL) {
  85924. + DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);
  85925. + return EINVAL;
  85926. + }
  85927. + for (c = cri; c != NULL; c = c->cri_next) {
  85928. + if (c->cri_alg == CRYPTO_MD5 ||
  85929. + c->cri_alg == CRYPTO_MD5_HMAC ||
  85930. + c->cri_alg == CRYPTO_SHA1 ||
  85931. + c->cri_alg == CRYPTO_SHA1_HMAC ||
  85932. + c->cri_alg == CRYPTO_NULL_HMAC) {
  85933. + if (macini)
  85934. + return EINVAL;
  85935. + macini = c;
  85936. + } else if (c->cri_alg == CRYPTO_DES_CBC ||
  85937. + c->cri_alg == CRYPTO_3DES_CBC ||
  85938. + c->cri_alg == CRYPTO_AES_CBC ||
  85939. + c->cri_alg == CRYPTO_NULL_CBC) {
  85940. + if (encini)
  85941. + return EINVAL;
  85942. + encini = c;
  85943. + } else {
  85944. + DPRINTF("UNKNOWN c->cri_alg %d\n", encini->cri_alg);
  85945. + return EINVAL;
  85946. + }
  85947. + }
  85948. + if (encini == NULL && macini == NULL)
  85949. + return EINVAL;
  85950. + if (encini) {
  85951. + /* validate key length */
  85952. + switch (encini->cri_alg) {
  85953. + case CRYPTO_DES_CBC:
  85954. + if (encini->cri_klen != 64)
  85955. + return EINVAL;
  85956. + break;
  85957. + case CRYPTO_3DES_CBC:
  85958. + if (encini->cri_klen != 192) {
  85959. + return EINVAL;
  85960. + }
  85961. + break;
  85962. + case CRYPTO_AES_CBC:
  85963. + if (encini->cri_klen != 128 &&
  85964. + encini->cri_klen != 192 &&
  85965. + encini->cri_klen != 256)
  85966. + return EINVAL;
  85967. + break;
  85968. + default:
  85969. + DPRINTF("UNKNOWN encini->cri_alg %d\n",
  85970. + encini->cri_alg);
  85971. + return EINVAL;
  85972. + }
  85973. + }
  85974. +
  85975. + if (sc->sc_sessions == NULL) {
  85976. + ses = sc->sc_sessions = (struct talitos_session *)
  85977. + kmalloc(sizeof(struct talitos_session), SLAB_ATOMIC);
  85978. + if (ses == NULL)
  85979. + return ENOMEM;
  85980. + memset(ses, 0, sizeof(struct talitos_session));
  85981. + sesn = 0;
  85982. + sc->sc_nsessions = 1;
  85983. + } else {
  85984. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  85985. + if (sc->sc_sessions[sesn].ses_used == 0) {
  85986. + ses = &sc->sc_sessions[sesn];
  85987. + break;
  85988. + }
  85989. + }
  85990. +
  85991. + if (ses == NULL) {
  85992. + /* allocating session */
  85993. + sesn = sc->sc_nsessions;
  85994. + ses = (struct talitos_session *) kmalloc(
  85995. + (sesn + 1) * sizeof(struct talitos_session),
  85996. + SLAB_ATOMIC);
  85997. + if (ses == NULL)
  85998. + return ENOMEM;
  85999. + memset(ses, 0,
  86000. + (sesn + 1) * sizeof(struct talitos_session));
  86001. + memcpy(ses, sc->sc_sessions,
  86002. + sesn * sizeof(struct talitos_session));
  86003. + memset(sc->sc_sessions, 0,
  86004. + sesn * sizeof(struct talitos_session));
  86005. + kfree(sc->sc_sessions);
  86006. + sc->sc_sessions = ses;
  86007. + ses = &sc->sc_sessions[sesn];
  86008. + sc->sc_nsessions++;
  86009. + }
  86010. + }
  86011. +
  86012. + ses->ses_used = 1;
  86013. +
  86014. + if (encini) {
  86015. + /* get an IV */
  86016. + /* XXX may read fewer than requested */
  86017. + read_random(ses->ses_iv, sizeof(ses->ses_iv));
  86018. +
  86019. + ses->ses_klen = (encini->cri_klen + 7) / 8;
  86020. + memcpy(ses->ses_key, encini->cri_key, ses->ses_klen);
  86021. + if (macini) {
  86022. + /* doing hash on top of cipher */
  86023. + ses->ses_hmac_len = (macini->cri_klen + 7) / 8;
  86024. + memcpy(ses->ses_hmac, macini->cri_key,
  86025. + ses->ses_hmac_len);
  86026. + }
  86027. + } else if (macini) {
  86028. + /* doing hash */
  86029. + ses->ses_klen = (macini->cri_klen + 7) / 8;
  86030. + memcpy(ses->ses_key, macini->cri_key, ses->ses_klen);
  86031. + }
  86032. +
  86033. + /* back compat way of determining MSC result len */
  86034. + if (macini) {
  86035. + ses->ses_mlen = macini->cri_mlen;
  86036. + if (ses->ses_mlen == 0) {
  86037. + if (macini->cri_alg == CRYPTO_MD5_HMAC)
  86038. + ses->ses_mlen = MD5_HASH_LEN;
  86039. + else
  86040. + ses->ses_mlen = SHA1_HASH_LEN;
  86041. + }
  86042. + }
  86043. +
  86044. + /* really should make up a template td here,
  86045. + * and only fill things like i/o and direction in process() */
  86046. +
  86047. + /* assign session ID */
  86048. + *sidp = TALITOS_SID(sc->sc_num, sesn);
  86049. + return 0;
  86050. +}
  86051. +
  86052. +/*
  86053. + * Deallocate a session.
  86054. + */
  86055. +static int
  86056. +talitos_freesession(device_t dev, u_int64_t tid)
  86057. +{
  86058. + struct talitos_softc *sc = device_get_softc(dev);
  86059. + int session, ret;
  86060. + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
  86061. +
  86062. + if (sc == NULL)
  86063. + return EINVAL;
  86064. + session = TALITOS_SESSION(sid);
  86065. + if (session < sc->sc_nsessions) {
  86066. + memset(&sc->sc_sessions[session], 0,
  86067. + sizeof(sc->sc_sessions[session]));
  86068. + ret = 0;
  86069. + } else
  86070. + ret = EINVAL;
  86071. + return ret;
  86072. +}
  86073. +
  86074. +/*
  86075. + * launch device processing - it will come back with done notification
  86076. + * in the form of an interrupt and/or HDR_DONE_BITS in header
  86077. + */
  86078. +static int
  86079. +talitos_submit(
  86080. + struct talitos_softc *sc,
  86081. + struct talitos_desc *td,
  86082. + int chsel)
  86083. +{
  86084. + u_int32_t v;
  86085. +
  86086. + v = dma_map_single(NULL, td, sizeof(*td), DMA_TO_DEVICE);
  86087. + talitos_write(sc->sc_base_addr +
  86088. + chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF, 0);
  86089. + talitos_write(sc->sc_base_addr +
  86090. + chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF_HI, v);
  86091. + return 0;
  86092. +}
  86093. +
  86094. +static int
  86095. +talitos_process(device_t dev, struct cryptop *crp, int hint)
  86096. +{
  86097. + int i, err = 0, ivsize;
  86098. + struct talitos_softc *sc = device_get_softc(dev);
  86099. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  86100. + caddr_t iv;
  86101. + struct talitos_session *ses;
  86102. + struct talitos_desc *td;
  86103. + unsigned long flags;
  86104. + /* descriptor mappings */
  86105. + int hmac_key, hmac_data, cipher_iv, cipher_key,
  86106. + in_fifo, out_fifo, cipher_iv_out;
  86107. + static int chsel = -1;
  86108. +
  86109. + DPRINTF("%s()\n", __FUNCTION__);
  86110. +
  86111. + if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
  86112. + return EINVAL;
  86113. + }
  86114. + crp->crp_etype = 0;
  86115. + if (TALITOS_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
  86116. + return EINVAL;
  86117. + }
  86118. +
  86119. + ses = &sc->sc_sessions[TALITOS_SESSION(crp->crp_sid)];
  86120. +
  86121. + /* enter the channel scheduler */
  86122. + spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  86123. +
  86124. + /* reuse channel that already had/has requests for the required EU */
  86125. + for (i = 0; i < sc->sc_num_channels; i++) {
  86126. + if (sc->sc_chnlastalg[i] == crp->crp_desc->crd_alg)
  86127. + break;
  86128. + }
  86129. + if (i == sc->sc_num_channels) {
  86130. + /*
  86131. + * haven't seen this algo the last sc_num_channels or more
  86132. + * use round robin in this case
  86133. + * nb: sc->sc_num_channels must be power of 2
  86134. + */
  86135. + chsel = (chsel + 1) & (sc->sc_num_channels - 1);
  86136. + } else {
  86137. + /*
  86138. + * matches channel with same target execution unit;
  86139. + * use same channel in this case
  86140. + */
  86141. + chsel = i;
  86142. + }
  86143. + sc->sc_chnlastalg[chsel] = crp->crp_desc->crd_alg;
  86144. +
  86145. + /* release the channel scheduler lock */
  86146. + spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  86147. +
  86148. + /* acquire the selected channel fifo lock */
  86149. + spin_lock_irqsave(&sc->sc_chnfifolock[chsel], flags);
  86150. +
  86151. + /* find and reserve next available descriptor-cryptop pair */
  86152. + for (i = 0; i < sc->sc_chfifo_len; i++) {
  86153. + if (sc->sc_chnfifo[chsel][i].cf_desc.hdr == 0) {
  86154. + /*
  86155. + * ensure correct descriptor formation by
  86156. + * avoiding inadvertently setting "optional" entries
  86157. + * e.g. not using "optional" dptr2 for MD/HMAC descs
  86158. + */
  86159. + memset(&sc->sc_chnfifo[chsel][i].cf_desc,
  86160. + 0, sizeof(*td));
  86161. + /* reserve it with done notification request bit */
  86162. + sc->sc_chnfifo[chsel][i].cf_desc.hdr |=
  86163. + TALITOS_DONE_NOTIFY;
  86164. + break;
  86165. + }
  86166. + }
  86167. + spin_unlock_irqrestore(&sc->sc_chnfifolock[chsel], flags);
  86168. +
  86169. + if (i == sc->sc_chfifo_len) {
  86170. + /* fifo full */
  86171. + err = ERESTART;
  86172. + goto errout;
  86173. + }
  86174. +
  86175. + td = &sc->sc_chnfifo[chsel][i].cf_desc;
  86176. + sc->sc_chnfifo[chsel][i].cf_crp = crp;
  86177. +
  86178. + crd1 = crp->crp_desc;
  86179. + if (crd1 == NULL) {
  86180. + err = EINVAL;
  86181. + goto errout;
  86182. + }
  86183. + crd2 = crd1->crd_next;
  86184. + /* prevent compiler warning */
  86185. + hmac_key = 0;
  86186. + hmac_data = 0;
  86187. + if (crd2 == NULL) {
  86188. + td->hdr |= TD_TYPE_COMMON_NONSNOOP_NO_AFEU;
  86189. + /* assign descriptor dword ptr mappings for this desc. type */
  86190. + cipher_iv = 1;
  86191. + cipher_key = 2;
  86192. + in_fifo = 3;
  86193. + cipher_iv_out = 5;
  86194. + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
  86195. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  86196. + crd1->crd_alg == CRYPTO_SHA1 ||
  86197. + crd1->crd_alg == CRYPTO_MD5) {
  86198. + out_fifo = 5;
  86199. + maccrd = crd1;
  86200. + enccrd = NULL;
  86201. + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
  86202. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  86203. + crd1->crd_alg == CRYPTO_AES_CBC ||
  86204. + crd1->crd_alg == CRYPTO_ARC4) {
  86205. + out_fifo = 4;
  86206. + maccrd = NULL;
  86207. + enccrd = crd1;
  86208. + } else {
  86209. + DPRINTF("UNKNOWN crd1->crd_alg %d\n", crd1->crd_alg);
  86210. + err = EINVAL;
  86211. + goto errout;
  86212. + }
  86213. + } else {
  86214. + if (sc->sc_desc_types & TALITOS_HAS_DT_IPSEC_ESP) {
  86215. + td->hdr |= TD_TYPE_IPSEC_ESP;
  86216. + } else {
  86217. + DPRINTF("unimplemented: multiple descriptor ipsec\n");
  86218. + err = EINVAL;
  86219. + goto errout;
  86220. + }
  86221. + /* assign descriptor dword ptr mappings for this desc. type */
  86222. + hmac_key = 0;
  86223. + hmac_data = 1;
  86224. + cipher_iv = 2;
  86225. + cipher_key = 3;
  86226. + in_fifo = 4;
  86227. + out_fifo = 5;
  86228. + cipher_iv_out = 6;
  86229. + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
  86230. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  86231. + crd1->crd_alg == CRYPTO_MD5 ||
  86232. + crd1->crd_alg == CRYPTO_SHA1) &&
  86233. + (crd2->crd_alg == CRYPTO_DES_CBC ||
  86234. + crd2->crd_alg == CRYPTO_3DES_CBC ||
  86235. + crd2->crd_alg == CRYPTO_AES_CBC ||
  86236. + crd2->crd_alg == CRYPTO_ARC4) &&
  86237. + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
  86238. + maccrd = crd1;
  86239. + enccrd = crd2;
  86240. + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
  86241. + crd1->crd_alg == CRYPTO_ARC4 ||
  86242. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  86243. + crd1->crd_alg == CRYPTO_AES_CBC) &&
  86244. + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
  86245. + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
  86246. + crd2->crd_alg == CRYPTO_MD5 ||
  86247. + crd2->crd_alg == CRYPTO_SHA1) &&
  86248. + (crd1->crd_flags & CRD_F_ENCRYPT)) {
  86249. + enccrd = crd1;
  86250. + maccrd = crd2;
  86251. + } else {
  86252. + /* We cannot order the SEC as requested */
  86253. + printk("%s: cannot do the order\n",
  86254. + device_get_nameunit(sc->sc_cdev));
  86255. + err = EINVAL;
  86256. + goto errout;
  86257. + }
  86258. + }
  86259. + /* assign in_fifo and out_fifo based on input/output struct type */
  86260. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  86261. + /* using SKB buffers */
  86262. + struct sk_buff *skb = (struct sk_buff *)crp->crp_buf;
  86263. + if (skb_shinfo(skb)->nr_frags) {
  86264. + printk("%s: skb frags unimplemented\n",
  86265. + device_get_nameunit(sc->sc_cdev));
  86266. + err = EINVAL;
  86267. + goto errout;
  86268. + }
  86269. + td->ptr[in_fifo].ptr = dma_map_single(NULL, skb->data,
  86270. + skb->len, DMA_TO_DEVICE);
  86271. + td->ptr[in_fifo].len = skb->len;
  86272. + td->ptr[out_fifo].ptr = dma_map_single(NULL, skb->data,
  86273. + skb->len, DMA_TO_DEVICE);
  86274. + td->ptr[out_fifo].len = skb->len;
  86275. + td->ptr[hmac_data].ptr = dma_map_single(NULL, skb->data,
  86276. + skb->len, DMA_TO_DEVICE);
  86277. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  86278. + /* using IOV buffers */
  86279. + struct uio *uiop = (struct uio *)crp->crp_buf;
  86280. + if (uiop->uio_iovcnt > 1) {
  86281. + printk("%s: iov frags unimplemented\n",
  86282. + device_get_nameunit(sc->sc_cdev));
  86283. + err = EINVAL;
  86284. + goto errout;
  86285. + }
  86286. + td->ptr[in_fifo].ptr = dma_map_single(NULL,
  86287. + uiop->uio_iov->iov_base, crp->crp_ilen, DMA_TO_DEVICE);
  86288. + td->ptr[in_fifo].len = crp->crp_ilen;
  86289. + /* crp_olen is never set; always use crp_ilen */
  86290. + td->ptr[out_fifo].ptr = dma_map_single(NULL,
  86291. + uiop->uio_iov->iov_base,
  86292. + crp->crp_ilen, DMA_TO_DEVICE);
  86293. + td->ptr[out_fifo].len = crp->crp_ilen;
  86294. + } else {
  86295. + /* using contig buffers */
  86296. + td->ptr[in_fifo].ptr = dma_map_single(NULL,
  86297. + crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);
  86298. + td->ptr[in_fifo].len = crp->crp_ilen;
  86299. + td->ptr[out_fifo].ptr = dma_map_single(NULL,
  86300. + crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);
  86301. + td->ptr[out_fifo].len = crp->crp_ilen;
  86302. + }
  86303. + if (enccrd) {
  86304. + switch (enccrd->crd_alg) {
  86305. + case CRYPTO_3DES_CBC:
  86306. + td->hdr |= TALITOS_MODE0_DEU_3DES;
  86307. + /* FALLTHROUGH */
  86308. + case CRYPTO_DES_CBC:
  86309. + td->hdr |= TALITOS_SEL0_DEU
  86310. + | TALITOS_MODE0_DEU_CBC;
  86311. + if (enccrd->crd_flags & CRD_F_ENCRYPT)
  86312. + td->hdr |= TALITOS_MODE0_DEU_ENC;
  86313. + ivsize = 2*sizeof(u_int32_t);
  86314. + DPRINTF("%cDES ses %d ch %d len %d\n",
  86315. + (td->hdr & TALITOS_MODE0_DEU_3DES)?'3':'1',
  86316. + (u32)TALITOS_SESSION(crp->crp_sid),
  86317. + chsel, td->ptr[in_fifo].len);
  86318. + break;
  86319. + case CRYPTO_AES_CBC:
  86320. + td->hdr |= TALITOS_SEL0_AESU
  86321. + | TALITOS_MODE0_AESU_CBC;
  86322. + if (enccrd->crd_flags & CRD_F_ENCRYPT)
  86323. + td->hdr |= TALITOS_MODE0_AESU_ENC;
  86324. + ivsize = 4*sizeof(u_int32_t);
  86325. + DPRINTF("AES ses %d ch %d len %d\n",
  86326. + (u32)TALITOS_SESSION(crp->crp_sid),
  86327. + chsel, td->ptr[in_fifo].len);
  86328. + break;
  86329. + default:
  86330. + printk("%s: unimplemented enccrd->crd_alg %d\n",
  86331. + device_get_nameunit(sc->sc_cdev), enccrd->crd_alg);
  86332. + err = EINVAL;
  86333. + goto errout;
  86334. + }
  86335. + /*
  86336. + * Setup encrypt/decrypt state. When using basic ops
  86337. + * we can't use an inline IV because hash/crypt offset
  86338. + * must be from the end of the IV to the start of the
  86339. + * crypt data and this leaves out the preceding header
  86340. + * from the hash calculation. Instead we place the IV
  86341. + * in the state record and set the hash/crypt offset to
  86342. + * copy both the header+IV.
  86343. + */
  86344. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  86345. + td->hdr |= TALITOS_DIR_OUTBOUND;
  86346. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  86347. + iv = enccrd->crd_iv;
  86348. + else
  86349. + iv = (caddr_t) ses->ses_iv;
  86350. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  86351. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  86352. + enccrd->crd_inject, ivsize, iv);
  86353. + }
  86354. + } else {
  86355. + td->hdr |= TALITOS_DIR_INBOUND;
  86356. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  86357. + iv = enccrd->crd_iv;
  86358. + bcopy(enccrd->crd_iv, iv, ivsize);
  86359. + } else {
  86360. + iv = (caddr_t) ses->ses_iv;
  86361. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  86362. + enccrd->crd_inject, ivsize, iv);
  86363. + }
  86364. + }
  86365. + td->ptr[cipher_iv].ptr = dma_map_single(NULL, iv, ivsize,
  86366. + DMA_TO_DEVICE);
  86367. + td->ptr[cipher_iv].len = ivsize;
  86368. + /*
  86369. + * we don't need the cipher iv out length/pointer
  86370. + * field to do ESP IPsec. Therefore we set the len field as 0,
  86371. + * which tells the SEC not to do anything with this len/ptr
  86372. + * field. Previously, when length/pointer as pointing to iv,
  86373. + * it gave us corruption of packets.
  86374. + */
  86375. + td->ptr[cipher_iv_out].len = 0;
  86376. + }
  86377. + if (enccrd && maccrd) {
  86378. + /* this is ipsec only for now */
  86379. + td->hdr |= TALITOS_SEL1_MDEU
  86380. + | TALITOS_MODE1_MDEU_INIT
  86381. + | TALITOS_MODE1_MDEU_PAD;
  86382. + switch (maccrd->crd_alg) {
  86383. + case CRYPTO_MD5:
  86384. + td->hdr |= TALITOS_MODE1_MDEU_MD5;
  86385. + break;
  86386. + case CRYPTO_MD5_HMAC:
  86387. + td->hdr |= TALITOS_MODE1_MDEU_MD5_HMAC;
  86388. + break;
  86389. + case CRYPTO_SHA1:
  86390. + td->hdr |= TALITOS_MODE1_MDEU_SHA1;
  86391. + break;
  86392. + case CRYPTO_SHA1_HMAC:
  86393. + td->hdr |= TALITOS_MODE1_MDEU_SHA1_HMAC;
  86394. + break;
  86395. + default:
  86396. + /* We cannot order the SEC as requested */
  86397. + printk("%s: cannot do the order\n",
  86398. + device_get_nameunit(sc->sc_cdev));
  86399. + err = EINVAL;
  86400. + goto errout;
  86401. + }
  86402. + if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
  86403. + (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
  86404. + /*
  86405. + * The offset from hash data to the start of
  86406. + * crypt data is the difference in the skips.
  86407. + */
  86408. + /* ipsec only for now */
  86409. + td->ptr[hmac_key].ptr = dma_map_single(NULL,
  86410. + ses->ses_hmac, ses->ses_hmac_len, DMA_TO_DEVICE);
  86411. + td->ptr[hmac_key].len = ses->ses_hmac_len;
  86412. + td->ptr[in_fifo].ptr += enccrd->crd_skip;
  86413. + td->ptr[in_fifo].len = enccrd->crd_len;
  86414. + td->ptr[out_fifo].ptr += enccrd->crd_skip;
  86415. + td->ptr[out_fifo].len = enccrd->crd_len;
  86416. + /* bytes of HMAC to postpend to ciphertext */
  86417. + td->ptr[out_fifo].extent = ses->ses_mlen;
  86418. + td->ptr[hmac_data].ptr += maccrd->crd_skip;
  86419. + td->ptr[hmac_data].len = enccrd->crd_skip - maccrd->crd_skip;
  86420. + }
  86421. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
  86422. + printk("%s: CRD_F_KEY_EXPLICIT unimplemented\n",
  86423. + device_get_nameunit(sc->sc_cdev));
  86424. + }
  86425. + }
  86426. + if (!enccrd && maccrd) {
  86427. + /* single MD5 or SHA */
  86428. + td->hdr |= TALITOS_SEL0_MDEU
  86429. + | TALITOS_MODE0_MDEU_INIT
  86430. + | TALITOS_MODE0_MDEU_PAD;
  86431. + switch (maccrd->crd_alg) {
  86432. + case CRYPTO_MD5:
  86433. + td->hdr |= TALITOS_MODE0_MDEU_MD5;
  86434. + DPRINTF("MD5 ses %d ch %d len %d\n",
  86435. + (u32)TALITOS_SESSION(crp->crp_sid),
  86436. + chsel, td->ptr[in_fifo].len);
  86437. + break;
  86438. + case CRYPTO_MD5_HMAC:
  86439. + td->hdr |= TALITOS_MODE0_MDEU_MD5_HMAC;
  86440. + break;
  86441. + case CRYPTO_SHA1:
  86442. + td->hdr |= TALITOS_MODE0_MDEU_SHA1;
  86443. + DPRINTF("SHA1 ses %d ch %d len %d\n",
  86444. + (u32)TALITOS_SESSION(crp->crp_sid),
  86445. + chsel, td->ptr[in_fifo].len);
  86446. + break;
  86447. + case CRYPTO_SHA1_HMAC:
  86448. + td->hdr |= TALITOS_MODE0_MDEU_SHA1_HMAC;
  86449. + break;
  86450. + default:
  86451. + /* We cannot order the SEC as requested */
  86452. + DPRINTF("cannot do the order\n");
  86453. + err = EINVAL;
  86454. + goto errout;
  86455. + }
  86456. +
  86457. + if (crp->crp_flags & CRYPTO_F_IOV)
  86458. + td->ptr[out_fifo].ptr += maccrd->crd_inject;
  86459. +
  86460. + if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
  86461. + (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
  86462. + td->ptr[hmac_key].ptr = dma_map_single(NULL,
  86463. + ses->ses_hmac, ses->ses_hmac_len,
  86464. + DMA_TO_DEVICE);
  86465. + td->ptr[hmac_key].len = ses->ses_hmac_len;
  86466. + }
  86467. + }
  86468. + else {
  86469. + /* using process key (session data has duplicate) */
  86470. + td->ptr[cipher_key].ptr = dma_map_single(NULL,
  86471. + enccrd->crd_key, (enccrd->crd_klen + 7) / 8,
  86472. + DMA_TO_DEVICE);
  86473. + td->ptr[cipher_key].len = (enccrd->crd_klen + 7) / 8;
  86474. + }
  86475. + /* descriptor complete - GO! */
  86476. + return talitos_submit(sc, td, chsel);
  86477. +
  86478. +errout:
  86479. + if (err != ERESTART) {
  86480. + crp->crp_etype = err;
  86481. + crypto_done(crp);
  86482. + }
  86483. + return err;
  86484. +}
  86485. +
  86486. +/* go through all channels descriptors, notifying OCF what has
  86487. + * _and_hasn't_ successfully completed and reset the device
  86488. + * (otherwise it's up to decoding desc hdrs!)
  86489. + */
  86490. +static void talitos_errorprocessing(struct talitos_softc *sc)
  86491. +{
  86492. + unsigned long flags;
  86493. + int i, j;
  86494. +
  86495. + /* disable further scheduling until under control */
  86496. + spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  86497. +
  86498. + if (debug) dump_talitos_status(sc);
  86499. + /* go through descriptors, try and salvage those successfully done,
  86500. + * and EIO those that weren't
  86501. + */
  86502. + for (i = 0; i < sc->sc_num_channels; i++) {
  86503. + spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
  86504. + for (j = 0; j < sc->sc_chfifo_len; j++) {
  86505. + if (sc->sc_chnfifo[i][j].cf_desc.hdr) {
  86506. + if ((sc->sc_chnfifo[i][j].cf_desc.hdr
  86507. + & TALITOS_HDR_DONE_BITS)
  86508. + != TALITOS_HDR_DONE_BITS) {
  86509. + /* this one didn't finish */
  86510. + /* signify in crp->etype */
  86511. + sc->sc_chnfifo[i][j].cf_crp->crp_etype
  86512. + = EIO;
  86513. + }
  86514. + } else
  86515. + continue; /* free entry */
  86516. + /* either way, notify ocf */
  86517. + crypto_done(sc->sc_chnfifo[i][j].cf_crp);
  86518. + /* and tag it available again
  86519. + *
  86520. + * memset to ensure correct descriptor formation by
  86521. + * avoiding inadvertently setting "optional" entries
  86522. + * e.g. not using "optional" dptr2 MD/HMAC processing
  86523. + */
  86524. + memset(&sc->sc_chnfifo[i][j].cf_desc,
  86525. + 0, sizeof(struct talitos_desc));
  86526. + }
  86527. + spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);
  86528. + }
  86529. + /* reset and initialize the SEC h/w device */
  86530. + talitos_reset_device(sc);
  86531. + talitos_init_device(sc);
  86532. +#ifdef CONFIG_OCF_RANDOMHARVEST
  86533. + if (sc->sc_exec_units & TALITOS_HAS_EU_RNG)
  86534. + talitos_rng_init(sc);
  86535. +#endif
  86536. +
  86537. + /* Okay. Stand by. */
  86538. + spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  86539. +
  86540. + return;
  86541. +}
  86542. +
  86543. +/* go through all channels descriptors, notifying OCF what's been done */
  86544. +static void talitos_doneprocessing(struct talitos_softc *sc)
  86545. +{
  86546. + unsigned long flags;
  86547. + int i, j;
  86548. +
  86549. + /* go through descriptors looking for done bits */
  86550. + for (i = 0; i < sc->sc_num_channels; i++) {
  86551. + spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
  86552. + for (j = 0; j < sc->sc_chfifo_len; j++) {
  86553. + /* descriptor has done bits set? */
  86554. + if ((sc->sc_chnfifo[i][j].cf_desc.hdr
  86555. + & TALITOS_HDR_DONE_BITS)
  86556. + == TALITOS_HDR_DONE_BITS) {
  86557. + /* notify ocf */
  86558. + crypto_done(sc->sc_chnfifo[i][j].cf_crp);
  86559. + /* and tag it available again
  86560. + *
  86561. + * memset to ensure correct descriptor formation by
  86562. + * avoiding inadvertently setting "optional" entries
  86563. + * e.g. not using "optional" dptr2 MD/HMAC processing
  86564. + */
  86565. + memset(&sc->sc_chnfifo[i][j].cf_desc,
  86566. + 0, sizeof(struct talitos_desc));
  86567. + }
  86568. + }
  86569. + spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);
  86570. + }
  86571. + return;
  86572. +}
  86573. +
  86574. +static irqreturn_t
  86575. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  86576. +talitos_intr(int irq, void *arg)
  86577. +#else
  86578. +talitos_intr(int irq, void *arg, struct pt_regs *regs)
  86579. +#endif
  86580. +{
  86581. + struct talitos_softc *sc = arg;
  86582. + u_int32_t v, v_hi;
  86583. +
  86584. + /* ack */
  86585. + v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
  86586. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
  86587. + talitos_write(sc->sc_base_addr + TALITOS_ICR, v);
  86588. + talitos_write(sc->sc_base_addr + TALITOS_ICR_HI, v_hi);
  86589. +
  86590. + if (unlikely(v & TALITOS_ISR_ERROR)) {
  86591. + /* Okay, Houston, we've had a problem here. */
  86592. + printk(KERN_DEBUG "%s: got error interrupt - ISR 0x%08x_%08x\n",
  86593. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  86594. + talitos_errorprocessing(sc);
  86595. + } else
  86596. + if (likely(v & TALITOS_ISR_DONE)) {
  86597. + talitos_doneprocessing(sc);
  86598. + }
  86599. + return IRQ_HANDLED;
  86600. +}
  86601. +
  86602. +/*
  86603. + * Initialize registers we need to touch only once.
  86604. + */
  86605. +static void
  86606. +talitos_init_device(struct talitos_softc *sc)
  86607. +{
  86608. + u_int32_t v;
  86609. + int i;
  86610. +
  86611. + DPRINTF("%s()\n", __FUNCTION__);
  86612. +
  86613. + /* init all channels */
  86614. + for (i = 0; i < sc->sc_num_channels; i++) {
  86615. + v = talitos_read(sc->sc_base_addr +
  86616. + i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI);
  86617. + v |= TALITOS_CH_CCCR_HI_CDWE
  86618. + | TALITOS_CH_CCCR_HI_CDIE; /* invoke interrupt if done */
  86619. + talitos_write(sc->sc_base_addr +
  86620. + i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI, v);
  86621. + }
  86622. + /* enable all interrupts */
  86623. + v = talitos_read(sc->sc_base_addr + TALITOS_IMR);
  86624. + v |= TALITOS_IMR_ALL;
  86625. + talitos_write(sc->sc_base_addr + TALITOS_IMR, v);
  86626. + v = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);
  86627. + v |= TALITOS_IMR_HI_ERRONLY;
  86628. + talitos_write(sc->sc_base_addr + TALITOS_IMR_HI, v);
  86629. + return;
  86630. +}
  86631. +
  86632. +/*
  86633. + * set the master reset bit on the device.
  86634. + */
  86635. +static void
  86636. +talitos_reset_device_master(struct talitos_softc *sc)
  86637. +{
  86638. + u_int32_t v;
  86639. +
  86640. + /* Reset the device by writing 1 to MCR:SWR and waiting 'til cleared */
  86641. + v = talitos_read(sc->sc_base_addr + TALITOS_MCR);
  86642. + talitos_write(sc->sc_base_addr + TALITOS_MCR, v | TALITOS_MCR_SWR);
  86643. +
  86644. + while (talitos_read(sc->sc_base_addr + TALITOS_MCR) & TALITOS_MCR_SWR)
  86645. + cpu_relax();
  86646. +
  86647. + return;
  86648. +}
  86649. +
  86650. +/*
  86651. + * Resets the device. Values in the registers are left as is
  86652. + * from the reset (i.e. initial values are assigned elsewhere).
  86653. + */
  86654. +static void
  86655. +talitos_reset_device(struct talitos_softc *sc)
  86656. +{
  86657. + u_int32_t v;
  86658. + int i;
  86659. +
  86660. + DPRINTF("%s()\n", __FUNCTION__);
  86661. +
  86662. + /*
  86663. + * Master reset
  86664. + * errata documentation: warning: certain SEC interrupts
  86665. + * are not fully cleared by writing the MCR:SWR bit,
  86666. + * set bit twice to completely reset
  86667. + */
  86668. + talitos_reset_device_master(sc); /* once */
  86669. + talitos_reset_device_master(sc); /* and once again */
  86670. +
  86671. + /* reset all channels */
  86672. + for (i = 0; i < sc->sc_num_channels; i++) {
  86673. + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  86674. + TALITOS_CH_CCCR);
  86675. + talitos_write(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  86676. + TALITOS_CH_CCCR, v | TALITOS_CH_CCCR_RESET);
  86677. + }
  86678. +}
  86679. +
  86680. +/* Set up the crypto device structure, private data,
  86681. + * and anything else we need before we start */
  86682. +#ifdef CONFIG_PPC_MERGE
  86683. +static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match)
  86684. +#else
  86685. +static int talitos_probe(struct platform_device *pdev)
  86686. +#endif
  86687. +{
  86688. + struct talitos_softc *sc = NULL;
  86689. + struct resource *r;
  86690. +#ifdef CONFIG_PPC_MERGE
  86691. + struct device *device = &ofdev->dev;
  86692. + struct device_node *np = ofdev->node;
  86693. + const unsigned int *prop;
  86694. + int err;
  86695. + struct resource res;
  86696. +#endif
  86697. + static int num_chips = 0;
  86698. + int rc;
  86699. + int i;
  86700. +
  86701. + DPRINTF("%s()\n", __FUNCTION__);
  86702. +
  86703. + sc = (struct talitos_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  86704. + if (!sc)
  86705. + return -ENOMEM;
  86706. + memset(sc, 0, sizeof(*sc));
  86707. +
  86708. + softc_device_init(sc, DRV_NAME, num_chips, talitos_methods);
  86709. +
  86710. + sc->sc_irq = -1;
  86711. + sc->sc_cid = -1;
  86712. +#ifndef CONFIG_PPC_MERGE
  86713. + sc->sc_dev = pdev;
  86714. +#endif
  86715. + sc->sc_num = num_chips++;
  86716. +
  86717. +#ifdef CONFIG_PPC_MERGE
  86718. + dev_set_drvdata(device, sc);
  86719. +#else
  86720. + platform_set_drvdata(sc->sc_dev, sc);
  86721. +#endif
  86722. +
  86723. + /* get the irq line */
  86724. +#ifdef CONFIG_PPC_MERGE
  86725. + err = of_address_to_resource(np, 0, &res);
  86726. + if (err)
  86727. + return -EINVAL;
  86728. + r = &res;
  86729. +
  86730. + sc->sc_irq = irq_of_parse_and_map(np, 0);
  86731. +#else
  86732. + /* get a pointer to the register memory */
  86733. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  86734. +
  86735. + sc->sc_irq = platform_get_irq(pdev, 0);
  86736. +#endif
  86737. + rc = request_irq(sc->sc_irq, talitos_intr, 0,
  86738. + device_get_nameunit(sc->sc_cdev), sc);
  86739. + if (rc) {
  86740. + printk(KERN_ERR "%s: failed to hook irq %d\n",
  86741. + device_get_nameunit(sc->sc_cdev), sc->sc_irq);
  86742. + sc->sc_irq = -1;
  86743. + goto out;
  86744. + }
  86745. +
  86746. + sc->sc_base_addr = (ocf_iomem_t) ioremap(r->start, (r->end - r->start));
  86747. + if (!sc->sc_base_addr) {
  86748. + printk(KERN_ERR "%s: failed to ioremap\n",
  86749. + device_get_nameunit(sc->sc_cdev));
  86750. + goto out;
  86751. + }
  86752. +
  86753. + /* figure out our SEC's properties and capabilities */
  86754. + sc->sc_chiprev = (u64)talitos_read(sc->sc_base_addr + TALITOS_ID) << 32
  86755. + | talitos_read(sc->sc_base_addr + TALITOS_ID_HI);
  86756. + DPRINTF("sec id 0x%llx\n", sc->sc_chiprev);
  86757. +
  86758. +#ifdef CONFIG_PPC_MERGE
  86759. + /* get SEC properties from device tree, defaulting to SEC 2.0 */
  86760. +
  86761. + prop = of_get_property(np, "num-channels", NULL);
  86762. + sc->sc_num_channels = prop ? *prop : TALITOS_NCHANNELS_SEC_2_0;
  86763. +
  86764. + prop = of_get_property(np, "channel-fifo-len", NULL);
  86765. + sc->sc_chfifo_len = prop ? *prop : TALITOS_CHFIFOLEN_SEC_2_0;
  86766. +
  86767. + prop = of_get_property(np, "exec-units-mask", NULL);
  86768. + sc->sc_exec_units = prop ? *prop : TALITOS_HAS_EUS_SEC_2_0;
  86769. +
  86770. + prop = of_get_property(np, "descriptor-types-mask", NULL);
  86771. + sc->sc_desc_types = prop ? *prop : TALITOS_HAS_DESCTYPES_SEC_2_0;
  86772. +#else
  86773. + /* bulk should go away with openfirmware flat device tree support */
  86774. + if (sc->sc_chiprev & TALITOS_ID_SEC_2_0) {
  86775. + sc->sc_num_channels = TALITOS_NCHANNELS_SEC_2_0;
  86776. + sc->sc_chfifo_len = TALITOS_CHFIFOLEN_SEC_2_0;
  86777. + sc->sc_exec_units = TALITOS_HAS_EUS_SEC_2_0;
  86778. + sc->sc_desc_types = TALITOS_HAS_DESCTYPES_SEC_2_0;
  86779. + } else {
  86780. + printk(KERN_ERR "%s: failed to id device\n",
  86781. + device_get_nameunit(sc->sc_cdev));
  86782. + goto out;
  86783. + }
  86784. +#endif
  86785. +
  86786. + /* + 1 is for the meta-channel lock used by the channel scheduler */
  86787. + sc->sc_chnfifolock = (spinlock_t *) kmalloc(
  86788. + (sc->sc_num_channels + 1) * sizeof(spinlock_t), GFP_KERNEL);
  86789. + if (!sc->sc_chnfifolock)
  86790. + goto out;
  86791. + for (i = 0; i < sc->sc_num_channels + 1; i++) {
  86792. + spin_lock_init(&sc->sc_chnfifolock[i]);
  86793. + }
  86794. +
  86795. + sc->sc_chnlastalg = (int *) kmalloc(
  86796. + sc->sc_num_channels * sizeof(int), GFP_KERNEL);
  86797. + if (!sc->sc_chnlastalg)
  86798. + goto out;
  86799. + memset(sc->sc_chnlastalg, 0, sc->sc_num_channels * sizeof(int));
  86800. +
  86801. + sc->sc_chnfifo = (struct desc_cryptop_pair **) kmalloc(
  86802. + sc->sc_num_channels * sizeof(struct desc_cryptop_pair *),
  86803. + GFP_KERNEL);
  86804. + if (!sc->sc_chnfifo)
  86805. + goto out;
  86806. + for (i = 0; i < sc->sc_num_channels; i++) {
  86807. + sc->sc_chnfifo[i] = (struct desc_cryptop_pair *) kmalloc(
  86808. + sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair),
  86809. + GFP_KERNEL);
  86810. + if (!sc->sc_chnfifo[i])
  86811. + goto out;
  86812. + memset(sc->sc_chnfifo[i], 0,
  86813. + sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair));
  86814. + }
  86815. +
  86816. + /* reset and initialize the SEC h/w device */
  86817. + talitos_reset_device(sc);
  86818. + talitos_init_device(sc);
  86819. +
  86820. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
  86821. + if (sc->sc_cid < 0) {
  86822. + printk(KERN_ERR "%s: could not get crypto driver id\n",
  86823. + device_get_nameunit(sc->sc_cdev));
  86824. + goto out;
  86825. + }
  86826. +
  86827. + /* register algorithms with the framework */
  86828. + printk("%s:", device_get_nameunit(sc->sc_cdev));
  86829. +
  86830. + if (sc->sc_exec_units & TALITOS_HAS_EU_RNG) {
  86831. + printk(" rng");
  86832. +#ifdef CONFIG_OCF_RANDOMHARVEST
  86833. + talitos_rng_init(sc);
  86834. + crypto_rregister(sc->sc_cid, talitos_read_random, sc);
  86835. +#endif
  86836. + }
  86837. + if (sc->sc_exec_units & TALITOS_HAS_EU_DEU) {
  86838. + printk(" des/3des");
  86839. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  86840. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  86841. + }
  86842. + if (sc->sc_exec_units & TALITOS_HAS_EU_AESU) {
  86843. + printk(" aes");
  86844. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  86845. + }
  86846. + if (sc->sc_exec_units & TALITOS_HAS_EU_MDEU) {
  86847. + printk(" md5");
  86848. + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
  86849. + /* HMAC support only with IPsec for now */
  86850. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  86851. + printk(" sha1");
  86852. + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
  86853. + /* HMAC support only with IPsec for now */
  86854. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  86855. + }
  86856. + printk("\n");
  86857. + return 0;
  86858. +
  86859. +out:
  86860. +#ifndef CONFIG_PPC_MERGE
  86861. + talitos_remove(pdev);
  86862. +#endif
  86863. + return -ENOMEM;
  86864. +}
  86865. +
  86866. +#ifdef CONFIG_PPC_MERGE
  86867. +static int talitos_remove(struct of_device *ofdev)
  86868. +#else
  86869. +static int talitos_remove(struct platform_device *pdev)
  86870. +#endif
  86871. +{
  86872. +#ifdef CONFIG_PPC_MERGE
  86873. + struct talitos_softc *sc = dev_get_drvdata(&ofdev->dev);
  86874. +#else
  86875. + struct talitos_softc *sc = platform_get_drvdata(pdev);
  86876. +#endif
  86877. + int i;
  86878. +
  86879. + DPRINTF("%s()\n", __FUNCTION__);
  86880. + if (sc->sc_cid >= 0)
  86881. + crypto_unregister_all(sc->sc_cid);
  86882. + if (sc->sc_chnfifo) {
  86883. + for (i = 0; i < sc->sc_num_channels; i++)
  86884. + if (sc->sc_chnfifo[i])
  86885. + kfree(sc->sc_chnfifo[i]);
  86886. + kfree(sc->sc_chnfifo);
  86887. + }
  86888. + if (sc->sc_chnlastalg)
  86889. + kfree(sc->sc_chnlastalg);
  86890. + if (sc->sc_chnfifolock)
  86891. + kfree(sc->sc_chnfifolock);
  86892. + if (sc->sc_irq != -1)
  86893. + free_irq(sc->sc_irq, sc);
  86894. + if (sc->sc_base_addr)
  86895. + iounmap((void *) sc->sc_base_addr);
  86896. + kfree(sc);
  86897. + return 0;
  86898. +}
  86899. +
  86900. +#ifdef CONFIG_PPC_MERGE
  86901. +static struct of_device_id talitos_match[] = {
  86902. + {
  86903. + .type = "crypto",
  86904. + .compatible = "talitos",
  86905. + },
  86906. + {},
  86907. +};
  86908. +
  86909. +MODULE_DEVICE_TABLE(of, talitos_match);
  86910. +
  86911. +static struct of_platform_driver talitos_driver = {
  86912. + .name = DRV_NAME,
  86913. + .match_table = talitos_match,
  86914. + .probe = talitos_probe,
  86915. + .remove = talitos_remove,
  86916. +};
  86917. +
  86918. +static int __init talitos_init(void)
  86919. +{
  86920. + return of_register_platform_driver(&talitos_driver);
  86921. +}
  86922. +
  86923. +static void __exit talitos_exit(void)
  86924. +{
  86925. + of_unregister_platform_driver(&talitos_driver);
  86926. +}
  86927. +#else
  86928. +/* Structure for a platform device driver */
  86929. +static struct platform_driver talitos_driver = {
  86930. + .probe = talitos_probe,
  86931. + .remove = talitos_remove,
  86932. + .driver = {
  86933. + .name = "fsl-sec2",
  86934. + }
  86935. +};
  86936. +
  86937. +static int __init talitos_init(void)
  86938. +{
  86939. + return platform_driver_register(&talitos_driver);
  86940. +}
  86941. +
  86942. +static void __exit talitos_exit(void)
  86943. +{
  86944. + platform_driver_unregister(&talitos_driver);
  86945. +}
  86946. +#endif
  86947. +
  86948. +module_init(talitos_init);
  86949. +module_exit(talitos_exit);
  86950. +
  86951. +MODULE_LICENSE("Dual BSD/GPL");
  86952. +MODULE_AUTHOR("kim.phillips@freescale.com");
  86953. +MODULE_DESCRIPTION("OCF driver for Freescale SEC (talitos)");
  86954. diff -Nur linux-2.6.35.orig/crypto/ocf/talitos/talitos_dev.h linux-2.6.35/crypto/ocf/talitos/talitos_dev.h
  86955. --- linux-2.6.35.orig/crypto/ocf/talitos/talitos_dev.h 1970-01-01 01:00:00.000000000 +0100
  86956. +++ linux-2.6.35/crypto/ocf/talitos/talitos_dev.h 2010-08-05 22:02:26.794868008 +0200
  86957. @@ -0,0 +1,277 @@
  86958. +/*
  86959. + * Freescale SEC (talitos) device dependent data structures
  86960. + *
  86961. + * Copyright (c) 2006 Freescale Semiconductor, Inc.
  86962. + *
  86963. + * Redistribution and use in source and binary forms, with or without
  86964. + * modification, are permitted provided that the following conditions
  86965. + * are met:
  86966. + *
  86967. + * 1. Redistributions of source code must retain the above copyright
  86968. + * notice, this list of conditions and the following disclaimer.
  86969. + * 2. Redistributions in binary form must reproduce the above copyright
  86970. + * notice, this list of conditions and the following disclaimer in the
  86971. + * documentation and/or other materials provided with the distribution.
  86972. + * 3. The name of the author may not be used to endorse or promote products
  86973. + * derived from this software without specific prior written permission.
  86974. + *
  86975. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  86976. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  86977. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  86978. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  86979. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  86980. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  86981. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  86982. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  86983. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  86984. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  86985. + *
  86986. + */
  86987. +
  86988. +/* device ID register values */
  86989. +#define TALITOS_ID_SEC_2_0 0x40
  86990. +#define TALITOS_ID_SEC_2_1 0x40 /* cross ref with IP block revision reg */
  86991. +
  86992. +/*
  86993. + * following num_channels, channel-fifo-depth, exec-unit-mask, and
  86994. + * descriptor-types-mask are for forward-compatibility with openfirmware
  86995. + * flat device trees
  86996. + */
  86997. +
  86998. +/*
  86999. + * num_channels : the number of channels available in each SEC version.
  87000. + */
  87001. +
  87002. +/* n.b. this driver requires these values be a power of 2 */
  87003. +#define TALITOS_NCHANNELS_SEC_1_0 4
  87004. +#define TALITOS_NCHANNELS_SEC_1_2 1
  87005. +#define TALITOS_NCHANNELS_SEC_2_0 4
  87006. +#define TALITOS_NCHANNELS_SEC_2_01 4
  87007. +#define TALITOS_NCHANNELS_SEC_2_1 4
  87008. +#define TALITOS_NCHANNELS_SEC_2_4 4
  87009. +
  87010. +/*
  87011. + * channel-fifo-depth : The number of descriptor
  87012. + * pointers a channel fetch fifo can hold.
  87013. + */
  87014. +#define TALITOS_CHFIFOLEN_SEC_1_0 1
  87015. +#define TALITOS_CHFIFOLEN_SEC_1_2 1
  87016. +#define TALITOS_CHFIFOLEN_SEC_2_0 24
  87017. +#define TALITOS_CHFIFOLEN_SEC_2_01 24
  87018. +#define TALITOS_CHFIFOLEN_SEC_2_1 24
  87019. +#define TALITOS_CHFIFOLEN_SEC_2_4 24
  87020. +
  87021. +/*
  87022. + * exec-unit-mask : The bitmask representing what Execution Units (EUs)
  87023. + * are available. EU information should be encoded following the SEC's
  87024. + * EU_SEL0 bitfield documentation, i.e. as follows:
  87025. + *
  87026. + * bit 31 = set if SEC permits no-EU selection (should be always set)
  87027. + * bit 30 = set if SEC has the ARC4 EU (AFEU)
  87028. + * bit 29 = set if SEC has the des/3des EU (DEU)
  87029. + * bit 28 = set if SEC has the message digest EU (MDEU)
  87030. + * bit 27 = set if SEC has the random number generator EU (RNG)
  87031. + * bit 26 = set if SEC has the public key EU (PKEU)
  87032. + * bit 25 = set if SEC has the aes EU (AESU)
  87033. + * bit 24 = set if SEC has the Kasumi EU (KEU)
  87034. + *
  87035. + */
  87036. +#define TALITOS_HAS_EU_NONE (1<<0)
  87037. +#define TALITOS_HAS_EU_AFEU (1<<1)
  87038. +#define TALITOS_HAS_EU_DEU (1<<2)
  87039. +#define TALITOS_HAS_EU_MDEU (1<<3)
  87040. +#define TALITOS_HAS_EU_RNG (1<<4)
  87041. +#define TALITOS_HAS_EU_PKEU (1<<5)
  87042. +#define TALITOS_HAS_EU_AESU (1<<6)
  87043. +#define TALITOS_HAS_EU_KEU (1<<7)
  87044. +
  87045. +/* the corresponding masks for each SEC version */
  87046. +#define TALITOS_HAS_EUS_SEC_1_0 0x7f
  87047. +#define TALITOS_HAS_EUS_SEC_1_2 0x4d
  87048. +#define TALITOS_HAS_EUS_SEC_2_0 0x7f
  87049. +#define TALITOS_HAS_EUS_SEC_2_01 0x7f
  87050. +#define TALITOS_HAS_EUS_SEC_2_1 0xff
  87051. +#define TALITOS_HAS_EUS_SEC_2_4 0x7f
  87052. +
  87053. +/*
  87054. + * descriptor-types-mask : The bitmask representing what descriptors
  87055. + * are available. Descriptor type information should be encoded
  87056. + * following the SEC's Descriptor Header Dword DESC_TYPE field
  87057. + * documentation, i.e. as follows:
  87058. + *
  87059. + * bit 0 = set if SEC supports the aesu_ctr_nonsnoop desc. type
  87060. + * bit 1 = set if SEC supports the ipsec_esp descriptor type
  87061. + * bit 2 = set if SEC supports the common_nonsnoop desc. type
  87062. + * bit 3 = set if SEC supports the 802.11i AES ccmp desc. type
  87063. + * bit 4 = set if SEC supports the hmac_snoop_no_afeu desc. type
  87064. + * bit 5 = set if SEC supports the srtp descriptor type
  87065. + * bit 6 = set if SEC supports the non_hmac_snoop_no_afeu desc.type
  87066. + * bit 7 = set if SEC supports the pkeu_assemble descriptor type
  87067. + * bit 8 = set if SEC supports the aesu_key_expand_output desc.type
  87068. + * bit 9 = set if SEC supports the pkeu_ptmul descriptor type
  87069. + * bit 10 = set if SEC supports the common_nonsnoop_afeu desc. type
  87070. + * bit 11 = set if SEC supports the pkeu_ptadd_dbl descriptor type
  87071. + *
  87072. + * ..and so on and so forth.
  87073. + */
  87074. +#define TALITOS_HAS_DT_AESU_CTR_NONSNOOP (1<<0)
  87075. +#define TALITOS_HAS_DT_IPSEC_ESP (1<<1)
  87076. +#define TALITOS_HAS_DT_COMMON_NONSNOOP (1<<2)
  87077. +
  87078. +/* the corresponding masks for each SEC version */
  87079. +#define TALITOS_HAS_DESCTYPES_SEC_2_0 0x01010ebf
  87080. +#define TALITOS_HAS_DESCTYPES_SEC_2_1 0x012b0ebf
  87081. +
  87082. +/*
  87083. + * a TALITOS_xxx_HI address points to the low data bits (32-63) of the register
  87084. + */
  87085. +
  87086. +/* global register offset addresses */
  87087. +#define TALITOS_ID 0x1020
  87088. +#define TALITOS_ID_HI 0x1024
  87089. +#define TALITOS_MCR 0x1030 /* master control register */
  87090. +#define TALITOS_MCR_HI 0x1038 /* master control register */
  87091. +#define TALITOS_MCR_SWR 0x1
  87092. +#define TALITOS_IMR 0x1008 /* interrupt mask register */
  87093. +#define TALITOS_IMR_ALL 0x00010fff /* enable all interrupts mask */
  87094. +#define TALITOS_IMR_ERRONLY 0x00010aaa /* enable error interrupts */
  87095. +#define TALITOS_IMR_HI 0x100C /* interrupt mask register */
  87096. +#define TALITOS_IMR_HI_ALL 0x00323333 /* enable all interrupts mask */
  87097. +#define TALITOS_IMR_HI_ERRONLY 0x00222222 /* enable error interrupts */
  87098. +#define TALITOS_ISR 0x1010 /* interrupt status register */
  87099. +#define TALITOS_ISR_ERROR 0x00010faa /* errors mask */
  87100. +#define TALITOS_ISR_DONE 0x00000055 /* channel(s) done mask */
  87101. +#define TALITOS_ISR_HI 0x1014 /* interrupt status register */
  87102. +#define TALITOS_ICR 0x1018 /* interrupt clear register */
  87103. +#define TALITOS_ICR_HI 0x101C /* interrupt clear register */
  87104. +
  87105. +/* channel register address stride */
  87106. +#define TALITOS_CH_OFFSET 0x100
  87107. +
  87108. +/* channel register offset addresses and bits */
  87109. +#define TALITOS_CH_CCCR 0x1108 /* Crypto-Channel Config Register */
  87110. +#define TALITOS_CH_CCCR_RESET 0x1 /* Channel Reset bit */
  87111. +#define TALITOS_CH_CCCR_HI 0x110c /* Crypto-Channel Config Register */
  87112. +#define TALITOS_CH_CCCR_HI_CDWE 0x10 /* Channel done writeback enable bit */
  87113. +#define TALITOS_CH_CCCR_HI_NT 0x4 /* Notification type bit */
  87114. +#define TALITOS_CH_CCCR_HI_CDIE 0x2 /* Channel Done Interrupt Enable bit */
  87115. +#define TALITOS_CH_CCPSR 0x1110 /* Crypto-Channel Pointer Status Reg */
  87116. +#define TALITOS_CH_CCPSR_HI 0x1114 /* Crypto-Channel Pointer Status Reg */
  87117. +#define TALITOS_CH_FF 0x1148 /* Fetch FIFO */
  87118. +#define TALITOS_CH_FF_HI 0x114c /* Fetch FIFO's FETCH_ADRS */
  87119. +#define TALITOS_CH_CDPR 0x1140 /* Crypto-Channel Pointer Status Reg */
  87120. +#define TALITOS_CH_CDPR_HI 0x1144 /* Crypto-Channel Pointer Status Reg */
  87121. +#define TALITOS_CH_DESCBUF 0x1180 /* (thru 11bf) Crypto-Channel
  87122. + * Descriptor Buffer (debug) */
  87123. +
  87124. +/* execution unit register offset addresses and bits */
  87125. +#define TALITOS_DEUSR 0x2028 /* DEU status register */
  87126. +#define TALITOS_DEUSR_HI 0x202c /* DEU status register */
  87127. +#define TALITOS_DEUISR 0x2030 /* DEU interrupt status register */
  87128. +#define TALITOS_DEUISR_HI 0x2034 /* DEU interrupt status register */
  87129. +#define TALITOS_DEUICR 0x2038 /* DEU interrupt control register */
  87130. +#define TALITOS_DEUICR_HI 0x203c /* DEU interrupt control register */
  87131. +#define TALITOS_AESUISR 0x4030 /* AESU interrupt status register */
  87132. +#define TALITOS_AESUISR_HI 0x4034 /* AESU interrupt status register */
  87133. +#define TALITOS_AESUICR 0x4038 /* AESU interrupt control register */
  87134. +#define TALITOS_AESUICR_HI 0x403c /* AESU interrupt control register */
  87135. +#define TALITOS_MDEUISR 0x6030 /* MDEU interrupt status register */
  87136. +#define TALITOS_MDEUISR_HI 0x6034 /* MDEU interrupt status register */
  87137. +#define TALITOS_RNGSR 0xa028 /* RNG status register */
  87138. +#define TALITOS_RNGSR_HI 0xa02c /* RNG status register */
  87139. +#define TALITOS_RNGSR_HI_RD 0x1 /* RNG Reset done */
  87140. +#define TALITOS_RNGSR_HI_OFL 0xff0000/* number of dwords in RNG output FIFO*/
  87141. +#define TALITOS_RNGDSR 0xa010 /* RNG data size register */
  87142. +#define TALITOS_RNGDSR_HI 0xa014 /* RNG data size register */
  87143. +#define TALITOS_RNG_FIFO 0xa800 /* RNG FIFO - pool of random numbers */
  87144. +#define TALITOS_RNGISR 0xa030 /* RNG Interrupt status register */
  87145. +#define TALITOS_RNGISR_HI 0xa034 /* RNG Interrupt status register */
  87146. +#define TALITOS_RNGRCR 0xa018 /* RNG Reset control register */
  87147. +#define TALITOS_RNGRCR_HI 0xa01c /* RNG Reset control register */
  87148. +#define TALITOS_RNGRCR_HI_SR 0x1 /* RNG RNGRCR:Software Reset */
  87149. +
  87150. +/* descriptor pointer entry */
  87151. +struct talitos_desc_ptr {
  87152. + u16 len; /* length */
  87153. + u8 extent; /* jump (to s/g link table) and extent */
  87154. + u8 res; /* reserved */
  87155. + u32 ptr; /* pointer */
  87156. +};
  87157. +
  87158. +/* descriptor */
  87159. +struct talitos_desc {
  87160. + u32 hdr; /* header */
  87161. + u32 res; /* reserved */
  87162. + struct talitos_desc_ptr ptr[7]; /* ptr/len pair array */
  87163. +};
  87164. +
  87165. +/* talitos descriptor header (hdr) bits */
  87166. +
  87167. +/* primary execution unit select */
  87168. +#define TALITOS_SEL0_AFEU 0x10000000
  87169. +#define TALITOS_SEL0_DEU 0x20000000
  87170. +#define TALITOS_SEL0_MDEU 0x30000000
  87171. +#define TALITOS_SEL0_RNG 0x40000000
  87172. +#define TALITOS_SEL0_PKEU 0x50000000
  87173. +#define TALITOS_SEL0_AESU 0x60000000
  87174. +
  87175. +/* primary execution unit mode (MODE0) and derivatives */
  87176. +#define TALITOS_MODE0_AESU_CBC 0x00200000
  87177. +#define TALITOS_MODE0_AESU_ENC 0x00100000
  87178. +#define TALITOS_MODE0_DEU_CBC 0x00400000
  87179. +#define TALITOS_MODE0_DEU_3DES 0x00200000
  87180. +#define TALITOS_MODE0_DEU_ENC 0x00100000
  87181. +#define TALITOS_MODE0_MDEU_INIT 0x01000000 /* init starting regs */
  87182. +#define TALITOS_MODE0_MDEU_HMAC 0x00800000
  87183. +#define TALITOS_MODE0_MDEU_PAD 0x00400000 /* PD */
  87184. +#define TALITOS_MODE0_MDEU_MD5 0x00200000
  87185. +#define TALITOS_MODE0_MDEU_SHA256 0x00100000
  87186. +#define TALITOS_MODE0_MDEU_SHA1 0x00000000 /* SHA-160 */
  87187. +#define TALITOS_MODE0_MDEU_MD5_HMAC \
  87188. + (TALITOS_MODE0_MDEU_MD5 | TALITOS_MODE0_MDEU_HMAC)
  87189. +#define TALITOS_MODE0_MDEU_SHA256_HMAC \
  87190. + (TALITOS_MODE0_MDEU_SHA256 | TALITOS_MODE0_MDEU_HMAC)
  87191. +#define TALITOS_MODE0_MDEU_SHA1_HMAC \
  87192. + (TALITOS_MODE0_MDEU_SHA1 | TALITOS_MODE0_MDEU_HMAC)
  87193. +
  87194. +/* secondary execution unit select (SEL1) */
  87195. +/* it's MDEU or nothing */
  87196. +#define TALITOS_SEL1_MDEU 0x00030000
  87197. +
  87198. +/* secondary execution unit mode (MODE1) and derivatives */
  87199. +#define TALITOS_MODE1_MDEU_INIT 0x00001000 /* init starting regs */
  87200. +#define TALITOS_MODE1_MDEU_HMAC 0x00000800
  87201. +#define TALITOS_MODE1_MDEU_PAD 0x00000400 /* PD */
  87202. +#define TALITOS_MODE1_MDEU_MD5 0x00000200
  87203. +#define TALITOS_MODE1_MDEU_SHA256 0x00000100
  87204. +#define TALITOS_MODE1_MDEU_SHA1 0x00000000 /* SHA-160 */
  87205. +#define TALITOS_MODE1_MDEU_MD5_HMAC \
  87206. + (TALITOS_MODE1_MDEU_MD5 | TALITOS_MODE1_MDEU_HMAC)
  87207. +#define TALITOS_MODE1_MDEU_SHA256_HMAC \
  87208. + (TALITOS_MODE1_MDEU_SHA256 | TALITOS_MODE1_MDEU_HMAC)
  87209. +#define TALITOS_MODE1_MDEU_SHA1_HMAC \
  87210. + (TALITOS_MODE1_MDEU_SHA1 | TALITOS_MODE1_MDEU_HMAC)
  87211. +
  87212. +/* direction of overall data flow (DIR) */
  87213. +#define TALITOS_DIR_OUTBOUND 0x00000000
  87214. +#define TALITOS_DIR_INBOUND 0x00000002
  87215. +
  87216. +/* done notification (DN) */
  87217. +#define TALITOS_DONE_NOTIFY 0x00000001
  87218. +
  87219. +/* descriptor types */
  87220. +/* odd numbers here are valid on SEC2 and greater only (e.g. ipsec_esp) */
  87221. +#define TD_TYPE_AESU_CTR_NONSNOOP (0 << 3)
  87222. +#define TD_TYPE_IPSEC_ESP (1 << 3)
  87223. +#define TD_TYPE_COMMON_NONSNOOP_NO_AFEU (2 << 3)
  87224. +#define TD_TYPE_HMAC_SNOOP_NO_AFEU (4 << 3)
  87225. +
  87226. +#define TALITOS_HDR_DONE_BITS 0xff000000
  87227. +
  87228. +#define DPRINTF(a...) do { \
  87229. + if (debug) { \
  87230. + printk("%s: ", sc ? \
  87231. + device_get_nameunit(sc->sc_cdev) : "talitos"); \
  87232. + printk(a); \
  87233. + } \
  87234. + } while (0)
  87235. diff -Nur linux-2.6.35.orig/crypto/ocf/talitos/talitos_soft.h linux-2.6.35/crypto/ocf/talitos/talitos_soft.h
  87236. --- linux-2.6.35.orig/crypto/ocf/talitos/talitos_soft.h 1970-01-01 01:00:00.000000000 +0100
  87237. +++ linux-2.6.35/crypto/ocf/talitos/talitos_soft.h 2010-08-05 22:02:26.834867922 +0200
  87238. @@ -0,0 +1,77 @@
  87239. +/*
  87240. + * Freescale SEC data structures for integration with ocf-linux
  87241. + *
  87242. + * Copyright (c) 2006 Freescale Semiconductor, Inc.
  87243. + *
  87244. + * Redistribution and use in source and binary forms, with or without
  87245. + * modification, are permitted provided that the following conditions
  87246. + * are met:
  87247. + *
  87248. + * 1. Redistributions of source code must retain the above copyright
  87249. + * notice, this list of conditions and the following disclaimer.
  87250. + * 2. Redistributions in binary form must reproduce the above copyright
  87251. + * notice, this list of conditions and the following disclaimer in the
  87252. + * documentation and/or other materials provided with the distribution.
  87253. + * 3. The name of the author may not be used to endorse or promote products
  87254. + * derived from this software without specific prior written permission.
  87255. + *
  87256. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  87257. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  87258. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  87259. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  87260. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  87261. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  87262. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  87263. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  87264. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  87265. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  87266. + */
  87267. +
  87268. +/*
  87269. + * paired descriptor and associated crypto operation
  87270. + */
  87271. +struct desc_cryptop_pair {
  87272. + struct talitos_desc cf_desc; /* descriptor ptr */
  87273. + struct cryptop *cf_crp; /* cryptop ptr */
  87274. +};
  87275. +
  87276. +/*
  87277. + * Holds data specific to a single talitos device.
  87278. + */
  87279. +struct talitos_softc {
  87280. + softc_device_decl sc_cdev;
  87281. + struct platform_device *sc_dev; /* device backpointer */
  87282. + ocf_iomem_t sc_base_addr;
  87283. + int sc_irq;
  87284. + int sc_num; /* if we have multiple chips */
  87285. + int32_t sc_cid; /* crypto tag */
  87286. + u64 sc_chiprev; /* major/minor chip revision */
  87287. + int sc_nsessions;
  87288. + struct talitos_session *sc_sessions;
  87289. + int sc_num_channels;/* number of crypto channels */
  87290. + int sc_chfifo_len; /* channel fetch fifo len */
  87291. + int sc_exec_units; /* execution units mask */
  87292. + int sc_desc_types; /* descriptor types mask */
  87293. + /*
  87294. + * mutual exclusion for intra-channel resources, e.g. fetch fifos
  87295. + * the last entry is a meta-channel lock used by the channel scheduler
  87296. + */
  87297. + spinlock_t *sc_chnfifolock;
  87298. + /* sc_chnlastalgo contains last algorithm for that channel */
  87299. + int *sc_chnlastalg;
  87300. + /* sc_chnfifo holds pending descriptor--crypto operation pairs */
  87301. + struct desc_cryptop_pair **sc_chnfifo;
  87302. +};
  87303. +
  87304. +struct talitos_session {
  87305. + u_int32_t ses_used;
  87306. + u_int32_t ses_klen; /* key length in bits */
  87307. + u_int32_t ses_key[8]; /* DES/3DES/AES key */
  87308. + u_int32_t ses_hmac[5]; /* hmac inner state */
  87309. + u_int32_t ses_hmac_len; /* hmac length */
  87310. + u_int32_t ses_iv[4]; /* DES/3DES/AES iv */
  87311. + u_int32_t ses_mlen; /* desired hash result len (12=ipsec or 16) */
  87312. +};
  87313. +
  87314. +#define TALITOS_SESSION(sid) ((sid) & 0x0fffffff)
  87315. +#define TALITOS_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))
  87316. diff -Nur linux-2.6.35.orig/crypto/ocf/uio.h linux-2.6.35/crypto/ocf/uio.h
  87317. --- linux-2.6.35.orig/crypto/ocf/uio.h 1970-01-01 01:00:00.000000000 +0100
  87318. +++ linux-2.6.35/crypto/ocf/uio.h 2010-08-05 22:02:26.873911706 +0200
  87319. @@ -0,0 +1,54 @@
  87320. +#ifndef _OCF_UIO_H_
  87321. +#define _OCF_UIO_H_
  87322. +
  87323. +#include <linux/uio.h>
  87324. +
  87325. +/*
  87326. + * The linux uio.h doesn't have all we need. To be fully api compatible
  87327. + * with the BSD cryptodev, we need to keep this around. Perhaps this can
  87328. + * be moved back into the linux/uio.h
  87329. + *
  87330. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  87331. + * Copyright (C) 2006-2010 David McCullough
  87332. + * Copyright (C) 2004-2005 Intel Corporation.
  87333. + *
  87334. + * LICENSE TERMS
  87335. + *
  87336. + * The free distribution and use of this software in both source and binary
  87337. + * form is allowed (with or without changes) provided that:
  87338. + *
  87339. + * 1. distributions of this source code include the above copyright
  87340. + * notice, this list of conditions and the following disclaimer;
  87341. + *
  87342. + * 2. distributions in binary form include the above copyright
  87343. + * notice, this list of conditions and the following disclaimer
  87344. + * in the documentation and/or other associated materials;
  87345. + *
  87346. + * 3. the copyright holder's name is not used to endorse products
  87347. + * built using this software without specific written permission.
  87348. + *
  87349. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  87350. + * may be distributed under the terms of the GNU General Public License (GPL),
  87351. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  87352. + *
  87353. + * DISCLAIMER
  87354. + *
  87355. + * This software is provided 'as is' with no explicit or implied warranties
  87356. + * in respect of its properties, including, but not limited to, correctness
  87357. + * and/or fitness for purpose.
  87358. + * ---------------------------------------------------------------------------
  87359. + */
  87360. +
  87361. +struct uio {
  87362. + struct iovec *uio_iov;
  87363. + int uio_iovcnt;
  87364. + off_t uio_offset;
  87365. + int uio_resid;
  87366. +#if 0
  87367. + enum uio_seg uio_segflg;
  87368. + enum uio_rw uio_rw;
  87369. + struct thread *uio_td;
  87370. +#endif
  87371. +};
  87372. +
  87373. +#endif
  87374. diff -Nur linux-2.6.35.orig/drivers/char/random.c linux-2.6.35/drivers/char/random.c
  87375. --- linux-2.6.35.orig/drivers/char/random.c 2010-08-02 00:11:14.000000000 +0200
  87376. +++ linux-2.6.35/drivers/char/random.c 2010-08-05 22:09:46.933620629 +0200
  87377. @@ -129,6 +129,9 @@
  87378. * unsigned int value);
  87379. * void add_interrupt_randomness(int irq);
  87380. *
  87381. + * void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
  87382. + * int random_input_wait(void);
  87383. + *
  87384. * add_input_randomness() uses the input layer interrupt timing, as well as
  87385. * the event type information from the hardware.
  87386. *
  87387. @@ -140,6 +143,13 @@
  87388. * a better measure, since the timing of the disk interrupts are more
  87389. * unpredictable.
  87390. *
  87391. + * random_input_words() just provides a raw block of entropy to the input
  87392. + * pool, such as from a hardware entropy generator.
  87393. + *
  87394. + * random_input_wait() suspends the caller until such time as the
  87395. + * entropy pool falls below the write threshold, and returns a count of how
  87396. + * much entropy (in bits) is needed to sustain the pool.
  87397. + *
  87398. * All of these routines try to estimate how many bits of randomness a
  87399. * particular randomness source. They do this by keeping track of the
  87400. * first and second order deltas of the event timings.
  87401. @@ -259,6 +269,7 @@
  87402. #define SEC_XFER_SIZE 512
  87403. #define EXTRACT_SIZE 10
  87404. +
  87405. /*
  87406. * The minimum number of bits of entropy before we wake up a read on
  87407. * /dev/random. Should be enough to do a significant reseed.
  87408. @@ -552,6 +563,60 @@
  87409. spin_unlock_irqrestore(&r->lock, flags);
  87410. }
  87411. +/*
  87412. + * random_input_words - add bulk entropy to pool
  87413. + *
  87414. + * @buf: buffer to add
  87415. + * @wordcount: number of __u32 words to add
  87416. + * @ent_count: total amount of entropy (in bits) to credit
  87417. + *
  87418. + * this provides bulk input of entropy to the input pool
  87419. + *
  87420. + */
  87421. +void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
  87422. +{
  87423. + mix_pool_bytes(&input_pool, buf, wordcount*4);
  87424. +
  87425. + credit_entropy_bits(&input_pool, ent_count);
  87426. +
  87427. + DEBUG_ENT("crediting %d bits => %d\n",
  87428. + ent_count, input_pool.entropy_count);
  87429. + /*
  87430. + * Wake up waiting processes if we have enough
  87431. + * entropy.
  87432. + */
  87433. + if (input_pool.entropy_count >= random_read_wakeup_thresh)
  87434. + wake_up_interruptible(&random_read_wait);
  87435. +}
  87436. +EXPORT_SYMBOL(random_input_words);
  87437. +
  87438. +/*
  87439. + * random_input_wait - wait until random needs entropy
  87440. + *
  87441. + * this function sleeps until the /dev/random subsystem actually
  87442. + * needs more entropy, and then return the amount of entropy
  87443. + * that it would be nice to have added to the system.
  87444. + */
  87445. +int random_input_wait(void)
  87446. +{
  87447. + int count;
  87448. +
  87449. + wait_event_interruptible(random_write_wait,
  87450. + input_pool.entropy_count < random_write_wakeup_thresh);
  87451. +
  87452. + count = random_write_wakeup_thresh - input_pool.entropy_count;
  87453. +
  87454. + /* likely we got woken up due to a signal */
  87455. + if (count <= 0) count = random_read_wakeup_thresh;
  87456. +
  87457. + DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
  87458. + count,
  87459. + input_pool.entropy_count, random_write_wakeup_thresh);
  87460. +
  87461. + return count;
  87462. +}
  87463. +EXPORT_SYMBOL(random_input_wait);
  87464. +
  87465. /*********************************************************************
  87466. *
  87467. * Entropy input management
  87468. diff -Nur linux-2.6.35.orig/fs/fcntl.c linux-2.6.35/fs/fcntl.c
  87469. --- linux-2.6.35.orig/fs/fcntl.c 2010-08-02 00:11:14.000000000 +0200
  87470. +++ linux-2.6.35/fs/fcntl.c 2010-08-05 22:02:26.954868383 +0200
  87471. @@ -142,6 +142,7 @@
  87472. }
  87473. return ret;
  87474. }
  87475. +EXPORT_SYMBOL(sys_dup);
  87476. #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
  87477. diff -Nur linux-2.6.35.orig/include/linux/miscdevice.h linux-2.6.35/include/linux/miscdevice.h
  87478. --- linux-2.6.35.orig/include/linux/miscdevice.h 2010-08-02 00:11:14.000000000 +0200
  87479. +++ linux-2.6.35/include/linux/miscdevice.h 2010-08-05 22:02:27.013866494 +0200
  87480. @@ -18,6 +18,7 @@
  87481. #define APOLLO_MOUSE_MINOR 7
  87482. #define PC110PAD_MINOR 9
  87483. /*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */
  87484. +#define CRYPTODEV_MINOR 70 /* /dev/crypto */
  87485. #define WATCHDOG_MINOR 130 /* Watchdog timer */
  87486. #define TEMP_MINOR 131 /* Temperature Sensor */
  87487. #define RTC_MINOR 135
  87488. diff -Nur linux-2.6.35.orig/include/linux/random.h linux-2.6.35/include/linux/random.h
  87489. --- linux-2.6.35.orig/include/linux/random.h 2010-08-02 00:11:14.000000000 +0200
  87490. +++ linux-2.6.35/include/linux/random.h 2010-08-05 22:02:27.054867984 +0200
  87491. @@ -9,6 +9,7 @@
  87492. #include <linux/types.h>
  87493. #include <linux/ioctl.h>
  87494. +#include <linux/types.h> /* for __u32 in user space */
  87495. #include <linux/irqnr.h>
  87496. /* ioctl()'s for the random number generator */
  87497. @@ -34,6 +35,30 @@
  87498. /* Clear the entropy pool and associated counters. (Superuser only.) */
  87499. #define RNDCLEARPOOL _IO( 'R', 0x06 )
  87500. +#ifdef CONFIG_FIPS_RNG
  87501. +
  87502. +/* Size of seed value - equal to AES blocksize */
  87503. +#define AES_BLOCK_SIZE_BYTES 16
  87504. +#define SEED_SIZE_BYTES AES_BLOCK_SIZE_BYTES
  87505. +/* Size of AES key */
  87506. +#define KEY_SIZE_BYTES 16
  87507. +
  87508. +/* ioctl() structure used by FIPS 140-2 Tests */
  87509. +struct rand_fips_test {
  87510. + unsigned char key[KEY_SIZE_BYTES]; /* Input */
  87511. + unsigned char datetime[SEED_SIZE_BYTES]; /* Input */
  87512. + unsigned char seed[SEED_SIZE_BYTES]; /* Input */
  87513. + unsigned char result[SEED_SIZE_BYTES]; /* Output */
  87514. +};
  87515. +
  87516. +/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
  87517. +#define RNDFIPSVST _IOWR('R', 0x10, struct rand_fips_test)
  87518. +
  87519. +/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
  87520. +#define RNDFIPSMCT _IOWR('R', 0x11, struct rand_fips_test)
  87521. +
  87522. +#endif /* #ifdef CONFIG_FIPS_RNG */
  87523. +
  87524. struct rand_pool_info {
  87525. int entropy_count;
  87526. int buf_size;
  87527. @@ -54,6 +79,10 @@
  87528. unsigned int value);
  87529. extern void add_interrupt_randomness(int irq);
  87530. +extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count);
  87531. +extern int random_input_wait(void);
  87532. +#define HAS_RANDOM_INPUT_WAIT 1
  87533. +
  87534. extern void get_random_bytes(void *buf, int nbytes);
  87535. void generate_random_uuid(unsigned char uuid_out[16]);