ocf-20100325.patch 2.9 MB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149301503015130152301533015430155301563015730158301593016030161301623016330164301653016630167301683016930170301713017230173301743017530176301773017830179301803018130182301833018430185301863018730188301893019030191301923019330194301953019630197301983019930200302013020230203302043020530206302073020830209302103021130212302133021430215302163021730218302193022030221302223022330224302253022630227302283022930230302313023230233302343023530236302373023830239302403024130242302433024430245302463024730248302493025030251302523025330254302553025630257302583025930260302613026230263302643026530266302673026830269302703027130272302733027430275302763027730278302793028030281302823028330284302853028630287302883028930290302913029230293302943029530296302973029830299303003030130302303033030430305303063030730308303093031030311303123031330314303153031630317303183031930320303213032230323303243032530326303273032830329303303033130332303333033430335303363033730338303393034030341303423034330344303453034630347303483034930350303513035230353303543035530356303573035830359303603036130362303633036430365303663036730368303693037030371303723037330374303753037630377303783037930380303813038230383303843038530386303873038830389303903039130392303933039430395303963039730398303993040030401304023040330404304053040630407304083040930410304113041230413304143041530416304173041830419304203042130422304233042430425304263042730428304293043030431304323043330434304353043630437304383043930440304413044230443304443044530446304473044830449304503045130452304533045430455304563045730458304593046030461304623046330464304653046630467304683046930470304713047230473304743047530476304773047830479304803048130482304833048430485304863048730488304893049030491304923049330494304953049630497304983049930500305013050230503305043050530506305073050830509305103051130512305133051430515305163051730518305193052030521305223052330524305253052630527305283052930530305313053230533305343053530536305373053830539305403054130542305433054430545305463054730548305493055030551305523055330554305553055630557305583055930560305613056230563305643056530566305673056830569305703057130572305733057430575305763057730578305793058030581305823058330584305853058630587305883058930590305913059230593305943059530596305973059830599306003060130602306033060430605306063060730608306093061030611306123061330614306153061630617306183061930620306213062230623306243062530626306273062830629306303063130632306333063430635306363063730638306393064030641306423064330644306453064630647306483064930650306513065230653306543065530656306573065830659306603066130662306633066430665306663066730668306693067030671306723067330674306753067630677306783067930680306813068230683306843068530686306873068830689306903069130692306933069430695306963069730698306993070030701307023070330704307053070630707307083070930710307113071230713307143071530716307173071830719307203072130722307233072430725307263072730728307293073030731307323073330734307353073630737307383073930740307413074230743307443074530746307473074830749307503075130752307533075430755307563075730758307593076030761307623076330764307653076630767307683076930770307713077230773307743077530776307773077830779307803078130782307833078430785307863078730788307893079030791307923079330794307953079630797307983079930800308013080230803308043080530806308073080830809308103081130812308133081430815308163081730818308193082030821308223082330824308253082630827308283082930830308313083230833308343083530836308373083830839308403084130842308433084430845308463084730848308493085030851308523085330854308553085630857308583085930860308613086230863308643086530866308673086830869308703087130872308733087430875308763087730878308793088030881308823088330884308853088630887308883088930890308913089230893308943089530896308973089830899309003090130902309033090430905309063090730908309093091030911309123091330914309153091630917309183091930920309213092230923309243092530926309273092830929309303093130932309333093430935309363093730938309393094030941309423094330944309453094630947309483094930950309513095230953309543095530956309573095830959309603096130962309633096430965309663096730968309693097030971309723097330974309753097630977309783097930980309813098230983309843098530986309873098830989309903099130992309933099430995309963099730998309993100031001310023100331004310053100631007310083100931010310113101231013310143101531016310173101831019310203102131022310233102431025310263102731028310293103031031310323103331034310353103631037310383103931040310413104231043310443104531046310473104831049310503105131052310533105431055310563105731058310593106031061310623106331064310653106631067310683106931070310713107231073310743107531076310773107831079310803108131082310833108431085310863108731088310893109031091310923109331094310953109631097310983109931100311013110231103311043110531106311073110831109311103111131112311133111431115311163111731118311193112031121311223112331124311253112631127311283112931130311313113231133311343113531136311373113831139311403114131142311433114431145311463114731148311493115031151311523115331154311553115631157311583115931160311613116231163311643116531166311673116831169311703117131172311733117431175311763117731178311793118031181311823118331184311853118631187311883118931190311913119231193311943119531196311973119831199312003120131202312033120431205312063120731208312093121031211312123121331214312153121631217312183121931220312213122231223312243122531226312273122831229312303123131232312333123431235312363123731238312393124031241312423124331244312453124631247312483124931250312513125231253312543125531256312573125831259312603126131262312633126431265312663126731268312693127031271312723127331274312753127631277312783127931280312813128231283312843128531286312873128831289312903129131292312933129431295312963129731298312993130031301313023130331304313053130631307313083130931310313113131231313313143131531316313173131831319313203132131322313233132431325313263132731328313293133031331313323133331334313353133631337313383133931340313413134231343313443134531346313473134831349313503135131352313533135431355313563135731358313593136031361313623136331364313653136631367313683136931370313713137231373313743137531376313773137831379313803138131382313833138431385313863138731388313893139031391313923139331394313953139631397313983139931400314013140231403314043140531406314073140831409314103141131412314133141431415314163141731418314193142031421314223142331424314253142631427314283142931430314313143231433314343143531436314373143831439314403144131442314433144431445314463144731448314493145031451314523145331454314553145631457314583145931460314613146231463314643146531466314673146831469314703147131472314733147431475314763147731478314793148031481314823148331484314853148631487314883148931490314913149231493314943149531496314973149831499315003150131502315033150431505315063150731508315093151031511315123151331514315153151631517315183151931520315213152231523315243152531526315273152831529315303153131532315333153431535315363153731538315393154031541315423154331544315453154631547315483154931550315513155231553315543155531556315573155831559315603156131562315633156431565315663156731568315693157031571315723157331574315753157631577315783157931580315813158231583315843158531586315873158831589315903159131592315933159431595315963159731598315993160031601316023160331604316053160631607316083160931610316113161231613316143161531616316173161831619316203162131622316233162431625316263162731628316293163031631316323163331634316353163631637316383163931640316413164231643316443164531646316473164831649316503165131652316533165431655316563165731658316593166031661316623166331664316653166631667316683166931670316713167231673316743167531676316773167831679316803168131682316833168431685316863168731688316893169031691316923169331694316953169631697316983169931700317013170231703317043170531706317073170831709317103171131712317133171431715317163171731718317193172031721317223172331724317253172631727317283172931730317313173231733317343173531736317373173831739317403174131742317433174431745317463174731748317493175031751317523175331754317553175631757317583175931760317613176231763317643176531766317673176831769317703177131772317733177431775317763177731778317793178031781317823178331784317853178631787317883178931790317913179231793317943179531796317973179831799318003180131802318033180431805318063180731808318093181031811318123181331814318153181631817318183181931820318213182231823318243182531826318273182831829318303183131832318333183431835318363183731838318393184031841318423184331844318453184631847318483184931850318513185231853318543185531856318573185831859318603186131862318633186431865318663186731868318693187031871318723187331874318753187631877318783187931880318813188231883318843188531886318873188831889318903189131892318933189431895318963189731898318993190031901319023190331904319053190631907319083190931910319113191231913319143191531916319173191831919319203192131922319233192431925319263192731928319293193031931319323193331934319353193631937319383193931940319413194231943319443194531946319473194831949319503195131952319533195431955319563195731958319593196031961319623196331964319653196631967319683196931970319713197231973319743197531976319773197831979319803198131982319833198431985319863198731988319893199031991319923199331994319953199631997319983199932000320013200232003320043200532006320073200832009320103201132012320133201432015320163201732018320193202032021320223202332024320253202632027320283202932030320313203232033320343203532036320373203832039320403204132042320433204432045320463204732048320493205032051320523205332054320553205632057320583205932060320613206232063320643206532066320673206832069320703207132072320733207432075320763207732078320793208032081320823208332084320853208632087320883208932090320913209232093320943209532096320973209832099321003210132102321033210432105321063210732108321093211032111321123211332114321153211632117321183211932120321213212232123321243212532126321273212832129321303213132132321333213432135321363213732138321393214032141321423214332144321453214632147321483214932150321513215232153321543215532156321573215832159321603216132162321633216432165321663216732168321693217032171321723217332174321753217632177321783217932180321813218232183321843218532186321873218832189321903219132192321933219432195321963219732198321993220032201322023220332204322053220632207322083220932210322113221232213322143221532216322173221832219322203222132222322233222432225322263222732228322293223032231322323223332234322353223632237322383223932240322413224232243322443224532246322473224832249322503225132252322533225432255322563225732258322593226032261322623226332264322653226632267322683226932270322713227232273322743227532276322773227832279322803228132282322833228432285322863228732288322893229032291322923229332294322953229632297322983229932300323013230232303323043230532306323073230832309323103231132312323133231432315323163231732318323193232032321323223232332324323253232632327323283232932330323313233232333323343233532336323373233832339323403234132342323433234432345323463234732348323493235032351323523235332354323553235632357323583235932360323613236232363323643236532366323673236832369323703237132372323733237432375323763237732378323793238032381323823238332384323853238632387323883238932390323913239232393323943239532396323973239832399324003240132402324033240432405324063240732408324093241032411324123241332414324153241632417324183241932420324213242232423324243242532426324273242832429324303243132432324333243432435324363243732438324393244032441324423244332444324453244632447324483244932450324513245232453324543245532456324573245832459324603246132462324633246432465324663246732468324693247032471324723247332474324753247632477324783247932480324813248232483324843248532486324873248832489324903249132492324933249432495324963249732498324993250032501325023250332504325053250632507325083250932510325113251232513325143251532516325173251832519325203252132522325233252432525325263252732528325293253032531325323253332534325353253632537325383253932540325413254232543325443254532546325473254832549325503255132552325533255432555325563255732558325593256032561325623256332564325653256632567325683256932570325713257232573325743257532576325773257832579325803258132582325833258432585325863258732588325893259032591325923259332594325953259632597325983259932600326013260232603326043260532606326073260832609326103261132612326133261432615326163261732618326193262032621326223262332624326253262632627326283262932630326313263232633326343263532636326373263832639326403264132642326433264432645326463264732648326493265032651326523265332654326553265632657326583265932660326613266232663326643266532666326673266832669326703267132672326733267432675326763267732678326793268032681326823268332684326853268632687326883268932690326913269232693326943269532696326973269832699327003270132702327033270432705327063270732708327093271032711327123271332714327153271632717327183271932720327213272232723327243272532726327273272832729327303273132732327333273432735327363273732738327393274032741327423274332744327453274632747327483274932750327513275232753327543275532756327573275832759327603276132762327633276432765327663276732768327693277032771327723277332774327753277632777327783277932780327813278232783327843278532786327873278832789327903279132792327933279432795327963279732798327993280032801328023280332804328053280632807328083280932810328113281232813328143281532816328173281832819328203282132822328233282432825328263282732828328293283032831328323283332834328353283632837328383283932840328413284232843328443284532846328473284832849328503285132852328533285432855328563285732858328593286032861328623286332864328653286632867328683286932870328713287232873328743287532876328773287832879328803288132882328833288432885328863288732888328893289032891328923289332894328953289632897328983289932900329013290232903329043290532906329073290832909329103291132912329133291432915329163291732918329193292032921329223292332924329253292632927329283292932930329313293232933329343293532936329373293832939329403294132942329433294432945329463294732948329493295032951329523295332954329553295632957329583295932960329613296232963329643296532966329673296832969329703297132972329733297432975329763297732978329793298032981329823298332984329853298632987329883298932990329913299232993329943299532996329973299832999330003300133002330033300433005330063300733008330093301033011330123301333014330153301633017330183301933020330213302233023330243302533026330273302833029330303303133032330333303433035330363303733038330393304033041330423304333044330453304633047330483304933050330513305233053330543305533056330573305833059330603306133062330633306433065330663306733068330693307033071330723307333074330753307633077330783307933080330813308233083330843308533086330873308833089330903309133092330933309433095330963309733098330993310033101331023310333104331053310633107331083310933110331113311233113331143311533116331173311833119331203312133122331233312433125331263312733128331293313033131331323313333134331353313633137331383313933140331413314233143331443314533146331473314833149331503315133152331533315433155331563315733158331593316033161331623316333164331653316633167331683316933170331713317233173331743317533176331773317833179331803318133182331833318433185331863318733188331893319033191331923319333194331953319633197331983319933200332013320233203332043320533206332073320833209332103321133212332133321433215332163321733218332193322033221332223322333224332253322633227332283322933230332313323233233332343323533236332373323833239332403324133242332433324433245332463324733248332493325033251332523325333254332553325633257332583325933260332613326233263332643326533266332673326833269332703327133272332733327433275332763327733278332793328033281332823328333284332853328633287332883328933290332913329233293332943329533296332973329833299333003330133302333033330433305333063330733308333093331033311333123331333314333153331633317333183331933320333213332233323333243332533326333273332833329333303333133332333333333433335333363333733338333393334033341333423334333344333453334633347333483334933350333513335233353333543335533356333573335833359333603336133362333633336433365333663336733368333693337033371333723337333374333753337633377333783337933380333813338233383333843338533386333873338833389333903339133392333933339433395333963339733398333993340033401334023340333404334053340633407334083340933410334113341233413334143341533416334173341833419334203342133422334233342433425334263342733428334293343033431334323343333434334353343633437334383343933440334413344233443334443344533446334473344833449334503345133452334533345433455334563345733458334593346033461334623346333464334653346633467334683346933470334713347233473334743347533476334773347833479334803348133482334833348433485334863348733488334893349033491334923349333494334953349633497334983349933500335013350233503335043350533506335073350833509335103351133512335133351433515335163351733518335193352033521335223352333524335253352633527335283352933530335313353233533335343353533536335373353833539335403354133542335433354433545335463354733548335493355033551335523355333554335553355633557335583355933560335613356233563335643356533566335673356833569335703357133572335733357433575335763357733578335793358033581335823358333584335853358633587335883358933590335913359233593335943359533596335973359833599336003360133602336033360433605336063360733608336093361033611336123361333614336153361633617336183361933620336213362233623336243362533626336273362833629336303363133632336333363433635336363363733638336393364033641336423364333644336453364633647336483364933650336513365233653336543365533656336573365833659336603366133662336633366433665336663366733668336693367033671336723367333674336753367633677336783367933680336813368233683336843368533686336873368833689336903369133692336933369433695336963369733698336993370033701337023370333704337053370633707337083370933710337113371233713337143371533716337173371833719337203372133722337233372433725337263372733728337293373033731337323373333734337353373633737337383373933740337413374233743337443374533746337473374833749337503375133752337533375433755337563375733758337593376033761337623376333764337653376633767337683376933770337713377233773337743377533776337773377833779337803378133782337833378433785337863378733788337893379033791337923379333794337953379633797337983379933800338013380233803338043380533806338073380833809338103381133812338133381433815338163381733818338193382033821338223382333824338253382633827338283382933830338313383233833338343383533836338373383833839338403384133842338433384433845338463384733848338493385033851338523385333854338553385633857338583385933860338613386233863338643386533866338673386833869338703387133872338733387433875338763387733878338793388033881338823388333884338853388633887338883388933890338913389233893338943389533896338973389833899339003390133902339033390433905339063390733908339093391033911339123391333914339153391633917339183391933920339213392233923339243392533926339273392833929339303393133932339333393433935339363393733938339393394033941339423394333944339453394633947339483394933950339513395233953339543395533956339573395833959339603396133962339633396433965339663396733968339693397033971339723397333974339753397633977339783397933980339813398233983339843398533986339873398833989339903399133992339933399433995339963399733998339993400034001340023400334004340053400634007340083400934010340113401234013340143401534016340173401834019340203402134022340233402434025340263402734028340293403034031340323403334034340353403634037340383403934040340413404234043340443404534046340473404834049340503405134052340533405434055340563405734058340593406034061340623406334064340653406634067340683406934070340713407234073340743407534076340773407834079340803408134082340833408434085340863408734088340893409034091340923409334094340953409634097340983409934100341013410234103341043410534106341073410834109341103411134112341133411434115341163411734118341193412034121341223412334124341253412634127341283412934130341313413234133341343413534136341373413834139341403414134142341433414434145341463414734148341493415034151341523415334154341553415634157341583415934160341613416234163341643416534166341673416834169341703417134172341733417434175341763417734178341793418034181341823418334184341853418634187341883418934190341913419234193341943419534196341973419834199342003420134202342033420434205342063420734208342093421034211342123421334214342153421634217342183421934220342213422234223342243422534226342273422834229342303423134232342333423434235342363423734238342393424034241342423424334244342453424634247342483424934250342513425234253342543425534256342573425834259342603426134262342633426434265342663426734268342693427034271342723427334274342753427634277342783427934280342813428234283342843428534286342873428834289342903429134292342933429434295342963429734298342993430034301343023430334304343053430634307343083430934310343113431234313343143431534316343173431834319343203432134322343233432434325343263432734328343293433034331343323433334334343353433634337343383433934340343413434234343343443434534346343473434834349343503435134352343533435434355343563435734358343593436034361343623436334364343653436634367343683436934370343713437234373343743437534376343773437834379343803438134382343833438434385343863438734388343893439034391343923439334394343953439634397343983439934400344013440234403344043440534406344073440834409344103441134412344133441434415344163441734418344193442034421344223442334424344253442634427344283442934430344313443234433344343443534436344373443834439344403444134442344433444434445344463444734448344493445034451344523445334454344553445634457344583445934460344613446234463344643446534466344673446834469344703447134472344733447434475344763447734478344793448034481344823448334484344853448634487344883448934490344913449234493344943449534496344973449834499345003450134502345033450434505345063450734508345093451034511345123451334514345153451634517345183451934520345213452234523345243452534526345273452834529345303453134532345333453434535345363453734538345393454034541345423454334544345453454634547345483454934550345513455234553345543455534556345573455834559345603456134562345633456434565345663456734568345693457034571345723457334574345753457634577345783457934580345813458234583345843458534586345873458834589345903459134592345933459434595345963459734598345993460034601346023460334604346053460634607346083460934610346113461234613346143461534616346173461834619346203462134622346233462434625346263462734628346293463034631346323463334634346353463634637346383463934640346413464234643346443464534646346473464834649346503465134652346533465434655346563465734658346593466034661346623466334664346653466634667346683466934670346713467234673346743467534676346773467834679346803468134682346833468434685346863468734688346893469034691346923469334694346953469634697346983469934700347013470234703347043470534706347073470834709347103471134712347133471434715347163471734718347193472034721347223472334724347253472634727347283472934730347313473234733347343473534736347373473834739347403474134742347433474434745347463474734748347493475034751347523475334754347553475634757347583475934760347613476234763347643476534766347673476834769347703477134772347733477434775347763477734778347793478034781347823478334784347853478634787347883478934790347913479234793347943479534796347973479834799348003480134802348033480434805348063480734808348093481034811348123481334814348153481634817348183481934820348213482234823348243482534826348273482834829348303483134832348333483434835348363483734838348393484034841348423484334844348453484634847348483484934850348513485234853348543485534856348573485834859348603486134862348633486434865348663486734868348693487034871348723487334874348753487634877348783487934880348813488234883348843488534886348873488834889348903489134892348933489434895348963489734898348993490034901349023490334904349053490634907349083490934910349113491234913349143491534916349173491834919349203492134922349233492434925349263492734928349293493034931349323493334934349353493634937349383493934940349413494234943349443494534946349473494834949349503495134952349533495434955349563495734958349593496034961349623496334964349653496634967349683496934970349713497234973349743497534976349773497834979349803498134982349833498434985349863498734988349893499034991349923499334994349953499634997349983499935000350013500235003350043500535006350073500835009350103501135012350133501435015350163501735018350193502035021350223502335024350253502635027350283502935030350313503235033350343503535036350373503835039350403504135042350433504435045350463504735048350493505035051350523505335054350553505635057350583505935060350613506235063350643506535066350673506835069350703507135072350733507435075350763507735078350793508035081350823508335084350853508635087350883508935090350913509235093350943509535096350973509835099351003510135102351033510435105351063510735108351093511035111351123511335114351153511635117351183511935120351213512235123351243512535126351273512835129351303513135132351333513435135351363513735138351393514035141351423514335144351453514635147351483514935150351513515235153351543515535156351573515835159351603516135162351633516435165351663516735168351693517035171351723517335174351753517635177351783517935180351813518235183351843518535186351873518835189351903519135192351933519435195351963519735198351993520035201352023520335204352053520635207352083520935210352113521235213352143521535216352173521835219352203522135222352233522435225352263522735228352293523035231352323523335234352353523635237352383523935240352413524235243352443524535246352473524835249352503525135252352533525435255352563525735258352593526035261352623526335264352653526635267352683526935270352713527235273352743527535276352773527835279352803528135282352833528435285352863528735288352893529035291352923529335294352953529635297352983529935300353013530235303353043530535306353073530835309353103531135312353133531435315353163531735318353193532035321353223532335324353253532635327353283532935330353313533235333353343533535336353373533835339353403534135342353433534435345353463534735348353493535035351353523535335354353553535635357353583535935360353613536235363353643536535366353673536835369353703537135372353733537435375353763537735378353793538035381353823538335384353853538635387353883538935390353913539235393353943539535396353973539835399354003540135402354033540435405354063540735408354093541035411354123541335414354153541635417354183541935420354213542235423354243542535426354273542835429354303543135432354333543435435354363543735438354393544035441354423544335444354453544635447354483544935450354513545235453354543545535456354573545835459354603546135462354633546435465354663546735468354693547035471354723547335474354753547635477354783547935480354813548235483354843548535486354873548835489354903549135492354933549435495354963549735498354993550035501355023550335504355053550635507355083550935510355113551235513355143551535516355173551835519355203552135522355233552435525355263552735528355293553035531355323553335534355353553635537355383553935540355413554235543355443554535546355473554835549355503555135552355533555435555355563555735558355593556035561355623556335564355653556635567355683556935570355713557235573355743557535576355773557835579355803558135582355833558435585355863558735588355893559035591355923559335594355953559635597355983559935600356013560235603356043560535606356073560835609356103561135612356133561435615356163561735618356193562035621356223562335624356253562635627356283562935630356313563235633356343563535636356373563835639356403564135642356433564435645356463564735648356493565035651356523565335654356553565635657356583565935660356613566235663356643566535666356673566835669356703567135672356733567435675356763567735678356793568035681356823568335684356853568635687356883568935690356913569235693356943569535696356973569835699357003570135702357033570435705357063570735708357093571035711357123571335714357153571635717357183571935720357213572235723357243572535726357273572835729357303573135732357333573435735357363573735738357393574035741357423574335744357453574635747357483574935750357513575235753357543575535756357573575835759357603576135762357633576435765357663576735768357693577035771357723577335774357753577635777357783577935780357813578235783357843578535786357873578835789357903579135792357933579435795357963579735798357993580035801358023580335804358053580635807358083580935810358113581235813358143581535816358173581835819358203582135822358233582435825358263582735828358293583035831358323583335834358353583635837358383583935840358413584235843358443584535846358473584835849358503585135852358533585435855358563585735858358593586035861358623586335864358653586635867358683586935870358713587235873358743587535876358773587835879358803588135882358833588435885358863588735888358893589035891358923589335894358953589635897358983589935900359013590235903359043590535906359073590835909359103591135912359133591435915359163591735918359193592035921359223592335924359253592635927359283592935930359313593235933359343593535936359373593835939359403594135942359433594435945359463594735948359493595035951359523595335954359553595635957359583595935960359613596235963359643596535966359673596835969359703597135972359733597435975359763597735978359793598035981359823598335984359853598635987359883598935990359913599235993359943599535996359973599835999360003600136002360033600436005360063600736008360093601036011360123601336014360153601636017360183601936020360213602236023360243602536026360273602836029360303603136032360333603436035360363603736038360393604036041360423604336044360453604636047360483604936050360513605236053360543605536056360573605836059360603606136062360633606436065360663606736068360693607036071360723607336074360753607636077360783607936080360813608236083360843608536086360873608836089360903609136092360933609436095360963609736098360993610036101361023610336104361053610636107361083610936110361113611236113361143611536116361173611836119361203612136122361233612436125361263612736128361293613036131361323613336134361353613636137361383613936140361413614236143361443614536146361473614836149361503615136152361533615436155361563615736158361593616036161361623616336164361653616636167361683616936170361713617236173361743617536176361773617836179361803618136182361833618436185361863618736188361893619036191361923619336194361953619636197361983619936200362013620236203362043620536206362073620836209362103621136212362133621436215362163621736218362193622036221362223622336224362253622636227362283622936230362313623236233362343623536236362373623836239362403624136242362433624436245362463624736248362493625036251362523625336254362553625636257362583625936260362613626236263362643626536266362673626836269362703627136272362733627436275362763627736278362793628036281362823628336284362853628636287362883628936290362913629236293362943629536296362973629836299363003630136302363033630436305363063630736308363093631036311363123631336314363153631636317363183631936320363213632236323363243632536326363273632836329363303633136332363333633436335363363633736338363393634036341363423634336344363453634636347363483634936350363513635236353363543635536356363573635836359363603636136362363633636436365363663636736368363693637036371363723637336374363753637636377363783637936380363813638236383363843638536386363873638836389363903639136392363933639436395363963639736398363993640036401364023640336404364053640636407364083640936410364113641236413364143641536416364173641836419364203642136422364233642436425364263642736428364293643036431364323643336434364353643636437364383643936440364413644236443364443644536446364473644836449364503645136452364533645436455364563645736458364593646036461364623646336464364653646636467364683646936470364713647236473364743647536476364773647836479364803648136482364833648436485364863648736488364893649036491364923649336494364953649636497364983649936500365013650236503365043650536506365073650836509365103651136512365133651436515365163651736518365193652036521365223652336524365253652636527365283652936530365313653236533365343653536536365373653836539365403654136542365433654436545365463654736548365493655036551365523655336554365553655636557365583655936560365613656236563365643656536566365673656836569365703657136572365733657436575365763657736578365793658036581365823658336584365853658636587365883658936590365913659236593365943659536596365973659836599366003660136602366033660436605366063660736608366093661036611366123661336614366153661636617366183661936620366213662236623366243662536626366273662836629366303663136632366333663436635366363663736638366393664036641366423664336644366453664636647366483664936650366513665236653366543665536656366573665836659366603666136662366633666436665366663666736668366693667036671366723667336674366753667636677366783667936680366813668236683366843668536686366873668836689366903669136692366933669436695366963669736698366993670036701367023670336704367053670636707367083670936710367113671236713367143671536716367173671836719367203672136722367233672436725367263672736728367293673036731367323673336734367353673636737367383673936740367413674236743367443674536746367473674836749367503675136752367533675436755367563675736758367593676036761367623676336764367653676636767367683676936770367713677236773367743677536776367773677836779367803678136782367833678436785367863678736788367893679036791367923679336794367953679636797367983679936800368013680236803368043680536806368073680836809368103681136812368133681436815368163681736818368193682036821368223682336824368253682636827368283682936830368313683236833368343683536836368373683836839368403684136842368433684436845368463684736848368493685036851368523685336854368553685636857368583685936860368613686236863368643686536866368673686836869368703687136872368733687436875368763687736878368793688036881368823688336884368853688636887368883688936890368913689236893368943689536896368973689836899369003690136902369033690436905369063690736908369093691036911369123691336914369153691636917369183691936920369213692236923369243692536926369273692836929369303693136932369333693436935369363693736938369393694036941369423694336944369453694636947369483694936950369513695236953369543695536956369573695836959369603696136962369633696436965369663696736968369693697036971369723697336974369753697636977369783697936980369813698236983369843698536986369873698836989369903699136992369933699436995369963699736998369993700037001370023700337004370053700637007370083700937010370113701237013370143701537016370173701837019370203702137022370233702437025370263702737028370293703037031370323703337034370353703637037370383703937040370413704237043370443704537046370473704837049370503705137052370533705437055370563705737058370593706037061370623706337064370653706637067370683706937070370713707237073370743707537076370773707837079370803708137082370833708437085370863708737088370893709037091370923709337094370953709637097370983709937100371013710237103371043710537106371073710837109371103711137112371133711437115371163711737118371193712037121371223712337124371253712637127371283712937130371313713237133371343713537136371373713837139371403714137142371433714437145371463714737148371493715037151371523715337154371553715637157371583715937160371613716237163371643716537166371673716837169371703717137172371733717437175371763717737178371793718037181371823718337184371853718637187371883718937190371913719237193371943719537196371973719837199372003720137202372033720437205372063720737208372093721037211372123721337214372153721637217372183721937220372213722237223372243722537226372273722837229372303723137232372333723437235372363723737238372393724037241372423724337244372453724637247372483724937250372513725237253372543725537256372573725837259372603726137262372633726437265372663726737268372693727037271372723727337274372753727637277372783727937280372813728237283372843728537286372873728837289372903729137292372933729437295372963729737298372993730037301373023730337304373053730637307373083730937310373113731237313373143731537316373173731837319373203732137322373233732437325373263732737328373293733037331373323733337334373353733637337373383733937340373413734237343373443734537346373473734837349373503735137352373533735437355373563735737358373593736037361373623736337364373653736637367373683736937370373713737237373373743737537376373773737837379373803738137382373833738437385373863738737388373893739037391373923739337394373953739637397373983739937400374013740237403374043740537406374073740837409374103741137412374133741437415374163741737418374193742037421374223742337424374253742637427374283742937430374313743237433374343743537436374373743837439374403744137442374433744437445374463744737448374493745037451374523745337454374553745637457374583745937460374613746237463374643746537466374673746837469374703747137472374733747437475374763747737478374793748037481374823748337484374853748637487374883748937490374913749237493374943749537496374973749837499375003750137502375033750437505375063750737508375093751037511375123751337514375153751637517375183751937520375213752237523375243752537526375273752837529375303753137532375333753437535375363753737538375393754037541375423754337544375453754637547375483754937550375513755237553375543755537556375573755837559375603756137562375633756437565375663756737568375693757037571375723757337574375753757637577375783757937580375813758237583375843758537586375873758837589375903759137592375933759437595375963759737598375993760037601376023760337604376053760637607376083760937610376113761237613376143761537616376173761837619376203762137622376233762437625376263762737628376293763037631376323763337634376353763637637376383763937640376413764237643376443764537646376473764837649376503765137652376533765437655376563765737658376593766037661376623766337664376653766637667376683766937670376713767237673376743767537676376773767837679376803768137682376833768437685376863768737688376893769037691376923769337694376953769637697376983769937700377013770237703377043770537706377073770837709377103771137712377133771437715377163771737718377193772037721377223772337724377253772637727377283772937730377313773237733377343773537736377373773837739377403774137742377433774437745377463774737748377493775037751377523775337754377553775637757377583775937760377613776237763377643776537766377673776837769377703777137772377733777437775377763777737778377793778037781377823778337784377853778637787377883778937790377913779237793377943779537796377973779837799378003780137802378033780437805378063780737808378093781037811378123781337814378153781637817378183781937820378213782237823378243782537826378273782837829378303783137832378333783437835378363783737838378393784037841378423784337844378453784637847378483784937850378513785237853378543785537856378573785837859378603786137862378633786437865378663786737868378693787037871378723787337874378753787637877378783787937880378813788237883378843788537886378873788837889378903789137892378933789437895378963789737898378993790037901379023790337904379053790637907379083790937910379113791237913379143791537916379173791837919379203792137922379233792437925379263792737928379293793037931379323793337934379353793637937379383793937940379413794237943379443794537946379473794837949379503795137952379533795437955379563795737958379593796037961379623796337964379653796637967379683796937970379713797237973379743797537976379773797837979379803798137982379833798437985379863798737988379893799037991379923799337994379953799637997379983799938000380013800238003380043800538006380073800838009380103801138012380133801438015380163801738018380193802038021380223802338024380253802638027380283802938030380313803238033380343803538036380373803838039380403804138042380433804438045380463804738048380493805038051380523805338054380553805638057380583805938060380613806238063380643806538066380673806838069380703807138072380733807438075380763807738078380793808038081380823808338084380853808638087380883808938090380913809238093380943809538096380973809838099381003810138102381033810438105381063810738108381093811038111381123811338114381153811638117381183811938120381213812238123381243812538126381273812838129381303813138132381333813438135381363813738138381393814038141381423814338144381453814638147381483814938150381513815238153381543815538156381573815838159381603816138162381633816438165381663816738168381693817038171381723817338174381753817638177381783817938180381813818238183381843818538186381873818838189381903819138192381933819438195381963819738198381993820038201382023820338204382053820638207382083820938210382113821238213382143821538216382173821838219382203822138222382233822438225382263822738228382293823038231382323823338234382353823638237382383823938240382413824238243382443824538246382473824838249382503825138252382533825438255382563825738258382593826038261382623826338264382653826638267382683826938270382713827238273382743827538276382773827838279382803828138282382833828438285382863828738288382893829038291382923829338294382953829638297382983829938300383013830238303383043830538306383073830838309383103831138312383133831438315383163831738318383193832038321383223832338324383253832638327383283832938330383313833238333383343833538336383373833838339383403834138342383433834438345383463834738348383493835038351383523835338354383553835638357383583835938360383613836238363383643836538366383673836838369383703837138372383733837438375383763837738378383793838038381383823838338384383853838638387383883838938390383913839238393383943839538396383973839838399384003840138402384033840438405384063840738408384093841038411384123841338414384153841638417384183841938420384213842238423384243842538426384273842838429384303843138432384333843438435384363843738438384393844038441384423844338444384453844638447384483844938450384513845238453384543845538456384573845838459384603846138462384633846438465384663846738468384693847038471384723847338474384753847638477384783847938480384813848238483384843848538486384873848838489384903849138492384933849438495384963849738498384993850038501385023850338504385053850638507385083850938510385113851238513385143851538516385173851838519385203852138522385233852438525385263852738528385293853038531385323853338534385353853638537385383853938540385413854238543385443854538546385473854838549385503855138552385533855438555385563855738558385593856038561385623856338564385653856638567385683856938570385713857238573385743857538576385773857838579385803858138582385833858438585385863858738588385893859038591385923859338594385953859638597385983859938600386013860238603386043860538606386073860838609386103861138612386133861438615386163861738618386193862038621386223862338624386253862638627386283862938630386313863238633386343863538636386373863838639386403864138642386433864438645386463864738648386493865038651386523865338654386553865638657386583865938660386613866238663386643866538666386673866838669386703867138672386733867438675386763867738678386793868038681386823868338684386853868638687386883868938690386913869238693386943869538696386973869838699387003870138702387033870438705387063870738708387093871038711387123871338714387153871638717387183871938720387213872238723387243872538726387273872838729387303873138732387333873438735387363873738738387393874038741387423874338744387453874638747387483874938750387513875238753387543875538756387573875838759387603876138762387633876438765387663876738768387693877038771387723877338774387753877638777387783877938780387813878238783387843878538786387873878838789387903879138792387933879438795387963879738798387993880038801388023880338804388053880638807388083880938810388113881238813388143881538816388173881838819388203882138822388233882438825388263882738828388293883038831388323883338834388353883638837388383883938840388413884238843388443884538846388473884838849388503885138852388533885438855388563885738858388593886038861388623886338864388653886638867388683886938870388713887238873388743887538876388773887838879388803888138882388833888438885388863888738888388893889038891388923889338894388953889638897388983889938900389013890238903389043890538906389073890838909389103891138912389133891438915389163891738918389193892038921389223892338924389253892638927389283892938930389313893238933389343893538936389373893838939389403894138942389433894438945389463894738948389493895038951389523895338954389553895638957389583895938960389613896238963389643896538966389673896838969389703897138972389733897438975389763897738978389793898038981389823898338984389853898638987389883898938990389913899238993389943899538996389973899838999390003900139002390033900439005390063900739008390093901039011390123901339014390153901639017390183901939020390213902239023390243902539026390273902839029390303903139032390333903439035390363903739038390393904039041390423904339044390453904639047390483904939050390513905239053390543905539056390573905839059390603906139062390633906439065390663906739068390693907039071390723907339074390753907639077390783907939080390813908239083390843908539086390873908839089390903909139092390933909439095390963909739098390993910039101391023910339104391053910639107391083910939110391113911239113391143911539116391173911839119391203912139122391233912439125391263912739128391293913039131391323913339134391353913639137391383913939140391413914239143391443914539146391473914839149391503915139152391533915439155391563915739158391593916039161391623916339164391653916639167391683916939170391713917239173391743917539176391773917839179391803918139182391833918439185391863918739188391893919039191391923919339194391953919639197391983919939200392013920239203392043920539206392073920839209392103921139212392133921439215392163921739218392193922039221392223922339224392253922639227392283922939230392313923239233392343923539236392373923839239392403924139242392433924439245392463924739248392493925039251392523925339254392553925639257392583925939260392613926239263392643926539266392673926839269392703927139272392733927439275392763927739278392793928039281392823928339284392853928639287392883928939290392913929239293392943929539296392973929839299393003930139302393033930439305393063930739308393093931039311393123931339314393153931639317393183931939320393213932239323393243932539326393273932839329393303933139332393333933439335393363933739338393393934039341393423934339344393453934639347393483934939350393513935239353393543935539356393573935839359393603936139362393633936439365393663936739368393693937039371393723937339374393753937639377393783937939380393813938239383393843938539386393873938839389393903939139392393933939439395393963939739398393993940039401394023940339404394053940639407394083940939410394113941239413394143941539416394173941839419394203942139422394233942439425394263942739428394293943039431394323943339434394353943639437394383943939440394413944239443394443944539446394473944839449394503945139452394533945439455394563945739458394593946039461394623946339464394653946639467394683946939470394713947239473394743947539476394773947839479394803948139482394833948439485394863948739488394893949039491394923949339494394953949639497394983949939500395013950239503395043950539506395073950839509395103951139512395133951439515395163951739518395193952039521395223952339524395253952639527395283952939530395313953239533395343953539536395373953839539395403954139542395433954439545395463954739548395493955039551395523955339554395553955639557395583955939560395613956239563395643956539566395673956839569395703957139572395733957439575395763957739578395793958039581395823958339584395853958639587395883958939590395913959239593395943959539596395973959839599396003960139602396033960439605396063960739608396093961039611396123961339614396153961639617396183961939620396213962239623396243962539626396273962839629396303963139632396333963439635396363963739638396393964039641396423964339644396453964639647396483964939650396513965239653396543965539656396573965839659396603966139662396633966439665396663966739668396693967039671396723967339674396753967639677396783967939680396813968239683396843968539686396873968839689396903969139692396933969439695396963969739698396993970039701397023970339704397053970639707397083970939710397113971239713397143971539716397173971839719397203972139722397233972439725397263972739728397293973039731397323973339734397353973639737397383973939740397413974239743397443974539746397473974839749397503975139752397533975439755397563975739758397593976039761397623976339764397653976639767397683976939770397713977239773397743977539776397773977839779397803978139782397833978439785397863978739788397893979039791397923979339794397953979639797397983979939800398013980239803398043980539806398073980839809398103981139812398133981439815398163981739818398193982039821398223982339824398253982639827398283982939830398313983239833398343983539836398373983839839398403984139842398433984439845398463984739848398493985039851398523985339854398553985639857398583985939860398613986239863398643986539866398673986839869398703987139872398733987439875398763987739878398793988039881398823988339884398853988639887398883988939890398913989239893398943989539896398973989839899399003990139902399033990439905399063990739908399093991039911399123991339914399153991639917399183991939920399213992239923399243992539926399273992839929399303993139932399333993439935399363993739938399393994039941399423994339944399453994639947399483994939950399513995239953399543995539956399573995839959399603996139962399633996439965399663996739968399693997039971399723997339974399753997639977399783997939980399813998239983399843998539986399873998839989399903999139992399933999439995399963999739998399994000040001400024000340004400054000640007400084000940010400114001240013400144001540016400174001840019400204002140022400234002440025400264002740028400294003040031400324003340034400354003640037400384003940040400414004240043400444004540046400474004840049400504005140052400534005440055400564005740058400594006040061400624006340064400654006640067400684006940070400714007240073400744007540076400774007840079400804008140082400834008440085400864008740088400894009040091400924009340094400954009640097400984009940100401014010240103401044010540106401074010840109401104011140112401134011440115401164011740118401194012040121401224012340124401254012640127401284012940130401314013240133401344013540136401374013840139401404014140142401434014440145401464014740148401494015040151401524015340154401554015640157401584015940160401614016240163401644016540166401674016840169401704017140172401734017440175401764017740178401794018040181401824018340184401854018640187401884018940190401914019240193401944019540196401974019840199402004020140202402034020440205402064020740208402094021040211402124021340214402154021640217402184021940220402214022240223402244022540226402274022840229402304023140232402334023440235402364023740238402394024040241402424024340244402454024640247402484024940250402514025240253402544025540256402574025840259402604026140262402634026440265402664026740268402694027040271402724027340274402754027640277402784027940280402814028240283402844028540286402874028840289402904029140292402934029440295402964029740298402994030040301403024030340304403054030640307403084030940310403114031240313403144031540316403174031840319403204032140322403234032440325403264032740328403294033040331403324033340334403354033640337403384033940340403414034240343403444034540346403474034840349403504035140352403534035440355403564035740358403594036040361403624036340364403654036640367403684036940370403714037240373403744037540376403774037840379403804038140382403834038440385403864038740388403894039040391403924039340394403954039640397403984039940400404014040240403404044040540406404074040840409404104041140412404134041440415404164041740418404194042040421404224042340424404254042640427404284042940430404314043240433404344043540436404374043840439404404044140442404434044440445404464044740448404494045040451404524045340454404554045640457404584045940460404614046240463404644046540466404674046840469404704047140472404734047440475404764047740478404794048040481404824048340484404854048640487404884048940490404914049240493404944049540496404974049840499405004050140502405034050440505405064050740508405094051040511405124051340514405154051640517405184051940520405214052240523405244052540526405274052840529405304053140532405334053440535405364053740538405394054040541405424054340544405454054640547405484054940550405514055240553405544055540556405574055840559405604056140562405634056440565405664056740568405694057040571405724057340574405754057640577405784057940580405814058240583405844058540586405874058840589405904059140592405934059440595405964059740598405994060040601406024060340604406054060640607406084060940610406114061240613406144061540616406174061840619406204062140622406234062440625406264062740628406294063040631406324063340634406354063640637406384063940640406414064240643406444064540646406474064840649406504065140652406534065440655406564065740658406594066040661406624066340664406654066640667406684066940670406714067240673406744067540676406774067840679406804068140682406834068440685406864068740688406894069040691406924069340694406954069640697406984069940700407014070240703407044070540706407074070840709407104071140712407134071440715407164071740718407194072040721407224072340724407254072640727407284072940730407314073240733407344073540736407374073840739407404074140742407434074440745407464074740748407494075040751407524075340754407554075640757407584075940760407614076240763407644076540766407674076840769407704077140772407734077440775407764077740778407794078040781407824078340784407854078640787407884078940790407914079240793407944079540796407974079840799408004080140802408034080440805408064080740808408094081040811408124081340814408154081640817408184081940820408214082240823408244082540826408274082840829408304083140832408334083440835408364083740838408394084040841408424084340844408454084640847408484084940850408514085240853408544085540856408574085840859408604086140862408634086440865408664086740868408694087040871408724087340874408754087640877408784087940880408814088240883408844088540886408874088840889408904089140892408934089440895408964089740898408994090040901409024090340904409054090640907409084090940910409114091240913409144091540916409174091840919409204092140922409234092440925409264092740928409294093040931409324093340934409354093640937409384093940940409414094240943409444094540946409474094840949409504095140952409534095440955409564095740958409594096040961409624096340964409654096640967409684096940970409714097240973409744097540976409774097840979409804098140982409834098440985409864098740988409894099040991409924099340994409954099640997409984099941000410014100241003410044100541006410074100841009410104101141012410134101441015410164101741018410194102041021410224102341024410254102641027410284102941030410314103241033410344103541036410374103841039410404104141042410434104441045410464104741048410494105041051410524105341054410554105641057410584105941060410614106241063410644106541066410674106841069410704107141072410734107441075410764107741078410794108041081410824108341084410854108641087410884108941090410914109241093410944109541096410974109841099411004110141102411034110441105411064110741108411094111041111411124111341114411154111641117411184111941120411214112241123411244112541126411274112841129411304113141132411334113441135411364113741138411394114041141411424114341144411454114641147411484114941150411514115241153411544115541156411574115841159411604116141162411634116441165411664116741168411694117041171411724117341174411754117641177411784117941180411814118241183411844118541186411874118841189411904119141192411934119441195411964119741198411994120041201412024120341204412054120641207412084120941210412114121241213412144121541216412174121841219412204122141222412234122441225412264122741228412294123041231412324123341234412354123641237412384123941240412414124241243412444124541246412474124841249412504125141252412534125441255412564125741258412594126041261412624126341264412654126641267412684126941270412714127241273412744127541276412774127841279412804128141282412834128441285412864128741288412894129041291412924129341294412954129641297412984129941300413014130241303413044130541306413074130841309413104131141312413134131441315413164131741318413194132041321413224132341324413254132641327413284132941330413314133241333413344133541336413374133841339413404134141342413434134441345413464134741348413494135041351413524135341354413554135641357413584135941360413614136241363413644136541366413674136841369413704137141372413734137441375413764137741378413794138041381413824138341384413854138641387413884138941390413914139241393413944139541396413974139841399414004140141402414034140441405414064140741408414094141041411414124141341414414154141641417414184141941420414214142241423414244142541426414274142841429414304143141432414334143441435414364143741438414394144041441414424144341444414454144641447414484144941450414514145241453414544145541456414574145841459414604146141462414634146441465414664146741468414694147041471414724147341474414754147641477414784147941480414814148241483414844148541486414874148841489414904149141492414934149441495414964149741498414994150041501415024150341504415054150641507415084150941510415114151241513415144151541516415174151841519415204152141522415234152441525415264152741528415294153041531415324153341534415354153641537415384153941540415414154241543415444154541546415474154841549415504155141552415534155441555415564155741558415594156041561415624156341564415654156641567415684156941570415714157241573415744157541576415774157841579415804158141582415834158441585415864158741588415894159041591415924159341594415954159641597415984159941600416014160241603416044160541606416074160841609416104161141612416134161441615416164161741618416194162041621416224162341624416254162641627416284162941630416314163241633416344163541636416374163841639416404164141642416434164441645416464164741648416494165041651416524165341654416554165641657416584165941660416614166241663416644166541666416674166841669416704167141672416734167441675416764167741678416794168041681416824168341684416854168641687416884168941690416914169241693416944169541696416974169841699417004170141702417034170441705417064170741708417094171041711417124171341714417154171641717417184171941720417214172241723417244172541726417274172841729417304173141732417334173441735417364173741738417394174041741417424174341744417454174641747417484174941750417514175241753417544175541756417574175841759417604176141762417634176441765417664176741768417694177041771417724177341774417754177641777417784177941780417814178241783417844178541786417874178841789417904179141792417934179441795417964179741798417994180041801418024180341804418054180641807418084180941810418114181241813418144181541816418174181841819418204182141822418234182441825418264182741828418294183041831418324183341834418354183641837418384183941840418414184241843418444184541846418474184841849418504185141852418534185441855418564185741858418594186041861418624186341864418654186641867418684186941870418714187241873418744187541876418774187841879418804188141882418834188441885418864188741888418894189041891418924189341894418954189641897418984189941900419014190241903419044190541906419074190841909419104191141912419134191441915419164191741918419194192041921419224192341924419254192641927419284192941930419314193241933419344193541936419374193841939419404194141942419434194441945419464194741948419494195041951419524195341954419554195641957419584195941960419614196241963419644196541966419674196841969419704197141972419734197441975419764197741978419794198041981419824198341984419854198641987419884198941990419914199241993419944199541996419974199841999420004200142002420034200442005420064200742008420094201042011420124201342014420154201642017420184201942020420214202242023420244202542026420274202842029420304203142032420334203442035420364203742038420394204042041420424204342044420454204642047420484204942050420514205242053420544205542056420574205842059420604206142062420634206442065420664206742068420694207042071420724207342074420754207642077420784207942080420814208242083420844208542086420874208842089420904209142092420934209442095420964209742098420994210042101421024210342104421054210642107421084210942110421114211242113421144211542116421174211842119421204212142122421234212442125421264212742128421294213042131421324213342134421354213642137421384213942140421414214242143421444214542146421474214842149421504215142152421534215442155421564215742158421594216042161421624216342164421654216642167421684216942170421714217242173421744217542176421774217842179421804218142182421834218442185421864218742188421894219042191421924219342194421954219642197421984219942200422014220242203422044220542206422074220842209422104221142212422134221442215422164221742218422194222042221422224222342224422254222642227422284222942230422314223242233422344223542236422374223842239422404224142242422434224442245422464224742248422494225042251422524225342254422554225642257422584225942260422614226242263422644226542266422674226842269422704227142272422734227442275422764227742278422794228042281422824228342284422854228642287422884228942290422914229242293422944229542296422974229842299423004230142302423034230442305423064230742308423094231042311423124231342314423154231642317423184231942320423214232242323423244232542326423274232842329423304233142332423334233442335423364233742338423394234042341423424234342344423454234642347423484234942350423514235242353423544235542356423574235842359423604236142362423634236442365423664236742368423694237042371423724237342374423754237642377423784237942380423814238242383423844238542386423874238842389423904239142392423934239442395423964239742398423994240042401424024240342404424054240642407424084240942410424114241242413424144241542416424174241842419424204242142422424234242442425424264242742428424294243042431424324243342434424354243642437424384243942440424414244242443424444244542446424474244842449424504245142452424534245442455424564245742458424594246042461424624246342464424654246642467424684246942470424714247242473424744247542476424774247842479424804248142482424834248442485424864248742488424894249042491424924249342494424954249642497424984249942500425014250242503425044250542506425074250842509425104251142512425134251442515425164251742518425194252042521425224252342524425254252642527425284252942530425314253242533425344253542536425374253842539425404254142542425434254442545425464254742548425494255042551425524255342554425554255642557425584255942560425614256242563425644256542566425674256842569425704257142572425734257442575425764257742578425794258042581425824258342584425854258642587425884258942590425914259242593425944259542596425974259842599426004260142602426034260442605426064260742608426094261042611426124261342614426154261642617426184261942620426214262242623426244262542626426274262842629426304263142632426334263442635426364263742638426394264042641426424264342644426454264642647426484264942650426514265242653426544265542656426574265842659426604266142662426634266442665426664266742668426694267042671426724267342674426754267642677426784267942680426814268242683426844268542686426874268842689426904269142692426934269442695426964269742698426994270042701427024270342704427054270642707427084270942710427114271242713427144271542716427174271842719427204272142722427234272442725427264272742728427294273042731427324273342734427354273642737427384273942740427414274242743427444274542746427474274842749427504275142752427534275442755427564275742758427594276042761427624276342764427654276642767427684276942770427714277242773427744277542776427774277842779427804278142782427834278442785427864278742788427894279042791427924279342794427954279642797427984279942800428014280242803428044280542806428074280842809428104281142812428134281442815428164281742818428194282042821428224282342824428254282642827428284282942830428314283242833428344283542836428374283842839428404284142842428434284442845428464284742848428494285042851428524285342854428554285642857428584285942860428614286242863428644286542866428674286842869428704287142872428734287442875428764287742878428794288042881428824288342884428854288642887428884288942890428914289242893428944289542896428974289842899429004290142902429034290442905429064290742908429094291042911429124291342914429154291642917429184291942920429214292242923429244292542926429274292842929429304293142932429334293442935429364293742938429394294042941429424294342944429454294642947429484294942950429514295242953429544295542956429574295842959429604296142962429634296442965429664296742968429694297042971429724297342974429754297642977429784297942980429814298242983429844298542986429874298842989429904299142992429934299442995429964299742998429994300043001430024300343004430054300643007430084300943010430114301243013430144301543016430174301843019430204302143022430234302443025430264302743028430294303043031430324303343034430354303643037430384303943040430414304243043430444304543046430474304843049430504305143052430534305443055430564305743058430594306043061430624306343064430654306643067430684306943070430714307243073430744307543076430774307843079430804308143082430834308443085430864308743088430894309043091430924309343094430954309643097430984309943100431014310243103431044310543106431074310843109431104311143112431134311443115431164311743118431194312043121431224312343124431254312643127431284312943130431314313243133431344313543136431374313843139431404314143142431434314443145431464314743148431494315043151431524315343154431554315643157431584315943160431614316243163431644316543166431674316843169431704317143172431734317443175431764317743178431794318043181431824318343184431854318643187431884318943190431914319243193431944319543196431974319843199432004320143202432034320443205432064320743208432094321043211432124321343214432154321643217432184321943220432214322243223432244322543226432274322843229432304323143232432334323443235432364323743238432394324043241432424324343244432454324643247432484324943250432514325243253432544325543256432574325843259432604326143262432634326443265432664326743268432694327043271432724327343274432754327643277432784327943280432814328243283432844328543286432874328843289432904329143292432934329443295432964329743298432994330043301433024330343304433054330643307433084330943310433114331243313433144331543316433174331843319433204332143322433234332443325433264332743328433294333043331433324333343334433354333643337433384333943340433414334243343433444334543346433474334843349433504335143352433534335443355433564335743358433594336043361433624336343364433654336643367433684336943370433714337243373433744337543376433774337843379433804338143382433834338443385433864338743388433894339043391433924339343394433954339643397433984339943400434014340243403434044340543406434074340843409434104341143412434134341443415434164341743418434194342043421434224342343424434254342643427434284342943430434314343243433434344343543436434374343843439434404344143442434434344443445434464344743448434494345043451434524345343454434554345643457434584345943460434614346243463434644346543466434674346843469434704347143472434734347443475434764347743478434794348043481434824348343484434854348643487434884348943490434914349243493434944349543496434974349843499435004350143502435034350443505435064350743508435094351043511435124351343514435154351643517435184351943520435214352243523435244352543526435274352843529435304353143532435334353443535435364353743538435394354043541435424354343544435454354643547435484354943550435514355243553435544355543556435574355843559435604356143562435634356443565435664356743568435694357043571435724357343574435754357643577435784357943580435814358243583435844358543586435874358843589435904359143592435934359443595435964359743598435994360043601436024360343604436054360643607436084360943610436114361243613436144361543616436174361843619436204362143622436234362443625436264362743628436294363043631436324363343634436354363643637436384363943640436414364243643436444364543646436474364843649436504365143652436534365443655436564365743658436594366043661436624366343664436654366643667436684366943670436714367243673436744367543676436774367843679436804368143682436834368443685436864368743688436894369043691436924369343694436954369643697436984369943700437014370243703437044370543706437074370843709437104371143712437134371443715437164371743718437194372043721437224372343724437254372643727437284372943730437314373243733437344373543736437374373843739437404374143742437434374443745437464374743748437494375043751437524375343754437554375643757437584375943760437614376243763437644376543766437674376843769437704377143772437734377443775437764377743778437794378043781437824378343784437854378643787437884378943790437914379243793437944379543796437974379843799438004380143802438034380443805438064380743808438094381043811438124381343814438154381643817438184381943820438214382243823438244382543826438274382843829438304383143832438334383443835438364383743838438394384043841438424384343844438454384643847438484384943850438514385243853438544385543856438574385843859438604386143862438634386443865438664386743868438694387043871438724387343874438754387643877438784387943880438814388243883438844388543886438874388843889438904389143892438934389443895438964389743898438994390043901439024390343904439054390643907439084390943910439114391243913439144391543916439174391843919439204392143922439234392443925439264392743928439294393043931439324393343934439354393643937439384393943940439414394243943439444394543946439474394843949439504395143952439534395443955439564395743958439594396043961439624396343964439654396643967439684396943970439714397243973439744397543976439774397843979439804398143982439834398443985439864398743988439894399043991439924399343994439954399643997439984399944000440014400244003440044400544006440074400844009440104401144012440134401444015440164401744018440194402044021440224402344024440254402644027440284402944030440314403244033440344403544036440374403844039440404404144042440434404444045440464404744048440494405044051440524405344054440554405644057440584405944060440614406244063440644406544066440674406844069440704407144072440734407444075440764407744078440794408044081440824408344084440854408644087440884408944090440914409244093440944409544096440974409844099441004410144102441034410444105441064410744108441094411044111441124411344114441154411644117441184411944120441214412244123441244412544126441274412844129441304413144132441334413444135441364413744138441394414044141441424414344144441454414644147441484414944150441514415244153441544415544156441574415844159441604416144162441634416444165441664416744168441694417044171441724417344174441754417644177441784417944180441814418244183441844418544186441874418844189441904419144192441934419444195441964419744198441994420044201442024420344204442054420644207442084420944210442114421244213442144421544216442174421844219442204422144222442234422444225442264422744228442294423044231442324423344234442354423644237442384423944240442414424244243442444424544246442474424844249442504425144252442534425444255442564425744258442594426044261442624426344264442654426644267442684426944270442714427244273442744427544276442774427844279442804428144282442834428444285442864428744288442894429044291442924429344294442954429644297442984429944300443014430244303443044430544306443074430844309443104431144312443134431444315443164431744318443194432044321443224432344324443254432644327443284432944330443314433244333443344433544336443374433844339443404434144342443434434444345443464434744348443494435044351443524435344354443554435644357443584435944360443614436244363443644436544366443674436844369443704437144372443734437444375443764437744378443794438044381443824438344384443854438644387443884438944390443914439244393443944439544396443974439844399444004440144402444034440444405444064440744408444094441044411444124441344414444154441644417444184441944420444214442244423444244442544426444274442844429444304443144432444334443444435444364443744438444394444044441444424444344444444454444644447444484444944450444514445244453444544445544456444574445844459444604446144462444634446444465444664446744468444694447044471444724447344474444754447644477444784447944480444814448244483444844448544486444874448844489444904449144492444934449444495444964449744498444994450044501445024450344504445054450644507445084450944510445114451244513445144451544516445174451844519445204452144522445234452444525445264452744528445294453044531445324453344534445354453644537445384453944540445414454244543445444454544546445474454844549445504455144552445534455444555445564455744558445594456044561445624456344564445654456644567445684456944570445714457244573445744457544576445774457844579445804458144582445834458444585445864458744588445894459044591445924459344594445954459644597445984459944600446014460244603446044460544606446074460844609446104461144612446134461444615446164461744618446194462044621446224462344624446254462644627446284462944630446314463244633446344463544636446374463844639446404464144642446434464444645446464464744648446494465044651446524465344654446554465644657446584465944660446614466244663446644466544666446674466844669446704467144672446734467444675446764467744678446794468044681446824468344684446854468644687446884468944690446914469244693446944469544696446974469844699447004470144702447034470444705447064470744708447094471044711447124471344714447154471644717447184471944720447214472244723447244472544726447274472844729447304473144732447334473444735447364473744738447394474044741447424474344744447454474644747447484474944750447514475244753447544475544756447574475844759447604476144762447634476444765447664476744768447694477044771447724477344774447754477644777447784477944780447814478244783447844478544786447874478844789447904479144792447934479444795447964479744798447994480044801448024480344804448054480644807448084480944810448114481244813448144481544816448174481844819448204482144822448234482444825448264482744828448294483044831448324483344834448354483644837448384483944840448414484244843448444484544846448474484844849448504485144852448534485444855448564485744858448594486044861448624486344864448654486644867448684486944870448714487244873448744487544876448774487844879448804488144882448834488444885448864488744888448894489044891448924489344894448954489644897448984489944900449014490244903449044490544906449074490844909449104491144912449134491444915449164491744918449194492044921449224492344924449254492644927449284492944930449314493244933449344493544936449374493844939449404494144942449434494444945449464494744948449494495044951449524495344954449554495644957449584495944960449614496244963449644496544966449674496844969449704497144972449734497444975449764497744978449794498044981449824498344984449854498644987449884498944990449914499244993449944499544996449974499844999450004500145002450034500445005450064500745008450094501045011450124501345014450154501645017450184501945020450214502245023450244502545026450274502845029450304503145032450334503445035450364503745038450394504045041450424504345044450454504645047450484504945050450514505245053450544505545056450574505845059450604506145062450634506445065450664506745068450694507045071450724507345074450754507645077450784507945080450814508245083450844508545086450874508845089450904509145092450934509445095450964509745098450994510045101451024510345104451054510645107451084510945110451114511245113451144511545116451174511845119451204512145122451234512445125451264512745128451294513045131451324513345134451354513645137451384513945140451414514245143451444514545146451474514845149451504515145152451534515445155451564515745158451594516045161451624516345164451654516645167451684516945170451714517245173451744517545176451774517845179451804518145182451834518445185451864518745188451894519045191451924519345194451954519645197451984519945200452014520245203452044520545206452074520845209452104521145212452134521445215452164521745218452194522045221452224522345224452254522645227452284522945230452314523245233452344523545236452374523845239452404524145242452434524445245452464524745248452494525045251452524525345254452554525645257452584525945260452614526245263452644526545266452674526845269452704527145272452734527445275452764527745278452794528045281452824528345284452854528645287452884528945290452914529245293452944529545296452974529845299453004530145302453034530445305453064530745308453094531045311453124531345314453154531645317453184531945320453214532245323453244532545326453274532845329453304533145332453334533445335453364533745338453394534045341453424534345344453454534645347453484534945350453514535245353453544535545356453574535845359453604536145362453634536445365453664536745368453694537045371453724537345374453754537645377453784537945380453814538245383453844538545386453874538845389453904539145392453934539445395453964539745398453994540045401454024540345404454054540645407454084540945410454114541245413454144541545416454174541845419454204542145422454234542445425454264542745428454294543045431454324543345434454354543645437454384543945440454414544245443454444544545446454474544845449454504545145452454534545445455454564545745458454594546045461454624546345464454654546645467454684546945470454714547245473454744547545476454774547845479454804548145482454834548445485454864548745488454894549045491454924549345494454954549645497454984549945500455014550245503455044550545506455074550845509455104551145512455134551445515455164551745518455194552045521455224552345524455254552645527455284552945530455314553245533455344553545536455374553845539455404554145542455434554445545455464554745548455494555045551455524555345554455554555645557455584555945560455614556245563455644556545566455674556845569455704557145572455734557445575455764557745578455794558045581455824558345584455854558645587455884558945590455914559245593455944559545596455974559845599456004560145602456034560445605456064560745608456094561045611456124561345614456154561645617456184561945620456214562245623456244562545626456274562845629456304563145632456334563445635456364563745638456394564045641456424564345644456454564645647456484564945650456514565245653456544565545656456574565845659456604566145662456634566445665456664566745668456694567045671456724567345674456754567645677456784567945680456814568245683456844568545686456874568845689456904569145692456934569445695456964569745698456994570045701457024570345704457054570645707457084570945710457114571245713457144571545716457174571845719457204572145722457234572445725457264572745728457294573045731457324573345734457354573645737457384573945740457414574245743457444574545746457474574845749457504575145752457534575445755457564575745758457594576045761457624576345764457654576645767457684576945770457714577245773457744577545776457774577845779457804578145782457834578445785457864578745788457894579045791457924579345794457954579645797457984579945800458014580245803458044580545806458074580845809458104581145812458134581445815458164581745818458194582045821458224582345824458254582645827458284582945830458314583245833458344583545836458374583845839458404584145842458434584445845458464584745848458494585045851458524585345854458554585645857458584585945860458614586245863458644586545866458674586845869458704587145872458734587445875458764587745878458794588045881458824588345884458854588645887458884588945890458914589245893458944589545896458974589845899459004590145902459034590445905459064590745908459094591045911459124591345914459154591645917459184591945920459214592245923459244592545926459274592845929459304593145932459334593445935459364593745938459394594045941459424594345944459454594645947459484594945950459514595245953459544595545956459574595845959459604596145962459634596445965459664596745968459694597045971459724597345974459754597645977459784597945980459814598245983459844598545986459874598845989459904599145992459934599445995459964599745998459994600046001460024600346004460054600646007460084600946010460114601246013460144601546016460174601846019460204602146022460234602446025460264602746028460294603046031460324603346034460354603646037460384603946040460414604246043460444604546046460474604846049460504605146052460534605446055460564605746058460594606046061460624606346064460654606646067460684606946070460714607246073460744607546076460774607846079460804608146082460834608446085460864608746088460894609046091460924609346094460954609646097460984609946100461014610246103461044610546106461074610846109461104611146112461134611446115461164611746118461194612046121461224612346124461254612646127461284612946130461314613246133461344613546136461374613846139461404614146142461434614446145461464614746148461494615046151461524615346154461554615646157461584615946160461614616246163461644616546166461674616846169461704617146172461734617446175461764617746178461794618046181461824618346184461854618646187461884618946190461914619246193461944619546196461974619846199462004620146202462034620446205462064620746208462094621046211462124621346214462154621646217462184621946220462214622246223462244622546226462274622846229462304623146232462334623446235462364623746238462394624046241462424624346244462454624646247462484624946250462514625246253462544625546256462574625846259462604626146262462634626446265462664626746268462694627046271462724627346274462754627646277462784627946280462814628246283462844628546286462874628846289462904629146292462934629446295462964629746298462994630046301463024630346304463054630646307463084630946310463114631246313463144631546316463174631846319463204632146322463234632446325463264632746328463294633046331463324633346334463354633646337463384633946340463414634246343463444634546346463474634846349463504635146352463534635446355463564635746358463594636046361463624636346364463654636646367463684636946370463714637246373463744637546376463774637846379463804638146382463834638446385463864638746388463894639046391463924639346394463954639646397463984639946400464014640246403464044640546406464074640846409464104641146412464134641446415464164641746418464194642046421464224642346424464254642646427464284642946430464314643246433464344643546436464374643846439464404644146442464434644446445464464644746448464494645046451464524645346454464554645646457464584645946460464614646246463464644646546466464674646846469464704647146472464734647446475464764647746478464794648046481464824648346484464854648646487464884648946490464914649246493464944649546496464974649846499465004650146502465034650446505465064650746508465094651046511465124651346514465154651646517465184651946520465214652246523465244652546526465274652846529465304653146532465334653446535465364653746538465394654046541465424654346544465454654646547465484654946550465514655246553465544655546556465574655846559465604656146562465634656446565465664656746568465694657046571465724657346574465754657646577465784657946580465814658246583465844658546586465874658846589465904659146592465934659446595465964659746598465994660046601466024660346604466054660646607466084660946610466114661246613466144661546616466174661846619466204662146622466234662446625466264662746628466294663046631466324663346634466354663646637466384663946640466414664246643466444664546646466474664846649466504665146652466534665446655466564665746658466594666046661466624666346664466654666646667466684666946670466714667246673466744667546676466774667846679466804668146682466834668446685466864668746688466894669046691466924669346694466954669646697466984669946700467014670246703467044670546706467074670846709467104671146712467134671446715467164671746718467194672046721467224672346724467254672646727467284672946730467314673246733467344673546736467374673846739467404674146742467434674446745467464674746748467494675046751467524675346754467554675646757467584675946760467614676246763467644676546766467674676846769467704677146772467734677446775467764677746778467794678046781467824678346784467854678646787467884678946790467914679246793467944679546796467974679846799468004680146802468034680446805468064680746808468094681046811468124681346814468154681646817468184681946820468214682246823468244682546826468274682846829468304683146832468334683446835468364683746838468394684046841468424684346844468454684646847468484684946850468514685246853468544685546856468574685846859468604686146862468634686446865468664686746868468694687046871468724687346874468754687646877468784687946880468814688246883468844688546886468874688846889468904689146892468934689446895468964689746898468994690046901469024690346904469054690646907469084690946910469114691246913469144691546916469174691846919469204692146922469234692446925469264692746928469294693046931469324693346934469354693646937469384693946940469414694246943469444694546946469474694846949469504695146952469534695446955469564695746958469594696046961469624696346964469654696646967469684696946970469714697246973469744697546976469774697846979469804698146982469834698446985469864698746988469894699046991469924699346994469954699646997469984699947000470014700247003470044700547006470074700847009470104701147012470134701447015470164701747018470194702047021470224702347024470254702647027470284702947030470314703247033470344703547036470374703847039470404704147042470434704447045470464704747048470494705047051470524705347054470554705647057470584705947060470614706247063470644706547066470674706847069470704707147072470734707447075470764707747078470794708047081470824708347084470854708647087470884708947090470914709247093470944709547096470974709847099471004710147102471034710447105471064710747108471094711047111471124711347114471154711647117471184711947120471214712247123471244712547126471274712847129471304713147132471334713447135471364713747138471394714047141471424714347144471454714647147471484714947150471514715247153471544715547156471574715847159471604716147162471634716447165471664716747168471694717047171471724717347174471754717647177471784717947180471814718247183471844718547186471874718847189471904719147192471934719447195471964719747198471994720047201472024720347204472054720647207472084720947210472114721247213472144721547216472174721847219472204722147222472234722447225472264722747228472294723047231472324723347234472354723647237472384723947240472414724247243472444724547246472474724847249472504725147252472534725447255472564725747258472594726047261472624726347264472654726647267472684726947270472714727247273472744727547276472774727847279472804728147282472834728447285472864728747288472894729047291472924729347294472954729647297472984729947300473014730247303473044730547306473074730847309473104731147312473134731447315473164731747318473194732047321473224732347324473254732647327473284732947330473314733247333473344733547336473374733847339473404734147342473434734447345473464734747348473494735047351473524735347354473554735647357473584735947360473614736247363473644736547366473674736847369473704737147372473734737447375473764737747378473794738047381473824738347384473854738647387473884738947390473914739247393473944739547396473974739847399474004740147402474034740447405474064740747408474094741047411474124741347414474154741647417474184741947420474214742247423474244742547426474274742847429474304743147432474334743447435474364743747438474394744047441474424744347444474454744647447474484744947450474514745247453474544745547456474574745847459474604746147462474634746447465474664746747468474694747047471474724747347474474754747647477474784747947480474814748247483474844748547486474874748847489474904749147492474934749447495474964749747498474994750047501475024750347504475054750647507475084750947510475114751247513475144751547516475174751847519475204752147522475234752447525475264752747528475294753047531475324753347534475354753647537475384753947540475414754247543475444754547546475474754847549475504755147552475534755447555475564755747558475594756047561475624756347564475654756647567475684756947570475714757247573475744757547576475774757847579475804758147582475834758447585475864758747588475894759047591475924759347594475954759647597475984759947600476014760247603476044760547606476074760847609476104761147612476134761447615476164761747618476194762047621476224762347624476254762647627476284762947630476314763247633476344763547636476374763847639476404764147642476434764447645476464764747648476494765047651476524765347654476554765647657476584765947660476614766247663476644766547666476674766847669476704767147672476734767447675476764767747678476794768047681476824768347684476854768647687476884768947690476914769247693476944769547696476974769847699477004770147702477034770447705477064770747708477094771047711477124771347714477154771647717477184771947720477214772247723477244772547726477274772847729477304773147732477334773447735477364773747738477394774047741477424774347744477454774647747477484774947750477514775247753477544775547756477574775847759477604776147762477634776447765477664776747768477694777047771477724777347774477754777647777477784777947780477814778247783477844778547786477874778847789477904779147792477934779447795477964779747798477994780047801478024780347804478054780647807478084780947810478114781247813478144781547816478174781847819478204782147822478234782447825478264782747828478294783047831478324783347834478354783647837478384783947840478414784247843478444784547846478474784847849478504785147852478534785447855478564785747858478594786047861478624786347864478654786647867478684786947870478714787247873478744787547876478774787847879478804788147882478834788447885478864788747888478894789047891478924789347894478954789647897478984789947900479014790247903479044790547906479074790847909479104791147912479134791447915479164791747918479194792047921479224792347924479254792647927479284792947930479314793247933479344793547936479374793847939479404794147942479434794447945479464794747948479494795047951479524795347954479554795647957479584795947960479614796247963479644796547966479674796847969479704797147972479734797447975479764797747978479794798047981479824798347984479854798647987479884798947990479914799247993479944799547996479974799847999480004800148002480034800448005480064800748008480094801048011480124801348014480154801648017480184801948020480214802248023480244802548026480274802848029480304803148032480334803448035480364803748038480394804048041480424804348044480454804648047480484804948050480514805248053480544805548056480574805848059480604806148062480634806448065480664806748068480694807048071480724807348074480754807648077480784807948080480814808248083480844808548086480874808848089480904809148092480934809448095480964809748098480994810048101481024810348104481054810648107481084810948110481114811248113481144811548116481174811848119481204812148122481234812448125481264812748128481294813048131481324813348134481354813648137481384813948140481414814248143481444814548146481474814848149481504815148152481534815448155481564815748158481594816048161481624816348164481654816648167481684816948170481714817248173481744817548176481774817848179481804818148182481834818448185481864818748188481894819048191481924819348194481954819648197481984819948200482014820248203482044820548206482074820848209482104821148212482134821448215482164821748218482194822048221482224822348224482254822648227482284822948230482314823248233482344823548236482374823848239482404824148242482434824448245482464824748248482494825048251482524825348254482554825648257482584825948260482614826248263482644826548266482674826848269482704827148272482734827448275482764827748278482794828048281482824828348284482854828648287482884828948290482914829248293482944829548296482974829848299483004830148302483034830448305483064830748308483094831048311483124831348314483154831648317483184831948320483214832248323483244832548326483274832848329483304833148332483334833448335483364833748338483394834048341483424834348344483454834648347483484834948350483514835248353483544835548356483574835848359483604836148362483634836448365483664836748368483694837048371483724837348374483754837648377483784837948380483814838248383483844838548386483874838848389483904839148392483934839448395483964839748398483994840048401484024840348404484054840648407484084840948410484114841248413484144841548416484174841848419484204842148422484234842448425484264842748428484294843048431484324843348434484354843648437484384843948440484414844248443484444844548446484474844848449484504845148452484534845448455484564845748458484594846048461484624846348464484654846648467484684846948470484714847248473484744847548476484774847848479484804848148482484834848448485484864848748488484894849048491484924849348494484954849648497484984849948500485014850248503485044850548506485074850848509485104851148512485134851448515485164851748518485194852048521485224852348524485254852648527485284852948530485314853248533485344853548536485374853848539485404854148542485434854448545485464854748548485494855048551485524855348554485554855648557485584855948560485614856248563485644856548566485674856848569485704857148572485734857448575485764857748578485794858048581485824858348584485854858648587485884858948590485914859248593485944859548596485974859848599486004860148602486034860448605486064860748608486094861048611486124861348614486154861648617486184861948620486214862248623486244862548626486274862848629486304863148632486334863448635486364863748638486394864048641486424864348644486454864648647486484864948650486514865248653486544865548656486574865848659486604866148662486634866448665486664866748668486694867048671486724867348674486754867648677486784867948680486814868248683486844868548686486874868848689486904869148692486934869448695486964869748698486994870048701487024870348704487054870648707487084870948710487114871248713487144871548716487174871848719487204872148722487234872448725487264872748728487294873048731487324873348734487354873648737487384873948740487414874248743487444874548746487474874848749487504875148752487534875448755487564875748758487594876048761487624876348764487654876648767487684876948770487714877248773487744877548776487774877848779487804878148782487834878448785487864878748788487894879048791487924879348794487954879648797487984879948800488014880248803488044880548806488074880848809488104881148812488134881448815488164881748818488194882048821488224882348824488254882648827488284882948830488314883248833488344883548836488374883848839488404884148842488434884448845488464884748848488494885048851488524885348854488554885648857488584885948860488614886248863488644886548866488674886848869488704887148872488734887448875488764887748878488794888048881488824888348884488854888648887488884888948890488914889248893488944889548896488974889848899489004890148902489034890448905489064890748908489094891048911489124891348914489154891648917489184891948920489214892248923489244892548926489274892848929489304893148932489334893448935489364893748938489394894048941489424894348944489454894648947489484894948950489514895248953489544895548956489574895848959489604896148962489634896448965489664896748968489694897048971489724897348974489754897648977489784897948980489814898248983489844898548986489874898848989489904899148992489934899448995489964899748998489994900049001490024900349004490054900649007490084900949010490114901249013490144901549016490174901849019490204902149022490234902449025490264902749028490294903049031490324903349034490354903649037490384903949040490414904249043490444904549046490474904849049490504905149052490534905449055490564905749058490594906049061490624906349064490654906649067490684906949070490714907249073490744907549076490774907849079490804908149082490834908449085490864908749088490894909049091490924909349094490954909649097490984909949100491014910249103491044910549106491074910849109491104911149112491134911449115491164911749118491194912049121491224912349124491254912649127491284912949130491314913249133491344913549136491374913849139491404914149142491434914449145491464914749148491494915049151491524915349154491554915649157491584915949160491614916249163491644916549166491674916849169491704917149172491734917449175491764917749178491794918049181491824918349184491854918649187491884918949190491914919249193491944919549196491974919849199492004920149202492034920449205492064920749208492094921049211492124921349214492154921649217492184921949220492214922249223492244922549226492274922849229492304923149232492334923449235492364923749238492394924049241492424924349244492454924649247492484924949250492514925249253492544925549256492574925849259492604926149262492634926449265492664926749268492694927049271492724927349274492754927649277492784927949280492814928249283492844928549286492874928849289492904929149292492934929449295492964929749298492994930049301493024930349304493054930649307493084930949310493114931249313493144931549316493174931849319493204932149322493234932449325493264932749328493294933049331493324933349334493354933649337493384933949340493414934249343493444934549346493474934849349493504935149352493534935449355493564935749358493594936049361493624936349364493654936649367493684936949370493714937249373493744937549376493774937849379493804938149382493834938449385493864938749388493894939049391493924939349394493954939649397493984939949400494014940249403494044940549406494074940849409494104941149412494134941449415494164941749418494194942049421494224942349424494254942649427494284942949430494314943249433494344943549436494374943849439494404944149442494434944449445494464944749448494494945049451494524945349454494554945649457494584945949460494614946249463494644946549466494674946849469494704947149472494734947449475494764947749478494794948049481494824948349484494854948649487494884948949490494914949249493494944949549496494974949849499495004950149502495034950449505495064950749508495094951049511495124951349514495154951649517495184951949520495214952249523495244952549526495274952849529495304953149532495334953449535495364953749538495394954049541495424954349544495454954649547495484954949550495514955249553495544955549556495574955849559495604956149562495634956449565495664956749568495694957049571495724957349574495754957649577495784957949580495814958249583495844958549586495874958849589495904959149592495934959449595495964959749598495994960049601496024960349604496054960649607496084960949610496114961249613496144961549616496174961849619496204962149622496234962449625496264962749628496294963049631496324963349634496354963649637496384963949640496414964249643496444964549646496474964849649496504965149652496534965449655496564965749658496594966049661496624966349664496654966649667496684966949670496714967249673496744967549676496774967849679496804968149682496834968449685496864968749688496894969049691496924969349694496954969649697496984969949700497014970249703497044970549706497074970849709497104971149712497134971449715497164971749718497194972049721497224972349724497254972649727497284972949730497314973249733497344973549736497374973849739497404974149742497434974449745497464974749748497494975049751497524975349754497554975649757497584975949760497614976249763497644976549766497674976849769497704977149772497734977449775497764977749778497794978049781497824978349784497854978649787497884978949790497914979249793497944979549796497974979849799498004980149802498034980449805498064980749808498094981049811498124981349814498154981649817498184981949820498214982249823498244982549826498274982849829498304983149832498334983449835498364983749838498394984049841498424984349844498454984649847498484984949850498514985249853498544985549856498574985849859498604986149862498634986449865498664986749868498694987049871498724987349874498754987649877498784987949880498814988249883498844988549886498874988849889498904989149892498934989449895498964989749898498994990049901499024990349904499054990649907499084990949910499114991249913499144991549916499174991849919499204992149922499234992449925499264992749928499294993049931499324993349934499354993649937499384993949940499414994249943499444994549946499474994849949499504995149952499534995449955499564995749958499594996049961499624996349964499654996649967499684996949970499714997249973499744997549976499774997849979499804998149982499834998449985499864998749988499894999049991499924999349994499954999649997499984999950000500015000250003500045000550006500075000850009500105001150012500135001450015500165001750018500195002050021500225002350024500255002650027500285002950030500315003250033500345003550036500375003850039500405004150042500435004450045500465004750048500495005050051500525005350054500555005650057500585005950060500615006250063500645006550066500675006850069500705007150072500735007450075500765007750078500795008050081500825008350084500855008650087500885008950090500915009250093500945009550096500975009850099501005010150102501035010450105501065010750108501095011050111501125011350114501155011650117501185011950120501215012250123501245012550126501275012850129501305013150132501335013450135501365013750138501395014050141501425014350144501455014650147501485014950150501515015250153501545015550156501575015850159501605016150162501635016450165501665016750168501695017050171501725017350174501755017650177501785017950180501815018250183501845018550186501875018850189501905019150192501935019450195501965019750198501995020050201502025020350204502055020650207502085020950210502115021250213502145021550216502175021850219502205022150222502235022450225502265022750228502295023050231502325023350234502355023650237502385023950240502415024250243502445024550246502475024850249502505025150252502535025450255502565025750258502595026050261502625026350264502655026650267502685026950270502715027250273502745027550276502775027850279502805028150282502835028450285502865028750288502895029050291502925029350294502955029650297502985029950300503015030250303503045030550306503075030850309503105031150312503135031450315503165031750318503195032050321503225032350324503255032650327503285032950330503315033250333503345033550336503375033850339503405034150342503435034450345503465034750348503495035050351503525035350354503555035650357503585035950360503615036250363503645036550366503675036850369503705037150372503735037450375503765037750378503795038050381503825038350384503855038650387503885038950390503915039250393503945039550396503975039850399504005040150402504035040450405504065040750408504095041050411504125041350414504155041650417504185041950420504215042250423504245042550426504275042850429504305043150432504335043450435504365043750438504395044050441504425044350444504455044650447504485044950450504515045250453504545045550456504575045850459504605046150462504635046450465504665046750468504695047050471504725047350474504755047650477504785047950480504815048250483504845048550486504875048850489504905049150492504935049450495504965049750498504995050050501505025050350504505055050650507505085050950510505115051250513505145051550516505175051850519505205052150522505235052450525505265052750528505295053050531505325053350534505355053650537505385053950540505415054250543505445054550546505475054850549505505055150552505535055450555505565055750558505595056050561505625056350564505655056650567505685056950570505715057250573505745057550576505775057850579505805058150582505835058450585505865058750588505895059050591505925059350594505955059650597505985059950600506015060250603506045060550606506075060850609506105061150612506135061450615506165061750618506195062050621506225062350624506255062650627506285062950630506315063250633506345063550636506375063850639506405064150642506435064450645506465064750648506495065050651506525065350654506555065650657506585065950660506615066250663506645066550666506675066850669506705067150672506735067450675506765067750678506795068050681506825068350684506855068650687506885068950690506915069250693506945069550696506975069850699507005070150702507035070450705507065070750708507095071050711507125071350714507155071650717507185071950720507215072250723507245072550726507275072850729507305073150732507335073450735507365073750738507395074050741507425074350744507455074650747507485074950750507515075250753507545075550756507575075850759507605076150762507635076450765507665076750768507695077050771507725077350774507755077650777507785077950780507815078250783507845078550786507875078850789507905079150792507935079450795507965079750798507995080050801508025080350804508055080650807508085080950810508115081250813508145081550816508175081850819508205082150822508235082450825508265082750828508295083050831508325083350834508355083650837508385083950840508415084250843508445084550846508475084850849508505085150852508535085450855508565085750858508595086050861508625086350864508655086650867508685086950870508715087250873508745087550876508775087850879508805088150882508835088450885508865088750888508895089050891508925089350894508955089650897508985089950900509015090250903509045090550906509075090850909509105091150912509135091450915509165091750918509195092050921509225092350924509255092650927509285092950930509315093250933509345093550936509375093850939509405094150942509435094450945509465094750948509495095050951509525095350954509555095650957509585095950960509615096250963509645096550966509675096850969509705097150972509735097450975509765097750978509795098050981509825098350984509855098650987509885098950990509915099250993509945099550996509975099850999510005100151002510035100451005510065100751008510095101051011510125101351014510155101651017510185101951020510215102251023510245102551026510275102851029510305103151032510335103451035510365103751038510395104051041510425104351044510455104651047510485104951050510515105251053510545105551056510575105851059510605106151062510635106451065510665106751068510695107051071510725107351074510755107651077510785107951080510815108251083510845108551086510875108851089510905109151092510935109451095510965109751098510995110051101511025110351104511055110651107511085110951110511115111251113511145111551116511175111851119511205112151122511235112451125511265112751128511295113051131511325113351134511355113651137511385113951140511415114251143511445114551146511475114851149511505115151152511535115451155511565115751158511595116051161511625116351164511655116651167511685116951170511715117251173511745117551176511775117851179511805118151182511835118451185511865118751188511895119051191511925119351194511955119651197511985119951200512015120251203512045120551206512075120851209512105121151212512135121451215512165121751218512195122051221512225122351224512255122651227512285122951230512315123251233512345123551236512375123851239512405124151242512435124451245512465124751248512495125051251512525125351254512555125651257512585125951260512615126251263512645126551266512675126851269512705127151272512735127451275512765127751278512795128051281512825128351284512855128651287512885128951290512915129251293512945129551296512975129851299513005130151302513035130451305513065130751308513095131051311513125131351314513155131651317513185131951320513215132251323513245132551326513275132851329513305133151332513335133451335513365133751338513395134051341513425134351344513455134651347513485134951350513515135251353513545135551356513575135851359513605136151362513635136451365513665136751368513695137051371513725137351374513755137651377513785137951380513815138251383513845138551386513875138851389513905139151392513935139451395513965139751398513995140051401514025140351404514055140651407514085140951410514115141251413514145141551416514175141851419514205142151422514235142451425514265142751428514295143051431514325143351434514355143651437514385143951440514415144251443514445144551446514475144851449514505145151452514535145451455514565145751458514595146051461514625146351464514655146651467514685146951470514715147251473514745147551476514775147851479514805148151482514835148451485514865148751488514895149051491514925149351494514955149651497514985149951500515015150251503515045150551506515075150851509515105151151512515135151451515515165151751518515195152051521515225152351524515255152651527515285152951530515315153251533515345153551536515375153851539515405154151542515435154451545515465154751548515495155051551515525155351554515555155651557515585155951560515615156251563515645156551566515675156851569515705157151572515735157451575515765157751578515795158051581515825158351584515855158651587515885158951590515915159251593515945159551596515975159851599516005160151602516035160451605516065160751608516095161051611516125161351614516155161651617516185161951620516215162251623516245162551626516275162851629516305163151632516335163451635516365163751638516395164051641516425164351644516455164651647516485164951650516515165251653516545165551656516575165851659516605166151662516635166451665516665166751668516695167051671516725167351674516755167651677516785167951680516815168251683516845168551686516875168851689516905169151692516935169451695516965169751698516995170051701517025170351704517055170651707517085170951710517115171251713517145171551716517175171851719517205172151722517235172451725517265172751728517295173051731517325173351734517355173651737517385173951740517415174251743517445174551746517475174851749517505175151752517535175451755517565175751758517595176051761517625176351764517655176651767517685176951770517715177251773517745177551776517775177851779517805178151782517835178451785517865178751788517895179051791517925179351794517955179651797517985179951800518015180251803518045180551806518075180851809518105181151812518135181451815518165181751818518195182051821518225182351824518255182651827518285182951830518315183251833518345183551836518375183851839518405184151842518435184451845518465184751848518495185051851518525185351854518555185651857518585185951860518615186251863518645186551866518675186851869518705187151872518735187451875518765187751878518795188051881518825188351884518855188651887518885188951890518915189251893518945189551896518975189851899519005190151902519035190451905519065190751908519095191051911519125191351914519155191651917519185191951920519215192251923519245192551926519275192851929519305193151932519335193451935519365193751938519395194051941519425194351944519455194651947519485194951950519515195251953519545195551956519575195851959519605196151962519635196451965519665196751968519695197051971519725197351974519755197651977519785197951980519815198251983519845198551986519875198851989519905199151992519935199451995519965199751998519995200052001520025200352004520055200652007520085200952010520115201252013520145201552016520175201852019520205202152022520235202452025520265202752028520295203052031520325203352034520355203652037520385203952040520415204252043520445204552046520475204852049520505205152052520535205452055520565205752058520595206052061520625206352064520655206652067520685206952070520715207252073520745207552076520775207852079520805208152082520835208452085520865208752088520895209052091520925209352094520955209652097520985209952100521015210252103521045210552106521075210852109521105211152112521135211452115521165211752118521195212052121521225212352124521255212652127521285212952130521315213252133521345213552136521375213852139521405214152142521435214452145521465214752148521495215052151521525215352154521555215652157521585215952160521615216252163521645216552166521675216852169521705217152172521735217452175521765217752178521795218052181521825218352184521855218652187521885218952190521915219252193521945219552196521975219852199522005220152202522035220452205522065220752208522095221052211522125221352214522155221652217522185221952220522215222252223522245222552226522275222852229522305223152232522335223452235522365223752238522395224052241522425224352244522455224652247522485224952250522515225252253522545225552256522575225852259522605226152262522635226452265522665226752268522695227052271522725227352274522755227652277522785227952280522815228252283522845228552286522875228852289522905229152292522935229452295522965229752298522995230052301523025230352304523055230652307523085230952310523115231252313523145231552316523175231852319523205232152322523235232452325523265232752328523295233052331523325233352334523355233652337523385233952340523415234252343523445234552346523475234852349523505235152352523535235452355523565235752358523595236052361523625236352364523655236652367523685236952370523715237252373523745237552376523775237852379523805238152382523835238452385523865238752388523895239052391523925239352394523955239652397523985239952400524015240252403524045240552406524075240852409524105241152412524135241452415524165241752418524195242052421524225242352424524255242652427524285242952430524315243252433524345243552436524375243852439524405244152442524435244452445524465244752448524495245052451524525245352454524555245652457524585245952460524615246252463524645246552466524675246852469524705247152472524735247452475524765247752478524795248052481524825248352484524855248652487524885248952490524915249252493524945249552496524975249852499525005250152502525035250452505525065250752508525095251052511525125251352514525155251652517525185251952520525215252252523525245252552526525275252852529525305253152532525335253452535525365253752538525395254052541525425254352544525455254652547525485254952550525515255252553525545255552556525575255852559525605256152562525635256452565525665256752568525695257052571525725257352574525755257652577525785257952580525815258252583525845258552586525875258852589525905259152592525935259452595525965259752598525995260052601526025260352604526055260652607526085260952610526115261252613526145261552616526175261852619526205262152622526235262452625526265262752628526295263052631526325263352634526355263652637526385263952640526415264252643526445264552646526475264852649526505265152652526535265452655526565265752658526595266052661526625266352664526655266652667526685266952670526715267252673526745267552676526775267852679526805268152682526835268452685526865268752688526895269052691526925269352694526955269652697526985269952700527015270252703527045270552706527075270852709527105271152712527135271452715527165271752718527195272052721527225272352724527255272652727527285272952730527315273252733527345273552736527375273852739527405274152742527435274452745527465274752748527495275052751527525275352754527555275652757527585275952760527615276252763527645276552766527675276852769527705277152772527735277452775527765277752778527795278052781527825278352784527855278652787527885278952790527915279252793527945279552796527975279852799528005280152802528035280452805528065280752808528095281052811528125281352814528155281652817528185281952820528215282252823528245282552826528275282852829528305283152832528335283452835528365283752838528395284052841528425284352844528455284652847528485284952850528515285252853528545285552856528575285852859528605286152862528635286452865528665286752868528695287052871528725287352874528755287652877528785287952880528815288252883528845288552886528875288852889528905289152892528935289452895528965289752898528995290052901529025290352904529055290652907529085290952910529115291252913529145291552916529175291852919529205292152922529235292452925529265292752928529295293052931529325293352934529355293652937529385293952940529415294252943529445294552946529475294852949529505295152952529535295452955529565295752958529595296052961529625296352964529655296652967529685296952970529715297252973529745297552976529775297852979529805298152982529835298452985529865298752988529895299052991529925299352994529955299652997529985299953000530015300253003530045300553006530075300853009530105301153012530135301453015530165301753018530195302053021530225302353024530255302653027530285302953030530315303253033530345303553036530375303853039530405304153042530435304453045530465304753048530495305053051530525305353054530555305653057530585305953060530615306253063530645306553066530675306853069530705307153072530735307453075530765307753078530795308053081530825308353084530855308653087530885308953090530915309253093530945309553096530975309853099531005310153102531035310453105531065310753108531095311053111531125311353114531155311653117531185311953120531215312253123531245312553126531275312853129531305313153132531335313453135531365313753138531395314053141531425314353144531455314653147531485314953150531515315253153531545315553156531575315853159531605316153162531635316453165531665316753168531695317053171531725317353174531755317653177531785317953180531815318253183531845318553186531875318853189531905319153192531935319453195531965319753198531995320053201532025320353204532055320653207532085320953210532115321253213532145321553216532175321853219532205322153222532235322453225532265322753228532295323053231532325323353234532355323653237532385323953240532415324253243532445324553246532475324853249532505325153252532535325453255532565325753258532595326053261532625326353264532655326653267532685326953270532715327253273532745327553276532775327853279532805328153282532835328453285532865328753288532895329053291532925329353294532955329653297532985329953300533015330253303533045330553306533075330853309533105331153312533135331453315533165331753318533195332053321533225332353324533255332653327533285332953330533315333253333533345333553336533375333853339533405334153342533435334453345533465334753348533495335053351533525335353354533555335653357533585335953360533615336253363533645336553366533675336853369533705337153372533735337453375533765337753378533795338053381533825338353384533855338653387533885338953390533915339253393533945339553396533975339853399534005340153402534035340453405534065340753408534095341053411534125341353414534155341653417534185341953420534215342253423534245342553426534275342853429534305343153432534335343453435534365343753438534395344053441534425344353444534455344653447534485344953450534515345253453534545345553456534575345853459534605346153462534635346453465534665346753468534695347053471534725347353474534755347653477534785347953480534815348253483534845348553486534875348853489534905349153492534935349453495534965349753498534995350053501535025350353504535055350653507535085350953510535115351253513535145351553516535175351853519535205352153522535235352453525535265352753528535295353053531535325353353534535355353653537535385353953540535415354253543535445354553546535475354853549535505355153552535535355453555535565355753558535595356053561535625356353564535655356653567535685356953570535715357253573535745357553576535775357853579535805358153582535835358453585535865358753588535895359053591535925359353594535955359653597535985359953600536015360253603536045360553606536075360853609536105361153612536135361453615536165361753618536195362053621536225362353624536255362653627536285362953630536315363253633536345363553636536375363853639536405364153642536435364453645536465364753648536495365053651536525365353654536555365653657536585365953660536615366253663536645366553666536675366853669536705367153672536735367453675536765367753678536795368053681536825368353684536855368653687536885368953690536915369253693536945369553696536975369853699537005370153702537035370453705537065370753708537095371053711537125371353714537155371653717537185371953720537215372253723537245372553726537275372853729537305373153732537335373453735537365373753738537395374053741537425374353744537455374653747537485374953750537515375253753537545375553756537575375853759537605376153762537635376453765537665376753768537695377053771537725377353774537755377653777537785377953780537815378253783537845378553786537875378853789537905379153792537935379453795537965379753798537995380053801538025380353804538055380653807538085380953810538115381253813538145381553816538175381853819538205382153822538235382453825538265382753828538295383053831538325383353834538355383653837538385383953840538415384253843538445384553846538475384853849538505385153852538535385453855538565385753858538595386053861538625386353864538655386653867538685386953870538715387253873538745387553876538775387853879538805388153882538835388453885538865388753888538895389053891538925389353894538955389653897538985389953900539015390253903539045390553906539075390853909539105391153912539135391453915539165391753918539195392053921539225392353924539255392653927539285392953930539315393253933539345393553936539375393853939539405394153942539435394453945539465394753948539495395053951539525395353954539555395653957539585395953960539615396253963539645396553966539675396853969539705397153972539735397453975539765397753978539795398053981539825398353984539855398653987539885398953990539915399253993539945399553996539975399853999540005400154002540035400454005540065400754008540095401054011540125401354014540155401654017540185401954020540215402254023540245402554026540275402854029540305403154032540335403454035540365403754038540395404054041540425404354044540455404654047540485404954050540515405254053540545405554056540575405854059540605406154062540635406454065540665406754068540695407054071540725407354074540755407654077540785407954080540815408254083540845408554086540875408854089540905409154092540935409454095540965409754098540995410054101541025410354104541055410654107541085410954110541115411254113541145411554116541175411854119541205412154122541235412454125541265412754128541295413054131541325413354134541355413654137541385413954140541415414254143541445414554146541475414854149541505415154152541535415454155541565415754158541595416054161541625416354164541655416654167541685416954170541715417254173541745417554176541775417854179541805418154182541835418454185541865418754188541895419054191541925419354194541955419654197541985419954200542015420254203542045420554206542075420854209542105421154212542135421454215542165421754218542195422054221542225422354224542255422654227542285422954230542315423254233542345423554236542375423854239542405424154242542435424454245542465424754248542495425054251542525425354254542555425654257542585425954260542615426254263542645426554266542675426854269542705427154272542735427454275542765427754278542795428054281542825428354284542855428654287542885428954290542915429254293542945429554296542975429854299543005430154302543035430454305543065430754308543095431054311543125431354314543155431654317543185431954320543215432254323543245432554326543275432854329543305433154332543335433454335543365433754338543395434054341543425434354344543455434654347543485434954350543515435254353543545435554356543575435854359543605436154362543635436454365543665436754368543695437054371543725437354374543755437654377543785437954380543815438254383543845438554386543875438854389543905439154392543935439454395543965439754398543995440054401544025440354404544055440654407544085440954410544115441254413544145441554416544175441854419544205442154422544235442454425544265442754428544295443054431544325443354434544355443654437544385443954440544415444254443544445444554446544475444854449544505445154452544535445454455544565445754458544595446054461544625446354464544655446654467544685446954470544715447254473544745447554476544775447854479544805448154482544835448454485544865448754488544895449054491544925449354494544955449654497544985449954500545015450254503545045450554506545075450854509545105451154512545135451454515545165451754518545195452054521545225452354524545255452654527545285452954530545315453254533545345453554536545375453854539545405454154542545435454454545545465454754548545495455054551545525455354554545555455654557545585455954560545615456254563545645456554566545675456854569545705457154572545735457454575545765457754578545795458054581545825458354584545855458654587545885458954590545915459254593545945459554596545975459854599546005460154602546035460454605546065460754608546095461054611546125461354614546155461654617546185461954620546215462254623546245462554626546275462854629546305463154632546335463454635546365463754638546395464054641546425464354644546455464654647546485464954650546515465254653546545465554656546575465854659546605466154662546635466454665546665466754668546695467054671546725467354674546755467654677546785467954680546815468254683546845468554686546875468854689546905469154692546935469454695546965469754698546995470054701547025470354704547055470654707547085470954710547115471254713547145471554716547175471854719547205472154722547235472454725547265472754728547295473054731547325473354734547355473654737547385473954740547415474254743547445474554746547475474854749547505475154752547535475454755547565475754758547595476054761547625476354764547655476654767547685476954770547715477254773547745477554776547775477854779547805478154782547835478454785547865478754788547895479054791547925479354794547955479654797547985479954800548015480254803548045480554806548075480854809548105481154812548135481454815548165481754818548195482054821548225482354824548255482654827548285482954830548315483254833548345483554836548375483854839548405484154842548435484454845548465484754848548495485054851548525485354854548555485654857548585485954860548615486254863548645486554866548675486854869548705487154872548735487454875548765487754878548795488054881548825488354884548855488654887548885488954890548915489254893548945489554896548975489854899549005490154902549035490454905549065490754908549095491054911549125491354914549155491654917549185491954920549215492254923549245492554926549275492854929549305493154932549335493454935549365493754938549395494054941549425494354944549455494654947549485494954950549515495254953549545495554956549575495854959549605496154962549635496454965549665496754968549695497054971549725497354974549755497654977549785497954980549815498254983549845498554986549875498854989549905499154992549935499454995549965499754998549995500055001550025500355004550055500655007550085500955010550115501255013550145501555016550175501855019550205502155022550235502455025550265502755028550295503055031550325503355034550355503655037550385503955040550415504255043550445504555046550475504855049550505505155052550535505455055550565505755058550595506055061550625506355064550655506655067550685506955070550715507255073550745507555076550775507855079550805508155082550835508455085550865508755088550895509055091550925509355094550955509655097550985509955100551015510255103551045510555106551075510855109551105511155112551135511455115551165511755118551195512055121551225512355124551255512655127551285512955130551315513255133551345513555136551375513855139551405514155142551435514455145551465514755148551495515055151551525515355154551555515655157551585515955160551615516255163551645516555166551675516855169551705517155172551735517455175551765517755178551795518055181551825518355184551855518655187551885518955190551915519255193551945519555196551975519855199552005520155202552035520455205552065520755208552095521055211552125521355214552155521655217552185521955220552215522255223552245522555226552275522855229552305523155232552335523455235552365523755238552395524055241552425524355244552455524655247552485524955250552515525255253552545525555256552575525855259552605526155262552635526455265552665526755268552695527055271552725527355274552755527655277552785527955280552815528255283552845528555286552875528855289552905529155292552935529455295552965529755298552995530055301553025530355304553055530655307553085530955310553115531255313553145531555316553175531855319553205532155322553235532455325553265532755328553295533055331553325533355334553355533655337553385533955340553415534255343553445534555346553475534855349553505535155352553535535455355553565535755358553595536055361553625536355364553655536655367553685536955370553715537255373553745537555376553775537855379553805538155382553835538455385553865538755388553895539055391553925539355394553955539655397553985539955400554015540255403554045540555406554075540855409554105541155412554135541455415554165541755418554195542055421554225542355424554255542655427554285542955430554315543255433554345543555436554375543855439554405544155442554435544455445554465544755448554495545055451554525545355454554555545655457554585545955460554615546255463554645546555466554675546855469554705547155472554735547455475554765547755478554795548055481554825548355484554855548655487554885548955490554915549255493554945549555496554975549855499555005550155502555035550455505555065550755508555095551055511555125551355514555155551655517555185551955520555215552255523555245552555526555275552855529555305553155532555335553455535555365553755538555395554055541555425554355544555455554655547555485554955550555515555255553555545555555556555575555855559555605556155562555635556455565555665556755568555695557055571555725557355574555755557655577555785557955580555815558255583555845558555586555875558855589555905559155592555935559455595555965559755598555995560055601556025560355604556055560655607556085560955610556115561255613556145561555616556175561855619556205562155622556235562455625556265562755628556295563055631556325563355634556355563655637556385563955640556415564255643556445564555646556475564855649556505565155652556535565455655556565565755658556595566055661556625566355664556655566655667556685566955670556715567255673556745567555676556775567855679556805568155682556835568455685556865568755688556895569055691556925569355694556955569655697556985569955700557015570255703557045570555706557075570855709557105571155712557135571455715557165571755718557195572055721557225572355724557255572655727557285572955730557315573255733557345573555736557375573855739557405574155742557435574455745557465574755748557495575055751557525575355754557555575655757557585575955760557615576255763557645576555766557675576855769557705577155772557735577455775557765577755778557795578055781557825578355784557855578655787557885578955790557915579255793557945579555796557975579855799558005580155802558035580455805558065580755808558095581055811558125581355814558155581655817558185581955820558215582255823558245582555826558275582855829558305583155832558335583455835558365583755838558395584055841558425584355844558455584655847558485584955850558515585255853558545585555856558575585855859558605586155862558635586455865558665586755868558695587055871558725587355874558755587655877558785587955880558815588255883558845588555886558875588855889558905589155892558935589455895558965589755898558995590055901559025590355904559055590655907559085590955910559115591255913559145591555916559175591855919559205592155922559235592455925559265592755928559295593055931559325593355934559355593655937559385593955940559415594255943559445594555946559475594855949559505595155952559535595455955559565595755958559595596055961559625596355964559655596655967559685596955970559715597255973559745597555976559775597855979559805598155982559835598455985559865598755988559895599055991559925599355994559955599655997559985599956000560015600256003560045600556006560075600856009560105601156012560135601456015560165601756018560195602056021560225602356024560255602656027560285602956030560315603256033560345603556036560375603856039560405604156042560435604456045560465604756048560495605056051560525605356054560555605656057560585605956060560615606256063560645606556066560675606856069560705607156072560735607456075560765607756078560795608056081560825608356084560855608656087560885608956090560915609256093560945609556096560975609856099561005610156102561035610456105561065610756108561095611056111561125611356114561155611656117561185611956120561215612256123561245612556126561275612856129561305613156132561335613456135561365613756138561395614056141561425614356144561455614656147561485614956150561515615256153561545615556156561575615856159561605616156162561635616456165561665616756168561695617056171561725617356174561755617656177561785617956180561815618256183561845618556186561875618856189561905619156192561935619456195561965619756198561995620056201562025620356204562055620656207562085620956210562115621256213562145621556216562175621856219562205622156222562235622456225562265622756228562295623056231562325623356234562355623656237562385623956240562415624256243562445624556246562475624856249562505625156252562535625456255562565625756258562595626056261562625626356264562655626656267562685626956270562715627256273562745627556276562775627856279562805628156282562835628456285562865628756288562895629056291562925629356294562955629656297562985629956300563015630256303563045630556306563075630856309563105631156312563135631456315563165631756318563195632056321563225632356324563255632656327563285632956330563315633256333563345633556336563375633856339563405634156342563435634456345563465634756348563495635056351563525635356354563555635656357563585635956360563615636256363563645636556366563675636856369563705637156372563735637456375563765637756378563795638056381563825638356384563855638656387563885638956390563915639256393563945639556396563975639856399564005640156402564035640456405564065640756408564095641056411564125641356414564155641656417564185641956420564215642256423564245642556426564275642856429564305643156432564335643456435564365643756438564395644056441564425644356444564455644656447564485644956450564515645256453564545645556456564575645856459564605646156462564635646456465564665646756468564695647056471564725647356474564755647656477564785647956480564815648256483564845648556486564875648856489564905649156492564935649456495564965649756498564995650056501565025650356504565055650656507565085650956510565115651256513565145651556516565175651856519565205652156522565235652456525565265652756528565295653056531565325653356534565355653656537565385653956540565415654256543565445654556546565475654856549565505655156552565535655456555565565655756558565595656056561565625656356564565655656656567565685656956570565715657256573565745657556576565775657856579565805658156582565835658456585565865658756588565895659056591565925659356594565955659656597565985659956600566015660256603566045660556606566075660856609566105661156612566135661456615566165661756618566195662056621566225662356624566255662656627566285662956630566315663256633566345663556636566375663856639566405664156642566435664456645566465664756648566495665056651566525665356654566555665656657566585665956660566615666256663566645666556666566675666856669566705667156672566735667456675566765667756678566795668056681566825668356684566855668656687566885668956690566915669256693566945669556696566975669856699567005670156702567035670456705567065670756708567095671056711567125671356714567155671656717567185671956720567215672256723567245672556726567275672856729567305673156732567335673456735567365673756738567395674056741567425674356744567455674656747567485674956750567515675256753567545675556756567575675856759567605676156762567635676456765567665676756768567695677056771567725677356774567755677656777567785677956780567815678256783567845678556786567875678856789567905679156792567935679456795567965679756798567995680056801568025680356804568055680656807568085680956810568115681256813568145681556816568175681856819568205682156822568235682456825568265682756828568295683056831568325683356834568355683656837568385683956840568415684256843568445684556846568475684856849568505685156852568535685456855568565685756858568595686056861568625686356864568655686656867568685686956870568715687256873568745687556876568775687856879568805688156882568835688456885568865688756888568895689056891568925689356894568955689656897568985689956900569015690256903569045690556906569075690856909569105691156912569135691456915569165691756918569195692056921569225692356924569255692656927569285692956930569315693256933569345693556936569375693856939569405694156942569435694456945569465694756948569495695056951569525695356954569555695656957569585695956960569615696256963569645696556966569675696856969569705697156972569735697456975569765697756978569795698056981569825698356984569855698656987569885698956990569915699256993569945699556996569975699856999570005700157002570035700457005570065700757008570095701057011570125701357014570155701657017570185701957020570215702257023570245702557026570275702857029570305703157032570335703457035570365703757038570395704057041570425704357044570455704657047570485704957050570515705257053570545705557056570575705857059570605706157062570635706457065570665706757068570695707057071570725707357074570755707657077570785707957080570815708257083570845708557086570875708857089570905709157092570935709457095570965709757098570995710057101571025710357104571055710657107571085710957110571115711257113571145711557116571175711857119571205712157122571235712457125571265712757128571295713057131571325713357134571355713657137571385713957140571415714257143571445714557146571475714857149571505715157152571535715457155571565715757158571595716057161571625716357164571655716657167571685716957170571715717257173571745717557176571775717857179571805718157182571835718457185571865718757188571895719057191571925719357194571955719657197571985719957200572015720257203572045720557206572075720857209572105721157212572135721457215572165721757218572195722057221572225722357224572255722657227572285722957230572315723257233572345723557236572375723857239572405724157242572435724457245572465724757248572495725057251572525725357254572555725657257572585725957260572615726257263572645726557266572675726857269572705727157272572735727457275572765727757278572795728057281572825728357284572855728657287572885728957290572915729257293572945729557296572975729857299573005730157302573035730457305573065730757308573095731057311573125731357314573155731657317573185731957320573215732257323573245732557326573275732857329573305733157332573335733457335573365733757338573395734057341573425734357344573455734657347573485734957350573515735257353573545735557356573575735857359573605736157362573635736457365573665736757368573695737057371573725737357374573755737657377573785737957380573815738257383573845738557386573875738857389573905739157392573935739457395573965739757398573995740057401574025740357404574055740657407574085740957410574115741257413574145741557416574175741857419574205742157422574235742457425574265742757428574295743057431574325743357434574355743657437574385743957440574415744257443574445744557446574475744857449574505745157452574535745457455574565745757458574595746057461574625746357464574655746657467574685746957470574715747257473574745747557476574775747857479574805748157482574835748457485574865748757488574895749057491574925749357494574955749657497574985749957500575015750257503575045750557506575075750857509575105751157512575135751457515575165751757518575195752057521575225752357524575255752657527575285752957530575315753257533575345753557536575375753857539575405754157542575435754457545575465754757548575495755057551575525755357554575555755657557575585755957560575615756257563575645756557566575675756857569575705757157572575735757457575575765757757578575795758057581575825758357584575855758657587575885758957590575915759257593575945759557596575975759857599576005760157602576035760457605576065760757608576095761057611576125761357614576155761657617576185761957620576215762257623576245762557626576275762857629576305763157632576335763457635576365763757638576395764057641576425764357644576455764657647576485764957650576515765257653576545765557656576575765857659576605766157662576635766457665576665766757668576695767057671576725767357674576755767657677576785767957680576815768257683576845768557686576875768857689576905769157692576935769457695576965769757698576995770057701577025770357704577055770657707577085770957710577115771257713577145771557716577175771857719577205772157722577235772457725577265772757728577295773057731577325773357734577355773657737577385773957740577415774257743577445774557746577475774857749577505775157752577535775457755577565775757758577595776057761577625776357764577655776657767577685776957770577715777257773577745777557776577775777857779577805778157782577835778457785577865778757788577895779057791577925779357794577955779657797577985779957800578015780257803578045780557806578075780857809578105781157812578135781457815578165781757818578195782057821578225782357824578255782657827578285782957830578315783257833578345783557836578375783857839578405784157842578435784457845578465784757848578495785057851578525785357854578555785657857578585785957860578615786257863578645786557866578675786857869578705787157872578735787457875578765787757878578795788057881578825788357884578855788657887578885788957890578915789257893578945789557896578975789857899579005790157902579035790457905579065790757908579095791057911579125791357914579155791657917579185791957920579215792257923579245792557926579275792857929579305793157932579335793457935579365793757938579395794057941579425794357944579455794657947579485794957950579515795257953579545795557956579575795857959579605796157962579635796457965579665796757968579695797057971579725797357974579755797657977579785797957980579815798257983579845798557986579875798857989579905799157992579935799457995579965799757998579995800058001580025800358004580055800658007580085800958010580115801258013580145801558016580175801858019580205802158022580235802458025580265802758028580295803058031580325803358034580355803658037580385803958040580415804258043580445804558046580475804858049580505805158052580535805458055580565805758058580595806058061580625806358064580655806658067580685806958070580715807258073580745807558076580775807858079580805808158082580835808458085580865808758088580895809058091580925809358094580955809658097580985809958100581015810258103581045810558106581075810858109581105811158112581135811458115581165811758118581195812058121581225812358124581255812658127581285812958130581315813258133581345813558136581375813858139581405814158142581435814458145581465814758148581495815058151581525815358154581555815658157581585815958160581615816258163581645816558166581675816858169581705817158172581735817458175581765817758178581795818058181581825818358184581855818658187581885818958190581915819258193581945819558196581975819858199582005820158202582035820458205582065820758208582095821058211582125821358214582155821658217582185821958220582215822258223582245822558226582275822858229582305823158232582335823458235582365823758238582395824058241582425824358244582455824658247582485824958250582515825258253582545825558256582575825858259582605826158262582635826458265582665826758268582695827058271582725827358274582755827658277582785827958280582815828258283582845828558286582875828858289582905829158292582935829458295582965829758298582995830058301583025830358304583055830658307583085830958310583115831258313583145831558316583175831858319583205832158322583235832458325583265832758328583295833058331583325833358334583355833658337583385833958340583415834258343583445834558346583475834858349583505835158352583535835458355583565835758358583595836058361583625836358364583655836658367583685836958370583715837258373583745837558376583775837858379583805838158382583835838458385583865838758388583895839058391583925839358394583955839658397583985839958400584015840258403584045840558406584075840858409584105841158412584135841458415584165841758418584195842058421584225842358424584255842658427584285842958430584315843258433584345843558436584375843858439584405844158442584435844458445584465844758448584495845058451584525845358454584555845658457584585845958460584615846258463584645846558466584675846858469584705847158472584735847458475584765847758478584795848058481584825848358484584855848658487584885848958490584915849258493584945849558496584975849858499585005850158502585035850458505585065850758508585095851058511585125851358514585155851658517585185851958520585215852258523585245852558526585275852858529585305853158532585335853458535585365853758538585395854058541585425854358544585455854658547585485854958550585515855258553585545855558556585575855858559585605856158562585635856458565585665856758568585695857058571585725857358574585755857658577585785857958580585815858258583585845858558586585875858858589585905859158592585935859458595585965859758598585995860058601586025860358604586055860658607586085860958610586115861258613586145861558616586175861858619586205862158622586235862458625586265862758628586295863058631586325863358634586355863658637586385863958640586415864258643586445864558646586475864858649586505865158652586535865458655586565865758658586595866058661586625866358664586655866658667586685866958670586715867258673586745867558676586775867858679586805868158682586835868458685586865868758688586895869058691586925869358694586955869658697586985869958700587015870258703587045870558706587075870858709587105871158712587135871458715587165871758718587195872058721587225872358724587255872658727587285872958730587315873258733587345873558736587375873858739587405874158742587435874458745587465874758748587495875058751587525875358754587555875658757587585875958760587615876258763587645876558766587675876858769587705877158772587735877458775587765877758778587795878058781587825878358784587855878658787587885878958790587915879258793587945879558796587975879858799588005880158802588035880458805588065880758808588095881058811588125881358814588155881658817588185881958820588215882258823588245882558826588275882858829588305883158832588335883458835588365883758838588395884058841588425884358844588455884658847588485884958850588515885258853588545885558856588575885858859588605886158862588635886458865588665886758868588695887058871588725887358874588755887658877588785887958880588815888258883588845888558886588875888858889588905889158892588935889458895588965889758898588995890058901589025890358904589055890658907589085890958910589115891258913589145891558916589175891858919589205892158922589235892458925589265892758928589295893058931589325893358934589355893658937589385893958940589415894258943589445894558946589475894858949589505895158952589535895458955589565895758958589595896058961589625896358964589655896658967589685896958970589715897258973589745897558976589775897858979589805898158982589835898458985589865898758988589895899058991589925899358994589955899658997589985899959000590015900259003590045900559006590075900859009590105901159012590135901459015590165901759018590195902059021590225902359024590255902659027590285902959030590315903259033590345903559036590375903859039590405904159042590435904459045590465904759048590495905059051590525905359054590555905659057590585905959060590615906259063590645906559066590675906859069590705907159072590735907459075590765907759078590795908059081590825908359084590855908659087590885908959090590915909259093590945909559096590975909859099591005910159102591035910459105591065910759108591095911059111591125911359114591155911659117591185911959120591215912259123591245912559126591275912859129591305913159132591335913459135591365913759138591395914059141591425914359144591455914659147591485914959150591515915259153591545915559156591575915859159591605916159162591635916459165591665916759168591695917059171591725917359174591755917659177591785917959180591815918259183591845918559186591875918859189591905919159192591935919459195591965919759198591995920059201592025920359204592055920659207592085920959210592115921259213592145921559216592175921859219592205922159222592235922459225592265922759228592295923059231592325923359234592355923659237592385923959240592415924259243592445924559246592475924859249592505925159252592535925459255592565925759258592595926059261592625926359264592655926659267592685926959270592715927259273592745927559276592775927859279592805928159282592835928459285592865928759288592895929059291592925929359294592955929659297592985929959300593015930259303593045930559306593075930859309593105931159312593135931459315593165931759318593195932059321593225932359324593255932659327593285932959330593315933259333593345933559336593375933859339593405934159342593435934459345593465934759348593495935059351593525935359354593555935659357593585935959360593615936259363593645936559366593675936859369593705937159372593735937459375593765937759378593795938059381593825938359384593855938659387593885938959390593915939259393593945939559396593975939859399594005940159402594035940459405594065940759408594095941059411594125941359414594155941659417594185941959420594215942259423594245942559426594275942859429594305943159432594335943459435594365943759438594395944059441594425944359444594455944659447594485944959450594515945259453594545945559456594575945859459594605946159462594635946459465594665946759468594695947059471594725947359474594755947659477594785947959480594815948259483594845948559486594875948859489594905949159492594935949459495594965949759498594995950059501595025950359504595055950659507595085950959510595115951259513595145951559516595175951859519595205952159522595235952459525595265952759528595295953059531595325953359534595355953659537595385953959540595415954259543595445954559546595475954859549595505955159552595535955459555595565955759558595595956059561595625956359564595655956659567595685956959570595715957259573595745957559576595775957859579595805958159582595835958459585595865958759588595895959059591595925959359594595955959659597595985959959600596015960259603596045960559606596075960859609596105961159612596135961459615596165961759618596195962059621596225962359624596255962659627596285962959630596315963259633596345963559636596375963859639596405964159642596435964459645596465964759648596495965059651596525965359654596555965659657596585965959660596615966259663596645966559666596675966859669596705967159672596735967459675596765967759678596795968059681596825968359684596855968659687596885968959690596915969259693596945969559696596975969859699597005970159702597035970459705597065970759708597095971059711597125971359714597155971659717597185971959720597215972259723597245972559726597275972859729597305973159732597335973459735597365973759738597395974059741597425974359744597455974659747597485974959750597515975259753597545975559756597575975859759597605976159762597635976459765597665976759768597695977059771597725977359774597755977659777597785977959780597815978259783597845978559786597875978859789597905979159792597935979459795597965979759798597995980059801598025980359804598055980659807598085980959810598115981259813598145981559816598175981859819598205982159822598235982459825598265982759828598295983059831598325983359834598355983659837598385983959840598415984259843598445984559846598475984859849598505985159852598535985459855598565985759858598595986059861598625986359864598655986659867598685986959870598715987259873598745987559876598775987859879598805988159882598835988459885598865988759888598895989059891598925989359894598955989659897598985989959900599015990259903599045990559906599075990859909599105991159912599135991459915599165991759918599195992059921599225992359924599255992659927599285992959930599315993259933599345993559936599375993859939599405994159942599435994459945599465994759948599495995059951599525995359954599555995659957599585995959960599615996259963599645996559966599675996859969599705997159972599735997459975599765997759978599795998059981599825998359984599855998659987599885998959990599915999259993599945999559996599975999859999600006000160002600036000460005600066000760008600096001060011600126001360014600156001660017600186001960020600216002260023600246002560026600276002860029600306003160032600336003460035600366003760038600396004060041600426004360044600456004660047600486004960050600516005260053600546005560056600576005860059600606006160062600636006460065600666006760068600696007060071600726007360074600756007660077600786007960080600816008260083600846008560086600876008860089600906009160092600936009460095600966009760098600996010060101601026010360104601056010660107601086010960110601116011260113601146011560116601176011860119601206012160122601236012460125601266012760128601296013060131601326013360134601356013660137601386013960140601416014260143601446014560146601476014860149601506015160152601536015460155601566015760158601596016060161601626016360164601656016660167601686016960170601716017260173601746017560176601776017860179601806018160182601836018460185601866018760188601896019060191601926019360194601956019660197601986019960200602016020260203602046020560206602076020860209602106021160212602136021460215602166021760218602196022060221602226022360224602256022660227602286022960230602316023260233602346023560236602376023860239602406024160242602436024460245602466024760248602496025060251602526025360254602556025660257602586025960260602616026260263602646026560266602676026860269602706027160272602736027460275602766027760278602796028060281602826028360284602856028660287602886028960290602916029260293602946029560296602976029860299603006030160302603036030460305603066030760308603096031060311603126031360314603156031660317603186031960320603216032260323603246032560326603276032860329603306033160332603336033460335603366033760338603396034060341603426034360344603456034660347603486034960350603516035260353603546035560356603576035860359603606036160362603636036460365603666036760368603696037060371603726037360374603756037660377603786037960380603816038260383603846038560386603876038860389603906039160392603936039460395603966039760398603996040060401604026040360404604056040660407604086040960410604116041260413604146041560416604176041860419604206042160422604236042460425604266042760428604296043060431604326043360434604356043660437604386043960440604416044260443604446044560446604476044860449604506045160452604536045460455604566045760458604596046060461604626046360464604656046660467604686046960470604716047260473604746047560476604776047860479604806048160482604836048460485604866048760488604896049060491604926049360494604956049660497604986049960500605016050260503605046050560506605076050860509605106051160512605136051460515605166051760518605196052060521605226052360524605256052660527605286052960530605316053260533605346053560536605376053860539605406054160542605436054460545605466054760548605496055060551605526055360554605556055660557605586055960560605616056260563605646056560566605676056860569605706057160572605736057460575605766057760578605796058060581605826058360584605856058660587605886058960590605916059260593605946059560596605976059860599606006060160602606036060460605606066060760608606096061060611606126061360614606156061660617606186061960620606216062260623606246062560626606276062860629606306063160632606336063460635606366063760638606396064060641606426064360644606456064660647606486064960650606516065260653606546065560656606576065860659606606066160662606636066460665606666066760668606696067060671606726067360674606756067660677606786067960680606816068260683606846068560686606876068860689606906069160692606936069460695606966069760698606996070060701607026070360704607056070660707607086070960710607116071260713607146071560716607176071860719607206072160722607236072460725607266072760728607296073060731607326073360734607356073660737607386073960740607416074260743607446074560746607476074860749607506075160752607536075460755607566075760758607596076060761607626076360764607656076660767607686076960770607716077260773607746077560776607776077860779607806078160782607836078460785607866078760788607896079060791607926079360794607956079660797607986079960800608016080260803608046080560806608076080860809608106081160812608136081460815608166081760818608196082060821608226082360824608256082660827608286082960830608316083260833608346083560836608376083860839608406084160842608436084460845608466084760848608496085060851608526085360854608556085660857608586085960860608616086260863608646086560866608676086860869608706087160872608736087460875608766087760878608796088060881608826088360884608856088660887608886088960890608916089260893608946089560896608976089860899609006090160902609036090460905609066090760908609096091060911609126091360914609156091660917609186091960920609216092260923609246092560926609276092860929609306093160932609336093460935609366093760938609396094060941609426094360944609456094660947609486094960950609516095260953609546095560956609576095860959609606096160962609636096460965609666096760968609696097060971609726097360974609756097660977609786097960980609816098260983609846098560986609876098860989609906099160992609936099460995609966099760998609996100061001610026100361004610056100661007610086100961010610116101261013610146101561016610176101861019610206102161022610236102461025610266102761028610296103061031610326103361034610356103661037610386103961040610416104261043610446104561046610476104861049610506105161052610536105461055610566105761058610596106061061610626106361064610656106661067610686106961070610716107261073610746107561076610776107861079610806108161082610836108461085610866108761088610896109061091610926109361094610956109661097610986109961100611016110261103611046110561106611076110861109611106111161112611136111461115611166111761118611196112061121611226112361124611256112661127611286112961130611316113261133611346113561136611376113861139611406114161142611436114461145611466114761148611496115061151611526115361154611556115661157611586115961160611616116261163611646116561166611676116861169611706117161172611736117461175611766117761178611796118061181611826118361184611856118661187611886118961190611916119261193611946119561196611976119861199612006120161202612036120461205612066120761208612096121061211612126121361214612156121661217612186121961220612216122261223612246122561226612276122861229612306123161232612336123461235612366123761238612396124061241612426124361244612456124661247612486124961250612516125261253612546125561256612576125861259612606126161262612636126461265612666126761268612696127061271612726127361274612756127661277612786127961280612816128261283612846128561286612876128861289612906129161292612936129461295612966129761298612996130061301613026130361304613056130661307613086130961310613116131261313613146131561316613176131861319613206132161322613236132461325613266132761328613296133061331613326133361334613356133661337613386133961340613416134261343613446134561346613476134861349613506135161352613536135461355613566135761358613596136061361613626136361364613656136661367613686136961370613716137261373613746137561376613776137861379613806138161382613836138461385613866138761388613896139061391613926139361394613956139661397613986139961400614016140261403614046140561406614076140861409614106141161412614136141461415614166141761418614196142061421614226142361424614256142661427614286142961430614316143261433614346143561436614376143861439614406144161442614436144461445614466144761448614496145061451614526145361454614556145661457614586145961460614616146261463614646146561466614676146861469614706147161472614736147461475614766147761478614796148061481614826148361484614856148661487614886148961490614916149261493614946149561496614976149861499615006150161502615036150461505615066150761508615096151061511615126151361514615156151661517615186151961520615216152261523615246152561526615276152861529615306153161532615336153461535615366153761538615396154061541615426154361544615456154661547615486154961550615516155261553615546155561556615576155861559615606156161562615636156461565615666156761568615696157061571615726157361574615756157661577615786157961580615816158261583615846158561586615876158861589615906159161592615936159461595615966159761598615996160061601616026160361604616056160661607616086160961610616116161261613616146161561616616176161861619616206162161622616236162461625616266162761628616296163061631616326163361634616356163661637616386163961640616416164261643616446164561646616476164861649616506165161652616536165461655616566165761658616596166061661616626166361664616656166661667616686166961670616716167261673616746167561676616776167861679616806168161682616836168461685616866168761688616896169061691616926169361694616956169661697616986169961700617016170261703617046170561706617076170861709617106171161712617136171461715617166171761718617196172061721617226172361724617256172661727617286172961730617316173261733617346173561736617376173861739617406174161742617436174461745617466174761748617496175061751617526175361754617556175661757617586175961760617616176261763617646176561766617676176861769617706177161772617736177461775617766177761778617796178061781617826178361784617856178661787617886178961790617916179261793617946179561796617976179861799618006180161802618036180461805618066180761808618096181061811618126181361814618156181661817618186181961820618216182261823618246182561826618276182861829618306183161832618336183461835618366183761838618396184061841618426184361844618456184661847618486184961850618516185261853618546185561856618576185861859618606186161862618636186461865618666186761868618696187061871618726187361874618756187661877618786187961880618816188261883618846188561886618876188861889618906189161892618936189461895618966189761898618996190061901619026190361904619056190661907619086190961910619116191261913619146191561916619176191861919619206192161922619236192461925619266192761928619296193061931619326193361934619356193661937619386193961940619416194261943619446194561946619476194861949619506195161952619536195461955619566195761958619596196061961619626196361964619656196661967619686196961970619716197261973619746197561976619776197861979619806198161982619836198461985619866198761988619896199061991619926199361994619956199661997619986199962000620016200262003620046200562006620076200862009620106201162012620136201462015620166201762018620196202062021620226202362024620256202662027620286202962030620316203262033620346203562036620376203862039620406204162042620436204462045620466204762048620496205062051620526205362054620556205662057620586205962060620616206262063620646206562066620676206862069620706207162072620736207462075620766207762078620796208062081620826208362084620856208662087620886208962090620916209262093620946209562096620976209862099621006210162102621036210462105621066210762108621096211062111621126211362114621156211662117621186211962120621216212262123621246212562126621276212862129621306213162132621336213462135621366213762138621396214062141621426214362144621456214662147621486214962150621516215262153621546215562156621576215862159621606216162162621636216462165621666216762168621696217062171621726217362174621756217662177621786217962180621816218262183621846218562186621876218862189621906219162192621936219462195621966219762198621996220062201622026220362204622056220662207622086220962210622116221262213622146221562216622176221862219622206222162222622236222462225622266222762228622296223062231622326223362234622356223662237622386223962240622416224262243622446224562246622476224862249622506225162252622536225462255622566225762258622596226062261622626226362264622656226662267622686226962270622716227262273622746227562276622776227862279622806228162282622836228462285622866228762288622896229062291622926229362294622956229662297622986229962300623016230262303623046230562306623076230862309623106231162312623136231462315623166231762318623196232062321623226232362324623256232662327623286232962330623316233262333623346233562336623376233862339623406234162342623436234462345623466234762348623496235062351623526235362354623556235662357623586235962360623616236262363623646236562366623676236862369623706237162372623736237462375623766237762378623796238062381623826238362384623856238662387623886238962390623916239262393623946239562396623976239862399624006240162402624036240462405624066240762408624096241062411624126241362414624156241662417624186241962420624216242262423624246242562426624276242862429624306243162432624336243462435624366243762438624396244062441624426244362444624456244662447624486244962450624516245262453624546245562456624576245862459624606246162462624636246462465624666246762468624696247062471624726247362474624756247662477624786247962480624816248262483624846248562486624876248862489624906249162492624936249462495624966249762498624996250062501625026250362504625056250662507625086250962510625116251262513625146251562516625176251862519625206252162522625236252462525625266252762528625296253062531625326253362534625356253662537625386253962540625416254262543625446254562546625476254862549625506255162552625536255462555625566255762558625596256062561625626256362564625656256662567625686256962570625716257262573625746257562576625776257862579625806258162582625836258462585625866258762588625896259062591625926259362594625956259662597625986259962600626016260262603626046260562606626076260862609626106261162612626136261462615626166261762618626196262062621626226262362624626256262662627626286262962630626316263262633626346263562636626376263862639626406264162642626436264462645626466264762648626496265062651626526265362654626556265662657626586265962660626616266262663626646266562666626676266862669626706267162672626736267462675626766267762678626796268062681626826268362684626856268662687626886268962690626916269262693626946269562696626976269862699627006270162702627036270462705627066270762708627096271062711627126271362714627156271662717627186271962720627216272262723627246272562726627276272862729627306273162732627336273462735627366273762738627396274062741627426274362744627456274662747627486274962750627516275262753627546275562756627576275862759627606276162762627636276462765627666276762768627696277062771627726277362774627756277662777627786277962780627816278262783627846278562786627876278862789627906279162792627936279462795627966279762798627996280062801628026280362804628056280662807628086280962810628116281262813628146281562816628176281862819628206282162822628236282462825628266282762828628296283062831628326283362834628356283662837628386283962840628416284262843628446284562846628476284862849628506285162852628536285462855628566285762858628596286062861628626286362864628656286662867628686286962870628716287262873628746287562876628776287862879628806288162882628836288462885628866288762888628896289062891628926289362894628956289662897628986289962900629016290262903629046290562906629076290862909629106291162912629136291462915629166291762918629196292062921629226292362924629256292662927629286292962930629316293262933629346293562936629376293862939629406294162942629436294462945629466294762948629496295062951629526295362954629556295662957629586295962960629616296262963629646296562966629676296862969629706297162972629736297462975629766297762978629796298062981629826298362984629856298662987629886298962990629916299262993629946299562996629976299862999630006300163002630036300463005630066300763008630096301063011630126301363014630156301663017630186301963020630216302263023630246302563026630276302863029630306303163032630336303463035630366303763038630396304063041630426304363044630456304663047630486304963050630516305263053630546305563056630576305863059630606306163062630636306463065630666306763068630696307063071630726307363074630756307663077630786307963080630816308263083630846308563086630876308863089630906309163092630936309463095630966309763098630996310063101631026310363104631056310663107631086310963110631116311263113631146311563116631176311863119631206312163122631236312463125631266312763128631296313063131631326313363134631356313663137631386313963140631416314263143631446314563146631476314863149631506315163152631536315463155631566315763158631596316063161631626316363164631656316663167631686316963170631716317263173631746317563176631776317863179631806318163182631836318463185631866318763188631896319063191631926319363194631956319663197631986319963200632016320263203632046320563206632076320863209632106321163212632136321463215632166321763218632196322063221632226322363224632256322663227632286322963230632316323263233632346323563236632376323863239632406324163242632436324463245632466324763248632496325063251632526325363254632556325663257632586325963260632616326263263632646326563266632676326863269632706327163272632736327463275632766327763278632796328063281632826328363284632856328663287632886328963290632916329263293632946329563296632976329863299633006330163302633036330463305633066330763308633096331063311633126331363314633156331663317633186331963320633216332263323633246332563326633276332863329633306333163332633336333463335633366333763338633396334063341633426334363344633456334663347633486334963350633516335263353633546335563356633576335863359633606336163362633636336463365633666336763368633696337063371633726337363374633756337663377633786337963380633816338263383633846338563386633876338863389633906339163392633936339463395633966339763398633996340063401634026340363404634056340663407634086340963410634116341263413634146341563416634176341863419634206342163422634236342463425634266342763428634296343063431634326343363434634356343663437634386343963440634416344263443634446344563446634476344863449634506345163452634536345463455634566345763458634596346063461634626346363464634656346663467634686346963470634716347263473634746347563476634776347863479634806348163482634836348463485634866348763488634896349063491634926349363494634956349663497634986349963500635016350263503635046350563506635076350863509635106351163512635136351463515635166351763518635196352063521635226352363524635256352663527635286352963530635316353263533635346353563536635376353863539635406354163542635436354463545635466354763548635496355063551635526355363554635556355663557635586355963560635616356263563635646356563566635676356863569635706357163572635736357463575635766357763578635796358063581635826358363584635856358663587635886358963590635916359263593635946359563596635976359863599636006360163602636036360463605636066360763608636096361063611636126361363614636156361663617636186361963620636216362263623636246362563626636276362863629636306363163632636336363463635636366363763638636396364063641636426364363644636456364663647636486364963650636516365263653636546365563656636576365863659636606366163662636636366463665636666366763668636696367063671636726367363674636756367663677636786367963680636816368263683636846368563686636876368863689636906369163692636936369463695636966369763698636996370063701637026370363704637056370663707637086370963710637116371263713637146371563716637176371863719637206372163722637236372463725637266372763728637296373063731637326373363734637356373663737637386373963740637416374263743637446374563746637476374863749637506375163752637536375463755637566375763758637596376063761637626376363764637656376663767637686376963770637716377263773637746377563776637776377863779637806378163782637836378463785637866378763788637896379063791637926379363794637956379663797637986379963800638016380263803638046380563806638076380863809638106381163812638136381463815638166381763818638196382063821638226382363824638256382663827638286382963830638316383263833638346383563836638376383863839638406384163842638436384463845638466384763848638496385063851638526385363854638556385663857638586385963860638616386263863638646386563866638676386863869638706387163872638736387463875638766387763878638796388063881638826388363884638856388663887638886388963890638916389263893638946389563896638976389863899639006390163902639036390463905639066390763908639096391063911639126391363914639156391663917639186391963920639216392263923639246392563926639276392863929639306393163932639336393463935639366393763938639396394063941639426394363944639456394663947639486394963950639516395263953639546395563956639576395863959639606396163962639636396463965639666396763968639696397063971639726397363974639756397663977639786397963980639816398263983639846398563986639876398863989639906399163992639936399463995639966399763998639996400064001640026400364004640056400664007640086400964010640116401264013640146401564016640176401864019640206402164022640236402464025640266402764028640296403064031640326403364034640356403664037640386403964040640416404264043640446404564046640476404864049640506405164052640536405464055640566405764058640596406064061640626406364064640656406664067640686406964070640716407264073640746407564076640776407864079640806408164082640836408464085640866408764088640896409064091640926409364094640956409664097640986409964100641016410264103641046410564106641076410864109641106411164112641136411464115641166411764118641196412064121641226412364124641256412664127641286412964130641316413264133641346413564136641376413864139641406414164142641436414464145641466414764148641496415064151641526415364154641556415664157641586415964160641616416264163641646416564166641676416864169641706417164172641736417464175641766417764178641796418064181641826418364184641856418664187641886418964190641916419264193641946419564196641976419864199642006420164202642036420464205642066420764208642096421064211642126421364214642156421664217642186421964220642216422264223642246422564226642276422864229642306423164232642336423464235642366423764238642396424064241642426424364244642456424664247642486424964250642516425264253642546425564256642576425864259642606426164262642636426464265642666426764268642696427064271642726427364274642756427664277642786427964280642816428264283642846428564286642876428864289642906429164292642936429464295642966429764298642996430064301643026430364304643056430664307643086430964310643116431264313643146431564316643176431864319643206432164322643236432464325643266432764328643296433064331643326433364334643356433664337643386433964340643416434264343643446434564346643476434864349643506435164352643536435464355643566435764358643596436064361643626436364364643656436664367643686436964370643716437264373643746437564376643776437864379643806438164382643836438464385643866438764388643896439064391643926439364394643956439664397643986439964400644016440264403644046440564406644076440864409644106441164412644136441464415644166441764418644196442064421644226442364424644256442664427644286442964430644316443264433644346443564436644376443864439644406444164442644436444464445644466444764448644496445064451644526445364454644556445664457644586445964460644616446264463644646446564466644676446864469644706447164472644736447464475644766447764478644796448064481644826448364484644856448664487644886448964490644916449264493644946449564496644976449864499645006450164502645036450464505645066450764508645096451064511645126451364514645156451664517645186451964520645216452264523645246452564526645276452864529645306453164532645336453464535645366453764538645396454064541645426454364544645456454664547645486454964550645516455264553645546455564556645576455864559645606456164562645636456464565645666456764568645696457064571645726457364574645756457664577645786457964580645816458264583645846458564586645876458864589645906459164592645936459464595645966459764598645996460064601646026460364604646056460664607646086460964610646116461264613646146461564616646176461864619646206462164622646236462464625646266462764628646296463064631646326463364634646356463664637646386463964640646416464264643646446464564646646476464864649646506465164652646536465464655646566465764658646596466064661646626466364664646656466664667646686466964670646716467264673646746467564676646776467864679646806468164682646836468464685646866468764688646896469064691646926469364694646956469664697646986469964700647016470264703647046470564706647076470864709647106471164712647136471464715647166471764718647196472064721647226472364724647256472664727647286472964730647316473264733647346473564736647376473864739647406474164742647436474464745647466474764748647496475064751647526475364754647556475664757647586475964760647616476264763647646476564766647676476864769647706477164772647736477464775647766477764778647796478064781647826478364784647856478664787647886478964790647916479264793647946479564796647976479864799648006480164802648036480464805648066480764808648096481064811648126481364814648156481664817648186481964820648216482264823648246482564826648276482864829648306483164832648336483464835648366483764838648396484064841648426484364844648456484664847648486484964850648516485264853648546485564856648576485864859648606486164862648636486464865648666486764868648696487064871648726487364874648756487664877648786487964880648816488264883648846488564886648876488864889648906489164892648936489464895648966489764898648996490064901649026490364904649056490664907649086490964910649116491264913649146491564916649176491864919649206492164922649236492464925649266492764928649296493064931649326493364934649356493664937649386493964940649416494264943649446494564946649476494864949649506495164952649536495464955649566495764958649596496064961649626496364964649656496664967649686496964970649716497264973649746497564976649776497864979649806498164982649836498464985649866498764988649896499064991649926499364994649956499664997649986499965000650016500265003650046500565006650076500865009650106501165012650136501465015650166501765018650196502065021650226502365024650256502665027650286502965030650316503265033650346503565036650376503865039650406504165042650436504465045650466504765048650496505065051650526505365054650556505665057650586505965060650616506265063650646506565066650676506865069650706507165072650736507465075650766507765078650796508065081650826508365084650856508665087650886508965090650916509265093650946509565096650976509865099651006510165102651036510465105651066510765108651096511065111651126511365114651156511665117651186511965120651216512265123651246512565126651276512865129651306513165132651336513465135651366513765138651396514065141651426514365144651456514665147651486514965150651516515265153651546515565156651576515865159651606516165162651636516465165651666516765168651696517065171651726517365174651756517665177651786517965180651816518265183651846518565186651876518865189651906519165192651936519465195651966519765198651996520065201652026520365204652056520665207652086520965210652116521265213652146521565216652176521865219652206522165222652236522465225652266522765228652296523065231652326523365234652356523665237652386523965240652416524265243652446524565246652476524865249652506525165252652536525465255652566525765258652596526065261652626526365264652656526665267652686526965270652716527265273652746527565276652776527865279652806528165282652836528465285652866528765288652896529065291652926529365294652956529665297652986529965300653016530265303653046530565306653076530865309653106531165312653136531465315653166531765318653196532065321653226532365324653256532665327653286532965330653316533265333653346533565336653376533865339653406534165342653436534465345653466534765348653496535065351653526535365354653556535665357653586535965360653616536265363653646536565366653676536865369653706537165372653736537465375653766537765378653796538065381653826538365384653856538665387653886538965390653916539265393653946539565396653976539865399654006540165402654036540465405654066540765408654096541065411654126541365414654156541665417654186541965420654216542265423654246542565426654276542865429654306543165432654336543465435654366543765438654396544065441654426544365444654456544665447654486544965450654516545265453654546545565456654576545865459654606546165462654636546465465654666546765468654696547065471654726547365474654756547665477654786547965480654816548265483654846548565486654876548865489654906549165492654936549465495654966549765498654996550065501655026550365504655056550665507655086550965510655116551265513655146551565516655176551865519655206552165522655236552465525655266552765528655296553065531655326553365534655356553665537655386553965540655416554265543655446554565546655476554865549655506555165552655536555465555655566555765558655596556065561655626556365564655656556665567655686556965570655716557265573655746557565576655776557865579655806558165582655836558465585655866558765588655896559065591655926559365594655956559665597655986559965600656016560265603656046560565606656076560865609656106561165612656136561465615656166561765618656196562065621656226562365624656256562665627656286562965630656316563265633656346563565636656376563865639656406564165642656436564465645656466564765648656496565065651656526565365654656556565665657656586565965660656616566265663656646566565666656676566865669656706567165672656736567465675656766567765678656796568065681656826568365684656856568665687656886568965690656916569265693656946569565696656976569865699657006570165702657036570465705657066570765708657096571065711657126571365714657156571665717657186571965720657216572265723657246572565726657276572865729657306573165732657336573465735657366573765738657396574065741657426574365744657456574665747657486574965750657516575265753657546575565756657576575865759657606576165762657636576465765657666576765768657696577065771657726577365774657756577665777657786577965780657816578265783657846578565786657876578865789657906579165792657936579465795657966579765798657996580065801658026580365804658056580665807658086580965810658116581265813658146581565816658176581865819658206582165822658236582465825658266582765828658296583065831658326583365834658356583665837658386583965840658416584265843658446584565846658476584865849658506585165852658536585465855658566585765858658596586065861658626586365864658656586665867658686586965870658716587265873658746587565876658776587865879658806588165882658836588465885658866588765888658896589065891658926589365894658956589665897658986589965900659016590265903659046590565906659076590865909659106591165912659136591465915659166591765918659196592065921659226592365924659256592665927659286592965930659316593265933659346593565936659376593865939659406594165942659436594465945659466594765948659496595065951659526595365954659556595665957659586595965960659616596265963659646596565966659676596865969659706597165972659736597465975659766597765978659796598065981659826598365984659856598665987659886598965990659916599265993659946599565996659976599865999660006600166002660036600466005660066600766008660096601066011660126601366014660156601666017660186601966020660216602266023660246602566026660276602866029660306603166032660336603466035660366603766038660396604066041660426604366044660456604666047660486604966050660516605266053660546605566056660576605866059660606606166062660636606466065660666606766068660696607066071660726607366074660756607666077660786607966080660816608266083660846608566086660876608866089660906609166092660936609466095660966609766098660996610066101661026610366104661056610666107661086610966110661116611266113661146611566116661176611866119661206612166122661236612466125661266612766128661296613066131661326613366134661356613666137661386613966140661416614266143661446614566146661476614866149661506615166152661536615466155661566615766158661596616066161661626616366164661656616666167661686616966170661716617266173661746617566176661776617866179661806618166182661836618466185661866618766188661896619066191661926619366194661956619666197661986619966200662016620266203662046620566206662076620866209662106621166212662136621466215662166621766218662196622066221662226622366224662256622666227662286622966230662316623266233662346623566236662376623866239662406624166242662436624466245662466624766248662496625066251662526625366254662556625666257662586625966260662616626266263662646626566266662676626866269662706627166272662736627466275662766627766278662796628066281662826628366284662856628666287662886628966290662916629266293662946629566296662976629866299663006630166302663036630466305663066630766308663096631066311663126631366314663156631666317663186631966320663216632266323663246632566326663276632866329663306633166332663336633466335663366633766338663396634066341663426634366344663456634666347663486634966350663516635266353663546635566356663576635866359663606636166362663636636466365663666636766368663696637066371663726637366374663756637666377663786637966380663816638266383663846638566386663876638866389663906639166392663936639466395663966639766398663996640066401664026640366404664056640666407664086640966410664116641266413664146641566416664176641866419664206642166422664236642466425664266642766428664296643066431664326643366434664356643666437664386643966440664416644266443664446644566446664476644866449664506645166452664536645466455664566645766458664596646066461664626646366464664656646666467664686646966470664716647266473664746647566476664776647866479664806648166482664836648466485664866648766488664896649066491664926649366494664956649666497664986649966500665016650266503665046650566506665076650866509665106651166512665136651466515665166651766518665196652066521665226652366524665256652666527665286652966530665316653266533665346653566536665376653866539665406654166542665436654466545665466654766548665496655066551665526655366554665556655666557665586655966560665616656266563665646656566566665676656866569665706657166572665736657466575665766657766578665796658066581665826658366584665856658666587665886658966590665916659266593665946659566596665976659866599666006660166602666036660466605666066660766608666096661066611666126661366614666156661666617666186661966620666216662266623666246662566626666276662866629666306663166632666336663466635666366663766638666396664066641666426664366644666456664666647666486664966650666516665266653666546665566656666576665866659666606666166662666636666466665666666666766668666696667066671666726667366674666756667666677666786667966680666816668266683666846668566686666876668866689666906669166692666936669466695666966669766698666996670066701667026670366704667056670666707667086670966710667116671266713667146671566716667176671866719667206672166722667236672466725667266672766728667296673066731667326673366734667356673666737667386673966740667416674266743667446674566746667476674866749667506675166752667536675466755667566675766758667596676066761667626676366764667656676666767667686676966770667716677266773667746677566776667776677866779667806678166782667836678466785667866678766788667896679066791667926679366794667956679666797667986679966800668016680266803668046680566806668076680866809668106681166812668136681466815668166681766818668196682066821668226682366824668256682666827668286682966830668316683266833668346683566836668376683866839668406684166842668436684466845668466684766848668496685066851668526685366854668556685666857668586685966860668616686266863668646686566866668676686866869668706687166872668736687466875668766687766878668796688066881668826688366884668856688666887668886688966890668916689266893668946689566896668976689866899669006690166902669036690466905669066690766908669096691066911669126691366914669156691666917669186691966920669216692266923669246692566926669276692866929669306693166932669336693466935669366693766938669396694066941669426694366944669456694666947669486694966950669516695266953669546695566956669576695866959669606696166962669636696466965669666696766968669696697066971669726697366974669756697666977669786697966980669816698266983669846698566986669876698866989669906699166992669936699466995669966699766998669996700067001670026700367004670056700667007670086700967010670116701267013670146701567016670176701867019670206702167022670236702467025670266702767028670296703067031670326703367034670356703667037670386703967040670416704267043670446704567046670476704867049670506705167052670536705467055670566705767058670596706067061670626706367064670656706667067670686706967070670716707267073670746707567076670776707867079670806708167082670836708467085670866708767088670896709067091670926709367094670956709667097670986709967100671016710267103671046710567106671076710867109671106711167112671136711467115671166711767118671196712067121671226712367124671256712667127671286712967130671316713267133671346713567136671376713867139671406714167142671436714467145671466714767148671496715067151671526715367154671556715667157671586715967160671616716267163671646716567166671676716867169671706717167172671736717467175671766717767178671796718067181671826718367184671856718667187671886718967190671916719267193671946719567196671976719867199672006720167202672036720467205672066720767208672096721067211672126721367214672156721667217672186721967220672216722267223672246722567226672276722867229672306723167232672336723467235672366723767238672396724067241672426724367244672456724667247672486724967250672516725267253672546725567256672576725867259672606726167262672636726467265672666726767268672696727067271672726727367274672756727667277672786727967280672816728267283672846728567286672876728867289672906729167292672936729467295672966729767298672996730067301673026730367304673056730667307673086730967310673116731267313673146731567316673176731867319673206732167322673236732467325673266732767328673296733067331673326733367334673356733667337673386733967340673416734267343673446734567346673476734867349673506735167352673536735467355673566735767358673596736067361673626736367364673656736667367673686736967370673716737267373673746737567376673776737867379673806738167382673836738467385673866738767388673896739067391673926739367394673956739667397673986739967400674016740267403674046740567406674076740867409674106741167412674136741467415674166741767418674196742067421674226742367424674256742667427674286742967430674316743267433674346743567436674376743867439674406744167442674436744467445674466744767448674496745067451674526745367454674556745667457674586745967460674616746267463674646746567466674676746867469674706747167472674736747467475674766747767478674796748067481674826748367484674856748667487674886748967490674916749267493674946749567496674976749867499675006750167502675036750467505675066750767508675096751067511675126751367514675156751667517675186751967520675216752267523675246752567526675276752867529675306753167532675336753467535675366753767538675396754067541675426754367544675456754667547675486754967550675516755267553675546755567556675576755867559675606756167562675636756467565675666756767568675696757067571675726757367574675756757667577675786757967580675816758267583675846758567586675876758867589675906759167592675936759467595675966759767598675996760067601676026760367604676056760667607676086760967610676116761267613676146761567616676176761867619676206762167622676236762467625676266762767628676296763067631676326763367634676356763667637676386763967640676416764267643676446764567646676476764867649676506765167652676536765467655676566765767658676596766067661676626766367664676656766667667676686766967670676716767267673676746767567676676776767867679676806768167682676836768467685676866768767688676896769067691676926769367694676956769667697676986769967700677016770267703677046770567706677076770867709677106771167712677136771467715677166771767718677196772067721677226772367724677256772667727677286772967730677316773267733677346773567736677376773867739677406774167742677436774467745677466774767748677496775067751677526775367754677556775667757677586775967760677616776267763677646776567766677676776867769677706777167772677736777467775677766777767778677796778067781677826778367784677856778667787677886778967790677916779267793677946779567796677976779867799678006780167802678036780467805678066780767808678096781067811678126781367814678156781667817678186781967820678216782267823678246782567826678276782867829678306783167832678336783467835678366783767838678396784067841678426784367844678456784667847678486784967850678516785267853678546785567856678576785867859678606786167862678636786467865678666786767868678696787067871678726787367874678756787667877678786787967880678816788267883678846788567886678876788867889678906789167892678936789467895678966789767898678996790067901679026790367904679056790667907679086790967910679116791267913679146791567916679176791867919679206792167922679236792467925679266792767928679296793067931679326793367934679356793667937679386793967940679416794267943679446794567946679476794867949679506795167952679536795467955679566795767958679596796067961679626796367964679656796667967679686796967970679716797267973679746797567976679776797867979679806798167982679836798467985679866798767988679896799067991679926799367994679956799667997679986799968000680016800268003680046800568006680076800868009680106801168012680136801468015680166801768018680196802068021680226802368024680256802668027680286802968030680316803268033680346803568036680376803868039680406804168042680436804468045680466804768048680496805068051680526805368054680556805668057680586805968060680616806268063680646806568066680676806868069680706807168072680736807468075680766807768078680796808068081680826808368084680856808668087680886808968090680916809268093680946809568096680976809868099681006810168102681036810468105681066810768108681096811068111681126811368114681156811668117681186811968120681216812268123681246812568126681276812868129681306813168132681336813468135681366813768138681396814068141681426814368144681456814668147681486814968150681516815268153681546815568156681576815868159681606816168162681636816468165681666816768168681696817068171681726817368174681756817668177681786817968180681816818268183681846818568186681876818868189681906819168192681936819468195681966819768198681996820068201682026820368204682056820668207682086820968210682116821268213682146821568216682176821868219682206822168222682236822468225682266822768228682296823068231682326823368234682356823668237682386823968240682416824268243682446824568246682476824868249682506825168252682536825468255682566825768258682596826068261682626826368264682656826668267682686826968270682716827268273682746827568276682776827868279682806828168282682836828468285682866828768288682896829068291682926829368294682956829668297682986829968300683016830268303683046830568306683076830868309683106831168312683136831468315683166831768318683196832068321683226832368324683256832668327683286832968330683316833268333683346833568336683376833868339683406834168342683436834468345683466834768348683496835068351683526835368354683556835668357683586835968360683616836268363683646836568366683676836868369683706837168372683736837468375683766837768378683796838068381683826838368384683856838668387683886838968390683916839268393683946839568396683976839868399684006840168402684036840468405684066840768408684096841068411684126841368414684156841668417684186841968420684216842268423684246842568426684276842868429684306843168432684336843468435684366843768438684396844068441684426844368444684456844668447684486844968450684516845268453684546845568456684576845868459684606846168462684636846468465684666846768468684696847068471684726847368474684756847668477684786847968480684816848268483684846848568486684876848868489684906849168492684936849468495684966849768498684996850068501685026850368504685056850668507685086850968510685116851268513685146851568516685176851868519685206852168522685236852468525685266852768528685296853068531685326853368534685356853668537685386853968540685416854268543685446854568546685476854868549685506855168552685536855468555685566855768558685596856068561685626856368564685656856668567685686856968570685716857268573685746857568576685776857868579685806858168582685836858468585685866858768588685896859068591685926859368594685956859668597685986859968600686016860268603686046860568606686076860868609686106861168612686136861468615686166861768618686196862068621686226862368624686256862668627686286862968630686316863268633686346863568636686376863868639686406864168642686436864468645686466864768648686496865068651686526865368654686556865668657686586865968660686616866268663686646866568666686676866868669686706867168672686736867468675686766867768678686796868068681686826868368684686856868668687686886868968690686916869268693686946869568696686976869868699687006870168702687036870468705687066870768708687096871068711687126871368714687156871668717687186871968720687216872268723687246872568726687276872868729687306873168732687336873468735687366873768738687396874068741687426874368744687456874668747687486874968750687516875268753687546875568756687576875868759687606876168762687636876468765687666876768768687696877068771687726877368774687756877668777687786877968780687816878268783687846878568786687876878868789687906879168792687936879468795687966879768798687996880068801688026880368804688056880668807688086880968810688116881268813688146881568816688176881868819688206882168822688236882468825688266882768828688296883068831688326883368834688356883668837688386883968840688416884268843688446884568846688476884868849688506885168852688536885468855688566885768858688596886068861688626886368864688656886668867688686886968870688716887268873688746887568876688776887868879688806888168882688836888468885688866888768888688896889068891688926889368894688956889668897688986889968900689016890268903689046890568906689076890868909689106891168912689136891468915689166891768918689196892068921689226892368924689256892668927689286892968930689316893268933689346893568936689376893868939689406894168942689436894468945689466894768948689496895068951689526895368954689556895668957689586895968960689616896268963689646896568966689676896868969689706897168972689736897468975689766897768978689796898068981689826898368984689856898668987689886898968990689916899268993689946899568996689976899868999690006900169002690036900469005690066900769008690096901069011690126901369014690156901669017690186901969020690216902269023690246902569026690276902869029690306903169032690336903469035690366903769038690396904069041690426904369044690456904669047690486904969050690516905269053690546905569056690576905869059690606906169062690636906469065690666906769068690696907069071690726907369074690756907669077690786907969080690816908269083690846908569086690876908869089690906909169092690936909469095690966909769098690996910069101691026910369104691056910669107691086910969110691116911269113691146911569116691176911869119691206912169122691236912469125691266912769128691296913069131691326913369134691356913669137691386913969140691416914269143691446914569146691476914869149691506915169152691536915469155691566915769158691596916069161691626916369164691656916669167691686916969170691716917269173691746917569176691776917869179691806918169182691836918469185691866918769188691896919069191691926919369194691956919669197691986919969200692016920269203692046920569206692076920869209692106921169212692136921469215692166921769218692196922069221692226922369224692256922669227692286922969230692316923269233692346923569236692376923869239692406924169242692436924469245692466924769248692496925069251692526925369254692556925669257692586925969260692616926269263692646926569266692676926869269692706927169272692736927469275692766927769278692796928069281692826928369284692856928669287692886928969290692916929269293692946929569296692976929869299693006930169302693036930469305693066930769308693096931069311693126931369314693156931669317693186931969320693216932269323693246932569326693276932869329693306933169332693336933469335693366933769338693396934069341693426934369344693456934669347693486934969350693516935269353693546935569356693576935869359693606936169362693636936469365693666936769368693696937069371693726937369374693756937669377693786937969380693816938269383693846938569386693876938869389693906939169392693936939469395693966939769398693996940069401694026940369404694056940669407694086940969410694116941269413694146941569416694176941869419694206942169422694236942469425694266942769428694296943069431694326943369434694356943669437694386943969440694416944269443694446944569446694476944869449694506945169452694536945469455694566945769458694596946069461694626946369464694656946669467694686946969470694716947269473694746947569476694776947869479694806948169482694836948469485694866948769488694896949069491694926949369494694956949669497694986949969500695016950269503695046950569506695076950869509695106951169512695136951469515695166951769518695196952069521695226952369524695256952669527695286952969530695316953269533695346953569536695376953869539695406954169542695436954469545695466954769548695496955069551695526955369554695556955669557695586955969560695616956269563695646956569566695676956869569695706957169572695736957469575695766957769578695796958069581695826958369584695856958669587695886958969590695916959269593695946959569596695976959869599696006960169602696036960469605696066960769608696096961069611696126961369614696156961669617696186961969620696216962269623696246962569626696276962869629696306963169632696336963469635696366963769638696396964069641696426964369644696456964669647696486964969650696516965269653696546965569656696576965869659696606966169662696636966469665696666966769668696696967069671696726967369674696756967669677696786967969680696816968269683696846968569686696876968869689696906969169692696936969469695696966969769698696996970069701697026970369704697056970669707697086970969710697116971269713697146971569716697176971869719697206972169722697236972469725697266972769728697296973069731697326973369734697356973669737697386973969740697416974269743697446974569746697476974869749697506975169752697536975469755697566975769758697596976069761697626976369764697656976669767697686976969770697716977269773697746977569776697776977869779697806978169782697836978469785697866978769788697896979069791697926979369794697956979669797697986979969800698016980269803698046980569806698076980869809698106981169812698136981469815698166981769818698196982069821698226982369824698256982669827698286982969830698316983269833698346983569836698376983869839698406984169842698436984469845698466984769848698496985069851698526985369854698556985669857698586985969860698616986269863698646986569866698676986869869698706987169872698736987469875698766987769878698796988069881698826988369884698856988669887698886988969890698916989269893698946989569896698976989869899699006990169902699036990469905699066990769908699096991069911699126991369914699156991669917699186991969920699216992269923699246992569926699276992869929699306993169932699336993469935699366993769938699396994069941699426994369944699456994669947699486994969950699516995269953699546995569956699576995869959699606996169962699636996469965699666996769968699696997069971699726997369974699756997669977699786997969980699816998269983699846998569986699876998869989699906999169992699936999469995699966999769998699997000070001700027000370004700057000670007700087000970010700117001270013700147001570016700177001870019700207002170022700237002470025700267002770028700297003070031700327003370034700357003670037700387003970040700417004270043700447004570046700477004870049700507005170052700537005470055700567005770058700597006070061700627006370064700657006670067700687006970070700717007270073700747007570076700777007870079700807008170082700837008470085700867008770088700897009070091700927009370094700957009670097700987009970100701017010270103701047010570106701077010870109701107011170112701137011470115701167011770118701197012070121701227012370124701257012670127701287012970130701317013270133701347013570136701377013870139701407014170142701437014470145701467014770148701497015070151701527015370154701557015670157701587015970160701617016270163701647016570166701677016870169701707017170172701737017470175701767017770178701797018070181701827018370184701857018670187701887018970190701917019270193701947019570196701977019870199702007020170202702037020470205702067020770208702097021070211702127021370214702157021670217702187021970220702217022270223702247022570226702277022870229702307023170232702337023470235702367023770238702397024070241702427024370244702457024670247702487024970250702517025270253702547025570256702577025870259702607026170262702637026470265702667026770268702697027070271702727027370274702757027670277702787027970280702817028270283702847028570286702877028870289702907029170292702937029470295702967029770298702997030070301703027030370304703057030670307703087030970310703117031270313703147031570316703177031870319703207032170322703237032470325703267032770328703297033070331703327033370334703357033670337703387033970340703417034270343703447034570346703477034870349703507035170352703537035470355703567035770358703597036070361703627036370364703657036670367703687036970370703717037270373703747037570376703777037870379703807038170382703837038470385703867038770388703897039070391703927039370394703957039670397703987039970400704017040270403704047040570406704077040870409704107041170412704137041470415704167041770418704197042070421704227042370424704257042670427704287042970430704317043270433704347043570436704377043870439704407044170442704437044470445704467044770448704497045070451704527045370454704557045670457704587045970460704617046270463704647046570466704677046870469704707047170472704737047470475704767047770478704797048070481704827048370484704857048670487704887048970490704917049270493704947049570496704977049870499705007050170502705037050470505705067050770508705097051070511705127051370514705157051670517705187051970520705217052270523705247052570526705277052870529705307053170532705337053470535705367053770538705397054070541705427054370544705457054670547705487054970550705517055270553705547055570556705577055870559705607056170562705637056470565705667056770568705697057070571705727057370574705757057670577705787057970580705817058270583705847058570586705877058870589705907059170592705937059470595705967059770598705997060070601706027060370604706057060670607706087060970610706117061270613706147061570616706177061870619706207062170622706237062470625706267062770628706297063070631706327063370634706357063670637706387063970640706417064270643706447064570646706477064870649706507065170652706537065470655706567065770658706597066070661706627066370664706657066670667706687066970670706717067270673706747067570676706777067870679706807068170682706837068470685706867068770688706897069070691706927069370694706957069670697706987069970700707017070270703707047070570706707077070870709707107071170712707137071470715707167071770718707197072070721707227072370724707257072670727707287072970730707317073270733707347073570736707377073870739707407074170742707437074470745707467074770748707497075070751707527075370754707557075670757707587075970760707617076270763707647076570766707677076870769707707077170772707737077470775707767077770778707797078070781707827078370784707857078670787707887078970790707917079270793707947079570796707977079870799708007080170802708037080470805708067080770808708097081070811708127081370814708157081670817708187081970820708217082270823708247082570826708277082870829708307083170832708337083470835708367083770838708397084070841708427084370844708457084670847708487084970850708517085270853708547085570856708577085870859708607086170862708637086470865708667086770868708697087070871708727087370874708757087670877708787087970880708817088270883708847088570886708877088870889708907089170892708937089470895708967089770898708997090070901709027090370904709057090670907709087090970910709117091270913709147091570916709177091870919709207092170922709237092470925709267092770928709297093070931709327093370934709357093670937709387093970940709417094270943709447094570946709477094870949709507095170952709537095470955709567095770958709597096070961709627096370964709657096670967709687096970970709717097270973709747097570976709777097870979709807098170982709837098470985709867098770988709897099070991709927099370994709957099670997709987099971000710017100271003710047100571006710077100871009710107101171012710137101471015710167101771018710197102071021710227102371024710257102671027710287102971030710317103271033710347103571036710377103871039710407104171042710437104471045710467104771048710497105071051710527105371054710557105671057710587105971060710617106271063710647106571066710677106871069710707107171072710737107471075710767107771078710797108071081710827108371084710857108671087710887108971090710917109271093710947109571096710977109871099711007110171102711037110471105711067110771108711097111071111711127111371114711157111671117711187111971120711217112271123711247112571126711277112871129711307113171132711337113471135711367113771138711397114071141711427114371144711457114671147711487114971150711517115271153711547115571156711577115871159711607116171162711637116471165711667116771168711697117071171711727117371174711757117671177711787117971180711817118271183711847118571186711877118871189711907119171192711937119471195711967119771198711997120071201712027120371204712057120671207712087120971210712117121271213712147121571216712177121871219712207122171222712237122471225712267122771228712297123071231712327123371234712357123671237712387123971240712417124271243712447124571246712477124871249712507125171252712537125471255712567125771258712597126071261712627126371264712657126671267712687126971270712717127271273712747127571276712777127871279712807128171282712837128471285712867128771288712897129071291712927129371294712957129671297712987129971300713017130271303713047130571306713077130871309713107131171312713137131471315713167131771318713197132071321713227132371324713257132671327713287132971330713317133271333713347133571336713377133871339713407134171342713437134471345713467134771348713497135071351713527135371354713557135671357713587135971360713617136271363713647136571366713677136871369713707137171372713737137471375713767137771378713797138071381713827138371384713857138671387713887138971390713917139271393713947139571396713977139871399714007140171402714037140471405714067140771408714097141071411714127141371414714157141671417714187141971420714217142271423714247142571426714277142871429714307143171432714337143471435714367143771438714397144071441714427144371444714457144671447714487144971450714517145271453714547145571456714577145871459714607146171462714637146471465714667146771468714697147071471714727147371474714757147671477714787147971480714817148271483714847148571486714877148871489714907149171492714937149471495714967149771498714997150071501715027150371504715057150671507715087150971510715117151271513715147151571516715177151871519715207152171522715237152471525715267152771528715297153071531715327153371534715357153671537715387153971540715417154271543715447154571546715477154871549715507155171552715537155471555715567155771558715597156071561715627156371564715657156671567715687156971570715717157271573715747157571576715777157871579715807158171582715837158471585715867158771588715897159071591715927159371594715957159671597715987159971600716017160271603716047160571606716077160871609716107161171612716137161471615716167161771618716197162071621716227162371624716257162671627716287162971630716317163271633716347163571636716377163871639716407164171642716437164471645716467164771648716497165071651716527165371654716557165671657716587165971660716617166271663716647166571666716677166871669716707167171672716737167471675716767167771678716797168071681716827168371684716857168671687716887168971690716917169271693716947169571696716977169871699717007170171702717037170471705717067170771708717097171071711717127171371714717157171671717717187171971720717217172271723717247172571726717277172871729717307173171732717337173471735717367173771738717397174071741717427174371744717457174671747717487174971750717517175271753717547175571756717577175871759717607176171762717637176471765717667176771768717697177071771717727177371774717757177671777717787177971780717817178271783717847178571786717877178871789717907179171792717937179471795717967179771798717997180071801718027180371804718057180671807718087180971810718117181271813718147181571816718177181871819718207182171822718237182471825718267182771828718297183071831718327183371834718357183671837718387183971840718417184271843718447184571846718477184871849718507185171852718537185471855718567185771858718597186071861718627186371864718657186671867718687186971870718717187271873718747187571876718777187871879718807188171882718837188471885718867188771888718897189071891718927189371894718957189671897718987189971900719017190271903719047190571906719077190871909719107191171912719137191471915719167191771918719197192071921719227192371924719257192671927719287192971930719317193271933719347193571936719377193871939719407194171942719437194471945719467194771948719497195071951719527195371954719557195671957719587195971960719617196271963719647196571966719677196871969719707197171972719737197471975719767197771978719797198071981719827198371984719857198671987719887198971990719917199271993719947199571996719977199871999720007200172002720037200472005720067200772008720097201072011720127201372014720157201672017720187201972020720217202272023720247202572026720277202872029720307203172032720337203472035720367203772038720397204072041720427204372044720457204672047720487204972050720517205272053720547205572056720577205872059720607206172062720637206472065720667206772068720697207072071720727207372074720757207672077720787207972080720817208272083720847208572086720877208872089720907209172092720937209472095720967209772098720997210072101721027210372104721057210672107721087210972110721117211272113721147211572116721177211872119721207212172122721237212472125721267212772128721297213072131721327213372134721357213672137721387213972140721417214272143721447214572146721477214872149721507215172152721537215472155721567215772158721597216072161721627216372164721657216672167721687216972170721717217272173721747217572176721777217872179721807218172182721837218472185721867218772188721897219072191721927219372194721957219672197721987219972200722017220272203722047220572206722077220872209722107221172212722137221472215722167221772218722197222072221722227222372224722257222672227722287222972230722317223272233722347223572236722377223872239722407224172242722437224472245722467224772248722497225072251722527225372254722557225672257722587225972260722617226272263722647226572266722677226872269722707227172272722737227472275722767227772278722797228072281722827228372284722857228672287722887228972290722917229272293722947229572296722977229872299723007230172302723037230472305723067230772308723097231072311723127231372314723157231672317723187231972320723217232272323723247232572326723277232872329723307233172332723337233472335723367233772338723397234072341723427234372344723457234672347723487234972350723517235272353723547235572356723577235872359723607236172362723637236472365723667236772368723697237072371723727237372374723757237672377723787237972380723817238272383723847238572386723877238872389723907239172392723937239472395723967239772398723997240072401724027240372404724057240672407724087240972410724117241272413724147241572416724177241872419724207242172422724237242472425724267242772428724297243072431724327243372434724357243672437724387243972440724417244272443724447244572446724477244872449724507245172452724537245472455724567245772458724597246072461724627246372464724657246672467724687246972470724717247272473724747247572476724777247872479724807248172482724837248472485724867248772488724897249072491724927249372494724957249672497724987249972500725017250272503725047250572506725077250872509725107251172512725137251472515725167251772518725197252072521725227252372524725257252672527725287252972530725317253272533725347253572536725377253872539725407254172542725437254472545725467254772548725497255072551725527255372554725557255672557725587255972560725617256272563725647256572566725677256872569725707257172572725737257472575725767257772578725797258072581725827258372584725857258672587725887258972590725917259272593725947259572596725977259872599726007260172602726037260472605726067260772608726097261072611726127261372614726157261672617726187261972620726217262272623726247262572626726277262872629726307263172632726337263472635726367263772638726397264072641726427264372644726457264672647726487264972650726517265272653726547265572656726577265872659726607266172662726637266472665726667266772668726697267072671726727267372674726757267672677726787267972680726817268272683726847268572686726877268872689726907269172692726937269472695726967269772698726997270072701727027270372704727057270672707727087270972710727117271272713727147271572716727177271872719727207272172722727237272472725727267272772728727297273072731727327273372734727357273672737727387273972740727417274272743727447274572746727477274872749727507275172752727537275472755727567275772758727597276072761727627276372764727657276672767727687276972770727717277272773727747277572776727777277872779727807278172782727837278472785727867278772788727897279072791727927279372794727957279672797727987279972800728017280272803728047280572806728077280872809728107281172812728137281472815728167281772818728197282072821728227282372824728257282672827728287282972830728317283272833728347283572836728377283872839728407284172842728437284472845728467284772848728497285072851728527285372854728557285672857728587285972860728617286272863728647286572866728677286872869728707287172872728737287472875728767287772878728797288072881728827288372884728857288672887728887288972890728917289272893728947289572896728977289872899729007290172902729037290472905729067290772908729097291072911729127291372914729157291672917729187291972920729217292272923729247292572926729277292872929729307293172932729337293472935729367293772938729397294072941729427294372944729457294672947729487294972950729517295272953729547295572956729577295872959729607296172962729637296472965729667296772968729697297072971729727297372974729757297672977729787297972980729817298272983729847298572986729877298872989729907299172992729937299472995729967299772998729997300073001730027300373004730057300673007730087300973010730117301273013730147301573016730177301873019730207302173022730237302473025730267302773028730297303073031730327303373034730357303673037730387303973040730417304273043730447304573046730477304873049730507305173052730537305473055730567305773058730597306073061730627306373064730657306673067730687306973070730717307273073730747307573076730777307873079730807308173082730837308473085730867308773088730897309073091730927309373094730957309673097730987309973100731017310273103731047310573106731077310873109731107311173112731137311473115731167311773118731197312073121731227312373124731257312673127731287312973130731317313273133731347313573136731377313873139731407314173142731437314473145731467314773148731497315073151731527315373154731557315673157731587315973160731617316273163731647316573166731677316873169731707317173172731737317473175731767317773178731797318073181731827318373184731857318673187731887318973190731917319273193731947319573196731977319873199732007320173202732037320473205732067320773208732097321073211732127321373214732157321673217732187321973220732217322273223732247322573226732277322873229732307323173232732337323473235732367323773238732397324073241732427324373244732457324673247732487324973250732517325273253732547325573256732577325873259732607326173262732637326473265732667326773268732697327073271732727327373274732757327673277732787327973280732817328273283732847328573286732877328873289732907329173292732937329473295732967329773298732997330073301733027330373304733057330673307733087330973310733117331273313733147331573316733177331873319733207332173322733237332473325733267332773328733297333073331733327333373334733357333673337733387333973340733417334273343733447334573346733477334873349733507335173352733537335473355733567335773358733597336073361733627336373364733657336673367733687336973370733717337273373733747337573376733777337873379733807338173382733837338473385733867338773388733897339073391733927339373394733957339673397733987339973400734017340273403734047340573406734077340873409734107341173412734137341473415734167341773418734197342073421734227342373424734257342673427734287342973430734317343273433734347343573436734377343873439734407344173442734437344473445734467344773448734497345073451734527345373454734557345673457734587345973460734617346273463734647346573466734677346873469734707347173472734737347473475734767347773478734797348073481734827348373484734857348673487734887348973490734917349273493734947349573496734977349873499735007350173502735037350473505735067350773508735097351073511735127351373514735157351673517735187351973520735217352273523735247352573526735277352873529735307353173532735337353473535735367353773538735397354073541735427354373544735457354673547735487354973550735517355273553735547355573556735577355873559735607356173562735637356473565735667356773568735697357073571735727357373574735757357673577735787357973580735817358273583735847358573586735877358873589735907359173592735937359473595735967359773598735997360073601736027360373604736057360673607736087360973610736117361273613736147361573616736177361873619736207362173622736237362473625736267362773628736297363073631736327363373634736357363673637736387363973640736417364273643736447364573646736477364873649736507365173652736537365473655736567365773658736597366073661736627366373664736657366673667736687366973670736717367273673736747367573676736777367873679736807368173682736837368473685736867368773688736897369073691736927369373694736957369673697736987369973700737017370273703737047370573706737077370873709737107371173712737137371473715737167371773718737197372073721737227372373724737257372673727737287372973730737317373273733737347373573736737377373873739737407374173742737437374473745737467374773748737497375073751737527375373754737557375673757737587375973760737617376273763737647376573766737677376873769737707377173772737737377473775737767377773778737797378073781737827378373784737857378673787737887378973790737917379273793737947379573796737977379873799738007380173802738037380473805738067380773808738097381073811738127381373814738157381673817738187381973820738217382273823738247382573826738277382873829738307383173832738337383473835738367383773838738397384073841738427384373844738457384673847738487384973850738517385273853738547385573856738577385873859738607386173862738637386473865738667386773868738697387073871738727387373874738757387673877738787387973880738817388273883738847388573886738877388873889738907389173892738937389473895738967389773898738997390073901739027390373904739057390673907739087390973910739117391273913739147391573916739177391873919739207392173922739237392473925739267392773928739297393073931739327393373934739357393673937739387393973940739417394273943739447394573946739477394873949739507395173952739537395473955739567395773958739597396073961739627396373964739657396673967739687396973970739717397273973739747397573976739777397873979739807398173982739837398473985739867398773988739897399073991739927399373994739957399673997739987399974000740017400274003740047400574006740077400874009740107401174012740137401474015740167401774018740197402074021740227402374024740257402674027740287402974030740317403274033740347403574036740377403874039740407404174042740437404474045740467404774048740497405074051740527405374054740557405674057740587405974060740617406274063740647406574066740677406874069740707407174072740737407474075740767407774078740797408074081740827408374084740857408674087740887408974090740917409274093740947409574096740977409874099741007410174102741037410474105741067410774108741097411074111741127411374114741157411674117741187411974120741217412274123741247412574126741277412874129741307413174132741337413474135741367413774138741397414074141741427414374144741457414674147741487414974150741517415274153741547415574156741577415874159741607416174162741637416474165741667416774168741697417074171741727417374174741757417674177741787417974180741817418274183741847418574186741877418874189741907419174192741937419474195741967419774198741997420074201742027420374204742057420674207742087420974210742117421274213742147421574216742177421874219742207422174222742237422474225742267422774228742297423074231742327423374234742357423674237742387423974240742417424274243742447424574246742477424874249742507425174252742537425474255742567425774258742597426074261742627426374264742657426674267742687426974270742717427274273742747427574276742777427874279742807428174282742837428474285742867428774288742897429074291742927429374294742957429674297742987429974300743017430274303743047430574306743077430874309743107431174312743137431474315743167431774318743197432074321743227432374324743257432674327743287432974330743317433274333743347433574336743377433874339743407434174342743437434474345743467434774348743497435074351743527435374354743557435674357743587435974360743617436274363743647436574366743677436874369743707437174372743737437474375743767437774378743797438074381743827438374384743857438674387743887438974390743917439274393743947439574396743977439874399744007440174402744037440474405744067440774408744097441074411744127441374414744157441674417744187441974420744217442274423744247442574426744277442874429744307443174432744337443474435744367443774438744397444074441744427444374444744457444674447744487444974450744517445274453744547445574456744577445874459744607446174462744637446474465744667446774468744697447074471744727447374474744757447674477744787447974480744817448274483744847448574486744877448874489744907449174492744937449474495744967449774498744997450074501745027450374504745057450674507745087450974510745117451274513745147451574516745177451874519745207452174522745237452474525745267452774528745297453074531745327453374534745357453674537745387453974540745417454274543745447454574546745477454874549745507455174552745537455474555745567455774558745597456074561745627456374564745657456674567745687456974570745717457274573745747457574576745777457874579745807458174582745837458474585745867458774588745897459074591745927459374594745957459674597745987459974600746017460274603746047460574606746077460874609746107461174612746137461474615746167461774618746197462074621746227462374624746257462674627746287462974630746317463274633746347463574636746377463874639746407464174642746437464474645746467464774648746497465074651746527465374654746557465674657746587465974660746617466274663746647466574666746677466874669746707467174672746737467474675746767467774678746797468074681746827468374684746857468674687746887468974690746917469274693746947469574696746977469874699747007470174702747037470474705747067470774708747097471074711747127471374714747157471674717747187471974720747217472274723747247472574726747277472874729747307473174732747337473474735747367473774738747397474074741747427474374744747457474674747747487474974750747517475274753747547475574756747577475874759747607476174762747637476474765747667476774768747697477074771747727477374774747757477674777747787477974780747817478274783747847478574786747877478874789747907479174792747937479474795747967479774798747997480074801748027480374804748057480674807748087480974810748117481274813748147481574816748177481874819748207482174822748237482474825748267482774828748297483074831748327483374834748357483674837748387483974840748417484274843748447484574846748477484874849748507485174852748537485474855748567485774858748597486074861748627486374864748657486674867748687486974870748717487274873748747487574876748777487874879748807488174882748837488474885748867488774888748897489074891748927489374894748957489674897748987489974900749017490274903749047490574906749077490874909749107491174912749137491474915749167491774918749197492074921749227492374924749257492674927749287492974930749317493274933749347493574936749377493874939749407494174942749437494474945749467494774948749497495074951749527495374954749557495674957749587495974960749617496274963749647496574966749677496874969749707497174972749737497474975749767497774978749797498074981749827498374984749857498674987749887498974990749917499274993749947499574996749977499874999750007500175002750037500475005750067500775008750097501075011750127501375014750157501675017750187501975020750217502275023750247502575026750277502875029750307503175032750337503475035750367503775038750397504075041750427504375044750457504675047750487504975050750517505275053750547505575056750577505875059750607506175062750637506475065750667506775068750697507075071750727507375074750757507675077750787507975080750817508275083750847508575086750877508875089750907509175092750937509475095750967509775098750997510075101751027510375104751057510675107751087510975110751117511275113751147511575116751177511875119751207512175122751237512475125751267512775128751297513075131751327513375134751357513675137751387513975140751417514275143751447514575146751477514875149751507515175152751537515475155751567515775158751597516075161751627516375164751657516675167751687516975170751717517275173751747517575176751777517875179751807518175182751837518475185751867518775188751897519075191751927519375194751957519675197751987519975200752017520275203752047520575206752077520875209752107521175212752137521475215752167521775218752197522075221752227522375224752257522675227752287522975230752317523275233752347523575236752377523875239752407524175242752437524475245752467524775248752497525075251752527525375254752557525675257752587525975260752617526275263752647526575266752677526875269752707527175272752737527475275752767527775278752797528075281752827528375284752857528675287752887528975290752917529275293752947529575296752977529875299753007530175302753037530475305753067530775308753097531075311753127531375314753157531675317753187531975320753217532275323753247532575326753277532875329753307533175332753337533475335753367533775338753397534075341753427534375344753457534675347753487534975350753517535275353753547535575356753577535875359753607536175362753637536475365753667536775368753697537075371753727537375374753757537675377753787537975380753817538275383753847538575386753877538875389753907539175392753937539475395753967539775398753997540075401754027540375404754057540675407754087540975410754117541275413754147541575416754177541875419754207542175422754237542475425754267542775428754297543075431754327543375434754357543675437754387543975440754417544275443754447544575446754477544875449754507545175452754537545475455754567545775458754597546075461754627546375464754657546675467754687546975470754717547275473754747547575476754777547875479754807548175482754837548475485754867548775488754897549075491754927549375494754957549675497754987549975500755017550275503755047550575506755077550875509755107551175512755137551475515755167551775518755197552075521755227552375524755257552675527755287552975530755317553275533755347553575536755377553875539755407554175542755437554475545755467554775548755497555075551755527555375554755557555675557755587555975560755617556275563755647556575566755677556875569755707557175572755737557475575755767557775578755797558075581755827558375584755857558675587755887558975590755917559275593755947559575596755977559875599756007560175602756037560475605756067560775608756097561075611756127561375614756157561675617756187561975620756217562275623756247562575626756277562875629756307563175632756337563475635756367563775638756397564075641756427564375644756457564675647756487564975650756517565275653756547565575656756577565875659756607566175662756637566475665756667566775668756697567075671756727567375674756757567675677756787567975680756817568275683756847568575686756877568875689756907569175692756937569475695756967569775698756997570075701757027570375704757057570675707757087570975710757117571275713757147571575716757177571875719757207572175722757237572475725757267572775728757297573075731757327573375734757357573675737757387573975740757417574275743757447574575746757477574875749757507575175752757537575475755757567575775758757597576075761757627576375764757657576675767757687576975770757717577275773757747577575776757777577875779757807578175782757837578475785757867578775788757897579075791757927579375794757957579675797757987579975800758017580275803758047580575806758077580875809758107581175812758137581475815758167581775818758197582075821758227582375824758257582675827758287582975830758317583275833758347583575836758377583875839758407584175842758437584475845758467584775848758497585075851758527585375854758557585675857758587585975860758617586275863758647586575866758677586875869758707587175872758737587475875758767587775878758797588075881758827588375884758857588675887758887588975890758917589275893758947589575896758977589875899759007590175902759037590475905759067590775908759097591075911759127591375914759157591675917759187591975920759217592275923759247592575926759277592875929759307593175932759337593475935759367593775938759397594075941759427594375944759457594675947759487594975950759517595275953759547595575956759577595875959759607596175962759637596475965759667596775968759697597075971759727597375974759757597675977759787597975980759817598275983759847598575986759877598875989759907599175992759937599475995759967599775998759997600076001760027600376004760057600676007760087600976010760117601276013760147601576016760177601876019760207602176022760237602476025760267602776028760297603076031760327603376034760357603676037760387603976040760417604276043760447604576046760477604876049760507605176052760537605476055760567605776058760597606076061760627606376064760657606676067760687606976070760717607276073760747607576076760777607876079760807608176082760837608476085760867608776088760897609076091760927609376094760957609676097760987609976100761017610276103761047610576106761077610876109761107611176112761137611476115761167611776118761197612076121761227612376124761257612676127761287612976130761317613276133761347613576136761377613876139761407614176142761437614476145761467614776148761497615076151761527615376154761557615676157761587615976160761617616276163761647616576166761677616876169761707617176172761737617476175761767617776178761797618076181761827618376184761857618676187761887618976190761917619276193761947619576196761977619876199762007620176202762037620476205762067620776208762097621076211762127621376214762157621676217762187621976220762217622276223762247622576226762277622876229762307623176232762337623476235762367623776238762397624076241762427624376244762457624676247762487624976250762517625276253762547625576256762577625876259762607626176262762637626476265762667626776268762697627076271762727627376274762757627676277762787627976280762817628276283762847628576286762877628876289762907629176292762937629476295762967629776298762997630076301763027630376304763057630676307763087630976310763117631276313763147631576316763177631876319763207632176322763237632476325763267632776328763297633076331763327633376334763357633676337763387633976340763417634276343763447634576346763477634876349763507635176352763537635476355763567635776358763597636076361763627636376364763657636676367763687636976370763717637276373763747637576376763777637876379763807638176382763837638476385763867638776388763897639076391763927639376394763957639676397763987639976400764017640276403764047640576406764077640876409764107641176412764137641476415764167641776418764197642076421764227642376424764257642676427764287642976430764317643276433764347643576436764377643876439764407644176442764437644476445764467644776448764497645076451764527645376454764557645676457764587645976460764617646276463764647646576466764677646876469764707647176472764737647476475764767647776478764797648076481764827648376484764857648676487764887648976490764917649276493764947649576496764977649876499765007650176502765037650476505765067650776508765097651076511765127651376514765157651676517765187651976520765217652276523765247652576526765277652876529765307653176532765337653476535765367653776538765397654076541765427654376544765457654676547765487654976550765517655276553765547655576556765577655876559765607656176562765637656476565765667656776568765697657076571765727657376574765757657676577765787657976580765817658276583765847658576586765877658876589765907659176592765937659476595765967659776598765997660076601766027660376604766057660676607766087660976610766117661276613766147661576616766177661876619766207662176622766237662476625766267662776628766297663076631766327663376634766357663676637766387663976640766417664276643766447664576646766477664876649766507665176652766537665476655766567665776658766597666076661766627666376664766657666676667766687666976670766717667276673766747667576676766777667876679766807668176682766837668476685766867668776688766897669076691766927669376694766957669676697766987669976700767017670276703767047670576706767077670876709767107671176712767137671476715767167671776718767197672076721767227672376724767257672676727767287672976730767317673276733767347673576736767377673876739767407674176742767437674476745767467674776748767497675076751767527675376754767557675676757767587675976760767617676276763767647676576766767677676876769767707677176772767737677476775767767677776778767797678076781767827678376784767857678676787767887678976790767917679276793767947679576796767977679876799768007680176802768037680476805768067680776808768097681076811768127681376814768157681676817768187681976820768217682276823768247682576826768277682876829768307683176832768337683476835768367683776838768397684076841768427684376844768457684676847768487684976850768517685276853768547685576856768577685876859768607686176862768637686476865768667686776868768697687076871768727687376874768757687676877768787687976880768817688276883768847688576886768877688876889768907689176892768937689476895768967689776898768997690076901769027690376904769057690676907769087690976910769117691276913769147691576916769177691876919769207692176922769237692476925769267692776928769297693076931769327693376934769357693676937769387693976940769417694276943769447694576946769477694876949769507695176952769537695476955769567695776958769597696076961769627696376964769657696676967769687696976970769717697276973769747697576976769777697876979769807698176982769837698476985769867698776988769897699076991769927699376994769957699676997769987699977000770017700277003770047700577006770077700877009770107701177012770137701477015770167701777018770197702077021770227702377024770257702677027770287702977030770317703277033770347703577036770377703877039770407704177042770437704477045770467704777048770497705077051770527705377054770557705677057770587705977060770617706277063770647706577066770677706877069770707707177072770737707477075770767707777078770797708077081770827708377084770857708677087770887708977090770917709277093770947709577096770977709877099771007710177102771037710477105771067710777108771097711077111771127711377114771157711677117771187711977120771217712277123771247712577126771277712877129771307713177132771337713477135771367713777138771397714077141771427714377144771457714677147771487714977150771517715277153771547715577156771577715877159771607716177162771637716477165771667716777168771697717077171771727717377174771757717677177771787717977180771817718277183771847718577186771877718877189771907719177192771937719477195771967719777198771997720077201772027720377204772057720677207772087720977210772117721277213772147721577216772177721877219772207722177222772237722477225772267722777228772297723077231772327723377234772357723677237772387723977240772417724277243772447724577246772477724877249772507725177252772537725477255772567725777258772597726077261772627726377264772657726677267772687726977270772717727277273772747727577276772777727877279772807728177282772837728477285772867728777288772897729077291772927729377294772957729677297772987729977300773017730277303773047730577306773077730877309773107731177312773137731477315773167731777318773197732077321773227732377324773257732677327773287732977330773317733277333773347733577336773377733877339773407734177342773437734477345773467734777348773497735077351773527735377354773557735677357773587735977360773617736277363773647736577366773677736877369773707737177372773737737477375773767737777378773797738077381773827738377384773857738677387773887738977390773917739277393773947739577396773977739877399774007740177402774037740477405774067740777408774097741077411774127741377414774157741677417774187741977420774217742277423774247742577426774277742877429774307743177432774337743477435774367743777438774397744077441774427744377444774457744677447774487744977450774517745277453774547745577456774577745877459774607746177462774637746477465774667746777468774697747077471774727747377474774757747677477774787747977480774817748277483774847748577486774877748877489774907749177492774937749477495774967749777498774997750077501775027750377504775057750677507775087750977510775117751277513775147751577516775177751877519775207752177522775237752477525775267752777528775297753077531775327753377534775357753677537775387753977540775417754277543775447754577546775477754877549775507755177552775537755477555775567755777558775597756077561775627756377564775657756677567775687756977570775717757277573775747757577576775777757877579775807758177582775837758477585775867758777588775897759077591775927759377594775957759677597775987759977600776017760277603776047760577606776077760877609776107761177612776137761477615776167761777618776197762077621776227762377624776257762677627776287762977630776317763277633776347763577636776377763877639776407764177642776437764477645776467764777648776497765077651776527765377654776557765677657776587765977660776617766277663776647766577666776677766877669776707767177672776737767477675776767767777678776797768077681776827768377684776857768677687776887768977690776917769277693776947769577696776977769877699777007770177702777037770477705777067770777708777097771077711777127771377714777157771677717777187771977720777217772277723777247772577726777277772877729777307773177732777337773477735777367773777738777397774077741777427774377744777457774677747777487774977750777517775277753777547775577756777577775877759777607776177762777637776477765777667776777768777697777077771777727777377774777757777677777777787777977780777817778277783777847778577786777877778877789777907779177792777937779477795777967779777798777997780077801778027780377804778057780677807778087780977810778117781277813778147781577816778177781877819778207782177822778237782477825778267782777828778297783077831778327783377834778357783677837778387783977840778417784277843778447784577846778477784877849778507785177852778537785477855778567785777858778597786077861778627786377864778657786677867778687786977870778717787277873778747787577876778777787877879778807788177882778837788477885778867788777888778897789077891778927789377894778957789677897778987789977900779017790277903779047790577906779077790877909779107791177912779137791477915779167791777918779197792077921779227792377924779257792677927779287792977930779317793277933779347793577936779377793877939779407794177942779437794477945779467794777948779497795077951779527795377954779557795677957779587795977960779617796277963779647796577966779677796877969779707797177972779737797477975779767797777978779797798077981779827798377984779857798677987779887798977990779917799277993779947799577996779977799877999780007800178002780037800478005780067800778008780097801078011780127801378014780157801678017780187801978020780217802278023780247802578026780277802878029780307803178032780337803478035780367803778038780397804078041780427804378044780457804678047780487804978050780517805278053780547805578056780577805878059780607806178062780637806478065780667806778068780697807078071780727807378074780757807678077780787807978080780817808278083780847808578086780877808878089780907809178092780937809478095780967809778098780997810078101781027810378104781057810678107781087810978110781117811278113781147811578116781177811878119781207812178122781237812478125781267812778128781297813078131781327813378134781357813678137781387813978140781417814278143781447814578146781477814878149781507815178152781537815478155781567815778158781597816078161781627816378164781657816678167781687816978170781717817278173781747817578176781777817878179781807818178182781837818478185781867818778188781897819078191781927819378194781957819678197781987819978200782017820278203782047820578206782077820878209782107821178212782137821478215782167821778218782197822078221782227822378224782257822678227782287822978230782317823278233782347823578236782377823878239782407824178242782437824478245782467824778248782497825078251782527825378254782557825678257782587825978260782617826278263782647826578266782677826878269782707827178272782737827478275782767827778278782797828078281782827828378284782857828678287782887828978290782917829278293782947829578296782977829878299783007830178302783037830478305783067830778308783097831078311783127831378314783157831678317783187831978320783217832278323783247832578326783277832878329783307833178332783337833478335783367833778338783397834078341783427834378344783457834678347783487834978350783517835278353783547835578356783577835878359783607836178362783637836478365783667836778368783697837078371783727837378374783757837678377783787837978380783817838278383783847838578386783877838878389783907839178392783937839478395783967839778398783997840078401784027840378404784057840678407784087840978410784117841278413784147841578416784177841878419784207842178422784237842478425784267842778428784297843078431784327843378434784357843678437784387843978440784417844278443784447844578446784477844878449784507845178452784537845478455784567845778458784597846078461784627846378464784657846678467784687846978470784717847278473784747847578476784777847878479784807848178482784837848478485784867848778488784897849078491784927849378494784957849678497784987849978500785017850278503785047850578506785077850878509785107851178512785137851478515785167851778518785197852078521785227852378524785257852678527785287852978530785317853278533785347853578536785377853878539785407854178542785437854478545785467854778548785497855078551785527855378554785557855678557785587855978560785617856278563785647856578566785677856878569785707857178572785737857478575785767857778578785797858078581785827858378584785857858678587785887858978590785917859278593785947859578596785977859878599786007860178602786037860478605786067860778608786097861078611786127861378614786157861678617786187861978620786217862278623786247862578626786277862878629786307863178632786337863478635786367863778638786397864078641786427864378644786457864678647786487864978650786517865278653786547865578656786577865878659786607866178662786637866478665786667866778668786697867078671786727867378674786757867678677786787867978680786817868278683786847868578686786877868878689786907869178692786937869478695786967869778698786997870078701787027870378704787057870678707787087870978710787117871278713787147871578716787177871878719787207872178722787237872478725787267872778728787297873078731787327873378734787357873678737787387873978740787417874278743787447874578746787477874878749787507875178752787537875478755787567875778758787597876078761787627876378764787657876678767787687876978770787717877278773787747877578776787777877878779787807878178782787837878478785787867878778788787897879078791787927879378794787957879678797787987879978800788017880278803788047880578806788077880878809788107881178812788137881478815788167881778818788197882078821788227882378824788257882678827788287882978830788317883278833788347883578836788377883878839788407884178842788437884478845788467884778848788497885078851788527885378854788557885678857788587885978860788617886278863788647886578866788677886878869788707887178872788737887478875788767887778878788797888078881788827888378884788857888678887788887888978890788917889278893788947889578896788977889878899789007890178902789037890478905789067890778908789097891078911789127891378914789157891678917789187891978920789217892278923789247892578926789277892878929789307893178932789337893478935789367893778938789397894078941789427894378944789457894678947789487894978950789517895278953789547895578956789577895878959789607896178962789637896478965789667896778968789697897078971789727897378974789757897678977789787897978980789817898278983789847898578986789877898878989789907899178992789937899478995789967899778998789997900079001790027900379004790057900679007790087900979010790117901279013790147901579016790177901879019790207902179022790237902479025790267902779028790297903079031790327903379034790357903679037790387903979040790417904279043790447904579046790477904879049790507905179052790537905479055790567905779058790597906079061790627906379064790657906679067790687906979070790717907279073790747907579076790777907879079790807908179082790837908479085790867908779088790897909079091790927909379094790957909679097790987909979100791017910279103791047910579106791077910879109791107911179112791137911479115791167911779118791197912079121791227912379124791257912679127791287912979130791317913279133791347913579136791377913879139791407914179142791437914479145791467914779148791497915079151791527915379154791557915679157791587915979160791617916279163791647916579166791677916879169791707917179172791737917479175791767917779178791797918079181791827918379184791857918679187791887918979190791917919279193791947919579196791977919879199792007920179202792037920479205792067920779208792097921079211792127921379214792157921679217792187921979220792217922279223792247922579226792277922879229792307923179232792337923479235792367923779238792397924079241792427924379244792457924679247792487924979250792517925279253792547925579256792577925879259792607926179262792637926479265792667926779268792697927079271792727927379274792757927679277792787927979280792817928279283792847928579286792877928879289792907929179292792937929479295792967929779298792997930079301793027930379304793057930679307793087930979310793117931279313793147931579316793177931879319793207932179322793237932479325793267932779328793297933079331793327933379334793357933679337793387933979340793417934279343793447934579346793477934879349793507935179352793537935479355793567935779358793597936079361793627936379364793657936679367793687936979370793717937279373793747937579376793777937879379793807938179382793837938479385793867938779388793897939079391793927939379394793957939679397793987939979400794017940279403794047940579406794077940879409794107941179412794137941479415794167941779418794197942079421794227942379424794257942679427794287942979430794317943279433794347943579436794377943879439794407944179442794437944479445794467944779448794497945079451794527945379454794557945679457794587945979460794617946279463794647946579466794677946879469794707947179472794737947479475794767947779478794797948079481794827948379484794857948679487794887948979490794917949279493794947949579496794977949879499795007950179502795037950479505795067950779508795097951079511795127951379514795157951679517795187951979520795217952279523795247952579526795277952879529795307953179532795337953479535795367953779538795397954079541795427954379544795457954679547795487954979550795517955279553795547955579556795577955879559795607956179562795637956479565795667956779568795697957079571795727957379574795757957679577795787957979580795817958279583795847958579586795877958879589795907959179592795937959479595795967959779598795997960079601796027960379604796057960679607796087960979610796117961279613796147961579616796177961879619796207962179622796237962479625796267962779628796297963079631796327963379634796357963679637796387963979640796417964279643796447964579646796477964879649796507965179652796537965479655796567965779658796597966079661796627966379664796657966679667796687966979670796717967279673796747967579676796777967879679796807968179682796837968479685796867968779688796897969079691796927969379694796957969679697796987969979700797017970279703797047970579706797077970879709797107971179712797137971479715797167971779718797197972079721797227972379724797257972679727797287972979730797317973279733797347973579736797377973879739797407974179742797437974479745797467974779748797497975079751797527975379754797557975679757797587975979760797617976279763797647976579766797677976879769797707977179772797737977479775797767977779778797797978079781797827978379784797857978679787797887978979790797917979279793797947979579796797977979879799798007980179802798037980479805798067980779808798097981079811798127981379814798157981679817798187981979820798217982279823798247982579826798277982879829798307983179832798337983479835798367983779838798397984079841798427984379844798457984679847798487984979850798517985279853798547985579856798577985879859798607986179862798637986479865798667986779868798697987079871798727987379874798757987679877798787987979880798817988279883798847988579886798877988879889798907989179892798937989479895798967989779898798997990079901799027990379904799057990679907799087990979910799117991279913799147991579916799177991879919799207992179922799237992479925799267992779928799297993079931799327993379934799357993679937799387993979940799417994279943799447994579946799477994879949799507995179952799537995479955799567995779958799597996079961799627996379964799657996679967799687996979970799717997279973799747997579976799777997879979799807998179982799837998479985799867998779988799897999079991799927999379994799957999679997799987999980000800018000280003800048000580006800078000880009800108001180012800138001480015800168001780018800198002080021800228002380024800258002680027800288002980030800318003280033800348003580036800378003880039800408004180042800438004480045800468004780048800498005080051800528005380054800558005680057800588005980060800618006280063800648006580066800678006880069800708007180072800738007480075800768007780078800798008080081800828008380084800858008680087800888008980090800918009280093800948009580096800978009880099801008010180102801038010480105801068010780108801098011080111801128011380114801158011680117801188011980120801218012280123801248012580126801278012880129801308013180132801338013480135801368013780138801398014080141801428014380144801458014680147801488014980150801518015280153801548015580156801578015880159801608016180162801638016480165801668016780168801698017080171801728017380174801758017680177801788017980180801818018280183801848018580186801878018880189801908019180192801938019480195801968019780198801998020080201802028020380204802058020680207802088020980210802118021280213802148021580216802178021880219802208022180222802238022480225802268022780228802298023080231802328023380234802358023680237802388023980240802418024280243802448024580246802478024880249802508025180252802538025480255802568025780258802598026080261802628026380264802658026680267802688026980270802718027280273802748027580276802778027880279802808028180282802838028480285802868028780288802898029080291802928029380294802958029680297802988029980300803018030280303803048030580306803078030880309803108031180312803138031480315803168031780318803198032080321803228032380324803258032680327803288032980330803318033280333803348033580336803378033880339803408034180342803438034480345803468034780348803498035080351803528035380354803558035680357803588035980360803618036280363803648036580366803678036880369803708037180372803738037480375803768037780378803798038080381803828038380384803858038680387803888038980390803918039280393803948039580396803978039880399804008040180402804038040480405804068040780408804098041080411804128041380414804158041680417804188041980420804218042280423804248042580426804278042880429804308043180432804338043480435804368043780438804398044080441804428044380444804458044680447804488044980450804518045280453804548045580456804578045880459804608046180462804638046480465804668046780468804698047080471804728047380474804758047680477804788047980480804818048280483804848048580486804878048880489804908049180492804938049480495804968049780498804998050080501805028050380504805058050680507805088050980510805118051280513805148051580516805178051880519805208052180522805238052480525805268052780528805298053080531805328053380534805358053680537805388053980540805418054280543805448054580546805478054880549805508055180552805538055480555805568055780558805598056080561805628056380564805658056680567805688056980570805718057280573805748057580576805778057880579805808058180582805838058480585805868058780588805898059080591805928059380594805958059680597805988059980600806018060280603806048060580606806078060880609806108061180612806138061480615806168061780618806198062080621806228062380624806258062680627806288062980630806318063280633806348063580636806378063880639806408064180642806438064480645806468064780648806498065080651806528065380654806558065680657806588065980660806618066280663806648066580666806678066880669806708067180672806738067480675806768067780678806798068080681806828068380684806858068680687806888068980690806918069280693806948069580696806978069880699807008070180702807038070480705807068070780708807098071080711807128071380714807158071680717807188071980720807218072280723807248072580726807278072880729807308073180732807338073480735807368073780738807398074080741807428074380744807458074680747807488074980750807518075280753807548075580756807578075880759807608076180762807638076480765807668076780768807698077080771807728077380774807758077680777807788077980780807818078280783807848078580786807878078880789807908079180792807938079480795807968079780798807998080080801808028080380804808058080680807808088080980810808118081280813808148081580816808178081880819808208082180822808238082480825808268082780828808298083080831808328083380834808358083680837808388083980840808418084280843808448084580846808478084880849808508085180852808538085480855808568085780858808598086080861808628086380864808658086680867808688086980870808718087280873808748087580876808778087880879808808088180882808838088480885808868088780888808898089080891808928089380894808958089680897808988089980900809018090280903809048090580906809078090880909809108091180912809138091480915809168091780918809198092080921809228092380924809258092680927809288092980930809318093280933809348093580936809378093880939809408094180942809438094480945809468094780948809498095080951809528095380954809558095680957809588095980960809618096280963809648096580966809678096880969809708097180972809738097480975809768097780978809798098080981809828098380984809858098680987809888098980990809918099280993809948099580996809978099880999810008100181002810038100481005810068100781008810098101081011810128101381014810158101681017810188101981020810218102281023810248102581026810278102881029810308103181032810338103481035810368103781038810398104081041810428104381044810458104681047810488104981050810518105281053810548105581056810578105881059810608106181062810638106481065810668106781068810698107081071810728107381074810758107681077810788107981080810818108281083810848108581086810878108881089810908109181092810938109481095810968109781098810998110081101811028110381104811058110681107811088110981110811118111281113811148111581116811178111881119811208112181122811238112481125811268112781128811298113081131811328113381134811358113681137811388113981140811418114281143811448114581146811478114881149811508115181152811538115481155811568115781158811598116081161811628116381164811658116681167811688116981170811718117281173811748117581176811778117881179811808118181182811838118481185811868118781188811898119081191811928119381194811958119681197811988119981200812018120281203812048120581206812078120881209812108121181212812138121481215812168121781218812198122081221812228122381224812258122681227812288122981230812318123281233812348123581236812378123881239812408124181242812438124481245812468124781248812498125081251812528125381254812558125681257812588125981260812618126281263812648126581266812678126881269812708127181272812738127481275812768127781278812798128081281812828128381284812858128681287812888128981290812918129281293812948129581296812978129881299813008130181302813038130481305813068130781308813098131081311813128131381314813158131681317813188131981320813218132281323813248132581326813278132881329813308133181332813338133481335813368133781338813398134081341813428134381344813458134681347813488134981350813518135281353813548135581356813578135881359813608136181362813638136481365813668136781368813698137081371813728137381374813758137681377813788137981380813818138281383813848138581386813878138881389813908139181392813938139481395813968139781398813998140081401814028140381404814058140681407814088140981410814118141281413814148141581416814178141881419814208142181422814238142481425814268142781428814298143081431814328143381434814358143681437814388143981440814418144281443814448144581446814478144881449814508145181452814538145481455814568145781458814598146081461814628146381464814658146681467814688146981470814718147281473814748147581476814778147881479814808148181482814838148481485814868148781488814898149081491814928149381494814958149681497814988149981500815018150281503815048150581506815078150881509815108151181512815138151481515815168151781518815198152081521815228152381524815258152681527815288152981530815318153281533815348153581536815378153881539815408154181542815438154481545815468154781548815498155081551815528155381554815558155681557815588155981560815618156281563815648156581566815678156881569815708157181572815738157481575815768157781578815798158081581815828158381584815858158681587815888158981590815918159281593815948159581596815978159881599816008160181602816038160481605816068160781608816098161081611816128161381614816158161681617816188161981620816218162281623816248162581626816278162881629816308163181632816338163481635816368163781638816398164081641816428164381644816458164681647816488164981650816518165281653816548165581656816578165881659816608166181662816638166481665816668166781668816698167081671816728167381674816758167681677816788167981680816818168281683816848168581686816878168881689816908169181692816938169481695816968169781698816998170081701817028170381704817058170681707817088170981710817118171281713817148171581716817178171881719817208172181722817238172481725817268172781728817298173081731817328173381734817358173681737817388173981740817418174281743817448174581746817478174881749817508175181752817538175481755817568175781758817598176081761817628176381764817658176681767817688176981770817718177281773817748177581776817778177881779817808178181782817838178481785817868178781788817898179081791817928179381794817958179681797817988179981800818018180281803818048180581806818078180881809818108181181812818138181481815818168181781818818198182081821818228182381824818258182681827818288182981830818318183281833818348183581836818378183881839818408184181842818438184481845818468184781848818498185081851818528185381854818558185681857818588185981860818618186281863818648186581866818678186881869818708187181872818738187481875818768187781878818798188081881818828188381884818858188681887818888188981890818918189281893818948189581896818978189881899819008190181902819038190481905819068190781908819098191081911819128191381914819158191681917819188191981920819218192281923819248192581926819278192881929819308193181932819338193481935819368193781938819398194081941819428194381944819458194681947819488194981950819518195281953819548195581956819578195881959819608196181962819638196481965819668196781968819698197081971819728197381974819758197681977819788197981980819818198281983819848198581986819878198881989819908199181992819938199481995819968199781998819998200082001820028200382004820058200682007820088200982010820118201282013820148201582016820178201882019820208202182022820238202482025820268202782028820298203082031820328203382034820358203682037820388203982040820418204282043820448204582046820478204882049820508205182052820538205482055820568205782058820598206082061820628206382064820658206682067820688206982070820718207282073820748207582076820778207882079820808208182082820838208482085820868208782088820898209082091820928209382094820958209682097820988209982100821018210282103821048210582106821078210882109821108211182112821138211482115821168211782118821198212082121821228212382124821258212682127821288212982130821318213282133821348213582136821378213882139821408214182142821438214482145821468214782148821498215082151821528215382154821558215682157821588215982160821618216282163821648216582166821678216882169821708217182172821738217482175821768217782178821798218082181821828218382184821858218682187821888218982190821918219282193821948219582196821978219882199822008220182202822038220482205822068220782208822098221082211822128221382214822158221682217822188221982220822218222282223822248222582226822278222882229822308223182232822338223482235822368223782238822398224082241822428224382244822458224682247822488224982250822518225282253822548225582256822578225882259822608226182262822638226482265822668226782268822698227082271822728227382274822758227682277822788227982280822818228282283822848228582286822878228882289822908229182292822938229482295822968229782298822998230082301823028230382304823058230682307823088230982310823118231282313823148231582316823178231882319823208232182322823238232482325823268232782328823298233082331823328233382334823358233682337823388233982340823418234282343823448234582346823478234882349823508235182352823538235482355823568235782358823598236082361823628236382364823658236682367823688236982370823718237282373823748237582376823778237882379823808238182382823838238482385823868238782388823898239082391823928239382394823958239682397823988239982400824018240282403824048240582406824078240882409824108241182412824138241482415824168241782418824198242082421824228242382424824258242682427824288242982430824318243282433824348243582436824378243882439824408244182442824438244482445824468244782448824498245082451824528245382454824558245682457824588245982460824618246282463824648246582466824678246882469824708247182472824738247482475824768247782478824798248082481824828248382484824858248682487824888248982490824918249282493824948249582496824978249882499825008250182502825038250482505825068250782508825098251082511825128251382514825158251682517825188251982520825218252282523825248252582526825278252882529825308253182532825338253482535825368253782538825398254082541825428254382544825458254682547825488254982550825518255282553825548255582556825578255882559825608256182562825638256482565825668256782568825698257082571825728257382574825758257682577825788257982580825818258282583825848258582586825878258882589825908259182592825938259482595825968259782598825998260082601826028260382604826058260682607826088260982610826118261282613826148261582616826178261882619826208262182622826238262482625826268262782628826298263082631826328263382634826358263682637826388263982640826418264282643826448264582646826478264882649826508265182652826538265482655826568265782658826598266082661826628266382664826658266682667826688266982670826718267282673826748267582676826778267882679826808268182682826838268482685826868268782688826898269082691826928269382694826958269682697826988269982700827018270282703827048270582706827078270882709827108271182712827138271482715827168271782718827198272082721827228272382724827258272682727827288272982730827318273282733827348273582736827378273882739827408274182742827438274482745827468274782748827498275082751827528275382754827558275682757827588275982760827618276282763827648276582766827678276882769827708277182772827738277482775827768277782778827798278082781827828278382784827858278682787827888278982790827918279282793827948279582796827978279882799828008280182802828038280482805828068280782808828098281082811828128281382814828158281682817828188281982820828218282282823828248282582826828278282882829828308283182832828338283482835828368283782838828398284082841828428284382844828458284682847828488284982850828518285282853828548285582856828578285882859828608286182862828638286482865828668286782868828698287082871828728287382874828758287682877828788287982880828818288282883828848288582886828878288882889828908289182892828938289482895828968289782898828998290082901829028290382904829058290682907829088290982910829118291282913829148291582916829178291882919829208292182922829238292482925829268292782928829298293082931829328293382934829358293682937829388293982940829418294282943829448294582946829478294882949829508295182952829538295482955829568295782958829598296082961829628296382964829658296682967829688296982970829718297282973829748297582976829778297882979829808298182982829838298482985829868298782988829898299082991829928299382994829958299682997829988299983000830018300283003830048300583006830078300883009830108301183012830138301483015830168301783018830198302083021830228302383024830258302683027830288302983030830318303283033830348303583036830378303883039830408304183042830438304483045830468304783048830498305083051830528305383054830558305683057830588305983060830618306283063830648306583066830678306883069830708307183072830738307483075830768307783078830798308083081830828308383084830858308683087830888308983090830918309283093830948309583096830978309883099831008310183102831038310483105831068310783108831098311083111831128311383114831158311683117831188311983120831218312283123831248312583126831278312883129831308313183132831338313483135831368313783138831398314083141831428314383144831458314683147831488314983150831518315283153831548315583156831578315883159831608316183162831638316483165831668316783168831698317083171831728317383174831758317683177831788317983180831818318283183831848318583186831878318883189831908319183192831938319483195831968319783198831998320083201832028320383204832058320683207832088320983210832118321283213832148321583216832178321883219832208322183222832238322483225832268322783228832298323083231832328323383234832358323683237832388323983240832418324283243832448324583246832478324883249832508325183252832538325483255832568325783258832598326083261832628326383264832658326683267832688326983270832718327283273832748327583276832778327883279832808328183282832838328483285832868328783288832898329083291832928329383294832958329683297832988329983300833018330283303833048330583306833078330883309833108331183312833138331483315833168331783318833198332083321833228332383324833258332683327833288332983330833318333283333833348333583336833378333883339833408334183342833438334483345833468334783348833498335083351833528335383354833558335683357833588335983360833618336283363833648336583366833678336883369833708337183372833738337483375833768337783378833798338083381833828338383384833858338683387833888338983390833918339283393833948339583396833978339883399834008340183402834038340483405834068340783408834098341083411834128341383414834158341683417834188341983420834218342283423834248342583426834278342883429834308343183432834338343483435834368343783438834398344083441834428344383444834458344683447834488344983450834518345283453834548345583456834578345883459834608346183462834638346483465834668346783468834698347083471834728347383474834758347683477834788347983480834818348283483834848348583486834878348883489834908349183492834938349483495834968349783498834998350083501835028350383504835058350683507835088350983510835118351283513835148351583516835178351883519835208352183522835238352483525835268352783528835298353083531835328353383534835358353683537835388353983540835418354283543835448354583546835478354883549835508355183552835538355483555835568355783558835598356083561835628356383564835658356683567835688356983570835718357283573835748357583576835778357883579835808358183582835838358483585835868358783588835898359083591835928359383594835958359683597835988359983600836018360283603836048360583606836078360883609836108361183612836138361483615836168361783618836198362083621836228362383624836258362683627836288362983630836318363283633836348363583636836378363883639836408364183642836438364483645836468364783648836498365083651836528365383654836558365683657836588365983660836618366283663836648366583666836678366883669836708367183672836738367483675836768367783678836798368083681836828368383684836858368683687836888368983690836918369283693836948369583696836978369883699837008370183702837038370483705837068370783708837098371083711837128371383714837158371683717837188371983720837218372283723837248372583726837278372883729837308373183732837338373483735837368373783738837398374083741837428374383744837458374683747837488374983750837518375283753837548375583756837578375883759837608376183762837638376483765837668376783768837698377083771837728377383774837758377683777837788377983780837818378283783837848378583786837878378883789837908379183792837938379483795837968379783798837998380083801838028380383804838058380683807838088380983810838118381283813838148381583816838178381883819838208382183822838238382483825838268382783828838298383083831838328383383834838358383683837838388383983840838418384283843838448384583846838478384883849838508385183852838538385483855838568385783858838598386083861838628386383864838658386683867838688386983870838718387283873838748387583876838778387883879838808388183882838838388483885838868388783888838898389083891838928389383894838958389683897838988389983900839018390283903839048390583906839078390883909839108391183912839138391483915839168391783918839198392083921839228392383924839258392683927839288392983930839318393283933839348393583936839378393883939839408394183942839438394483945839468394783948839498395083951839528395383954839558395683957839588395983960839618396283963839648396583966839678396883969839708397183972839738397483975839768397783978839798398083981839828398383984839858398683987839888398983990839918399283993839948399583996839978399883999840008400184002840038400484005840068400784008840098401084011840128401384014840158401684017840188401984020840218402284023840248402584026840278402884029840308403184032840338403484035840368403784038840398404084041840428404384044840458404684047840488404984050840518405284053840548405584056840578405884059840608406184062840638406484065840668406784068840698407084071840728407384074840758407684077840788407984080840818408284083840848408584086840878408884089840908409184092840938409484095840968409784098840998410084101841028410384104841058410684107841088410984110841118411284113841148411584116841178411884119841208412184122841238412484125841268412784128841298413084131841328413384134841358413684137841388413984140841418414284143841448414584146841478414884149841508415184152841538415484155841568415784158841598416084161841628416384164841658416684167841688416984170841718417284173841748417584176841778417884179841808418184182841838418484185841868418784188841898419084191841928419384194841958419684197841988419984200842018420284203842048420584206842078420884209842108421184212842138421484215842168421784218842198422084221842228422384224842258422684227842288422984230842318423284233842348423584236842378423884239842408424184242842438424484245842468424784248842498425084251842528425384254842558425684257842588425984260842618426284263842648426584266842678426884269842708427184272842738427484275842768427784278842798428084281842828428384284842858428684287842888428984290842918429284293842948429584296842978429884299843008430184302843038430484305843068430784308843098431084311843128431384314843158431684317843188431984320843218432284323843248432584326843278432884329843308433184332843338433484335843368433784338843398434084341843428434384344843458434684347843488434984350843518435284353843548435584356843578435884359843608436184362843638436484365843668436784368843698437084371843728437384374843758437684377843788437984380843818438284383843848438584386843878438884389843908439184392843938439484395843968439784398843998440084401844028440384404844058440684407844088440984410844118441284413844148441584416844178441884419844208442184422844238442484425844268442784428844298443084431844328443384434844358443684437844388443984440844418444284443844448444584446844478444884449844508445184452844538445484455844568445784458844598446084461844628446384464844658446684467844688446984470844718447284473844748447584476844778447884479844808448184482844838448484485844868448784488844898449084491844928449384494844958449684497844988449984500845018450284503845048450584506845078450884509845108451184512845138451484515845168451784518845198452084521845228452384524845258452684527845288452984530845318453284533845348453584536845378453884539845408454184542845438454484545845468454784548845498455084551845528455384554845558455684557845588455984560845618456284563845648456584566845678456884569845708457184572845738457484575845768457784578845798458084581845828458384584845858458684587845888458984590845918459284593845948459584596845978459884599846008460184602846038460484605846068460784608846098461084611846128461384614846158461684617846188461984620846218462284623846248462584626846278462884629846308463184632846338463484635846368463784638846398464084641846428464384644846458464684647846488464984650846518465284653846548465584656846578465884659846608466184662846638466484665846668466784668846698467084671846728467384674846758467684677846788467984680846818468284683846848468584686846878468884689846908469184692846938469484695846968469784698846998470084701847028470384704847058470684707847088470984710847118471284713847148471584716847178471884719847208472184722847238472484725847268472784728847298473084731847328473384734847358473684737847388473984740847418474284743847448474584746847478474884749847508475184752847538475484755847568475784758847598476084761847628476384764847658476684767847688476984770847718477284773847748477584776847778477884779847808478184782847838478484785847868478784788847898479084791847928479384794847958479684797847988479984800848018480284803848048480584806848078480884809848108481184812848138481484815848168481784818848198482084821848228482384824848258482684827848288482984830848318483284833848348483584836848378483884839848408484184842848438484484845848468484784848848498485084851848528485384854848558485684857848588485984860848618486284863848648486584866848678486884869848708487184872848738487484875848768487784878848798488084881848828488384884848858488684887848888488984890848918489284893848948489584896848978489884899849008490184902849038490484905849068490784908849098491084911849128491384914849158491684917849188491984920849218492284923849248492584926849278492884929849308493184932849338493484935849368493784938849398494084941849428494384944849458494684947849488494984950849518495284953849548495584956849578495884959849608496184962849638496484965849668496784968849698497084971849728497384974849758497684977849788497984980849818498284983849848498584986849878498884989849908499184992849938499484995849968499784998849998500085001850028500385004850058500685007850088500985010850118501285013850148501585016850178501885019850208502185022850238502485025850268502785028850298503085031850328503385034850358503685037850388503985040850418504285043850448504585046850478504885049850508505185052850538505485055850568505785058850598506085061850628506385064850658506685067850688506985070850718507285073850748507585076850778507885079850808508185082850838508485085850868508785088850898509085091850928509385094850958509685097850988509985100851018510285103851048510585106851078510885109851108511185112851138511485115851168511785118851198512085121851228512385124851258512685127851288512985130851318513285133851348513585136851378513885139851408514185142851438514485145851468514785148851498515085151851528515385154851558515685157851588515985160851618516285163851648516585166851678516885169851708517185172851738517485175851768517785178851798518085181851828518385184851858518685187851888518985190851918519285193851948519585196851978519885199852008520185202852038520485205852068520785208852098521085211852128521385214852158521685217852188521985220852218522285223852248522585226852278522885229852308523185232852338523485235852368523785238852398524085241852428524385244852458524685247852488524985250852518525285253852548525585256852578525885259852608526185262852638526485265852668526785268852698527085271852728527385274852758527685277852788527985280852818528285283852848528585286852878528885289852908529185292852938529485295852968529785298852998530085301853028530385304853058530685307853088530985310853118531285313853148531585316853178531885319853208532185322853238532485325853268532785328853298533085331853328533385334853358533685337853388533985340853418534285343853448534585346853478534885349853508535185352853538535485355853568535785358853598536085361853628536385364853658536685367853688536985370853718537285373853748537585376853778537885379853808538185382853838538485385853868538785388853898539085391853928539385394853958539685397853988539985400854018540285403854048540585406854078540885409854108541185412854138541485415854168541785418854198542085421854228542385424854258542685427854288542985430854318543285433854348543585436854378543885439854408544185442854438544485445854468544785448854498545085451854528545385454854558545685457854588545985460854618546285463854648546585466854678546885469854708547185472854738547485475854768547785478854798548085481854828548385484854858548685487854888548985490854918549285493854948549585496854978549885499855008550185502855038550485505855068550785508855098551085511855128551385514855158551685517855188551985520855218552285523855248552585526855278552885529855308553185532855338553485535855368553785538855398554085541855428554385544855458554685547855488554985550855518555285553855548555585556855578555885559855608556185562855638556485565855668556785568855698557085571855728557385574855758557685577855788557985580855818558285583855848558585586855878558885589855908559185592855938559485595855968559785598855998560085601856028560385604856058560685607856088560985610856118561285613856148561585616856178561885619856208562185622856238562485625856268562785628856298563085631856328563385634856358563685637856388563985640856418564285643856448564585646856478564885649856508565185652856538565485655856568565785658856598566085661856628566385664856658566685667856688566985670856718567285673856748567585676856778567885679856808568185682856838568485685856868568785688856898569085691856928569385694856958569685697856988569985700857018570285703857048570585706857078570885709857108571185712857138571485715857168571785718857198572085721857228572385724857258572685727857288572985730857318573285733857348573585736857378573885739857408574185742857438574485745857468574785748857498575085751857528575385754857558575685757857588575985760857618576285763857648576585766857678576885769857708577185772857738577485775857768577785778857798578085781857828578385784857858578685787857888578985790857918579285793857948579585796857978579885799858008580185802858038580485805858068580785808858098581085811858128581385814858158581685817858188581985820858218582285823858248582585826858278582885829858308583185832858338583485835858368583785838858398584085841858428584385844858458584685847858488584985850858518585285853858548585585856858578585885859858608586185862858638586485865858668586785868858698587085871858728587385874858758587685877858788587985880858818588285883858848588585886858878588885889858908589185892858938589485895858968589785898858998590085901859028590385904859058590685907859088590985910859118591285913859148591585916859178591885919859208592185922859238592485925859268592785928859298593085931859328593385934859358593685937859388593985940859418594285943859448594585946859478594885949859508595185952859538595485955859568595785958859598596085961859628596385964859658596685967859688596985970859718597285973859748597585976859778597885979859808598185982859838598485985859868598785988859898599085991859928599385994859958599685997859988599986000860018600286003860048600586006860078600886009860108601186012860138601486015860168601786018860198602086021860228602386024860258602686027860288602986030860318603286033860348603586036860378603886039860408604186042860438604486045860468604786048860498605086051860528605386054860558605686057860588605986060860618606286063860648606586066860678606886069860708607186072860738607486075860768607786078860798608086081860828608386084860858608686087860888608986090860918609286093860948609586096860978609886099861008610186102861038610486105861068610786108861098611086111861128611386114861158611686117861188611986120861218612286123861248612586126861278612886129861308613186132861338613486135861368613786138861398614086141861428614386144861458614686147861488614986150861518615286153861548615586156861578615886159861608616186162861638616486165861668616786168861698617086171861728617386174861758617686177861788617986180861818618286183861848618586186861878618886189861908619186192861938619486195861968619786198861998620086201862028620386204862058620686207862088620986210862118621286213862148621586216862178621886219862208622186222862238622486225862268622786228862298623086231862328623386234862358623686237862388623986240862418624286243862448624586246862478624886249862508625186252862538625486255862568625786258862598626086261862628626386264862658626686267862688626986270862718627286273862748627586276862778627886279862808628186282862838628486285862868628786288862898629086291862928629386294862958629686297862988629986300863018630286303863048630586306863078630886309863108631186312863138631486315863168631786318863198632086321863228632386324863258632686327863288632986330863318633286333863348633586336863378633886339863408634186342863438634486345863468634786348863498635086351863528635386354863558635686357863588635986360863618636286363863648636586366863678636886369863708637186372863738637486375863768637786378863798638086381863828638386384863858638686387863888638986390863918639286393863948639586396863978639886399864008640186402864038640486405864068640786408864098641086411864128641386414864158641686417864188641986420864218642286423864248642586426864278642886429864308643186432864338643486435864368643786438864398644086441864428644386444864458644686447864488644986450864518645286453864548645586456864578645886459864608646186462864638646486465864668646786468864698647086471864728647386474864758647686477864788647986480864818648286483864848648586486864878648886489864908649186492864938649486495864968649786498864998650086501865028650386504865058650686507865088650986510865118651286513865148651586516865178651886519865208652186522865238652486525865268652786528865298653086531865328653386534865358653686537865388653986540865418654286543865448654586546865478654886549865508655186552865538655486555865568655786558865598656086561865628656386564865658656686567865688656986570865718657286573865748657586576865778657886579865808658186582865838658486585865868658786588865898659086591865928659386594865958659686597865988659986600866018660286603866048660586606866078660886609866108661186612866138661486615866168661786618866198662086621866228662386624866258662686627866288662986630866318663286633866348663586636866378663886639866408664186642866438664486645866468664786648866498665086651866528665386654866558665686657866588665986660866618666286663866648666586666866678666886669866708667186672866738667486675866768667786678866798668086681866828668386684866858668686687866888668986690866918669286693866948669586696866978669886699867008670186702867038670486705867068670786708867098671086711867128671386714867158671686717867188671986720867218672286723867248672586726867278672886729867308673186732867338673486735867368673786738867398674086741867428674386744867458674686747867488674986750867518675286753867548675586756867578675886759867608676186762867638676486765867668676786768867698677086771867728677386774867758677686777867788677986780867818678286783867848678586786867878678886789867908679186792867938679486795867968679786798867998680086801868028680386804868058680686807868088680986810868118681286813868148681586816868178681886819868208682186822868238682486825868268682786828868298683086831868328683386834868358683686837868388683986840868418684286843868448684586846868478684886849868508685186852868538685486855868568685786858868598686086861868628686386864868658686686867868688686986870868718687286873868748687586876868778687886879868808688186882868838688486885868868688786888868898689086891868928689386894868958689686897868988689986900869018690286903869048690586906869078690886909869108691186912869138691486915869168691786918869198692086921869228692386924869258692686927869288692986930869318693286933869348693586936869378693886939869408694186942869438694486945869468694786948869498695086951869528695386954869558695686957869588695986960869618696286963869648696586966869678696886969869708697186972869738697486975869768697786978869798698086981869828698386984869858698686987869888698986990869918699286993869948699586996869978699886999870008700187002870038700487005870068700787008870098701087011870128701387014870158701687017870188701987020870218702287023870248702587026870278702887029870308703187032870338703487035870368703787038870398704087041870428704387044870458704687047870488704987050870518705287053870548705587056870578705887059870608706187062870638706487065870668706787068870698707087071870728707387074870758707687077870788707987080870818708287083870848708587086870878708887089870908709187092870938709487095870968709787098870998710087101871028710387104871058710687107871088710987110871118711287113871148711587116871178711887119871208712187122871238712487125871268712787128871298713087131871328713387134871358713687137871388713987140871418714287143871448714587146871478714887149871508715187152871538715487155871568715787158871598716087161871628716387164871658716687167871688716987170871718717287173871748717587176871778717887179871808718187182871838718487185871868718787188871898719087191871928719387194871958719687197871988719987200872018720287203872048720587206872078720887209872108721187212872138721487215872168721787218872198722087221872228722387224872258722687227872288722987230872318723287233872348723587236872378723887239872408724187242872438724487245872468724787248872498725087251872528725387254872558725687257872588725987260872618726287263872648726587266872678726887269872708727187272872738727487275872768727787278872798728087281872828728387284872858728687287872888728987290872918729287293872948729587296872978729887299873008730187302873038730487305873068730787308873098731087311873128731387314873158731687317873188731987320873218732287323873248732587326873278732887329873308733187332873338733487335873368733787338873398734087341873428734387344873458734687347873488734987350873518735287353873548735587356873578735887359873608736187362873638736487365873668736787368873698737087371873728737387374873758737687377873788737987380873818738287383873848738587386873878738887389873908739187392873938739487395873968739787398873998740087401874028740387404874058740687407874088740987410874118741287413874148741587416874178741887419874208742187422874238742487425874268742787428874298743087431874328743387434874358743687437874388743987440874418744287443874448744587446874478744887449874508745187452874538745487455874568745787458874598746087461874628746387464874658746687467874688746987470874718747287473874748747587476874778747887479874808748187482874838748487485874868748787488874898749087491874928749387494874958749687497874988749987500875018750287503875048750587506875078750887509875108751187512875138751487515875168751787518875198752087521875228752387524875258752687527875288752987530875318753287533875348753587536875378753887539875408754187542875438754487545875468754787548875498755087551875528755387554875558755687557875588755987560875618756287563875648756587566875678756887569875708757187572875738757487575875768757787578875798758087581875828758387584875858758687587875888758987590875918759287593875948759587596875978759887599876008760187602876038760487605876068760787608876098761087611876128761387614876158761687617876188761987620876218762287623876248762587626876278762887629876308763187632876338763487635876368763787638876398764087641876428764387644876458764687647876488764987650876518765287653876548765587656876578765887659876608766187662876638766487665876668766787668876698767087671876728767387674876758767687677876788767987680876818768287683876848768587686876878768887689876908769187692876938769487695876968769787698876998770087701877028770387704877058770687707877088770987710877118771287713877148771587716877178771887719877208772187722877238772487725877268772787728877298773087731877328773387734877358773687737877388773987740877418774287743877448774587746877478774887749877508775187752877538775487755877568775787758877598776087761877628776387764877658776687767877688776987770877718777287773877748777587776877778777887779877808778187782877838778487785877868778787788877898779087791877928779387794877958779687797877988779987800878018780287803878048780587806878078780887809878108781187812878138781487815878168781787818878198782087821878228782387824878258782687827878288782987830878318783287833878348783587836878378783887839878408784187842878438784487845878468784787848878498785087851878528785387854878558785687857878588785987860878618786287863878648786587866878678786887869878708787187872878738787487875878768787787878878798788087881878828788387884878858788687887878888788987890878918789287893878948789587896878978789887899879008790187902879038790487905879068790787908879098791087911879128791387914879158791687917879188791987920879218792287923879248792587926879278792887929879308793187932879338793487935879368793787938879398794087941879428794387944879458794687947879488794987950879518795287953879548795587956879578795887959879608796187962879638796487965879668796787968879698797087971879728797387974879758797687977879788797987980879818798287983879848798587986879878798887989879908799187992879938799487995879968799787998879998800088001880028800388004880058800688007880088800988010880118801288013880148801588016880178801888019880208802188022880238802488025880268802788028880298803088031880328803388034880358803688037880388803988040880418804288043880448804588046880478804888049880508805188052880538805488055880568805788058880598806088061880628806388064880658806688067880688806988070880718807288073880748807588076880778807888079880808808188082880838808488085880868808788088880898809088091880928809388094880958809688097880988809988100881018810288103881048810588106881078810888109881108811188112881138811488115881168811788118881198812088121881228812388124881258812688127881288812988130881318813288133881348813588136881378813888139881408814188142881438814488145881468814788148881498815088151881528815388154881558815688157881588815988160881618816288163881648816588166881678816888169881708817188172881738817488175881768817788178881798818088181881828818388184881858818688187881888818988190881918819288193881948819588196881978819888199882008820188202882038820488205882068820788208882098821088211882128821388214882158821688217882188821988220882218822288223882248822588226882278822888229882308823188232882338823488235882368823788238882398824088241882428824388244882458824688247882488824988250882518825288253882548825588256882578825888259882608826188262882638826488265882668826788268882698827088271882728827388274882758827688277882788827988280882818828288283882848828588286882878828888289882908829188292882938829488295882968829788298882998830088301883028830388304883058830688307883088830988310883118831288313883148831588316883178831888319883208832188322883238832488325883268832788328883298833088331883328833388334883358833688337883388833988340883418834288343883448834588346883478834888349883508835188352883538835488355883568835788358883598836088361883628836388364883658836688367883688836988370883718837288373883748837588376883778837888379883808838188382883838838488385883868838788388883898839088391883928839388394883958839688397883988839988400884018840288403884048840588406884078840888409884108841188412884138841488415884168841788418884198842088421884228842388424884258842688427884288842988430884318843288433884348843588436884378843888439884408844188442884438844488445884468844788448884498845088451884528845388454884558845688457884588845988460884618846288463884648846588466884678846888469884708847188472884738847488475884768847788478884798848088481884828848388484884858848688487884888848988490884918849288493884948849588496884978849888499885008850188502885038850488505885068850788508885098851088511885128851388514885158851688517885188851988520885218852288523885248852588526885278852888529885308853188532885338853488535885368853788538885398854088541885428854388544885458854688547885488854988550885518855288553885548855588556885578855888559885608856188562885638856488565885668856788568885698857088571885728857388574885758857688577885788857988580885818858288583885848858588586885878858888589885908859188592885938859488595885968859788598885998860088601886028860388604886058860688607886088860988610886118861288613886148861588616886178861888619886208862188622886238862488625886268862788628886298863088631886328863388634886358863688637886388863988640886418864288643886448864588646886478864888649886508865188652886538865488655886568865788658886598866088661886628866388664886658866688667886688866988670886718867288673886748867588676886778867888679886808868188682886838868488685886868868788688886898869088691886928869388694886958869688697886988869988700887018870288703887048870588706887078870888709887108871188712887138871488715887168871788718887198872088721887228872388724887258872688727887288872988730887318873288733887348873588736887378873888739887408874188742887438874488745887468874788748887498875088751887528875388754887558875688757887588875988760887618876288763887648876588766887678876888769887708877188772887738877488775887768877788778887798878088781887828878388784887858878688787887888878988790887918879288793887948879588796887978879888799888008880188802888038880488805888068880788808888098881088811888128881388814888158881688817888188881988820888218882288823888248882588826888278882888829888308883188832888338883488835888368883788838888398884088841888428884388844888458884688847888488884988850888518885288853888548885588856888578885888859888608886188862888638886488865888668886788868888698887088871888728887388874888758887688877888788887988880888818888288883888848888588886888878888888889888908889188892888938889488895888968889788898888998890088901889028890388904889058890688907889088890988910889118891288913889148891588916889178891888919889208892188922889238892488925889268892788928889298893088931889328893388934889358893688937889388893988940889418894288943889448894588946889478894888949889508895188952889538895488955889568895788958889598896088961889628896388964889658896688967889688896988970889718897288973889748897588976889778897888979889808898188982889838898488985889868898788988889898899088991889928899388994889958899688997889988899989000890018900289003890048900589006890078900889009890108901189012890138901489015890168901789018890198902089021890228902389024890258902689027890288902989030890318903289033890348903589036890378903889039890408904189042890438904489045890468904789048890498905089051890528905389054890558905689057890588905989060890618906289063890648906589066890678906889069890708907189072890738907489075890768907789078890798908089081890828908389084890858908689087890888908989090890918909289093890948909589096890978909889099891008910189102891038910489105891068910789108891098911089111891128911389114891158911689117891188911989120891218912289123891248912589126891278912889129891308913189132891338913489135891368913789138891398914089141891428914389144891458914689147891488914989150891518915289153891548915589156891578915889159891608916189162891638916489165891668916789168891698917089171891728917389174891758917689177891788917989180891818918289183891848918589186891878918889189891908919189192891938919489195891968919789198891998920089201892028920389204892058920689207892088920989210892118921289213892148921589216892178921889219892208922189222892238922489225892268922789228892298923089231892328923389234892358923689237892388923989240892418924289243892448924589246892478924889249892508925189252892538925489255892568925789258892598926089261892628926389264892658926689267892688926989270892718927289273892748927589276892778927889279892808928189282892838928489285892868928789288892898929089291892928929389294892958929689297892988929989300893018930289303893048930589306893078930889309893108931189312893138931489315893168931789318893198932089321893228932389324893258932689327893288932989330893318933289333893348933589336893378933889339893408934189342893438934489345893468934789348893498935089351893528935389354893558935689357893588935989360893618936289363893648936589366893678936889369893708937189372893738937489375893768937789378893798938089381893828938389384893858938689387893888938989390893918939289393893948939589396893978939889399894008940189402894038940489405894068940789408894098941089411894128941389414894158941689417894188941989420894218942289423894248942589426894278942889429894308943189432894338943489435894368943789438894398944089441894428944389444894458944689447894488944989450894518945289453894548945589456894578945889459894608946189462894638946489465894668946789468894698947089471894728947389474894758947689477894788947989480894818948289483894848948589486894878948889489894908949189492894938949489495894968949789498894998950089501895028950389504895058950689507895088950989510895118951289513895148951589516895178951889519895208952189522895238952489525895268952789528895298953089531895328953389534895358953689537895388953989540895418954289543895448954589546895478954889549895508955189552895538955489555895568955789558895598956089561895628956389564895658956689567895688956989570895718957289573895748957589576895778957889579895808958189582895838958489585895868958789588895898959089591895928959389594895958959689597895988959989600896018960289603896048960589606896078960889609896108961189612896138961489615896168961789618896198962089621896228962389624896258962689627896288962989630896318963289633896348963589636896378963889639896408964189642896438964489645896468964789648896498965089651896528965389654896558965689657896588965989660896618966289663896648966589666896678966889669896708967189672896738967489675896768967789678896798968089681896828968389684896858968689687896888968989690896918969289693896948969589696896978969889699897008970189702897038970489705897068970789708897098971089711897128971389714897158971689717897188971989720897218972289723897248972589726897278972889729897308973189732897338973489735897368973789738897398974089741897428974389744897458974689747897488974989750897518975289753897548975589756897578975889759897608976189762897638976489765897668976789768897698977089771897728977389774897758977689777897788977989780897818978289783897848978589786897878978889789897908979189792897938979489795897968979789798897998980089801898028980389804898058980689807898088980989810898118981289813898148981589816898178981889819898208982189822898238982489825898268982789828898298983089831898328983389834898358983689837898388983989840898418984289843898448984589846898478984889849898508985189852898538985489855898568985789858898598986089861898628986389864898658986689867898688986989870898718987289873898748987589876898778987889879898808988189882898838988489885898868988789888898898989089891898928989389894898958989689897898988989989900899018990289903899048990589906899078990889909899108991189912899138991489915899168991789918899198992089921899228992389924899258992689927899288992989930899318993289933899348993589936899378993889939899408994189942899438994489945899468994789948899498995089951899528995389954899558995689957899588995989960899618996289963899648996589966899678996889969899708997189972899738997489975899768997789978899798998089981899828998389984899858998689987899888998989990899918999289993899948999589996899978999889999900009000190002900039000490005900069000790008900099001090011900129001390014900159001690017900189001990020900219002290023900249002590026900279002890029900309003190032900339003490035900369003790038900399004090041900429004390044900459004690047900489004990050900519005290053900549005590056900579005890059900609006190062900639006490065900669006790068900699007090071900729007390074900759007690077900789007990080900819008290083900849008590086900879008890089900909009190092900939009490095900969009790098900999010090101901029010390104901059010690107901089010990110901119011290113901149011590116901179011890119901209012190122901239012490125901269012790128901299013090131901329013390134901359013690137901389013990140901419014290143901449014590146901479014890149901509015190152901539015490155901569015790158901599016090161901629016390164901659016690167901689016990170901719017290173901749017590176
  1. diff -Nur linux-2.6.39.orig/crypto/Kconfig linux-2.6.39/crypto/Kconfig
  2. --- linux-2.6.39.orig/crypto/Kconfig 2011-05-19 06:06:34.000000000 +0200
  3. +++ linux-2.6.39/crypto/Kconfig 2011-08-01 14:38:18.000000000 +0200
  4. @@ -866,3 +866,6 @@
  5. source "drivers/crypto/Kconfig"
  6. endif # if CRYPTO
  7. +
  8. +source "crypto/ocf/Kconfig"
  9. +
  10. diff -Nur linux-2.6.39.orig/crypto/Kconfig.orig linux-2.6.39/crypto/Kconfig.orig
  11. --- linux-2.6.39.orig/crypto/Kconfig.orig 1970-01-01 01:00:00.000000000 +0100
  12. +++ linux-2.6.39/crypto/Kconfig.orig 2011-08-01 14:38:18.000000000 +0200
  13. @@ -0,0 +1,868 @@
  14. +#
  15. +# Generic algorithms support
  16. +#
  17. +config XOR_BLOCKS
  18. + tristate
  19. +
  20. +#
  21. +# async_tx api: hardware offloaded memory transfer/transform support
  22. +#
  23. +source "crypto/async_tx/Kconfig"
  24. +
  25. +#
  26. +# Cryptographic API Configuration
  27. +#
  28. +menuconfig CRYPTO
  29. + tristate "Cryptographic API"
  30. + help
  31. + This option provides the core Cryptographic API.
  32. +
  33. +if CRYPTO
  34. +
  35. +comment "Crypto core or helper"
  36. +
  37. +config CRYPTO_FIPS
  38. + bool "FIPS 200 compliance"
  39. + depends on CRYPTO_ANSI_CPRNG && !CRYPTO_MANAGER_DISABLE_TESTS
  40. + help
  41. + This options enables the fips boot option which is
  42. + required if you want to system to operate in a FIPS 200
  43. + certification. You should say no unless you know what
  44. + this is.
  45. +
  46. +config CRYPTO_ALGAPI
  47. + tristate
  48. + select CRYPTO_ALGAPI2
  49. + help
  50. + This option provides the API for cryptographic algorithms.
  51. +
  52. +config CRYPTO_ALGAPI2
  53. + tristate
  54. +
  55. +config CRYPTO_AEAD
  56. + tristate
  57. + select CRYPTO_AEAD2
  58. + select CRYPTO_ALGAPI
  59. +
  60. +config CRYPTO_AEAD2
  61. + tristate
  62. + select CRYPTO_ALGAPI2
  63. +
  64. +config CRYPTO_BLKCIPHER
  65. + tristate
  66. + select CRYPTO_BLKCIPHER2
  67. + select CRYPTO_ALGAPI
  68. +
  69. +config CRYPTO_BLKCIPHER2
  70. + tristate
  71. + select CRYPTO_ALGAPI2
  72. + select CRYPTO_RNG2
  73. + select CRYPTO_WORKQUEUE
  74. +
  75. +config CRYPTO_HASH
  76. + tristate
  77. + select CRYPTO_HASH2
  78. + select CRYPTO_ALGAPI
  79. +
  80. +config CRYPTO_HASH2
  81. + tristate
  82. + select CRYPTO_ALGAPI2
  83. +
  84. +config CRYPTO_RNG
  85. + tristate
  86. + select CRYPTO_RNG2
  87. + select CRYPTO_ALGAPI
  88. +
  89. +config CRYPTO_RNG2
  90. + tristate
  91. + select CRYPTO_ALGAPI2
  92. +
  93. +config CRYPTO_PCOMP
  94. + tristate
  95. + select CRYPTO_PCOMP2
  96. + select CRYPTO_ALGAPI
  97. +
  98. +config CRYPTO_PCOMP2
  99. + tristate
  100. + select CRYPTO_ALGAPI2
  101. +
  102. +config CRYPTO_MANAGER
  103. + tristate "Cryptographic algorithm manager"
  104. + select CRYPTO_MANAGER2
  105. + help
  106. + Create default cryptographic template instantiations such as
  107. + cbc(aes).
  108. +
  109. +config CRYPTO_MANAGER2
  110. + def_tristate CRYPTO_MANAGER || (CRYPTO_MANAGER!=n && CRYPTO_ALGAPI=y)
  111. + select CRYPTO_AEAD2
  112. + select CRYPTO_HASH2
  113. + select CRYPTO_BLKCIPHER2
  114. + select CRYPTO_PCOMP2
  115. +
  116. +config CRYPTO_MANAGER_DISABLE_TESTS
  117. + bool "Disable run-time self tests"
  118. + default y
  119. + depends on CRYPTO_MANAGER2
  120. + help
  121. + Disable run-time self tests that normally take place at
  122. + algorithm registration.
  123. +
  124. +config CRYPTO_GF128MUL
  125. + tristate "GF(2^128) multiplication functions (EXPERIMENTAL)"
  126. + help
  127. + Efficient table driven implementation of multiplications in the
  128. + field GF(2^128). This is needed by some cypher modes. This
  129. + option will be selected automatically if you select such a
  130. + cipher mode. Only select this option by hand if you expect to load
  131. + an external module that requires these functions.
  132. +
  133. +config CRYPTO_NULL
  134. + tristate "Null algorithms"
  135. + select CRYPTO_ALGAPI
  136. + select CRYPTO_BLKCIPHER
  137. + select CRYPTO_HASH
  138. + help
  139. + These are 'Null' algorithms, used by IPsec, which do nothing.
  140. +
  141. +config CRYPTO_PCRYPT
  142. + tristate "Parallel crypto engine (EXPERIMENTAL)"
  143. + depends on SMP && EXPERIMENTAL
  144. + select PADATA
  145. + select CRYPTO_MANAGER
  146. + select CRYPTO_AEAD
  147. + help
  148. + This converts an arbitrary crypto algorithm into a parallel
  149. + algorithm that executes in kernel threads.
  150. +
  151. +config CRYPTO_WORKQUEUE
  152. + tristate
  153. +
  154. +config CRYPTO_CRYPTD
  155. + tristate "Software async crypto daemon"
  156. + select CRYPTO_BLKCIPHER
  157. + select CRYPTO_HASH
  158. + select CRYPTO_MANAGER
  159. + select CRYPTO_WORKQUEUE
  160. + help
  161. + This is a generic software asynchronous crypto daemon that
  162. + converts an arbitrary synchronous software crypto algorithm
  163. + into an asynchronous algorithm that executes in a kernel thread.
  164. +
  165. +config CRYPTO_AUTHENC
  166. + tristate "Authenc support"
  167. + select CRYPTO_AEAD
  168. + select CRYPTO_BLKCIPHER
  169. + select CRYPTO_MANAGER
  170. + select CRYPTO_HASH
  171. + help
  172. + Authenc: Combined mode wrapper for IPsec.
  173. + This is required for IPSec.
  174. +
  175. +config CRYPTO_TEST
  176. + tristate "Testing module"
  177. + depends on m
  178. + select CRYPTO_MANAGER
  179. + help
  180. + Quick & dirty crypto test module.
  181. +
  182. +comment "Authenticated Encryption with Associated Data"
  183. +
  184. +config CRYPTO_CCM
  185. + tristate "CCM support"
  186. + select CRYPTO_CTR
  187. + select CRYPTO_AEAD
  188. + help
  189. + Support for Counter with CBC MAC. Required for IPsec.
  190. +
  191. +config CRYPTO_GCM
  192. + tristate "GCM/GMAC support"
  193. + select CRYPTO_CTR
  194. + select CRYPTO_AEAD
  195. + select CRYPTO_GHASH
  196. + help
  197. + Support for Galois/Counter Mode (GCM) and Galois Message
  198. + Authentication Code (GMAC). Required for IPSec.
  199. +
  200. +config CRYPTO_SEQIV
  201. + tristate "Sequence Number IV Generator"
  202. + select CRYPTO_AEAD
  203. + select CRYPTO_BLKCIPHER
  204. + select CRYPTO_RNG
  205. + help
  206. + This IV generator generates an IV based on a sequence number by
  207. + xoring it with a salt. This algorithm is mainly useful for CTR
  208. +
  209. +comment "Block modes"
  210. +
  211. +config CRYPTO_CBC
  212. + tristate "CBC support"
  213. + select CRYPTO_BLKCIPHER
  214. + select CRYPTO_MANAGER
  215. + help
  216. + CBC: Cipher Block Chaining mode
  217. + This block cipher algorithm is required for IPSec.
  218. +
  219. +config CRYPTO_CTR
  220. + tristate "CTR support"
  221. + select CRYPTO_BLKCIPHER
  222. + select CRYPTO_SEQIV
  223. + select CRYPTO_MANAGER
  224. + help
  225. + CTR: Counter mode
  226. + This block cipher algorithm is required for IPSec.
  227. +
  228. +config CRYPTO_CTS
  229. + tristate "CTS support"
  230. + select CRYPTO_BLKCIPHER
  231. + help
  232. + CTS: Cipher Text Stealing
  233. + This is the Cipher Text Stealing mode as described by
  234. + Section 8 of rfc2040 and referenced by rfc3962.
  235. + (rfc3962 includes errata information in its Appendix A)
  236. + This mode is required for Kerberos gss mechanism support
  237. + for AES encryption.
  238. +
  239. +config CRYPTO_ECB
  240. + tristate "ECB support"
  241. + select CRYPTO_BLKCIPHER
  242. + select CRYPTO_MANAGER
  243. + help
  244. + ECB: Electronic CodeBook mode
  245. + This is the simplest block cipher algorithm. It simply encrypts
  246. + the input block by block.
  247. +
  248. +config CRYPTO_LRW
  249. + tristate "LRW support (EXPERIMENTAL)"
  250. + depends on EXPERIMENTAL
  251. + select CRYPTO_BLKCIPHER
  252. + select CRYPTO_MANAGER
  253. + select CRYPTO_GF128MUL
  254. + help
  255. + LRW: Liskov Rivest Wagner, a tweakable, non malleable, non movable
  256. + narrow block cipher mode for dm-crypt. Use it with cipher
  257. + specification string aes-lrw-benbi, the key must be 256, 320 or 384.
  258. + The first 128, 192 or 256 bits in the key are used for AES and the
  259. + rest is used to tie each cipher block to its logical position.
  260. +
  261. +config CRYPTO_PCBC
  262. + tristate "PCBC support"
  263. + select CRYPTO_BLKCIPHER
  264. + select CRYPTO_MANAGER
  265. + help
  266. + PCBC: Propagating Cipher Block Chaining mode
  267. + This block cipher algorithm is required for RxRPC.
  268. +
  269. +config CRYPTO_XTS
  270. + tristate "XTS support (EXPERIMENTAL)"
  271. + depends on EXPERIMENTAL
  272. + select CRYPTO_BLKCIPHER
  273. + select CRYPTO_MANAGER
  274. + select CRYPTO_GF128MUL
  275. + help
  276. + XTS: IEEE1619/D16 narrow block cipher use with aes-xts-plain,
  277. + key size 256, 384 or 512 bits. This implementation currently
  278. + can't handle a sectorsize which is not a multiple of 16 bytes.
  279. +
  280. +config CRYPTO_FPU
  281. + tristate
  282. + select CRYPTO_BLKCIPHER
  283. + select CRYPTO_MANAGER
  284. +
  285. +comment "Hash modes"
  286. +
  287. +config CRYPTO_HMAC
  288. + tristate "HMAC support"
  289. + select CRYPTO_HASH
  290. + select CRYPTO_MANAGER
  291. + help
  292. + HMAC: Keyed-Hashing for Message Authentication (RFC2104).
  293. + This is required for IPSec.
  294. +
  295. +config CRYPTO_XCBC
  296. + tristate "XCBC support"
  297. + depends on EXPERIMENTAL
  298. + select CRYPTO_HASH
  299. + select CRYPTO_MANAGER
  300. + help
  301. + XCBC: Keyed-Hashing with encryption algorithm
  302. + http://www.ietf.org/rfc/rfc3566.txt
  303. + http://csrc.nist.gov/encryption/modes/proposedmodes/
  304. + xcbc-mac/xcbc-mac-spec.pdf
  305. +
  306. +config CRYPTO_VMAC
  307. + tristate "VMAC support"
  308. + depends on EXPERIMENTAL
  309. + select CRYPTO_HASH
  310. + select CRYPTO_MANAGER
  311. + help
  312. + VMAC is a message authentication algorithm designed for
  313. + very high speed on 64-bit architectures.
  314. +
  315. + See also:
  316. + <http://fastcrypto.org/vmac>
  317. +
  318. +comment "Digest"
  319. +
  320. +config CRYPTO_CRC32C
  321. + tristate "CRC32c CRC algorithm"
  322. + select CRYPTO_HASH
  323. + help
  324. + Castagnoli, et al Cyclic Redundancy-Check Algorithm. Used
  325. + by iSCSI for header and data digests and by others.
  326. + See Castagnoli93. Module will be crc32c.
  327. +
  328. +config CRYPTO_CRC32C_INTEL
  329. + tristate "CRC32c INTEL hardware acceleration"
  330. + depends on X86
  331. + select CRYPTO_HASH
  332. + help
  333. + In Intel processor with SSE4.2 supported, the processor will
  334. + support CRC32C implementation using hardware accelerated CRC32
  335. + instruction. This option will create 'crc32c-intel' module,
  336. + which will enable any routine to use the CRC32 instruction to
  337. + gain performance compared with software implementation.
  338. + Module will be crc32c-intel.
  339. +
  340. +config CRYPTO_GHASH
  341. + tristate "GHASH digest algorithm"
  342. + select CRYPTO_SHASH
  343. + select CRYPTO_GF128MUL
  344. + help
  345. + GHASH is message digest algorithm for GCM (Galois/Counter Mode).
  346. +
  347. +config CRYPTO_MD4
  348. + tristate "MD4 digest algorithm"
  349. + select CRYPTO_HASH
  350. + help
  351. + MD4 message digest algorithm (RFC1320).
  352. +
  353. +config CRYPTO_MD5
  354. + tristate "MD5 digest algorithm"
  355. + select CRYPTO_HASH
  356. + help
  357. + MD5 message digest algorithm (RFC1321).
  358. +
  359. +config CRYPTO_MICHAEL_MIC
  360. + tristate "Michael MIC keyed digest algorithm"
  361. + select CRYPTO_HASH
  362. + help
  363. + Michael MIC is used for message integrity protection in TKIP
  364. + (IEEE 802.11i). This algorithm is required for TKIP, but it
  365. + should not be used for other purposes because of the weakness
  366. + of the algorithm.
  367. +
  368. +config CRYPTO_RMD128
  369. + tristate "RIPEMD-128 digest algorithm"
  370. + select CRYPTO_HASH
  371. + help
  372. + RIPEMD-128 (ISO/IEC 10118-3:2004).
  373. +
  374. + RIPEMD-128 is a 128-bit cryptographic hash function. It should only
  375. + to be used as a secure replacement for RIPEMD. For other use cases
  376. + RIPEMD-160 should be used.
  377. +
  378. + Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
  379. + See <http://homes.esat.kuleuven.be/~bosselae/ripemd160.html>
  380. +
  381. +config CRYPTO_RMD160
  382. + tristate "RIPEMD-160 digest algorithm"
  383. + select CRYPTO_HASH
  384. + help
  385. + RIPEMD-160 (ISO/IEC 10118-3:2004).
  386. +
  387. + RIPEMD-160 is a 160-bit cryptographic hash function. It is intended
  388. + to be used as a secure replacement for the 128-bit hash functions
  389. + MD4, MD5 and it's predecessor RIPEMD
  390. + (not to be confused with RIPEMD-128).
  391. +
  392. + It's speed is comparable to SHA1 and there are no known attacks
  393. + against RIPEMD-160.
  394. +
  395. + Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
  396. + See <http://homes.esat.kuleuven.be/~bosselae/ripemd160.html>
  397. +
  398. +config CRYPTO_RMD256
  399. + tristate "RIPEMD-256 digest algorithm"
  400. + select CRYPTO_HASH
  401. + help
  402. + RIPEMD-256 is an optional extension of RIPEMD-128 with a
  403. + 256 bit hash. It is intended for applications that require
  404. + longer hash-results, without needing a larger security level
  405. + (than RIPEMD-128).
  406. +
  407. + Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
  408. + See <http://homes.esat.kuleuven.be/~bosselae/ripemd160.html>
  409. +
  410. +config CRYPTO_RMD320
  411. + tristate "RIPEMD-320 digest algorithm"
  412. + select CRYPTO_HASH
  413. + help
  414. + RIPEMD-320 is an optional extension of RIPEMD-160 with a
  415. + 320 bit hash. It is intended for applications that require
  416. + longer hash-results, without needing a larger security level
  417. + (than RIPEMD-160).
  418. +
  419. + Developed by Hans Dobbertin, Antoon Bosselaers and Bart Preneel.
  420. + See <http://homes.esat.kuleuven.be/~bosselae/ripemd160.html>
  421. +
  422. +config CRYPTO_SHA1
  423. + tristate "SHA1 digest algorithm"
  424. + select CRYPTO_HASH
  425. + help
  426. + SHA-1 secure hash standard (FIPS 180-1/DFIPS 180-2).
  427. +
  428. +config CRYPTO_SHA256
  429. + tristate "SHA224 and SHA256 digest algorithm"
  430. + select CRYPTO_HASH
  431. + help
  432. + SHA256 secure hash standard (DFIPS 180-2).
  433. +
  434. + This version of SHA implements a 256 bit hash with 128 bits of
  435. + security against collision attacks.
  436. +
  437. + This code also includes SHA-224, a 224 bit hash with 112 bits
  438. + of security against collision attacks.
  439. +
  440. +config CRYPTO_SHA512
  441. + tristate "SHA384 and SHA512 digest algorithms"
  442. + select CRYPTO_HASH
  443. + help
  444. + SHA512 secure hash standard (DFIPS 180-2).
  445. +
  446. + This version of SHA implements a 512 bit hash with 256 bits of
  447. + security against collision attacks.
  448. +
  449. + This code also includes SHA-384, a 384 bit hash with 192 bits
  450. + of security against collision attacks.
  451. +
  452. +config CRYPTO_TGR192
  453. + tristate "Tiger digest algorithms"
  454. + select CRYPTO_HASH
  455. + help
  456. + Tiger hash algorithm 192, 160 and 128-bit hashes
  457. +
  458. + Tiger is a hash function optimized for 64-bit processors while
  459. + still having decent performance on 32-bit processors.
  460. + Tiger was developed by Ross Anderson and Eli Biham.
  461. +
  462. + See also:
  463. + <http://www.cs.technion.ac.il/~biham/Reports/Tiger/>.
  464. +
  465. +config CRYPTO_WP512
  466. + tristate "Whirlpool digest algorithms"
  467. + select CRYPTO_HASH
  468. + help
  469. + Whirlpool hash algorithm 512, 384 and 256-bit hashes
  470. +
  471. + Whirlpool-512 is part of the NESSIE cryptographic primitives.
  472. + Whirlpool will be part of the ISO/IEC 10118-3:2003(E) standard
  473. +
  474. + See also:
  475. + <http://www.larc.usp.br/~pbarreto/WhirlpoolPage.html>
  476. +
  477. +config CRYPTO_GHASH_CLMUL_NI_INTEL
  478. + tristate "GHASH digest algorithm (CLMUL-NI accelerated)"
  479. + depends on (X86 || UML_X86) && 64BIT
  480. + select CRYPTO_SHASH
  481. + select CRYPTO_CRYPTD
  482. + help
  483. + GHASH is message digest algorithm for GCM (Galois/Counter Mode).
  484. + The implementation is accelerated by CLMUL-NI of Intel.
  485. +
  486. +comment "Ciphers"
  487. +
  488. +config CRYPTO_AES
  489. + tristate "AES cipher algorithms"
  490. + select CRYPTO_ALGAPI
  491. + help
  492. + AES cipher algorithms (FIPS-197). AES uses the Rijndael
  493. + algorithm.
  494. +
  495. + Rijndael appears to be consistently a very good performer in
  496. + both hardware and software across a wide range of computing
  497. + environments regardless of its use in feedback or non-feedback
  498. + modes. Its key setup time is excellent, and its key agility is
  499. + good. Rijndael's very low memory requirements make it very well
  500. + suited for restricted-space environments, in which it also
  501. + demonstrates excellent performance. Rijndael's operations are
  502. + among the easiest to defend against power and timing attacks.
  503. +
  504. + The AES specifies three key sizes: 128, 192 and 256 bits
  505. +
  506. + See <http://csrc.nist.gov/CryptoToolkit/aes/> for more information.
  507. +
  508. +config CRYPTO_AES_586
  509. + tristate "AES cipher algorithms (i586)"
  510. + depends on (X86 || UML_X86) && !64BIT
  511. + select CRYPTO_ALGAPI
  512. + select CRYPTO_AES
  513. + help
  514. + AES cipher algorithms (FIPS-197). AES uses the Rijndael
  515. + algorithm.
  516. +
  517. + Rijndael appears to be consistently a very good performer in
  518. + both hardware and software across a wide range of computing
  519. + environments regardless of its use in feedback or non-feedback
  520. + modes. Its key setup time is excellent, and its key agility is
  521. + good. Rijndael's very low memory requirements make it very well
  522. + suited for restricted-space environments, in which it also
  523. + demonstrates excellent performance. Rijndael's operations are
  524. + among the easiest to defend against power and timing attacks.
  525. +
  526. + The AES specifies three key sizes: 128, 192 and 256 bits
  527. +
  528. + See <http://csrc.nist.gov/encryption/aes/> for more information.
  529. +
  530. +config CRYPTO_AES_X86_64
  531. + tristate "AES cipher algorithms (x86_64)"
  532. + depends on (X86 || UML_X86) && 64BIT
  533. + select CRYPTO_ALGAPI
  534. + select CRYPTO_AES
  535. + help
  536. + AES cipher algorithms (FIPS-197). AES uses the Rijndael
  537. + algorithm.
  538. +
  539. + Rijndael appears to be consistently a very good performer in
  540. + both hardware and software across a wide range of computing
  541. + environments regardless of its use in feedback or non-feedback
  542. + modes. Its key setup time is excellent, and its key agility is
  543. + good. Rijndael's very low memory requirements make it very well
  544. + suited for restricted-space environments, in which it also
  545. + demonstrates excellent performance. Rijndael's operations are
  546. + among the easiest to defend against power and timing attacks.
  547. +
  548. + The AES specifies three key sizes: 128, 192 and 256 bits
  549. +
  550. + See <http://csrc.nist.gov/encryption/aes/> for more information.
  551. +
  552. +config CRYPTO_AES_NI_INTEL
  553. + tristate "AES cipher algorithms (AES-NI)"
  554. + depends on (X86 || UML_X86)
  555. + select CRYPTO_AES_X86_64 if 64BIT
  556. + select CRYPTO_AES_586 if !64BIT
  557. + select CRYPTO_CRYPTD
  558. + select CRYPTO_ALGAPI
  559. + select CRYPTO_FPU
  560. + help
  561. + Use Intel AES-NI instructions for AES algorithm.
  562. +
  563. + AES cipher algorithms (FIPS-197). AES uses the Rijndael
  564. + algorithm.
  565. +
  566. + Rijndael appears to be consistently a very good performer in
  567. + both hardware and software across a wide range of computing
  568. + environments regardless of its use in feedback or non-feedback
  569. + modes. Its key setup time is excellent, and its key agility is
  570. + good. Rijndael's very low memory requirements make it very well
  571. + suited for restricted-space environments, in which it also
  572. + demonstrates excellent performance. Rijndael's operations are
  573. + among the easiest to defend against power and timing attacks.
  574. +
  575. + The AES specifies three key sizes: 128, 192 and 256 bits
  576. +
  577. + See <http://csrc.nist.gov/encryption/aes/> for more information.
  578. +
  579. + In addition to AES cipher algorithm support, the acceleration
  580. + for some popular block cipher mode is supported too, including
  581. + ECB, CBC, LRW, PCBC, XTS. The 64 bit version has additional
  582. + acceleration for CTR.
  583. +
  584. +config CRYPTO_ANUBIS
  585. + tristate "Anubis cipher algorithm"
  586. + select CRYPTO_ALGAPI
  587. + help
  588. + Anubis cipher algorithm.
  589. +
  590. + Anubis is a variable key length cipher which can use keys from
  591. + 128 bits to 320 bits in length. It was evaluated as a entrant
  592. + in the NESSIE competition.
  593. +
  594. + See also:
  595. + <https://www.cosic.esat.kuleuven.be/nessie/reports/>
  596. + <http://www.larc.usp.br/~pbarreto/AnubisPage.html>
  597. +
  598. +config CRYPTO_ARC4
  599. + tristate "ARC4 cipher algorithm"
  600. + select CRYPTO_ALGAPI
  601. + help
  602. + ARC4 cipher algorithm.
  603. +
  604. + ARC4 is a stream cipher using keys ranging from 8 bits to 2048
  605. + bits in length. This algorithm is required for driver-based
  606. + WEP, but it should not be for other purposes because of the
  607. + weakness of the algorithm.
  608. +
  609. +config CRYPTO_BLOWFISH
  610. + tristate "Blowfish cipher algorithm"
  611. + select CRYPTO_ALGAPI
  612. + help
  613. + Blowfish cipher algorithm, by Bruce Schneier.
  614. +
  615. + This is a variable key length cipher which can use keys from 32
  616. + bits to 448 bits in length. It's fast, simple and specifically
  617. + designed for use on "large microprocessors".
  618. +
  619. + See also:
  620. + <http://www.schneier.com/blowfish.html>
  621. +
  622. +config CRYPTO_CAMELLIA
  623. + tristate "Camellia cipher algorithms"
  624. + depends on CRYPTO
  625. + select CRYPTO_ALGAPI
  626. + help
  627. + Camellia cipher algorithms module.
  628. +
  629. + Camellia is a symmetric key block cipher developed jointly
  630. + at NTT and Mitsubishi Electric Corporation.
  631. +
  632. + The Camellia specifies three key sizes: 128, 192 and 256 bits.
  633. +
  634. + See also:
  635. + <https://info.isl.ntt.co.jp/crypt/eng/camellia/index_s.html>
  636. +
  637. +config CRYPTO_CAST5
  638. + tristate "CAST5 (CAST-128) cipher algorithm"
  639. + select CRYPTO_ALGAPI
  640. + help
  641. + The CAST5 encryption algorithm (synonymous with CAST-128) is
  642. + described in RFC2144.
  643. +
  644. +config CRYPTO_CAST6
  645. + tristate "CAST6 (CAST-256) cipher algorithm"
  646. + select CRYPTO_ALGAPI
  647. + help
  648. + The CAST6 encryption algorithm (synonymous with CAST-256) is
  649. + described in RFC2612.
  650. +
  651. +config CRYPTO_DES
  652. + tristate "DES and Triple DES EDE cipher algorithms"
  653. + select CRYPTO_ALGAPI
  654. + help
  655. + DES cipher algorithm (FIPS 46-2), and Triple DES EDE (FIPS 46-3).
  656. +
  657. +config CRYPTO_FCRYPT
  658. + tristate "FCrypt cipher algorithm"
  659. + select CRYPTO_ALGAPI
  660. + select CRYPTO_BLKCIPHER
  661. + help
  662. + FCrypt algorithm used by RxRPC.
  663. +
  664. +config CRYPTO_KHAZAD
  665. + tristate "Khazad cipher algorithm"
  666. + select CRYPTO_ALGAPI
  667. + help
  668. + Khazad cipher algorithm.
  669. +
  670. + Khazad was a finalist in the initial NESSIE competition. It is
  671. + an algorithm optimized for 64-bit processors with good performance
  672. + on 32-bit processors. Khazad uses an 128 bit key size.
  673. +
  674. + See also:
  675. + <http://www.larc.usp.br/~pbarreto/KhazadPage.html>
  676. +
  677. +config CRYPTO_SALSA20
  678. + tristate "Salsa20 stream cipher algorithm (EXPERIMENTAL)"
  679. + depends on EXPERIMENTAL
  680. + select CRYPTO_BLKCIPHER
  681. + help
  682. + Salsa20 stream cipher algorithm.
  683. +
  684. + Salsa20 is a stream cipher submitted to eSTREAM, the ECRYPT
  685. + Stream Cipher Project. See <http://www.ecrypt.eu.org/stream/>
  686. +
  687. + The Salsa20 stream cipher algorithm is designed by Daniel J.
  688. + Bernstein <djb@cr.yp.to>. See <http://cr.yp.to/snuffle.html>
  689. +
  690. +config CRYPTO_SALSA20_586
  691. + tristate "Salsa20 stream cipher algorithm (i586) (EXPERIMENTAL)"
  692. + depends on (X86 || UML_X86) && !64BIT
  693. + depends on EXPERIMENTAL
  694. + select CRYPTO_BLKCIPHER
  695. + help
  696. + Salsa20 stream cipher algorithm.
  697. +
  698. + Salsa20 is a stream cipher submitted to eSTREAM, the ECRYPT
  699. + Stream Cipher Project. See <http://www.ecrypt.eu.org/stream/>
  700. +
  701. + The Salsa20 stream cipher algorithm is designed by Daniel J.
  702. + Bernstein <djb@cr.yp.to>. See <http://cr.yp.to/snuffle.html>
  703. +
  704. +config CRYPTO_SALSA20_X86_64
  705. + tristate "Salsa20 stream cipher algorithm (x86_64) (EXPERIMENTAL)"
  706. + depends on (X86 || UML_X86) && 64BIT
  707. + depends on EXPERIMENTAL
  708. + select CRYPTO_BLKCIPHER
  709. + help
  710. + Salsa20 stream cipher algorithm.
  711. +
  712. + Salsa20 is a stream cipher submitted to eSTREAM, the ECRYPT
  713. + Stream Cipher Project. See <http://www.ecrypt.eu.org/stream/>
  714. +
  715. + The Salsa20 stream cipher algorithm is designed by Daniel J.
  716. + Bernstein <djb@cr.yp.to>. See <http://cr.yp.to/snuffle.html>
  717. +
  718. +config CRYPTO_SEED
  719. + tristate "SEED cipher algorithm"
  720. + select CRYPTO_ALGAPI
  721. + help
  722. + SEED cipher algorithm (RFC4269).
  723. +
  724. + SEED is a 128-bit symmetric key block cipher that has been
  725. + developed by KISA (Korea Information Security Agency) as a
  726. + national standard encryption algorithm of the Republic of Korea.
  727. + It is a 16 round block cipher with the key size of 128 bit.
  728. +
  729. + See also:
  730. + <http://www.kisa.or.kr/kisa/seed/jsp/seed_eng.jsp>
  731. +
  732. +config CRYPTO_SERPENT
  733. + tristate "Serpent cipher algorithm"
  734. + select CRYPTO_ALGAPI
  735. + help
  736. + Serpent cipher algorithm, by Anderson, Biham & Knudsen.
  737. +
  738. + Keys are allowed to be from 0 to 256 bits in length, in steps
  739. + of 8 bits. Also includes the 'Tnepres' algorithm, a reversed
  740. + variant of Serpent for compatibility with old kerneli.org code.
  741. +
  742. + See also:
  743. + <http://www.cl.cam.ac.uk/~rja14/serpent.html>
  744. +
  745. +config CRYPTO_TEA
  746. + tristate "TEA, XTEA and XETA cipher algorithms"
  747. + select CRYPTO_ALGAPI
  748. + help
  749. + TEA cipher algorithm.
  750. +
  751. + Tiny Encryption Algorithm is a simple cipher that uses
  752. + many rounds for security. It is very fast and uses
  753. + little memory.
  754. +
  755. + Xtendend Tiny Encryption Algorithm is a modification to
  756. + the TEA algorithm to address a potential key weakness
  757. + in the TEA algorithm.
  758. +
  759. + Xtendend Encryption Tiny Algorithm is a mis-implementation
  760. + of the XTEA algorithm for compatibility purposes.
  761. +
  762. +config CRYPTO_TWOFISH
  763. + tristate "Twofish cipher algorithm"
  764. + select CRYPTO_ALGAPI
  765. + select CRYPTO_TWOFISH_COMMON
  766. + help
  767. + Twofish cipher algorithm.
  768. +
  769. + Twofish was submitted as an AES (Advanced Encryption Standard)
  770. + candidate cipher by researchers at CounterPane Systems. It is a
  771. + 16 round block cipher supporting key sizes of 128, 192, and 256
  772. + bits.
  773. +
  774. + See also:
  775. + <http://www.schneier.com/twofish.html>
  776. +
  777. +config CRYPTO_TWOFISH_COMMON
  778. + tristate
  779. + help
  780. + Common parts of the Twofish cipher algorithm shared by the
  781. + generic c and the assembler implementations.
  782. +
  783. +config CRYPTO_TWOFISH_586
  784. + tristate "Twofish cipher algorithms (i586)"
  785. + depends on (X86 || UML_X86) && !64BIT
  786. + select CRYPTO_ALGAPI
  787. + select CRYPTO_TWOFISH_COMMON
  788. + help
  789. + Twofish cipher algorithm.
  790. +
  791. + Twofish was submitted as an AES (Advanced Encryption Standard)
  792. + candidate cipher by researchers at CounterPane Systems. It is a
  793. + 16 round block cipher supporting key sizes of 128, 192, and 256
  794. + bits.
  795. +
  796. + See also:
  797. + <http://www.schneier.com/twofish.html>
  798. +
  799. +config CRYPTO_TWOFISH_X86_64
  800. + tristate "Twofish cipher algorithm (x86_64)"
  801. + depends on (X86 || UML_X86) && 64BIT
  802. + select CRYPTO_ALGAPI
  803. + select CRYPTO_TWOFISH_COMMON
  804. + help
  805. + Twofish cipher algorithm (x86_64).
  806. +
  807. + Twofish was submitted as an AES (Advanced Encryption Standard)
  808. + candidate cipher by researchers at CounterPane Systems. It is a
  809. + 16 round block cipher supporting key sizes of 128, 192, and 256
  810. + bits.
  811. +
  812. + See also:
  813. + <http://www.schneier.com/twofish.html>
  814. +
  815. +comment "Compression"
  816. +
  817. +config CRYPTO_DEFLATE
  818. + tristate "Deflate compression algorithm"
  819. + select CRYPTO_ALGAPI
  820. + select ZLIB_INFLATE
  821. + select ZLIB_DEFLATE
  822. + help
  823. + This is the Deflate algorithm (RFC1951), specified for use in
  824. + IPSec with the IPCOMP protocol (RFC3173, RFC2394).
  825. +
  826. + You will most probably want this if using IPSec.
  827. +
  828. +config CRYPTO_ZLIB
  829. + tristate "Zlib compression algorithm"
  830. + select CRYPTO_PCOMP
  831. + select ZLIB_INFLATE
  832. + select ZLIB_DEFLATE
  833. + select NLATTR
  834. + help
  835. + This is the zlib algorithm.
  836. +
  837. +config CRYPTO_LZO
  838. + tristate "LZO compression algorithm"
  839. + select CRYPTO_ALGAPI
  840. + select LZO_COMPRESS
  841. + select LZO_DECOMPRESS
  842. + help
  843. + This is the LZO algorithm.
  844. +
  845. +comment "Random Number Generation"
  846. +
  847. +config CRYPTO_ANSI_CPRNG
  848. + tristate "Pseudo Random Number Generation for Cryptographic modules"
  849. + default m
  850. + select CRYPTO_AES
  851. + select CRYPTO_RNG
  852. + help
  853. + This option enables the generic pseudo random number generator
  854. + for cryptographic modules. Uses the Algorithm specified in
  855. + ANSI X9.31 A.2.4. Note that this option must be enabled if
  856. + CRYPTO_FIPS is selected
  857. +
  858. +config CRYPTO_USER_API
  859. + tristate
  860. +
  861. +config CRYPTO_USER_API_HASH
  862. + tristate "User-space interface for hash algorithms"
  863. + depends on NET
  864. + select CRYPTO_HASH
  865. + select CRYPTO_USER_API
  866. + help
  867. + This option enables the user-spaces interface for hash
  868. + algorithms.
  869. +
  870. +config CRYPTO_USER_API_SKCIPHER
  871. + tristate "User-space interface for symmetric key cipher algorithms"
  872. + depends on NET
  873. + select CRYPTO_BLKCIPHER
  874. + select CRYPTO_USER_API
  875. + help
  876. + This option enables the user-spaces interface for symmetric
  877. + key cipher algorithms.
  878. +
  879. +source "drivers/crypto/Kconfig"
  880. +
  881. +endif # if CRYPTO
  882. diff -Nur linux-2.6.39.orig/crypto/Makefile linux-2.6.39/crypto/Makefile
  883. --- linux-2.6.39.orig/crypto/Makefile 2011-05-19 06:06:34.000000000 +0200
  884. +++ linux-2.6.39/crypto/Makefile 2011-08-01 14:38:18.000000000 +0200
  885. @@ -89,6 +89,8 @@
  886. obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o
  887. obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o
  888. +obj-$(CONFIG_OCF_OCF) += ocf/
  889. +
  890. #
  891. # generic algorithms and the async_tx api
  892. #
  893. diff -Nur linux-2.6.39.orig/crypto/Makefile.orig linux-2.6.39/crypto/Makefile.orig
  894. --- linux-2.6.39.orig/crypto/Makefile.orig 1970-01-01 01:00:00.000000000 +0100
  895. +++ linux-2.6.39/crypto/Makefile.orig 2011-08-01 14:38:18.000000000 +0200
  896. @@ -0,0 +1,96 @@
  897. +#
  898. +# Cryptographic API
  899. +#
  900. +
  901. +obj-$(CONFIG_CRYPTO) += crypto.o
  902. +crypto-y := api.o cipher.o compress.o
  903. +
  904. +obj-$(CONFIG_CRYPTO_WORKQUEUE) += crypto_wq.o
  905. +
  906. +obj-$(CONFIG_CRYPTO_FIPS) += fips.o
  907. +
  908. +crypto_algapi-$(CONFIG_PROC_FS) += proc.o
  909. +crypto_algapi-y := algapi.o scatterwalk.o $(crypto_algapi-y)
  910. +obj-$(CONFIG_CRYPTO_ALGAPI2) += crypto_algapi.o
  911. +
  912. +obj-$(CONFIG_CRYPTO_AEAD2) += aead.o
  913. +
  914. +crypto_blkcipher-y := ablkcipher.o
  915. +crypto_blkcipher-y += blkcipher.o
  916. +obj-$(CONFIG_CRYPTO_BLKCIPHER2) += crypto_blkcipher.o
  917. +obj-$(CONFIG_CRYPTO_BLKCIPHER2) += chainiv.o
  918. +obj-$(CONFIG_CRYPTO_BLKCIPHER2) += eseqiv.o
  919. +obj-$(CONFIG_CRYPTO_SEQIV) += seqiv.o
  920. +
  921. +crypto_hash-y += ahash.o
  922. +crypto_hash-y += shash.o
  923. +obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o
  924. +
  925. +obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o
  926. +
  927. +cryptomgr-y := algboss.o testmgr.o
  928. +
  929. +obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o
  930. +obj-$(CONFIG_CRYPTO_HMAC) += hmac.o
  931. +obj-$(CONFIG_CRYPTO_VMAC) += vmac.o
  932. +obj-$(CONFIG_CRYPTO_XCBC) += xcbc.o
  933. +obj-$(CONFIG_CRYPTO_NULL) += crypto_null.o
  934. +obj-$(CONFIG_CRYPTO_MD4) += md4.o
  935. +obj-$(CONFIG_CRYPTO_MD5) += md5.o
  936. +obj-$(CONFIG_CRYPTO_RMD128) += rmd128.o
  937. +obj-$(CONFIG_CRYPTO_RMD160) += rmd160.o
  938. +obj-$(CONFIG_CRYPTO_RMD256) += rmd256.o
  939. +obj-$(CONFIG_CRYPTO_RMD320) += rmd320.o
  940. +obj-$(CONFIG_CRYPTO_SHA1) += sha1_generic.o
  941. +obj-$(CONFIG_CRYPTO_SHA256) += sha256_generic.o
  942. +obj-$(CONFIG_CRYPTO_SHA512) += sha512_generic.o
  943. +obj-$(CONFIG_CRYPTO_WP512) += wp512.o
  944. +obj-$(CONFIG_CRYPTO_TGR192) += tgr192.o
  945. +obj-$(CONFIG_CRYPTO_GF128MUL) += gf128mul.o
  946. +obj-$(CONFIG_CRYPTO_ECB) += ecb.o
  947. +obj-$(CONFIG_CRYPTO_CBC) += cbc.o
  948. +obj-$(CONFIG_CRYPTO_PCBC) += pcbc.o
  949. +obj-$(CONFIG_CRYPTO_CTS) += cts.o
  950. +obj-$(CONFIG_CRYPTO_LRW) += lrw.o
  951. +obj-$(CONFIG_CRYPTO_XTS) += xts.o
  952. +obj-$(CONFIG_CRYPTO_CTR) += ctr.o
  953. +obj-$(CONFIG_CRYPTO_GCM) += gcm.o
  954. +obj-$(CONFIG_CRYPTO_CCM) += ccm.o
  955. +obj-$(CONFIG_CRYPTO_PCRYPT) += pcrypt.o
  956. +obj-$(CONFIG_CRYPTO_CRYPTD) += cryptd.o
  957. +obj-$(CONFIG_CRYPTO_DES) += des_generic.o
  958. +obj-$(CONFIG_CRYPTO_FCRYPT) += fcrypt.o
  959. +obj-$(CONFIG_CRYPTO_BLOWFISH) += blowfish.o
  960. +obj-$(CONFIG_CRYPTO_TWOFISH) += twofish_generic.o
  961. +obj-$(CONFIG_CRYPTO_TWOFISH_COMMON) += twofish_common.o
  962. +obj-$(CONFIG_CRYPTO_SERPENT) += serpent.o
  963. +obj-$(CONFIG_CRYPTO_AES) += aes_generic.o
  964. +obj-$(CONFIG_CRYPTO_CAMELLIA) += camellia.o
  965. +obj-$(CONFIG_CRYPTO_CAST5) += cast5.o
  966. +obj-$(CONFIG_CRYPTO_CAST6) += cast6.o
  967. +obj-$(CONFIG_CRYPTO_ARC4) += arc4.o
  968. +obj-$(CONFIG_CRYPTO_TEA) += tea.o
  969. +obj-$(CONFIG_CRYPTO_KHAZAD) += khazad.o
  970. +obj-$(CONFIG_CRYPTO_ANUBIS) += anubis.o
  971. +obj-$(CONFIG_CRYPTO_SEED) += seed.o
  972. +obj-$(CONFIG_CRYPTO_SALSA20) += salsa20_generic.o
  973. +obj-$(CONFIG_CRYPTO_DEFLATE) += deflate.o
  974. +obj-$(CONFIG_CRYPTO_ZLIB) += zlib.o
  975. +obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
  976. +obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
  977. +obj-$(CONFIG_CRYPTO_AUTHENC) += authenc.o authencesn.o
  978. +obj-$(CONFIG_CRYPTO_LZO) += lzo.o
  979. +obj-$(CONFIG_CRYPTO_RNG2) += rng.o
  980. +obj-$(CONFIG_CRYPTO_RNG2) += krng.o
  981. +obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o
  982. +obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
  983. +obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o
  984. +obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o
  985. +obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o
  986. +obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o
  987. +
  988. +#
  989. +# generic algorithms and the async_tx api
  990. +#
  991. +obj-$(CONFIG_XOR_BLOCKS) += xor.o
  992. +obj-$(CONFIG_ASYNC_CORE) += async_tx/
  993. diff -Nur linux-2.6.39.orig/crypto/ocf/Config.in linux-2.6.39/crypto/ocf/Config.in
  994. --- linux-2.6.39.orig/crypto/ocf/Config.in 1970-01-01 01:00:00.000000000 +0100
  995. +++ linux-2.6.39/crypto/ocf/Config.in 2011-08-01 14:38:18.000000000 +0200
  996. @@ -0,0 +1,36 @@
  997. +#############################################################################
  998. +
  999. +mainmenu_option next_comment
  1000. +comment 'OCF Configuration'
  1001. +tristate 'OCF (Open Cryptograhic Framework)' CONFIG_OCF_OCF
  1002. +dep_mbool ' enable fips RNG checks (fips check on RNG data before use)' \
  1003. + CONFIG_OCF_FIPS $CONFIG_OCF_OCF
  1004. +dep_mbool ' enable harvesting entropy for /dev/random' \
  1005. + CONFIG_OCF_RANDOMHARVEST $CONFIG_OCF_OCF
  1006. +dep_tristate ' cryptodev (user space support)' \
  1007. + CONFIG_OCF_CRYPTODEV $CONFIG_OCF_OCF
  1008. +dep_tristate ' cryptosoft (software crypto engine)' \
  1009. + CONFIG_OCF_CRYPTOSOFT $CONFIG_OCF_OCF
  1010. +dep_tristate ' safenet (HW crypto engine)' \
  1011. + CONFIG_OCF_SAFE $CONFIG_OCF_OCF
  1012. +dep_tristate ' IXP4xx (HW crypto engine)' \
  1013. + CONFIG_OCF_IXP4XX $CONFIG_OCF_OCF
  1014. +dep_mbool ' Enable IXP4xx HW to perform SHA1 and MD5 hashing (very slow)' \
  1015. + CONFIG_OCF_IXP4XX_SHA1_MD5 $CONFIG_OCF_IXP4XX
  1016. +dep_tristate ' hifn (HW crypto engine)' \
  1017. + CONFIG_OCF_HIFN $CONFIG_OCF_OCF
  1018. +dep_tristate ' talitos (HW crypto engine)' \
  1019. + CONFIG_OCF_TALITOS $CONFIG_OCF_OCF
  1020. +dep_tristate ' pasemi (HW crypto engine)' \
  1021. + CONFIG_OCF_PASEMI $CONFIG_OCF_OCF
  1022. +dep_tristate ' ep80579 (HW crypto engine)' \
  1023. + CONFIG_OCF_EP80579 $CONFIG_OCF_OCF
  1024. +dep_tristate ' Micronas c7108 (HW crypto engine)' \
  1025. + CONFIG_OCF_C7108 $CONFIG_OCF_OCF
  1026. +dep_tristate ' ocfnull (does no crypto)' \
  1027. + CONFIG_OCF_OCFNULL $CONFIG_OCF_OCF
  1028. +dep_tristate ' ocf-bench (HW crypto in-kernel benchmark)' \
  1029. + CONFIG_OCF_BENCH $CONFIG_OCF_OCF
  1030. +endmenu
  1031. +
  1032. +#############################################################################
  1033. diff -Nur linux-2.6.39.orig/crypto/ocf/Kconfig linux-2.6.39/crypto/ocf/Kconfig
  1034. --- linux-2.6.39.orig/crypto/ocf/Kconfig 1970-01-01 01:00:00.000000000 +0100
  1035. +++ linux-2.6.39/crypto/ocf/Kconfig 2011-08-01 14:38:18.000000000 +0200
  1036. @@ -0,0 +1,119 @@
  1037. +menu "OCF Configuration"
  1038. +
  1039. +config OCF_OCF
  1040. + tristate "OCF (Open Cryptograhic Framework)"
  1041. + help
  1042. + A linux port of the OpenBSD/FreeBSD crypto framework.
  1043. +
  1044. +config OCF_RANDOMHARVEST
  1045. + bool "crypto random --- harvest entropy for /dev/random"
  1046. + depends on OCF_OCF
  1047. + help
  1048. + Includes code to harvest random numbers from devices that support it.
  1049. +
  1050. +config OCF_FIPS
  1051. + bool "enable fips RNG checks"
  1052. + depends on OCF_OCF && OCF_RANDOMHARVEST
  1053. + help
  1054. + Run all RNG provided data through a fips check before
  1055. + adding it /dev/random's entropy pool.
  1056. +
  1057. +config OCF_CRYPTODEV
  1058. + tristate "cryptodev (user space support)"
  1059. + depends on OCF_OCF
  1060. + help
  1061. + The user space API to access crypto hardware.
  1062. +
  1063. +config OCF_CRYPTOSOFT
  1064. + tristate "cryptosoft (software crypto engine)"
  1065. + depends on OCF_OCF
  1066. + help
  1067. + A software driver for the OCF framework that uses
  1068. + the kernel CryptoAPI.
  1069. +
  1070. +config OCF_SAFE
  1071. + tristate "safenet (HW crypto engine)"
  1072. + depends on OCF_OCF
  1073. + help
  1074. + A driver for a number of the safenet Excel crypto accelerators.
  1075. + Currently tested and working on the 1141 and 1741.
  1076. +
  1077. +config OCF_IXP4XX
  1078. + tristate "IXP4xx (HW crypto engine)"
  1079. + depends on OCF_OCF
  1080. + help
  1081. + XScale IXP4xx crypto accelerator driver. Requires the
  1082. + Intel Access library.
  1083. +
  1084. +config OCF_IXP4XX_SHA1_MD5
  1085. + bool "IXP4xx SHA1 and MD5 Hashing"
  1086. + depends on OCF_IXP4XX
  1087. + help
  1088. + Allows the IXP4xx crypto accelerator to perform SHA1 and MD5 hashing.
  1089. + Note: this is MUCH slower than using cryptosoft (software crypto engine).
  1090. +
  1091. +config OCF_HIFN
  1092. + tristate "hifn (HW crypto engine)"
  1093. + depends on OCF_OCF
  1094. + help
  1095. + OCF driver for various HIFN based crypto accelerators.
  1096. + (7951, 7955, 7956, 7751, 7811)
  1097. +
  1098. +config OCF_HIFNHIPP
  1099. + tristate "Hifn HIPP (HW packet crypto engine)"
  1100. + depends on OCF_OCF
  1101. + help
  1102. + OCF driver for various HIFN (HIPP) based crypto accelerators
  1103. + (7855)
  1104. +
  1105. +config OCF_TALITOS
  1106. + tristate "talitos (HW crypto engine)"
  1107. + depends on OCF_OCF
  1108. + help
  1109. + OCF driver for Freescale's security engine (SEC/talitos).
  1110. +
  1111. +config OCF_PASEMI
  1112. + tristate "pasemi (HW crypto engine)"
  1113. + depends on OCF_OCF && PPC_PASEMI
  1114. + help
  1115. + OCF driver for the PA Semi PWRficient DMA Engine
  1116. +
  1117. +config OCF_EP80579
  1118. + tristate "ep80579 (HW crypto engine)"
  1119. + depends on OCF_OCF
  1120. + help
  1121. + OCF driver for the Intel EP80579 Integrated Processor Product Line.
  1122. +
  1123. +config OCF_CRYPTOCTEON
  1124. + tristate "cryptocteon (HW crypto engine)"
  1125. + depends on OCF_OCF
  1126. + help
  1127. + OCF driver for the Cavium OCTEON Processors.
  1128. +
  1129. +config OCF_KIRKWOOD
  1130. + tristate "kirkwood (HW crypto engine)"
  1131. + depends on OCF_OCF
  1132. + help
  1133. + OCF driver for the Marvell Kirkwood (88F6xxx) Processors.
  1134. +
  1135. +config OCF_C7108
  1136. + tristate "Micronas 7108 (HW crypto engine)"
  1137. + depends on OCF_OCF
  1138. + help
  1139. + OCF driver for the Microna 7108 Cipher processors.
  1140. +
  1141. +config OCF_OCFNULL
  1142. + tristate "ocfnull (fake crypto engine)"
  1143. + depends on OCF_OCF
  1144. + help
  1145. + OCF driver for measuring ipsec overheads (does no crypto)
  1146. +
  1147. +config OCF_BENCH
  1148. + tristate "ocf-bench (HW crypto in-kernel benchmark)"
  1149. + depends on OCF_OCF
  1150. + help
  1151. + A very simple encryption test for the in-kernel interface
  1152. + of OCF. Also includes code to benchmark the IXP Access library
  1153. + for comparison.
  1154. +
  1155. +endmenu
  1156. diff -Nur linux-2.6.39.orig/crypto/ocf/Makefile linux-2.6.39/crypto/ocf/Makefile
  1157. --- linux-2.6.39.orig/crypto/ocf/Makefile 1970-01-01 01:00:00.000000000 +0100
  1158. +++ linux-2.6.39/crypto/ocf/Makefile 2011-08-01 14:38:19.000000000 +0200
  1159. @@ -0,0 +1,124 @@
  1160. +# for SGlinux builds
  1161. +-include $(ROOTDIR)/modules/.config
  1162. +
  1163. +OCF_OBJS = crypto.o criov.o
  1164. +
  1165. +ifdef CONFIG_OCF_RANDOMHARVEST
  1166. + OCF_OBJS += random.o
  1167. +endif
  1168. +
  1169. +ifdef CONFIG_OCF_FIPS
  1170. + OCF_OBJS += rndtest.o
  1171. +endif
  1172. +
  1173. +# Add in autoconf.h to get #defines for CONFIG_xxx
  1174. +AUTOCONF_H=$(ROOTDIR)/modules/autoconf.h
  1175. +ifeq ($(AUTOCONF_H), $(wildcard $(AUTOCONF_H)))
  1176. + EXTRA_CFLAGS += -include $(AUTOCONF_H)
  1177. + export EXTRA_CFLAGS
  1178. +endif
  1179. +
  1180. +ifndef obj
  1181. + obj ?= .
  1182. + _obj = subdir
  1183. + mod-subdirs := safe hifn ixp4xx talitos ocfnull
  1184. + export-objs += crypto.o criov.o random.o
  1185. + list-multi += ocf.o
  1186. + _slash :=
  1187. +else
  1188. + _obj = obj
  1189. + _slash := /
  1190. +endif
  1191. +
  1192. +EXTRA_CFLAGS += -I$(obj)/.
  1193. +
  1194. +obj-$(CONFIG_OCF_OCF) += ocf.o
  1195. +obj-$(CONFIG_OCF_CRYPTODEV) += cryptodev.o
  1196. +obj-$(CONFIG_OCF_CRYPTOSOFT) += cryptosoft.o
  1197. +obj-$(CONFIG_OCF_BENCH) += ocf-bench.o
  1198. +
  1199. +$(_obj)-$(CONFIG_OCF_SAFE) += safe$(_slash)
  1200. +$(_obj)-$(CONFIG_OCF_HIFN) += hifn$(_slash)
  1201. +$(_obj)-$(CONFIG_OCF_IXP4XX) += ixp4xx$(_slash)
  1202. +$(_obj)-$(CONFIG_OCF_TALITOS) += talitos$(_slash)
  1203. +$(_obj)-$(CONFIG_OCF_PASEMI) += pasemi$(_slash)
  1204. +$(_obj)-$(CONFIG_OCF_EP80579) += ep80579$(_slash)
  1205. +$(_obj)-$(CONFIG_OCF_CRYPTOCTEON) += cryptocteon$(_slash)
  1206. +$(_obj)-$(CONFIG_OCF_KIRKWOOD) += kirkwood$(_slash)
  1207. +$(_obj)-$(CONFIG_OCF_OCFNULL) += ocfnull$(_slash)
  1208. +$(_obj)-$(CONFIG_OCF_C7108) += c7108$(_slash)
  1209. +
  1210. +ocf-objs := $(OCF_OBJS)
  1211. +
  1212. +$(list-multi) dummy1: $(ocf-objs)
  1213. + $(LD) -r -o $@ $(ocf-objs)
  1214. +
  1215. +.PHONY:
  1216. +clean:
  1217. + rm -f *.o *.ko .*.o.flags .*.ko.cmd .*.o.cmd .*.mod.o.cmd *.mod.c
  1218. + rm -f */*.o */*.ko */.*.o.cmd */.*.ko.cmd */.*.mod.o.cmd */*.mod.c */.*.o.flags
  1219. +
  1220. +ifdef TOPDIR
  1221. +-include $(TOPDIR)/Rules.make
  1222. +endif
  1223. +
  1224. +#
  1225. +# release gen targets
  1226. +#
  1227. +
  1228. +.PHONY: patch
  1229. +patch:
  1230. + REL=`date +%Y%m%d`; \
  1231. + patch=ocf-linux-$$REL.patch; \
  1232. + patch24=ocf-linux-24-$$REL.patch; \
  1233. + patch26=ocf-linux-26-$$REL.patch; \
  1234. + ( \
  1235. + find . -name Makefile; \
  1236. + find . -name Config.in; \
  1237. + find . -name Kconfig; \
  1238. + find . -name README; \
  1239. + find . -name '*.[ch]' | grep -v '.mod.c'; \
  1240. + ) | while read t; do \
  1241. + diff -Nau /dev/null $$t | sed 's?^+++ \./?+++ linux/crypto/ocf/?'; \
  1242. + done > $$patch; \
  1243. + cat patches/linux-2.4.35-ocf.patch $$patch > $$patch24; \
  1244. + cat patches/linux-2.6.33-ocf.patch $$patch > $$patch26
  1245. +
  1246. +.PHONY: tarball
  1247. +tarball:
  1248. + REL=`date +%Y%m%d`; RELDIR=/tmp/ocf-linux-$$REL; \
  1249. + CURDIR=`pwd`; \
  1250. + rm -rf /tmp/ocf-linux-$$REL*; \
  1251. + mkdir -p $$RELDIR/tools; \
  1252. + cp README* $$RELDIR; \
  1253. + cp patches/openss*.patch $$RELDIR; \
  1254. + cp patches/crypto-tools.patch $$RELDIR; \
  1255. + cp tools/[!C]* $$RELDIR/tools; \
  1256. + cd ..; \
  1257. + tar cvf $$RELDIR/ocf-linux.tar \
  1258. + --exclude=CVS \
  1259. + --exclude=.* \
  1260. + --exclude=*.o \
  1261. + --exclude=*.ko \
  1262. + --exclude=*.mod.* \
  1263. + --exclude=README* \
  1264. + --exclude=ocf-*.patch \
  1265. + --exclude=ocf/patches/openss*.patch \
  1266. + --exclude=ocf/patches/crypto-tools.patch \
  1267. + --exclude=ocf/tools \
  1268. + ocf; \
  1269. + gzip -9 $$RELDIR/ocf-linux.tar; \
  1270. + cd /tmp; \
  1271. + tar cvf ocf-linux-$$REL.tar ocf-linux-$$REL; \
  1272. + gzip -9 ocf-linux-$$REL.tar; \
  1273. + cd $$CURDIR/../../user; \
  1274. + rm -rf /tmp/crypto-tools-$$REL*; \
  1275. + tar cvf /tmp/crypto-tools-$$REL.tar \
  1276. + --exclude=CVS \
  1277. + --exclude=.* \
  1278. + --exclude=*.o \
  1279. + --exclude=cryptotest \
  1280. + --exclude=cryptokeytest \
  1281. + crypto-tools; \
  1282. + gzip -9 /tmp/crypto-tools-$$REL.tar
  1283. +
  1284. diff -Nur linux-2.6.39.orig/crypto/ocf/README linux-2.6.39/crypto/ocf/README
  1285. --- linux-2.6.39.orig/crypto/ocf/README 1970-01-01 01:00:00.000000000 +0100
  1286. +++ linux-2.6.39/crypto/ocf/README 2011-08-01 14:38:19.000000000 +0200
  1287. @@ -0,0 +1,167 @@
  1288. +README - ocf-linux-20100325
  1289. +---------------------------
  1290. +
  1291. +This README provides instructions for getting ocf-linux compiled and
  1292. +operating in a generic linux environment. For other information you
  1293. +might like to visit the home page for this project:
  1294. +
  1295. + http://ocf-linux.sourceforge.net/
  1296. +
  1297. +Adding OCF to linux
  1298. +-------------------
  1299. +
  1300. + Not much in this file for now, just some notes. I usually build
  1301. + the ocf support as modules but it can be built into the kernel as
  1302. + well. To use it:
  1303. +
  1304. + * mknod /dev/crypto c 10 70
  1305. +
  1306. + * to add OCF to your kernel source, you have two options. Apply
  1307. + the kernel specific patch:
  1308. +
  1309. + cd linux-2.4*; gunzip < ocf-linux-24-XXXXXXXX.patch.gz | patch -p1
  1310. + cd linux-2.6*; gunzip < ocf-linux-26-XXXXXXXX.patch.gz | patch -p1
  1311. +
  1312. + if you do one of the above, then you can proceed to the next step,
  1313. + or you can do the above process by hand with using the patches against
  1314. + linux-2.4.35 and 2.6.33 to include the ocf code under crypto/ocf.
  1315. + Here's how to add it:
  1316. +
  1317. + for 2.4.35 (and later)
  1318. +
  1319. + cd linux-2.4.35/crypto
  1320. + tar xvzf ocf-linux.tar.gz
  1321. + cd ..
  1322. + patch -p1 < crypto/ocf/patches/linux-2.4.35-ocf.patch
  1323. +
  1324. + for 2.6.23 (and later), find the kernel patch specific (or nearest)
  1325. + to your kernel versions and then:
  1326. +
  1327. + cd linux-2.6.NN/crypto
  1328. + tar xvzf ocf-linux.tar.gz
  1329. + cd ..
  1330. + patch -p1 < crypto/ocf/patches/linux-2.6.NN-ocf.patch
  1331. +
  1332. + It should be easy to take this patch and apply it to other more
  1333. + recent versions of the kernels. The same patches should also work
  1334. + relatively easily on kernels as old as 2.6.11 and 2.4.18.
  1335. +
  1336. + * under 2.4 if you are on a non-x86 platform, you may need to:
  1337. +
  1338. + cp linux-2.X.x/include/asm-i386/kmap_types.h linux-2.X.x/include/asm-YYY
  1339. +
  1340. + so that you can build the kernel crypto support needed for the cryptosoft
  1341. + driver.
  1342. +
  1343. + * For simplicity you should enable all the crypto support in your kernel
  1344. + except for the test driver. Likewise for the OCF options. Do not
  1345. + enable OCF crypto drivers for HW that you do not have (for example
  1346. + ixp4xx will not compile on non-Xscale systems).
  1347. +
  1348. + * make sure that cryptodev.h (from ocf-linux.tar.gz) is installed as
  1349. + crypto/cryptodev.h in an include directory that is used for building
  1350. + applications for your platform. For example on a host system that
  1351. + might be:
  1352. +
  1353. + /usr/include/crypto/cryptodev.h
  1354. +
  1355. + * patch your openssl-0.9.8n code with the openssl-0.9.8n.patch.
  1356. + (NOTE: there is no longer a need to patch ssh). The patch is against:
  1357. + openssl-0_9_8e
  1358. +
  1359. + If you need a patch for an older version of openssl, you should look
  1360. + to older OCF releases. This patch is unlikely to work on older
  1361. + openssl versions.
  1362. +
  1363. + openssl-0.9.8n.patch
  1364. + - enables --with-cryptodev for non BSD systems
  1365. + - adds -cpu option to openssl speed for calculating CPU load
  1366. + under linux
  1367. + - fixes null pointer in openssl speed multi thread output.
  1368. + - fixes test keys to work with linux crypto's more stringent
  1369. + key checking.
  1370. + - adds MD5/SHA acceleration (Ronen Shitrit), only enabled
  1371. + with the --with-cryptodev-digests option
  1372. + - fixes bug in engine code caching.
  1373. +
  1374. + * build crypto-tools-XXXXXXXX.tar.gz if you want to try some of the BSD
  1375. + tools for testing OCF (ie., cryptotest).
  1376. +
  1377. +How to load the OCF drivers
  1378. +---------------------------
  1379. +
  1380. + First insert the base modules:
  1381. +
  1382. + insmod ocf
  1383. + insmod cryptodev
  1384. +
  1385. + You can then install the software OCF driver with:
  1386. +
  1387. + insmod cryptosoft
  1388. +
  1389. + and one or more of the OCF HW drivers with:
  1390. +
  1391. + insmod safe
  1392. + insmod hifn7751
  1393. + insmod ixp4xx
  1394. + ...
  1395. +
  1396. + all the drivers take a debug option to enable verbose debug so that
  1397. + you can see what is going on. For debug you load them as:
  1398. +
  1399. + insmod ocf crypto_debug=1
  1400. + insmod cryptodev cryptodev_debug=1
  1401. + insmod cryptosoft swcr_debug=1
  1402. +
  1403. + You may load more than one OCF crypto driver but then there is no guarantee
  1404. + as to which will be used.
  1405. +
  1406. + You can also enable debug at run time on 2.6 systems with the following:
  1407. +
  1408. + echo 1 > /sys/module/ocf/parameters/crypto_debug
  1409. + echo 1 > /sys/module/cryptodev/parameters/cryptodev_debug
  1410. + echo 1 > /sys/module/cryptosoft/parameters/swcr_debug
  1411. + echo 1 > /sys/module/hifn7751/parameters/hifn_debug
  1412. + echo 1 > /sys/module/safe/parameters/safe_debug
  1413. + echo 1 > /sys/module/ixp4xx/parameters/ixp_debug
  1414. + ...
  1415. +
  1416. +Testing the OCF support
  1417. +-----------------------
  1418. +
  1419. + run "cryptotest", it should do a short test for a couple of
  1420. + des packets. If it does everything is working.
  1421. +
  1422. + If this works, then ssh will use the driver when invoked as:
  1423. +
  1424. + ssh -c 3des username@host
  1425. +
  1426. + to see for sure that it is operating, enable debug as defined above.
  1427. +
  1428. + To get a better idea of performance run:
  1429. +
  1430. + cryptotest 100 4096
  1431. +
  1432. + There are more options to cryptotest, see the help.
  1433. +
  1434. + It is also possible to use openssl to test the speed of the crypto
  1435. + drivers.
  1436. +
  1437. + openssl speed -evp des -engine cryptodev -elapsed
  1438. + openssl speed -evp des3 -engine cryptodev -elapsed
  1439. + openssl speed -evp aes128 -engine cryptodev -elapsed
  1440. +
  1441. + and multiple threads (10) with:
  1442. +
  1443. + openssl speed -evp des -engine cryptodev -elapsed -multi 10
  1444. + openssl speed -evp des3 -engine cryptodev -elapsed -multi 10
  1445. + openssl speed -evp aes128 -engine cryptodev -elapsed -multi 10
  1446. +
  1447. + for public key testing you can try:
  1448. +
  1449. + cryptokeytest
  1450. + openssl speed -engine cryptodev rsa -elapsed
  1451. + openssl speed -engine cryptodev dsa -elapsed
  1452. +
  1453. +David McCullough
  1454. +david_mccullough@mcafee.com
  1455. diff -Nur linux-2.6.39.orig/crypto/ocf/c7108/Makefile linux-2.6.39/crypto/ocf/c7108/Makefile
  1456. --- linux-2.6.39.orig/crypto/ocf/c7108/Makefile 1970-01-01 01:00:00.000000000 +0100
  1457. +++ linux-2.6.39/crypto/ocf/c7108/Makefile 2011-08-01 14:38:18.000000000 +0200
  1458. @@ -0,0 +1,12 @@
  1459. +# for SGlinux builds
  1460. +-include $(ROOTDIR)/modules/.config
  1461. +
  1462. +obj-$(CONFIG_OCF_C7108) += aes-7108.o
  1463. +
  1464. +obj ?= .
  1465. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  1466. +
  1467. +ifdef TOPDIR
  1468. +-include $(TOPDIR)/Rules.make
  1469. +endif
  1470. +
  1471. diff -Nur linux-2.6.39.orig/crypto/ocf/c7108/aes-7108.c linux-2.6.39/crypto/ocf/c7108/aes-7108.c
  1472. --- linux-2.6.39.orig/crypto/ocf/c7108/aes-7108.c 1970-01-01 01:00:00.000000000 +0100
  1473. +++ linux-2.6.39/crypto/ocf/c7108/aes-7108.c 2011-08-01 14:38:18.000000000 +0200
  1474. @@ -0,0 +1,839 @@
  1475. +/*
  1476. + * Copyright (C) 2006 Micronas USA
  1477. + *
  1478. + * 1. Redistributions of source code must retain the above copyright
  1479. + * notice, this list of conditions and the following disclaimer.
  1480. + * 2. Redistributions in binary form must reproduce the above copyright
  1481. + * notice, this list of conditions and the following disclaimer in the
  1482. + * documentation and/or other materials provided with the distribution.
  1483. + * 3. The name of the author may not be used to endorse or promote products
  1484. + * derived from this software without specific prior written permission.
  1485. + *
  1486. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  1487. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  1488. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  1489. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  1490. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  1491. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  1492. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  1493. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  1494. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  1495. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1496. + *
  1497. + * Effort sponsored in part by the Defense Advanced Research Projects
  1498. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  1499. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  1500. + *
  1501. + */
  1502. +
  1503. +//#include <linux/config.h>
  1504. +#include <linux/module.h>
  1505. +#include <linux/init.h>
  1506. +#include <linux/list.h>
  1507. +#include <linux/slab.h>
  1508. +#include <linux/sched.h>
  1509. +#include <linux/wait.h>
  1510. +#include <linux/crypto.h>
  1511. +#include <linux/mm.h>
  1512. +#include <linux/skbuff.h>
  1513. +#include <linux/random.h>
  1514. +#include <asm/io.h>
  1515. +#include <asm/delay.h>
  1516. +//#include <asm/scatterlist.h>
  1517. +#include <linux/scatterlist.h>
  1518. +#include <linux/dma-mapping.h>
  1519. +#include <linux/highmem.h>
  1520. +#include <cryptodev.h>
  1521. +#include <uio.h>
  1522. +#include <aes-7108.h>
  1523. +
  1524. +/* Runtime mode */
  1525. +static int c7108_crypto_mode = C7108_AES_CTRL_MODE_CTR;
  1526. +//static int c7108_crypto_mode = C7108_AES_CTRL_MODE_CBC;
  1527. +
  1528. +static int32_t c7108_id = -1;
  1529. +static struct cipher_7108 **c7108_sessions = NULL;
  1530. +static u_int32_t c7108_sesnum = 0;
  1531. +static unsigned long iobar;
  1532. +
  1533. +/* Crypto entry points */
  1534. +static int c7108_process(void *, struct cryptop *, int);
  1535. +static int c7108_newsession(void *, u_int32_t *, struct cryptoini *);
  1536. +static int c7108_freesession(void *, u_int64_t);
  1537. +
  1538. +/* Globals */
  1539. +static int debug = 0;
  1540. +static spinlock_t csr_mutex;
  1541. +
  1542. +/* Generic controller-based lock */
  1543. +#define AES_LOCK()\
  1544. + spin_lock(&csr_mutex)
  1545. +#define AES_UNLOCK()\
  1546. + spin_unlock(&csr_mutex)
  1547. +
  1548. +/* 7108 AES register access */
  1549. +#define c7108_reg_wr8(a,d) iowrite8(d, (void*)(iobar+(a)))
  1550. +#define c7108_reg_wr16(a,d) iowrite16(d, (void*)(iobar+(a)))
  1551. +#define c7108_reg_wr32(a,d) iowrite32(d, (void*)(iobar+(a)))
  1552. +#define c7108_reg_rd8(a) ioread8((void*)(iobar+(a)))
  1553. +#define c7108_reg_rd16(a) ioread16((void*)(iobar+(a)))
  1554. +#define c7108_reg_rd32(a) ioread32((void*)(iobar+(a)))
  1555. +
  1556. +static int
  1557. +c7108_xlate_key(int klen, u8* k8ptr, u32* k32ptr)
  1558. +{
  1559. + int i, nw=0;
  1560. + nw = ((klen >= 256) ? 8 : (klen >= 192) ? 6 : 4);
  1561. + for ( i = 0; i < nw; i++) {
  1562. + k32ptr[i] = (k8ptr[i+3] << 24) | (k8ptr[i+2] << 16) |
  1563. + (k8ptr[i+1] << 8) | k8ptr[i];
  1564. +
  1565. + }
  1566. + return 0;
  1567. +}
  1568. +
  1569. +static int
  1570. +c7108_cache_key(int klen, u32* k32ptr, u8* k8ptr)
  1571. +{
  1572. + int i, nb=0;
  1573. + u8* ptr = (u8*)k32ptr;
  1574. + nb = ((klen >= 256) ? 32 : (klen >= 192) ? 24 : 16);
  1575. + for ( i = 0; i < nb; i++)
  1576. + k8ptr[i] = ptr[i];
  1577. + return 0;
  1578. +}
  1579. +
  1580. +static int
  1581. +c7108_aes_setup_dma(u32 src, u32 dst, u32 len)
  1582. +{
  1583. + if (len < 16) {
  1584. + printk("len < 16\n");
  1585. + return -10;
  1586. + }
  1587. + if (len % 16) {
  1588. + printk("len not multiple of 16\n");
  1589. + return -11;
  1590. + }
  1591. + c7108_reg_wr16(C7108_AES_DMA_SRC0_LO, (u16) src);
  1592. + c7108_reg_wr16(C7108_AES_DMA_SRC0_HI, (u16)((src & 0xffff0000) >> 16));
  1593. + c7108_reg_wr16(C7108_AES_DMA_DST0_LO, (u16) dst);
  1594. + c7108_reg_wr16(C7108_AES_DMA_DST0_HI, (u16)((dst & 0xffff0000) >> 16));
  1595. + c7108_reg_wr16(C7108_AES_DMA_LEN, (u16) ((len / 16) - 1));
  1596. +
  1597. + return 0;
  1598. +}
  1599. +
  1600. +static int
  1601. +c7108_aes_set_hw_iv(u8 iv[16])
  1602. +{
  1603. + c7108_reg_wr16(C7108_AES_IV0_LO, (u16) ((iv[1] << 8) | iv[0]));
  1604. + c7108_reg_wr16(C7108_AES_IV0_HI, (u16) ((iv[3] << 8) | iv[2]));
  1605. + c7108_reg_wr16(C7108_AES_IV1_LO, (u16) ((iv[5] << 8) | iv[4]));
  1606. + c7108_reg_wr16(C7108_AES_IV1_HI, (u16) ((iv[7] << 8) | iv[6]));
  1607. + c7108_reg_wr16(C7108_AES_IV2_LO, (u16) ((iv[9] << 8) | iv[8]));
  1608. + c7108_reg_wr16(C7108_AES_IV2_HI, (u16) ((iv[11] << 8) | iv[10]));
  1609. + c7108_reg_wr16(C7108_AES_IV3_LO, (u16) ((iv[13] << 8) | iv[12]));
  1610. + c7108_reg_wr16(C7108_AES_IV3_HI, (u16) ((iv[15] << 8) | iv[14]));
  1611. +
  1612. + return 0;
  1613. +}
  1614. +
  1615. +static void
  1616. +c7108_aes_read_dkey(u32 * dkey)
  1617. +{
  1618. + dkey[0] = (c7108_reg_rd16(C7108_AES_EKEY0_HI) << 16) |
  1619. + c7108_reg_rd16(C7108_AES_EKEY0_LO);
  1620. + dkey[1] = (c7108_reg_rd16(C7108_AES_EKEY1_HI) << 16) |
  1621. + c7108_reg_rd16(C7108_AES_EKEY1_LO);
  1622. + dkey[2] = (c7108_reg_rd16(C7108_AES_EKEY2_HI) << 16) |
  1623. + c7108_reg_rd16(C7108_AES_EKEY2_LO);
  1624. + dkey[3] = (c7108_reg_rd16(C7108_AES_EKEY3_HI) << 16) |
  1625. + c7108_reg_rd16(C7108_AES_EKEY3_LO);
  1626. + dkey[4] = (c7108_reg_rd16(C7108_AES_EKEY4_HI) << 16) |
  1627. + c7108_reg_rd16(C7108_AES_EKEY4_LO);
  1628. + dkey[5] = (c7108_reg_rd16(C7108_AES_EKEY5_HI) << 16) |
  1629. + c7108_reg_rd16(C7108_AES_EKEY5_LO);
  1630. + dkey[6] = (c7108_reg_rd16(C7108_AES_EKEY6_HI) << 16) |
  1631. + c7108_reg_rd16(C7108_AES_EKEY6_LO);
  1632. + dkey[7] = (c7108_reg_rd16(C7108_AES_EKEY7_HI) << 16) |
  1633. + c7108_reg_rd16(C7108_AES_EKEY7_LO);
  1634. +}
  1635. +
  1636. +static int
  1637. +c7108_aes_cipher(int op,
  1638. + u32 dst,
  1639. + u32 src,
  1640. + u32 len,
  1641. + int klen,
  1642. + u16 mode,
  1643. + u32 key[8],
  1644. + u8 iv[16])
  1645. +{
  1646. + int rv = 0, cnt=0;
  1647. + u16 ctrl = 0, stat = 0;
  1648. +
  1649. + AES_LOCK();
  1650. +
  1651. + /* Setup key length */
  1652. + if (klen == 128) {
  1653. + ctrl |= C7108_AES_KEY_LEN_128;
  1654. + } else if (klen == 192) {
  1655. + ctrl |= C7108_AES_KEY_LEN_192;
  1656. + } else if (klen == 256) {
  1657. + ctrl |= C7108_AES_KEY_LEN_256;
  1658. + } else {
  1659. + AES_UNLOCK();
  1660. + return -3;
  1661. + }
  1662. +
  1663. + /* Check opcode */
  1664. + if (C7108_AES_ENCRYPT == op) {
  1665. + ctrl |= C7108_AES_ENCRYPT;
  1666. + } else if (C7108_AES_DECRYPT == op) {
  1667. + ctrl |= C7108_AES_DECRYPT;
  1668. + } else {
  1669. + AES_UNLOCK();
  1670. + return -4;
  1671. + }
  1672. +
  1673. + /* check mode */
  1674. + if ( (mode != C7108_AES_CTRL_MODE_CBC) &&
  1675. + (mode != C7108_AES_CTRL_MODE_CFB) &&
  1676. + (mode != C7108_AES_CTRL_MODE_OFB) &&
  1677. + (mode != C7108_AES_CTRL_MODE_CTR) &&
  1678. + (mode != C7108_AES_CTRL_MODE_ECB) ) {
  1679. + AES_UNLOCK();
  1680. + return -5;
  1681. + }
  1682. +
  1683. + /* Now set mode */
  1684. + ctrl |= mode;
  1685. +
  1686. + /* For CFB, OFB, and CTR, neither backward key
  1687. + * expansion nor key inversion is required.
  1688. + */
  1689. + if ( (C7108_AES_DECRYPT == op) &&
  1690. + (C7108_AES_CTRL_MODE_CBC == mode ||
  1691. + C7108_AES_CTRL_MODE_ECB == mode ) ){
  1692. +
  1693. + /* Program Key */
  1694. + c7108_reg_wr16(C7108_AES_KEY0_LO, (u16) key[4]);
  1695. + c7108_reg_wr16(C7108_AES_KEY0_HI, (u16) (key[4] >> 16));
  1696. + c7108_reg_wr16(C7108_AES_KEY1_LO, (u16) key[5]);
  1697. + c7108_reg_wr16(C7108_AES_KEY1_HI, (u16) (key[5] >> 16));
  1698. + c7108_reg_wr16(C7108_AES_KEY2_LO, (u16) key[6]);
  1699. + c7108_reg_wr16(C7108_AES_KEY2_HI, (u16) (key[6] >> 16));
  1700. + c7108_reg_wr16(C7108_AES_KEY3_LO, (u16) key[7]);
  1701. + c7108_reg_wr16(C7108_AES_KEY3_HI, (u16) (key[7] >> 16));
  1702. + c7108_reg_wr16(C7108_AES_KEY6_LO, (u16) key[2]);
  1703. + c7108_reg_wr16(C7108_AES_KEY6_HI, (u16) (key[2] >> 16));
  1704. + c7108_reg_wr16(C7108_AES_KEY7_LO, (u16) key[3]);
  1705. + c7108_reg_wr16(C7108_AES_KEY7_HI, (u16) (key[3] >> 16));
  1706. +
  1707. +
  1708. + if (192 == klen) {
  1709. + c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[7]);
  1710. + c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[7] >> 16));
  1711. + c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[7]);
  1712. + c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[7] >> 16));
  1713. +
  1714. + } else if (256 == klen) {
  1715. + /* 256 */
  1716. + c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[0]);
  1717. + c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[0] >> 16));
  1718. + c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[1]);
  1719. + c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[1] >> 16));
  1720. +
  1721. + }
  1722. +
  1723. + } else {
  1724. + /* Program Key */
  1725. + c7108_reg_wr16(C7108_AES_KEY0_LO, (u16) key[0]);
  1726. + c7108_reg_wr16(C7108_AES_KEY0_HI, (u16) (key[0] >> 16));
  1727. + c7108_reg_wr16(C7108_AES_KEY1_LO, (u16) key[1]);
  1728. + c7108_reg_wr16(C7108_AES_KEY1_HI, (u16) (key[1] >> 16));
  1729. + c7108_reg_wr16(C7108_AES_KEY2_LO, (u16) key[2]);
  1730. + c7108_reg_wr16(C7108_AES_KEY2_HI, (u16) (key[2] >> 16));
  1731. + c7108_reg_wr16(C7108_AES_KEY3_LO, (u16) key[3]);
  1732. + c7108_reg_wr16(C7108_AES_KEY3_HI, (u16) (key[3] >> 16));
  1733. + c7108_reg_wr16(C7108_AES_KEY4_LO, (u16) key[4]);
  1734. + c7108_reg_wr16(C7108_AES_KEY4_HI, (u16) (key[4] >> 16));
  1735. + c7108_reg_wr16(C7108_AES_KEY5_LO, (u16) key[5]);
  1736. + c7108_reg_wr16(C7108_AES_KEY5_HI, (u16) (key[5] >> 16));
  1737. + c7108_reg_wr16(C7108_AES_KEY6_LO, (u16) key[6]);
  1738. + c7108_reg_wr16(C7108_AES_KEY6_HI, (u16) (key[6] >> 16));
  1739. + c7108_reg_wr16(C7108_AES_KEY7_LO, (u16) key[7]);
  1740. + c7108_reg_wr16(C7108_AES_KEY7_HI, (u16) (key[7] >> 16));
  1741. +
  1742. + }
  1743. +
  1744. + /* Set IV always */
  1745. + c7108_aes_set_hw_iv(iv);
  1746. +
  1747. + /* Program DMA addresses */
  1748. + if ((rv = c7108_aes_setup_dma(src, dst, len)) < 0) {
  1749. + AES_UNLOCK();
  1750. + return rv;
  1751. + }
  1752. +
  1753. +
  1754. + /* Start AES cipher */
  1755. + c7108_reg_wr16(C7108_AES_CTRL, ctrl | C7108_AES_GO);
  1756. +
  1757. + //printk("Ctrl: 0x%x\n", ctrl | C7108_AES_GO);
  1758. + do {
  1759. + /* TODO: interrupt mode */
  1760. + // printk("aes_stat=0x%x\n", stat);
  1761. + //udelay(100);
  1762. + } while ((cnt++ < 1000000) &&
  1763. + !((stat=c7108_reg_rd16(C7108_AES_CTRL))&C7108_AES_OP_DONE));
  1764. +
  1765. +
  1766. + if ((mode == C7108_AES_CTRL_MODE_ECB)||
  1767. + (mode == C7108_AES_CTRL_MODE_CBC)) {
  1768. + /* Save out key when the lock is held ... */
  1769. + c7108_aes_read_dkey(key);
  1770. + }
  1771. +
  1772. + AES_UNLOCK();
  1773. + return 0;
  1774. +
  1775. +}
  1776. +
  1777. +/*
  1778. + * Generate a new crypto device session.
  1779. + */
  1780. +static int
  1781. +c7108_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)
  1782. +{
  1783. + struct cipher_7108 **swd;
  1784. + u_int32_t i;
  1785. + char *algo;
  1786. + int mode, xfm_type;
  1787. +
  1788. + dprintk("%s()\n", __FUNCTION__);
  1789. + if (sid == NULL || cri == NULL) {
  1790. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  1791. + return EINVAL;
  1792. + }
  1793. +
  1794. + if (c7108_sessions) {
  1795. + for (i = 1; i < c7108_sesnum; i++)
  1796. + if (c7108_sessions[i] == NULL)
  1797. + break;
  1798. + } else
  1799. + i = 1; /* NB: to silence compiler warning */
  1800. +
  1801. + if (c7108_sessions == NULL || i == c7108_sesnum) {
  1802. + if (c7108_sessions == NULL) {
  1803. + i = 1; /* We leave c7108_sessions[0] empty */
  1804. + c7108_sesnum = CRYPTO_SW_SESSIONS;
  1805. + } else
  1806. + c7108_sesnum *= 2;
  1807. +
  1808. + swd = kmalloc(c7108_sesnum * sizeof(struct cipher_7108 *),
  1809. + GFP_ATOMIC);
  1810. + if (swd == NULL) {
  1811. + /* Reset session number */
  1812. + if (c7108_sesnum == CRYPTO_SW_SESSIONS)
  1813. + c7108_sesnum = 0;
  1814. + else
  1815. + c7108_sesnum /= 2;
  1816. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  1817. + return ENOBUFS;
  1818. + }
  1819. + memset(swd, 0, c7108_sesnum * sizeof(struct cipher_7108 *));
  1820. +
  1821. + /* Copy existing sessions */
  1822. + if (c7108_sessions) {
  1823. + memcpy(swd, c7108_sessions,
  1824. + (c7108_sesnum / 2) * sizeof(struct cipher_7108 *));
  1825. + kfree(c7108_sessions);
  1826. + }
  1827. +
  1828. + c7108_sessions = swd;
  1829. +
  1830. + }
  1831. +
  1832. + swd = &c7108_sessions[i];
  1833. + *sid = i;
  1834. +
  1835. + while (cri) {
  1836. + *swd = (struct cipher_7108 *)
  1837. + kmalloc(sizeof(struct cipher_7108), GFP_ATOMIC);
  1838. + if (*swd == NULL) {
  1839. + c7108_freesession(NULL, i);
  1840. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  1841. + return ENOBUFS;
  1842. + }
  1843. + memset(*swd, 0, sizeof(struct cipher_7108));
  1844. +
  1845. + algo = NULL;
  1846. + mode = 0;
  1847. + xfm_type = HW_TYPE_CIPHER;
  1848. +
  1849. + switch (cri->cri_alg) {
  1850. +
  1851. + case CRYPTO_AES_CBC:
  1852. + algo = "aes";
  1853. + mode = CRYPTO_TFM_MODE_CBC;
  1854. + c7108_crypto_mode = C7108_AES_CTRL_MODE_CBC;
  1855. + break;
  1856. +#if 0
  1857. + case CRYPTO_AES_CTR:
  1858. + algo = "aes_ctr";
  1859. + mode = CRYPTO_TFM_MODE_CBC;
  1860. + c7108_crypto_mode = C7108_AES_CTRL_MODE_CTR;
  1861. + break;
  1862. + case CRYPTO_AES_ECB:
  1863. + algo = "aes_ecb";
  1864. + mode = CRYPTO_TFM_MODE_CBC;
  1865. + c7108_crypto_mode = C7108_AES_CTRL_MODE_ECB;
  1866. + break;
  1867. + case CRYPTO_AES_OFB:
  1868. + algo = "aes_ofb";
  1869. + mode = CRYPTO_TFM_MODE_CBC;
  1870. + c7108_crypto_mode = C7108_AES_CTRL_MODE_OFB;
  1871. + break;
  1872. + case CRYPTO_AES_CFB:
  1873. + algo = "aes_cfb";
  1874. + mode = CRYPTO_TFM_MODE_CBC;
  1875. + c7108_crypto_mode = C7108_AES_CTRL_MODE_CFB;
  1876. + break;
  1877. +#endif
  1878. + default:
  1879. + printk("unsupported crypto algorithm: %d\n",
  1880. + cri->cri_alg);
  1881. + return -EINVAL;
  1882. + break;
  1883. + }
  1884. +
  1885. +
  1886. + if (!algo || !*algo) {
  1887. + printk("cypher_7108_crypto: Unknown algo 0x%x\n",
  1888. + cri->cri_alg);
  1889. + c7108_freesession(NULL, i);
  1890. + return EINVAL;
  1891. + }
  1892. +
  1893. + if (xfm_type == HW_TYPE_CIPHER) {
  1894. + if (debug) {
  1895. + dprintk("%s key:", __FUNCTION__);
  1896. + for (i = 0; i < (cri->cri_klen + 7) / 8; i++)
  1897. + dprintk("%s0x%02x", (i % 8) ? " " : "\n ",
  1898. + cri->cri_key[i]);
  1899. + dprintk("\n");
  1900. + }
  1901. +
  1902. + } else if (xfm_type == SW_TYPE_HMAC ||
  1903. + xfm_type == SW_TYPE_HASH) {
  1904. + printk("cypher_7108_crypto: HMAC unsupported!\n");
  1905. + return -EINVAL;
  1906. + c7108_freesession(NULL, i);
  1907. + } else {
  1908. + printk("cypher_7108_crypto: "
  1909. + "Unhandled xfm_type %d\n", xfm_type);
  1910. + c7108_freesession(NULL, i);
  1911. + return EINVAL;
  1912. + }
  1913. +
  1914. + (*swd)->cri_alg = cri->cri_alg;
  1915. + (*swd)->xfm_type = xfm_type;
  1916. +
  1917. + cri = cri->cri_next;
  1918. + swd = &((*swd)->next);
  1919. + }
  1920. + return 0;
  1921. +}
  1922. +
  1923. +/*
  1924. + * Free a session.
  1925. + */
  1926. +static int
  1927. +c7108_freesession(void *arg, u_int64_t tid)
  1928. +{
  1929. + struct cipher_7108 *swd;
  1930. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  1931. +
  1932. + dprintk("%s()\n", __FUNCTION__);
  1933. + if (sid > c7108_sesnum || c7108_sessions == NULL ||
  1934. + c7108_sessions[sid] == NULL) {
  1935. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  1936. + return(EINVAL);
  1937. + }
  1938. +
  1939. + /* Silently accept and return */
  1940. + if (sid == 0)
  1941. + return(0);
  1942. +
  1943. + while ((swd = c7108_sessions[sid]) != NULL) {
  1944. + c7108_sessions[sid] = swd->next;
  1945. + kfree(swd);
  1946. + }
  1947. + return 0;
  1948. +}
  1949. +
  1950. +/*
  1951. + * Process a hardware request.
  1952. + */
  1953. +static int
  1954. +c7108_process(void *arg, struct cryptop *crp, int hint)
  1955. +{
  1956. + struct cryptodesc *crd;
  1957. + struct cipher_7108 *sw;
  1958. + u_int32_t lid;
  1959. + int type;
  1960. + u32 hwkey[8];
  1961. +
  1962. +#define SCATTERLIST_MAX 16
  1963. + struct scatterlist sg[SCATTERLIST_MAX];
  1964. + int sg_num, sg_len, skip;
  1965. + struct sk_buff *skb = NULL;
  1966. + struct uio *uiop = NULL;
  1967. +
  1968. + dprintk("%s()\n", __FUNCTION__);
  1969. + /* Sanity check */
  1970. + if (crp == NULL) {
  1971. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  1972. + return EINVAL;
  1973. + }
  1974. +
  1975. + crp->crp_etype = 0;
  1976. +
  1977. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  1978. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  1979. + crp->crp_etype = EINVAL;
  1980. + goto done;
  1981. + }
  1982. +
  1983. + lid = crp->crp_sid & 0xffffffff;
  1984. + if (lid >= c7108_sesnum || lid == 0 || c7108_sessions == NULL ||
  1985. + c7108_sessions[lid] == NULL) {
  1986. + crp->crp_etype = ENOENT;
  1987. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  1988. + goto done;
  1989. + }
  1990. +
  1991. + /*
  1992. + * do some error checking outside of the loop for SKB and IOV
  1993. + * processing this leaves us with valid skb or uiop pointers
  1994. + * for later
  1995. + */
  1996. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  1997. + skb = (struct sk_buff *) crp->crp_buf;
  1998. + if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
  1999. + printk("%s,%d: %d nr_frags > SCATTERLIST_MAX",
  2000. + __FILE__, __LINE__,
  2001. + skb_shinfo(skb)->nr_frags);
  2002. + goto done;
  2003. + }
  2004. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  2005. + uiop = (struct uio *) crp->crp_buf;
  2006. + if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
  2007. + printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX",
  2008. + __FILE__, __LINE__,
  2009. + uiop->uio_iovcnt);
  2010. + goto done;
  2011. + }
  2012. + }
  2013. +
  2014. + /* Go through crypto descriptors, processing as we go */
  2015. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  2016. + /*
  2017. + * Find the crypto context.
  2018. + *
  2019. + * XXX Note that the logic here prevents us from having
  2020. + * XXX the same algorithm multiple times in a session
  2021. + * XXX (or rather, we can but it won't give us the right
  2022. + * XXX results). To do that, we'd need some way of differentiating
  2023. + * XXX between the various instances of an algorithm (so we can
  2024. + * XXX locate the correct crypto context).
  2025. + */
  2026. + for (sw = c7108_sessions[lid];
  2027. + sw && sw->cri_alg != crd->crd_alg;
  2028. + sw = sw->next)
  2029. + ;
  2030. +
  2031. + /* No such context ? */
  2032. + if (sw == NULL) {
  2033. + crp->crp_etype = EINVAL;
  2034. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  2035. + goto done;
  2036. + }
  2037. +
  2038. + skip = crd->crd_skip;
  2039. +
  2040. + /*
  2041. + * setup the SG list skip from the start of the buffer
  2042. + */
  2043. + memset(sg, 0, sizeof(sg));
  2044. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  2045. + int i, len;
  2046. + type = CRYPTO_BUF_SKBUF;
  2047. +
  2048. + sg_num = 0;
  2049. + sg_len = 0;
  2050. +
  2051. + if (skip < skb_headlen(skb)) {
  2052. + //sg[sg_num].page = virt_to_page(skb->data + skip);
  2053. + //sg[sg_num].offset = offset_in_page(skb->data + skip);
  2054. + len = skb_headlen(skb) - skip;
  2055. + if (len + sg_len > crd->crd_len)
  2056. + len = crd->crd_len - sg_len;
  2057. + //sg[sg_num].length = len;
  2058. + sg_set_page(&sg[sg_num], virt_to_page(skb->data + skip), len, offset_in_page(skb->data + skip));
  2059. + sg_len += sg[sg_num].length;
  2060. + sg_num++;
  2061. + skip = 0;
  2062. + } else
  2063. + skip -= skb_headlen(skb);
  2064. +
  2065. + for (i = 0; sg_len < crd->crd_len &&
  2066. + i < skb_shinfo(skb)->nr_frags &&
  2067. + sg_num < SCATTERLIST_MAX; i++) {
  2068. + if (skip < skb_shinfo(skb)->frags[i].size) {
  2069. + //sg[sg_num].page = skb_shinfo(skb)->frags[i].page;
  2070. + //sg[sg_num].offset = skb_shinfo(skb)->frags[i].page_offset + skip;
  2071. + len = skb_shinfo(skb)->frags[i].size - skip;
  2072. + if (len + sg_len > crd->crd_len)
  2073. + len = crd->crd_len - sg_len;
  2074. + //sg[sg_num].length = len;
  2075. + sg_set_page(&sg[sg_num], skb_shinfo(skb)->frags[i].page, len, skb_shinfo(skb)->frags[i].page_offset + skip);
  2076. + sg_len += sg[sg_num].length;
  2077. + sg_num++;
  2078. + skip = 0;
  2079. + } else
  2080. + skip -= skb_shinfo(skb)->frags[i].size;
  2081. + }
  2082. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  2083. + int len;
  2084. + type = CRYPTO_BUF_IOV;
  2085. + sg_len = 0;
  2086. + for (sg_num = 0; sg_len < crd->crd_len &&
  2087. + sg_num < uiop->uio_iovcnt &&
  2088. + sg_num < SCATTERLIST_MAX; sg_num++) {
  2089. + if (skip < uiop->uio_iov[sg_num].iov_len) {
  2090. + //sg[sg_num].page = virt_to_page(uiop->uio_iov[sg_num].iov_base+skip);
  2091. + //sg[sg_num].offset = offset_in_page(uiop->uio_iov[sg_num].iov_base+skip);
  2092. + len = uiop->uio_iov[sg_num].iov_len - skip;
  2093. + if (len + sg_len > crd->crd_len)
  2094. + len = crd->crd_len - sg_len;
  2095. + //sg[sg_num].length = len;
  2096. + 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));
  2097. + sg_len += sg[sg_num].length;
  2098. + skip = 0;
  2099. + } else
  2100. + skip -= uiop->uio_iov[sg_num].iov_len;
  2101. + }
  2102. + } else {
  2103. + type = CRYPTO_BUF_CONTIG;
  2104. + //sg[0].page = virt_to_page(crp->crp_buf + skip);
  2105. + //sg[0].offset = offset_in_page(crp->crp_buf + skip);
  2106. + sg_len = (crp->crp_ilen - skip);
  2107. + if (sg_len > crd->crd_len)
  2108. + sg_len = crd->crd_len;
  2109. + //sg[0].length = sg_len;
  2110. + sg_set_page(&sg[0], virt_to_page(crp->crp_buf + skip), sg_len, offset_in_page(crp->crp_buf + skip));
  2111. + sg_num = 1;
  2112. + }
  2113. +
  2114. +
  2115. + switch (sw->xfm_type) {
  2116. +
  2117. + case HW_TYPE_CIPHER: {
  2118. +
  2119. + unsigned char iv[64];
  2120. + unsigned char *ivp = iv;
  2121. + int i;
  2122. + int ivsize = 16; /* fixed for AES */
  2123. + int blocksize = 16; /* fixed for AES */
  2124. +
  2125. + if (sg_len < blocksize) {
  2126. + crp->crp_etype = EINVAL;
  2127. + dprintk("%s,%d: EINVAL len %d < %d\n",
  2128. + __FILE__, __LINE__,
  2129. + sg_len,
  2130. + blocksize);
  2131. + goto done;
  2132. + }
  2133. +
  2134. + if (ivsize > sizeof(iv)) {
  2135. + crp->crp_etype = EINVAL;
  2136. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  2137. + goto done;
  2138. + }
  2139. +
  2140. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  2141. +
  2142. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  2143. + ivp = crd->crd_iv;
  2144. + } else {
  2145. + get_random_bytes(ivp, ivsize);
  2146. + }
  2147. + /*
  2148. + * do we have to copy the IV back to the buffer ?
  2149. + */
  2150. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  2151. + crypto_copyback(crp->crp_buf,
  2152. + crd->crd_inject,
  2153. + ivsize,
  2154. + (caddr_t)ivp);
  2155. + }
  2156. +
  2157. + c7108_xlate_key(crd->crd_klen,
  2158. + (u8*)crd->crd_key, (u32*)hwkey);
  2159. +
  2160. + /* Encrypt SG list */
  2161. + for (i = 0; i < sg_num; i++) {
  2162. + sg[i].dma_address =
  2163. + dma_map_single(NULL,
  2164. + kmap(sg_page(&sg[i])) + sg[i].offset, sg_len, DMA_BIDIRECTIONAL);
  2165. +#if 0
  2166. + printk("sg[%d]:0x%08x, off 0x%08x "
  2167. + "kmap 0x%08x phys 0x%08x\n",
  2168. + i, sg[i].page, sg[i].offset,
  2169. + kmap(sg[i].page) + sg[i].offset,
  2170. + sg[i].dma_address);
  2171. +#endif
  2172. + c7108_aes_cipher(C7108_AES_ENCRYPT,
  2173. + sg[i].dma_address,
  2174. + sg[i].dma_address,
  2175. + sg_len,
  2176. + crd->crd_klen,
  2177. + c7108_crypto_mode,
  2178. + hwkey,
  2179. + ivp);
  2180. +
  2181. + if ((c7108_crypto_mode == C7108_AES_CTRL_MODE_CBC)||
  2182. + (c7108_crypto_mode == C7108_AES_CTRL_MODE_ECB)) {
  2183. + /* Read back expanded key and cache it in key
  2184. + * context.
  2185. + * NOTE: for ECB/CBC modes only (not CTR, CFB, OFB)
  2186. + * where you set the key once.
  2187. + */
  2188. + c7108_cache_key(crd->crd_klen,
  2189. + (u32*)hwkey, (u8*)crd->crd_key);
  2190. +#if 0
  2191. + printk("%s expanded key:", __FUNCTION__);
  2192. + for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
  2193. + printk("%s0x%02x", (i % 8) ? " " : "\n ",
  2194. + crd->crd_key[i]);
  2195. + printk("\n");
  2196. +#endif
  2197. + }
  2198. + }
  2199. + }
  2200. + else { /*decrypt */
  2201. +
  2202. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  2203. + ivp = crd->crd_iv;
  2204. + } else {
  2205. + crypto_copydata(crp->crp_buf, crd->crd_inject,
  2206. + ivsize, (caddr_t)ivp);
  2207. + }
  2208. +
  2209. + c7108_xlate_key(crd->crd_klen,
  2210. + (u8*)crd->crd_key, (u32*)hwkey);
  2211. +
  2212. + /* Decrypt SG list */
  2213. + for (i = 0; i < sg_num; i++) {
  2214. + sg[i].dma_address =
  2215. + dma_map_single(NULL,
  2216. + kmap(sg_page(&sg[i])) + sg[i].offset,
  2217. + sg_len, DMA_BIDIRECTIONAL);
  2218. +
  2219. +#if 0
  2220. + printk("sg[%d]:0x%08x, off 0x%08x "
  2221. + "kmap 0x%08x phys 0x%08x\n",
  2222. + i, sg[i].page, sg[i].offset,
  2223. + kmap(sg[i].page) + sg[i].offset,
  2224. + sg[i].dma_address);
  2225. +#endif
  2226. + c7108_aes_cipher(C7108_AES_DECRYPT,
  2227. + sg[i].dma_address,
  2228. + sg[i].dma_address,
  2229. + sg_len,
  2230. + crd->crd_klen,
  2231. + c7108_crypto_mode,
  2232. + hwkey,
  2233. + ivp);
  2234. + }
  2235. + }
  2236. + } break;
  2237. + case SW_TYPE_HMAC:
  2238. + case SW_TYPE_HASH:
  2239. + crp->crp_etype = EINVAL;
  2240. + goto done;
  2241. + break;
  2242. +
  2243. + case SW_TYPE_COMP:
  2244. + crp->crp_etype = EINVAL;
  2245. + goto done;
  2246. + break;
  2247. +
  2248. + default:
  2249. + /* Unknown/unsupported algorithm */
  2250. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  2251. + crp->crp_etype = EINVAL;
  2252. + goto done;
  2253. + }
  2254. + }
  2255. +
  2256. +done:
  2257. + crypto_done(crp);
  2258. + return 0;
  2259. +}
  2260. +
  2261. +static struct {
  2262. + softc_device_decl sc_dev;
  2263. +} a7108dev;
  2264. +
  2265. +static device_method_t a7108_methods = {
  2266. +/* crypto device methods */
  2267. + DEVMETHOD(cryptodev_newsession, c7108_newsession),
  2268. + DEVMETHOD(cryptodev_freesession, c7108_freesession),
  2269. + DEVMETHOD(cryptodev_process, c7108_process),
  2270. + DEVMETHOD(cryptodev_kprocess, NULL)
  2271. +};
  2272. +
  2273. +static int
  2274. +cypher_7108_crypto_init(void)
  2275. +{
  2276. + dprintk("%s(%p)\n", __FUNCTION__, cypher_7108_crypto_init);
  2277. +
  2278. + iobar = (unsigned long)ioremap(CCU_AES_REG_BASE, 0x4000);
  2279. + printk("7108: AES @ 0x%08x (0x%08x phys) %s mode\n",
  2280. + iobar, CCU_AES_REG_BASE,
  2281. + c7108_crypto_mode & C7108_AES_CTRL_MODE_CBC ? "CBC" :
  2282. + c7108_crypto_mode & C7108_AES_CTRL_MODE_ECB ? "ECB" :
  2283. + c7108_crypto_mode & C7108_AES_CTRL_MODE_CTR ? "CTR" :
  2284. + c7108_crypto_mode & C7108_AES_CTRL_MODE_CFB ? "CFB" :
  2285. + c7108_crypto_mode & C7108_AES_CTRL_MODE_OFB ? "OFB" : "???");
  2286. + csr_mutex = SPIN_LOCK_UNLOCKED;
  2287. +
  2288. + memset(&a7108dev, 0, sizeof(a7108dev));
  2289. + softc_device_init(&a7108dev, "aes7108", 0, a7108_methods);
  2290. +
  2291. + c7108_id = crypto_get_driverid(softc_get_device(&a7108dev), CRYPTOCAP_F_HARDWARE);
  2292. + if (c7108_id < 0)
  2293. + panic("7108: crypto device cannot initialize!");
  2294. +
  2295. +// crypto_register(c7108_id, CRYPTO_AES_CBC, 0, 0, c7108_newsession, c7108_freesession, c7108_process, NULL);
  2296. + crypto_register(c7108_id, CRYPTO_AES_CBC, 0, 0);
  2297. +
  2298. + return(0);
  2299. +}
  2300. +
  2301. +static void
  2302. +cypher_7108_crypto_exit(void)
  2303. +{
  2304. + dprintk("%s()\n", __FUNCTION__);
  2305. + crypto_unregister_all(c7108_id);
  2306. + c7108_id = -1;
  2307. +}
  2308. +
  2309. +module_init(cypher_7108_crypto_init);
  2310. +module_exit(cypher_7108_crypto_exit);
  2311. +
  2312. +MODULE_LICENSE("Dual BSD/GPL");
  2313. +MODULE_DESCRIPTION("Cypher 7108 Crypto (OCF module for kernel crypto)");
  2314. diff -Nur linux-2.6.39.orig/crypto/ocf/c7108/aes-7108.h linux-2.6.39/crypto/ocf/c7108/aes-7108.h
  2315. --- linux-2.6.39.orig/crypto/ocf/c7108/aes-7108.h 1970-01-01 01:00:00.000000000 +0100
  2316. +++ linux-2.6.39/crypto/ocf/c7108/aes-7108.h 2011-08-01 14:38:18.000000000 +0200
  2317. @@ -0,0 +1,134 @@
  2318. +/*
  2319. + * Copyright (C) 2006 Micronas USA
  2320. + *
  2321. + * 1. Redistributions of source code must retain the above copyright
  2322. + * notice, this list of conditions and the following disclaimer.
  2323. + * 2. Redistributions in binary form must reproduce the above copyright
  2324. + * notice, this list of conditions and the following disclaimer in the
  2325. + * documentation and/or other materials provided with the distribution.
  2326. + * 3. The name of the author may not be used to endorse or promote products
  2327. + * derived from this software without specific prior written permission.
  2328. + *
  2329. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  2330. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  2331. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  2332. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  2333. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  2334. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  2335. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  2336. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  2337. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  2338. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2339. + *
  2340. + * Effort sponsored in part by the Defense Advanced Research Projects
  2341. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  2342. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  2343. + *
  2344. + */
  2345. +
  2346. +#ifndef __AES_7108_H__
  2347. +#define __AES_7108_H__
  2348. +
  2349. +/* Cypher 7108 AES Controller Hardware */
  2350. +#define CCU_REG_BASE 0x1b500000
  2351. +#define CCU_AES_REG_BASE (CCU_REG_BASE + 0x100)
  2352. +#define C7108_AES_KEY0_LO (0x0000)
  2353. +#define C7108_AES_KEY0_HI (0x0004)
  2354. +#define C7108_AES_KEY1_LO (0x0008)
  2355. +#define C7108_AES_KEY1_HI (0x000c)
  2356. +#define C7108_AES_KEY2_LO (0x0010)
  2357. +#define C7108_AES_KEY2_HI (0x0014)
  2358. +#define C7108_AES_KEY3_LO (0x0018)
  2359. +#define C7108_AES_KEY3_HI (0x001c)
  2360. +#define C7108_AES_KEY4_LO (0x0020)
  2361. +#define C7108_AES_KEY4_HI (0x0024)
  2362. +#define C7108_AES_KEY5_LO (0x0028)
  2363. +#define C7108_AES_KEY5_HI (0x002c)
  2364. +#define C7108_AES_KEY6_LO (0x0030)
  2365. +#define C7108_AES_KEY6_HI (0x0034)
  2366. +#define C7108_AES_KEY7_LO (0x0038)
  2367. +#define C7108_AES_KEY7_HI (0x003c)
  2368. +#define C7108_AES_IV0_LO (0x0040)
  2369. +#define C7108_AES_IV0_HI (0x0044)
  2370. +#define C7108_AES_IV1_LO (0x0048)
  2371. +#define C7108_AES_IV1_HI (0x004c)
  2372. +#define C7108_AES_IV2_LO (0x0050)
  2373. +#define C7108_AES_IV2_HI (0x0054)
  2374. +#define C7108_AES_IV3_LO (0x0058)
  2375. +#define C7108_AES_IV3_HI (0x005c)
  2376. +
  2377. +#define C7108_AES_DMA_SRC0_LO (0x0068) /* Bits 0:15 */
  2378. +#define C7108_AES_DMA_SRC0_HI (0x006c) /* Bits 27:16 */
  2379. +#define C7108_AES_DMA_DST0_LO (0x0070) /* Bits 0:15 */
  2380. +#define C7108_AES_DMA_DST0_HI (0x0074) /* Bits 27:16 */
  2381. +#define C7108_AES_DMA_LEN (0x0078) /*Bytes:(Count+1)x16 */
  2382. +
  2383. +/* AES/Copy engine control register */
  2384. +#define C7108_AES_CTRL (0x007c) /* AES control */
  2385. +#define C7108_AES_CTRL_RS (1<<0) /* Which set of src/dst to use */
  2386. +
  2387. +/* AES Cipher mode, controlled by setting Bits 2:0 */
  2388. +#define C7108_AES_CTRL_MODE_CBC 0
  2389. +#define C7108_AES_CTRL_MODE_CFB (1<<0)
  2390. +#define C7108_AES_CTRL_MODE_OFB (1<<1)
  2391. +#define C7108_AES_CTRL_MODE_CTR ((1<<0)|(1<<1))
  2392. +#define C7108_AES_CTRL_MODE_ECB (1<<2)
  2393. +
  2394. +/* AES Key length , Bits 5:4 */
  2395. +#define C7108_AES_KEY_LEN_128 0 /* 00 */
  2396. +#define C7108_AES_KEY_LEN_192 (1<<4) /* 01 */
  2397. +#define C7108_AES_KEY_LEN_256 (1<<5) /* 10 */
  2398. +
  2399. +/* AES Operation (crypt/decrypt), Bit 3 */
  2400. +#define C7108_AES_DECRYPT (1<<3) /* Clear for encrypt */
  2401. +#define C7108_AES_ENCRYPT 0
  2402. +#define C7108_AES_INTR (1<<13) /* Set on done trans from 0->1*/
  2403. +#define C7108_AES_GO (1<<14) /* Run */
  2404. +#define C7108_AES_OP_DONE (1<<15) /* Set when complete */
  2405. +
  2406. +
  2407. +/* Expanded key registers */
  2408. +#define C7108_AES_EKEY0_LO (0x0080)
  2409. +#define C7108_AES_EKEY0_HI (0x0084)
  2410. +#define C7108_AES_EKEY1_LO (0x0088)
  2411. +#define C7108_AES_EKEY1_HI (0x008c)
  2412. +#define C7108_AES_EKEY2_LO (0x0090)
  2413. +#define C7108_AES_EKEY2_HI (0x0094)
  2414. +#define C7108_AES_EKEY3_LO (0x0098)
  2415. +#define C7108_AES_EKEY3_HI (0x009c)
  2416. +#define C7108_AES_EKEY4_LO (0x00a0)
  2417. +#define C7108_AES_EKEY4_HI (0x00a4)
  2418. +#define C7108_AES_EKEY5_LO (0x00a8)
  2419. +#define C7108_AES_EKEY5_HI (0x00ac)
  2420. +#define C7108_AES_EKEY6_LO (0x00b0)
  2421. +#define C7108_AES_EKEY6_HI (0x00b4)
  2422. +#define C7108_AES_EKEY7_LO (0x00b8)
  2423. +#define C7108_AES_EKEY7_HI (0x00bc)
  2424. +#define C7108_AES_OK (0x00fc) /* Reset: "OK" */
  2425. +
  2426. +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
  2427. +
  2428. +/* Software session entry */
  2429. +
  2430. +#define HW_TYPE_CIPHER 0
  2431. +#define SW_TYPE_HMAC 1
  2432. +#define SW_TYPE_AUTH2 2
  2433. +#define SW_TYPE_HASH 3
  2434. +#define SW_TYPE_COMP 4
  2435. +
  2436. +struct cipher_7108 {
  2437. + int xfm_type;
  2438. + int cri_alg;
  2439. + union {
  2440. + struct {
  2441. + char sw_key[HMAC_BLOCK_LEN];
  2442. + int sw_klen;
  2443. + int sw_authlen;
  2444. + } hmac;
  2445. + } u;
  2446. + struct cipher_7108 *next;
  2447. +};
  2448. +
  2449. +
  2450. +
  2451. +#endif /* __C7108_AES_7108_H__ */
  2452. diff -Nur linux-2.6.39.orig/crypto/ocf/criov.c linux-2.6.39/crypto/ocf/criov.c
  2453. --- linux-2.6.39.orig/crypto/ocf/criov.c 1970-01-01 01:00:00.000000000 +0100
  2454. +++ linux-2.6.39/crypto/ocf/criov.c 2011-08-01 14:39:10.000000000 +0200
  2455. @@ -0,0 +1,212 @@
  2456. +/* $OpenBSD: criov.c,v 1.9 2002/01/29 15:48:29 jason Exp $ */
  2457. +
  2458. +/*
  2459. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  2460. + * Copyright (C) 2006-2010 David McCullough
  2461. + * Copyright (C) 2004-2005 Intel Corporation.
  2462. + * The license and original author are listed below.
  2463. + *
  2464. + * Copyright (c) 1999 Theo de Raadt
  2465. + *
  2466. + * Redistribution and use in source and binary forms, with or without
  2467. + * modification, are permitted provided that the following conditions
  2468. + * are met:
  2469. + *
  2470. + * 1. Redistributions of source code must retain the above copyright
  2471. + * notice, this list of conditions and the following disclaimer.
  2472. + * 2. Redistributions in binary form must reproduce the above copyright
  2473. + * notice, this list of conditions and the following disclaimer in the
  2474. + * documentation and/or other materials provided with the distribution.
  2475. + * 3. The name of the author may not be used to endorse or promote products
  2476. + * derived from this software without specific prior written permission.
  2477. + *
  2478. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  2479. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  2480. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  2481. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  2482. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  2483. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  2484. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  2485. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  2486. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  2487. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2488. + *
  2489. +__FBSDID("$FreeBSD: src/sys/opencrypto/criov.c,v 1.5 2006/06/04 22:15:13 pjd Exp $");
  2490. + */
  2491. +
  2492. +#include <linux/module.h>
  2493. +#include <linux/init.h>
  2494. +#include <linux/slab.h>
  2495. +#include <linux/uio.h>
  2496. +#include <linux/skbuff.h>
  2497. +#include <linux/kernel.h>
  2498. +#include <linux/mm.h>
  2499. +#include <asm/io.h>
  2500. +
  2501. +#include <uio.h>
  2502. +#include <cryptodev.h>
  2503. +
  2504. +/*
  2505. + * This macro is only for avoiding code duplication, as we need to skip
  2506. + * given number of bytes in the same way in three functions below.
  2507. + */
  2508. +#define CUIO_SKIP() do { \
  2509. + KASSERT(off >= 0, ("%s: off %d < 0", __func__, off)); \
  2510. + KASSERT(len >= 0, ("%s: len %d < 0", __func__, len)); \
  2511. + while (off > 0) { \
  2512. + KASSERT(iol >= 0, ("%s: empty in skip", __func__)); \
  2513. + if (off < iov->iov_len) \
  2514. + break; \
  2515. + off -= iov->iov_len; \
  2516. + iol--; \
  2517. + iov++; \
  2518. + } \
  2519. +} while (0)
  2520. +
  2521. +void
  2522. +cuio_copydata(struct uio* uio, int off, int len, caddr_t cp)
  2523. +{
  2524. + struct iovec *iov = uio->uio_iov;
  2525. + int iol = uio->uio_iovcnt;
  2526. + unsigned count;
  2527. +
  2528. + CUIO_SKIP();
  2529. + while (len > 0) {
  2530. + KASSERT(iol >= 0, ("%s: empty", __func__));
  2531. + count = min((int)(iov->iov_len - off), len);
  2532. + memcpy(cp, ((caddr_t)iov->iov_base) + off, count);
  2533. + len -= count;
  2534. + cp += count;
  2535. + off = 0;
  2536. + iol--;
  2537. + iov++;
  2538. + }
  2539. +}
  2540. +
  2541. +void
  2542. +cuio_copyback(struct uio* uio, int off, int len, caddr_t cp)
  2543. +{
  2544. + struct iovec *iov = uio->uio_iov;
  2545. + int iol = uio->uio_iovcnt;
  2546. + unsigned count;
  2547. +
  2548. + CUIO_SKIP();
  2549. + while (len > 0) {
  2550. + KASSERT(iol >= 0, ("%s: empty", __func__));
  2551. + count = min((int)(iov->iov_len - off), len);
  2552. + memcpy(((caddr_t)iov->iov_base) + off, cp, count);
  2553. + len -= count;
  2554. + cp += count;
  2555. + off = 0;
  2556. + iol--;
  2557. + iov++;
  2558. + }
  2559. +}
  2560. +
  2561. +/*
  2562. + * Return a pointer to iov/offset of location in iovec list.
  2563. + */
  2564. +struct iovec *
  2565. +cuio_getptr(struct uio *uio, int loc, int *off)
  2566. +{
  2567. + struct iovec *iov = uio->uio_iov;
  2568. + int iol = uio->uio_iovcnt;
  2569. +
  2570. + while (loc >= 0) {
  2571. + /* Normal end of search */
  2572. + if (loc < iov->iov_len) {
  2573. + *off = loc;
  2574. + return (iov);
  2575. + }
  2576. +
  2577. + loc -= iov->iov_len;
  2578. + if (iol == 0) {
  2579. + if (loc == 0) {
  2580. + /* Point at the end of valid data */
  2581. + *off = iov->iov_len;
  2582. + return (iov);
  2583. + } else
  2584. + return (NULL);
  2585. + } else {
  2586. + iov++, iol--;
  2587. + }
  2588. + }
  2589. +
  2590. + return (NULL);
  2591. +}
  2592. +
  2593. +EXPORT_SYMBOL(cuio_copyback);
  2594. +EXPORT_SYMBOL(cuio_copydata);
  2595. +EXPORT_SYMBOL(cuio_getptr);
  2596. +
  2597. +
  2598. +static void
  2599. +skb_copy_bits_back(struct sk_buff *skb, int offset, caddr_t cp, int len)
  2600. +{
  2601. + int i;
  2602. + if (offset < skb_headlen(skb)) {
  2603. + memcpy(skb->data + offset, cp, min_t(int, skb_headlen(skb), len));
  2604. + len -= skb_headlen(skb);
  2605. + cp += skb_headlen(skb);
  2606. + }
  2607. + offset -= skb_headlen(skb);
  2608. + for (i = 0; len > 0 && i < skb_shinfo(skb)->nr_frags; i++) {
  2609. + if (offset < skb_shinfo(skb)->frags[i].size) {
  2610. + memcpy(page_address(skb_shinfo(skb)->frags[i].page) +
  2611. + skb_shinfo(skb)->frags[i].page_offset,
  2612. + cp, min_t(int, skb_shinfo(skb)->frags[i].size, len));
  2613. + len -= skb_shinfo(skb)->frags[i].size;
  2614. + cp += skb_shinfo(skb)->frags[i].size;
  2615. + }
  2616. + offset -= skb_shinfo(skb)->frags[i].size;
  2617. + }
  2618. +}
  2619. +
  2620. +void
  2621. +crypto_copyback(int flags, caddr_t buf, int off, int size, caddr_t in)
  2622. +{
  2623. +
  2624. + if ((flags & CRYPTO_F_SKBUF) != 0)
  2625. + skb_copy_bits_back((struct sk_buff *)buf, off, in, size);
  2626. + else if ((flags & CRYPTO_F_IOV) != 0)
  2627. + cuio_copyback((struct uio *)buf, off, size, in);
  2628. + else
  2629. + bcopy(in, buf + off, size);
  2630. +}
  2631. +
  2632. +void
  2633. +crypto_copydata(int flags, caddr_t buf, int off, int size, caddr_t out)
  2634. +{
  2635. +
  2636. + if ((flags & CRYPTO_F_SKBUF) != 0)
  2637. + skb_copy_bits((struct sk_buff *)buf, off, out, size);
  2638. + else if ((flags & CRYPTO_F_IOV) != 0)
  2639. + cuio_copydata((struct uio *)buf, off, size, out);
  2640. + else
  2641. + bcopy(buf + off, out, size);
  2642. +}
  2643. +
  2644. +int
  2645. +crypto_apply(int flags, caddr_t buf, int off, int len,
  2646. + int (*f)(void *, void *, u_int), void *arg)
  2647. +{
  2648. +#if 0
  2649. + int error;
  2650. +
  2651. + if ((flags & CRYPTO_F_SKBUF) != 0)
  2652. + error = XXXXXX((struct mbuf *)buf, off, len, f, arg);
  2653. + else if ((flags & CRYPTO_F_IOV) != 0)
  2654. + error = cuio_apply((struct uio *)buf, off, len, f, arg);
  2655. + else
  2656. + error = (*f)(arg, buf + off, len);
  2657. + return (error);
  2658. +#else
  2659. + KASSERT(0, ("crypto_apply not implemented!\n"));
  2660. +#endif
  2661. + return 0;
  2662. +}
  2663. +
  2664. +EXPORT_SYMBOL(crypto_copyback);
  2665. +EXPORT_SYMBOL(crypto_copydata);
  2666. +EXPORT_SYMBOL(crypto_apply);
  2667. +
  2668. diff -Nur linux-2.6.39.orig/crypto/ocf/crypto.c linux-2.6.39/crypto/ocf/crypto.c
  2669. --- linux-2.6.39.orig/crypto/ocf/crypto.c 1970-01-01 01:00:00.000000000 +0100
  2670. +++ linux-2.6.39/crypto/ocf/crypto.c 2011-08-01 14:38:42.000000000 +0200
  2671. @@ -0,0 +1,1781 @@
  2672. +/*-
  2673. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  2674. + * Copyright (C) 2006-2010 David McCullough
  2675. + * Copyright (C) 2004-2005 Intel Corporation.
  2676. + * The license and original author are listed below.
  2677. + *
  2678. + * Redistribution and use in source and binary forms, with or without
  2679. + * Copyright (c) 2002-2006 Sam Leffler. All rights reserved.
  2680. + *
  2681. + * modification, are permitted provided that the following conditions
  2682. + * are met:
  2683. + * 1. Redistributions of source code must retain the above copyright
  2684. + * notice, this list of conditions and the following disclaimer.
  2685. + * 2. Redistributions in binary form must reproduce the above copyright
  2686. + * notice, this list of conditions and the following disclaimer in the
  2687. + * documentation and/or other materials provided with the distribution.
  2688. + *
  2689. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  2690. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  2691. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  2692. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  2693. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  2694. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  2695. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  2696. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  2697. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  2698. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  2699. + */
  2700. +
  2701. +#if 0
  2702. +#include <sys/cdefs.h>
  2703. +__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.27 2007/03/21 03:42:51 sam Exp $");
  2704. +#endif
  2705. +
  2706. +/*
  2707. + * Cryptographic Subsystem.
  2708. + *
  2709. + * This code is derived from the Openbsd Cryptographic Framework (OCF)
  2710. + * that has the copyright shown below. Very little of the original
  2711. + * code remains.
  2712. + */
  2713. +/*-
  2714. + * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
  2715. + *
  2716. + * This code was written by Angelos D. Keromytis in Athens, Greece, in
  2717. + * February 2000. Network Security Technologies Inc. (NSTI) kindly
  2718. + * supported the development of this code.
  2719. + *
  2720. + * Copyright (c) 2000, 2001 Angelos D. Keromytis
  2721. + *
  2722. + * Permission to use, copy, and modify this software with or without fee
  2723. + * is hereby granted, provided that this entire notice is included in
  2724. + * all source code copies of any software which is or includes a copy or
  2725. + * modification of this software.
  2726. + *
  2727. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
  2728. + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
  2729. + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
  2730. + * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
  2731. + * PURPOSE.
  2732. + *
  2733. +__FBSDID("$FreeBSD: src/sys/opencrypto/crypto.c,v 1.16 2005/01/07 02:29:16 imp Exp $");
  2734. + */
  2735. +
  2736. +
  2737. +#include <linux/module.h>
  2738. +#include <linux/init.h>
  2739. +#include <linux/list.h>
  2740. +#include <linux/slab.h>
  2741. +#include <linux/wait.h>
  2742. +#include <linux/sched.h>
  2743. +#include <linux/spinlock.h>
  2744. +#include <linux/version.h>
  2745. +#include <cryptodev.h>
  2746. +
  2747. +/*
  2748. + * keep track of whether or not we have been initialised, a big
  2749. + * issue if we are linked into the kernel and a driver gets started before
  2750. + * us
  2751. + */
  2752. +static int crypto_initted = 0;
  2753. +
  2754. +/*
  2755. + * Crypto drivers register themselves by allocating a slot in the
  2756. + * crypto_drivers table with crypto_get_driverid() and then registering
  2757. + * each algorithm they support with crypto_register() and crypto_kregister().
  2758. + */
  2759. +
  2760. +/*
  2761. + * lock on driver table
  2762. + * we track its state as spin_is_locked does not do anything on non-SMP boxes
  2763. + */
  2764. +static spinlock_t crypto_drivers_lock;
  2765. +static int crypto_drivers_locked; /* for non-SMP boxes */
  2766. +
  2767. +#define CRYPTO_DRIVER_LOCK() \
  2768. + ({ \
  2769. + spin_lock_irqsave(&crypto_drivers_lock, d_flags); \
  2770. + crypto_drivers_locked = 1; \
  2771. + dprintk("%s,%d: DRIVER_LOCK()\n", __FILE__, __LINE__); \
  2772. + })
  2773. +#define CRYPTO_DRIVER_UNLOCK() \
  2774. + ({ \
  2775. + dprintk("%s,%d: DRIVER_UNLOCK()\n", __FILE__, __LINE__); \
  2776. + crypto_drivers_locked = 0; \
  2777. + spin_unlock_irqrestore(&crypto_drivers_lock, d_flags); \
  2778. + })
  2779. +#define CRYPTO_DRIVER_ASSERT() \
  2780. + ({ \
  2781. + if (!crypto_drivers_locked) { \
  2782. + dprintk("%s,%d: DRIVER_ASSERT!\n", __FILE__, __LINE__); \
  2783. + } \
  2784. + })
  2785. +
  2786. +/*
  2787. + * Crypto device/driver capabilities structure.
  2788. + *
  2789. + * Synchronization:
  2790. + * (d) - protected by CRYPTO_DRIVER_LOCK()
  2791. + * (q) - protected by CRYPTO_Q_LOCK()
  2792. + * Not tagged fields are read-only.
  2793. + */
  2794. +struct cryptocap {
  2795. + device_t cc_dev; /* (d) device/driver */
  2796. + u_int32_t cc_sessions; /* (d) # of sessions */
  2797. + u_int32_t cc_koperations; /* (d) # os asym operations */
  2798. + /*
  2799. + * Largest possible operator length (in bits) for each type of
  2800. + * encryption algorithm. XXX not used
  2801. + */
  2802. + u_int16_t cc_max_op_len[CRYPTO_ALGORITHM_MAX + 1];
  2803. + u_int8_t cc_alg[CRYPTO_ALGORITHM_MAX + 1];
  2804. + u_int8_t cc_kalg[CRK_ALGORITHM_MAX + 1];
  2805. +
  2806. + int cc_flags; /* (d) flags */
  2807. +#define CRYPTOCAP_F_CLEANUP 0x80000000 /* needs resource cleanup */
  2808. + int cc_qblocked; /* (q) symmetric q blocked */
  2809. + int cc_kqblocked; /* (q) asymmetric q blocked */
  2810. +
  2811. + int cc_unqblocked; /* (q) symmetric q blocked */
  2812. + int cc_unkqblocked; /* (q) asymmetric q blocked */
  2813. +};
  2814. +static struct cryptocap *crypto_drivers = NULL;
  2815. +static int crypto_drivers_num = 0;
  2816. +
  2817. +/*
  2818. + * There are two queues for crypto requests; one for symmetric (e.g.
  2819. + * cipher) operations and one for asymmetric (e.g. MOD)operations.
  2820. + * A single mutex is used to lock access to both queues. We could
  2821. + * have one per-queue but having one simplifies handling of block/unblock
  2822. + * operations.
  2823. + */
  2824. +static int crp_sleep = 0;
  2825. +static LIST_HEAD(crp_q); /* request queues */
  2826. +static LIST_HEAD(crp_kq);
  2827. +
  2828. +static spinlock_t crypto_q_lock;
  2829. +
  2830. +int crypto_all_qblocked = 0; /* protect with Q_LOCK */
  2831. +module_param(crypto_all_qblocked, int, 0444);
  2832. +MODULE_PARM_DESC(crypto_all_qblocked, "Are all crypto queues blocked");
  2833. +
  2834. +int crypto_all_kqblocked = 0; /* protect with Q_LOCK */
  2835. +module_param(crypto_all_kqblocked, int, 0444);
  2836. +MODULE_PARM_DESC(crypto_all_kqblocked, "Are all asym crypto queues blocked");
  2837. +
  2838. +#define CRYPTO_Q_LOCK() \
  2839. + ({ \
  2840. + spin_lock_irqsave(&crypto_q_lock, q_flags); \
  2841. + dprintk("%s,%d: Q_LOCK()\n", __FILE__, __LINE__); \
  2842. + })
  2843. +#define CRYPTO_Q_UNLOCK() \
  2844. + ({ \
  2845. + dprintk("%s,%d: Q_UNLOCK()\n", __FILE__, __LINE__); \
  2846. + spin_unlock_irqrestore(&crypto_q_lock, q_flags); \
  2847. + })
  2848. +
  2849. +/*
  2850. + * There are two queues for processing completed crypto requests; one
  2851. + * for the symmetric and one for the asymmetric ops. We only need one
  2852. + * but have two to avoid type futzing (cryptop vs. cryptkop). A single
  2853. + * mutex is used to lock access to both queues. Note that this lock
  2854. + * must be separate from the lock on request queues to insure driver
  2855. + * callbacks don't generate lock order reversals.
  2856. + */
  2857. +static LIST_HEAD(crp_ret_q); /* callback queues */
  2858. +static LIST_HEAD(crp_ret_kq);
  2859. +
  2860. +static spinlock_t crypto_ret_q_lock;
  2861. +#define CRYPTO_RETQ_LOCK() \
  2862. + ({ \
  2863. + spin_lock_irqsave(&crypto_ret_q_lock, r_flags); \
  2864. + dprintk("%s,%d: RETQ_LOCK\n", __FILE__, __LINE__); \
  2865. + })
  2866. +#define CRYPTO_RETQ_UNLOCK() \
  2867. + ({ \
  2868. + dprintk("%s,%d: RETQ_UNLOCK\n", __FILE__, __LINE__); \
  2869. + spin_unlock_irqrestore(&crypto_ret_q_lock, r_flags); \
  2870. + })
  2871. +#define CRYPTO_RETQ_EMPTY() (list_empty(&crp_ret_q) && list_empty(&crp_ret_kq))
  2872. +
  2873. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  2874. +static kmem_cache_t *cryptop_zone;
  2875. +static kmem_cache_t *cryptodesc_zone;
  2876. +#else
  2877. +static struct kmem_cache *cryptop_zone;
  2878. +static struct kmem_cache *cryptodesc_zone;
  2879. +#endif
  2880. +
  2881. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
  2882. +#include <linux/sched.h>
  2883. +#define kill_proc(p,s,v) send_sig(s,find_task_by_vpid(p),0)
  2884. +#endif
  2885. +
  2886. +#define debug crypto_debug
  2887. +int crypto_debug = 0;
  2888. +module_param(crypto_debug, int, 0644);
  2889. +MODULE_PARM_DESC(crypto_debug, "Enable debug");
  2890. +EXPORT_SYMBOL(crypto_debug);
  2891. +
  2892. +/*
  2893. + * Maximum number of outstanding crypto requests before we start
  2894. + * failing requests. We need this to prevent DOS when too many
  2895. + * requests are arriving for us to keep up. Otherwise we will
  2896. + * run the system out of memory. Since crypto is slow, we are
  2897. + * usually the bottleneck that needs to say, enough is enough.
  2898. + *
  2899. + * We cannot print errors when this condition occurs, we are already too
  2900. + * slow, printing anything will just kill us
  2901. + */
  2902. +
  2903. +static int crypto_q_cnt = 0;
  2904. +module_param(crypto_q_cnt, int, 0444);
  2905. +MODULE_PARM_DESC(crypto_q_cnt,
  2906. + "Current number of outstanding crypto requests");
  2907. +
  2908. +static int crypto_q_max = 1000;
  2909. +module_param(crypto_q_max, int, 0644);
  2910. +MODULE_PARM_DESC(crypto_q_max,
  2911. + "Maximum number of outstanding crypto requests");
  2912. +
  2913. +#define bootverbose crypto_verbose
  2914. +static int crypto_verbose = 0;
  2915. +module_param(crypto_verbose, int, 0644);
  2916. +MODULE_PARM_DESC(crypto_verbose,
  2917. + "Enable verbose crypto startup");
  2918. +
  2919. +int crypto_usercrypto = 1; /* userland may do crypto reqs */
  2920. +module_param(crypto_usercrypto, int, 0644);
  2921. +MODULE_PARM_DESC(crypto_usercrypto,
  2922. + "Enable/disable user-mode access to crypto support");
  2923. +
  2924. +int crypto_userasymcrypto = 1; /* userland may do asym crypto reqs */
  2925. +module_param(crypto_userasymcrypto, int, 0644);
  2926. +MODULE_PARM_DESC(crypto_userasymcrypto,
  2927. + "Enable/disable user-mode access to asymmetric crypto support");
  2928. +
  2929. +int crypto_devallowsoft = 0; /* only use hardware crypto */
  2930. +module_param(crypto_devallowsoft, int, 0644);
  2931. +MODULE_PARM_DESC(crypto_devallowsoft,
  2932. + "Enable/disable use of software crypto support");
  2933. +
  2934. +/*
  2935. + * This parameter controls the maximum number of crypto operations to
  2936. + * do consecutively in the crypto kernel thread before scheduling to allow
  2937. + * other processes to run. Without it, it is possible to get into a
  2938. + * situation where the crypto thread never allows any other processes to run.
  2939. + * Default to 1000 which should be less than one second.
  2940. + */
  2941. +static int crypto_max_loopcount = 1000;
  2942. +module_param(crypto_max_loopcount, int, 0644);
  2943. +MODULE_PARM_DESC(crypto_max_loopcount,
  2944. + "Maximum number of crypto ops to do before yielding to other processes");
  2945. +
  2946. +static pid_t cryptoproc = (pid_t) -1;
  2947. +static struct completion cryptoproc_exited;
  2948. +static DECLARE_WAIT_QUEUE_HEAD(cryptoproc_wait);
  2949. +static pid_t cryptoretproc = (pid_t) -1;
  2950. +static struct completion cryptoretproc_exited;
  2951. +static DECLARE_WAIT_QUEUE_HEAD(cryptoretproc_wait);
  2952. +
  2953. +static int crypto_proc(void *arg);
  2954. +static int crypto_ret_proc(void *arg);
  2955. +static int crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint);
  2956. +static int crypto_kinvoke(struct cryptkop *krp, int flags);
  2957. +static void crypto_exit(void);
  2958. +static int crypto_init(void);
  2959. +
  2960. +static struct cryptostats cryptostats;
  2961. +
  2962. +static struct cryptocap *
  2963. +crypto_checkdriver(u_int32_t hid)
  2964. +{
  2965. + if (crypto_drivers == NULL)
  2966. + return NULL;
  2967. + return (hid >= crypto_drivers_num ? NULL : &crypto_drivers[hid]);
  2968. +}
  2969. +
  2970. +/*
  2971. + * Compare a driver's list of supported algorithms against another
  2972. + * list; return non-zero if all algorithms are supported.
  2973. + */
  2974. +static int
  2975. +driver_suitable(const struct cryptocap *cap, const struct cryptoini *cri)
  2976. +{
  2977. + const struct cryptoini *cr;
  2978. +
  2979. + /* See if all the algorithms are supported. */
  2980. + for (cr = cri; cr; cr = cr->cri_next)
  2981. + if (cap->cc_alg[cr->cri_alg] == 0)
  2982. + return 0;
  2983. + return 1;
  2984. +}
  2985. +
  2986. +/*
  2987. + * Select a driver for a new session that supports the specified
  2988. + * algorithms and, optionally, is constrained according to the flags.
  2989. + * The algorithm we use here is pretty stupid; just use the
  2990. + * first driver that supports all the algorithms we need. If there
  2991. + * are multiple drivers we choose the driver with the fewest active
  2992. + * sessions. We prefer hardware-backed drivers to software ones.
  2993. + *
  2994. + * XXX We need more smarts here (in real life too, but that's
  2995. + * XXX another story altogether).
  2996. + */
  2997. +static struct cryptocap *
  2998. +crypto_select_driver(const struct cryptoini *cri, int flags)
  2999. +{
  3000. + struct cryptocap *cap, *best;
  3001. + int match, hid;
  3002. +
  3003. + CRYPTO_DRIVER_ASSERT();
  3004. +
  3005. + /*
  3006. + * Look first for hardware crypto devices if permitted.
  3007. + */
  3008. + if (flags & CRYPTOCAP_F_HARDWARE)
  3009. + match = CRYPTOCAP_F_HARDWARE;
  3010. + else
  3011. + match = CRYPTOCAP_F_SOFTWARE;
  3012. + best = NULL;
  3013. +again:
  3014. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  3015. + cap = &crypto_drivers[hid];
  3016. + /*
  3017. + * If it's not initialized, is in the process of
  3018. + * going away, or is not appropriate (hardware
  3019. + * or software based on match), then skip.
  3020. + */
  3021. + if (cap->cc_dev == NULL ||
  3022. + (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
  3023. + (cap->cc_flags & match) == 0)
  3024. + continue;
  3025. +
  3026. + /* verify all the algorithms are supported. */
  3027. + if (driver_suitable(cap, cri)) {
  3028. + if (best == NULL ||
  3029. + cap->cc_sessions < best->cc_sessions)
  3030. + best = cap;
  3031. + }
  3032. + }
  3033. + if (best != NULL)
  3034. + return best;
  3035. + if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
  3036. + /* sort of an Algol 68-style for loop */
  3037. + match = CRYPTOCAP_F_SOFTWARE;
  3038. + goto again;
  3039. + }
  3040. + return best;
  3041. +}
  3042. +
  3043. +/*
  3044. + * Create a new session. The crid argument specifies a crypto
  3045. + * driver to use or constraints on a driver to select (hardware
  3046. + * only, software only, either). Whatever driver is selected
  3047. + * must be capable of the requested crypto algorithms.
  3048. + */
  3049. +int
  3050. +crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int crid)
  3051. +{
  3052. + struct cryptocap *cap;
  3053. + u_int32_t hid, lid;
  3054. + int err;
  3055. + unsigned long d_flags;
  3056. +
  3057. + CRYPTO_DRIVER_LOCK();
  3058. + if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
  3059. + /*
  3060. + * Use specified driver; verify it is capable.
  3061. + */
  3062. + cap = crypto_checkdriver(crid);
  3063. + if (cap != NULL && !driver_suitable(cap, cri))
  3064. + cap = NULL;
  3065. + } else {
  3066. + /*
  3067. + * No requested driver; select based on crid flags.
  3068. + */
  3069. + cap = crypto_select_driver(cri, crid);
  3070. + /*
  3071. + * if NULL then can't do everything in one session.
  3072. + * XXX Fix this. We need to inject a "virtual" session
  3073. + * XXX layer right about here.
  3074. + */
  3075. + }
  3076. + if (cap != NULL) {
  3077. + /* Call the driver initialization routine. */
  3078. + hid = cap - crypto_drivers;
  3079. + lid = hid; /* Pass the driver ID. */
  3080. + cap->cc_sessions++;
  3081. + CRYPTO_DRIVER_UNLOCK();
  3082. + err = CRYPTODEV_NEWSESSION(cap->cc_dev, &lid, cri);
  3083. + CRYPTO_DRIVER_LOCK();
  3084. + if (err == 0) {
  3085. + (*sid) = (cap->cc_flags & 0xff000000)
  3086. + | (hid & 0x00ffffff);
  3087. + (*sid) <<= 32;
  3088. + (*sid) |= (lid & 0xffffffff);
  3089. + } else
  3090. + cap->cc_sessions--;
  3091. + } else
  3092. + err = EINVAL;
  3093. + CRYPTO_DRIVER_UNLOCK();
  3094. + return err;
  3095. +}
  3096. +
  3097. +static void
  3098. +crypto_remove(struct cryptocap *cap)
  3099. +{
  3100. + CRYPTO_DRIVER_ASSERT();
  3101. + if (cap->cc_sessions == 0 && cap->cc_koperations == 0)
  3102. + bzero(cap, sizeof(*cap));
  3103. +}
  3104. +
  3105. +/*
  3106. + * Delete an existing session (or a reserved session on an unregistered
  3107. + * driver).
  3108. + */
  3109. +int
  3110. +crypto_freesession(u_int64_t sid)
  3111. +{
  3112. + struct cryptocap *cap;
  3113. + u_int32_t hid;
  3114. + int err = 0;
  3115. + unsigned long d_flags;
  3116. +
  3117. + dprintk("%s()\n", __FUNCTION__);
  3118. + CRYPTO_DRIVER_LOCK();
  3119. +
  3120. + if (crypto_drivers == NULL) {
  3121. + err = EINVAL;
  3122. + goto done;
  3123. + }
  3124. +
  3125. + /* Determine two IDs. */
  3126. + hid = CRYPTO_SESID2HID(sid);
  3127. +
  3128. + if (hid >= crypto_drivers_num) {
  3129. + dprintk("%s - INVALID DRIVER NUM %d\n", __FUNCTION__, hid);
  3130. + err = ENOENT;
  3131. + goto done;
  3132. + }
  3133. + cap = &crypto_drivers[hid];
  3134. +
  3135. + if (cap->cc_dev) {
  3136. + CRYPTO_DRIVER_UNLOCK();
  3137. + /* Call the driver cleanup routine, if available, unlocked. */
  3138. + err = CRYPTODEV_FREESESSION(cap->cc_dev, sid);
  3139. + CRYPTO_DRIVER_LOCK();
  3140. + }
  3141. +
  3142. + if (cap->cc_sessions)
  3143. + cap->cc_sessions--;
  3144. +
  3145. + if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
  3146. + crypto_remove(cap);
  3147. +
  3148. +done:
  3149. + CRYPTO_DRIVER_UNLOCK();
  3150. + return err;
  3151. +}
  3152. +
  3153. +/*
  3154. + * Return an unused driver id. Used by drivers prior to registering
  3155. + * support for the algorithms they handle.
  3156. + */
  3157. +int32_t
  3158. +crypto_get_driverid(device_t dev, int flags)
  3159. +{
  3160. + struct cryptocap *newdrv;
  3161. + int i;
  3162. + unsigned long d_flags;
  3163. +
  3164. + if ((flags & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
  3165. + printf("%s: no flags specified when registering driver\n",
  3166. + device_get_nameunit(dev));
  3167. + return -1;
  3168. + }
  3169. +
  3170. + CRYPTO_DRIVER_LOCK();
  3171. +
  3172. + for (i = 0; i < crypto_drivers_num; i++) {
  3173. + if (crypto_drivers[i].cc_dev == NULL &&
  3174. + (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP) == 0) {
  3175. + break;
  3176. + }
  3177. + }
  3178. +
  3179. + /* Out of entries, allocate some more. */
  3180. + if (i == crypto_drivers_num) {
  3181. + /* Be careful about wrap-around. */
  3182. + if (2 * crypto_drivers_num <= crypto_drivers_num) {
  3183. + CRYPTO_DRIVER_UNLOCK();
  3184. + printk("crypto: driver count wraparound!\n");
  3185. + return -1;
  3186. + }
  3187. +
  3188. + newdrv = kmalloc(2 * crypto_drivers_num * sizeof(struct cryptocap),
  3189. + GFP_KERNEL);
  3190. + if (newdrv == NULL) {
  3191. + CRYPTO_DRIVER_UNLOCK();
  3192. + printk("crypto: no space to expand driver table!\n");
  3193. + return -1;
  3194. + }
  3195. +
  3196. + memcpy(newdrv, crypto_drivers,
  3197. + crypto_drivers_num * sizeof(struct cryptocap));
  3198. + memset(&newdrv[crypto_drivers_num], 0,
  3199. + crypto_drivers_num * sizeof(struct cryptocap));
  3200. +
  3201. + crypto_drivers_num *= 2;
  3202. +
  3203. + kfree(crypto_drivers);
  3204. + crypto_drivers = newdrv;
  3205. + }
  3206. +
  3207. + /* NB: state is zero'd on free */
  3208. + crypto_drivers[i].cc_sessions = 1; /* Mark */
  3209. + crypto_drivers[i].cc_dev = dev;
  3210. + crypto_drivers[i].cc_flags = flags;
  3211. + if (bootverbose)
  3212. + printf("crypto: assign %s driver id %u, flags %u\n",
  3213. + device_get_nameunit(dev), i, flags);
  3214. +
  3215. + CRYPTO_DRIVER_UNLOCK();
  3216. +
  3217. + return i;
  3218. +}
  3219. +
  3220. +/*
  3221. + * Lookup a driver by name. We match against the full device
  3222. + * name and unit, and against just the name. The latter gives
  3223. + * us a simple widlcarding by device name. On success return the
  3224. + * driver/hardware identifier; otherwise return -1.
  3225. + */
  3226. +int
  3227. +crypto_find_driver(const char *match)
  3228. +{
  3229. + int i, len = strlen(match);
  3230. + unsigned long d_flags;
  3231. +
  3232. + CRYPTO_DRIVER_LOCK();
  3233. + for (i = 0; i < crypto_drivers_num; i++) {
  3234. + device_t dev = crypto_drivers[i].cc_dev;
  3235. + if (dev == NULL ||
  3236. + (crypto_drivers[i].cc_flags & CRYPTOCAP_F_CLEANUP))
  3237. + continue;
  3238. + if (strncmp(match, device_get_nameunit(dev), len) == 0 ||
  3239. + strncmp(match, device_get_name(dev), len) == 0)
  3240. + break;
  3241. + }
  3242. + CRYPTO_DRIVER_UNLOCK();
  3243. + return i < crypto_drivers_num ? i : -1;
  3244. +}
  3245. +
  3246. +/*
  3247. + * Return the device_t for the specified driver or NULL
  3248. + * if the driver identifier is invalid.
  3249. + */
  3250. +device_t
  3251. +crypto_find_device_byhid(int hid)
  3252. +{
  3253. + struct cryptocap *cap = crypto_checkdriver(hid);
  3254. + return cap != NULL ? cap->cc_dev : NULL;
  3255. +}
  3256. +
  3257. +/*
  3258. + * Return the device/driver capabilities.
  3259. + */
  3260. +int
  3261. +crypto_getcaps(int hid)
  3262. +{
  3263. + struct cryptocap *cap = crypto_checkdriver(hid);
  3264. + return cap != NULL ? cap->cc_flags : 0;
  3265. +}
  3266. +
  3267. +/*
  3268. + * Register support for a key-related algorithm. This routine
  3269. + * is called once for each algorithm supported a driver.
  3270. + */
  3271. +int
  3272. +crypto_kregister(u_int32_t driverid, int kalg, u_int32_t flags)
  3273. +{
  3274. + struct cryptocap *cap;
  3275. + int err;
  3276. + unsigned long d_flags;
  3277. +
  3278. + dprintk("%s()\n", __FUNCTION__);
  3279. + CRYPTO_DRIVER_LOCK();
  3280. +
  3281. + cap = crypto_checkdriver(driverid);
  3282. + if (cap != NULL &&
  3283. + (CRK_ALGORITM_MIN <= kalg && kalg <= CRK_ALGORITHM_MAX)) {
  3284. + /*
  3285. + * XXX Do some performance testing to determine placing.
  3286. + * XXX We probably need an auxiliary data structure that
  3287. + * XXX describes relative performances.
  3288. + */
  3289. +
  3290. + cap->cc_kalg[kalg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
  3291. + if (bootverbose)
  3292. + printf("crypto: %s registers key alg %u flags %u\n"
  3293. + , device_get_nameunit(cap->cc_dev)
  3294. + , kalg
  3295. + , flags
  3296. + );
  3297. + err = 0;
  3298. + } else
  3299. + err = EINVAL;
  3300. +
  3301. + CRYPTO_DRIVER_UNLOCK();
  3302. + return err;
  3303. +}
  3304. +
  3305. +/*
  3306. + * Register support for a non-key-related algorithm. This routine
  3307. + * is called once for each such algorithm supported by a driver.
  3308. + */
  3309. +int
  3310. +crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
  3311. + u_int32_t flags)
  3312. +{
  3313. + struct cryptocap *cap;
  3314. + int err;
  3315. + unsigned long d_flags;
  3316. +
  3317. + dprintk("%s(id=0x%x, alg=%d, maxoplen=%d, flags=0x%x)\n", __FUNCTION__,
  3318. + driverid, alg, maxoplen, flags);
  3319. +
  3320. + CRYPTO_DRIVER_LOCK();
  3321. +
  3322. + cap = crypto_checkdriver(driverid);
  3323. + /* NB: algorithms are in the range [1..max] */
  3324. + if (cap != NULL &&
  3325. + (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX)) {
  3326. + /*
  3327. + * XXX Do some performance testing to determine placing.
  3328. + * XXX We probably need an auxiliary data structure that
  3329. + * XXX describes relative performances.
  3330. + */
  3331. +
  3332. + cap->cc_alg[alg] = flags | CRYPTO_ALG_FLAG_SUPPORTED;
  3333. + cap->cc_max_op_len[alg] = maxoplen;
  3334. + if (bootverbose)
  3335. + printf("crypto: %s registers alg %u flags %u maxoplen %u\n"
  3336. + , device_get_nameunit(cap->cc_dev)
  3337. + , alg
  3338. + , flags
  3339. + , maxoplen
  3340. + );
  3341. + cap->cc_sessions = 0; /* Unmark */
  3342. + err = 0;
  3343. + } else
  3344. + err = EINVAL;
  3345. +
  3346. + CRYPTO_DRIVER_UNLOCK();
  3347. + return err;
  3348. +}
  3349. +
  3350. +static void
  3351. +driver_finis(struct cryptocap *cap)
  3352. +{
  3353. + u_int32_t ses, kops;
  3354. +
  3355. + CRYPTO_DRIVER_ASSERT();
  3356. +
  3357. + ses = cap->cc_sessions;
  3358. + kops = cap->cc_koperations;
  3359. + bzero(cap, sizeof(*cap));
  3360. + if (ses != 0 || kops != 0) {
  3361. + /*
  3362. + * If there are pending sessions,
  3363. + * just mark as invalid.
  3364. + */
  3365. + cap->cc_flags |= CRYPTOCAP_F_CLEANUP;
  3366. + cap->cc_sessions = ses;
  3367. + cap->cc_koperations = kops;
  3368. + }
  3369. +}
  3370. +
  3371. +/*
  3372. + * Unregister a crypto driver. If there are pending sessions using it,
  3373. + * leave enough information around so that subsequent calls using those
  3374. + * sessions will correctly detect the driver has been unregistered and
  3375. + * reroute requests.
  3376. + */
  3377. +int
  3378. +crypto_unregister(u_int32_t driverid, int alg)
  3379. +{
  3380. + struct cryptocap *cap;
  3381. + int i, err;
  3382. + unsigned long d_flags;
  3383. +
  3384. + dprintk("%s()\n", __FUNCTION__);
  3385. + CRYPTO_DRIVER_LOCK();
  3386. +
  3387. + cap = crypto_checkdriver(driverid);
  3388. + if (cap != NULL &&
  3389. + (CRYPTO_ALGORITHM_MIN <= alg && alg <= CRYPTO_ALGORITHM_MAX) &&
  3390. + cap->cc_alg[alg] != 0) {
  3391. + cap->cc_alg[alg] = 0;
  3392. + cap->cc_max_op_len[alg] = 0;
  3393. +
  3394. + /* Was this the last algorithm ? */
  3395. + for (i = 1; i <= CRYPTO_ALGORITHM_MAX; i++)
  3396. + if (cap->cc_alg[i] != 0)
  3397. + break;
  3398. +
  3399. + if (i == CRYPTO_ALGORITHM_MAX + 1)
  3400. + driver_finis(cap);
  3401. + err = 0;
  3402. + } else
  3403. + err = EINVAL;
  3404. + CRYPTO_DRIVER_UNLOCK();
  3405. + return err;
  3406. +}
  3407. +
  3408. +/*
  3409. + * Unregister all algorithms associated with a crypto driver.
  3410. + * If there are pending sessions using it, leave enough information
  3411. + * around so that subsequent calls using those sessions will
  3412. + * correctly detect the driver has been unregistered and reroute
  3413. + * requests.
  3414. + */
  3415. +int
  3416. +crypto_unregister_all(u_int32_t driverid)
  3417. +{
  3418. + struct cryptocap *cap;
  3419. + int err;
  3420. + unsigned long d_flags;
  3421. +
  3422. + dprintk("%s()\n", __FUNCTION__);
  3423. + CRYPTO_DRIVER_LOCK();
  3424. + cap = crypto_checkdriver(driverid);
  3425. + if (cap != NULL) {
  3426. + driver_finis(cap);
  3427. + err = 0;
  3428. + } else
  3429. + err = EINVAL;
  3430. + CRYPTO_DRIVER_UNLOCK();
  3431. +
  3432. + return err;
  3433. +}
  3434. +
  3435. +/*
  3436. + * Clear blockage on a driver. The what parameter indicates whether
  3437. + * the driver is now ready for cryptop's and/or cryptokop's.
  3438. + */
  3439. +int
  3440. +crypto_unblock(u_int32_t driverid, int what)
  3441. +{
  3442. + struct cryptocap *cap;
  3443. + int err;
  3444. + unsigned long q_flags;
  3445. +
  3446. + CRYPTO_Q_LOCK();
  3447. + cap = crypto_checkdriver(driverid);
  3448. + if (cap != NULL) {
  3449. + if (what & CRYPTO_SYMQ) {
  3450. + cap->cc_qblocked = 0;
  3451. + cap->cc_unqblocked = 0;
  3452. + crypto_all_qblocked = 0;
  3453. + }
  3454. + if (what & CRYPTO_ASYMQ) {
  3455. + cap->cc_kqblocked = 0;
  3456. + cap->cc_unkqblocked = 0;
  3457. + crypto_all_kqblocked = 0;
  3458. + }
  3459. + if (crp_sleep)
  3460. + wake_up_interruptible(&cryptoproc_wait);
  3461. + err = 0;
  3462. + } else
  3463. + err = EINVAL;
  3464. + CRYPTO_Q_UNLOCK(); //DAVIDM should this be a driver lock
  3465. +
  3466. + return err;
  3467. +}
  3468. +
  3469. +/*
  3470. + * Add a crypto request to a queue, to be processed by the kernel thread.
  3471. + */
  3472. +int
  3473. +crypto_dispatch(struct cryptop *crp)
  3474. +{
  3475. + struct cryptocap *cap;
  3476. + int result = -1;
  3477. + unsigned long q_flags;
  3478. +
  3479. + dprintk("%s()\n", __FUNCTION__);
  3480. +
  3481. + cryptostats.cs_ops++;
  3482. +
  3483. + CRYPTO_Q_LOCK();
  3484. + if (crypto_q_cnt >= crypto_q_max) {
  3485. + CRYPTO_Q_UNLOCK();
  3486. + cryptostats.cs_drops++;
  3487. + return ENOMEM;
  3488. + }
  3489. + crypto_q_cnt++;
  3490. +
  3491. + /* make sure we are starting a fresh run on this crp. */
  3492. + crp->crp_flags &= ~CRYPTO_F_DONE;
  3493. + crp->crp_etype = 0;
  3494. +
  3495. + /*
  3496. + * Caller marked the request to be processed immediately; dispatch
  3497. + * it directly to the driver unless the driver is currently blocked.
  3498. + */
  3499. + if ((crp->crp_flags & CRYPTO_F_BATCH) == 0) {
  3500. + int hid = CRYPTO_SESID2HID(crp->crp_sid);
  3501. + cap = crypto_checkdriver(hid);
  3502. + /* Driver cannot disappear when there is an active session. */
  3503. + KASSERT(cap != NULL, ("%s: Driver disappeared.", __func__));
  3504. + if (!cap->cc_qblocked) {
  3505. + crypto_all_qblocked = 0;
  3506. + crypto_drivers[hid].cc_unqblocked = 1;
  3507. + CRYPTO_Q_UNLOCK();
  3508. + result = crypto_invoke(cap, crp, 0);
  3509. + CRYPTO_Q_LOCK();
  3510. + if (result == ERESTART)
  3511. + if (crypto_drivers[hid].cc_unqblocked)
  3512. + crypto_drivers[hid].cc_qblocked = 1;
  3513. + crypto_drivers[hid].cc_unqblocked = 0;
  3514. + }
  3515. + }
  3516. + if (result == ERESTART) {
  3517. + /*
  3518. + * The driver ran out of resources, mark the
  3519. + * driver ``blocked'' for cryptop's and put
  3520. + * the request back in the queue. It would
  3521. + * best to put the request back where we got
  3522. + * it but that's hard so for now we put it
  3523. + * at the front. This should be ok; putting
  3524. + * it at the end does not work.
  3525. + */
  3526. + list_add(&crp->crp_next, &crp_q);
  3527. + cryptostats.cs_blocks++;
  3528. + result = 0;
  3529. + } else if (result == -1) {
  3530. + TAILQ_INSERT_TAIL(&crp_q, crp, crp_next);
  3531. + result = 0;
  3532. + }
  3533. + if (crp_sleep)
  3534. + wake_up_interruptible(&cryptoproc_wait);
  3535. + CRYPTO_Q_UNLOCK();
  3536. + return result;
  3537. +}
  3538. +
  3539. +/*
  3540. + * Add an asymetric crypto request to a queue,
  3541. + * to be processed by the kernel thread.
  3542. + */
  3543. +int
  3544. +crypto_kdispatch(struct cryptkop *krp)
  3545. +{
  3546. + int error;
  3547. + unsigned long q_flags;
  3548. +
  3549. + cryptostats.cs_kops++;
  3550. +
  3551. + error = crypto_kinvoke(krp, krp->krp_crid);
  3552. + if (error == ERESTART) {
  3553. + CRYPTO_Q_LOCK();
  3554. + TAILQ_INSERT_TAIL(&crp_kq, krp, krp_next);
  3555. + if (crp_sleep)
  3556. + wake_up_interruptible(&cryptoproc_wait);
  3557. + CRYPTO_Q_UNLOCK();
  3558. + error = 0;
  3559. + }
  3560. + return error;
  3561. +}
  3562. +
  3563. +/*
  3564. + * Verify a driver is suitable for the specified operation.
  3565. + */
  3566. +static __inline int
  3567. +kdriver_suitable(const struct cryptocap *cap, const struct cryptkop *krp)
  3568. +{
  3569. + return (cap->cc_kalg[krp->krp_op] & CRYPTO_ALG_FLAG_SUPPORTED) != 0;
  3570. +}
  3571. +
  3572. +/*
  3573. + * Select a driver for an asym operation. The driver must
  3574. + * support the necessary algorithm. The caller can constrain
  3575. + * which device is selected with the flags parameter. The
  3576. + * algorithm we use here is pretty stupid; just use the first
  3577. + * driver that supports the algorithms we need. If there are
  3578. + * multiple suitable drivers we choose the driver with the
  3579. + * fewest active operations. We prefer hardware-backed
  3580. + * drivers to software ones when either may be used.
  3581. + */
  3582. +static struct cryptocap *
  3583. +crypto_select_kdriver(const struct cryptkop *krp, int flags)
  3584. +{
  3585. + struct cryptocap *cap, *best, *blocked;
  3586. + int match, hid;
  3587. +
  3588. + CRYPTO_DRIVER_ASSERT();
  3589. +
  3590. + /*
  3591. + * Look first for hardware crypto devices if permitted.
  3592. + */
  3593. + if (flags & CRYPTOCAP_F_HARDWARE)
  3594. + match = CRYPTOCAP_F_HARDWARE;
  3595. + else
  3596. + match = CRYPTOCAP_F_SOFTWARE;
  3597. + best = NULL;
  3598. + blocked = NULL;
  3599. +again:
  3600. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  3601. + cap = &crypto_drivers[hid];
  3602. + /*
  3603. + * If it's not initialized, is in the process of
  3604. + * going away, or is not appropriate (hardware
  3605. + * or software based on match), then skip.
  3606. + */
  3607. + if (cap->cc_dev == NULL ||
  3608. + (cap->cc_flags & CRYPTOCAP_F_CLEANUP) ||
  3609. + (cap->cc_flags & match) == 0)
  3610. + continue;
  3611. +
  3612. + /* verify all the algorithms are supported. */
  3613. + if (kdriver_suitable(cap, krp)) {
  3614. + if (best == NULL ||
  3615. + cap->cc_koperations < best->cc_koperations)
  3616. + best = cap;
  3617. + }
  3618. + }
  3619. + if (best != NULL)
  3620. + return best;
  3621. + if (match == CRYPTOCAP_F_HARDWARE && (flags & CRYPTOCAP_F_SOFTWARE)) {
  3622. + /* sort of an Algol 68-style for loop */
  3623. + match = CRYPTOCAP_F_SOFTWARE;
  3624. + goto again;
  3625. + }
  3626. + return best;
  3627. +}
  3628. +
  3629. +/*
  3630. + * Dispatch an assymetric crypto request.
  3631. + */
  3632. +static int
  3633. +crypto_kinvoke(struct cryptkop *krp, int crid)
  3634. +{
  3635. + struct cryptocap *cap = NULL;
  3636. + int error;
  3637. + unsigned long d_flags;
  3638. +
  3639. + KASSERT(krp != NULL, ("%s: krp == NULL", __func__));
  3640. + KASSERT(krp->krp_callback != NULL,
  3641. + ("%s: krp->crp_callback == NULL", __func__));
  3642. +
  3643. + CRYPTO_DRIVER_LOCK();
  3644. + if ((crid & (CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE)) == 0) {
  3645. + cap = crypto_checkdriver(crid);
  3646. + if (cap != NULL) {
  3647. + /*
  3648. + * Driver present, it must support the necessary
  3649. + * algorithm and, if s/w drivers are excluded,
  3650. + * it must be registered as hardware-backed.
  3651. + */
  3652. + if (!kdriver_suitable(cap, krp) ||
  3653. + (!crypto_devallowsoft &&
  3654. + (cap->cc_flags & CRYPTOCAP_F_HARDWARE) == 0))
  3655. + cap = NULL;
  3656. + }
  3657. + } else {
  3658. + /*
  3659. + * No requested driver; select based on crid flags.
  3660. + */
  3661. + if (!crypto_devallowsoft) /* NB: disallow s/w drivers */
  3662. + crid &= ~CRYPTOCAP_F_SOFTWARE;
  3663. + cap = crypto_select_kdriver(krp, crid);
  3664. + }
  3665. + if (cap != NULL && !cap->cc_kqblocked) {
  3666. + krp->krp_hid = cap - crypto_drivers;
  3667. + cap->cc_koperations++;
  3668. + CRYPTO_DRIVER_UNLOCK();
  3669. + error = CRYPTODEV_KPROCESS(cap->cc_dev, krp, 0);
  3670. + CRYPTO_DRIVER_LOCK();
  3671. + if (error == ERESTART) {
  3672. + cap->cc_koperations--;
  3673. + CRYPTO_DRIVER_UNLOCK();
  3674. + return (error);
  3675. + }
  3676. + /* return the actual device used */
  3677. + krp->krp_crid = krp->krp_hid;
  3678. + } else {
  3679. + /*
  3680. + * NB: cap is !NULL if device is blocked; in
  3681. + * that case return ERESTART so the operation
  3682. + * is resubmitted if possible.
  3683. + */
  3684. + error = (cap == NULL) ? ENODEV : ERESTART;
  3685. + }
  3686. + CRYPTO_DRIVER_UNLOCK();
  3687. +
  3688. + if (error) {
  3689. + krp->krp_status = error;
  3690. + crypto_kdone(krp);
  3691. + }
  3692. + return 0;
  3693. +}
  3694. +
  3695. +
  3696. +/*
  3697. + * Dispatch a crypto request to the appropriate crypto devices.
  3698. + */
  3699. +static int
  3700. +crypto_invoke(struct cryptocap *cap, struct cryptop *crp, int hint)
  3701. +{
  3702. + KASSERT(crp != NULL, ("%s: crp == NULL", __func__));
  3703. + KASSERT(crp->crp_callback != NULL,
  3704. + ("%s: crp->crp_callback == NULL", __func__));
  3705. + KASSERT(crp->crp_desc != NULL, ("%s: crp->crp_desc == NULL", __func__));
  3706. +
  3707. + dprintk("%s()\n", __FUNCTION__);
  3708. +
  3709. +#ifdef CRYPTO_TIMING
  3710. + if (crypto_timing)
  3711. + crypto_tstat(&cryptostats.cs_invoke, &crp->crp_tstamp);
  3712. +#endif
  3713. + if (cap->cc_flags & CRYPTOCAP_F_CLEANUP) {
  3714. + struct cryptodesc *crd;
  3715. + u_int64_t nid;
  3716. +
  3717. + /*
  3718. + * Driver has unregistered; migrate the session and return
  3719. + * an error to the caller so they'll resubmit the op.
  3720. + *
  3721. + * XXX: What if there are more already queued requests for this
  3722. + * session?
  3723. + */
  3724. + crypto_freesession(crp->crp_sid);
  3725. +
  3726. + for (crd = crp->crp_desc; crd->crd_next; crd = crd->crd_next)
  3727. + crd->CRD_INI.cri_next = &(crd->crd_next->CRD_INI);
  3728. +
  3729. + /* XXX propagate flags from initial session? */
  3730. + if (crypto_newsession(&nid, &(crp->crp_desc->CRD_INI),
  3731. + CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE) == 0)
  3732. + crp->crp_sid = nid;
  3733. +
  3734. + crp->crp_etype = EAGAIN;
  3735. + crypto_done(crp);
  3736. + return 0;
  3737. + } else {
  3738. + /*
  3739. + * Invoke the driver to process the request.
  3740. + */
  3741. + return CRYPTODEV_PROCESS(cap->cc_dev, crp, hint);
  3742. + }
  3743. +}
  3744. +
  3745. +/*
  3746. + * Release a set of crypto descriptors.
  3747. + */
  3748. +void
  3749. +crypto_freereq(struct cryptop *crp)
  3750. +{
  3751. + struct cryptodesc *crd;
  3752. +
  3753. + if (crp == NULL)
  3754. + return;
  3755. +
  3756. +#ifdef DIAGNOSTIC
  3757. + {
  3758. + struct cryptop *crp2;
  3759. + unsigned long q_flags;
  3760. +
  3761. + CRYPTO_Q_LOCK();
  3762. + TAILQ_FOREACH(crp2, &crp_q, crp_next) {
  3763. + KASSERT(crp2 != crp,
  3764. + ("Freeing cryptop from the crypto queue (%p).",
  3765. + crp));
  3766. + }
  3767. + CRYPTO_Q_UNLOCK();
  3768. + CRYPTO_RETQ_LOCK();
  3769. + TAILQ_FOREACH(crp2, &crp_ret_q, crp_next) {
  3770. + KASSERT(crp2 != crp,
  3771. + ("Freeing cryptop from the return queue (%p).",
  3772. + crp));
  3773. + }
  3774. + CRYPTO_RETQ_UNLOCK();
  3775. + }
  3776. +#endif
  3777. +
  3778. + while ((crd = crp->crp_desc) != NULL) {
  3779. + crp->crp_desc = crd->crd_next;
  3780. + kmem_cache_free(cryptodesc_zone, crd);
  3781. + }
  3782. + kmem_cache_free(cryptop_zone, crp);
  3783. +}
  3784. +
  3785. +/*
  3786. + * Acquire a set of crypto descriptors.
  3787. + */
  3788. +struct cryptop *
  3789. +crypto_getreq(int num)
  3790. +{
  3791. + struct cryptodesc *crd;
  3792. + struct cryptop *crp;
  3793. +
  3794. + crp = kmem_cache_alloc(cryptop_zone, SLAB_ATOMIC);
  3795. + if (crp != NULL) {
  3796. + memset(crp, 0, sizeof(*crp));
  3797. + INIT_LIST_HEAD(&crp->crp_next);
  3798. + init_waitqueue_head(&crp->crp_waitq);
  3799. + while (num--) {
  3800. + crd = kmem_cache_alloc(cryptodesc_zone, SLAB_ATOMIC);
  3801. + if (crd == NULL) {
  3802. + crypto_freereq(crp);
  3803. + return NULL;
  3804. + }
  3805. + memset(crd, 0, sizeof(*crd));
  3806. + crd->crd_next = crp->crp_desc;
  3807. + crp->crp_desc = crd;
  3808. + }
  3809. + }
  3810. + return crp;
  3811. +}
  3812. +
  3813. +/*
  3814. + * Invoke the callback on behalf of the driver.
  3815. + */
  3816. +void
  3817. +crypto_done(struct cryptop *crp)
  3818. +{
  3819. + unsigned long q_flags;
  3820. +
  3821. + dprintk("%s()\n", __FUNCTION__);
  3822. + if ((crp->crp_flags & CRYPTO_F_DONE) == 0) {
  3823. + crp->crp_flags |= CRYPTO_F_DONE;
  3824. + CRYPTO_Q_LOCK();
  3825. + crypto_q_cnt--;
  3826. + CRYPTO_Q_UNLOCK();
  3827. + } else
  3828. + printk("crypto: crypto_done op already done, flags 0x%x",
  3829. + crp->crp_flags);
  3830. + if (crp->crp_etype != 0)
  3831. + cryptostats.cs_errs++;
  3832. + /*
  3833. + * CBIMM means unconditionally do the callback immediately;
  3834. + * CBIFSYNC means do the callback immediately only if the
  3835. + * operation was done synchronously. Both are used to avoid
  3836. + * doing extraneous context switches; the latter is mostly
  3837. + * used with the software crypto driver.
  3838. + */
  3839. + if ((crp->crp_flags & CRYPTO_F_CBIMM) ||
  3840. + ((crp->crp_flags & CRYPTO_F_CBIFSYNC) &&
  3841. + (CRYPTO_SESID2CAPS(crp->crp_sid) & CRYPTOCAP_F_SYNC))) {
  3842. + /*
  3843. + * Do the callback directly. This is ok when the
  3844. + * callback routine does very little (e.g. the
  3845. + * /dev/crypto callback method just does a wakeup).
  3846. + */
  3847. + crp->crp_callback(crp);
  3848. + } else {
  3849. + unsigned long r_flags;
  3850. + /*
  3851. + * Normal case; queue the callback for the thread.
  3852. + */
  3853. + CRYPTO_RETQ_LOCK();
  3854. + if (CRYPTO_RETQ_EMPTY())
  3855. + wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
  3856. + TAILQ_INSERT_TAIL(&crp_ret_q, crp, crp_next);
  3857. + CRYPTO_RETQ_UNLOCK();
  3858. + }
  3859. +}
  3860. +
  3861. +/*
  3862. + * Invoke the callback on behalf of the driver.
  3863. + */
  3864. +void
  3865. +crypto_kdone(struct cryptkop *krp)
  3866. +{
  3867. + struct cryptocap *cap;
  3868. + unsigned long d_flags;
  3869. +
  3870. + if ((krp->krp_flags & CRYPTO_KF_DONE) != 0)
  3871. + printk("crypto: crypto_kdone op already done, flags 0x%x",
  3872. + krp->krp_flags);
  3873. + krp->krp_flags |= CRYPTO_KF_DONE;
  3874. + if (krp->krp_status != 0)
  3875. + cryptostats.cs_kerrs++;
  3876. +
  3877. + CRYPTO_DRIVER_LOCK();
  3878. + /* XXX: What if driver is loaded in the meantime? */
  3879. + if (krp->krp_hid < crypto_drivers_num) {
  3880. + cap = &crypto_drivers[krp->krp_hid];
  3881. + cap->cc_koperations--;
  3882. + KASSERT(cap->cc_koperations >= 0, ("cc_koperations < 0"));
  3883. + if (cap->cc_flags & CRYPTOCAP_F_CLEANUP)
  3884. + crypto_remove(cap);
  3885. + }
  3886. + CRYPTO_DRIVER_UNLOCK();
  3887. +
  3888. + /*
  3889. + * CBIMM means unconditionally do the callback immediately;
  3890. + * This is used to avoid doing extraneous context switches
  3891. + */
  3892. + if ((krp->krp_flags & CRYPTO_KF_CBIMM)) {
  3893. + /*
  3894. + * Do the callback directly. This is ok when the
  3895. + * callback routine does very little (e.g. the
  3896. + * /dev/crypto callback method just does a wakeup).
  3897. + */
  3898. + krp->krp_callback(krp);
  3899. + } else {
  3900. + unsigned long r_flags;
  3901. + /*
  3902. + * Normal case; queue the callback for the thread.
  3903. + */
  3904. + CRYPTO_RETQ_LOCK();
  3905. + if (CRYPTO_RETQ_EMPTY())
  3906. + wake_up_interruptible(&cryptoretproc_wait);/* shared wait channel */
  3907. + TAILQ_INSERT_TAIL(&crp_ret_kq, krp, krp_next);
  3908. + CRYPTO_RETQ_UNLOCK();
  3909. + }
  3910. +}
  3911. +
  3912. +int
  3913. +crypto_getfeat(int *featp)
  3914. +{
  3915. + int hid, kalg, feat = 0;
  3916. + unsigned long d_flags;
  3917. +
  3918. + CRYPTO_DRIVER_LOCK();
  3919. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  3920. + const struct cryptocap *cap = &crypto_drivers[hid];
  3921. +
  3922. + if ((cap->cc_flags & CRYPTOCAP_F_SOFTWARE) &&
  3923. + !crypto_devallowsoft) {
  3924. + continue;
  3925. + }
  3926. + for (kalg = 0; kalg < CRK_ALGORITHM_MAX; kalg++)
  3927. + if (cap->cc_kalg[kalg] & CRYPTO_ALG_FLAG_SUPPORTED)
  3928. + feat |= 1 << kalg;
  3929. + }
  3930. + CRYPTO_DRIVER_UNLOCK();
  3931. + *featp = feat;
  3932. + return (0);
  3933. +}
  3934. +
  3935. +/*
  3936. + * Crypto thread, dispatches crypto requests.
  3937. + */
  3938. +static int
  3939. +crypto_proc(void *arg)
  3940. +{
  3941. + struct cryptop *crp, *submit;
  3942. + struct cryptkop *krp, *krpp;
  3943. + struct cryptocap *cap;
  3944. + u_int32_t hid;
  3945. + int result, hint;
  3946. + unsigned long q_flags;
  3947. + int loopcount = 0;
  3948. +
  3949. + ocf_daemonize("crypto");
  3950. +
  3951. + CRYPTO_Q_LOCK();
  3952. + for (;;) {
  3953. + /*
  3954. + * we need to make sure we don't get into a busy loop with nothing
  3955. + * to do, the two crypto_all_*blocked vars help us find out when
  3956. + * we are all full and can do nothing on any driver or Q. If so we
  3957. + * wait for an unblock.
  3958. + */
  3959. + crypto_all_qblocked = !list_empty(&crp_q);
  3960. +
  3961. + /*
  3962. + * Find the first element in the queue that can be
  3963. + * processed and look-ahead to see if multiple ops
  3964. + * are ready for the same driver.
  3965. + */
  3966. + submit = NULL;
  3967. + hint = 0;
  3968. + list_for_each_entry(crp, &crp_q, crp_next) {
  3969. + hid = CRYPTO_SESID2HID(crp->crp_sid);
  3970. + cap = crypto_checkdriver(hid);
  3971. + /*
  3972. + * Driver cannot disappear when there is an active
  3973. + * session.
  3974. + */
  3975. + KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
  3976. + __func__, __LINE__));
  3977. + if (cap == NULL || cap->cc_dev == NULL) {
  3978. + /* Op needs to be migrated, process it. */
  3979. + if (submit == NULL)
  3980. + submit = crp;
  3981. + break;
  3982. + }
  3983. + if (!cap->cc_qblocked) {
  3984. + if (submit != NULL) {
  3985. + /*
  3986. + * We stop on finding another op,
  3987. + * regardless whether its for the same
  3988. + * driver or not. We could keep
  3989. + * searching the queue but it might be
  3990. + * better to just use a per-driver
  3991. + * queue instead.
  3992. + */
  3993. + if (CRYPTO_SESID2HID(submit->crp_sid) == hid)
  3994. + hint = CRYPTO_HINT_MORE;
  3995. + break;
  3996. + } else {
  3997. + submit = crp;
  3998. + if ((submit->crp_flags & CRYPTO_F_BATCH) == 0)
  3999. + break;
  4000. + /* keep scanning for more are q'd */
  4001. + }
  4002. + }
  4003. + }
  4004. + if (submit != NULL) {
  4005. + hid = CRYPTO_SESID2HID(submit->crp_sid);
  4006. + crypto_all_qblocked = 0;
  4007. + list_del(&submit->crp_next);
  4008. + crypto_drivers[hid].cc_unqblocked = 1;
  4009. + cap = crypto_checkdriver(hid);
  4010. + CRYPTO_Q_UNLOCK();
  4011. + KASSERT(cap != NULL, ("%s:%u Driver disappeared.",
  4012. + __func__, __LINE__));
  4013. + result = crypto_invoke(cap, submit, hint);
  4014. + CRYPTO_Q_LOCK();
  4015. + if (result == ERESTART) {
  4016. + /*
  4017. + * The driver ran out of resources, mark the
  4018. + * driver ``blocked'' for cryptop's and put
  4019. + * the request back in the queue. It would
  4020. + * best to put the request back where we got
  4021. + * it but that's hard so for now we put it
  4022. + * at the front. This should be ok; putting
  4023. + * it at the end does not work.
  4024. + */
  4025. + /* XXX validate sid again? */
  4026. + list_add(&submit->crp_next, &crp_q);
  4027. + cryptostats.cs_blocks++;
  4028. + if (crypto_drivers[hid].cc_unqblocked)
  4029. + crypto_drivers[hid].cc_qblocked=0;
  4030. + crypto_drivers[hid].cc_unqblocked=0;
  4031. + }
  4032. + crypto_drivers[hid].cc_unqblocked = 0;
  4033. + }
  4034. +
  4035. + crypto_all_kqblocked = !list_empty(&crp_kq);
  4036. +
  4037. + /* As above, but for key ops */
  4038. + krp = NULL;
  4039. + list_for_each_entry(krpp, &crp_kq, krp_next) {
  4040. + cap = crypto_checkdriver(krpp->krp_hid);
  4041. + if (cap == NULL || cap->cc_dev == NULL) {
  4042. + /*
  4043. + * Operation needs to be migrated, invalidate
  4044. + * the assigned device so it will reselect a
  4045. + * new one below. Propagate the original
  4046. + * crid selection flags if supplied.
  4047. + */
  4048. + krp->krp_hid = krp->krp_crid &
  4049. + (CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE);
  4050. + if (krp->krp_hid == 0)
  4051. + krp->krp_hid =
  4052. + CRYPTOCAP_F_SOFTWARE|CRYPTOCAP_F_HARDWARE;
  4053. + break;
  4054. + }
  4055. + if (!cap->cc_kqblocked) {
  4056. + krp = krpp;
  4057. + break;
  4058. + }
  4059. + }
  4060. + if (krp != NULL) {
  4061. + crypto_all_kqblocked = 0;
  4062. + list_del(&krp->krp_next);
  4063. + crypto_drivers[krp->krp_hid].cc_kqblocked = 1;
  4064. + CRYPTO_Q_UNLOCK();
  4065. + result = crypto_kinvoke(krp, krp->krp_hid);
  4066. + CRYPTO_Q_LOCK();
  4067. + if (result == ERESTART) {
  4068. + /*
  4069. + * The driver ran out of resources, mark the
  4070. + * driver ``blocked'' for cryptkop's and put
  4071. + * the request back in the queue. It would
  4072. + * best to put the request back where we got
  4073. + * it but that's hard so for now we put it
  4074. + * at the front. This should be ok; putting
  4075. + * it at the end does not work.
  4076. + */
  4077. + /* XXX validate sid again? */
  4078. + list_add(&krp->krp_next, &crp_kq);
  4079. + cryptostats.cs_kblocks++;
  4080. + } else
  4081. + crypto_drivers[krp->krp_hid].cc_kqblocked = 0;
  4082. + }
  4083. +
  4084. + if (submit == NULL && krp == NULL) {
  4085. + /*
  4086. + * Nothing more to be processed. Sleep until we're
  4087. + * woken because there are more ops to process.
  4088. + * This happens either by submission or by a driver
  4089. + * becoming unblocked and notifying us through
  4090. + * crypto_unblock. Note that when we wakeup we
  4091. + * start processing each queue again from the
  4092. + * front. It's not clear that it's important to
  4093. + * preserve this ordering since ops may finish
  4094. + * out of order if dispatched to different devices
  4095. + * and some become blocked while others do not.
  4096. + */
  4097. + dprintk("%s - sleeping (qe=%d qb=%d kqe=%d kqb=%d)\n",
  4098. + __FUNCTION__,
  4099. + list_empty(&crp_q), crypto_all_qblocked,
  4100. + list_empty(&crp_kq), crypto_all_kqblocked);
  4101. + loopcount = 0;
  4102. + CRYPTO_Q_UNLOCK();
  4103. + crp_sleep = 1;
  4104. + wait_event_interruptible(cryptoproc_wait,
  4105. + !(list_empty(&crp_q) || crypto_all_qblocked) ||
  4106. + !(list_empty(&crp_kq) || crypto_all_kqblocked) ||
  4107. + cryptoproc == (pid_t) -1);
  4108. + crp_sleep = 0;
  4109. + if (signal_pending (current)) {
  4110. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  4111. + spin_lock_irq(&current->sigmask_lock);
  4112. +#endif
  4113. + flush_signals(current);
  4114. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  4115. + spin_unlock_irq(&current->sigmask_lock);
  4116. +#endif
  4117. + }
  4118. + CRYPTO_Q_LOCK();
  4119. + dprintk("%s - awake\n", __FUNCTION__);
  4120. + if (cryptoproc == (pid_t) -1)
  4121. + break;
  4122. + cryptostats.cs_intrs++;
  4123. + } else if (loopcount > crypto_max_loopcount) {
  4124. + /*
  4125. + * Give other processes a chance to run if we've
  4126. + * been using the CPU exclusively for a while.
  4127. + */
  4128. + loopcount = 0;
  4129. + schedule();
  4130. + }
  4131. + loopcount++;
  4132. + }
  4133. + CRYPTO_Q_UNLOCK();
  4134. + complete_and_exit(&cryptoproc_exited, 0);
  4135. +}
  4136. +
  4137. +/*
  4138. + * Crypto returns thread, does callbacks for processed crypto requests.
  4139. + * Callbacks are done here, rather than in the crypto drivers, because
  4140. + * callbacks typically are expensive and would slow interrupt handling.
  4141. + */
  4142. +static int
  4143. +crypto_ret_proc(void *arg)
  4144. +{
  4145. + struct cryptop *crpt;
  4146. + struct cryptkop *krpt;
  4147. + unsigned long r_flags;
  4148. +
  4149. + ocf_daemonize("crypto_ret");
  4150. +
  4151. + CRYPTO_RETQ_LOCK();
  4152. + for (;;) {
  4153. + /* Harvest return q's for completed ops */
  4154. + crpt = NULL;
  4155. + if (!list_empty(&crp_ret_q))
  4156. + crpt = list_entry(crp_ret_q.next, typeof(*crpt), crp_next);
  4157. + if (crpt != NULL)
  4158. + list_del(&crpt->crp_next);
  4159. +
  4160. + krpt = NULL;
  4161. + if (!list_empty(&crp_ret_kq))
  4162. + krpt = list_entry(crp_ret_kq.next, typeof(*krpt), krp_next);
  4163. + if (krpt != NULL)
  4164. + list_del(&krpt->krp_next);
  4165. +
  4166. + if (crpt != NULL || krpt != NULL) {
  4167. + CRYPTO_RETQ_UNLOCK();
  4168. + /*
  4169. + * Run callbacks unlocked.
  4170. + */
  4171. + if (crpt != NULL)
  4172. + crpt->crp_callback(crpt);
  4173. + if (krpt != NULL)
  4174. + krpt->krp_callback(krpt);
  4175. + CRYPTO_RETQ_LOCK();
  4176. + } else {
  4177. + /*
  4178. + * Nothing more to be processed. Sleep until we're
  4179. + * woken because there are more returns to process.
  4180. + */
  4181. + dprintk("%s - sleeping\n", __FUNCTION__);
  4182. + CRYPTO_RETQ_UNLOCK();
  4183. + wait_event_interruptible(cryptoretproc_wait,
  4184. + cryptoretproc == (pid_t) -1 ||
  4185. + !list_empty(&crp_ret_q) ||
  4186. + !list_empty(&crp_ret_kq));
  4187. + if (signal_pending (current)) {
  4188. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  4189. + spin_lock_irq(&current->sigmask_lock);
  4190. +#endif
  4191. + flush_signals(current);
  4192. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  4193. + spin_unlock_irq(&current->sigmask_lock);
  4194. +#endif
  4195. + }
  4196. + CRYPTO_RETQ_LOCK();
  4197. + dprintk("%s - awake\n", __FUNCTION__);
  4198. + if (cryptoretproc == (pid_t) -1) {
  4199. + dprintk("%s - EXITING!\n", __FUNCTION__);
  4200. + break;
  4201. + }
  4202. + cryptostats.cs_rets++;
  4203. + }
  4204. + }
  4205. + CRYPTO_RETQ_UNLOCK();
  4206. + complete_and_exit(&cryptoretproc_exited, 0);
  4207. +}
  4208. +
  4209. +
  4210. +#if 0 /* should put this into /proc or something */
  4211. +static void
  4212. +db_show_drivers(void)
  4213. +{
  4214. + int hid;
  4215. +
  4216. + db_printf("%12s %4s %4s %8s %2s %2s\n"
  4217. + , "Device"
  4218. + , "Ses"
  4219. + , "Kops"
  4220. + , "Flags"
  4221. + , "QB"
  4222. + , "KB"
  4223. + );
  4224. + for (hid = 0; hid < crypto_drivers_num; hid++) {
  4225. + const struct cryptocap *cap = &crypto_drivers[hid];
  4226. + if (cap->cc_dev == NULL)
  4227. + continue;
  4228. + db_printf("%-12s %4u %4u %08x %2u %2u\n"
  4229. + , device_get_nameunit(cap->cc_dev)
  4230. + , cap->cc_sessions
  4231. + , cap->cc_koperations
  4232. + , cap->cc_flags
  4233. + , cap->cc_qblocked
  4234. + , cap->cc_kqblocked
  4235. + );
  4236. + }
  4237. +}
  4238. +
  4239. +DB_SHOW_COMMAND(crypto, db_show_crypto)
  4240. +{
  4241. + struct cryptop *crp;
  4242. +
  4243. + db_show_drivers();
  4244. + db_printf("\n");
  4245. +
  4246. + db_printf("%4s %8s %4s %4s %4s %4s %8s %8s\n",
  4247. + "HID", "Caps", "Ilen", "Olen", "Etype", "Flags",
  4248. + "Desc", "Callback");
  4249. + TAILQ_FOREACH(crp, &crp_q, crp_next) {
  4250. + db_printf("%4u %08x %4u %4u %4u %04x %8p %8p\n"
  4251. + , (int) CRYPTO_SESID2HID(crp->crp_sid)
  4252. + , (int) CRYPTO_SESID2CAPS(crp->crp_sid)
  4253. + , crp->crp_ilen, crp->crp_olen
  4254. + , crp->crp_etype
  4255. + , crp->crp_flags
  4256. + , crp->crp_desc
  4257. + , crp->crp_callback
  4258. + );
  4259. + }
  4260. + if (!TAILQ_EMPTY(&crp_ret_q)) {
  4261. + db_printf("\n%4s %4s %4s %8s\n",
  4262. + "HID", "Etype", "Flags", "Callback");
  4263. + TAILQ_FOREACH(crp, &crp_ret_q, crp_next) {
  4264. + db_printf("%4u %4u %04x %8p\n"
  4265. + , (int) CRYPTO_SESID2HID(crp->crp_sid)
  4266. + , crp->crp_etype
  4267. + , crp->crp_flags
  4268. + , crp->crp_callback
  4269. + );
  4270. + }
  4271. + }
  4272. +}
  4273. +
  4274. +DB_SHOW_COMMAND(kcrypto, db_show_kcrypto)
  4275. +{
  4276. + struct cryptkop *krp;
  4277. +
  4278. + db_show_drivers();
  4279. + db_printf("\n");
  4280. +
  4281. + db_printf("%4s %5s %4s %4s %8s %4s %8s\n",
  4282. + "Op", "Status", "#IP", "#OP", "CRID", "HID", "Callback");
  4283. + TAILQ_FOREACH(krp, &crp_kq, krp_next) {
  4284. + db_printf("%4u %5u %4u %4u %08x %4u %8p\n"
  4285. + , krp->krp_op
  4286. + , krp->krp_status
  4287. + , krp->krp_iparams, krp->krp_oparams
  4288. + , krp->krp_crid, krp->krp_hid
  4289. + , krp->krp_callback
  4290. + );
  4291. + }
  4292. + if (!TAILQ_EMPTY(&crp_ret_q)) {
  4293. + db_printf("%4s %5s %8s %4s %8s\n",
  4294. + "Op", "Status", "CRID", "HID", "Callback");
  4295. + TAILQ_FOREACH(krp, &crp_ret_kq, krp_next) {
  4296. + db_printf("%4u %5u %08x %4u %8p\n"
  4297. + , krp->krp_op
  4298. + , krp->krp_status
  4299. + , krp->krp_crid, krp->krp_hid
  4300. + , krp->krp_callback
  4301. + );
  4302. + }
  4303. + }
  4304. +}
  4305. +#endif
  4306. +
  4307. +
  4308. +static int
  4309. +crypto_init(void)
  4310. +{
  4311. + int error;
  4312. +
  4313. + dprintk("%s(%p)\n", __FUNCTION__, (void *) crypto_init);
  4314. +
  4315. + if (crypto_initted)
  4316. + return 0;
  4317. + crypto_initted = 1;
  4318. +
  4319. + spin_lock_init(&crypto_drivers_lock);
  4320. + spin_lock_init(&crypto_q_lock);
  4321. + spin_lock_init(&crypto_ret_q_lock);
  4322. +
  4323. + cryptop_zone = kmem_cache_create("cryptop", sizeof(struct cryptop),
  4324. + 0, SLAB_HWCACHE_ALIGN, NULL
  4325. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  4326. + , NULL
  4327. +#endif
  4328. + );
  4329. +
  4330. + cryptodesc_zone = kmem_cache_create("cryptodesc", sizeof(struct cryptodesc),
  4331. + 0, SLAB_HWCACHE_ALIGN, NULL
  4332. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  4333. + , NULL
  4334. +#endif
  4335. + );
  4336. +
  4337. + if (cryptodesc_zone == NULL || cryptop_zone == NULL) {
  4338. + printk("crypto: crypto_init cannot setup crypto zones\n");
  4339. + error = ENOMEM;
  4340. + goto bad;
  4341. + }
  4342. +
  4343. + crypto_drivers_num = CRYPTO_DRIVERS_INITIAL;
  4344. + crypto_drivers = kmalloc(crypto_drivers_num * sizeof(struct cryptocap),
  4345. + GFP_KERNEL);
  4346. + if (crypto_drivers == NULL) {
  4347. + printk("crypto: crypto_init cannot setup crypto drivers\n");
  4348. + error = ENOMEM;
  4349. + goto bad;
  4350. + }
  4351. +
  4352. + memset(crypto_drivers, 0, crypto_drivers_num * sizeof(struct cryptocap));
  4353. +
  4354. + init_completion(&cryptoproc_exited);
  4355. + init_completion(&cryptoretproc_exited);
  4356. +
  4357. + cryptoproc = 0; /* to avoid race condition where proc runs first */
  4358. + cryptoproc = kernel_thread(crypto_proc, NULL, CLONE_FS|CLONE_FILES);
  4359. + if (cryptoproc < 0) {
  4360. + error = cryptoproc;
  4361. + printk("crypto: crypto_init cannot start crypto thread; error %d",
  4362. + error);
  4363. + goto bad;
  4364. + }
  4365. +
  4366. + cryptoretproc = 0; /* to avoid race condition where proc runs first */
  4367. + cryptoretproc = kernel_thread(crypto_ret_proc, NULL, CLONE_FS|CLONE_FILES);
  4368. + if (cryptoretproc < 0) {
  4369. + error = cryptoretproc;
  4370. + printk("crypto: crypto_init cannot start cryptoret thread; error %d",
  4371. + error);
  4372. + goto bad;
  4373. + }
  4374. +
  4375. + return 0;
  4376. +bad:
  4377. + crypto_exit();
  4378. + return error;
  4379. +}
  4380. +
  4381. +
  4382. +static void
  4383. +crypto_exit(void)
  4384. +{
  4385. + pid_t p;
  4386. + unsigned long d_flags;
  4387. +
  4388. + dprintk("%s()\n", __FUNCTION__);
  4389. +
  4390. + /*
  4391. + * Terminate any crypto threads.
  4392. + */
  4393. +
  4394. + CRYPTO_DRIVER_LOCK();
  4395. + p = cryptoproc;
  4396. + cryptoproc = (pid_t) -1;
  4397. + kill_proc(p, SIGTERM, 1);
  4398. + wake_up_interruptible(&cryptoproc_wait);
  4399. + CRYPTO_DRIVER_UNLOCK();
  4400. +
  4401. + wait_for_completion(&cryptoproc_exited);
  4402. +
  4403. + CRYPTO_DRIVER_LOCK();
  4404. + p = cryptoretproc;
  4405. + cryptoretproc = (pid_t) -1;
  4406. + kill_proc(p, SIGTERM, 1);
  4407. + wake_up_interruptible(&cryptoretproc_wait);
  4408. + CRYPTO_DRIVER_UNLOCK();
  4409. +
  4410. + wait_for_completion(&cryptoretproc_exited);
  4411. +
  4412. + /* XXX flush queues??? */
  4413. +
  4414. + /*
  4415. + * Reclaim dynamically allocated resources.
  4416. + */
  4417. + if (crypto_drivers != NULL)
  4418. + kfree(crypto_drivers);
  4419. +
  4420. + if (cryptodesc_zone != NULL)
  4421. + kmem_cache_destroy(cryptodesc_zone);
  4422. + if (cryptop_zone != NULL)
  4423. + kmem_cache_destroy(cryptop_zone);
  4424. +}
  4425. +
  4426. +
  4427. +EXPORT_SYMBOL(crypto_newsession);
  4428. +EXPORT_SYMBOL(crypto_freesession);
  4429. +EXPORT_SYMBOL(crypto_get_driverid);
  4430. +EXPORT_SYMBOL(crypto_kregister);
  4431. +EXPORT_SYMBOL(crypto_register);
  4432. +EXPORT_SYMBOL(crypto_unregister);
  4433. +EXPORT_SYMBOL(crypto_unregister_all);
  4434. +EXPORT_SYMBOL(crypto_unblock);
  4435. +EXPORT_SYMBOL(crypto_dispatch);
  4436. +EXPORT_SYMBOL(crypto_kdispatch);
  4437. +EXPORT_SYMBOL(crypto_freereq);
  4438. +EXPORT_SYMBOL(crypto_getreq);
  4439. +EXPORT_SYMBOL(crypto_done);
  4440. +EXPORT_SYMBOL(crypto_kdone);
  4441. +EXPORT_SYMBOL(crypto_getfeat);
  4442. +EXPORT_SYMBOL(crypto_userasymcrypto);
  4443. +EXPORT_SYMBOL(crypto_getcaps);
  4444. +EXPORT_SYMBOL(crypto_find_driver);
  4445. +EXPORT_SYMBOL(crypto_find_device_byhid);
  4446. +
  4447. +module_init(crypto_init);
  4448. +module_exit(crypto_exit);
  4449. +
  4450. +MODULE_LICENSE("BSD");
  4451. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  4452. +MODULE_DESCRIPTION("OCF (OpenBSD Cryptographic Framework)");
  4453. diff -Nur linux-2.6.39.orig/crypto/ocf/cryptocteon/Makefile linux-2.6.39/crypto/ocf/cryptocteon/Makefile
  4454. --- linux-2.6.39.orig/crypto/ocf/cryptocteon/Makefile 1970-01-01 01:00:00.000000000 +0100
  4455. +++ linux-2.6.39/crypto/ocf/cryptocteon/Makefile 2011-08-01 14:38:18.000000000 +0200
  4456. @@ -0,0 +1,17 @@
  4457. +# for SGlinux builds
  4458. +-include $(ROOTDIR)/modules/.config
  4459. +
  4460. +obj-$(CONFIG_OCF_CRYPTOCTEON) += cryptocteon.o
  4461. +
  4462. +obj ?= .
  4463. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  4464. +
  4465. +ifdef CONFIG_OCF_CRYPTOCTEON
  4466. +# you need the cavium crypto component installed
  4467. +EXTRA_CFLAGS += -I$(ROOTDIR)/prop/include
  4468. +endif
  4469. +
  4470. +ifdef TOPDIR
  4471. +-include $(TOPDIR)/Rules.make
  4472. +endif
  4473. +
  4474. diff -Nur linux-2.6.39.orig/crypto/ocf/cryptocteon/cavium_crypto.c linux-2.6.39/crypto/ocf/cryptocteon/cavium_crypto.c
  4475. --- linux-2.6.39.orig/crypto/ocf/cryptocteon/cavium_crypto.c 1970-01-01 01:00:00.000000000 +0100
  4476. +++ linux-2.6.39/crypto/ocf/cryptocteon/cavium_crypto.c 2011-08-01 14:38:18.000000000 +0200
  4477. @@ -0,0 +1,2283 @@
  4478. +/*
  4479. + * Copyright (c) 2009 David McCullough <david.mccullough@securecomputing.com>
  4480. + *
  4481. + * Copyright (c) 2003-2007 Cavium Networks (support@cavium.com). All rights
  4482. + * reserved.
  4483. + *
  4484. + * Redistribution and use in source and binary forms, with or without
  4485. + * modification, are permitted provided that the following conditions are met:
  4486. + * 1. Redistributions of source code must retain the above copyright notice,
  4487. + * this list of conditions and the following disclaimer.
  4488. + * 2. Redistributions in binary form must reproduce the above copyright notice,
  4489. + * this list of conditions and the following disclaimer in the documentation
  4490. + * and/or other materials provided with the distribution.
  4491. + * 3. All advertising materials mentioning features or use of this software
  4492. + * must display the following acknowledgement:
  4493. + * This product includes software developed by Cavium Networks
  4494. + * 4. Cavium Networks' name may not be used to endorse or promote products
  4495. + * derived from this software without specific prior written permission.
  4496. + *
  4497. + * This Software, including technical data, may be subject to U.S. export
  4498. + * control laws, including the U.S. Export Administration Act and its
  4499. + * associated regulations, and may be subject to export or import regulations
  4500. + * in other countries. You warrant that You will comply strictly in all
  4501. + * respects with all such regulations and acknowledge that you have the
  4502. + * responsibility to obtain licenses to export, re-export or import the
  4503. + * Software.
  4504. + *
  4505. + * TO THE MAXIMUM EXTENT PERMITTED BY LAW, THE SOFTWARE IS PROVIDED "AS IS" AND
  4506. + * WITH ALL FAULTS AND CAVIUM MAKES NO PROMISES, REPRESENTATIONS OR WARRANTIES,
  4507. + * EITHER EXPRESS, IMPLIED, STATUTORY, OR OTHERWISE, WITH RESPECT TO THE
  4508. + * SOFTWARE, INCLUDING ITS CONDITION, ITS CONFORMITY TO ANY REPRESENTATION OR
  4509. + * DESCRIPTION, OR THE EXISTENCE OF ANY LATENT OR PATENT DEFECTS, AND CAVIUM
  4510. + * SPECIFICALLY DISCLAIMS ALL IMPLIED (IF ANY) WARRANTIES OF TITLE,
  4511. + * MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR A PARTICULAR PURPOSE, LACK OF
  4512. + * VIRUSES, ACCURACY OR COMPLETENESS, QUIET ENJOYMENT, QUIET POSSESSION OR
  4513. + * CORRESPONDENCE TO DESCRIPTION. THE ENTIRE RISK ARISING OUT OF USE OR
  4514. + * PERFORMANCE OF THE SOFTWARE LIES WITH YOU.
  4515. +*/
  4516. +/****************************************************************************/
  4517. +
  4518. +#include <linux/scatterlist.h>
  4519. +#include <asm/octeon/octeon.h>
  4520. +#include "octeon-asm.h"
  4521. +
  4522. +/****************************************************************************/
  4523. +
  4524. +extern unsigned long octeon_crypto_enable(struct octeon_cop2_state *);
  4525. +extern void octeon_crypto_disable(struct octeon_cop2_state *, unsigned long);
  4526. +
  4527. +#define SG_INIT(s, p, i, l) \
  4528. + { \
  4529. + (i) = 0; \
  4530. + (l) = (s)[0].length; \
  4531. + (p) = (typeof(p)) sg_virt((s)); \
  4532. + CVMX_PREFETCH0((p)); \
  4533. + }
  4534. +
  4535. +#define SG_CONSUME(s, p, i, l) \
  4536. + { \
  4537. + (p)++; \
  4538. + (l) -= sizeof(*(p)); \
  4539. + if ((l) < 0) { \
  4540. + dprintk("%s, %d: l = %d\n", __FILE__, __LINE__, l); \
  4541. + } else if ((l) == 0) { \
  4542. + (i)++; \
  4543. + (l) = (s)[0].length; \
  4544. + (p) = (typeof(p)) sg_virt(s); \
  4545. + CVMX_PREFETCH0((p)); \
  4546. + } \
  4547. + }
  4548. +
  4549. +#define ESP_HEADER_LENGTH 8
  4550. +#define DES_CBC_IV_LENGTH 8
  4551. +#define AES_CBC_IV_LENGTH 16
  4552. +#define ESP_HMAC_LEN 12
  4553. +
  4554. +#define ESP_HEADER_LENGTH 8
  4555. +#define DES_CBC_IV_LENGTH 8
  4556. +
  4557. +/****************************************************************************/
  4558. +
  4559. +#define CVM_LOAD_SHA_UNIT(dat, next) { \
  4560. + if (next == 0) { \
  4561. + next = 1; \
  4562. + CVMX_MT_HSH_DAT (dat, 0); \
  4563. + } else if (next == 1) { \
  4564. + next = 2; \
  4565. + CVMX_MT_HSH_DAT (dat, 1); \
  4566. + } else if (next == 2) { \
  4567. + next = 3; \
  4568. + CVMX_MT_HSH_DAT (dat, 2); \
  4569. + } else if (next == 3) { \
  4570. + next = 4; \
  4571. + CVMX_MT_HSH_DAT (dat, 3); \
  4572. + } else if (next == 4) { \
  4573. + next = 5; \
  4574. + CVMX_MT_HSH_DAT (dat, 4); \
  4575. + } else if (next == 5) { \
  4576. + next = 6; \
  4577. + CVMX_MT_HSH_DAT (dat, 5); \
  4578. + } else if (next == 6) { \
  4579. + next = 7; \
  4580. + CVMX_MT_HSH_DAT (dat, 6); \
  4581. + } else { \
  4582. + CVMX_MT_HSH_STARTSHA (dat); \
  4583. + next = 0; \
  4584. + } \
  4585. +}
  4586. +
  4587. +#define CVM_LOAD2_SHA_UNIT(dat1, dat2, next) { \
  4588. + if (next == 0) { \
  4589. + CVMX_MT_HSH_DAT (dat1, 0); \
  4590. + CVMX_MT_HSH_DAT (dat2, 1); \
  4591. + next = 2; \
  4592. + } else if (next == 1) { \
  4593. + CVMX_MT_HSH_DAT (dat1, 1); \
  4594. + CVMX_MT_HSH_DAT (dat2, 2); \
  4595. + next = 3; \
  4596. + } else if (next == 2) { \
  4597. + CVMX_MT_HSH_DAT (dat1, 2); \
  4598. + CVMX_MT_HSH_DAT (dat2, 3); \
  4599. + next = 4; \
  4600. + } else if (next == 3) { \
  4601. + CVMX_MT_HSH_DAT (dat1, 3); \
  4602. + CVMX_MT_HSH_DAT (dat2, 4); \
  4603. + next = 5; \
  4604. + } else if (next == 4) { \
  4605. + CVMX_MT_HSH_DAT (dat1, 4); \
  4606. + CVMX_MT_HSH_DAT (dat2, 5); \
  4607. + next = 6; \
  4608. + } else if (next == 5) { \
  4609. + CVMX_MT_HSH_DAT (dat1, 5); \
  4610. + CVMX_MT_HSH_DAT (dat2, 6); \
  4611. + next = 7; \
  4612. + } else if (next == 6) { \
  4613. + CVMX_MT_HSH_DAT (dat1, 6); \
  4614. + CVMX_MT_HSH_STARTSHA (dat2); \
  4615. + next = 0; \
  4616. + } else { \
  4617. + CVMX_MT_HSH_STARTSHA (dat1); \
  4618. + CVMX_MT_HSH_DAT (dat2, 0); \
  4619. + next = 1; \
  4620. + } \
  4621. +}
  4622. +
  4623. +/****************************************************************************/
  4624. +
  4625. +#define CVM_LOAD_MD5_UNIT(dat, next) { \
  4626. + if (next == 0) { \
  4627. + next = 1; \
  4628. + CVMX_MT_HSH_DAT (dat, 0); \
  4629. + } else if (next == 1) { \
  4630. + next = 2; \
  4631. + CVMX_MT_HSH_DAT (dat, 1); \
  4632. + } else if (next == 2) { \
  4633. + next = 3; \
  4634. + CVMX_MT_HSH_DAT (dat, 2); \
  4635. + } else if (next == 3) { \
  4636. + next = 4; \
  4637. + CVMX_MT_HSH_DAT (dat, 3); \
  4638. + } else if (next == 4) { \
  4639. + next = 5; \
  4640. + CVMX_MT_HSH_DAT (dat, 4); \
  4641. + } else if (next == 5) { \
  4642. + next = 6; \
  4643. + CVMX_MT_HSH_DAT (dat, 5); \
  4644. + } else if (next == 6) { \
  4645. + next = 7; \
  4646. + CVMX_MT_HSH_DAT (dat, 6); \
  4647. + } else { \
  4648. + CVMX_MT_HSH_STARTMD5 (dat); \
  4649. + next = 0; \
  4650. + } \
  4651. +}
  4652. +
  4653. +#define CVM_LOAD2_MD5_UNIT(dat1, dat2, next) { \
  4654. + if (next == 0) { \
  4655. + CVMX_MT_HSH_DAT (dat1, 0); \
  4656. + CVMX_MT_HSH_DAT (dat2, 1); \
  4657. + next = 2; \
  4658. + } else if (next == 1) { \
  4659. + CVMX_MT_HSH_DAT (dat1, 1); \
  4660. + CVMX_MT_HSH_DAT (dat2, 2); \
  4661. + next = 3; \
  4662. + } else if (next == 2) { \
  4663. + CVMX_MT_HSH_DAT (dat1, 2); \
  4664. + CVMX_MT_HSH_DAT (dat2, 3); \
  4665. + next = 4; \
  4666. + } else if (next == 3) { \
  4667. + CVMX_MT_HSH_DAT (dat1, 3); \
  4668. + CVMX_MT_HSH_DAT (dat2, 4); \
  4669. + next = 5; \
  4670. + } else if (next == 4) { \
  4671. + CVMX_MT_HSH_DAT (dat1, 4); \
  4672. + CVMX_MT_HSH_DAT (dat2, 5); \
  4673. + next = 6; \
  4674. + } else if (next == 5) { \
  4675. + CVMX_MT_HSH_DAT (dat1, 5); \
  4676. + CVMX_MT_HSH_DAT (dat2, 6); \
  4677. + next = 7; \
  4678. + } else if (next == 6) { \
  4679. + CVMX_MT_HSH_DAT (dat1, 6); \
  4680. + CVMX_MT_HSH_STARTMD5 (dat2); \
  4681. + next = 0; \
  4682. + } else { \
  4683. + CVMX_MT_HSH_STARTMD5 (dat1); \
  4684. + CVMX_MT_HSH_DAT (dat2, 0); \
  4685. + next = 1; \
  4686. + } \
  4687. +}
  4688. +
  4689. +/****************************************************************************/
  4690. +
  4691. +static inline uint64_t
  4692. +swap64(uint64_t a)
  4693. +{
  4694. + return ((a >> 56) |
  4695. + (((a >> 48) & 0xfful) << 8) |
  4696. + (((a >> 40) & 0xfful) << 16) |
  4697. + (((a >> 32) & 0xfful) << 24) |
  4698. + (((a >> 24) & 0xfful) << 32) |
  4699. + (((a >> 16) & 0xfful) << 40) |
  4700. + (((a >> 8) & 0xfful) << 48) | (((a >> 0) & 0xfful) << 56));
  4701. +}
  4702. +
  4703. +/****************************************************************************/
  4704. +
  4705. +void
  4706. +octo_calc_hash(__u8 auth, unsigned char *key, uint64_t *inner, uint64_t *outer)
  4707. +{
  4708. + uint8_t hash_key[64];
  4709. + uint64_t *key1;
  4710. + register uint64_t xor1 = 0x3636363636363636ULL;
  4711. + register uint64_t xor2 = 0x5c5c5c5c5c5c5c5cULL;
  4712. + struct octeon_cop2_state state;
  4713. + unsigned long flags;
  4714. +
  4715. + dprintk("%s()\n", __FUNCTION__);
  4716. +
  4717. + memset(hash_key, 0, sizeof(hash_key));
  4718. + memcpy(hash_key, (uint8_t *) key, (auth ? 20 : 16));
  4719. + key1 = (uint64_t *) hash_key;
  4720. + flags = octeon_crypto_enable(&state);
  4721. + if (auth) {
  4722. + CVMX_MT_HSH_IV(0x67452301EFCDAB89ULL, 0);
  4723. + CVMX_MT_HSH_IV(0x98BADCFE10325476ULL, 1);
  4724. + CVMX_MT_HSH_IV(0xC3D2E1F000000000ULL, 2);
  4725. + } else {
  4726. + CVMX_MT_HSH_IV(0x0123456789ABCDEFULL, 0);
  4727. + CVMX_MT_HSH_IV(0xFEDCBA9876543210ULL, 1);
  4728. + }
  4729. +
  4730. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 0);
  4731. + key1++;
  4732. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 1);
  4733. + key1++;
  4734. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 2);
  4735. + key1++;
  4736. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 3);
  4737. + key1++;
  4738. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 4);
  4739. + key1++;
  4740. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 5);
  4741. + key1++;
  4742. + CVMX_MT_HSH_DAT((*key1 ^ xor1), 6);
  4743. + key1++;
  4744. + if (auth)
  4745. + CVMX_MT_HSH_STARTSHA((*key1 ^ xor1));
  4746. + else
  4747. + CVMX_MT_HSH_STARTMD5((*key1 ^ xor1));
  4748. +
  4749. + CVMX_MF_HSH_IV(inner[0], 0);
  4750. + CVMX_MF_HSH_IV(inner[1], 1);
  4751. + if (auth) {
  4752. + inner[2] = 0;
  4753. + CVMX_MF_HSH_IV(((uint64_t *) inner)[2], 2);
  4754. + }
  4755. +
  4756. + memset(hash_key, 0, sizeof(hash_key));
  4757. + memcpy(hash_key, (uint8_t *) key, (auth ? 20 : 16));
  4758. + key1 = (uint64_t *) hash_key;
  4759. + if (auth) {
  4760. + CVMX_MT_HSH_IV(0x67452301EFCDAB89ULL, 0);
  4761. + CVMX_MT_HSH_IV(0x98BADCFE10325476ULL, 1);
  4762. + CVMX_MT_HSH_IV(0xC3D2E1F000000000ULL, 2);
  4763. + } else {
  4764. + CVMX_MT_HSH_IV(0x0123456789ABCDEFULL, 0);
  4765. + CVMX_MT_HSH_IV(0xFEDCBA9876543210ULL, 1);
  4766. + }
  4767. +
  4768. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 0);
  4769. + key1++;
  4770. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 1);
  4771. + key1++;
  4772. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 2);
  4773. + key1++;
  4774. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 3);
  4775. + key1++;
  4776. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 4);
  4777. + key1++;
  4778. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 5);
  4779. + key1++;
  4780. + CVMX_MT_HSH_DAT((*key1 ^ xor2), 6);
  4781. + key1++;
  4782. + if (auth)
  4783. + CVMX_MT_HSH_STARTSHA((*key1 ^ xor2));
  4784. + else
  4785. + CVMX_MT_HSH_STARTMD5((*key1 ^ xor2));
  4786. +
  4787. + CVMX_MF_HSH_IV(outer[0], 0);
  4788. + CVMX_MF_HSH_IV(outer[1], 1);
  4789. + if (auth) {
  4790. + outer[2] = 0;
  4791. + CVMX_MF_HSH_IV(outer[2], 2);
  4792. + }
  4793. + octeon_crypto_disable(&state, flags);
  4794. + return;
  4795. +}
  4796. +
  4797. +/****************************************************************************/
  4798. +/* DES functions */
  4799. +
  4800. +int
  4801. +octo_des_cbc_encrypt(
  4802. + struct octo_sess *od,
  4803. + struct scatterlist *sg, int sg_len,
  4804. + int auth_off, int auth_len,
  4805. + int crypt_off, int crypt_len,
  4806. + int icv_off, uint8_t *ivp)
  4807. +{
  4808. + uint64_t *data;
  4809. + int data_i, data_l;
  4810. + struct octeon_cop2_state state;
  4811. + unsigned long flags;
  4812. +
  4813. + dprintk("%s()\n", __FUNCTION__);
  4814. +
  4815. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  4816. + (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
  4817. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  4818. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  4819. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  4820. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  4821. + return -EINVAL;
  4822. + }
  4823. +
  4824. + SG_INIT(sg, data, data_i, data_l);
  4825. +
  4826. + CVMX_PREFETCH0(ivp);
  4827. + CVMX_PREFETCH0(od->octo_enckey);
  4828. +
  4829. + flags = octeon_crypto_enable(&state);
  4830. +
  4831. + /* load 3DES Key */
  4832. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  4833. + if (od->octo_encklen == 24) {
  4834. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  4835. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4836. + } else if (od->octo_encklen == 8) {
  4837. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  4838. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  4839. + } else {
  4840. + octeon_crypto_disable(&state, flags);
  4841. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  4842. + return -EINVAL;
  4843. + }
  4844. +
  4845. + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  4846. +
  4847. + while (crypt_off > 0) {
  4848. + SG_CONSUME(sg, data, data_i, data_l);
  4849. + crypt_off -= 8;
  4850. + }
  4851. +
  4852. + while (crypt_len > 0) {
  4853. + CVMX_MT_3DES_ENC_CBC(*data);
  4854. + CVMX_MF_3DES_RESULT(*data);
  4855. + SG_CONSUME(sg, data, data_i, data_l);
  4856. + crypt_len -= 8;
  4857. + }
  4858. +
  4859. + octeon_crypto_disable(&state, flags);
  4860. + return 0;
  4861. +}
  4862. +
  4863. +
  4864. +int
  4865. +octo_des_cbc_decrypt(
  4866. + struct octo_sess *od,
  4867. + struct scatterlist *sg, int sg_len,
  4868. + int auth_off, int auth_len,
  4869. + int crypt_off, int crypt_len,
  4870. + int icv_off, uint8_t *ivp)
  4871. +{
  4872. + uint64_t *data;
  4873. + int data_i, data_l;
  4874. + struct octeon_cop2_state state;
  4875. + unsigned long flags;
  4876. +
  4877. + dprintk("%s()\n", __FUNCTION__);
  4878. +
  4879. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  4880. + (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
  4881. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  4882. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  4883. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  4884. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  4885. + return -EINVAL;
  4886. + }
  4887. +
  4888. + SG_INIT(sg, data, data_i, data_l);
  4889. +
  4890. + CVMX_PREFETCH0(ivp);
  4891. + CVMX_PREFETCH0(od->octo_enckey);
  4892. +
  4893. + flags = octeon_crypto_enable(&state);
  4894. +
  4895. + /* load 3DES Key */
  4896. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  4897. + if (od->octo_encklen == 24) {
  4898. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  4899. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4900. + } else if (od->octo_encklen == 8) {
  4901. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  4902. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  4903. + } else {
  4904. + octeon_crypto_disable(&state, flags);
  4905. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  4906. + return -EINVAL;
  4907. + }
  4908. +
  4909. + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  4910. +
  4911. + while (crypt_off > 0) {
  4912. + SG_CONSUME(sg, data, data_i, data_l);
  4913. + crypt_off -= 8;
  4914. + }
  4915. +
  4916. + while (crypt_len > 0) {
  4917. + CVMX_MT_3DES_DEC_CBC(*data);
  4918. + CVMX_MF_3DES_RESULT(*data);
  4919. + SG_CONSUME(sg, data, data_i, data_l);
  4920. + crypt_len -= 8;
  4921. + }
  4922. +
  4923. + octeon_crypto_disable(&state, flags);
  4924. + return 0;
  4925. +}
  4926. +
  4927. +/****************************************************************************/
  4928. +/* AES functions */
  4929. +
  4930. +int
  4931. +octo_aes_cbc_encrypt(
  4932. + struct octo_sess *od,
  4933. + struct scatterlist *sg, int sg_len,
  4934. + int auth_off, int auth_len,
  4935. + int crypt_off, int crypt_len,
  4936. + int icv_off, uint8_t *ivp)
  4937. +{
  4938. + uint64_t *data, *pdata;
  4939. + int data_i, data_l;
  4940. + struct octeon_cop2_state state;
  4941. + unsigned long flags;
  4942. +
  4943. + dprintk("%s()\n", __FUNCTION__);
  4944. +
  4945. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  4946. + (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
  4947. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  4948. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  4949. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  4950. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  4951. + return -EINVAL;
  4952. + }
  4953. +
  4954. + SG_INIT(sg, data, data_i, data_l);
  4955. +
  4956. + CVMX_PREFETCH0(ivp);
  4957. + CVMX_PREFETCH0(od->octo_enckey);
  4958. +
  4959. + flags = octeon_crypto_enable(&state);
  4960. +
  4961. + /* load AES Key */
  4962. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  4963. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  4964. +
  4965. + if (od->octo_encklen == 16) {
  4966. + CVMX_MT_AES_KEY(0x0, 2);
  4967. + CVMX_MT_AES_KEY(0x0, 3);
  4968. + } else if (od->octo_encklen == 24) {
  4969. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4970. + CVMX_MT_AES_KEY(0x0, 3);
  4971. + } else if (od->octo_encklen == 32) {
  4972. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  4973. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  4974. + } else {
  4975. + octeon_crypto_disable(&state, flags);
  4976. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  4977. + return -EINVAL;
  4978. + }
  4979. + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  4980. +
  4981. + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  4982. + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  4983. +
  4984. + while (crypt_off > 0) {
  4985. + SG_CONSUME(sg, data, data_i, data_l);
  4986. + crypt_off -= 8;
  4987. + }
  4988. +
  4989. + while (crypt_len > 0) {
  4990. + pdata = data;
  4991. + CVMX_MT_AES_ENC_CBC0(*data);
  4992. + SG_CONSUME(sg, data, data_i, data_l);
  4993. + CVMX_MT_AES_ENC_CBC1(*data);
  4994. + CVMX_MF_AES_RESULT(*pdata, 0);
  4995. + CVMX_MF_AES_RESULT(*data, 1);
  4996. + SG_CONSUME(sg, data, data_i, data_l);
  4997. + crypt_len -= 16;
  4998. + }
  4999. +
  5000. + octeon_crypto_disable(&state, flags);
  5001. + return 0;
  5002. +}
  5003. +
  5004. +
  5005. +int
  5006. +octo_aes_cbc_decrypt(
  5007. + struct octo_sess *od,
  5008. + struct scatterlist *sg, int sg_len,
  5009. + int auth_off, int auth_len,
  5010. + int crypt_off, int crypt_len,
  5011. + int icv_off, uint8_t *ivp)
  5012. +{
  5013. + uint64_t *data, *pdata;
  5014. + int data_i, data_l;
  5015. + struct octeon_cop2_state state;
  5016. + unsigned long flags;
  5017. +
  5018. + dprintk("%s()\n", __FUNCTION__);
  5019. +
  5020. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  5021. + (crypt_off & 0x7) || (crypt_off + crypt_len > sg_len))) {
  5022. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  5023. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  5024. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  5025. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  5026. + return -EINVAL;
  5027. + }
  5028. +
  5029. + SG_INIT(sg, data, data_i, data_l);
  5030. +
  5031. + CVMX_PREFETCH0(ivp);
  5032. + CVMX_PREFETCH0(od->octo_enckey);
  5033. +
  5034. + flags = octeon_crypto_enable(&state);
  5035. +
  5036. + /* load AES Key */
  5037. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  5038. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  5039. +
  5040. + if (od->octo_encklen == 16) {
  5041. + CVMX_MT_AES_KEY(0x0, 2);
  5042. + CVMX_MT_AES_KEY(0x0, 3);
  5043. + } else if (od->octo_encklen == 24) {
  5044. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5045. + CVMX_MT_AES_KEY(0x0, 3);
  5046. + } else if (od->octo_encklen == 32) {
  5047. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5048. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  5049. + } else {
  5050. + octeon_crypto_disable(&state, flags);
  5051. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  5052. + return -EINVAL;
  5053. + }
  5054. + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  5055. +
  5056. + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  5057. + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  5058. +
  5059. + while (crypt_off > 0) {
  5060. + SG_CONSUME(sg, data, data_i, data_l);
  5061. + crypt_off -= 8;
  5062. + }
  5063. +
  5064. + while (crypt_len > 0) {
  5065. + pdata = data;
  5066. + CVMX_MT_AES_DEC_CBC0(*data);
  5067. + SG_CONSUME(sg, data, data_i, data_l);
  5068. + CVMX_MT_AES_DEC_CBC1(*data);
  5069. + CVMX_MF_AES_RESULT(*pdata, 0);
  5070. + CVMX_MF_AES_RESULT(*data, 1);
  5071. + SG_CONSUME(sg, data, data_i, data_l);
  5072. + crypt_len -= 16;
  5073. + }
  5074. +
  5075. + octeon_crypto_disable(&state, flags);
  5076. + return 0;
  5077. +}
  5078. +
  5079. +/****************************************************************************/
  5080. +/* MD5 */
  5081. +
  5082. +int
  5083. +octo_null_md5_encrypt(
  5084. + struct octo_sess *od,
  5085. + struct scatterlist *sg, int sg_len,
  5086. + int auth_off, int auth_len,
  5087. + int crypt_off, int crypt_len,
  5088. + int icv_off, uint8_t *ivp)
  5089. +{
  5090. + register int next = 0;
  5091. + uint64_t *data;
  5092. + uint64_t tmp1, tmp2;
  5093. + int data_i, data_l, alen = auth_len;
  5094. + struct octeon_cop2_state state;
  5095. + unsigned long flags;
  5096. +
  5097. + dprintk("%s()\n", __FUNCTION__);
  5098. +
  5099. + if (unlikely(od == NULL || sg==NULL || sg_len==0 ||
  5100. + (auth_off & 0x7) || (auth_off + auth_len > sg_len))) {
  5101. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  5102. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  5103. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  5104. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  5105. + return -EINVAL;
  5106. + }
  5107. +
  5108. + SG_INIT(sg, data, data_i, data_l);
  5109. +
  5110. + flags = octeon_crypto_enable(&state);
  5111. +
  5112. + /* Load MD5 IV */
  5113. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  5114. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  5115. +
  5116. + while (auth_off > 0) {
  5117. + SG_CONSUME(sg, data, data_i, data_l);
  5118. + auth_off -= 8;
  5119. + }
  5120. +
  5121. + while (auth_len > 0) {
  5122. + CVM_LOAD_MD5_UNIT(*data, next);
  5123. + auth_len -= 8;
  5124. + SG_CONSUME(sg, data, data_i, data_l);
  5125. + }
  5126. +
  5127. + /* finish the hash */
  5128. + CVMX_PREFETCH0(od->octo_hmouter);
  5129. +#if 0
  5130. + if (unlikely(inplen)) {
  5131. + uint64_t tmp = 0;
  5132. + uint8_t *p = (uint8_t *) & tmp;
  5133. + p[inplen] = 0x80;
  5134. + do {
  5135. + inplen--;
  5136. + p[inplen] = ((uint8_t *) data)[inplen];
  5137. + } while (inplen);
  5138. + CVM_LOAD_MD5_UNIT(tmp, next);
  5139. + } else {
  5140. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  5141. + }
  5142. +#else
  5143. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  5144. +#endif
  5145. +
  5146. + /* Finish Inner hash */
  5147. + while (next != 7) {
  5148. + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
  5149. + }
  5150. + CVMX_ES64(tmp1, ((alen + 64) << 3));
  5151. + CVM_LOAD_MD5_UNIT(tmp1, next);
  5152. +
  5153. + /* Get the inner hash of HMAC */
  5154. + CVMX_MF_HSH_IV(tmp1, 0);
  5155. + CVMX_MF_HSH_IV(tmp2, 1);
  5156. +
  5157. + /* Initialize hash unit */
  5158. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  5159. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  5160. +
  5161. + CVMX_MT_HSH_DAT(tmp1, 0);
  5162. + CVMX_MT_HSH_DAT(tmp2, 1);
  5163. + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
  5164. + CVMX_MT_HSH_DATZ(3);
  5165. + CVMX_MT_HSH_DATZ(4);
  5166. + CVMX_MT_HSH_DATZ(5);
  5167. + CVMX_MT_HSH_DATZ(6);
  5168. + CVMX_ES64(tmp1, ((64 + 16) << 3));
  5169. + CVMX_MT_HSH_STARTMD5(tmp1);
  5170. +
  5171. + /* save the HMAC */
  5172. + SG_INIT(sg, data, data_i, data_l);
  5173. + while (icv_off > 0) {
  5174. + SG_CONSUME(sg, data, data_i, data_l);
  5175. + icv_off -= 8;
  5176. + }
  5177. + CVMX_MF_HSH_IV(*data, 0);
  5178. + SG_CONSUME(sg, data, data_i, data_l);
  5179. + CVMX_MF_HSH_IV(tmp1, 1);
  5180. + *(uint32_t *)data = (uint32_t) (tmp1 >> 32);
  5181. +
  5182. + octeon_crypto_disable(&state, flags);
  5183. + return 0;
  5184. +}
  5185. +
  5186. +/****************************************************************************/
  5187. +/* SHA1 */
  5188. +
  5189. +int
  5190. +octo_null_sha1_encrypt(
  5191. + struct octo_sess *od,
  5192. + struct scatterlist *sg, int sg_len,
  5193. + int auth_off, int auth_len,
  5194. + int crypt_off, int crypt_len,
  5195. + int icv_off, uint8_t *ivp)
  5196. +{
  5197. + register int next = 0;
  5198. + uint64_t *data;
  5199. + uint64_t tmp1, tmp2, tmp3;
  5200. + int data_i, data_l, alen = auth_len;
  5201. + struct octeon_cop2_state state;
  5202. + unsigned long flags;
  5203. +
  5204. + dprintk("%s()\n", __FUNCTION__);
  5205. +
  5206. + if (unlikely(od == NULL || sg==NULL || sg_len==0 ||
  5207. + (auth_off & 0x7) || (auth_off + auth_len > sg_len))) {
  5208. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  5209. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  5210. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  5211. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  5212. + return -EINVAL;
  5213. + }
  5214. +
  5215. + SG_INIT(sg, data, data_i, data_l);
  5216. +
  5217. + flags = octeon_crypto_enable(&state);
  5218. +
  5219. + /* Load SHA1 IV */
  5220. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  5221. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  5222. + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
  5223. +
  5224. + while (auth_off > 0) {
  5225. + SG_CONSUME(sg, data, data_i, data_l);
  5226. + auth_off -= 8;
  5227. + }
  5228. +
  5229. + while (auth_len > 0) {
  5230. + CVM_LOAD_SHA_UNIT(*data, next);
  5231. + auth_len -= 8;
  5232. + SG_CONSUME(sg, data, data_i, data_l);
  5233. + }
  5234. +
  5235. + /* finish the hash */
  5236. + CVMX_PREFETCH0(od->octo_hmouter);
  5237. +#if 0
  5238. + if (unlikely(inplen)) {
  5239. + uint64_t tmp = 0;
  5240. + uint8_t *p = (uint8_t *) & tmp;
  5241. + p[inplen] = 0x80;
  5242. + do {
  5243. + inplen--;
  5244. + p[inplen] = ((uint8_t *) data)[inplen];
  5245. + } while (inplen);
  5246. + CVM_LOAD_MD5_UNIT(tmp, next);
  5247. + } else {
  5248. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  5249. + }
  5250. +#else
  5251. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  5252. +#endif
  5253. +
  5254. + /* Finish Inner hash */
  5255. + while (next != 7) {
  5256. + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
  5257. + }
  5258. + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
  5259. +
  5260. + /* Get the inner hash of HMAC */
  5261. + CVMX_MF_HSH_IV(tmp1, 0);
  5262. + CVMX_MF_HSH_IV(tmp2, 1);
  5263. + tmp3 = 0;
  5264. + CVMX_MF_HSH_IV(tmp3, 2);
  5265. +
  5266. + /* Initialize hash unit */
  5267. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  5268. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  5269. + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
  5270. +
  5271. + CVMX_MT_HSH_DAT(tmp1, 0);
  5272. + CVMX_MT_HSH_DAT(tmp2, 1);
  5273. + tmp3 |= 0x0000000080000000;
  5274. + CVMX_MT_HSH_DAT(tmp3, 2);
  5275. + CVMX_MT_HSH_DATZ(3);
  5276. + CVMX_MT_HSH_DATZ(4);
  5277. + CVMX_MT_HSH_DATZ(5);
  5278. + CVMX_MT_HSH_DATZ(6);
  5279. + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
  5280. +
  5281. + /* save the HMAC */
  5282. + SG_INIT(sg, data, data_i, data_l);
  5283. + while (icv_off > 0) {
  5284. + SG_CONSUME(sg, data, data_i, data_l);
  5285. + icv_off -= 8;
  5286. + }
  5287. + CVMX_MF_HSH_IV(*data, 0);
  5288. + SG_CONSUME(sg, data, data_i, data_l);
  5289. + CVMX_MF_HSH_IV(tmp1, 1);
  5290. + *(uint32_t *)data = (uint32_t) (tmp1 >> 32);
  5291. +
  5292. + octeon_crypto_disable(&state, flags);
  5293. + return 0;
  5294. +}
  5295. +
  5296. +/****************************************************************************/
  5297. +/* DES MD5 */
  5298. +
  5299. +int
  5300. +octo_des_cbc_md5_encrypt(
  5301. + struct octo_sess *od,
  5302. + struct scatterlist *sg, int sg_len,
  5303. + int auth_off, int auth_len,
  5304. + int crypt_off, int crypt_len,
  5305. + int icv_off, uint8_t *ivp)
  5306. +{
  5307. + register int next = 0;
  5308. + union {
  5309. + uint32_t data32[2];
  5310. + uint64_t data64[1];
  5311. + } mydata;
  5312. + uint64_t *data = &mydata.data64[0];
  5313. + uint32_t *data32;
  5314. + uint64_t tmp1, tmp2;
  5315. + int data_i, data_l, alen = auth_len;
  5316. + struct octeon_cop2_state state;
  5317. + unsigned long flags;
  5318. +
  5319. + dprintk("%s()\n", __FUNCTION__);
  5320. +
  5321. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  5322. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  5323. + (crypt_len & 0x7) ||
  5324. + (auth_len & 0x7) ||
  5325. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  5326. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  5327. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  5328. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  5329. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  5330. + return -EINVAL;
  5331. + }
  5332. +
  5333. + SG_INIT(sg, data32, data_i, data_l);
  5334. +
  5335. + CVMX_PREFETCH0(ivp);
  5336. + CVMX_PREFETCH0(od->octo_enckey);
  5337. +
  5338. + flags = octeon_crypto_enable(&state);
  5339. +
  5340. + /* load 3DES Key */
  5341. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  5342. + if (od->octo_encklen == 24) {
  5343. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  5344. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5345. + } else if (od->octo_encklen == 8) {
  5346. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  5347. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  5348. + } else {
  5349. + octeon_crypto_disable(&state, flags);
  5350. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  5351. + return -EINVAL;
  5352. + }
  5353. +
  5354. + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  5355. +
  5356. + /* Load MD5 IV */
  5357. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  5358. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  5359. +
  5360. + while (crypt_off > 0 && auth_off > 0) {
  5361. + SG_CONSUME(sg, data32, data_i, data_l);
  5362. + crypt_off -= 4;
  5363. + auth_off -= 4;
  5364. + }
  5365. +
  5366. + while (crypt_len > 0 || auth_len > 0) {
  5367. + uint32_t *first = data32;
  5368. + mydata.data32[0] = *first;
  5369. + SG_CONSUME(sg, data32, data_i, data_l);
  5370. + mydata.data32[1] = *data32;
  5371. + if (crypt_off <= 0) {
  5372. + if (crypt_len > 0) {
  5373. + CVMX_MT_3DES_ENC_CBC(*data);
  5374. + CVMX_MF_3DES_RESULT(*data);
  5375. + crypt_len -= 8;
  5376. + }
  5377. + } else
  5378. + crypt_off -= 8;
  5379. + if (auth_off <= 0) {
  5380. + if (auth_len > 0) {
  5381. + CVM_LOAD_MD5_UNIT(*data, next);
  5382. + auth_len -= 8;
  5383. + }
  5384. + } else
  5385. + auth_off -= 8;
  5386. + *first = mydata.data32[0];
  5387. + *data32 = mydata.data32[1];
  5388. + SG_CONSUME(sg, data32, data_i, data_l);
  5389. + }
  5390. +
  5391. + /* finish the hash */
  5392. + CVMX_PREFETCH0(od->octo_hmouter);
  5393. +#if 0
  5394. + if (unlikely(inplen)) {
  5395. + uint64_t tmp = 0;
  5396. + uint8_t *p = (uint8_t *) & tmp;
  5397. + p[inplen] = 0x80;
  5398. + do {
  5399. + inplen--;
  5400. + p[inplen] = ((uint8_t *) data)[inplen];
  5401. + } while (inplen);
  5402. + CVM_LOAD_MD5_UNIT(tmp, next);
  5403. + } else {
  5404. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  5405. + }
  5406. +#else
  5407. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  5408. +#endif
  5409. +
  5410. + /* Finish Inner hash */
  5411. + while (next != 7) {
  5412. + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
  5413. + }
  5414. + CVMX_ES64(tmp1, ((alen + 64) << 3));
  5415. + CVM_LOAD_MD5_UNIT(tmp1, next);
  5416. +
  5417. + /* Get the inner hash of HMAC */
  5418. + CVMX_MF_HSH_IV(tmp1, 0);
  5419. + CVMX_MF_HSH_IV(tmp2, 1);
  5420. +
  5421. + /* Initialize hash unit */
  5422. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  5423. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  5424. +
  5425. + CVMX_MT_HSH_DAT(tmp1, 0);
  5426. + CVMX_MT_HSH_DAT(tmp2, 1);
  5427. + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
  5428. + CVMX_MT_HSH_DATZ(3);
  5429. + CVMX_MT_HSH_DATZ(4);
  5430. + CVMX_MT_HSH_DATZ(5);
  5431. + CVMX_MT_HSH_DATZ(6);
  5432. + CVMX_ES64(tmp1, ((64 + 16) << 3));
  5433. + CVMX_MT_HSH_STARTMD5(tmp1);
  5434. +
  5435. + /* save the HMAC */
  5436. + SG_INIT(sg, data32, data_i, data_l);
  5437. + while (icv_off > 0) {
  5438. + SG_CONSUME(sg, data32, data_i, data_l);
  5439. + icv_off -= 4;
  5440. + }
  5441. + CVMX_MF_HSH_IV(tmp1, 0);
  5442. + *data32 = (uint32_t) (tmp1 >> 32);
  5443. + SG_CONSUME(sg, data32, data_i, data_l);
  5444. + *data32 = (uint32_t) tmp1;
  5445. + SG_CONSUME(sg, data32, data_i, data_l);
  5446. + CVMX_MF_HSH_IV(tmp1, 1);
  5447. + *data32 = (uint32_t) (tmp1 >> 32);
  5448. +
  5449. + octeon_crypto_disable(&state, flags);
  5450. + return 0;
  5451. +}
  5452. +
  5453. +int
  5454. +octo_des_cbc_md5_decrypt(
  5455. + struct octo_sess *od,
  5456. + struct scatterlist *sg, int sg_len,
  5457. + int auth_off, int auth_len,
  5458. + int crypt_off, int crypt_len,
  5459. + int icv_off, uint8_t *ivp)
  5460. +{
  5461. + register int next = 0;
  5462. + union {
  5463. + uint32_t data32[2];
  5464. + uint64_t data64[1];
  5465. + } mydata;
  5466. + uint64_t *data = &mydata.data64[0];
  5467. + uint32_t *data32;
  5468. + uint64_t tmp1, tmp2;
  5469. + int data_i, data_l, alen = auth_len;
  5470. + struct octeon_cop2_state state;
  5471. + unsigned long flags;
  5472. +
  5473. + dprintk("%s()\n", __FUNCTION__);
  5474. +
  5475. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  5476. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  5477. + (crypt_len & 0x7) ||
  5478. + (auth_len & 0x7) ||
  5479. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  5480. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  5481. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  5482. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  5483. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  5484. + return -EINVAL;
  5485. + }
  5486. +
  5487. + SG_INIT(sg, data32, data_i, data_l);
  5488. +
  5489. + CVMX_PREFETCH0(ivp);
  5490. + CVMX_PREFETCH0(od->octo_enckey);
  5491. +
  5492. + flags = octeon_crypto_enable(&state);
  5493. +
  5494. + /* load 3DES Key */
  5495. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  5496. + if (od->octo_encklen == 24) {
  5497. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  5498. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5499. + } else if (od->octo_encklen == 8) {
  5500. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  5501. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  5502. + } else {
  5503. + octeon_crypto_disable(&state, flags);
  5504. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  5505. + return -EINVAL;
  5506. + }
  5507. +
  5508. + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  5509. +
  5510. + /* Load MD5 IV */
  5511. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  5512. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  5513. +
  5514. + while (crypt_off > 0 && auth_off > 0) {
  5515. + SG_CONSUME(sg, data32, data_i, data_l);
  5516. + crypt_off -= 4;
  5517. + auth_off -= 4;
  5518. + }
  5519. +
  5520. + while (crypt_len > 0 || auth_len > 0) {
  5521. + uint32_t *first = data32;
  5522. + mydata.data32[0] = *first;
  5523. + SG_CONSUME(sg, data32, data_i, data_l);
  5524. + mydata.data32[1] = *data32;
  5525. + if (auth_off <= 0) {
  5526. + if (auth_len > 0) {
  5527. + CVM_LOAD_MD5_UNIT(*data, next);
  5528. + auth_len -= 8;
  5529. + }
  5530. + } else
  5531. + auth_off -= 8;
  5532. + if (crypt_off <= 0) {
  5533. + if (crypt_len > 0) {
  5534. + CVMX_MT_3DES_DEC_CBC(*data);
  5535. + CVMX_MF_3DES_RESULT(*data);
  5536. + crypt_len -= 8;
  5537. + }
  5538. + } else
  5539. + crypt_off -= 8;
  5540. + *first = mydata.data32[0];
  5541. + *data32 = mydata.data32[1];
  5542. + SG_CONSUME(sg, data32, data_i, data_l);
  5543. + }
  5544. +
  5545. + /* finish the hash */
  5546. + CVMX_PREFETCH0(od->octo_hmouter);
  5547. +#if 0
  5548. + if (unlikely(inplen)) {
  5549. + uint64_t tmp = 0;
  5550. + uint8_t *p = (uint8_t *) & tmp;
  5551. + p[inplen] = 0x80;
  5552. + do {
  5553. + inplen--;
  5554. + p[inplen] = ((uint8_t *) data)[inplen];
  5555. + } while (inplen);
  5556. + CVM_LOAD_MD5_UNIT(tmp, next);
  5557. + } else {
  5558. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  5559. + }
  5560. +#else
  5561. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  5562. +#endif
  5563. +
  5564. + /* Finish Inner hash */
  5565. + while (next != 7) {
  5566. + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
  5567. + }
  5568. + CVMX_ES64(tmp1, ((alen + 64) << 3));
  5569. + CVM_LOAD_MD5_UNIT(tmp1, next);
  5570. +
  5571. + /* Get the inner hash of HMAC */
  5572. + CVMX_MF_HSH_IV(tmp1, 0);
  5573. + CVMX_MF_HSH_IV(tmp2, 1);
  5574. +
  5575. + /* Initialize hash unit */
  5576. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  5577. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  5578. +
  5579. + CVMX_MT_HSH_DAT(tmp1, 0);
  5580. + CVMX_MT_HSH_DAT(tmp2, 1);
  5581. + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
  5582. + CVMX_MT_HSH_DATZ(3);
  5583. + CVMX_MT_HSH_DATZ(4);
  5584. + CVMX_MT_HSH_DATZ(5);
  5585. + CVMX_MT_HSH_DATZ(6);
  5586. + CVMX_ES64(tmp1, ((64 + 16) << 3));
  5587. + CVMX_MT_HSH_STARTMD5(tmp1);
  5588. +
  5589. + /* save the HMAC */
  5590. + SG_INIT(sg, data32, data_i, data_l);
  5591. + while (icv_off > 0) {
  5592. + SG_CONSUME(sg, data32, data_i, data_l);
  5593. + icv_off -= 4;
  5594. + }
  5595. + CVMX_MF_HSH_IV(tmp1, 0);
  5596. + *data32 = (uint32_t) (tmp1 >> 32);
  5597. + SG_CONSUME(sg, data32, data_i, data_l);
  5598. + *data32 = (uint32_t) tmp1;
  5599. + SG_CONSUME(sg, data32, data_i, data_l);
  5600. + CVMX_MF_HSH_IV(tmp1, 1);
  5601. + *data32 = (uint32_t) (tmp1 >> 32);
  5602. +
  5603. + octeon_crypto_disable(&state, flags);
  5604. + return 0;
  5605. +}
  5606. +
  5607. +/****************************************************************************/
  5608. +/* DES SHA */
  5609. +
  5610. +int
  5611. +octo_des_cbc_sha1_encrypt(
  5612. + struct octo_sess *od,
  5613. + struct scatterlist *sg, int sg_len,
  5614. + int auth_off, int auth_len,
  5615. + int crypt_off, int crypt_len,
  5616. + int icv_off, uint8_t *ivp)
  5617. +{
  5618. + register int next = 0;
  5619. + union {
  5620. + uint32_t data32[2];
  5621. + uint64_t data64[1];
  5622. + } mydata;
  5623. + uint64_t *data = &mydata.data64[0];
  5624. + uint32_t *data32;
  5625. + uint64_t tmp1, tmp2, tmp3;
  5626. + int data_i, data_l, alen = auth_len;
  5627. + struct octeon_cop2_state state;
  5628. + unsigned long flags;
  5629. +
  5630. + dprintk("%s()\n", __FUNCTION__);
  5631. +
  5632. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  5633. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  5634. + (crypt_len & 0x7) ||
  5635. + (auth_len & 0x7) ||
  5636. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  5637. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  5638. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  5639. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  5640. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  5641. + return -EINVAL;
  5642. + }
  5643. +
  5644. + SG_INIT(sg, data32, data_i, data_l);
  5645. +
  5646. + CVMX_PREFETCH0(ivp);
  5647. + CVMX_PREFETCH0(od->octo_enckey);
  5648. +
  5649. + flags = octeon_crypto_enable(&state);
  5650. +
  5651. + /* load 3DES Key */
  5652. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  5653. + if (od->octo_encklen == 24) {
  5654. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  5655. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5656. + } else if (od->octo_encklen == 8) {
  5657. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  5658. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  5659. + } else {
  5660. + octeon_crypto_disable(&state, flags);
  5661. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  5662. + return -EINVAL;
  5663. + }
  5664. +
  5665. + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  5666. +
  5667. + /* Load SHA1 IV */
  5668. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  5669. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  5670. + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
  5671. +
  5672. + while (crypt_off > 0 && auth_off > 0) {
  5673. + SG_CONSUME(sg, data32, data_i, data_l);
  5674. + crypt_off -= 4;
  5675. + auth_off -= 4;
  5676. + }
  5677. +
  5678. + while (crypt_len > 0 || auth_len > 0) {
  5679. + uint32_t *first = data32;
  5680. + mydata.data32[0] = *first;
  5681. + SG_CONSUME(sg, data32, data_i, data_l);
  5682. + mydata.data32[1] = *data32;
  5683. + if (crypt_off <= 0) {
  5684. + if (crypt_len > 0) {
  5685. + CVMX_MT_3DES_ENC_CBC(*data);
  5686. + CVMX_MF_3DES_RESULT(*data);
  5687. + crypt_len -= 8;
  5688. + }
  5689. + } else
  5690. + crypt_off -= 8;
  5691. + if (auth_off <= 0) {
  5692. + if (auth_len > 0) {
  5693. + CVM_LOAD_SHA_UNIT(*data, next);
  5694. + auth_len -= 8;
  5695. + }
  5696. + } else
  5697. + auth_off -= 8;
  5698. + *first = mydata.data32[0];
  5699. + *data32 = mydata.data32[1];
  5700. + SG_CONSUME(sg, data32, data_i, data_l);
  5701. + }
  5702. +
  5703. + /* finish the hash */
  5704. + CVMX_PREFETCH0(od->octo_hmouter);
  5705. +#if 0
  5706. + if (unlikely(inplen)) {
  5707. + uint64_t tmp = 0;
  5708. + uint8_t *p = (uint8_t *) & tmp;
  5709. + p[inplen] = 0x80;
  5710. + do {
  5711. + inplen--;
  5712. + p[inplen] = ((uint8_t *) data)[inplen];
  5713. + } while (inplen);
  5714. + CVM_LOAD_SHA_UNIT(tmp, next);
  5715. + } else {
  5716. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  5717. + }
  5718. +#else
  5719. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  5720. +#endif
  5721. +
  5722. + /* Finish Inner hash */
  5723. + while (next != 7) {
  5724. + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
  5725. + }
  5726. + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
  5727. +
  5728. + /* Get the inner hash of HMAC */
  5729. + CVMX_MF_HSH_IV(tmp1, 0);
  5730. + CVMX_MF_HSH_IV(tmp2, 1);
  5731. + tmp3 = 0;
  5732. + CVMX_MF_HSH_IV(tmp3, 2);
  5733. +
  5734. + /* Initialize hash unit */
  5735. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  5736. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  5737. + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
  5738. +
  5739. + CVMX_MT_HSH_DAT(tmp1, 0);
  5740. + CVMX_MT_HSH_DAT(tmp2, 1);
  5741. + tmp3 |= 0x0000000080000000;
  5742. + CVMX_MT_HSH_DAT(tmp3, 2);
  5743. + CVMX_MT_HSH_DATZ(3);
  5744. + CVMX_MT_HSH_DATZ(4);
  5745. + CVMX_MT_HSH_DATZ(5);
  5746. + CVMX_MT_HSH_DATZ(6);
  5747. + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
  5748. +
  5749. + /* save the HMAC */
  5750. + SG_INIT(sg, data32, data_i, data_l);
  5751. + while (icv_off > 0) {
  5752. + SG_CONSUME(sg, data32, data_i, data_l);
  5753. + icv_off -= 4;
  5754. + }
  5755. + CVMX_MF_HSH_IV(tmp1, 0);
  5756. + *data32 = (uint32_t) (tmp1 >> 32);
  5757. + SG_CONSUME(sg, data32, data_i, data_l);
  5758. + *data32 = (uint32_t) tmp1;
  5759. + SG_CONSUME(sg, data32, data_i, data_l);
  5760. + CVMX_MF_HSH_IV(tmp1, 1);
  5761. + *data32 = (uint32_t) (tmp1 >> 32);
  5762. +
  5763. + octeon_crypto_disable(&state, flags);
  5764. + return 0;
  5765. +}
  5766. +
  5767. +int
  5768. +octo_des_cbc_sha1_decrypt(
  5769. + struct octo_sess *od,
  5770. + struct scatterlist *sg, int sg_len,
  5771. + int auth_off, int auth_len,
  5772. + int crypt_off, int crypt_len,
  5773. + int icv_off, uint8_t *ivp)
  5774. +{
  5775. + register int next = 0;
  5776. + union {
  5777. + uint32_t data32[2];
  5778. + uint64_t data64[1];
  5779. + } mydata;
  5780. + uint64_t *data = &mydata.data64[0];
  5781. + uint32_t *data32;
  5782. + uint64_t tmp1, tmp2, tmp3;
  5783. + int data_i, data_l, alen = auth_len;
  5784. + struct octeon_cop2_state state;
  5785. + unsigned long flags;
  5786. +
  5787. + dprintk("%s()\n", __FUNCTION__);
  5788. +
  5789. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  5790. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  5791. + (crypt_len & 0x7) ||
  5792. + (auth_len & 0x7) ||
  5793. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  5794. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  5795. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  5796. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  5797. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  5798. + return -EINVAL;
  5799. + }
  5800. +
  5801. + SG_INIT(sg, data32, data_i, data_l);
  5802. +
  5803. + CVMX_PREFETCH0(ivp);
  5804. + CVMX_PREFETCH0(od->octo_enckey);
  5805. +
  5806. + flags = octeon_crypto_enable(&state);
  5807. +
  5808. + /* load 3DES Key */
  5809. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  5810. + if (od->octo_encklen == 24) {
  5811. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  5812. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5813. + } else if (od->octo_encklen == 8) {
  5814. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 1);
  5815. + CVMX_MT_3DES_KEY(((uint64_t *) od->octo_enckey)[0], 2);
  5816. + } else {
  5817. + octeon_crypto_disable(&state, flags);
  5818. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  5819. + return -EINVAL;
  5820. + }
  5821. +
  5822. + CVMX_MT_3DES_IV(* (uint64_t *) ivp);
  5823. +
  5824. + /* Load SHA1 IV */
  5825. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  5826. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  5827. + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
  5828. +
  5829. + while (crypt_off > 0 && auth_off > 0) {
  5830. + SG_CONSUME(sg, data32, data_i, data_l);
  5831. + crypt_off -= 4;
  5832. + auth_off -= 4;
  5833. + }
  5834. +
  5835. + while (crypt_len > 0 || auth_len > 0) {
  5836. + uint32_t *first = data32;
  5837. + mydata.data32[0] = *first;
  5838. + SG_CONSUME(sg, data32, data_i, data_l);
  5839. + mydata.data32[1] = *data32;
  5840. + if (auth_off <= 0) {
  5841. + if (auth_len > 0) {
  5842. + CVM_LOAD_SHA_UNIT(*data, next);
  5843. + auth_len -= 8;
  5844. + }
  5845. + } else
  5846. + auth_off -= 8;
  5847. + if (crypt_off <= 0) {
  5848. + if (crypt_len > 0) {
  5849. + CVMX_MT_3DES_DEC_CBC(*data);
  5850. + CVMX_MF_3DES_RESULT(*data);
  5851. + crypt_len -= 8;
  5852. + }
  5853. + } else
  5854. + crypt_off -= 8;
  5855. + *first = mydata.data32[0];
  5856. + *data32 = mydata.data32[1];
  5857. + SG_CONSUME(sg, data32, data_i, data_l);
  5858. + }
  5859. +
  5860. + /* finish the hash */
  5861. + CVMX_PREFETCH0(od->octo_hmouter);
  5862. +#if 0
  5863. + if (unlikely(inplen)) {
  5864. + uint64_t tmp = 0;
  5865. + uint8_t *p = (uint8_t *) & tmp;
  5866. + p[inplen] = 0x80;
  5867. + do {
  5868. + inplen--;
  5869. + p[inplen] = ((uint8_t *) data)[inplen];
  5870. + } while (inplen);
  5871. + CVM_LOAD_SHA_UNIT(tmp, next);
  5872. + } else {
  5873. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  5874. + }
  5875. +#else
  5876. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  5877. +#endif
  5878. +
  5879. + /* Finish Inner hash */
  5880. + while (next != 7) {
  5881. + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
  5882. + }
  5883. + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
  5884. +
  5885. + /* Get the inner hash of HMAC */
  5886. + CVMX_MF_HSH_IV(tmp1, 0);
  5887. + CVMX_MF_HSH_IV(tmp2, 1);
  5888. + tmp3 = 0;
  5889. + CVMX_MF_HSH_IV(tmp3, 2);
  5890. +
  5891. + /* Initialize hash unit */
  5892. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  5893. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  5894. + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
  5895. +
  5896. + CVMX_MT_HSH_DAT(tmp1, 0);
  5897. + CVMX_MT_HSH_DAT(tmp2, 1);
  5898. + tmp3 |= 0x0000000080000000;
  5899. + CVMX_MT_HSH_DAT(tmp3, 2);
  5900. + CVMX_MT_HSH_DATZ(3);
  5901. + CVMX_MT_HSH_DATZ(4);
  5902. + CVMX_MT_HSH_DATZ(5);
  5903. + CVMX_MT_HSH_DATZ(6);
  5904. + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
  5905. + /* save the HMAC */
  5906. + SG_INIT(sg, data32, data_i, data_l);
  5907. + while (icv_off > 0) {
  5908. + SG_CONSUME(sg, data32, data_i, data_l);
  5909. + icv_off -= 4;
  5910. + }
  5911. + CVMX_MF_HSH_IV(tmp1, 0);
  5912. + *data32 = (uint32_t) (tmp1 >> 32);
  5913. + SG_CONSUME(sg, data32, data_i, data_l);
  5914. + *data32 = (uint32_t) tmp1;
  5915. + SG_CONSUME(sg, data32, data_i, data_l);
  5916. + CVMX_MF_HSH_IV(tmp1, 1);
  5917. + *data32 = (uint32_t) (tmp1 >> 32);
  5918. +
  5919. + octeon_crypto_disable(&state, flags);
  5920. + return 0;
  5921. +}
  5922. +
  5923. +/****************************************************************************/
  5924. +/* AES MD5 */
  5925. +
  5926. +int
  5927. +octo_aes_cbc_md5_encrypt(
  5928. + struct octo_sess *od,
  5929. + struct scatterlist *sg, int sg_len,
  5930. + int auth_off, int auth_len,
  5931. + int crypt_off, int crypt_len,
  5932. + int icv_off, uint8_t *ivp)
  5933. +{
  5934. + register int next = 0;
  5935. + union {
  5936. + uint32_t data32[2];
  5937. + uint64_t data64[1];
  5938. + } mydata[2];
  5939. + uint64_t *pdata = &mydata[0].data64[0];
  5940. + uint64_t *data = &mydata[1].data64[0];
  5941. + uint32_t *data32;
  5942. + uint64_t tmp1, tmp2;
  5943. + int data_i, data_l, alen = auth_len;
  5944. + struct octeon_cop2_state state;
  5945. + unsigned long flags;
  5946. +
  5947. + dprintk("%s()\n", __FUNCTION__);
  5948. +
  5949. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  5950. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  5951. + (crypt_len & 0x7) ||
  5952. + (auth_len & 0x7) ||
  5953. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  5954. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  5955. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  5956. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  5957. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  5958. + return -EINVAL;
  5959. + }
  5960. +
  5961. + SG_INIT(sg, data32, data_i, data_l);
  5962. +
  5963. + CVMX_PREFETCH0(ivp);
  5964. + CVMX_PREFETCH0(od->octo_enckey);
  5965. +
  5966. + flags = octeon_crypto_enable(&state);
  5967. +
  5968. + /* load AES Key */
  5969. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  5970. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  5971. +
  5972. + if (od->octo_encklen == 16) {
  5973. + CVMX_MT_AES_KEY(0x0, 2);
  5974. + CVMX_MT_AES_KEY(0x0, 3);
  5975. + } else if (od->octo_encklen == 24) {
  5976. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5977. + CVMX_MT_AES_KEY(0x0, 3);
  5978. + } else if (od->octo_encklen == 32) {
  5979. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  5980. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  5981. + } else {
  5982. + octeon_crypto_disable(&state, flags);
  5983. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  5984. + return -EINVAL;
  5985. + }
  5986. + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  5987. +
  5988. + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  5989. + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  5990. +
  5991. + /* Load MD5 IV */
  5992. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  5993. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  5994. +
  5995. + while (crypt_off > 0 && auth_off > 0) {
  5996. + SG_CONSUME(sg, data32, data_i, data_l);
  5997. + crypt_off -= 4;
  5998. + auth_off -= 4;
  5999. + }
  6000. +
  6001. + /* align auth and crypt */
  6002. + while (crypt_off > 0 && auth_len > 0) {
  6003. + mydata[0].data32[0] = *data32;
  6004. + SG_CONSUME(sg, data32, data_i, data_l);
  6005. + mydata[0].data32[1] = *data32;
  6006. + SG_CONSUME(sg, data32, data_i, data_l);
  6007. + CVM_LOAD_MD5_UNIT(*pdata, next);
  6008. + crypt_off -= 8;
  6009. + auth_len -= 8;
  6010. + }
  6011. +
  6012. + while (crypt_len > 0) {
  6013. + uint32_t *pdata32[3];
  6014. +
  6015. + pdata32[0] = data32;
  6016. + mydata[0].data32[0] = *data32;
  6017. + SG_CONSUME(sg, data32, data_i, data_l);
  6018. +
  6019. + pdata32[1] = data32;
  6020. + mydata[0].data32[1] = *data32;
  6021. + SG_CONSUME(sg, data32, data_i, data_l);
  6022. +
  6023. + pdata32[2] = data32;
  6024. + mydata[1].data32[0] = *data32;
  6025. + SG_CONSUME(sg, data32, data_i, data_l);
  6026. +
  6027. + mydata[1].data32[1] = *data32;
  6028. +
  6029. + CVMX_MT_AES_ENC_CBC0(*pdata);
  6030. + CVMX_MT_AES_ENC_CBC1(*data);
  6031. + CVMX_MF_AES_RESULT(*pdata, 0);
  6032. + CVMX_MF_AES_RESULT(*data, 1);
  6033. + crypt_len -= 16;
  6034. +
  6035. + if (auth_len > 0) {
  6036. + CVM_LOAD_MD5_UNIT(*pdata, next);
  6037. + auth_len -= 8;
  6038. + }
  6039. + if (auth_len > 0) {
  6040. + CVM_LOAD_MD5_UNIT(*data, next);
  6041. + auth_len -= 8;
  6042. + }
  6043. +
  6044. + *pdata32[0] = mydata[0].data32[0];
  6045. + *pdata32[1] = mydata[0].data32[1];
  6046. + *pdata32[2] = mydata[1].data32[0];
  6047. + *data32 = mydata[1].data32[1];
  6048. +
  6049. + SG_CONSUME(sg, data32, data_i, data_l);
  6050. + }
  6051. +
  6052. + /* finish any left over hashing */
  6053. + while (auth_len > 0) {
  6054. + mydata[0].data32[0] = *data32;
  6055. + SG_CONSUME(sg, data32, data_i, data_l);
  6056. + mydata[0].data32[1] = *data32;
  6057. + SG_CONSUME(sg, data32, data_i, data_l);
  6058. + CVM_LOAD_MD5_UNIT(*pdata, next);
  6059. + auth_len -= 8;
  6060. + }
  6061. +
  6062. + /* finish the hash */
  6063. + CVMX_PREFETCH0(od->octo_hmouter);
  6064. +#if 0
  6065. + if (unlikely(inplen)) {
  6066. + uint64_t tmp = 0;
  6067. + uint8_t *p = (uint8_t *) & tmp;
  6068. + p[inplen] = 0x80;
  6069. + do {
  6070. + inplen--;
  6071. + p[inplen] = ((uint8_t *) data)[inplen];
  6072. + } while (inplen);
  6073. + CVM_LOAD_MD5_UNIT(tmp, next);
  6074. + } else {
  6075. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  6076. + }
  6077. +#else
  6078. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  6079. +#endif
  6080. +
  6081. + /* Finish Inner hash */
  6082. + while (next != 7) {
  6083. + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
  6084. + }
  6085. + CVMX_ES64(tmp1, ((alen + 64) << 3));
  6086. + CVM_LOAD_MD5_UNIT(tmp1, next);
  6087. +
  6088. + /* Get the inner hash of HMAC */
  6089. + CVMX_MF_HSH_IV(tmp1, 0);
  6090. + CVMX_MF_HSH_IV(tmp2, 1);
  6091. +
  6092. + /* Initialize hash unit */
  6093. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  6094. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  6095. +
  6096. + CVMX_MT_HSH_DAT(tmp1, 0);
  6097. + CVMX_MT_HSH_DAT(tmp2, 1);
  6098. + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
  6099. + CVMX_MT_HSH_DATZ(3);
  6100. + CVMX_MT_HSH_DATZ(4);
  6101. + CVMX_MT_HSH_DATZ(5);
  6102. + CVMX_MT_HSH_DATZ(6);
  6103. + CVMX_ES64(tmp1, ((64 + 16) << 3));
  6104. + CVMX_MT_HSH_STARTMD5(tmp1);
  6105. +
  6106. + /* save the HMAC */
  6107. + SG_INIT(sg, data32, data_i, data_l);
  6108. + while (icv_off > 0) {
  6109. + SG_CONSUME(sg, data32, data_i, data_l);
  6110. + icv_off -= 4;
  6111. + }
  6112. + CVMX_MF_HSH_IV(tmp1, 0);
  6113. + *data32 = (uint32_t) (tmp1 >> 32);
  6114. + SG_CONSUME(sg, data32, data_i, data_l);
  6115. + *data32 = (uint32_t) tmp1;
  6116. + SG_CONSUME(sg, data32, data_i, data_l);
  6117. + CVMX_MF_HSH_IV(tmp1, 1);
  6118. + *data32 = (uint32_t) (tmp1 >> 32);
  6119. +
  6120. + octeon_crypto_disable(&state, flags);
  6121. + return 0;
  6122. +}
  6123. +
  6124. +int
  6125. +octo_aes_cbc_md5_decrypt(
  6126. + struct octo_sess *od,
  6127. + struct scatterlist *sg, int sg_len,
  6128. + int auth_off, int auth_len,
  6129. + int crypt_off, int crypt_len,
  6130. + int icv_off, uint8_t *ivp)
  6131. +{
  6132. + register int next = 0;
  6133. + union {
  6134. + uint32_t data32[2];
  6135. + uint64_t data64[1];
  6136. + } mydata[2];
  6137. + uint64_t *pdata = &mydata[0].data64[0];
  6138. + uint64_t *data = &mydata[1].data64[0];
  6139. + uint32_t *data32;
  6140. + uint64_t tmp1, tmp2;
  6141. + int data_i, data_l, alen = auth_len;
  6142. + struct octeon_cop2_state state;
  6143. + unsigned long flags;
  6144. +
  6145. + dprintk("%s()\n", __FUNCTION__);
  6146. +
  6147. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  6148. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  6149. + (crypt_len & 0x7) ||
  6150. + (auth_len & 0x7) ||
  6151. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  6152. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  6153. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  6154. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  6155. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  6156. + return -EINVAL;
  6157. + }
  6158. +
  6159. + SG_INIT(sg, data32, data_i, data_l);
  6160. +
  6161. + CVMX_PREFETCH0(ivp);
  6162. + CVMX_PREFETCH0(od->octo_enckey);
  6163. +
  6164. + flags = octeon_crypto_enable(&state);
  6165. +
  6166. + /* load AES Key */
  6167. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  6168. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  6169. +
  6170. + if (od->octo_encklen == 16) {
  6171. + CVMX_MT_AES_KEY(0x0, 2);
  6172. + CVMX_MT_AES_KEY(0x0, 3);
  6173. + } else if (od->octo_encklen == 24) {
  6174. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  6175. + CVMX_MT_AES_KEY(0x0, 3);
  6176. + } else if (od->octo_encklen == 32) {
  6177. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  6178. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  6179. + } else {
  6180. + octeon_crypto_disable(&state, flags);
  6181. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  6182. + return -EINVAL;
  6183. + }
  6184. + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  6185. +
  6186. + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  6187. + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  6188. +
  6189. + /* Load MD5 IV */
  6190. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  6191. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  6192. +
  6193. + while (crypt_off > 0 && auth_off > 0) {
  6194. + SG_CONSUME(sg, data32, data_i, data_l);
  6195. + crypt_off -= 4;
  6196. + auth_off -= 4;
  6197. + }
  6198. +
  6199. + /* align auth and crypt */
  6200. + while (crypt_off > 0 && auth_len > 0) {
  6201. + mydata[0].data32[0] = *data32;
  6202. + SG_CONSUME(sg, data32, data_i, data_l);
  6203. + mydata[0].data32[1] = *data32;
  6204. + SG_CONSUME(sg, data32, data_i, data_l);
  6205. + CVM_LOAD_MD5_UNIT(*pdata, next);
  6206. + crypt_off -= 8;
  6207. + auth_len -= 8;
  6208. + }
  6209. +
  6210. + while (crypt_len > 0) {
  6211. + uint32_t *pdata32[3];
  6212. +
  6213. + pdata32[0] = data32;
  6214. + mydata[0].data32[0] = *data32;
  6215. + SG_CONSUME(sg, data32, data_i, data_l);
  6216. + pdata32[1] = data32;
  6217. + mydata[0].data32[1] = *data32;
  6218. + SG_CONSUME(sg, data32, data_i, data_l);
  6219. + pdata32[2] = data32;
  6220. + mydata[1].data32[0] = *data32;
  6221. + SG_CONSUME(sg, data32, data_i, data_l);
  6222. + mydata[1].data32[1] = *data32;
  6223. +
  6224. + if (auth_len > 0) {
  6225. + CVM_LOAD_MD5_UNIT(*pdata, next);
  6226. + auth_len -= 8;
  6227. + }
  6228. +
  6229. + if (auth_len > 0) {
  6230. + CVM_LOAD_MD5_UNIT(*data, next);
  6231. + auth_len -= 8;
  6232. + }
  6233. +
  6234. + CVMX_MT_AES_DEC_CBC0(*pdata);
  6235. + CVMX_MT_AES_DEC_CBC1(*data);
  6236. + CVMX_MF_AES_RESULT(*pdata, 0);
  6237. + CVMX_MF_AES_RESULT(*data, 1);
  6238. + crypt_len -= 16;
  6239. +
  6240. + *pdata32[0] = mydata[0].data32[0];
  6241. + *pdata32[1] = mydata[0].data32[1];
  6242. + *pdata32[2] = mydata[1].data32[0];
  6243. + *data32 = mydata[1].data32[1];
  6244. +
  6245. + SG_CONSUME(sg, data32, data_i, data_l);
  6246. + }
  6247. +
  6248. + /* finish left over hash if any */
  6249. + while (auth_len > 0) {
  6250. + mydata[0].data32[0] = *data32;
  6251. + SG_CONSUME(sg, data32, data_i, data_l);
  6252. + mydata[0].data32[1] = *data32;
  6253. + SG_CONSUME(sg, data32, data_i, data_l);
  6254. + CVM_LOAD_MD5_UNIT(*pdata, next);
  6255. + auth_len -= 8;
  6256. + }
  6257. +
  6258. +
  6259. + /* finish the hash */
  6260. + CVMX_PREFETCH0(od->octo_hmouter);
  6261. +#if 0
  6262. + if (unlikely(inplen)) {
  6263. + uint64_t tmp = 0;
  6264. + uint8_t *p = (uint8_t *) & tmp;
  6265. + p[inplen] = 0x80;
  6266. + do {
  6267. + inplen--;
  6268. + p[inplen] = ((uint8_t *) data)[inplen];
  6269. + } while (inplen);
  6270. + CVM_LOAD_MD5_UNIT(tmp, next);
  6271. + } else {
  6272. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  6273. + }
  6274. +#else
  6275. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  6276. +#endif
  6277. +
  6278. + /* Finish Inner hash */
  6279. + while (next != 7) {
  6280. + CVM_LOAD_MD5_UNIT(((uint64_t) 0x0ULL), next);
  6281. + }
  6282. + CVMX_ES64(tmp1, ((alen + 64) << 3));
  6283. + CVM_LOAD_MD5_UNIT(tmp1, next);
  6284. +
  6285. + /* Get the inner hash of HMAC */
  6286. + CVMX_MF_HSH_IV(tmp1, 0);
  6287. + CVMX_MF_HSH_IV(tmp2, 1);
  6288. +
  6289. + /* Initialize hash unit */
  6290. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  6291. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  6292. +
  6293. + CVMX_MT_HSH_DAT(tmp1, 0);
  6294. + CVMX_MT_HSH_DAT(tmp2, 1);
  6295. + CVMX_MT_HSH_DAT(0x8000000000000000ULL, 2);
  6296. + CVMX_MT_HSH_DATZ(3);
  6297. + CVMX_MT_HSH_DATZ(4);
  6298. + CVMX_MT_HSH_DATZ(5);
  6299. + CVMX_MT_HSH_DATZ(6);
  6300. + CVMX_ES64(tmp1, ((64 + 16) << 3));
  6301. + CVMX_MT_HSH_STARTMD5(tmp1);
  6302. +
  6303. + /* save the HMAC */
  6304. + SG_INIT(sg, data32, data_i, data_l);
  6305. + while (icv_off > 0) {
  6306. + SG_CONSUME(sg, data32, data_i, data_l);
  6307. + icv_off -= 4;
  6308. + }
  6309. + CVMX_MF_HSH_IV(tmp1, 0);
  6310. + *data32 = (uint32_t) (tmp1 >> 32);
  6311. + SG_CONSUME(sg, data32, data_i, data_l);
  6312. + *data32 = (uint32_t) tmp1;
  6313. + SG_CONSUME(sg, data32, data_i, data_l);
  6314. + CVMX_MF_HSH_IV(tmp1, 1);
  6315. + *data32 = (uint32_t) (tmp1 >> 32);
  6316. +
  6317. + octeon_crypto_disable(&state, flags);
  6318. + return 0;
  6319. +}
  6320. +
  6321. +/****************************************************************************/
  6322. +/* AES SHA1 */
  6323. +
  6324. +int
  6325. +octo_aes_cbc_sha1_encrypt(
  6326. + struct octo_sess *od,
  6327. + struct scatterlist *sg, int sg_len,
  6328. + int auth_off, int auth_len,
  6329. + int crypt_off, int crypt_len,
  6330. + int icv_off, uint8_t *ivp)
  6331. +{
  6332. + register int next = 0;
  6333. + union {
  6334. + uint32_t data32[2];
  6335. + uint64_t data64[1];
  6336. + } mydata[2];
  6337. + uint64_t *pdata = &mydata[0].data64[0];
  6338. + uint64_t *data = &mydata[1].data64[0];
  6339. + uint32_t *data32;
  6340. + uint64_t tmp1, tmp2, tmp3;
  6341. + int data_i, data_l, alen = auth_len;
  6342. + struct octeon_cop2_state state;
  6343. + unsigned long flags;
  6344. +
  6345. + dprintk("%s(a_off=%d a_len=%d c_off=%d c_len=%d icv_off=%d)\n",
  6346. + __FUNCTION__, auth_off, auth_len, crypt_off, crypt_len, icv_off);
  6347. +
  6348. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  6349. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  6350. + (crypt_len & 0x7) ||
  6351. + (auth_len & 0x7) ||
  6352. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  6353. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  6354. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  6355. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  6356. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  6357. + return -EINVAL;
  6358. + }
  6359. +
  6360. + SG_INIT(sg, data32, data_i, data_l);
  6361. +
  6362. + CVMX_PREFETCH0(ivp);
  6363. + CVMX_PREFETCH0(od->octo_enckey);
  6364. +
  6365. + flags = octeon_crypto_enable(&state);
  6366. +
  6367. + /* load AES Key */
  6368. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  6369. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  6370. +
  6371. + if (od->octo_encklen == 16) {
  6372. + CVMX_MT_AES_KEY(0x0, 2);
  6373. + CVMX_MT_AES_KEY(0x0, 3);
  6374. + } else if (od->octo_encklen == 24) {
  6375. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  6376. + CVMX_MT_AES_KEY(0x0, 3);
  6377. + } else if (od->octo_encklen == 32) {
  6378. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  6379. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  6380. + } else {
  6381. + octeon_crypto_disable(&state, flags);
  6382. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  6383. + return -EINVAL;
  6384. + }
  6385. + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  6386. +
  6387. + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  6388. + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  6389. +
  6390. + /* Load SHA IV */
  6391. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  6392. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  6393. + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
  6394. +
  6395. + while (crypt_off > 0 && auth_off > 0) {
  6396. + SG_CONSUME(sg, data32, data_i, data_l);
  6397. + crypt_off -= 4;
  6398. + auth_off -= 4;
  6399. + }
  6400. +
  6401. + /* align auth and crypt */
  6402. + while (crypt_off > 0 && auth_len > 0) {
  6403. + mydata[0].data32[0] = *data32;
  6404. + SG_CONSUME(sg, data32, data_i, data_l);
  6405. + mydata[0].data32[1] = *data32;
  6406. + SG_CONSUME(sg, data32, data_i, data_l);
  6407. + CVM_LOAD_SHA_UNIT(*pdata, next);
  6408. + crypt_off -= 8;
  6409. + auth_len -= 8;
  6410. + }
  6411. +
  6412. + while (crypt_len > 0) {
  6413. + uint32_t *pdata32[3];
  6414. +
  6415. + pdata32[0] = data32;
  6416. + mydata[0].data32[0] = *data32;
  6417. + SG_CONSUME(sg, data32, data_i, data_l);
  6418. + pdata32[1] = data32;
  6419. + mydata[0].data32[1] = *data32;
  6420. + SG_CONSUME(sg, data32, data_i, data_l);
  6421. + pdata32[2] = data32;
  6422. + mydata[1].data32[0] = *data32;
  6423. + SG_CONSUME(sg, data32, data_i, data_l);
  6424. + mydata[1].data32[1] = *data32;
  6425. +
  6426. + CVMX_MT_AES_ENC_CBC0(*pdata);
  6427. + CVMX_MT_AES_ENC_CBC1(*data);
  6428. + CVMX_MF_AES_RESULT(*pdata, 0);
  6429. + CVMX_MF_AES_RESULT(*data, 1);
  6430. + crypt_len -= 16;
  6431. +
  6432. + if (auth_len > 0) {
  6433. + CVM_LOAD_SHA_UNIT(*pdata, next);
  6434. + auth_len -= 8;
  6435. + }
  6436. + if (auth_len > 0) {
  6437. + CVM_LOAD_SHA_UNIT(*data, next);
  6438. + auth_len -= 8;
  6439. + }
  6440. +
  6441. + *pdata32[0] = mydata[0].data32[0];
  6442. + *pdata32[1] = mydata[0].data32[1];
  6443. + *pdata32[2] = mydata[1].data32[0];
  6444. + *data32 = mydata[1].data32[1];
  6445. +
  6446. + SG_CONSUME(sg, data32, data_i, data_l);
  6447. + }
  6448. +
  6449. + /* finish and hashing */
  6450. + while (auth_len > 0) {
  6451. + mydata[0].data32[0] = *data32;
  6452. + SG_CONSUME(sg, data32, data_i, data_l);
  6453. + mydata[0].data32[1] = *data32;
  6454. + SG_CONSUME(sg, data32, data_i, data_l);
  6455. + CVM_LOAD_SHA_UNIT(*pdata, next);
  6456. + auth_len -= 8;
  6457. + }
  6458. +
  6459. + /* finish the hash */
  6460. + CVMX_PREFETCH0(od->octo_hmouter);
  6461. +#if 0
  6462. + if (unlikely(inplen)) {
  6463. + uint64_t tmp = 0;
  6464. + uint8_t *p = (uint8_t *) & tmp;
  6465. + p[inplen] = 0x80;
  6466. + do {
  6467. + inplen--;
  6468. + p[inplen] = ((uint8_t *) data)[inplen];
  6469. + } while (inplen);
  6470. + CVM_LOAD_SHA_UNIT(tmp, next);
  6471. + } else {
  6472. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  6473. + }
  6474. +#else
  6475. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  6476. +#endif
  6477. +
  6478. + /* Finish Inner hash */
  6479. + while (next != 7) {
  6480. + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
  6481. + }
  6482. + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
  6483. +
  6484. + /* Get the inner hash of HMAC */
  6485. + CVMX_MF_HSH_IV(tmp1, 0);
  6486. + CVMX_MF_HSH_IV(tmp2, 1);
  6487. + tmp3 = 0;
  6488. + CVMX_MF_HSH_IV(tmp3, 2);
  6489. +
  6490. + /* Initialize hash unit */
  6491. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  6492. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  6493. + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
  6494. +
  6495. + CVMX_MT_HSH_DAT(tmp1, 0);
  6496. + CVMX_MT_HSH_DAT(tmp2, 1);
  6497. + tmp3 |= 0x0000000080000000;
  6498. + CVMX_MT_HSH_DAT(tmp3, 2);
  6499. + CVMX_MT_HSH_DATZ(3);
  6500. + CVMX_MT_HSH_DATZ(4);
  6501. + CVMX_MT_HSH_DATZ(5);
  6502. + CVMX_MT_HSH_DATZ(6);
  6503. + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
  6504. +
  6505. + /* finish the hash */
  6506. + CVMX_PREFETCH0(od->octo_hmouter);
  6507. +#if 0
  6508. + if (unlikely(inplen)) {
  6509. + uint64_t tmp = 0;
  6510. + uint8_t *p = (uint8_t *) & tmp;
  6511. + p[inplen] = 0x80;
  6512. + do {
  6513. + inplen--;
  6514. + p[inplen] = ((uint8_t *) data)[inplen];
  6515. + } while (inplen);
  6516. + CVM_LOAD_MD5_UNIT(tmp, next);
  6517. + } else {
  6518. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  6519. + }
  6520. +#else
  6521. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  6522. +#endif
  6523. +
  6524. + /* save the HMAC */
  6525. + SG_INIT(sg, data32, data_i, data_l);
  6526. + while (icv_off > 0) {
  6527. + SG_CONSUME(sg, data32, data_i, data_l);
  6528. + icv_off -= 4;
  6529. + }
  6530. + CVMX_MF_HSH_IV(tmp1, 0);
  6531. + *data32 = (uint32_t) (tmp1 >> 32);
  6532. + SG_CONSUME(sg, data32, data_i, data_l);
  6533. + *data32 = (uint32_t) tmp1;
  6534. + SG_CONSUME(sg, data32, data_i, data_l);
  6535. + CVMX_MF_HSH_IV(tmp1, 1);
  6536. + *data32 = (uint32_t) (tmp1 >> 32);
  6537. +
  6538. + octeon_crypto_disable(&state, flags);
  6539. + return 0;
  6540. +}
  6541. +
  6542. +int
  6543. +octo_aes_cbc_sha1_decrypt(
  6544. + struct octo_sess *od,
  6545. + struct scatterlist *sg, int sg_len,
  6546. + int auth_off, int auth_len,
  6547. + int crypt_off, int crypt_len,
  6548. + int icv_off, uint8_t *ivp)
  6549. +{
  6550. + register int next = 0;
  6551. + union {
  6552. + uint32_t data32[2];
  6553. + uint64_t data64[1];
  6554. + } mydata[2];
  6555. + uint64_t *pdata = &mydata[0].data64[0];
  6556. + uint64_t *data = &mydata[1].data64[0];
  6557. + uint32_t *data32;
  6558. + uint64_t tmp1, tmp2, tmp3;
  6559. + int data_i, data_l, alen = auth_len;
  6560. + struct octeon_cop2_state state;
  6561. + unsigned long flags;
  6562. +
  6563. + dprintk("%s(a_off=%d a_len=%d c_off=%d c_len=%d icv_off=%d)\n",
  6564. + __FUNCTION__, auth_off, auth_len, crypt_off, crypt_len, icv_off);
  6565. +
  6566. + if (unlikely(od == NULL || sg==NULL || sg_len==0 || ivp==NULL ||
  6567. + (crypt_off & 0x3) || (crypt_off + crypt_len > sg_len) ||
  6568. + (crypt_len & 0x7) ||
  6569. + (auth_len & 0x7) ||
  6570. + (auth_off & 0x3) || (auth_off + auth_len > sg_len))) {
  6571. + dprintk("%s: Bad parameters od=%p sg=%p sg_len=%d "
  6572. + "auth_off=%d auth_len=%d crypt_off=%d crypt_len=%d "
  6573. + "icv_off=%d ivp=%p\n", __FUNCTION__, od, sg, sg_len,
  6574. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  6575. + return -EINVAL;
  6576. + }
  6577. +
  6578. + SG_INIT(sg, data32, data_i, data_l);
  6579. +
  6580. + CVMX_PREFETCH0(ivp);
  6581. + CVMX_PREFETCH0(od->octo_enckey);
  6582. +
  6583. + flags = octeon_crypto_enable(&state);
  6584. +
  6585. + /* load AES Key */
  6586. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[0], 0);
  6587. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[1], 1);
  6588. +
  6589. + if (od->octo_encklen == 16) {
  6590. + CVMX_MT_AES_KEY(0x0, 2);
  6591. + CVMX_MT_AES_KEY(0x0, 3);
  6592. + } else if (od->octo_encklen == 24) {
  6593. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  6594. + CVMX_MT_AES_KEY(0x0, 3);
  6595. + } else if (od->octo_encklen == 32) {
  6596. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[2], 2);
  6597. + CVMX_MT_AES_KEY(((uint64_t *) od->octo_enckey)[3], 3);
  6598. + } else {
  6599. + octeon_crypto_disable(&state, flags);
  6600. + dprintk("%s: Bad key length %d\n", __FUNCTION__, od->octo_encklen);
  6601. + return -EINVAL;
  6602. + }
  6603. + CVMX_MT_AES_KEYLENGTH(od->octo_encklen / 8 - 1);
  6604. +
  6605. + CVMX_MT_AES_IV(((uint64_t *) ivp)[0], 0);
  6606. + CVMX_MT_AES_IV(((uint64_t *) ivp)[1], 1);
  6607. +
  6608. + /* Load SHA1 IV */
  6609. + CVMX_MT_HSH_IV(od->octo_hminner[0], 0);
  6610. + CVMX_MT_HSH_IV(od->octo_hminner[1], 1);
  6611. + CVMX_MT_HSH_IV(od->octo_hminner[2], 2);
  6612. +
  6613. + while (crypt_off > 0 && auth_off > 0) {
  6614. + SG_CONSUME(sg, data32, data_i, data_l);
  6615. + crypt_off -= 4;
  6616. + auth_off -= 4;
  6617. + }
  6618. +
  6619. + /* align auth and crypt */
  6620. + while (crypt_off > 0 && auth_len > 0) {
  6621. + mydata[0].data32[0] = *data32;
  6622. + SG_CONSUME(sg, data32, data_i, data_l);
  6623. + mydata[0].data32[1] = *data32;
  6624. + SG_CONSUME(sg, data32, data_i, data_l);
  6625. + CVM_LOAD_SHA_UNIT(*pdata, next);
  6626. + crypt_off -= 8;
  6627. + auth_len -= 8;
  6628. + }
  6629. +
  6630. + while (crypt_len > 0) {
  6631. + uint32_t *pdata32[3];
  6632. +
  6633. + pdata32[0] = data32;
  6634. + mydata[0].data32[0] = *data32;
  6635. + SG_CONSUME(sg, data32, data_i, data_l);
  6636. + pdata32[1] = data32;
  6637. + mydata[0].data32[1] = *data32;
  6638. + SG_CONSUME(sg, data32, data_i, data_l);
  6639. + pdata32[2] = data32;
  6640. + mydata[1].data32[0] = *data32;
  6641. + SG_CONSUME(sg, data32, data_i, data_l);
  6642. + mydata[1].data32[1] = *data32;
  6643. +
  6644. + if (auth_len > 0) {
  6645. + CVM_LOAD_SHA_UNIT(*pdata, next);
  6646. + auth_len -= 8;
  6647. + }
  6648. + if (auth_len > 0) {
  6649. + CVM_LOAD_SHA_UNIT(*data, next);
  6650. + auth_len -= 8;
  6651. + }
  6652. +
  6653. + CVMX_MT_AES_DEC_CBC0(*pdata);
  6654. + CVMX_MT_AES_DEC_CBC1(*data);
  6655. + CVMX_MF_AES_RESULT(*pdata, 0);
  6656. + CVMX_MF_AES_RESULT(*data, 1);
  6657. + crypt_len -= 16;
  6658. +
  6659. + *pdata32[0] = mydata[0].data32[0];
  6660. + *pdata32[1] = mydata[0].data32[1];
  6661. + *pdata32[2] = mydata[1].data32[0];
  6662. + *data32 = mydata[1].data32[1];
  6663. +
  6664. + SG_CONSUME(sg, data32, data_i, data_l);
  6665. + }
  6666. +
  6667. + /* finish and leftover hashing */
  6668. + while (auth_len > 0) {
  6669. + mydata[0].data32[0] = *data32;
  6670. + SG_CONSUME(sg, data32, data_i, data_l);
  6671. + mydata[0].data32[1] = *data32;
  6672. + SG_CONSUME(sg, data32, data_i, data_l);
  6673. + CVM_LOAD_SHA_UNIT(*pdata, next);
  6674. + auth_len -= 8;
  6675. + }
  6676. +
  6677. + /* finish the hash */
  6678. + CVMX_PREFETCH0(od->octo_hmouter);
  6679. +#if 0
  6680. + if (unlikely(inplen)) {
  6681. + uint64_t tmp = 0;
  6682. + uint8_t *p = (uint8_t *) & tmp;
  6683. + p[inplen] = 0x80;
  6684. + do {
  6685. + inplen--;
  6686. + p[inplen] = ((uint8_t *) data)[inplen];
  6687. + } while (inplen);
  6688. + CVM_LOAD_SHA_UNIT(tmp, next);
  6689. + } else {
  6690. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  6691. + }
  6692. +#else
  6693. + CVM_LOAD_SHA_UNIT(0x8000000000000000ULL, next);
  6694. +#endif
  6695. +
  6696. + /* Finish Inner hash */
  6697. + while (next != 7) {
  6698. + CVM_LOAD_SHA_UNIT(((uint64_t) 0x0ULL), next);
  6699. + }
  6700. + CVM_LOAD_SHA_UNIT((uint64_t) ((alen + 64) << 3), next);
  6701. +
  6702. + /* Get the inner hash of HMAC */
  6703. + CVMX_MF_HSH_IV(tmp1, 0);
  6704. + CVMX_MF_HSH_IV(tmp2, 1);
  6705. + tmp3 = 0;
  6706. + CVMX_MF_HSH_IV(tmp3, 2);
  6707. +
  6708. + /* Initialize hash unit */
  6709. + CVMX_MT_HSH_IV(od->octo_hmouter[0], 0);
  6710. + CVMX_MT_HSH_IV(od->octo_hmouter[1], 1);
  6711. + CVMX_MT_HSH_IV(od->octo_hmouter[2], 2);
  6712. +
  6713. + CVMX_MT_HSH_DAT(tmp1, 0);
  6714. + CVMX_MT_HSH_DAT(tmp2, 1);
  6715. + tmp3 |= 0x0000000080000000;
  6716. + CVMX_MT_HSH_DAT(tmp3, 2);
  6717. + CVMX_MT_HSH_DATZ(3);
  6718. + CVMX_MT_HSH_DATZ(4);
  6719. + CVMX_MT_HSH_DATZ(5);
  6720. + CVMX_MT_HSH_DATZ(6);
  6721. + CVMX_MT_HSH_STARTSHA((uint64_t) ((64 + 20) << 3));
  6722. +
  6723. + /* finish the hash */
  6724. + CVMX_PREFETCH0(od->octo_hmouter);
  6725. +#if 0
  6726. + if (unlikely(inplen)) {
  6727. + uint64_t tmp = 0;
  6728. + uint8_t *p = (uint8_t *) & tmp;
  6729. + p[inplen] = 0x80;
  6730. + do {
  6731. + inplen--;
  6732. + p[inplen] = ((uint8_t *) data)[inplen];
  6733. + } while (inplen);
  6734. + CVM_LOAD_MD5_UNIT(tmp, next);
  6735. + } else {
  6736. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  6737. + }
  6738. +#else
  6739. + CVM_LOAD_MD5_UNIT(0x8000000000000000ULL, next);
  6740. +#endif
  6741. +
  6742. + /* save the HMAC */
  6743. + SG_INIT(sg, data32, data_i, data_l);
  6744. + while (icv_off > 0) {
  6745. + SG_CONSUME(sg, data32, data_i, data_l);
  6746. + icv_off -= 4;
  6747. + }
  6748. + CVMX_MF_HSH_IV(tmp1, 0);
  6749. + *data32 = (uint32_t) (tmp1 >> 32);
  6750. + SG_CONSUME(sg, data32, data_i, data_l);
  6751. + *data32 = (uint32_t) tmp1;
  6752. + SG_CONSUME(sg, data32, data_i, data_l);
  6753. + CVMX_MF_HSH_IV(tmp1, 1);
  6754. + *data32 = (uint32_t) (tmp1 >> 32);
  6755. +
  6756. + octeon_crypto_disable(&state, flags);
  6757. + return 0;
  6758. +}
  6759. +
  6760. +/****************************************************************************/
  6761. diff -Nur linux-2.6.39.orig/crypto/ocf/cryptocteon/cryptocteon.c linux-2.6.39/crypto/ocf/cryptocteon/cryptocteon.c
  6762. --- linux-2.6.39.orig/crypto/ocf/cryptocteon/cryptocteon.c 1970-01-01 01:00:00.000000000 +0100
  6763. +++ linux-2.6.39/crypto/ocf/cryptocteon/cryptocteon.c 2011-08-01 14:38:18.000000000 +0200
  6764. @@ -0,0 +1,574 @@
  6765. +/*
  6766. + * Octeon Crypto for OCF
  6767. + *
  6768. + * Written by David McCullough <david_mccullough@mcafee.com>
  6769. + * Copyright (C) 2009-2010 David McCullough
  6770. + *
  6771. + * LICENSE TERMS
  6772. + *
  6773. + * The free distribution and use of this software in both source and binary
  6774. + * form is allowed (with or without changes) provided that:
  6775. + *
  6776. + * 1. distributions of this source code include the above copyright
  6777. + * notice, this list of conditions and the following disclaimer;
  6778. + *
  6779. + * 2. distributions in binary form include the above copyright
  6780. + * notice, this list of conditions and the following disclaimer
  6781. + * in the documentation and/or other associated materials;
  6782. + *
  6783. + * 3. the copyright holder's name is not used to endorse products
  6784. + * built using this software without specific written permission.
  6785. + *
  6786. + * DISCLAIMER
  6787. + *
  6788. + * This software is provided 'as is' with no explicit or implied warranties
  6789. + * in respect of its properties, including, but not limited to, correctness
  6790. + * and/or fitness for purpose.
  6791. + * ---------------------------------------------------------------------------
  6792. + */
  6793. +
  6794. +#ifndef AUTOCONF_INCLUDED
  6795. +#include <linux/config.h>
  6796. +#endif
  6797. +#include <linux/module.h>
  6798. +#include <linux/init.h>
  6799. +#include <linux/list.h>
  6800. +#include <linux/slab.h>
  6801. +#include <linux/sched.h>
  6802. +#include <linux/wait.h>
  6803. +#include <linux/crypto.h>
  6804. +#include <linux/mm.h>
  6805. +#include <linux/skbuff.h>
  6806. +#include <linux/random.h>
  6807. +#include <linux/scatterlist.h>
  6808. +
  6809. +#include <cryptodev.h>
  6810. +#include <uio.h>
  6811. +
  6812. +struct {
  6813. + softc_device_decl sc_dev;
  6814. +} octo_softc;
  6815. +
  6816. +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
  6817. +
  6818. +struct octo_sess {
  6819. + int octo_encalg;
  6820. + #define MAX_CIPHER_KEYLEN 64
  6821. + char octo_enckey[MAX_CIPHER_KEYLEN];
  6822. + int octo_encklen;
  6823. +
  6824. + int octo_macalg;
  6825. + #define MAX_HASH_KEYLEN 64
  6826. + char octo_mackey[MAX_HASH_KEYLEN];
  6827. + int octo_macklen;
  6828. + int octo_mackey_set;
  6829. +
  6830. + int octo_mlen;
  6831. + int octo_ivsize;
  6832. +
  6833. +#if 0
  6834. + int (*octo_decrypt)(struct scatterlist *sg, int sg_len,
  6835. + uint8_t *key, int key_len, uint8_t * iv,
  6836. + uint64_t *hminner, uint64_t *hmouter);
  6837. +
  6838. + int (*octo_encrypt)(struct scatterlist *sg, int sg_len,
  6839. + uint8_t *key, int key_len, uint8_t * iv,
  6840. + uint64_t *hminner, uint64_t *hmouter);
  6841. +#else
  6842. + int (*octo_encrypt)(struct octo_sess *od,
  6843. + struct scatterlist *sg, int sg_len,
  6844. + int auth_off, int auth_len,
  6845. + int crypt_off, int crypt_len,
  6846. + int icv_off, uint8_t *ivp);
  6847. + int (*octo_decrypt)(struct octo_sess *od,
  6848. + struct scatterlist *sg, int sg_len,
  6849. + int auth_off, int auth_len,
  6850. + int crypt_off, int crypt_len,
  6851. + int icv_off, uint8_t *ivp);
  6852. +#endif
  6853. +
  6854. + uint64_t octo_hminner[3];
  6855. + uint64_t octo_hmouter[3];
  6856. +};
  6857. +
  6858. +int32_t octo_id = -1;
  6859. +module_param(octo_id, int, 0444);
  6860. +MODULE_PARM_DESC(octo_id, "Read-Only OCF ID for cryptocteon driver");
  6861. +
  6862. +static struct octo_sess **octo_sessions = NULL;
  6863. +static u_int32_t octo_sesnum = 0;
  6864. +
  6865. +static int octo_process(device_t, struct cryptop *, int);
  6866. +static int octo_newsession(device_t, u_int32_t *, struct cryptoini *);
  6867. +static int octo_freesession(device_t, u_int64_t);
  6868. +
  6869. +static device_method_t octo_methods = {
  6870. + /* crypto device methods */
  6871. + DEVMETHOD(cryptodev_newsession, octo_newsession),
  6872. + DEVMETHOD(cryptodev_freesession,octo_freesession),
  6873. + DEVMETHOD(cryptodev_process, octo_process),
  6874. +};
  6875. +
  6876. +#define debug octo_debug
  6877. +int octo_debug = 0;
  6878. +module_param(octo_debug, int, 0644);
  6879. +MODULE_PARM_DESC(octo_debug, "Enable debug");
  6880. +
  6881. +
  6882. +#include "cavium_crypto.c"
  6883. +
  6884. +
  6885. +/*
  6886. + * Generate a new octo session. We artifically limit it to a single
  6887. + * hash/cipher or hash-cipher combo just to make it easier, most callers
  6888. + * do not expect more than this anyway.
  6889. + */
  6890. +static int
  6891. +octo_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  6892. +{
  6893. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  6894. + struct octo_sess **ocd;
  6895. + int i;
  6896. +
  6897. + dprintk("%s()\n", __FUNCTION__);
  6898. + if (sid == NULL || cri == NULL) {
  6899. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  6900. + return EINVAL;
  6901. + }
  6902. +
  6903. + /*
  6904. + * To keep it simple, we only handle hash, cipher or hash/cipher in a
  6905. + * session, you cannot currently do multiple ciphers/hashes in one
  6906. + * session even though it would be possibel to code this driver to
  6907. + * handle it.
  6908. + */
  6909. + for (i = 0, c = cri; c && i < 2; i++) {
  6910. + if (c->cri_alg == CRYPTO_MD5_HMAC ||
  6911. + c->cri_alg == CRYPTO_SHA1_HMAC ||
  6912. + c->cri_alg == CRYPTO_NULL_HMAC) {
  6913. + if (macini) {
  6914. + break;
  6915. + }
  6916. + macini = c;
  6917. + }
  6918. + if (c->cri_alg == CRYPTO_DES_CBC ||
  6919. + c->cri_alg == CRYPTO_3DES_CBC ||
  6920. + c->cri_alg == CRYPTO_AES_CBC ||
  6921. + c->cri_alg == CRYPTO_NULL_CBC) {
  6922. + if (encini) {
  6923. + break;
  6924. + }
  6925. + encini = c;
  6926. + }
  6927. + c = c->cri_next;
  6928. + }
  6929. + if (!macini && !encini) {
  6930. + dprintk("%s,%d - EINVAL bad cipher/hash or combination\n",
  6931. + __FILE__, __LINE__);
  6932. + return EINVAL;
  6933. + }
  6934. + if (c) {
  6935. + dprintk("%s,%d - EINVAL cannot handle chained cipher/hash combos\n",
  6936. + __FILE__, __LINE__);
  6937. + return EINVAL;
  6938. + }
  6939. +
  6940. + /*
  6941. + * So we have something we can do, lets setup the session
  6942. + */
  6943. +
  6944. + if (octo_sessions) {
  6945. + for (i = 1; i < octo_sesnum; i++)
  6946. + if (octo_sessions[i] == NULL)
  6947. + break;
  6948. + } else
  6949. + i = 1; /* NB: to silence compiler warning */
  6950. +
  6951. + if (octo_sessions == NULL || i == octo_sesnum) {
  6952. + if (octo_sessions == NULL) {
  6953. + i = 1; /* We leave octo_sessions[0] empty */
  6954. + octo_sesnum = CRYPTO_SW_SESSIONS;
  6955. + } else
  6956. + octo_sesnum *= 2;
  6957. +
  6958. + ocd = kmalloc(octo_sesnum * sizeof(struct octo_sess *), SLAB_ATOMIC);
  6959. + if (ocd == NULL) {
  6960. + /* Reset session number */
  6961. + if (octo_sesnum == CRYPTO_SW_SESSIONS)
  6962. + octo_sesnum = 0;
  6963. + else
  6964. + octo_sesnum /= 2;
  6965. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  6966. + return ENOBUFS;
  6967. + }
  6968. + memset(ocd, 0, octo_sesnum * sizeof(struct octo_sess *));
  6969. +
  6970. + /* Copy existing sessions */
  6971. + if (octo_sessions) {
  6972. + memcpy(ocd, octo_sessions,
  6973. + (octo_sesnum / 2) * sizeof(struct octo_sess *));
  6974. + kfree(octo_sessions);
  6975. + }
  6976. +
  6977. + octo_sessions = ocd;
  6978. + }
  6979. +
  6980. + ocd = &octo_sessions[i];
  6981. + *sid = i;
  6982. +
  6983. +
  6984. + *ocd = (struct octo_sess *) kmalloc(sizeof(struct octo_sess), SLAB_ATOMIC);
  6985. + if (*ocd == NULL) {
  6986. + octo_freesession(NULL, i);
  6987. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  6988. + return ENOBUFS;
  6989. + }
  6990. + memset(*ocd, 0, sizeof(struct octo_sess));
  6991. +
  6992. + if (encini && encini->cri_key) {
  6993. + (*ocd)->octo_encklen = (encini->cri_klen + 7) / 8;
  6994. + memcpy((*ocd)->octo_enckey, encini->cri_key, (*ocd)->octo_encklen);
  6995. + }
  6996. +
  6997. + if (macini && macini->cri_key) {
  6998. + (*ocd)->octo_macklen = (macini->cri_klen + 7) / 8;
  6999. + memcpy((*ocd)->octo_mackey, macini->cri_key, (*ocd)->octo_macklen);
  7000. + }
  7001. +
  7002. + (*ocd)->octo_mlen = 0;
  7003. + if (encini && encini->cri_mlen)
  7004. + (*ocd)->octo_mlen = encini->cri_mlen;
  7005. + else if (macini && macini->cri_mlen)
  7006. + (*ocd)->octo_mlen = macini->cri_mlen;
  7007. + else
  7008. + (*ocd)->octo_mlen = 12;
  7009. +
  7010. + /*
  7011. + * point c at the enc if it exists, otherwise the mac
  7012. + */
  7013. + c = encini ? encini : macini;
  7014. +
  7015. + switch (c->cri_alg) {
  7016. + case CRYPTO_DES_CBC:
  7017. + case CRYPTO_3DES_CBC:
  7018. + (*ocd)->octo_ivsize = 8;
  7019. + switch (macini ? macini->cri_alg : -1) {
  7020. + case CRYPTO_MD5_HMAC:
  7021. + (*ocd)->octo_encrypt = octo_des_cbc_md5_encrypt;
  7022. + (*ocd)->octo_decrypt = octo_des_cbc_md5_decrypt;
  7023. + octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,
  7024. + (*ocd)->octo_hmouter);
  7025. + break;
  7026. + case CRYPTO_SHA1_HMAC:
  7027. + (*ocd)->octo_encrypt = octo_des_cbc_sha1_encrypt;
  7028. + (*ocd)->octo_decrypt = octo_des_cbc_sha1_encrypt;
  7029. + octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,
  7030. + (*ocd)->octo_hmouter);
  7031. + break;
  7032. + case -1:
  7033. + (*ocd)->octo_encrypt = octo_des_cbc_encrypt;
  7034. + (*ocd)->octo_decrypt = octo_des_cbc_decrypt;
  7035. + break;
  7036. + default:
  7037. + octo_freesession(NULL, i);
  7038. + dprintk("%s,%d: EINVALn", __FILE__, __LINE__);
  7039. + return EINVAL;
  7040. + }
  7041. + break;
  7042. + case CRYPTO_AES_CBC:
  7043. + (*ocd)->octo_ivsize = 16;
  7044. + switch (macini ? macini->cri_alg : -1) {
  7045. + case CRYPTO_MD5_HMAC:
  7046. + (*ocd)->octo_encrypt = octo_aes_cbc_md5_encrypt;
  7047. + (*ocd)->octo_decrypt = octo_aes_cbc_md5_decrypt;
  7048. + octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,
  7049. + (*ocd)->octo_hmouter);
  7050. + break;
  7051. + case CRYPTO_SHA1_HMAC:
  7052. + (*ocd)->octo_encrypt = octo_aes_cbc_sha1_encrypt;
  7053. + (*ocd)->octo_decrypt = octo_aes_cbc_sha1_decrypt;
  7054. + octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,
  7055. + (*ocd)->octo_hmouter);
  7056. + break;
  7057. + case -1:
  7058. + (*ocd)->octo_encrypt = octo_aes_cbc_encrypt;
  7059. + (*ocd)->octo_decrypt = octo_aes_cbc_decrypt;
  7060. + break;
  7061. + default:
  7062. + octo_freesession(NULL, i);
  7063. + dprintk("%s,%d: EINVALn", __FILE__, __LINE__);
  7064. + return EINVAL;
  7065. + }
  7066. + break;
  7067. + case CRYPTO_MD5_HMAC:
  7068. + (*ocd)->octo_encrypt = octo_null_md5_encrypt;
  7069. + (*ocd)->octo_decrypt = octo_null_md5_encrypt;
  7070. + octo_calc_hash(0, macini->cri_key, (*ocd)->octo_hminner,
  7071. + (*ocd)->octo_hmouter);
  7072. + break;
  7073. + case CRYPTO_SHA1_HMAC:
  7074. + (*ocd)->octo_encrypt = octo_null_sha1_encrypt;
  7075. + (*ocd)->octo_decrypt = octo_null_sha1_encrypt;
  7076. + octo_calc_hash(1, macini->cri_key, (*ocd)->octo_hminner,
  7077. + (*ocd)->octo_hmouter);
  7078. + break;
  7079. + default:
  7080. + octo_freesession(NULL, i);
  7081. + dprintk("%s,%d: EINVALn", __FILE__, __LINE__);
  7082. + return EINVAL;
  7083. + }
  7084. +
  7085. + (*ocd)->octo_encalg = encini ? encini->cri_alg : -1;
  7086. + (*ocd)->octo_macalg = macini ? macini->cri_alg : -1;
  7087. +
  7088. + return 0;
  7089. +}
  7090. +
  7091. +/*
  7092. + * Free a session.
  7093. + */
  7094. +static int
  7095. +octo_freesession(device_t dev, u_int64_t tid)
  7096. +{
  7097. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  7098. +
  7099. + dprintk("%s()\n", __FUNCTION__);
  7100. + if (sid > octo_sesnum || octo_sessions == NULL ||
  7101. + octo_sessions[sid] == NULL) {
  7102. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  7103. + return(EINVAL);
  7104. + }
  7105. +
  7106. + /* Silently accept and return */
  7107. + if (sid == 0)
  7108. + return(0);
  7109. +
  7110. + if (octo_sessions[sid])
  7111. + kfree(octo_sessions[sid]);
  7112. + octo_sessions[sid] = NULL;
  7113. + return 0;
  7114. +}
  7115. +
  7116. +/*
  7117. + * Process a request.
  7118. + */
  7119. +static int
  7120. +octo_process(device_t dev, struct cryptop *crp, int hint)
  7121. +{
  7122. + struct cryptodesc *crd;
  7123. + struct octo_sess *od;
  7124. + u_int32_t lid;
  7125. +#define SCATTERLIST_MAX 16
  7126. + struct scatterlist sg[SCATTERLIST_MAX];
  7127. + int sg_num, sg_len;
  7128. + struct sk_buff *skb = NULL;
  7129. + struct uio *uiop = NULL;
  7130. + struct cryptodesc *enccrd = NULL, *maccrd = NULL;
  7131. + unsigned char *ivp = NULL;
  7132. + unsigned char iv_data[HASH_MAX_LEN];
  7133. + int auth_off = 0, auth_len = 0, crypt_off = 0, crypt_len = 0, icv_off = 0;
  7134. +
  7135. + dprintk("%s()\n", __FUNCTION__);
  7136. + /* Sanity check */
  7137. + if (crp == NULL) {
  7138. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  7139. + return EINVAL;
  7140. + }
  7141. +
  7142. + crp->crp_etype = 0;
  7143. +
  7144. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  7145. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  7146. + crp->crp_etype = EINVAL;
  7147. + goto done;
  7148. + }
  7149. +
  7150. + lid = crp->crp_sid & 0xffffffff;
  7151. + if (lid >= octo_sesnum || lid == 0 || octo_sessions == NULL ||
  7152. + octo_sessions[lid] == NULL) {
  7153. + crp->crp_etype = ENOENT;
  7154. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  7155. + goto done;
  7156. + }
  7157. + od = octo_sessions[lid];
  7158. +
  7159. + /*
  7160. + * do some error checking outside of the loop for SKB and IOV processing
  7161. + * this leaves us with valid skb or uiop pointers for later
  7162. + */
  7163. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  7164. + skb = (struct sk_buff *) crp->crp_buf;
  7165. + if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
  7166. + printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__,
  7167. + skb_shinfo(skb)->nr_frags);
  7168. + goto done;
  7169. + }
  7170. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  7171. + uiop = (struct uio *) crp->crp_buf;
  7172. + if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
  7173. + printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__,
  7174. + uiop->uio_iovcnt);
  7175. + goto done;
  7176. + }
  7177. + }
  7178. +
  7179. + /* point our enccrd and maccrd appropriately */
  7180. + crd = crp->crp_desc;
  7181. + if (crd->crd_alg == od->octo_encalg) enccrd = crd;
  7182. + if (crd->crd_alg == od->octo_macalg) maccrd = crd;
  7183. + crd = crd->crd_next;
  7184. + if (crd) {
  7185. + if (crd->crd_alg == od->octo_encalg) enccrd = crd;
  7186. + if (crd->crd_alg == od->octo_macalg) maccrd = crd;
  7187. + crd = crd->crd_next;
  7188. + }
  7189. + if (crd) {
  7190. + crp->crp_etype = EINVAL;
  7191. + dprintk("%s,%d: ENOENT - descriptors do not match session\n",
  7192. + __FILE__, __LINE__);
  7193. + goto done;
  7194. + }
  7195. +
  7196. + if (enccrd) {
  7197. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  7198. + ivp = enccrd->crd_iv;
  7199. + } else {
  7200. + ivp = iv_data;
  7201. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  7202. + enccrd->crd_inject, od->octo_ivsize, (caddr_t) ivp);
  7203. + }
  7204. +
  7205. + if (maccrd) {
  7206. + auth_off = maccrd->crd_skip;
  7207. + auth_len = maccrd->crd_len;
  7208. + icv_off = maccrd->crd_inject;
  7209. + }
  7210. +
  7211. + crypt_off = enccrd->crd_skip;
  7212. + crypt_len = enccrd->crd_len;
  7213. + } else { /* if (maccrd) */
  7214. + auth_off = maccrd->crd_skip;
  7215. + auth_len = maccrd->crd_len;
  7216. + icv_off = maccrd->crd_inject;
  7217. + }
  7218. +
  7219. +
  7220. + /*
  7221. + * setup the SG list to cover the buffer
  7222. + */
  7223. + memset(sg, 0, sizeof(sg));
  7224. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  7225. + int i, len;
  7226. +
  7227. + sg_num = 0;
  7228. + sg_len = 0;
  7229. +
  7230. + len = skb_headlen(skb);
  7231. + sg_set_page(&sg[sg_num], virt_to_page(skb->data), len,
  7232. + offset_in_page(skb->data));
  7233. + sg_len += len;
  7234. + sg_num++;
  7235. +
  7236. + for (i = 0; i < skb_shinfo(skb)->nr_frags && sg_num < SCATTERLIST_MAX;
  7237. + i++) {
  7238. + len = skb_shinfo(skb)->frags[i].size;
  7239. + sg_set_page(&sg[sg_num], skb_shinfo(skb)->frags[i].page,
  7240. + len, skb_shinfo(skb)->frags[i].page_offset);
  7241. + sg_len += len;
  7242. + sg_num++;
  7243. + }
  7244. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  7245. + int len;
  7246. +
  7247. + sg_len = 0;
  7248. + for (sg_num = 0; sg_len < crp->crp_ilen &&
  7249. + sg_num < uiop->uio_iovcnt &&
  7250. + sg_num < SCATTERLIST_MAX; sg_num++) {
  7251. + len = uiop->uio_iov[sg_num].iov_len;
  7252. + sg_set_page(&sg[sg_num],
  7253. + virt_to_page(uiop->uio_iov[sg_num].iov_base), len,
  7254. + offset_in_page(uiop->uio_iov[sg_num].iov_base));
  7255. + sg_len += len;
  7256. + }
  7257. + } else {
  7258. + sg_len = crp->crp_ilen;
  7259. + sg_set_page(&sg[0], virt_to_page(crp->crp_buf), sg_len,
  7260. + offset_in_page(crp->crp_buf));
  7261. + sg_num = 1;
  7262. + }
  7263. +
  7264. +
  7265. + /*
  7266. + * setup a new explicit key
  7267. + */
  7268. + if (enccrd) {
  7269. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
  7270. + od->octo_encklen = (enccrd->crd_klen + 7) / 8;
  7271. + memcpy(od->octo_enckey, enccrd->crd_key, od->octo_encklen);
  7272. + }
  7273. + }
  7274. + if (maccrd) {
  7275. + if (maccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
  7276. + od->octo_macklen = (maccrd->crd_klen + 7) / 8;
  7277. + memcpy(od->octo_mackey, maccrd->crd_key, od->octo_macklen);
  7278. + od->octo_mackey_set = 0;
  7279. + }
  7280. + if (!od->octo_mackey_set) {
  7281. + octo_calc_hash(maccrd->crd_alg == CRYPTO_MD5_HMAC ? 0 : 1,
  7282. + maccrd->crd_key, od->octo_hminner, od->octo_hmouter);
  7283. + od->octo_mackey_set = 1;
  7284. + }
  7285. + }
  7286. +
  7287. +
  7288. + if (!enccrd || (enccrd->crd_flags & CRD_F_ENCRYPT))
  7289. + (*od->octo_encrypt)(od, sg, sg_len,
  7290. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  7291. + else
  7292. + (*od->octo_decrypt)(od, sg, sg_len,
  7293. + auth_off, auth_len, crypt_off, crypt_len, icv_off, ivp);
  7294. +
  7295. +done:
  7296. + crypto_done(crp);
  7297. + return 0;
  7298. +}
  7299. +
  7300. +static int
  7301. +cryptocteon_init(void)
  7302. +{
  7303. + dprintk("%s(%p)\n", __FUNCTION__, cryptocteon_init);
  7304. +
  7305. + softc_device_init(&octo_softc, "cryptocteon", 0, octo_methods);
  7306. +
  7307. + octo_id = crypto_get_driverid(softc_get_device(&octo_softc),
  7308. + CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SYNC);
  7309. + if (octo_id < 0) {
  7310. + printk("Cryptocteon device cannot initialize!");
  7311. + return -ENODEV;
  7312. + }
  7313. +
  7314. + crypto_register(octo_id, CRYPTO_MD5_HMAC, 0,0);
  7315. + crypto_register(octo_id, CRYPTO_SHA1_HMAC, 0,0);
  7316. + //crypto_register(octo_id, CRYPTO_MD5, 0,0);
  7317. + //crypto_register(octo_id, CRYPTO_SHA1, 0,0);
  7318. + crypto_register(octo_id, CRYPTO_DES_CBC, 0,0);
  7319. + crypto_register(octo_id, CRYPTO_3DES_CBC, 0,0);
  7320. + crypto_register(octo_id, CRYPTO_AES_CBC, 0,0);
  7321. +
  7322. + return(0);
  7323. +}
  7324. +
  7325. +static void
  7326. +cryptocteon_exit(void)
  7327. +{
  7328. + dprintk("%s()\n", __FUNCTION__);
  7329. + crypto_unregister_all(octo_id);
  7330. + octo_id = -1;
  7331. +}
  7332. +
  7333. +module_init(cryptocteon_init);
  7334. +module_exit(cryptocteon_exit);
  7335. +
  7336. +MODULE_LICENSE("BSD");
  7337. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  7338. +MODULE_DESCRIPTION("Cryptocteon (OCF module for Cavium OCTEON crypto)");
  7339. diff -Nur linux-2.6.39.orig/crypto/ocf/cryptodev.c linux-2.6.39/crypto/ocf/cryptodev.c
  7340. --- linux-2.6.39.orig/crypto/ocf/cryptodev.c 1970-01-01 01:00:00.000000000 +0100
  7341. +++ linux-2.6.39/crypto/ocf/cryptodev.c 2011-08-01 14:38:54.000000000 +0200
  7342. @@ -0,0 +1,1057 @@
  7343. +/* $OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $ */
  7344. +
  7345. +/*-
  7346. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  7347. + * Copyright (C) 2006-2010 David McCullough
  7348. + * Copyright (C) 2004-2005 Intel Corporation.
  7349. + * The license and original author are listed below.
  7350. + *
  7351. + * Copyright (c) 2001 Theo de Raadt
  7352. + * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
  7353. + *
  7354. + * Redistribution and use in source and binary forms, with or without
  7355. + * modification, are permitted provided that the following conditions
  7356. + * are met:
  7357. + *
  7358. + * 1. Redistributions of source code must retain the above copyright
  7359. + * notice, this list of conditions and the following disclaimer.
  7360. + * 2. Redistributions in binary form must reproduce the above copyright
  7361. + * notice, this list of conditions and the following disclaimer in the
  7362. + * documentation and/or other materials provided with the distribution.
  7363. + * 3. The name of the author may not be used to endorse or promote products
  7364. + * derived from this software without specific prior written permission.
  7365. + *
  7366. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  7367. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  7368. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  7369. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  7370. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  7371. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  7372. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  7373. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  7374. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  7375. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  7376. + *
  7377. + * Effort sponsored in part by the Defense Advanced Research Projects
  7378. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  7379. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  7380. + *
  7381. +__FBSDID("$FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.34 2007/05/09 19:37:02 gnn Exp $");
  7382. + */
  7383. +
  7384. +#include <linux/types.h>
  7385. +#include <linux/time.h>
  7386. +#include <linux/delay.h>
  7387. +#include <linux/list.h>
  7388. +#include <linux/init.h>
  7389. +#include <linux/sched.h>
  7390. +#include <linux/unistd.h>
  7391. +#include <linux/module.h>
  7392. +#include <linux/wait.h>
  7393. +#include <linux/slab.h>
  7394. +#include <linux/fs.h>
  7395. +#include <linux/dcache.h>
  7396. +#include <linux/file.h>
  7397. +#include <linux/mount.h>
  7398. +#include <linux/miscdevice.h>
  7399. +#include <linux/version.h>
  7400. +#include <asm/uaccess.h>
  7401. +
  7402. +#include <cryptodev.h>
  7403. +#include <uio.h>
  7404. +
  7405. +extern asmlinkage long sys_dup(unsigned int fildes);
  7406. +
  7407. +#define debug cryptodev_debug
  7408. +int cryptodev_debug = 0;
  7409. +module_param(cryptodev_debug, int, 0644);
  7410. +MODULE_PARM_DESC(cryptodev_debug, "Enable cryptodev debug");
  7411. +
  7412. +struct csession_info {
  7413. + u_int16_t blocksize;
  7414. + u_int16_t minkey, maxkey;
  7415. +
  7416. + u_int16_t keysize;
  7417. + /* u_int16_t hashsize; */
  7418. + u_int16_t authsize;
  7419. + u_int16_t authkey;
  7420. + /* u_int16_t ctxsize; */
  7421. +};
  7422. +
  7423. +struct csession {
  7424. + struct list_head list;
  7425. + u_int64_t sid;
  7426. + u_int32_t ses;
  7427. +
  7428. + wait_queue_head_t waitq;
  7429. +
  7430. + u_int32_t cipher;
  7431. +
  7432. + u_int32_t mac;
  7433. +
  7434. + caddr_t key;
  7435. + int keylen;
  7436. + u_char tmp_iv[EALG_MAX_BLOCK_LEN];
  7437. +
  7438. + caddr_t mackey;
  7439. + int mackeylen;
  7440. +
  7441. + struct csession_info info;
  7442. +
  7443. + struct iovec iovec;
  7444. + struct uio uio;
  7445. + int error;
  7446. +};
  7447. +
  7448. +struct fcrypt {
  7449. + struct list_head csessions;
  7450. + int sesn;
  7451. +};
  7452. +
  7453. +static struct csession *csefind(struct fcrypt *, u_int);
  7454. +static int csedelete(struct fcrypt *, struct csession *);
  7455. +static struct csession *cseadd(struct fcrypt *, struct csession *);
  7456. +static struct csession *csecreate(struct fcrypt *, u_int64_t,
  7457. + struct cryptoini *crie, struct cryptoini *cria, struct csession_info *);
  7458. +static int csefree(struct csession *);
  7459. +
  7460. +static int cryptodev_op(struct csession *, struct crypt_op *);
  7461. +static int cryptodev_key(struct crypt_kop *);
  7462. +static int cryptodev_find(struct crypt_find_op *);
  7463. +
  7464. +static int cryptodev_cb(void *);
  7465. +static int cryptodev_open(struct inode *inode, struct file *filp);
  7466. +
  7467. +/*
  7468. + * Check a crypto identifier to see if it requested
  7469. + * a valid crid and it's capabilities match.
  7470. + */
  7471. +static int
  7472. +checkcrid(int crid)
  7473. +{
  7474. + int hid = crid & ~(CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
  7475. + int typ = crid & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE);
  7476. + int caps = 0;
  7477. +
  7478. + /* if the user hasn't selected a driver, then just call newsession */
  7479. + if (hid == 0 && typ != 0)
  7480. + return 0;
  7481. +
  7482. + caps = crypto_getcaps(hid);
  7483. +
  7484. + /* didn't find anything with capabilities */
  7485. + if (caps == 0) {
  7486. + dprintk("%s: hid=%x typ=%x not matched\n", __FUNCTION__, hid, typ);
  7487. + return EINVAL;
  7488. + }
  7489. +
  7490. + /* the user didn't specify SW or HW, so the driver is ok */
  7491. + if (typ == 0)
  7492. + return 0;
  7493. +
  7494. + /* if the type specified didn't match */
  7495. + if (typ != (caps & (CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_HARDWARE))) {
  7496. + dprintk("%s: hid=%x typ=%x caps=%x not matched\n", __FUNCTION__,
  7497. + hid, typ, caps);
  7498. + return EINVAL;
  7499. + }
  7500. +
  7501. + return 0;
  7502. +}
  7503. +
  7504. +static int
  7505. +cryptodev_op(struct csession *cse, struct crypt_op *cop)
  7506. +{
  7507. + struct cryptop *crp = NULL;
  7508. + struct cryptodesc *crde = NULL, *crda = NULL;
  7509. + int error = 0;
  7510. +
  7511. + dprintk("%s()\n", __FUNCTION__);
  7512. + if (cop->len > CRYPTO_MAX_DATA_LEN) {
  7513. + dprintk("%s: %d > %d\n", __FUNCTION__, cop->len, CRYPTO_MAX_DATA_LEN);
  7514. + return (E2BIG);
  7515. + }
  7516. +
  7517. + if (cse->info.blocksize && (cop->len % cse->info.blocksize) != 0) {
  7518. + dprintk("%s: blocksize=%d len=%d\n", __FUNCTION__, cse->info.blocksize,
  7519. + cop->len);
  7520. + return (EINVAL);
  7521. + }
  7522. +
  7523. + cse->uio.uio_iov = &cse->iovec;
  7524. + cse->uio.uio_iovcnt = 1;
  7525. + cse->uio.uio_offset = 0;
  7526. +#if 0
  7527. + cse->uio.uio_resid = cop->len;
  7528. + cse->uio.uio_segflg = UIO_SYSSPACE;
  7529. + cse->uio.uio_rw = UIO_WRITE;
  7530. + cse->uio.uio_td = td;
  7531. +#endif
  7532. + cse->uio.uio_iov[0].iov_len = cop->len;
  7533. + if (cse->info.authsize)
  7534. + cse->uio.uio_iov[0].iov_len += cse->info.authsize;
  7535. + cse->uio.uio_iov[0].iov_base = kmalloc(cse->uio.uio_iov[0].iov_len,
  7536. + GFP_KERNEL);
  7537. +
  7538. + if (cse->uio.uio_iov[0].iov_base == NULL) {
  7539. + dprintk("%s: iov_base kmalloc(%d) failed\n", __FUNCTION__,
  7540. + (int)cse->uio.uio_iov[0].iov_len);
  7541. + return (ENOMEM);
  7542. + }
  7543. +
  7544. + crp = crypto_getreq((cse->info.blocksize != 0) + (cse->info.authsize != 0));
  7545. + if (crp == NULL) {
  7546. + dprintk("%s: ENOMEM\n", __FUNCTION__);
  7547. + error = ENOMEM;
  7548. + goto bail;
  7549. + }
  7550. +
  7551. + if (cse->info.authsize && cse->info.blocksize) {
  7552. + if (cop->op == COP_ENCRYPT) {
  7553. + crde = crp->crp_desc;
  7554. + crda = crde->crd_next;
  7555. + } else {
  7556. + crda = crp->crp_desc;
  7557. + crde = crda->crd_next;
  7558. + }
  7559. + } else if (cse->info.authsize) {
  7560. + crda = crp->crp_desc;
  7561. + } else if (cse->info.blocksize) {
  7562. + crde = crp->crp_desc;
  7563. + } else {
  7564. + dprintk("%s: bad request\n", __FUNCTION__);
  7565. + error = EINVAL;
  7566. + goto bail;
  7567. + }
  7568. +
  7569. + if ((error = copy_from_user(cse->uio.uio_iov[0].iov_base, cop->src,
  7570. + cop->len))) {
  7571. + dprintk("%s: bad copy\n", __FUNCTION__);
  7572. + goto bail;
  7573. + }
  7574. +
  7575. + if (crda) {
  7576. + crda->crd_skip = 0;
  7577. + crda->crd_len = cop->len;
  7578. + crda->crd_inject = cop->len;
  7579. +
  7580. + crda->crd_alg = cse->mac;
  7581. + crda->crd_key = cse->mackey;
  7582. + crda->crd_klen = cse->mackeylen * 8;
  7583. + }
  7584. +
  7585. + if (crde) {
  7586. + if (cop->op == COP_ENCRYPT)
  7587. + crde->crd_flags |= CRD_F_ENCRYPT;
  7588. + else
  7589. + crde->crd_flags &= ~CRD_F_ENCRYPT;
  7590. + crde->crd_len = cop->len;
  7591. + crde->crd_inject = 0;
  7592. +
  7593. + crde->crd_alg = cse->cipher;
  7594. + crde->crd_key = cse->key;
  7595. + crde->crd_klen = cse->keylen * 8;
  7596. + }
  7597. +
  7598. + crp->crp_ilen = cse->uio.uio_iov[0].iov_len;
  7599. + crp->crp_flags = CRYPTO_F_IOV | CRYPTO_F_CBIMM
  7600. + | (cop->flags & COP_F_BATCH);
  7601. + crp->crp_buf = (caddr_t)&cse->uio;
  7602. + crp->crp_callback = (int (*) (struct cryptop *)) cryptodev_cb;
  7603. + crp->crp_sid = cse->sid;
  7604. + crp->crp_opaque = (void *)cse;
  7605. +
  7606. + if (cop->iv) {
  7607. + if (crde == NULL) {
  7608. + error = EINVAL;
  7609. + dprintk("%s no crde\n", __FUNCTION__);
  7610. + goto bail;
  7611. + }
  7612. + if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
  7613. + error = EINVAL;
  7614. + dprintk("%s arc4 with IV\n", __FUNCTION__);
  7615. + goto bail;
  7616. + }
  7617. + if ((error = copy_from_user(cse->tmp_iv, cop->iv,
  7618. + cse->info.blocksize))) {
  7619. + dprintk("%s bad iv copy\n", __FUNCTION__);
  7620. + goto bail;
  7621. + }
  7622. + memcpy(crde->crd_iv, cse->tmp_iv, cse->info.blocksize);
  7623. + crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
  7624. + crde->crd_skip = 0;
  7625. + } else if (cse->cipher == CRYPTO_ARC4) { /* XXX use flag? */
  7626. + crde->crd_skip = 0;
  7627. + } else if (crde) {
  7628. + crde->crd_flags |= CRD_F_IV_PRESENT;
  7629. + crde->crd_skip = cse->info.blocksize;
  7630. + crde->crd_len -= cse->info.blocksize;
  7631. + }
  7632. +
  7633. + if (cop->mac && crda == NULL) {
  7634. + error = EINVAL;
  7635. + dprintk("%s no crda\n", __FUNCTION__);
  7636. + goto bail;
  7637. + }
  7638. +
  7639. + /*
  7640. + * Let the dispatch run unlocked, then, interlock against the
  7641. + * callback before checking if the operation completed and going
  7642. + * to sleep. This insures drivers don't inherit our lock which
  7643. + * results in a lock order reversal between crypto_dispatch forced
  7644. + * entry and the crypto_done callback into us.
  7645. + */
  7646. + error = crypto_dispatch(crp);
  7647. + if (error) {
  7648. + dprintk("%s error in crypto_dispatch\n", __FUNCTION__);
  7649. + goto bail;
  7650. + }
  7651. +
  7652. + dprintk("%s about to WAIT\n", __FUNCTION__);
  7653. + /*
  7654. + * we really need to wait for driver to complete to maintain
  7655. + * state, luckily interrupts will be remembered
  7656. + */
  7657. + do {
  7658. + error = wait_event_interruptible(crp->crp_waitq,
  7659. + ((crp->crp_flags & CRYPTO_F_DONE) != 0));
  7660. + /*
  7661. + * we can't break out of this loop or we will leave behind
  7662. + * a huge mess, however, staying here means if your driver
  7663. + * is broken user applications can hang and not be killed.
  7664. + * The solution, fix your driver :-)
  7665. + */
  7666. + if (error) {
  7667. + schedule();
  7668. + error = 0;
  7669. + }
  7670. + } while ((crp->crp_flags & CRYPTO_F_DONE) == 0);
  7671. + dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
  7672. +
  7673. + if (crp->crp_etype != 0) {
  7674. + error = crp->crp_etype;
  7675. + dprintk("%s error in crp processing\n", __FUNCTION__);
  7676. + goto bail;
  7677. + }
  7678. +
  7679. + if (cse->error) {
  7680. + error = cse->error;
  7681. + dprintk("%s error in cse processing\n", __FUNCTION__);
  7682. + goto bail;
  7683. + }
  7684. +
  7685. + if (cop->dst && (error = copy_to_user(cop->dst,
  7686. + cse->uio.uio_iov[0].iov_base, cop->len))) {
  7687. + dprintk("%s bad dst copy\n", __FUNCTION__);
  7688. + goto bail;
  7689. + }
  7690. +
  7691. + if (cop->mac &&
  7692. + (error=copy_to_user(cop->mac,
  7693. + (caddr_t)cse->uio.uio_iov[0].iov_base + cop->len,
  7694. + cse->info.authsize))) {
  7695. + dprintk("%s bad mac copy\n", __FUNCTION__);
  7696. + goto bail;
  7697. + }
  7698. +
  7699. +bail:
  7700. + if (crp)
  7701. + crypto_freereq(crp);
  7702. + if (cse->uio.uio_iov[0].iov_base)
  7703. + kfree(cse->uio.uio_iov[0].iov_base);
  7704. +
  7705. + return (error);
  7706. +}
  7707. +
  7708. +static int
  7709. +cryptodev_cb(void *op)
  7710. +{
  7711. + struct cryptop *crp = (struct cryptop *) op;
  7712. + struct csession *cse = (struct csession *)crp->crp_opaque;
  7713. + int error;
  7714. +
  7715. + dprintk("%s()\n", __FUNCTION__);
  7716. + error = crp->crp_etype;
  7717. + if (error == EAGAIN) {
  7718. + crp->crp_flags &= ~CRYPTO_F_DONE;
  7719. +#ifdef NOTYET
  7720. + /*
  7721. + * DAVIDM I am fairly sure that we should turn this into a batch
  7722. + * request to stop bad karma/lockup, revisit
  7723. + */
  7724. + crp->crp_flags |= CRYPTO_F_BATCH;
  7725. +#endif
  7726. + return crypto_dispatch(crp);
  7727. + }
  7728. + if (error != 0 || (crp->crp_flags & CRYPTO_F_DONE)) {
  7729. + cse->error = error;
  7730. + wake_up_interruptible(&crp->crp_waitq);
  7731. + }
  7732. + return (0);
  7733. +}
  7734. +
  7735. +static int
  7736. +cryptodevkey_cb(void *op)
  7737. +{
  7738. + struct cryptkop *krp = (struct cryptkop *) op;
  7739. + dprintk("%s()\n", __FUNCTION__);
  7740. + wake_up_interruptible(&krp->krp_waitq);
  7741. + return (0);
  7742. +}
  7743. +
  7744. +static int
  7745. +cryptodev_key(struct crypt_kop *kop)
  7746. +{
  7747. + struct cryptkop *krp = NULL;
  7748. + int error = EINVAL;
  7749. + int in, out, size, i;
  7750. +
  7751. + dprintk("%s()\n", __FUNCTION__);
  7752. + if (kop->crk_iparams + kop->crk_oparams > CRK_MAXPARAM) {
  7753. + dprintk("%s params too big\n", __FUNCTION__);
  7754. + return (EFBIG);
  7755. + }
  7756. +
  7757. + in = kop->crk_iparams;
  7758. + out = kop->crk_oparams;
  7759. + switch (kop->crk_op) {
  7760. + case CRK_MOD_EXP:
  7761. + if (in == 3 && out == 1)
  7762. + break;
  7763. + return (EINVAL);
  7764. + case CRK_MOD_EXP_CRT:
  7765. + if (in == 6 && out == 1)
  7766. + break;
  7767. + return (EINVAL);
  7768. + case CRK_DSA_SIGN:
  7769. + if (in == 5 && out == 2)
  7770. + break;
  7771. + return (EINVAL);
  7772. + case CRK_DSA_VERIFY:
  7773. + if (in == 7 && out == 0)
  7774. + break;
  7775. + return (EINVAL);
  7776. + case CRK_DH_COMPUTE_KEY:
  7777. + if (in == 3 && out == 1)
  7778. + break;
  7779. + return (EINVAL);
  7780. + default:
  7781. + return (EINVAL);
  7782. + }
  7783. +
  7784. + krp = (struct cryptkop *)kmalloc(sizeof *krp, GFP_KERNEL);
  7785. + if (!krp)
  7786. + return (ENOMEM);
  7787. + bzero(krp, sizeof *krp);
  7788. + krp->krp_op = kop->crk_op;
  7789. + krp->krp_status = kop->crk_status;
  7790. + krp->krp_iparams = kop->crk_iparams;
  7791. + krp->krp_oparams = kop->crk_oparams;
  7792. + krp->krp_crid = kop->crk_crid;
  7793. + krp->krp_status = 0;
  7794. + krp->krp_flags = CRYPTO_KF_CBIMM;
  7795. + krp->krp_callback = (int (*) (struct cryptkop *)) cryptodevkey_cb;
  7796. + init_waitqueue_head(&krp->krp_waitq);
  7797. +
  7798. + for (i = 0; i < CRK_MAXPARAM; i++)
  7799. + krp->krp_param[i].crp_nbits = kop->crk_param[i].crp_nbits;
  7800. + for (i = 0; i < krp->krp_iparams + krp->krp_oparams; i++) {
  7801. + size = (krp->krp_param[i].crp_nbits + 7) / 8;
  7802. + if (size == 0)
  7803. + continue;
  7804. + krp->krp_param[i].crp_p = (caddr_t) kmalloc(size, GFP_KERNEL);
  7805. + if (i >= krp->krp_iparams)
  7806. + continue;
  7807. + error = copy_from_user(krp->krp_param[i].crp_p,
  7808. + kop->crk_param[i].crp_p, size);
  7809. + if (error)
  7810. + goto fail;
  7811. + }
  7812. +
  7813. + error = crypto_kdispatch(krp);
  7814. + if (error)
  7815. + goto fail;
  7816. +
  7817. + do {
  7818. + error = wait_event_interruptible(krp->krp_waitq,
  7819. + ((krp->krp_flags & CRYPTO_KF_DONE) != 0));
  7820. + /*
  7821. + * we can't break out of this loop or we will leave behind
  7822. + * a huge mess, however, staying here means if your driver
  7823. + * is broken user applications can hang and not be killed.
  7824. + * The solution, fix your driver :-)
  7825. + */
  7826. + if (error) {
  7827. + schedule();
  7828. + error = 0;
  7829. + }
  7830. + } while ((krp->krp_flags & CRYPTO_KF_DONE) == 0);
  7831. +
  7832. + dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
  7833. +
  7834. + kop->crk_crid = krp->krp_crid; /* device that did the work */
  7835. + if (krp->krp_status != 0) {
  7836. + error = krp->krp_status;
  7837. + goto fail;
  7838. + }
  7839. +
  7840. + for (i = krp->krp_iparams; i < krp->krp_iparams + krp->krp_oparams; i++) {
  7841. + size = (krp->krp_param[i].crp_nbits + 7) / 8;
  7842. + if (size == 0)
  7843. + continue;
  7844. + error = copy_to_user(kop->crk_param[i].crp_p, krp->krp_param[i].crp_p,
  7845. + size);
  7846. + if (error)
  7847. + goto fail;
  7848. + }
  7849. +
  7850. +fail:
  7851. + if (krp) {
  7852. + kop->crk_status = krp->krp_status;
  7853. + for (i = 0; i < CRK_MAXPARAM; i++) {
  7854. + if (krp->krp_param[i].crp_p)
  7855. + kfree(krp->krp_param[i].crp_p);
  7856. + }
  7857. + kfree(krp);
  7858. + }
  7859. + return (error);
  7860. +}
  7861. +
  7862. +static int
  7863. +cryptodev_find(struct crypt_find_op *find)
  7864. +{
  7865. + device_t dev;
  7866. +
  7867. + if (find->crid != -1) {
  7868. + dev = crypto_find_device_byhid(find->crid);
  7869. + if (dev == NULL)
  7870. + return (ENOENT);
  7871. + strlcpy(find->name, device_get_nameunit(dev),
  7872. + sizeof(find->name));
  7873. + } else {
  7874. + find->crid = crypto_find_driver(find->name);
  7875. + if (find->crid == -1)
  7876. + return (ENOENT);
  7877. + }
  7878. + return (0);
  7879. +}
  7880. +
  7881. +static struct csession *
  7882. +csefind(struct fcrypt *fcr, u_int ses)
  7883. +{
  7884. + struct csession *cse;
  7885. +
  7886. + dprintk("%s()\n", __FUNCTION__);
  7887. + list_for_each_entry(cse, &fcr->csessions, list)
  7888. + if (cse->ses == ses)
  7889. + return (cse);
  7890. + return (NULL);
  7891. +}
  7892. +
  7893. +static int
  7894. +csedelete(struct fcrypt *fcr, struct csession *cse_del)
  7895. +{
  7896. + struct csession *cse;
  7897. +
  7898. + dprintk("%s()\n", __FUNCTION__);
  7899. + list_for_each_entry(cse, &fcr->csessions, list) {
  7900. + if (cse == cse_del) {
  7901. + list_del(&cse->list);
  7902. + return (1);
  7903. + }
  7904. + }
  7905. + return (0);
  7906. +}
  7907. +
  7908. +static struct csession *
  7909. +cseadd(struct fcrypt *fcr, struct csession *cse)
  7910. +{
  7911. + dprintk("%s()\n", __FUNCTION__);
  7912. + list_add_tail(&cse->list, &fcr->csessions);
  7913. + cse->ses = fcr->sesn++;
  7914. + return (cse);
  7915. +}
  7916. +
  7917. +static struct csession *
  7918. +csecreate(struct fcrypt *fcr, u_int64_t sid, struct cryptoini *crie,
  7919. + struct cryptoini *cria, struct csession_info *info)
  7920. +{
  7921. + struct csession *cse;
  7922. +
  7923. + dprintk("%s()\n", __FUNCTION__);
  7924. + cse = (struct csession *) kmalloc(sizeof(struct csession), GFP_KERNEL);
  7925. + if (cse == NULL)
  7926. + return NULL;
  7927. + memset(cse, 0, sizeof(struct csession));
  7928. +
  7929. + INIT_LIST_HEAD(&cse->list);
  7930. + init_waitqueue_head(&cse->waitq);
  7931. +
  7932. + cse->key = crie->cri_key;
  7933. + cse->keylen = crie->cri_klen/8;
  7934. + cse->mackey = cria->cri_key;
  7935. + cse->mackeylen = cria->cri_klen/8;
  7936. + cse->sid = sid;
  7937. + cse->cipher = crie->cri_alg;
  7938. + cse->mac = cria->cri_alg;
  7939. + cse->info = *info;
  7940. + cseadd(fcr, cse);
  7941. + return (cse);
  7942. +}
  7943. +
  7944. +static int
  7945. +csefree(struct csession *cse)
  7946. +{
  7947. + int error;
  7948. +
  7949. + dprintk("%s()\n", __FUNCTION__);
  7950. + error = crypto_freesession(cse->sid);
  7951. + if (cse->key)
  7952. + kfree(cse->key);
  7953. + if (cse->mackey)
  7954. + kfree(cse->mackey);
  7955. + kfree(cse);
  7956. + return(error);
  7957. +}
  7958. +
  7959. +static int
  7960. +cryptodev_ioctl(
  7961. + struct inode *inode,
  7962. + struct file *filp,
  7963. + unsigned int cmd,
  7964. + unsigned long arg)
  7965. +{
  7966. + struct cryptoini cria, crie;
  7967. + struct fcrypt *fcr = filp->private_data;
  7968. + struct csession *cse;
  7969. + struct csession_info info;
  7970. + struct session2_op sop;
  7971. + struct crypt_op cop;
  7972. + struct crypt_kop kop;
  7973. + struct crypt_find_op fop;
  7974. + u_int64_t sid;
  7975. + u_int32_t ses = 0;
  7976. + int feat, fd, error = 0, crid;
  7977. + mm_segment_t fs;
  7978. +
  7979. + dprintk("%s(cmd=%x arg=%lx)\n", __FUNCTION__, cmd, arg);
  7980. +
  7981. + switch (cmd) {
  7982. +
  7983. + case CRIOGET: {
  7984. + dprintk("%s(CRIOGET)\n", __FUNCTION__);
  7985. + fs = get_fs();
  7986. + set_fs(get_ds());
  7987. + for (fd = 0; fd < files_fdtable(current->files)->max_fds; fd++)
  7988. + if (files_fdtable(current->files)->fd[fd] == filp)
  7989. + break;
  7990. + fd = sys_dup(fd);
  7991. + set_fs(fs);
  7992. + put_user(fd, (int *) arg);
  7993. + return IS_ERR_VALUE(fd) ? fd : 0;
  7994. + }
  7995. +
  7996. +#define CIOCGSESSSTR (cmd == CIOCGSESSION ? "CIOCGSESSION" : "CIOCGSESSION2")
  7997. + case CIOCGSESSION:
  7998. + case CIOCGSESSION2:
  7999. + dprintk("%s(%s)\n", __FUNCTION__, CIOCGSESSSTR);
  8000. + memset(&crie, 0, sizeof(crie));
  8001. + memset(&cria, 0, sizeof(cria));
  8002. + memset(&info, 0, sizeof(info));
  8003. + memset(&sop, 0, sizeof(sop));
  8004. +
  8005. + if (copy_from_user(&sop, (void*)arg, (cmd == CIOCGSESSION) ?
  8006. + sizeof(struct session_op) : sizeof(sop))) {
  8007. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  8008. + error = EFAULT;
  8009. + goto bail;
  8010. + }
  8011. +
  8012. + switch (sop.cipher) {
  8013. + case 0:
  8014. + dprintk("%s(%s) - no cipher\n", __FUNCTION__, CIOCGSESSSTR);
  8015. + break;
  8016. + case CRYPTO_NULL_CBC:
  8017. + info.blocksize = NULL_BLOCK_LEN;
  8018. + info.minkey = NULL_MIN_KEY_LEN;
  8019. + info.maxkey = NULL_MAX_KEY_LEN;
  8020. + break;
  8021. + case CRYPTO_DES_CBC:
  8022. + info.blocksize = DES_BLOCK_LEN;
  8023. + info.minkey = DES_MIN_KEY_LEN;
  8024. + info.maxkey = DES_MAX_KEY_LEN;
  8025. + break;
  8026. + case CRYPTO_3DES_CBC:
  8027. + info.blocksize = DES3_BLOCK_LEN;
  8028. + info.minkey = DES3_MIN_KEY_LEN;
  8029. + info.maxkey = DES3_MAX_KEY_LEN;
  8030. + break;
  8031. + case CRYPTO_BLF_CBC:
  8032. + info.blocksize = BLOWFISH_BLOCK_LEN;
  8033. + info.minkey = BLOWFISH_MIN_KEY_LEN;
  8034. + info.maxkey = BLOWFISH_MAX_KEY_LEN;
  8035. + break;
  8036. + case CRYPTO_CAST_CBC:
  8037. + info.blocksize = CAST128_BLOCK_LEN;
  8038. + info.minkey = CAST128_MIN_KEY_LEN;
  8039. + info.maxkey = CAST128_MAX_KEY_LEN;
  8040. + break;
  8041. + case CRYPTO_SKIPJACK_CBC:
  8042. + info.blocksize = SKIPJACK_BLOCK_LEN;
  8043. + info.minkey = SKIPJACK_MIN_KEY_LEN;
  8044. + info.maxkey = SKIPJACK_MAX_KEY_LEN;
  8045. + break;
  8046. + case CRYPTO_AES_CBC:
  8047. + info.blocksize = AES_BLOCK_LEN;
  8048. + info.minkey = AES_MIN_KEY_LEN;
  8049. + info.maxkey = AES_MAX_KEY_LEN;
  8050. + break;
  8051. + case CRYPTO_ARC4:
  8052. + info.blocksize = ARC4_BLOCK_LEN;
  8053. + info.minkey = ARC4_MIN_KEY_LEN;
  8054. + info.maxkey = ARC4_MAX_KEY_LEN;
  8055. + break;
  8056. + case CRYPTO_CAMELLIA_CBC:
  8057. + info.blocksize = CAMELLIA_BLOCK_LEN;
  8058. + info.minkey = CAMELLIA_MIN_KEY_LEN;
  8059. + info.maxkey = CAMELLIA_MAX_KEY_LEN;
  8060. + break;
  8061. + default:
  8062. + dprintk("%s(%s) - bad cipher\n", __FUNCTION__, CIOCGSESSSTR);
  8063. + error = EINVAL;
  8064. + goto bail;
  8065. + }
  8066. +
  8067. + switch (sop.mac) {
  8068. + case 0:
  8069. + dprintk("%s(%s) - no mac\n", __FUNCTION__, CIOCGSESSSTR);
  8070. + break;
  8071. + case CRYPTO_NULL_HMAC:
  8072. + info.authsize = NULL_HASH_LEN;
  8073. + break;
  8074. + case CRYPTO_MD5:
  8075. + info.authsize = MD5_HASH_LEN;
  8076. + break;
  8077. + case CRYPTO_SHA1:
  8078. + info.authsize = SHA1_HASH_LEN;
  8079. + break;
  8080. + case CRYPTO_SHA2_256:
  8081. + info.authsize = SHA2_256_HASH_LEN;
  8082. + break;
  8083. + case CRYPTO_SHA2_384:
  8084. + info.authsize = SHA2_384_HASH_LEN;
  8085. + break;
  8086. + case CRYPTO_SHA2_512:
  8087. + info.authsize = SHA2_512_HASH_LEN;
  8088. + break;
  8089. + case CRYPTO_RIPEMD160:
  8090. + info.authsize = RIPEMD160_HASH_LEN;
  8091. + break;
  8092. + case CRYPTO_MD5_HMAC:
  8093. + info.authsize = MD5_HASH_LEN;
  8094. + info.authkey = 16;
  8095. + break;
  8096. + case CRYPTO_SHA1_HMAC:
  8097. + info.authsize = SHA1_HASH_LEN;
  8098. + info.authkey = 20;
  8099. + break;
  8100. + case CRYPTO_SHA2_256_HMAC:
  8101. + info.authsize = SHA2_256_HASH_LEN;
  8102. + info.authkey = 32;
  8103. + break;
  8104. + case CRYPTO_SHA2_384_HMAC:
  8105. + info.authsize = SHA2_384_HASH_LEN;
  8106. + info.authkey = 48;
  8107. + break;
  8108. + case CRYPTO_SHA2_512_HMAC:
  8109. + info.authsize = SHA2_512_HASH_LEN;
  8110. + info.authkey = 64;
  8111. + break;
  8112. + case CRYPTO_RIPEMD160_HMAC:
  8113. + info.authsize = RIPEMD160_HASH_LEN;
  8114. + info.authkey = 20;
  8115. + break;
  8116. + default:
  8117. + dprintk("%s(%s) - bad mac\n", __FUNCTION__, CIOCGSESSSTR);
  8118. + error = EINVAL;
  8119. + goto bail;
  8120. + }
  8121. +
  8122. + if (info.blocksize) {
  8123. + crie.cri_alg = sop.cipher;
  8124. + crie.cri_klen = sop.keylen * 8;
  8125. + if ((info.maxkey && sop.keylen > info.maxkey) ||
  8126. + sop.keylen < info.minkey) {
  8127. + dprintk("%s(%s) - bad key\n", __FUNCTION__, CIOCGSESSSTR);
  8128. + error = EINVAL;
  8129. + goto bail;
  8130. + }
  8131. +
  8132. + crie.cri_key = (u_int8_t *) kmalloc(crie.cri_klen/8+1, GFP_KERNEL);
  8133. + if (copy_from_user(crie.cri_key, sop.key,
  8134. + crie.cri_klen/8)) {
  8135. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  8136. + error = EFAULT;
  8137. + goto bail;
  8138. + }
  8139. + if (info.authsize)
  8140. + crie.cri_next = &cria;
  8141. + }
  8142. +
  8143. + if (info.authsize) {
  8144. + cria.cri_alg = sop.mac;
  8145. + cria.cri_klen = sop.mackeylen * 8;
  8146. + if (info.authkey && sop.mackeylen != info.authkey) {
  8147. + dprintk("%s(%s) - mackeylen %d != %d\n", __FUNCTION__,
  8148. + CIOCGSESSSTR, sop.mackeylen, info.authkey);
  8149. + error = EINVAL;
  8150. + goto bail;
  8151. + }
  8152. +
  8153. + if (cria.cri_klen) {
  8154. + cria.cri_key = (u_int8_t *) kmalloc(cria.cri_klen/8,GFP_KERNEL);
  8155. + if (copy_from_user(cria.cri_key, sop.mackey,
  8156. + cria.cri_klen / 8)) {
  8157. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  8158. + error = EFAULT;
  8159. + goto bail;
  8160. + }
  8161. + }
  8162. + }
  8163. +
  8164. + /* NB: CIOGSESSION2 has the crid */
  8165. + if (cmd == CIOCGSESSION2) {
  8166. + crid = sop.crid;
  8167. + error = checkcrid(crid);
  8168. + if (error) {
  8169. + dprintk("%s(%s) - checkcrid %x\n", __FUNCTION__,
  8170. + CIOCGSESSSTR, error);
  8171. + goto bail;
  8172. + }
  8173. + } else {
  8174. + /* allow either HW or SW to be used */
  8175. + crid = CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
  8176. + }
  8177. + error = crypto_newsession(&sid, (info.blocksize ? &crie : &cria), crid);
  8178. + if (error) {
  8179. + dprintk("%s(%s) - newsession %d\n",__FUNCTION__,CIOCGSESSSTR,error);
  8180. + goto bail;
  8181. + }
  8182. +
  8183. + cse = csecreate(fcr, sid, &crie, &cria, &info);
  8184. + if (cse == NULL) {
  8185. + crypto_freesession(sid);
  8186. + error = EINVAL;
  8187. + dprintk("%s(%s) - csecreate failed\n", __FUNCTION__, CIOCGSESSSTR);
  8188. + goto bail;
  8189. + }
  8190. + sop.ses = cse->ses;
  8191. +
  8192. + if (cmd == CIOCGSESSION2) {
  8193. + /* return hardware/driver id */
  8194. + sop.crid = CRYPTO_SESID2HID(cse->sid);
  8195. + }
  8196. +
  8197. + if (copy_to_user((void*)arg, &sop, (cmd == CIOCGSESSION) ?
  8198. + sizeof(struct session_op) : sizeof(sop))) {
  8199. + dprintk("%s(%s) - bad copy\n", __FUNCTION__, CIOCGSESSSTR);
  8200. + error = EFAULT;
  8201. + }
  8202. +bail:
  8203. + if (error) {
  8204. + dprintk("%s(%s) - bail %d\n", __FUNCTION__, CIOCGSESSSTR, error);
  8205. + if (crie.cri_key)
  8206. + kfree(crie.cri_key);
  8207. + if (cria.cri_key)
  8208. + kfree(cria.cri_key);
  8209. + }
  8210. + break;
  8211. + case CIOCFSESSION:
  8212. + dprintk("%s(CIOCFSESSION)\n", __FUNCTION__);
  8213. + get_user(ses, (uint32_t*)arg);
  8214. + cse = csefind(fcr, ses);
  8215. + if (cse == NULL) {
  8216. + error = EINVAL;
  8217. + dprintk("%s(CIOCFSESSION) - Fail %d\n", __FUNCTION__, error);
  8218. + break;
  8219. + }
  8220. + csedelete(fcr, cse);
  8221. + error = csefree(cse);
  8222. + break;
  8223. + case CIOCCRYPT:
  8224. + dprintk("%s(CIOCCRYPT)\n", __FUNCTION__);
  8225. + if(copy_from_user(&cop, (void*)arg, sizeof(cop))) {
  8226. + dprintk("%s(CIOCCRYPT) - bad copy\n", __FUNCTION__);
  8227. + error = EFAULT;
  8228. + goto bail;
  8229. + }
  8230. + cse = csefind(fcr, cop.ses);
  8231. + if (cse == NULL) {
  8232. + error = EINVAL;
  8233. + dprintk("%s(CIOCCRYPT) - Fail %d\n", __FUNCTION__, error);
  8234. + break;
  8235. + }
  8236. + error = cryptodev_op(cse, &cop);
  8237. + if(copy_to_user((void*)arg, &cop, sizeof(cop))) {
  8238. + dprintk("%s(CIOCCRYPT) - bad return copy\n", __FUNCTION__);
  8239. + error = EFAULT;
  8240. + goto bail;
  8241. + }
  8242. + break;
  8243. + case CIOCKEY:
  8244. + case CIOCKEY2:
  8245. + dprintk("%s(CIOCKEY)\n", __FUNCTION__);
  8246. + if (!crypto_userasymcrypto)
  8247. + return (EPERM); /* XXX compat? */
  8248. + if(copy_from_user(&kop, (void*)arg, sizeof(kop))) {
  8249. + dprintk("%s(CIOCKEY) - bad copy\n", __FUNCTION__);
  8250. + error = EFAULT;
  8251. + goto bail;
  8252. + }
  8253. + if (cmd == CIOCKEY) {
  8254. + /* NB: crypto core enforces s/w driver use */
  8255. + kop.crk_crid =
  8256. + CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
  8257. + }
  8258. + error = cryptodev_key(&kop);
  8259. + if(copy_to_user((void*)arg, &kop, sizeof(kop))) {
  8260. + dprintk("%s(CIOCGKEY) - bad return copy\n", __FUNCTION__);
  8261. + error = EFAULT;
  8262. + goto bail;
  8263. + }
  8264. + break;
  8265. + case CIOCASYMFEAT:
  8266. + dprintk("%s(CIOCASYMFEAT)\n", __FUNCTION__);
  8267. + if (!crypto_userasymcrypto) {
  8268. + /*
  8269. + * NB: if user asym crypto operations are
  8270. + * not permitted return "no algorithms"
  8271. + * so well-behaved applications will just
  8272. + * fallback to doing them in software.
  8273. + */
  8274. + feat = 0;
  8275. + } else
  8276. + error = crypto_getfeat(&feat);
  8277. + if (!error) {
  8278. + error = copy_to_user((void*)arg, &feat, sizeof(feat));
  8279. + }
  8280. + break;
  8281. + case CIOCFINDDEV:
  8282. + if (copy_from_user(&fop, (void*)arg, sizeof(fop))) {
  8283. + dprintk("%s(CIOCFINDDEV) - bad copy\n", __FUNCTION__);
  8284. + error = EFAULT;
  8285. + goto bail;
  8286. + }
  8287. + error = cryptodev_find(&fop);
  8288. + if (copy_to_user((void*)arg, &fop, sizeof(fop))) {
  8289. + dprintk("%s(CIOCFINDDEV) - bad return copy\n", __FUNCTION__);
  8290. + error = EFAULT;
  8291. + goto bail;
  8292. + }
  8293. + break;
  8294. + default:
  8295. + dprintk("%s(unknown ioctl 0x%x)\n", __FUNCTION__, cmd);
  8296. + error = EINVAL;
  8297. + break;
  8298. + }
  8299. + return(-error);
  8300. +}
  8301. +
  8302. +#ifdef HAVE_UNLOCKED_IOCTL
  8303. +static long
  8304. +cryptodev_unlocked_ioctl(
  8305. + struct file *filp,
  8306. + unsigned int cmd,
  8307. + unsigned long arg)
  8308. +{
  8309. + return cryptodev_ioctl(NULL, filp, cmd, arg);
  8310. +}
  8311. +#endif
  8312. +
  8313. +static int
  8314. +cryptodev_open(struct inode *inode, struct file *filp)
  8315. +{
  8316. + struct fcrypt *fcr;
  8317. +
  8318. + dprintk("%s()\n", __FUNCTION__);
  8319. + if (filp->private_data) {
  8320. + printk("cryptodev: Private data already exists !\n");
  8321. + return(0);
  8322. + }
  8323. +
  8324. + fcr = kmalloc(sizeof(*fcr), GFP_KERNEL);
  8325. + if (!fcr) {
  8326. + dprintk("%s() - malloc failed\n", __FUNCTION__);
  8327. + return(-ENOMEM);
  8328. + }
  8329. + memset(fcr, 0, sizeof(*fcr));
  8330. +
  8331. + INIT_LIST_HEAD(&fcr->csessions);
  8332. + filp->private_data = fcr;
  8333. + return(0);
  8334. +}
  8335. +
  8336. +static int
  8337. +cryptodev_release(struct inode *inode, struct file *filp)
  8338. +{
  8339. + struct fcrypt *fcr = filp->private_data;
  8340. + struct csession *cse, *tmp;
  8341. +
  8342. + dprintk("%s()\n", __FUNCTION__);
  8343. + if (!filp) {
  8344. + printk("cryptodev: No private data on release\n");
  8345. + return(0);
  8346. + }
  8347. +
  8348. + list_for_each_entry_safe(cse, tmp, &fcr->csessions, list) {
  8349. + list_del(&cse->list);
  8350. + (void)csefree(cse);
  8351. + }
  8352. + filp->private_data = NULL;
  8353. + kfree(fcr);
  8354. + return(0);
  8355. +}
  8356. +
  8357. +static struct file_operations cryptodev_fops = {
  8358. + .owner = THIS_MODULE,
  8359. + .open = cryptodev_open,
  8360. + .release = cryptodev_release,
  8361. +#ifdef HAVE_UNLOCKED_IOCTL
  8362. + .unlocked_ioctl = cryptodev_unlocked_ioctl,
  8363. +#endif
  8364. +};
  8365. +
  8366. +static struct miscdevice cryptodev = {
  8367. + .minor = CRYPTODEV_MINOR,
  8368. + .name = "crypto",
  8369. + .fops = &cryptodev_fops,
  8370. +};
  8371. +
  8372. +static int __init
  8373. +cryptodev_init(void)
  8374. +{
  8375. + int rc;
  8376. +
  8377. + dprintk("%s(%p)\n", __FUNCTION__, cryptodev_init);
  8378. + rc = misc_register(&cryptodev);
  8379. + if (rc) {
  8380. + printk(KERN_ERR "cryptodev: registration of /dev/crypto failed\n");
  8381. + return(rc);
  8382. + }
  8383. +
  8384. + return(0);
  8385. +}
  8386. +
  8387. +static void __exit
  8388. +cryptodev_exit(void)
  8389. +{
  8390. + dprintk("%s()\n", __FUNCTION__);
  8391. + misc_deregister(&cryptodev);
  8392. +}
  8393. +
  8394. +module_init(cryptodev_init);
  8395. +module_exit(cryptodev_exit);
  8396. +
  8397. +MODULE_LICENSE("BSD");
  8398. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  8399. +MODULE_DESCRIPTION("Cryptodev (user interface to OCF)");
  8400. diff -Nur linux-2.6.39.orig/crypto/ocf/cryptodev.h linux-2.6.39/crypto/ocf/cryptodev.h
  8401. --- linux-2.6.39.orig/crypto/ocf/cryptodev.h 1970-01-01 01:00:00.000000000 +0100
  8402. +++ linux-2.6.39/crypto/ocf/cryptodev.h 2011-08-01 14:38:18.000000000 +0200
  8403. @@ -0,0 +1,479 @@
  8404. +/* $FreeBSD: src/sys/opencrypto/cryptodev.h,v 1.25 2007/05/09 19:37:02 gnn Exp $ */
  8405. +/* $OpenBSD: cryptodev.h,v 1.31 2002/06/11 11:14:29 beck Exp $ */
  8406. +
  8407. +/*-
  8408. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  8409. + * Copyright (C) 2006-2010 David McCullough
  8410. + * Copyright (C) 2004-2005 Intel Corporation.
  8411. + * The license and original author are listed below.
  8412. + *
  8413. + * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu)
  8414. + * Copyright (c) 2002-2006 Sam Leffler, Errno Consulting
  8415. + *
  8416. + * This code was written by Angelos D. Keromytis in Athens, Greece, in
  8417. + * February 2000. Network Security Technologies Inc. (NSTI) kindly
  8418. + * supported the development of this code.
  8419. + *
  8420. + * Copyright (c) 2000 Angelos D. Keromytis
  8421. + *
  8422. + * Permission to use, copy, and modify this software with or without fee
  8423. + * is hereby granted, provided that this entire notice is included in
  8424. + * all source code copies of any software which is or includes a copy or
  8425. + * modification of this software.
  8426. + *
  8427. + * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
  8428. + * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
  8429. + * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
  8430. + * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
  8431. + * PURPOSE.
  8432. + *
  8433. + * Copyright (c) 2001 Theo de Raadt
  8434. + *
  8435. + * Redistribution and use in source and binary forms, with or without
  8436. + * modification, are permitted provided that the following conditions
  8437. + * are met:
  8438. + *
  8439. + * 1. Redistributions of source code must retain the above copyright
  8440. + * notice, this list of conditions and the following disclaimer.
  8441. + * 2. Redistributions in binary form must reproduce the above copyright
  8442. + * notice, this list of conditions and the following disclaimer in the
  8443. + * documentation and/or other materials provided with the distribution.
  8444. + * 3. The name of the author may not be used to endorse or promote products
  8445. + * derived from this software without specific prior written permission.
  8446. + *
  8447. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  8448. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  8449. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  8450. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  8451. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  8452. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  8453. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  8454. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  8455. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  8456. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  8457. + *
  8458. + * Effort sponsored in part by the Defense Advanced Research Projects
  8459. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  8460. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  8461. + *
  8462. + */
  8463. +
  8464. +#ifndef _CRYPTO_CRYPTO_H_
  8465. +#define _CRYPTO_CRYPTO_H_
  8466. +
  8467. +/* Some initial values */
  8468. +#define CRYPTO_DRIVERS_INITIAL 4
  8469. +#define CRYPTO_SW_SESSIONS 32
  8470. +
  8471. +/* Hash values */
  8472. +#define NULL_HASH_LEN 0
  8473. +#define MD5_HASH_LEN 16
  8474. +#define SHA1_HASH_LEN 20
  8475. +#define RIPEMD160_HASH_LEN 20
  8476. +#define SHA2_256_HASH_LEN 32
  8477. +#define SHA2_384_HASH_LEN 48
  8478. +#define SHA2_512_HASH_LEN 64
  8479. +#define MD5_KPDK_HASH_LEN 16
  8480. +#define SHA1_KPDK_HASH_LEN 20
  8481. +/* Maximum hash algorithm result length */
  8482. +#define HASH_MAX_LEN SHA2_512_HASH_LEN /* Keep this updated */
  8483. +
  8484. +/* HMAC values */
  8485. +#define NULL_HMAC_BLOCK_LEN 1
  8486. +#define MD5_HMAC_BLOCK_LEN 64
  8487. +#define SHA1_HMAC_BLOCK_LEN 64
  8488. +#define RIPEMD160_HMAC_BLOCK_LEN 64
  8489. +#define SHA2_256_HMAC_BLOCK_LEN 64
  8490. +#define SHA2_384_HMAC_BLOCK_LEN 128
  8491. +#define SHA2_512_HMAC_BLOCK_LEN 128
  8492. +/* Maximum HMAC block length */
  8493. +#define HMAC_MAX_BLOCK_LEN SHA2_512_HMAC_BLOCK_LEN /* Keep this updated */
  8494. +#define HMAC_IPAD_VAL 0x36
  8495. +#define HMAC_OPAD_VAL 0x5C
  8496. +
  8497. +/* Encryption algorithm block sizes */
  8498. +#define NULL_BLOCK_LEN 1
  8499. +#define DES_BLOCK_LEN 8
  8500. +#define DES3_BLOCK_LEN 8
  8501. +#define BLOWFISH_BLOCK_LEN 8
  8502. +#define SKIPJACK_BLOCK_LEN 8
  8503. +#define CAST128_BLOCK_LEN 8
  8504. +#define RIJNDAEL128_BLOCK_LEN 16
  8505. +#define AES_BLOCK_LEN RIJNDAEL128_BLOCK_LEN
  8506. +#define CAMELLIA_BLOCK_LEN 16
  8507. +#define ARC4_BLOCK_LEN 1
  8508. +#define EALG_MAX_BLOCK_LEN AES_BLOCK_LEN /* Keep this updated */
  8509. +
  8510. +/* Encryption algorithm min and max key sizes */
  8511. +#define NULL_MIN_KEY_LEN 0
  8512. +#define NULL_MAX_KEY_LEN 0
  8513. +#define DES_MIN_KEY_LEN 8
  8514. +#define DES_MAX_KEY_LEN 8
  8515. +#define DES3_MIN_KEY_LEN 24
  8516. +#define DES3_MAX_KEY_LEN 24
  8517. +#define BLOWFISH_MIN_KEY_LEN 4
  8518. +#define BLOWFISH_MAX_KEY_LEN 56
  8519. +#define SKIPJACK_MIN_KEY_LEN 10
  8520. +#define SKIPJACK_MAX_KEY_LEN 10
  8521. +#define CAST128_MIN_KEY_LEN 5
  8522. +#define CAST128_MAX_KEY_LEN 16
  8523. +#define RIJNDAEL128_MIN_KEY_LEN 16
  8524. +#define RIJNDAEL128_MAX_KEY_LEN 32
  8525. +#define AES_MIN_KEY_LEN RIJNDAEL128_MIN_KEY_LEN
  8526. +#define AES_MAX_KEY_LEN RIJNDAEL128_MAX_KEY_LEN
  8527. +#define CAMELLIA_MIN_KEY_LEN 16
  8528. +#define CAMELLIA_MAX_KEY_LEN 32
  8529. +#define ARC4_MIN_KEY_LEN 1
  8530. +#define ARC4_MAX_KEY_LEN 256
  8531. +
  8532. +/* Max size of data that can be processed */
  8533. +#define CRYPTO_MAX_DATA_LEN 64*1024 - 1
  8534. +
  8535. +#define CRYPTO_ALGORITHM_MIN 1
  8536. +#define CRYPTO_DES_CBC 1
  8537. +#define CRYPTO_3DES_CBC 2
  8538. +#define CRYPTO_BLF_CBC 3
  8539. +#define CRYPTO_CAST_CBC 4
  8540. +#define CRYPTO_SKIPJACK_CBC 5
  8541. +#define CRYPTO_MD5_HMAC 6
  8542. +#define CRYPTO_SHA1_HMAC 7
  8543. +#define CRYPTO_RIPEMD160_HMAC 8
  8544. +#define CRYPTO_MD5_KPDK 9
  8545. +#define CRYPTO_SHA1_KPDK 10
  8546. +#define CRYPTO_RIJNDAEL128_CBC 11 /* 128 bit blocksize */
  8547. +#define CRYPTO_AES_CBC 11 /* 128 bit blocksize -- the same as above */
  8548. +#define CRYPTO_ARC4 12
  8549. +#define CRYPTO_MD5 13
  8550. +#define CRYPTO_SHA1 14
  8551. +#define CRYPTO_NULL_HMAC 15
  8552. +#define CRYPTO_NULL_CBC 16
  8553. +#define CRYPTO_DEFLATE_COMP 17 /* Deflate compression algorithm */
  8554. +#define CRYPTO_SHA2_256_HMAC 18
  8555. +#define CRYPTO_SHA2_384_HMAC 19
  8556. +#define CRYPTO_SHA2_512_HMAC 20
  8557. +#define CRYPTO_CAMELLIA_CBC 21
  8558. +#define CRYPTO_SHA2_256 22
  8559. +#define CRYPTO_SHA2_384 23
  8560. +#define CRYPTO_SHA2_512 24
  8561. +#define CRYPTO_RIPEMD160 25
  8562. +#define CRYPTO_ALGORITHM_MAX 25 /* Keep updated - see below */
  8563. +
  8564. +/* Algorithm flags */
  8565. +#define CRYPTO_ALG_FLAG_SUPPORTED 0x01 /* Algorithm is supported */
  8566. +#define CRYPTO_ALG_FLAG_RNG_ENABLE 0x02 /* Has HW RNG for DH/DSA */
  8567. +#define CRYPTO_ALG_FLAG_DSA_SHA 0x04 /* Can do SHA on msg */
  8568. +
  8569. +/*
  8570. + * Crypto driver/device flags. They can set in the crid
  8571. + * parameter when creating a session or submitting a key
  8572. + * op to affect the device/driver assigned. If neither
  8573. + * of these are specified then the crid is assumed to hold
  8574. + * the driver id of an existing (and suitable) device that
  8575. + * must be used to satisfy the request.
  8576. + */
  8577. +#define CRYPTO_FLAG_HARDWARE 0x01000000 /* hardware accelerated */
  8578. +#define CRYPTO_FLAG_SOFTWARE 0x02000000 /* software implementation */
  8579. +
  8580. +/* NB: deprecated */
  8581. +struct session_op {
  8582. + u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
  8583. + u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
  8584. +
  8585. + u_int32_t keylen; /* cipher key */
  8586. + caddr_t key;
  8587. + int mackeylen; /* mac key */
  8588. + caddr_t mackey;
  8589. +
  8590. + u_int32_t ses; /* returns: session # */
  8591. +};
  8592. +
  8593. +struct session2_op {
  8594. + u_int32_t cipher; /* ie. CRYPTO_DES_CBC */
  8595. + u_int32_t mac; /* ie. CRYPTO_MD5_HMAC */
  8596. +
  8597. + u_int32_t keylen; /* cipher key */
  8598. + caddr_t key;
  8599. + int mackeylen; /* mac key */
  8600. + caddr_t mackey;
  8601. +
  8602. + u_int32_t ses; /* returns: session # */
  8603. + int crid; /* driver id + flags (rw) */
  8604. + int pad[4]; /* for future expansion */
  8605. +};
  8606. +
  8607. +struct crypt_op {
  8608. + u_int32_t ses;
  8609. + u_int16_t op; /* i.e. COP_ENCRYPT */
  8610. +#define COP_NONE 0
  8611. +#define COP_ENCRYPT 1
  8612. +#define COP_DECRYPT 2
  8613. + u_int16_t flags;
  8614. +#define COP_F_BATCH 0x0008 /* Batch op if possible */
  8615. + u_int len;
  8616. + caddr_t src, dst; /* become iov[] inside kernel */
  8617. + caddr_t mac; /* must be big enough for chosen MAC */
  8618. + caddr_t iv;
  8619. +};
  8620. +
  8621. +/*
  8622. + * Parameters for looking up a crypto driver/device by
  8623. + * device name or by id. The latter are returned for
  8624. + * created sessions (crid) and completed key operations.
  8625. + */
  8626. +struct crypt_find_op {
  8627. + int crid; /* driver id + flags */
  8628. + char name[32]; /* device/driver name */
  8629. +};
  8630. +
  8631. +/* bignum parameter, in packed bytes, ... */
  8632. +struct crparam {
  8633. + caddr_t crp_p;
  8634. + u_int crp_nbits;
  8635. +};
  8636. +
  8637. +#define CRK_MAXPARAM 8
  8638. +
  8639. +struct crypt_kop {
  8640. + u_int crk_op; /* ie. CRK_MOD_EXP or other */
  8641. + u_int crk_status; /* return status */
  8642. + u_short crk_iparams; /* # of input parameters */
  8643. + u_short crk_oparams; /* # of output parameters */
  8644. + u_int crk_crid; /* NB: only used by CIOCKEY2 (rw) */
  8645. + struct crparam crk_param[CRK_MAXPARAM];
  8646. +};
  8647. +#define CRK_ALGORITM_MIN 0
  8648. +#define CRK_MOD_EXP 0
  8649. +#define CRK_MOD_EXP_CRT 1
  8650. +#define CRK_DSA_SIGN 2
  8651. +#define CRK_DSA_VERIFY 3
  8652. +#define CRK_DH_COMPUTE_KEY 4
  8653. +#define CRK_ALGORITHM_MAX 4 /* Keep updated - see below */
  8654. +
  8655. +#define CRF_MOD_EXP (1 << CRK_MOD_EXP)
  8656. +#define CRF_MOD_EXP_CRT (1 << CRK_MOD_EXP_CRT)
  8657. +#define CRF_DSA_SIGN (1 << CRK_DSA_SIGN)
  8658. +#define CRF_DSA_VERIFY (1 << CRK_DSA_VERIFY)
  8659. +#define CRF_DH_COMPUTE_KEY (1 << CRK_DH_COMPUTE_KEY)
  8660. +
  8661. +/*
  8662. + * done against open of /dev/crypto, to get a cloned descriptor.
  8663. + * Please use F_SETFD against the cloned descriptor.
  8664. + */
  8665. +#define CRIOGET _IOWR('c', 100, u_int32_t)
  8666. +#define CRIOASYMFEAT CIOCASYMFEAT
  8667. +#define CRIOFINDDEV CIOCFINDDEV
  8668. +
  8669. +/* the following are done against the cloned descriptor */
  8670. +#define CIOCGSESSION _IOWR('c', 101, struct session_op)
  8671. +#define CIOCFSESSION _IOW('c', 102, u_int32_t)
  8672. +#define CIOCCRYPT _IOWR('c', 103, struct crypt_op)
  8673. +#define CIOCKEY _IOWR('c', 104, struct crypt_kop)
  8674. +#define CIOCASYMFEAT _IOR('c', 105, u_int32_t)
  8675. +#define CIOCGSESSION2 _IOWR('c', 106, struct session2_op)
  8676. +#define CIOCKEY2 _IOWR('c', 107, struct crypt_kop)
  8677. +#define CIOCFINDDEV _IOWR('c', 108, struct crypt_find_op)
  8678. +
  8679. +struct cryptotstat {
  8680. + struct timespec acc; /* total accumulated time */
  8681. + struct timespec min; /* min time */
  8682. + struct timespec max; /* max time */
  8683. + u_int32_t count; /* number of observations */
  8684. +};
  8685. +
  8686. +struct cryptostats {
  8687. + u_int32_t cs_ops; /* symmetric crypto ops submitted */
  8688. + u_int32_t cs_errs; /* symmetric crypto ops that failed */
  8689. + u_int32_t cs_kops; /* asymetric/key ops submitted */
  8690. + u_int32_t cs_kerrs; /* asymetric/key ops that failed */
  8691. + u_int32_t cs_intrs; /* crypto swi thread activations */
  8692. + u_int32_t cs_rets; /* crypto return thread activations */
  8693. + u_int32_t cs_blocks; /* symmetric op driver block */
  8694. + u_int32_t cs_kblocks; /* symmetric op driver block */
  8695. + /*
  8696. + * When CRYPTO_TIMING is defined at compile time and the
  8697. + * sysctl debug.crypto is set to 1, the crypto system will
  8698. + * accumulate statistics about how long it takes to process
  8699. + * crypto requests at various points during processing.
  8700. + */
  8701. + struct cryptotstat cs_invoke; /* crypto_dipsatch -> crypto_invoke */
  8702. + struct cryptotstat cs_done; /* crypto_invoke -> crypto_done */
  8703. + struct cryptotstat cs_cb; /* crypto_done -> callback */
  8704. + struct cryptotstat cs_finis; /* callback -> callback return */
  8705. +
  8706. + u_int32_t cs_drops; /* crypto ops dropped due to congestion */
  8707. +};
  8708. +
  8709. +#ifdef __KERNEL__
  8710. +
  8711. +/* Standard initialization structure beginning */
  8712. +struct cryptoini {
  8713. + int cri_alg; /* Algorithm to use */
  8714. + int cri_klen; /* Key length, in bits */
  8715. + int cri_mlen; /* Number of bytes we want from the
  8716. + entire hash. 0 means all. */
  8717. + caddr_t cri_key; /* key to use */
  8718. + u_int8_t cri_iv[EALG_MAX_BLOCK_LEN]; /* IV to use */
  8719. + struct cryptoini *cri_next;
  8720. +};
  8721. +
  8722. +/* Describe boundaries of a single crypto operation */
  8723. +struct cryptodesc {
  8724. + int crd_skip; /* How many bytes to ignore from start */
  8725. + int crd_len; /* How many bytes to process */
  8726. + int crd_inject; /* Where to inject results, if applicable */
  8727. + int crd_flags;
  8728. +
  8729. +#define CRD_F_ENCRYPT 0x01 /* Set when doing encryption */
  8730. +#define CRD_F_IV_PRESENT 0x02 /* When encrypting, IV is already in
  8731. + place, so don't copy. */
  8732. +#define CRD_F_IV_EXPLICIT 0x04 /* IV explicitly provided */
  8733. +#define CRD_F_DSA_SHA_NEEDED 0x08 /* Compute SHA-1 of buffer for DSA */
  8734. +#define CRD_F_KEY_EXPLICIT 0x10 /* Key explicitly provided */
  8735. +#define CRD_F_COMP 0x0f /* Set when doing compression */
  8736. +
  8737. + struct cryptoini CRD_INI; /* Initialization/context data */
  8738. +#define crd_iv CRD_INI.cri_iv
  8739. +#define crd_key CRD_INI.cri_key
  8740. +#define crd_alg CRD_INI.cri_alg
  8741. +#define crd_klen CRD_INI.cri_klen
  8742. +#define crd_mlen CRD_INI.cri_mlen
  8743. +
  8744. + struct cryptodesc *crd_next;
  8745. +};
  8746. +
  8747. +/* Structure describing complete operation */
  8748. +struct cryptop {
  8749. + struct list_head crp_next;
  8750. + wait_queue_head_t crp_waitq;
  8751. +
  8752. + u_int64_t crp_sid; /* Session ID */
  8753. + int crp_ilen; /* Input data total length */
  8754. + int crp_olen; /* Result total length */
  8755. +
  8756. + int crp_etype; /*
  8757. + * Error type (zero means no error).
  8758. + * All error codes except EAGAIN
  8759. + * indicate possible data corruption (as in,
  8760. + * the data have been touched). On all
  8761. + * errors, the crp_sid may have changed
  8762. + * (reset to a new one), so the caller
  8763. + * should always check and use the new
  8764. + * value on future requests.
  8765. + */
  8766. + int crp_flags;
  8767. +
  8768. +#define CRYPTO_F_SKBUF 0x0001 /* Input/output are skbuf chains */
  8769. +#define CRYPTO_F_IOV 0x0002 /* Input/output are uio */
  8770. +#define CRYPTO_F_REL 0x0004 /* Must return data in same place */
  8771. +#define CRYPTO_F_BATCH 0x0008 /* Batch op if possible */
  8772. +#define CRYPTO_F_CBIMM 0x0010 /* Do callback immediately */
  8773. +#define CRYPTO_F_DONE 0x0020 /* Operation completed */
  8774. +#define CRYPTO_F_CBIFSYNC 0x0040 /* Do CBIMM if op is synchronous */
  8775. +
  8776. + caddr_t crp_buf; /* Data to be processed */
  8777. + caddr_t crp_opaque; /* Opaque pointer, passed along */
  8778. + struct cryptodesc *crp_desc; /* Linked list of processing descriptors */
  8779. +
  8780. + int (*crp_callback)(struct cryptop *); /* Callback function */
  8781. +};
  8782. +
  8783. +#define CRYPTO_BUF_CONTIG 0x0
  8784. +#define CRYPTO_BUF_IOV 0x1
  8785. +#define CRYPTO_BUF_SKBUF 0x2
  8786. +
  8787. +#define CRYPTO_OP_DECRYPT 0x0
  8788. +#define CRYPTO_OP_ENCRYPT 0x1
  8789. +
  8790. +/*
  8791. + * Hints passed to process methods.
  8792. + */
  8793. +#define CRYPTO_HINT_MORE 0x1 /* more ops coming shortly */
  8794. +
  8795. +struct cryptkop {
  8796. + struct list_head krp_next;
  8797. + wait_queue_head_t krp_waitq;
  8798. +
  8799. + int krp_flags;
  8800. +#define CRYPTO_KF_DONE 0x0001 /* Operation completed */
  8801. +#define CRYPTO_KF_CBIMM 0x0002 /* Do callback immediately */
  8802. +
  8803. + u_int krp_op; /* ie. CRK_MOD_EXP or other */
  8804. + u_int krp_status; /* return status */
  8805. + u_short krp_iparams; /* # of input parameters */
  8806. + u_short krp_oparams; /* # of output parameters */
  8807. + u_int krp_crid; /* desired device, etc. */
  8808. + u_int32_t krp_hid;
  8809. + struct crparam krp_param[CRK_MAXPARAM]; /* kvm */
  8810. + int (*krp_callback)(struct cryptkop *);
  8811. +};
  8812. +
  8813. +#include <ocf-compat.h>
  8814. +
  8815. +/*
  8816. + * Session ids are 64 bits. The lower 32 bits contain a "local id" which
  8817. + * is a driver-private session identifier. The upper 32 bits contain a
  8818. + * "hardware id" used by the core crypto code to identify the driver and
  8819. + * a copy of the driver's capabilities that can be used by client code to
  8820. + * optimize operation.
  8821. + */
  8822. +#define CRYPTO_SESID2HID(_sid) (((_sid) >> 32) & 0x00ffffff)
  8823. +#define CRYPTO_SESID2CAPS(_sid) (((_sid) >> 32) & 0xff000000)
  8824. +#define CRYPTO_SESID2LID(_sid) (((u_int32_t) (_sid)) & 0xffffffff)
  8825. +
  8826. +extern int crypto_newsession(u_int64_t *sid, struct cryptoini *cri, int hard);
  8827. +extern int crypto_freesession(u_int64_t sid);
  8828. +#define CRYPTOCAP_F_HARDWARE CRYPTO_FLAG_HARDWARE
  8829. +#define CRYPTOCAP_F_SOFTWARE CRYPTO_FLAG_SOFTWARE
  8830. +#define CRYPTOCAP_F_SYNC 0x04000000 /* operates synchronously */
  8831. +extern int32_t crypto_get_driverid(device_t dev, int flags);
  8832. +extern int crypto_find_driver(const char *);
  8833. +extern device_t crypto_find_device_byhid(int hid);
  8834. +extern int crypto_getcaps(int hid);
  8835. +extern int crypto_register(u_int32_t driverid, int alg, u_int16_t maxoplen,
  8836. + u_int32_t flags);
  8837. +extern int crypto_kregister(u_int32_t, int, u_int32_t);
  8838. +extern int crypto_unregister(u_int32_t driverid, int alg);
  8839. +extern int crypto_unregister_all(u_int32_t driverid);
  8840. +extern int crypto_dispatch(struct cryptop *crp);
  8841. +extern int crypto_kdispatch(struct cryptkop *);
  8842. +#define CRYPTO_SYMQ 0x1
  8843. +#define CRYPTO_ASYMQ 0x2
  8844. +extern int crypto_unblock(u_int32_t, int);
  8845. +extern void crypto_done(struct cryptop *crp);
  8846. +extern void crypto_kdone(struct cryptkop *);
  8847. +extern int crypto_getfeat(int *);
  8848. +
  8849. +extern void crypto_freereq(struct cryptop *crp);
  8850. +extern struct cryptop *crypto_getreq(int num);
  8851. +
  8852. +extern int crypto_usercrypto; /* userland may do crypto requests */
  8853. +extern int crypto_userasymcrypto; /* userland may do asym crypto reqs */
  8854. +extern int crypto_devallowsoft; /* only use hardware crypto */
  8855. +
  8856. +/*
  8857. + * random number support, crypto_unregister_all will unregister
  8858. + */
  8859. +extern int crypto_rregister(u_int32_t driverid,
  8860. + int (*read_random)(void *arg, u_int32_t *buf, int len), void *arg);
  8861. +extern int crypto_runregister_all(u_int32_t driverid);
  8862. +
  8863. +/*
  8864. + * Crypto-related utility routines used mainly by drivers.
  8865. + *
  8866. + * XXX these don't really belong here; but for now they're
  8867. + * kept apart from the rest of the system.
  8868. + */
  8869. +struct uio;
  8870. +extern void cuio_copydata(struct uio* uio, int off, int len, caddr_t cp);
  8871. +extern void cuio_copyback(struct uio* uio, int off, int len, caddr_t cp);
  8872. +extern struct iovec *cuio_getptr(struct uio *uio, int loc, int *off);
  8873. +
  8874. +extern void crypto_copyback(int flags, caddr_t buf, int off, int size,
  8875. + caddr_t in);
  8876. +extern void crypto_copydata(int flags, caddr_t buf, int off, int size,
  8877. + caddr_t out);
  8878. +extern int crypto_apply(int flags, caddr_t buf, int off, int len,
  8879. + int (*f)(void *, void *, u_int), void *arg);
  8880. +
  8881. +#endif /* __KERNEL__ */
  8882. +#endif /* _CRYPTO_CRYPTO_H_ */
  8883. diff -Nur linux-2.6.39.orig/crypto/ocf/cryptosoft.c linux-2.6.39/crypto/ocf/cryptosoft.c
  8884. --- linux-2.6.39.orig/crypto/ocf/cryptosoft.c 1970-01-01 01:00:00.000000000 +0100
  8885. +++ linux-2.6.39/crypto/ocf/cryptosoft.c 2011-08-01 14:38:18.000000000 +0200
  8886. @@ -0,0 +1,1210 @@
  8887. +/*
  8888. + * An OCF module that uses the linux kernel cryptoapi, based on the
  8889. + * original cryptosoft for BSD by Angelos D. Keromytis (angelos@cis.upenn.edu)
  8890. + * but is mostly unrecognisable,
  8891. + *
  8892. + * Written by David McCullough <david_mccullough@mcafee.com>
  8893. + * Copyright (C) 2004-2010 David McCullough
  8894. + * Copyright (C) 2004-2005 Intel Corporation.
  8895. + *
  8896. + * LICENSE TERMS
  8897. + *
  8898. + * The free distribution and use of this software in both source and binary
  8899. + * form is allowed (with or without changes) provided that:
  8900. + *
  8901. + * 1. distributions of this source code include the above copyright
  8902. + * notice, this list of conditions and the following disclaimer;
  8903. + *
  8904. + * 2. distributions in binary form include the above copyright
  8905. + * notice, this list of conditions and the following disclaimer
  8906. + * in the documentation and/or other associated materials;
  8907. + *
  8908. + * 3. the copyright holder's name is not used to endorse products
  8909. + * built using this software without specific written permission.
  8910. + *
  8911. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  8912. + * may be distributed under the terms of the GNU General Public License (GPL),
  8913. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  8914. + *
  8915. + * DISCLAIMER
  8916. + *
  8917. + * This software is provided 'as is' with no explicit or implied warranties
  8918. + * in respect of its properties, including, but not limited to, correctness
  8919. + * and/or fitness for purpose.
  8920. + * ---------------------------------------------------------------------------
  8921. + */
  8922. +
  8923. +#ifndef AUTOCONF_INCLUDED
  8924. +#include <linux/config.h>
  8925. +#endif
  8926. +#include <linux/module.h>
  8927. +#include <linux/init.h>
  8928. +#include <linux/list.h>
  8929. +#include <linux/slab.h>
  8930. +#include <linux/sched.h>
  8931. +#include <linux/wait.h>
  8932. +#include <linux/crypto.h>
  8933. +#include <linux/mm.h>
  8934. +#include <linux/skbuff.h>
  8935. +#include <linux/random.h>
  8936. +#include <linux/version.h>
  8937. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)
  8938. +#include <linux/scatterlist.h>
  8939. +#endif
  8940. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
  8941. +#include <crypto/hash.h>
  8942. +#endif
  8943. +
  8944. +#include <cryptodev.h>
  8945. +#include <uio.h>
  8946. +
  8947. +struct {
  8948. + softc_device_decl sc_dev;
  8949. +} swcr_softc;
  8950. +
  8951. +#define offset_in_page(p) ((unsigned long)(p) & ~PAGE_MASK)
  8952. +
  8953. +#define SW_TYPE_CIPHER 0x01
  8954. +#define SW_TYPE_HMAC 0x02
  8955. +#define SW_TYPE_HASH 0x04
  8956. +#define SW_TYPE_COMP 0x08
  8957. +#define SW_TYPE_BLKCIPHER 0x10
  8958. +#define SW_TYPE_ALG_MASK 0x1f
  8959. +
  8960. +#define SW_TYPE_ASYNC 0x8000
  8961. +
  8962. +/* We change some of the above if we have an async interface */
  8963. +
  8964. +#define SW_TYPE_ALG_AMASK (SW_TYPE_ALG_MASK | SW_TYPE_ASYNC)
  8965. +
  8966. +#define SW_TYPE_ABLKCIPHER (SW_TYPE_BLKCIPHER | SW_TYPE_ASYNC)
  8967. +#define SW_TYPE_AHASH (SW_TYPE_HASH | SW_TYPE_ASYNC)
  8968. +#define SW_TYPE_AHMAC (SW_TYPE_HMAC | SW_TYPE_ASYNC)
  8969. +
  8970. +#define SCATTERLIST_MAX 16
  8971. +
  8972. +struct swcr_data {
  8973. + int sw_type;
  8974. + int sw_alg;
  8975. + struct crypto_tfm *sw_tfm;
  8976. + union {
  8977. + struct {
  8978. + char *sw_key;
  8979. + int sw_klen;
  8980. + int sw_mlen;
  8981. + } hmac;
  8982. + void *sw_comp_buf;
  8983. + } u;
  8984. + struct swcr_data *sw_next;
  8985. +};
  8986. +
  8987. +struct swcr_req {
  8988. + struct swcr_data *sw_head;
  8989. + struct swcr_data *sw;
  8990. + struct cryptop *crp;
  8991. + struct cryptodesc *crd;
  8992. + struct scatterlist sg[SCATTERLIST_MAX];
  8993. + unsigned char iv[EALG_MAX_BLOCK_LEN];
  8994. + char result[HASH_MAX_LEN];
  8995. + void *crypto_req;
  8996. +};
  8997. +
  8998. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  8999. +static kmem_cache_t *swcr_req_cache;
  9000. +#else
  9001. +static struct kmem_cache *swcr_req_cache;
  9002. +#endif
  9003. +
  9004. +#ifndef CRYPTO_TFM_MODE_CBC
  9005. +/*
  9006. + * As of linux-2.6.21 this is no longer defined, and presumably no longer
  9007. + * needed to be passed into the crypto core code.
  9008. + */
  9009. +#define CRYPTO_TFM_MODE_CBC 0
  9010. +#define CRYPTO_TFM_MODE_ECB 0
  9011. +#endif
  9012. +
  9013. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
  9014. + /*
  9015. + * Linux 2.6.19 introduced a new Crypto API, setup macro's to convert new
  9016. + * API into old API.
  9017. + */
  9018. +
  9019. + /* Symmetric/Block Cipher */
  9020. + struct blkcipher_desc
  9021. + {
  9022. + struct crypto_tfm *tfm;
  9023. + void *info;
  9024. + };
  9025. + #define ecb(X) #X , CRYPTO_TFM_MODE_ECB
  9026. + #define cbc(X) #X , CRYPTO_TFM_MODE_CBC
  9027. + #define crypto_has_blkcipher(X, Y, Z) crypto_alg_available(X, 0)
  9028. + #define crypto_blkcipher_cast(X) X
  9029. + #define crypto_blkcipher_tfm(X) X
  9030. + #define crypto_alloc_blkcipher(X, Y, Z) crypto_alloc_tfm(X, mode)
  9031. + #define crypto_blkcipher_ivsize(X) crypto_tfm_alg_ivsize(X)
  9032. + #define crypto_blkcipher_blocksize(X) crypto_tfm_alg_blocksize(X)
  9033. + #define crypto_blkcipher_setkey(X, Y, Z) crypto_cipher_setkey(X, Y, Z)
  9034. + #define crypto_blkcipher_encrypt_iv(W, X, Y, Z) \
  9035. + crypto_cipher_encrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
  9036. + #define crypto_blkcipher_decrypt_iv(W, X, Y, Z) \
  9037. + crypto_cipher_decrypt_iv((W)->tfm, X, Y, Z, (u8 *)((W)->info))
  9038. + #define crypto_blkcipher_set_flags(x, y) /* nop */
  9039. +
  9040. + /* Hash/HMAC/Digest */
  9041. + struct hash_desc
  9042. + {
  9043. + struct crypto_tfm *tfm;
  9044. + };
  9045. + #define hmac(X) #X , 0
  9046. + #define crypto_has_hash(X, Y, Z) crypto_alg_available(X, 0)
  9047. + #define crypto_hash_cast(X) X
  9048. + #define crypto_hash_tfm(X) X
  9049. + #define crypto_alloc_hash(X, Y, Z) crypto_alloc_tfm(X, mode)
  9050. + #define crypto_hash_digestsize(X) crypto_tfm_alg_digestsize(X)
  9051. + #define crypto_hash_digest(W, X, Y, Z) \
  9052. + crypto_digest_digest((W)->tfm, X, sg_num, Z)
  9053. +
  9054. + /* Asymmetric Cipher */
  9055. + #define crypto_has_cipher(X, Y, Z) crypto_alg_available(X, 0)
  9056. +
  9057. + /* Compression */
  9058. + #define crypto_has_comp(X, Y, Z) crypto_alg_available(X, 0)
  9059. + #define crypto_comp_tfm(X) X
  9060. + #define crypto_comp_cast(X) X
  9061. + #define crypto_alloc_comp(X, Y, Z) crypto_alloc_tfm(X, mode)
  9062. + #define plain(X) #X , 0
  9063. +#else
  9064. + #define ecb(X) "ecb(" #X ")" , 0
  9065. + #define cbc(X) "cbc(" #X ")" , 0
  9066. + #define hmac(X) "hmac(" #X ")" , 0
  9067. + #define plain(X) #X , 0
  9068. +#endif /* if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
  9069. +
  9070. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22)
  9071. +/* no ablkcipher in older kernels */
  9072. +#define crypto_alloc_ablkcipher(a,b,c) (NULL)
  9073. +#define crypto_ablkcipher_tfm(x) ((struct crypto_tfm *)(x))
  9074. +#define crypto_ablkcipher_set_flags(a, b) /* nop */
  9075. +#define crypto_ablkcipher_setkey(x, y, z) (-EINVAL)
  9076. +#define crypto_has_ablkcipher(a,b,c) (0)
  9077. +#else
  9078. +#define HAVE_ABLKCIPHER
  9079. +#endif
  9080. +
  9081. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
  9082. +/* no ahash in older kernels */
  9083. +#define crypto_ahash_tfm(x) ((struct crypto_tfm *)(x))
  9084. +#define crypto_alloc_ahash(a,b,c) (NULL)
  9085. +#define crypto_ahash_digestsize(x) 0
  9086. +#else
  9087. +#define HAVE_AHASH
  9088. +#endif
  9089. +
  9090. +struct crypto_details {
  9091. + char *alg_name;
  9092. + int mode;
  9093. + int sw_type;
  9094. +};
  9095. +
  9096. +static struct crypto_details crypto_details[] = {
  9097. + [CRYPTO_DES_CBC] = { cbc(des), SW_TYPE_BLKCIPHER, },
  9098. + [CRYPTO_3DES_CBC] = { cbc(des3_ede), SW_TYPE_BLKCIPHER, },
  9099. + [CRYPTO_BLF_CBC] = { cbc(blowfish), SW_TYPE_BLKCIPHER, },
  9100. + [CRYPTO_CAST_CBC] = { cbc(cast5), SW_TYPE_BLKCIPHER, },
  9101. + [CRYPTO_SKIPJACK_CBC] = { cbc(skipjack), SW_TYPE_BLKCIPHER, },
  9102. + [CRYPTO_MD5_HMAC] = { hmac(md5), SW_TYPE_HMAC, },
  9103. + [CRYPTO_SHA1_HMAC] = { hmac(sha1), SW_TYPE_HMAC, },
  9104. + [CRYPTO_RIPEMD160_HMAC] = { hmac(ripemd160), SW_TYPE_HMAC, },
  9105. + [CRYPTO_MD5_KPDK] = { plain(md5-kpdk), SW_TYPE_HASH, },
  9106. + [CRYPTO_SHA1_KPDK] = { plain(sha1-kpdk), SW_TYPE_HASH, },
  9107. + [CRYPTO_AES_CBC] = { cbc(aes), SW_TYPE_BLKCIPHER, },
  9108. + [CRYPTO_ARC4] = { ecb(arc4), SW_TYPE_BLKCIPHER, },
  9109. + [CRYPTO_MD5] = { plain(md5), SW_TYPE_HASH, },
  9110. + [CRYPTO_SHA1] = { plain(sha1), SW_TYPE_HASH, },
  9111. + [CRYPTO_NULL_HMAC] = { hmac(digest_null), SW_TYPE_HMAC, },
  9112. + [CRYPTO_NULL_CBC] = { cbc(cipher_null), SW_TYPE_BLKCIPHER, },
  9113. + [CRYPTO_DEFLATE_COMP] = { plain(deflate), SW_TYPE_COMP, },
  9114. + [CRYPTO_SHA2_256_HMAC] = { hmac(sha256), SW_TYPE_HMAC, },
  9115. + [CRYPTO_SHA2_384_HMAC] = { hmac(sha384), SW_TYPE_HMAC, },
  9116. + [CRYPTO_SHA2_512_HMAC] = { hmac(sha512), SW_TYPE_HMAC, },
  9117. + [CRYPTO_CAMELLIA_CBC] = { cbc(camellia), SW_TYPE_BLKCIPHER, },
  9118. + [CRYPTO_SHA2_256] = { plain(sha256), SW_TYPE_HASH, },
  9119. + [CRYPTO_SHA2_384] = { plain(sha384), SW_TYPE_HASH, },
  9120. + [CRYPTO_SHA2_512] = { plain(sha512), SW_TYPE_HASH, },
  9121. + [CRYPTO_RIPEMD160] = { plain(ripemd160), SW_TYPE_HASH, },
  9122. +};
  9123. +
  9124. +int32_t swcr_id = -1;
  9125. +module_param(swcr_id, int, 0444);
  9126. +MODULE_PARM_DESC(swcr_id, "Read-Only OCF ID for cryptosoft driver");
  9127. +
  9128. +int swcr_fail_if_compression_grows = 1;
  9129. +module_param(swcr_fail_if_compression_grows, int, 0644);
  9130. +MODULE_PARM_DESC(swcr_fail_if_compression_grows,
  9131. + "Treat compression that results in more data as a failure");
  9132. +
  9133. +int swcr_no_ahash = 0;
  9134. +module_param(swcr_no_ahash, int, 0644);
  9135. +MODULE_PARM_DESC(swcr_no_ahash,
  9136. + "Do not use async hash/hmac even if available");
  9137. +
  9138. +int swcr_no_ablk = 0;
  9139. +module_param(swcr_no_ablk, int, 0644);
  9140. +MODULE_PARM_DESC(swcr_no_ablk,
  9141. + "Do not use async blk ciphers even if available");
  9142. +
  9143. +static struct swcr_data **swcr_sessions = NULL;
  9144. +static u_int32_t swcr_sesnum = 0;
  9145. +
  9146. +static int swcr_process(device_t, struct cryptop *, int);
  9147. +static int swcr_newsession(device_t, u_int32_t *, struct cryptoini *);
  9148. +static int swcr_freesession(device_t, u_int64_t);
  9149. +
  9150. +static device_method_t swcr_methods = {
  9151. + /* crypto device methods */
  9152. + DEVMETHOD(cryptodev_newsession, swcr_newsession),
  9153. + DEVMETHOD(cryptodev_freesession,swcr_freesession),
  9154. + DEVMETHOD(cryptodev_process, swcr_process),
  9155. +};
  9156. +
  9157. +#define debug swcr_debug
  9158. +int swcr_debug = 0;
  9159. +module_param(swcr_debug, int, 0644);
  9160. +MODULE_PARM_DESC(swcr_debug, "Enable debug");
  9161. +
  9162. +static void swcr_process_req(struct swcr_req *req);
  9163. +
  9164. +/*
  9165. + * Generate a new software session.
  9166. + */
  9167. +static int
  9168. +swcr_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  9169. +{
  9170. + struct swcr_data **swd;
  9171. + u_int32_t i;
  9172. + int error;
  9173. + char *algo;
  9174. + int mode;
  9175. +
  9176. + dprintk("%s()\n", __FUNCTION__);
  9177. + if (sid == NULL || cri == NULL) {
  9178. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  9179. + return EINVAL;
  9180. + }
  9181. +
  9182. + if (swcr_sessions) {
  9183. + for (i = 1; i < swcr_sesnum; i++)
  9184. + if (swcr_sessions[i] == NULL)
  9185. + break;
  9186. + } else
  9187. + i = 1; /* NB: to silence compiler warning */
  9188. +
  9189. + if (swcr_sessions == NULL || i == swcr_sesnum) {
  9190. + if (swcr_sessions == NULL) {
  9191. + i = 1; /* We leave swcr_sessions[0] empty */
  9192. + swcr_sesnum = CRYPTO_SW_SESSIONS;
  9193. + } else
  9194. + swcr_sesnum *= 2;
  9195. +
  9196. + swd = kmalloc(swcr_sesnum * sizeof(struct swcr_data *), SLAB_ATOMIC);
  9197. + if (swd == NULL) {
  9198. + /* Reset session number */
  9199. + if (swcr_sesnum == CRYPTO_SW_SESSIONS)
  9200. + swcr_sesnum = 0;
  9201. + else
  9202. + swcr_sesnum /= 2;
  9203. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  9204. + return ENOBUFS;
  9205. + }
  9206. + memset(swd, 0, swcr_sesnum * sizeof(struct swcr_data *));
  9207. +
  9208. + /* Copy existing sessions */
  9209. + if (swcr_sessions) {
  9210. + memcpy(swd, swcr_sessions,
  9211. + (swcr_sesnum / 2) * sizeof(struct swcr_data *));
  9212. + kfree(swcr_sessions);
  9213. + }
  9214. +
  9215. + swcr_sessions = swd;
  9216. + }
  9217. +
  9218. + swd = &swcr_sessions[i];
  9219. + *sid = i;
  9220. +
  9221. + while (cri) {
  9222. + *swd = (struct swcr_data *) kmalloc(sizeof(struct swcr_data),
  9223. + SLAB_ATOMIC);
  9224. + if (*swd == NULL) {
  9225. + swcr_freesession(NULL, i);
  9226. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  9227. + return ENOBUFS;
  9228. + }
  9229. + memset(*swd, 0, sizeof(struct swcr_data));
  9230. +
  9231. + if (cri->cri_alg < 0 ||
  9232. + cri->cri_alg>=sizeof(crypto_details)/sizeof(crypto_details[0])){
  9233. + printk("cryptosoft: Unknown algorithm 0x%x\n", cri->cri_alg);
  9234. + swcr_freesession(NULL, i);
  9235. + return EINVAL;
  9236. + }
  9237. +
  9238. + algo = crypto_details[cri->cri_alg].alg_name;
  9239. + if (!algo || !*algo) {
  9240. + printk("cryptosoft: Unsupported algorithm 0x%x\n", cri->cri_alg);
  9241. + swcr_freesession(NULL, i);
  9242. + return EINVAL;
  9243. + }
  9244. +
  9245. + mode = crypto_details[cri->cri_alg].mode;
  9246. + (*swd)->sw_type = crypto_details[cri->cri_alg].sw_type;
  9247. + (*swd)->sw_alg = cri->cri_alg;
  9248. +
  9249. + /* Algorithm specific configuration */
  9250. + switch (cri->cri_alg) {
  9251. + case CRYPTO_NULL_CBC:
  9252. + cri->cri_klen = 0; /* make it work with crypto API */
  9253. + break;
  9254. + default:
  9255. + break;
  9256. + }
  9257. +
  9258. + if ((*swd)->sw_type & SW_TYPE_BLKCIPHER) {
  9259. + dprintk("%s crypto_alloc_*blkcipher(%s, 0x%x)\n", __FUNCTION__,
  9260. + algo, mode);
  9261. +
  9262. + /* try async first */
  9263. + (*swd)->sw_tfm = swcr_no_ablk ? NULL :
  9264. + crypto_ablkcipher_tfm(crypto_alloc_ablkcipher(algo, 0, 0));
  9265. + if ((*swd)->sw_tfm) {
  9266. + dprintk("%s %s cipher is async\n", __FUNCTION__, algo);
  9267. + (*swd)->sw_type |= SW_TYPE_ASYNC;
  9268. + } else {
  9269. + dprintk("%s %s cipher is sync\n", __FUNCTION__, algo);
  9270. + (*swd)->sw_tfm = crypto_blkcipher_tfm(
  9271. + crypto_alloc_blkcipher(algo, 0, CRYPTO_ALG_ASYNC));
  9272. + }
  9273. + if (!(*swd)->sw_tfm) {
  9274. + dprintk("cryptosoft: crypto_alloc_blkcipher failed(%s, 0x%x)\n",
  9275. + algo,mode);
  9276. + swcr_freesession(NULL, i);
  9277. + return EINVAL;
  9278. + }
  9279. +
  9280. + if (debug) {
  9281. + dprintk("%s key:cri->cri_klen=%d,(cri->cri_klen + 7)/8=%d",
  9282. + __FUNCTION__, cri->cri_klen, (cri->cri_klen + 7) / 8);
  9283. + for (i = 0; i < (cri->cri_klen + 7) / 8; i++)
  9284. + dprintk("%s0x%x", (i % 8) ? " " : "\n ",
  9285. + cri->cri_key[i] & 0xff);
  9286. + dprintk("\n");
  9287. + }
  9288. + if ((*swd)->sw_type & SW_TYPE_ASYNC) {
  9289. + /* OCF doesn't enforce keys */
  9290. + crypto_ablkcipher_set_flags(
  9291. + __crypto_ablkcipher_cast((*swd)->sw_tfm),
  9292. + CRYPTO_TFM_REQ_WEAK_KEY);
  9293. + error = crypto_ablkcipher_setkey(
  9294. + __crypto_ablkcipher_cast((*swd)->sw_tfm),
  9295. + cri->cri_key, (cri->cri_klen + 7) / 8);
  9296. + } else {
  9297. + /* OCF doesn't enforce keys */
  9298. + crypto_blkcipher_set_flags(
  9299. + crypto_blkcipher_cast((*swd)->sw_tfm),
  9300. + CRYPTO_TFM_REQ_WEAK_KEY);
  9301. + error = crypto_blkcipher_setkey(
  9302. + crypto_blkcipher_cast((*swd)->sw_tfm),
  9303. + cri->cri_key, (cri->cri_klen + 7) / 8);
  9304. + }
  9305. + if (error) {
  9306. + printk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n", error,
  9307. + (*swd)->sw_tfm->crt_flags);
  9308. + swcr_freesession(NULL, i);
  9309. + return error;
  9310. + }
  9311. + } else if ((*swd)->sw_type & (SW_TYPE_HMAC | SW_TYPE_HASH)) {
  9312. + dprintk("%s crypto_alloc_*hash(%s, 0x%x)\n", __FUNCTION__,
  9313. + algo, mode);
  9314. +
  9315. + /* try async first */
  9316. + (*swd)->sw_tfm = swcr_no_ahash ? NULL :
  9317. + crypto_ahash_tfm(crypto_alloc_ahash(algo, 0, 0));
  9318. + if ((*swd)->sw_tfm) {
  9319. + dprintk("%s %s hash is async\n", __FUNCTION__, algo);
  9320. + (*swd)->sw_type |= SW_TYPE_ASYNC;
  9321. + } else {
  9322. + dprintk("%s %s hash is sync\n", __FUNCTION__, algo);
  9323. + (*swd)->sw_tfm = crypto_hash_tfm(
  9324. + crypto_alloc_hash(algo, 0, CRYPTO_ALG_ASYNC));
  9325. + }
  9326. +
  9327. + if (!(*swd)->sw_tfm) {
  9328. + dprintk("cryptosoft: crypto_alloc_hash failed(%s,0x%x)\n",
  9329. + algo, mode);
  9330. + swcr_freesession(NULL, i);
  9331. + return EINVAL;
  9332. + }
  9333. +
  9334. + (*swd)->u.hmac.sw_klen = (cri->cri_klen + 7) / 8;
  9335. + (*swd)->u.hmac.sw_key = (char *)kmalloc((*swd)->u.hmac.sw_klen,
  9336. + SLAB_ATOMIC);
  9337. + if ((*swd)->u.hmac.sw_key == NULL) {
  9338. + swcr_freesession(NULL, i);
  9339. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  9340. + return ENOBUFS;
  9341. + }
  9342. + memcpy((*swd)->u.hmac.sw_key, cri->cri_key, (*swd)->u.hmac.sw_klen);
  9343. + if (cri->cri_mlen) {
  9344. + (*swd)->u.hmac.sw_mlen = cri->cri_mlen;
  9345. + } else if ((*swd)->sw_type & SW_TYPE_ASYNC) {
  9346. + (*swd)->u.hmac.sw_mlen = crypto_ahash_digestsize(
  9347. + __crypto_ahash_cast((*swd)->sw_tfm));
  9348. + } else {
  9349. + (*swd)->u.hmac.sw_mlen = crypto_hash_digestsize(
  9350. + crypto_hash_cast((*swd)->sw_tfm));
  9351. + }
  9352. + } else if ((*swd)->sw_type & SW_TYPE_COMP) {
  9353. + (*swd)->sw_tfm = crypto_comp_tfm(
  9354. + crypto_alloc_comp(algo, 0, CRYPTO_ALG_ASYNC));
  9355. + if (!(*swd)->sw_tfm) {
  9356. + dprintk("cryptosoft: crypto_alloc_comp failed(%s,0x%x)\n",
  9357. + algo, mode);
  9358. + swcr_freesession(NULL, i);
  9359. + return EINVAL;
  9360. + }
  9361. + (*swd)->u.sw_comp_buf = kmalloc(CRYPTO_MAX_DATA_LEN, SLAB_ATOMIC);
  9362. + if ((*swd)->u.sw_comp_buf == NULL) {
  9363. + swcr_freesession(NULL, i);
  9364. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  9365. + return ENOBUFS;
  9366. + }
  9367. + } else {
  9368. + printk("cryptosoft: Unhandled sw_type %d\n", (*swd)->sw_type);
  9369. + swcr_freesession(NULL, i);
  9370. + return EINVAL;
  9371. + }
  9372. +
  9373. + cri = cri->cri_next;
  9374. + swd = &((*swd)->sw_next);
  9375. + }
  9376. + return 0;
  9377. +}
  9378. +
  9379. +/*
  9380. + * Free a session.
  9381. + */
  9382. +static int
  9383. +swcr_freesession(device_t dev, u_int64_t tid)
  9384. +{
  9385. + struct swcr_data *swd;
  9386. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  9387. +
  9388. + dprintk("%s()\n", __FUNCTION__);
  9389. + if (sid > swcr_sesnum || swcr_sessions == NULL ||
  9390. + swcr_sessions[sid] == NULL) {
  9391. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  9392. + return(EINVAL);
  9393. + }
  9394. +
  9395. + /* Silently accept and return */
  9396. + if (sid == 0)
  9397. + return(0);
  9398. +
  9399. + while ((swd = swcr_sessions[sid]) != NULL) {
  9400. + swcr_sessions[sid] = swd->sw_next;
  9401. + if (swd->sw_tfm) {
  9402. + switch (swd->sw_type & SW_TYPE_ALG_AMASK) {
  9403. +#ifdef HAVE_AHASH
  9404. + case SW_TYPE_AHMAC:
  9405. + case SW_TYPE_AHASH:
  9406. + crypto_free_ahash(__crypto_ahash_cast(swd->sw_tfm));
  9407. + break;
  9408. +#endif
  9409. +#ifdef HAVE_ABLKCIPHER
  9410. + case SW_TYPE_ABLKCIPHER:
  9411. + crypto_free_ablkcipher(__crypto_ablkcipher_cast(swd->sw_tfm));
  9412. + break;
  9413. +#endif
  9414. + case SW_TYPE_BLKCIPHER:
  9415. + crypto_free_blkcipher(crypto_blkcipher_cast(swd->sw_tfm));
  9416. + break;
  9417. + case SW_TYPE_HMAC:
  9418. + case SW_TYPE_HASH:
  9419. + crypto_free_hash(crypto_hash_cast(swd->sw_tfm));
  9420. + break;
  9421. + case SW_TYPE_COMP:
  9422. + crypto_free_comp(crypto_comp_cast(swd->sw_tfm));
  9423. + default:
  9424. + crypto_free_tfm(swd->sw_tfm);
  9425. + break;
  9426. + }
  9427. + swd->sw_tfm = NULL;
  9428. + }
  9429. + if (swd->sw_type & SW_TYPE_COMP) {
  9430. + if (swd->u.sw_comp_buf)
  9431. + kfree(swd->u.sw_comp_buf);
  9432. + } else {
  9433. + if (swd->u.hmac.sw_key)
  9434. + kfree(swd->u.hmac.sw_key);
  9435. + }
  9436. + kfree(swd);
  9437. + }
  9438. + return 0;
  9439. +}
  9440. +
  9441. +#if defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH)
  9442. +/* older kernels had no async interface */
  9443. +
  9444. +static void swcr_process_callback(struct crypto_async_request *creq, int err)
  9445. +{
  9446. + struct swcr_req *req = creq->data;
  9447. +
  9448. + dprintk("%s()\n", __FUNCTION__);
  9449. + if (err) {
  9450. + if (err == -EINPROGRESS)
  9451. + return;
  9452. + dprintk("%s() fail %d\n", __FUNCTION__, -err);
  9453. + req->crp->crp_etype = -err;
  9454. + goto done;
  9455. + }
  9456. +
  9457. + switch (req->sw->sw_type & SW_TYPE_ALG_AMASK) {
  9458. + case SW_TYPE_AHMAC:
  9459. + case SW_TYPE_AHASH:
  9460. + crypto_copyback(req->crp->crp_flags, req->crp->crp_buf,
  9461. + req->crd->crd_inject, req->sw->u.hmac.sw_mlen, req->result);
  9462. + ahash_request_free(req->crypto_req);
  9463. + break;
  9464. + case SW_TYPE_ABLKCIPHER:
  9465. + ablkcipher_request_free(req->crypto_req);
  9466. + break;
  9467. + default:
  9468. + req->crp->crp_etype = EINVAL;
  9469. + goto done;
  9470. + }
  9471. +
  9472. + req->crd = req->crd->crd_next;
  9473. + if (req->crd) {
  9474. + swcr_process_req(req);
  9475. + return;
  9476. + }
  9477. +
  9478. +done:
  9479. + dprintk("%s crypto_done %p\n", __FUNCTION__, req);
  9480. + crypto_done(req->crp);
  9481. + kmem_cache_free(swcr_req_cache, req);
  9482. +}
  9483. +#endif /* defined(HAVE_ABLKCIPHER) || defined(HAVE_AHASH) */
  9484. +
  9485. +
  9486. +static void swcr_process_req(struct swcr_req *req)
  9487. +{
  9488. + struct swcr_data *sw;
  9489. + struct cryptop *crp = req->crp;
  9490. + struct cryptodesc *crd = req->crd;
  9491. + struct sk_buff *skb = (struct sk_buff *) crp->crp_buf;
  9492. + struct uio *uiop = (struct uio *) crp->crp_buf;
  9493. + int sg_num, sg_len, skip;
  9494. +
  9495. + dprintk("%s()\n", __FUNCTION__);
  9496. +
  9497. + /*
  9498. + * Find the crypto context.
  9499. + *
  9500. + * XXX Note that the logic here prevents us from having
  9501. + * XXX the same algorithm multiple times in a session
  9502. + * XXX (or rather, we can but it won't give us the right
  9503. + * XXX results). To do that, we'd need some way of differentiating
  9504. + * XXX between the various instances of an algorithm (so we can
  9505. + * XXX locate the correct crypto context).
  9506. + */
  9507. + for (sw = req->sw_head; sw && sw->sw_alg != crd->crd_alg; sw = sw->sw_next)
  9508. + ;
  9509. +
  9510. + /* No such context ? */
  9511. + if (sw == NULL) {
  9512. + crp->crp_etype = EINVAL;
  9513. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  9514. + goto done;
  9515. + }
  9516. +
  9517. + req->sw = sw;
  9518. + skip = crd->crd_skip;
  9519. +
  9520. + /*
  9521. + * setup the SG list skip from the start of the buffer
  9522. + */
  9523. + memset(req->sg, 0, sizeof(req->sg));
  9524. + sg_init_table(req->sg, SCATTERLIST_MAX);
  9525. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  9526. + int i, len;
  9527. +
  9528. + sg_num = 0;
  9529. + sg_len = 0;
  9530. +
  9531. + if (skip < skb_headlen(skb)) {
  9532. + len = skb_headlen(skb) - skip;
  9533. + if (len + sg_len > crd->crd_len)
  9534. + len = crd->crd_len - sg_len;
  9535. + sg_set_page(&req->sg[sg_num],
  9536. + virt_to_page(skb->data + skip), len,
  9537. + offset_in_page(skb->data + skip));
  9538. + sg_len += len;
  9539. + sg_num++;
  9540. + skip = 0;
  9541. + } else
  9542. + skip -= skb_headlen(skb);
  9543. +
  9544. + for (i = 0; sg_len < crd->crd_len &&
  9545. + i < skb_shinfo(skb)->nr_frags &&
  9546. + sg_num < SCATTERLIST_MAX; i++) {
  9547. + if (skip < skb_shinfo(skb)->frags[i].size) {
  9548. + len = skb_shinfo(skb)->frags[i].size - skip;
  9549. + if (len + sg_len > crd->crd_len)
  9550. + len = crd->crd_len - sg_len;
  9551. + sg_set_page(&req->sg[sg_num],
  9552. + skb_shinfo(skb)->frags[i].page,
  9553. + len,
  9554. + skb_shinfo(skb)->frags[i].page_offset + skip);
  9555. + sg_len += len;
  9556. + sg_num++;
  9557. + skip = 0;
  9558. + } else
  9559. + skip -= skb_shinfo(skb)->frags[i].size;
  9560. + }
  9561. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  9562. + int len;
  9563. +
  9564. + sg_len = 0;
  9565. + for (sg_num = 0; sg_len < crd->crd_len &&
  9566. + sg_num < uiop->uio_iovcnt &&
  9567. + sg_num < SCATTERLIST_MAX; sg_num++) {
  9568. + if (skip <= uiop->uio_iov[sg_num].iov_len) {
  9569. + len = uiop->uio_iov[sg_num].iov_len - skip;
  9570. + if (len + sg_len > crd->crd_len)
  9571. + len = crd->crd_len - sg_len;
  9572. + sg_set_page(&req->sg[sg_num],
  9573. + virt_to_page(uiop->uio_iov[sg_num].iov_base+skip),
  9574. + len,
  9575. + offset_in_page(uiop->uio_iov[sg_num].iov_base+skip));
  9576. + sg_len += len;
  9577. + skip = 0;
  9578. + } else
  9579. + skip -= uiop->uio_iov[sg_num].iov_len;
  9580. + }
  9581. + } else {
  9582. + sg_len = (crp->crp_ilen - skip);
  9583. + if (sg_len > crd->crd_len)
  9584. + sg_len = crd->crd_len;
  9585. + sg_set_page(&req->sg[0], virt_to_page(crp->crp_buf + skip),
  9586. + sg_len, offset_in_page(crp->crp_buf + skip));
  9587. + sg_num = 1;
  9588. + }
  9589. +
  9590. + switch (sw->sw_type & SW_TYPE_ALG_AMASK) {
  9591. +
  9592. +#ifdef HAVE_AHASH
  9593. + case SW_TYPE_AHMAC:
  9594. + case SW_TYPE_AHASH:
  9595. + {
  9596. + int ret;
  9597. +
  9598. + /* check we have room for the result */
  9599. + if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
  9600. + dprintk("cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d "
  9601. + "digestsize=%d\n", crp->crp_ilen, crd->crd_skip + sg_len,
  9602. + crd->crd_inject, sw->u.hmac.sw_mlen);
  9603. + crp->crp_etype = EINVAL;
  9604. + goto done;
  9605. + }
  9606. +
  9607. + req->crypto_req =
  9608. + ahash_request_alloc(__crypto_ahash_cast(sw->sw_tfm),GFP_KERNEL);
  9609. + if (!req->crypto_req) {
  9610. + crp->crp_etype = ENOMEM;
  9611. + dprintk("%s,%d: ENOMEM ahash_request_alloc", __FILE__, __LINE__);
  9612. + goto done;
  9613. + }
  9614. +
  9615. + ahash_request_set_callback(req->crypto_req,
  9616. + CRYPTO_TFM_REQ_MAY_BACKLOG, swcr_process_callback, req);
  9617. +
  9618. + memset(req->result, 0, sizeof(req->result));
  9619. +
  9620. + if (sw->sw_type & SW_TYPE_AHMAC)
  9621. + crypto_ahash_setkey(__crypto_ahash_cast(sw->sw_tfm),
  9622. + sw->u.hmac.sw_key, sw->u.hmac.sw_klen);
  9623. + ahash_request_set_crypt(req->crypto_req, req->sg, req->result, sg_len);
  9624. + ret = crypto_ahash_digest(req->crypto_req);
  9625. + switch (ret) {
  9626. + case -EINPROGRESS:
  9627. + case -EBUSY:
  9628. + return;
  9629. + default:
  9630. + case 0:
  9631. + dprintk("hash OP %s %d\n", ret ? "failed" : "success", ret);
  9632. + crp->crp_etype = ret;
  9633. + ahash_request_free(req->crypto_req);
  9634. + goto done;
  9635. + }
  9636. + } break;
  9637. +#endif /* HAVE_AHASH */
  9638. +
  9639. +#ifdef HAVE_ABLKCIPHER
  9640. + case SW_TYPE_ABLKCIPHER: {
  9641. + int ret;
  9642. + unsigned char *ivp = req->iv;
  9643. + int ivsize =
  9644. + crypto_ablkcipher_ivsize(__crypto_ablkcipher_cast(sw->sw_tfm));
  9645. +
  9646. + if (sg_len < crypto_ablkcipher_blocksize(
  9647. + __crypto_ablkcipher_cast(sw->sw_tfm))) {
  9648. + crp->crp_etype = EINVAL;
  9649. + dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
  9650. + sg_len, crypto_ablkcipher_blocksize(
  9651. + __crypto_ablkcipher_cast(sw->sw_tfm)));
  9652. + goto done;
  9653. + }
  9654. +
  9655. + if (ivsize > sizeof(req->iv)) {
  9656. + crp->crp_etype = EINVAL;
  9657. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  9658. + goto done;
  9659. + }
  9660. +
  9661. + req->crypto_req = ablkcipher_request_alloc(
  9662. + __crypto_ablkcipher_cast(sw->sw_tfm), GFP_KERNEL);
  9663. + if (!req->crypto_req) {
  9664. + crp->crp_etype = ENOMEM;
  9665. + dprintk("%s,%d: ENOMEM ablkcipher_request_alloc",
  9666. + __FILE__, __LINE__);
  9667. + goto done;
  9668. + }
  9669. +
  9670. + ablkcipher_request_set_callback(req->crypto_req,
  9671. + CRYPTO_TFM_REQ_MAY_BACKLOG, swcr_process_callback, req);
  9672. +
  9673. + if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
  9674. + int i, error;
  9675. +
  9676. + if (debug) {
  9677. + dprintk("%s key:", __FUNCTION__);
  9678. + for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
  9679. + dprintk("%s0x%x", (i % 8) ? " " : "\n ",
  9680. + crd->crd_key[i] & 0xff);
  9681. + dprintk("\n");
  9682. + }
  9683. + /* OCF doesn't enforce keys */
  9684. + crypto_ablkcipher_set_flags(__crypto_ablkcipher_cast(sw->sw_tfm),
  9685. + CRYPTO_TFM_REQ_WEAK_KEY);
  9686. + error = crypto_ablkcipher_setkey(
  9687. + __crypto_ablkcipher_cast(sw->sw_tfm), crd->crd_key,
  9688. + (crd->crd_klen + 7) / 8);
  9689. + if (error) {
  9690. + dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
  9691. + error, sw->sw_tfm->crt_flags);
  9692. + crp->crp_etype = -error;
  9693. + }
  9694. + }
  9695. +
  9696. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  9697. +
  9698. + if (crd->crd_flags & CRD_F_IV_EXPLICIT)
  9699. + ivp = crd->crd_iv;
  9700. + else
  9701. + get_random_bytes(ivp, ivsize);
  9702. + /*
  9703. + * do we have to copy the IV back to the buffer ?
  9704. + */
  9705. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  9706. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  9707. + crd->crd_inject, ivsize, (caddr_t)ivp);
  9708. + }
  9709. + ablkcipher_request_set_crypt(req->crypto_req, req->sg, req->sg,
  9710. + sg_len, ivp);
  9711. + ret = crypto_ablkcipher_encrypt(req->crypto_req);
  9712. +
  9713. + } else { /*decrypt */
  9714. +
  9715. + if (crd->crd_flags & CRD_F_IV_EXPLICIT)
  9716. + ivp = crd->crd_iv;
  9717. + else
  9718. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  9719. + crd->crd_inject, ivsize, (caddr_t)ivp);
  9720. + ablkcipher_request_set_crypt(req->crypto_req, req->sg, req->sg,
  9721. + sg_len, ivp);
  9722. + ret = crypto_ablkcipher_decrypt(req->crypto_req);
  9723. + }
  9724. +
  9725. + switch (ret) {
  9726. + case -EINPROGRESS:
  9727. + case -EBUSY:
  9728. + return;
  9729. + default:
  9730. + case 0:
  9731. + dprintk("crypto OP %s %d\n", ret ? "failed" : "success", ret);
  9732. + crp->crp_etype = ret;
  9733. + goto done;
  9734. + }
  9735. + } break;
  9736. +#endif /* HAVE_ABLKCIPHER */
  9737. +
  9738. + case SW_TYPE_BLKCIPHER: {
  9739. + unsigned char iv[EALG_MAX_BLOCK_LEN];
  9740. + unsigned char *ivp = iv;
  9741. + struct blkcipher_desc desc;
  9742. + int ivsize = crypto_blkcipher_ivsize(crypto_blkcipher_cast(sw->sw_tfm));
  9743. +
  9744. + if (sg_len < crypto_blkcipher_blocksize(
  9745. + crypto_blkcipher_cast(sw->sw_tfm))) {
  9746. + crp->crp_etype = EINVAL;
  9747. + dprintk("%s,%d: EINVAL len %d < %d\n", __FILE__, __LINE__,
  9748. + sg_len, crypto_blkcipher_blocksize(
  9749. + crypto_blkcipher_cast(sw->sw_tfm)));
  9750. + goto done;
  9751. + }
  9752. +
  9753. + if (ivsize > sizeof(iv)) {
  9754. + crp->crp_etype = EINVAL;
  9755. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  9756. + goto done;
  9757. + }
  9758. +
  9759. + if (crd->crd_flags & CRD_F_KEY_EXPLICIT) {
  9760. + int i, error;
  9761. +
  9762. + if (debug) {
  9763. + dprintk("%s key:", __FUNCTION__);
  9764. + for (i = 0; i < (crd->crd_klen + 7) / 8; i++)
  9765. + dprintk("%s0x%x", (i % 8) ? " " : "\n ",
  9766. + crd->crd_key[i] & 0xff);
  9767. + dprintk("\n");
  9768. + }
  9769. + /* OCF doesn't enforce keys */
  9770. + crypto_blkcipher_set_flags(crypto_blkcipher_cast(sw->sw_tfm),
  9771. + CRYPTO_TFM_REQ_WEAK_KEY);
  9772. + error = crypto_blkcipher_setkey(
  9773. + crypto_blkcipher_cast(sw->sw_tfm), crd->crd_key,
  9774. + (crd->crd_klen + 7) / 8);
  9775. + if (error) {
  9776. + dprintk("cryptosoft: setkey failed %d (crt_flags=0x%x)\n",
  9777. + error, sw->sw_tfm->crt_flags);
  9778. + crp->crp_etype = -error;
  9779. + }
  9780. + }
  9781. +
  9782. + memset(&desc, 0, sizeof(desc));
  9783. + desc.tfm = crypto_blkcipher_cast(sw->sw_tfm);
  9784. +
  9785. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  9786. +
  9787. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  9788. + ivp = crd->crd_iv;
  9789. + } else {
  9790. + get_random_bytes(ivp, ivsize);
  9791. + }
  9792. + /*
  9793. + * do we have to copy the IV back to the buffer ?
  9794. + */
  9795. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  9796. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  9797. + crd->crd_inject, ivsize, (caddr_t)ivp);
  9798. + }
  9799. + desc.info = ivp;
  9800. + crypto_blkcipher_encrypt_iv(&desc, req->sg, req->sg, sg_len);
  9801. +
  9802. + } else { /*decrypt */
  9803. +
  9804. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  9805. + ivp = crd->crd_iv;
  9806. + } else {
  9807. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  9808. + crd->crd_inject, ivsize, (caddr_t)ivp);
  9809. + }
  9810. + desc.info = ivp;
  9811. + crypto_blkcipher_decrypt_iv(&desc, req->sg, req->sg, sg_len);
  9812. + }
  9813. + } break;
  9814. +
  9815. + case SW_TYPE_HMAC:
  9816. + case SW_TYPE_HASH:
  9817. + {
  9818. + char result[HASH_MAX_LEN];
  9819. + struct hash_desc desc;
  9820. +
  9821. + /* check we have room for the result */
  9822. + if (crp->crp_ilen - crd->crd_inject < sw->u.hmac.sw_mlen) {
  9823. + dprintk("cryptosoft: EINVAL crp_ilen=%d, len=%d, inject=%d "
  9824. + "digestsize=%d\n", crp->crp_ilen, crd->crd_skip + sg_len,
  9825. + crd->crd_inject, sw->u.hmac.sw_mlen);
  9826. + crp->crp_etype = EINVAL;
  9827. + goto done;
  9828. + }
  9829. +
  9830. + memset(&desc, 0, sizeof(desc));
  9831. + desc.tfm = crypto_hash_cast(sw->sw_tfm);
  9832. +
  9833. + memset(result, 0, sizeof(result));
  9834. +
  9835. + if (sw->sw_type & SW_TYPE_HMAC) {
  9836. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)
  9837. + crypto_hmac(sw->sw_tfm, sw->u.hmac.sw_key, &sw->u.hmac.sw_klen,
  9838. + req->sg, sg_num, result);
  9839. +#else
  9840. + crypto_hash_setkey(desc.tfm, sw->u.hmac.sw_key,
  9841. + sw->u.hmac.sw_klen);
  9842. + crypto_hash_digest(&desc, req->sg, sg_len, result);
  9843. +#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19) */
  9844. +
  9845. + } else { /* SW_TYPE_HASH */
  9846. + crypto_hash_digest(&desc, req->sg, sg_len, result);
  9847. + }
  9848. +
  9849. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  9850. + crd->crd_inject, sw->u.hmac.sw_mlen, result);
  9851. + }
  9852. + break;
  9853. +
  9854. + case SW_TYPE_COMP: {
  9855. + void *ibuf = NULL;
  9856. + void *obuf = sw->u.sw_comp_buf;
  9857. + int ilen = sg_len, olen = CRYPTO_MAX_DATA_LEN;
  9858. + int ret = 0;
  9859. +
  9860. + /*
  9861. + * we need to use an additional copy if there is more than one
  9862. + * input chunk since the kernel comp routines do not handle
  9863. + * SG yet. Otherwise we just use the input buffer as is.
  9864. + * Rather than allocate another buffer we just split the tmp
  9865. + * buffer we already have.
  9866. + * Perhaps we should just use zlib directly ?
  9867. + */
  9868. + if (sg_num > 1) {
  9869. + int blk;
  9870. +
  9871. + ibuf = obuf;
  9872. + for (blk = 0; blk < sg_num; blk++) {
  9873. + memcpy(obuf, sg_virt(&req->sg[blk]),
  9874. + req->sg[blk].length);
  9875. + obuf += req->sg[blk].length;
  9876. + }
  9877. + olen -= sg_len;
  9878. + } else
  9879. + ibuf = sg_virt(&req->sg[0]);
  9880. +
  9881. + if (crd->crd_flags & CRD_F_ENCRYPT) { /* compress */
  9882. + ret = crypto_comp_compress(crypto_comp_cast(sw->sw_tfm),
  9883. + ibuf, ilen, obuf, &olen);
  9884. + if (!ret && olen > crd->crd_len) {
  9885. + dprintk("cryptosoft: ERANGE compress %d into %d\n",
  9886. + crd->crd_len, olen);
  9887. + if (swcr_fail_if_compression_grows)
  9888. + ret = ERANGE;
  9889. + }
  9890. + } else { /* decompress */
  9891. + ret = crypto_comp_decompress(crypto_comp_cast(sw->sw_tfm),
  9892. + ibuf, ilen, obuf, &olen);
  9893. + if (!ret && (olen + crd->crd_inject) > crp->crp_olen) {
  9894. + dprintk("cryptosoft: ETOOSMALL decompress %d into %d, "
  9895. + "space for %d,at offset %d\n",
  9896. + crd->crd_len, olen, crp->crp_olen, crd->crd_inject);
  9897. + ret = ETOOSMALL;
  9898. + }
  9899. + }
  9900. + if (ret)
  9901. + dprintk("%s,%d: ret = %d\n", __FILE__, __LINE__, ret);
  9902. +
  9903. + /*
  9904. + * on success copy result back,
  9905. + * linux crpyto API returns -errno, we need to fix that
  9906. + */
  9907. + crp->crp_etype = ret < 0 ? -ret : ret;
  9908. + if (ret == 0) {
  9909. + /* copy back the result and return it's size */
  9910. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  9911. + crd->crd_inject, olen, obuf);
  9912. + crp->crp_olen = olen;
  9913. + }
  9914. +
  9915. +
  9916. + } break;
  9917. +
  9918. + default:
  9919. + /* Unknown/unsupported algorithm */
  9920. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  9921. + crp->crp_etype = EINVAL;
  9922. + goto done;
  9923. + }
  9924. +
  9925. +done:
  9926. + crypto_done(crp);
  9927. + kmem_cache_free(swcr_req_cache, req);
  9928. +}
  9929. +
  9930. +
  9931. +/*
  9932. + * Process a crypto request.
  9933. + */
  9934. +static int
  9935. +swcr_process(device_t dev, struct cryptop *crp, int hint)
  9936. +{
  9937. + struct swcr_req *req = NULL;
  9938. + u_int32_t lid;
  9939. +
  9940. + dprintk("%s()\n", __FUNCTION__);
  9941. + /* Sanity check */
  9942. + if (crp == NULL) {
  9943. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  9944. + return EINVAL;
  9945. + }
  9946. +
  9947. + crp->crp_etype = 0;
  9948. +
  9949. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  9950. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  9951. + crp->crp_etype = EINVAL;
  9952. + goto done;
  9953. + }
  9954. +
  9955. + lid = crp->crp_sid & 0xffffffff;
  9956. + if (lid >= swcr_sesnum || lid == 0 || swcr_sessions == NULL ||
  9957. + swcr_sessions[lid] == NULL) {
  9958. + crp->crp_etype = ENOENT;
  9959. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  9960. + goto done;
  9961. + }
  9962. +
  9963. + /*
  9964. + * do some error checking outside of the loop for SKB and IOV processing
  9965. + * this leaves us with valid skb or uiop pointers for later
  9966. + */
  9967. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  9968. + struct sk_buff *skb = (struct sk_buff *) crp->crp_buf;
  9969. + if (skb_shinfo(skb)->nr_frags >= SCATTERLIST_MAX) {
  9970. + printk("%s,%d: %d nr_frags > SCATTERLIST_MAX", __FILE__, __LINE__,
  9971. + skb_shinfo(skb)->nr_frags);
  9972. + goto done;
  9973. + }
  9974. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  9975. + struct uio *uiop = (struct uio *) crp->crp_buf;
  9976. + if (uiop->uio_iovcnt > SCATTERLIST_MAX) {
  9977. + printk("%s,%d: %d uio_iovcnt > SCATTERLIST_MAX", __FILE__, __LINE__,
  9978. + uiop->uio_iovcnt);
  9979. + goto done;
  9980. + }
  9981. + }
  9982. +
  9983. + /*
  9984. + * setup a new request ready for queuing
  9985. + */
  9986. + req = kmem_cache_alloc(swcr_req_cache, SLAB_ATOMIC);
  9987. + if (req == NULL) {
  9988. + dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);
  9989. + crp->crp_etype = ENOMEM;
  9990. + goto done;
  9991. + }
  9992. + memset(req, 0, sizeof(*req));
  9993. +
  9994. + req->sw_head = swcr_sessions[lid];
  9995. + req->crp = crp;
  9996. + req->crd = crp->crp_desc;
  9997. +
  9998. + swcr_process_req(req);
  9999. + return 0;
  10000. +
  10001. +done:
  10002. + crypto_done(crp);
  10003. + if (req)
  10004. + kmem_cache_free(swcr_req_cache, req);
  10005. + return 0;
  10006. +}
  10007. +
  10008. +
  10009. +static int
  10010. +cryptosoft_init(void)
  10011. +{
  10012. + int i, sw_type, mode;
  10013. + char *algo;
  10014. +
  10015. + dprintk("%s(%p)\n", __FUNCTION__, cryptosoft_init);
  10016. +
  10017. + swcr_req_cache = kmem_cache_create("cryptosoft_req",
  10018. + sizeof(struct swcr_req), 0, SLAB_HWCACHE_ALIGN, NULL
  10019. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  10020. + , NULL
  10021. +#endif
  10022. + );
  10023. + if (!swcr_req_cache) {
  10024. + printk("cryptosoft: failed to create request cache\n");
  10025. + return -ENOENT;
  10026. + }
  10027. +
  10028. + softc_device_init(&swcr_softc, "cryptosoft", 0, swcr_methods);
  10029. +
  10030. + swcr_id = crypto_get_driverid(softc_get_device(&swcr_softc),
  10031. + CRYPTOCAP_F_SOFTWARE | CRYPTOCAP_F_SYNC);
  10032. + if (swcr_id < 0) {
  10033. + printk("cryptosoft: Software crypto device cannot initialize!");
  10034. + return -ENODEV;
  10035. + }
  10036. +
  10037. +#define REGISTER(alg) \
  10038. + crypto_register(swcr_id, alg, 0,0)
  10039. +
  10040. + for (i = 0; i < sizeof(crypto_details)/sizeof(crypto_details[0]); i++) {
  10041. + int found;
  10042. +
  10043. + algo = crypto_details[i].alg_name;
  10044. + if (!algo || !*algo) {
  10045. + dprintk("%s:Algorithm %d not supported\n", __FUNCTION__, i);
  10046. + continue;
  10047. + }
  10048. +
  10049. + mode = crypto_details[i].mode;
  10050. + sw_type = crypto_details[i].sw_type;
  10051. +
  10052. + found = 0;
  10053. + switch (sw_type & SW_TYPE_ALG_MASK) {
  10054. + case SW_TYPE_CIPHER:
  10055. + found = crypto_has_cipher(algo, 0, CRYPTO_ALG_ASYNC);
  10056. + break;
  10057. + case SW_TYPE_HMAC:
  10058. + found = crypto_has_hash(algo, 0, swcr_no_ahash?CRYPTO_ALG_ASYNC:0);
  10059. + break;
  10060. + case SW_TYPE_HASH:
  10061. + found = crypto_has_hash(algo, 0, swcr_no_ahash?CRYPTO_ALG_ASYNC:0);
  10062. + break;
  10063. + case SW_TYPE_COMP:
  10064. + found = crypto_has_comp(algo, 0, CRYPTO_ALG_ASYNC);
  10065. + break;
  10066. + case SW_TYPE_BLKCIPHER:
  10067. + found = crypto_has_blkcipher(algo, 0, CRYPTO_ALG_ASYNC);
  10068. + if (!found && !swcr_no_ablk)
  10069. + found = crypto_has_ablkcipher(algo, 0, 0);
  10070. + break;
  10071. + }
  10072. + if (found) {
  10073. + REGISTER(i);
  10074. + } else {
  10075. + dprintk("%s:Algorithm Type %d not supported (algorithm %d:'%s')\n",
  10076. + __FUNCTION__, sw_type, i, algo);
  10077. + }
  10078. + }
  10079. + return 0;
  10080. +}
  10081. +
  10082. +static void
  10083. +cryptosoft_exit(void)
  10084. +{
  10085. + dprintk("%s()\n", __FUNCTION__);
  10086. + crypto_unregister_all(swcr_id);
  10087. + swcr_id = -1;
  10088. + kmem_cache_destroy(swcr_req_cache);
  10089. +}
  10090. +
  10091. +late_initcall(cryptosoft_init);
  10092. +module_exit(cryptosoft_exit);
  10093. +
  10094. +MODULE_LICENSE("Dual BSD/GPL");
  10095. +MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
  10096. +MODULE_DESCRIPTION("Cryptosoft (OCF module for kernel crypto)");
  10097. diff -Nur linux-2.6.39.orig/crypto/ocf/ep80579/Makefile linux-2.6.39/crypto/ocf/ep80579/Makefile
  10098. --- linux-2.6.39.orig/crypto/ocf/ep80579/Makefile 1970-01-01 01:00:00.000000000 +0100
  10099. +++ linux-2.6.39/crypto/ocf/ep80579/Makefile 2011-08-01 14:38:18.000000000 +0200
  10100. @@ -0,0 +1,119 @@
  10101. +#########################################################################
  10102. +#
  10103. +# Targets supported
  10104. +# all - builds everything and installs
  10105. +# install - identical to all
  10106. +# depend - build dependencies
  10107. +# clean - clears derived objects except the .depend files
  10108. +# distclean- clears all derived objects and the .depend file
  10109. +#
  10110. +# @par
  10111. +# This file is provided under a dual BSD/GPLv2 license. When using or
  10112. +# redistributing this file, you may do so under either license.
  10113. +#
  10114. +# GPL LICENSE SUMMARY
  10115. +#
  10116. +# Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  10117. +#
  10118. +# This program is free software; you can redistribute it and/or modify
  10119. +# it under the terms of version 2 of the GNU General Public License as
  10120. +# published by the Free Software Foundation.
  10121. +#
  10122. +# This program is distributed in the hope that it will be useful, but
  10123. +# WITHOUT ANY WARRANTY; without even the implied warranty of
  10124. +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10125. +# General Public License for more details.
  10126. +#
  10127. +# You should have received a copy of the GNU General Public License
  10128. +# along with this program; if not, write to the Free Software
  10129. +# Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  10130. +# The full GNU General Public License is included in this distribution
  10131. +# in the file called LICENSE.GPL.
  10132. +#
  10133. +# Contact Information:
  10134. +# Intel Corporation
  10135. +#
  10136. +# BSD LICENSE
  10137. +#
  10138. +# Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  10139. +# All rights reserved.
  10140. +#
  10141. +# Redistribution and use in source and binary forms, with or without
  10142. +# modification, are permitted provided that the following conditions
  10143. +# are met:
  10144. +#
  10145. +# * Redistributions of source code must retain the above copyright
  10146. +# notice, this list of conditions and the following disclaimer.
  10147. +# * Redistributions in binary form must reproduce the above copyright
  10148. +# notice, this list of conditions and the following disclaimer in
  10149. +# the documentation and/or other materials provided with the
  10150. +# distribution.
  10151. +# * Neither the name of Intel Corporation nor the names of its
  10152. +# contributors may be used to endorse or promote products derived
  10153. +# from this software without specific prior written permission.
  10154. +#
  10155. +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  10156. +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  10157. +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  10158. +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  10159. +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10160. +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  10161. +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10162. +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  10163. +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  10164. +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  10165. +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  10166. +#
  10167. +#
  10168. +# version: Security.L.1.0.2-229
  10169. +############################################################################
  10170. +
  10171. +
  10172. +####################Common variables and definitions########################
  10173. +
  10174. +ifndef ICP_ROOT
  10175. +$(warning ICP_ROOT is undefined. Please set the path to EP80579 release package directory \
  10176. + "-> setenv ICP_ROOT <path>")
  10177. +all fastdep:
  10178. + :
  10179. +else
  10180. +
  10181. +ifndef KERNEL_SOURCE_ROOT
  10182. +$(error KERNEL_SOURCE_ROOT is undefined. Please set the path to the kernel source directory \
  10183. + "-> setenv KERNEL_SOURCE_ROOT <path>")
  10184. +endif
  10185. +
  10186. +# Ensure The ENV_DIR environmental var is defined.
  10187. +ifndef ICP_ENV_DIR
  10188. +$(error ICP_ENV_DIR is undefined. Please set the path to EP80579 driver environment.mk file \
  10189. + "-> setenv ICP_ENV_DIR <path>")
  10190. +endif
  10191. +
  10192. +#Add your project environment Makefile
  10193. +include ${ICP_ENV_DIR}/environment.mk
  10194. +
  10195. +#include the makefile with all the default and common Make variable definitions
  10196. +include ${ICP_BUILDSYSTEM_PATH}/build_files/common.mk
  10197. +
  10198. +#Add the name for the executable, Library or Module output definitions
  10199. +OUTPUT_NAME= icp_ocf
  10200. +
  10201. +# List of Source Files to be compiled
  10202. +SOURCES= icp_common.c icp_sym.c icp_asym.c icp_ocf_linux.c
  10203. +
  10204. +#common includes between all supported OSes
  10205. +INCLUDES= -I ${ICP_API_DIR} -I${ICP_LAC_API} \
  10206. +-I${ICP_OCF_SRC_DIR}
  10207. +
  10208. +# The location of the os level makefile needs to be changed.
  10209. +include ${ICP_ENV_DIR}/${ICP_OS}_${ICP_OS_LEVEL}.mk
  10210. +
  10211. +# On the line directly below list the outputs you wish to build for,
  10212. +# e.g "lib_static lib_shared exe module" as shown below
  10213. +install: module
  10214. +
  10215. +###################Include rules makefiles########################
  10216. +include ${ICP_BUILDSYSTEM_PATH}/build_files/rules.mk
  10217. +###################End of Rules inclusion#########################
  10218. +
  10219. +endif
  10220. diff -Nur linux-2.6.39.orig/crypto/ocf/ep80579/icp_asym.c linux-2.6.39/crypto/ocf/ep80579/icp_asym.c
  10221. --- linux-2.6.39.orig/crypto/ocf/ep80579/icp_asym.c 1970-01-01 01:00:00.000000000 +0100
  10222. +++ linux-2.6.39/crypto/ocf/ep80579/icp_asym.c 2011-08-01 14:38:18.000000000 +0200
  10223. @@ -0,0 +1,1334 @@
  10224. +/***************************************************************************
  10225. + *
  10226. + * This file is provided under a dual BSD/GPLv2 license. When using or
  10227. + * redistributing this file, you may do so under either license.
  10228. + *
  10229. + * GPL LICENSE SUMMARY
  10230. + *
  10231. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  10232. + *
  10233. + * This program is free software; you can redistribute it and/or modify
  10234. + * it under the terms of version 2 of the GNU General Public License as
  10235. + * published by the Free Software Foundation.
  10236. + *
  10237. + * This program is distributed in the hope that it will be useful, but
  10238. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  10239. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  10240. + * General Public License for more details.
  10241. + *
  10242. + * You should have received a copy of the GNU General Public License
  10243. + * along with this program; if not, write to the Free Software
  10244. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  10245. + * The full GNU General Public License is included in this distribution
  10246. + * in the file called LICENSE.GPL.
  10247. + *
  10248. + * Contact Information:
  10249. + * Intel Corporation
  10250. + *
  10251. + * BSD LICENSE
  10252. + *
  10253. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  10254. + * All rights reserved.
  10255. + *
  10256. + * Redistribution and use in source and binary forms, with or without
  10257. + * modification, are permitted provided that the following conditions
  10258. + * are met:
  10259. + *
  10260. + * * Redistributions of source code must retain the above copyright
  10261. + * notice, this list of conditions and the following disclaimer.
  10262. + * * Redistributions in binary form must reproduce the above copyright
  10263. + * notice, this list of conditions and the following disclaimer in
  10264. + * the documentation and/or other materials provided with the
  10265. + * distribution.
  10266. + * * Neither the name of Intel Corporation nor the names of its
  10267. + * contributors may be used to endorse or promote products derived
  10268. + * from this software without specific prior written permission.
  10269. + *
  10270. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  10271. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  10272. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  10273. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  10274. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  10275. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  10276. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  10277. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  10278. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  10279. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  10280. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  10281. + *
  10282. + *
  10283. + * version: Security.L.1.0.2-229
  10284. + *
  10285. + ***************************************************************************/
  10286. +
  10287. +#include "icp_ocf.h"
  10288. +
  10289. +/*The following define values (containing the word 'INDEX') are used to find
  10290. +the index of each input buffer of the crypto_kop struct (see OCF cryptodev.h).
  10291. +These values were found through analysis of the OCF OpenSSL patch. If the
  10292. +calling program uses different input buffer positions, these defines will have
  10293. +to be changed.*/
  10294. +
  10295. +/*DIFFIE HELLMAN buffer index values*/
  10296. +#define ICP_DH_KRP_PARAM_PRIME_INDEX (0)
  10297. +#define ICP_DH_KRP_PARAM_BASE_INDEX (1)
  10298. +#define ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX (2)
  10299. +#define ICP_DH_KRP_PARAM_RESULT_INDEX (3)
  10300. +
  10301. +/*MOD EXP buffer index values*/
  10302. +#define ICP_MOD_EXP_KRP_PARAM_BASE_INDEX (0)
  10303. +#define ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX (1)
  10304. +#define ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX (2)
  10305. +#define ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX (3)
  10306. +
  10307. +/*MOD EXP CRT buffer index values*/
  10308. +#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX (0)
  10309. +#define ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX (1)
  10310. +#define ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX (2)
  10311. +#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX (3)
  10312. +#define ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX (4)
  10313. +#define ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX (5)
  10314. +#define ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX (6)
  10315. +
  10316. +/*DSA sign buffer index values*/
  10317. +#define ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX (0)
  10318. +#define ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX (1)
  10319. +#define ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX (2)
  10320. +#define ICP_DSA_SIGN_KRP_PARAM_G_INDEX (3)
  10321. +#define ICP_DSA_SIGN_KRP_PARAM_X_INDEX (4)
  10322. +#define ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX (5)
  10323. +#define ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX (6)
  10324. +
  10325. +/*DSA verify buffer index values*/
  10326. +#define ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX (0)
  10327. +#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX (1)
  10328. +#define ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX (2)
  10329. +#define ICP_DSA_VERIFY_KRP_PARAM_G_INDEX (3)
  10330. +#define ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX (4)
  10331. +#define ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX (5)
  10332. +#define ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX (6)
  10333. +
  10334. +/*DSA sign prime Q vs random number K size check values*/
  10335. +#define DONT_RUN_LESS_THAN_CHECK (0)
  10336. +#define FAIL_A_IS_GREATER_THAN_B (1)
  10337. +#define FAIL_A_IS_EQUAL_TO_B (1)
  10338. +#define SUCCESS_A_IS_LESS_THAN_B (0)
  10339. +#define DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS (500)
  10340. +
  10341. +/* We need to set a cryptokp success value just in case it is set or allocated
  10342. + and not set to zero outside of this module */
  10343. +#define CRYPTO_OP_SUCCESS (0)
  10344. +
  10345. +/*Function to compute Diffie Hellman (DH) phase 1 or phase 2 key values*/
  10346. +static int icp_ocfDrvDHComputeKey(struct cryptkop *krp);
  10347. +
  10348. +/*Function to compute a Modular Exponentiation (Mod Exp)*/
  10349. +static int icp_ocfDrvModExp(struct cryptkop *krp);
  10350. +
  10351. +/*Function to compute a Mod Exp using the Chinease Remainder Theorem*/
  10352. +static int icp_ocfDrvModExpCRT(struct cryptkop *krp);
  10353. +
  10354. +/*Helper function to compute whether the first big number argument is less than
  10355. + the second big number argument */
  10356. +static int
  10357. +icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck);
  10358. +
  10359. +/*Function to sign an input with DSA R and S keys*/
  10360. +static int icp_ocfDrvDsaSign(struct cryptkop *krp);
  10361. +
  10362. +/*Function to Verify a DSA buffer signature*/
  10363. +static int icp_ocfDrvDsaVerify(struct cryptkop *krp);
  10364. +
  10365. +/*Callback function for DH operation*/
  10366. +static void
  10367. +icp_ocfDrvDhP1CallBack(void *callbackTag,
  10368. + CpaStatus status,
  10369. + void *pOpData, CpaFlatBuffer * pLocalOctetStringPV);
  10370. +
  10371. +/*Callback function for ME operation*/
  10372. +static void
  10373. +icp_ocfDrvModExpCallBack(void *callbackTag,
  10374. + CpaStatus status,
  10375. + void *pOpData, CpaFlatBuffer * pResult);
  10376. +
  10377. +/*Callback function for ME CRT operation*/
  10378. +static void
  10379. +icp_ocfDrvModExpCRTCallBack(void *callbackTag,
  10380. + CpaStatus status,
  10381. + void *pOpData, CpaFlatBuffer * pOutputData);
  10382. +
  10383. +/*Callback function for DSA sign operation*/
  10384. +static void
  10385. +icp_ocfDrvDsaRSSignCallBack(void *callbackTag,
  10386. + CpaStatus status,
  10387. + void *pOpData,
  10388. + CpaBoolean protocolStatus,
  10389. + CpaFlatBuffer * pR, CpaFlatBuffer * pS);
  10390. +
  10391. +/*Callback function for DSA Verify operation*/
  10392. +static void
  10393. +icp_ocfDrvDsaVerifyCallBack(void *callbackTag,
  10394. + CpaStatus status,
  10395. + void *pOpData, CpaBoolean verifyStatus);
  10396. +
  10397. +/* Name : icp_ocfDrvPkeProcess
  10398. + *
  10399. + * Description : This function will choose which PKE process to follow
  10400. + * based on the input arguments
  10401. + */
  10402. +int icp_ocfDrvPkeProcess(icp_device_t dev, struct cryptkop *krp, int hint)
  10403. +{
  10404. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  10405. +
  10406. + if (NULL == krp) {
  10407. + DPRINTK("%s(): Invalid input parameters, cryptkop = %p\n",
  10408. + __FUNCTION__, krp);
  10409. + return EINVAL;
  10410. + }
  10411. +
  10412. + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  10413. + krp->krp_status = ECANCELED;
  10414. + return ECANCELED;
  10415. + }
  10416. +
  10417. + switch (krp->krp_op) {
  10418. + case CRK_DH_COMPUTE_KEY:
  10419. + DPRINTK("%s() doing DH_COMPUTE_KEY\n", __FUNCTION__);
  10420. + lacStatus = icp_ocfDrvDHComputeKey(krp);
  10421. + if (CPA_STATUS_SUCCESS != lacStatus) {
  10422. + EPRINTK("%s(): icp_ocfDrvDHComputeKey failed "
  10423. + "(%d).\n", __FUNCTION__, lacStatus);
  10424. + krp->krp_status = ECANCELED;
  10425. + return ECANCELED;
  10426. + }
  10427. +
  10428. + break;
  10429. +
  10430. + case CRK_MOD_EXP:
  10431. + DPRINTK("%s() doing MOD_EXP \n", __FUNCTION__);
  10432. + lacStatus = icp_ocfDrvModExp(krp);
  10433. + if (CPA_STATUS_SUCCESS != lacStatus) {
  10434. + EPRINTK("%s(): icp_ocfDrvModExp failed (%d).\n",
  10435. + __FUNCTION__, lacStatus);
  10436. + krp->krp_status = ECANCELED;
  10437. + return ECANCELED;
  10438. + }
  10439. +
  10440. + break;
  10441. +
  10442. + case CRK_MOD_EXP_CRT:
  10443. + DPRINTK("%s() doing MOD_EXP_CRT \n", __FUNCTION__);
  10444. + lacStatus = icp_ocfDrvModExpCRT(krp);
  10445. + if (CPA_STATUS_SUCCESS != lacStatus) {
  10446. + EPRINTK("%s(): icp_ocfDrvModExpCRT "
  10447. + "failed (%d).\n", __FUNCTION__, lacStatus);
  10448. + krp->krp_status = ECANCELED;
  10449. + return ECANCELED;
  10450. + }
  10451. +
  10452. + break;
  10453. +
  10454. + case CRK_DSA_SIGN:
  10455. + DPRINTK("%s() doing DSA_SIGN \n", __FUNCTION__);
  10456. + lacStatus = icp_ocfDrvDsaSign(krp);
  10457. + if (CPA_STATUS_SUCCESS != lacStatus) {
  10458. + EPRINTK("%s(): icp_ocfDrvDsaSign "
  10459. + "failed (%d).\n", __FUNCTION__, lacStatus);
  10460. + krp->krp_status = ECANCELED;
  10461. + return ECANCELED;
  10462. + }
  10463. +
  10464. + break;
  10465. +
  10466. + case CRK_DSA_VERIFY:
  10467. + DPRINTK("%s() doing DSA_VERIFY \n", __FUNCTION__);
  10468. + lacStatus = icp_ocfDrvDsaVerify(krp);
  10469. + if (CPA_STATUS_SUCCESS != lacStatus) {
  10470. + EPRINTK("%s(): icp_ocfDrvDsaVerify "
  10471. + "failed (%d).\n", __FUNCTION__, lacStatus);
  10472. + krp->krp_status = ECANCELED;
  10473. + return ECANCELED;
  10474. + }
  10475. +
  10476. + break;
  10477. +
  10478. + default:
  10479. + EPRINTK("%s(): Asymettric function not "
  10480. + "supported (%d).\n", __FUNCTION__, krp->krp_op);
  10481. + krp->krp_status = EOPNOTSUPP;
  10482. + return EOPNOTSUPP;
  10483. + }
  10484. +
  10485. + return ICP_OCF_DRV_STATUS_SUCCESS;
  10486. +}
  10487. +
  10488. +/* Name : icp_ocfDrvSwapBytes
  10489. + *
  10490. + * Description : This function is used to swap the byte order of a buffer.
  10491. + * It has been seen that in general we are passed little endian byte order
  10492. + * buffers, but LAC only accepts big endian byte order buffers.
  10493. + */
  10494. +static void inline icp_ocfDrvSwapBytes(u_int8_t * num, u_int32_t buff_len_bytes)
  10495. +{
  10496. +
  10497. + int i;
  10498. + u_int8_t *end_ptr;
  10499. + u_int8_t hold_val;
  10500. +
  10501. + end_ptr = num + (buff_len_bytes - 1);
  10502. + buff_len_bytes = buff_len_bytes >> 1;
  10503. + for (i = 0; i < buff_len_bytes; i++) {
  10504. + hold_val = *num;
  10505. + *num = *end_ptr;
  10506. + num++;
  10507. + *end_ptr = hold_val;
  10508. + end_ptr--;
  10509. + }
  10510. +}
  10511. +
  10512. +/* Name : icp_ocfDrvDHComputeKey
  10513. + *
  10514. + * Description : This function will map Diffie Hellman calls from OCF
  10515. + * to the LAC API. OCF uses this function for Diffie Hellman Phase1 and
  10516. + * Phase2. LAC has a separate Diffie Hellman Phase2 call, however both phases
  10517. + * break down to a modular exponentiation.
  10518. + */
  10519. +static int icp_ocfDrvDHComputeKey(struct cryptkop *krp)
  10520. +{
  10521. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  10522. + void *callbackTag = NULL;
  10523. + CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;
  10524. + CpaFlatBuffer *pLocalOctetStringPV = NULL;
  10525. + uint32_t dh_prime_len_bytes = 0, dh_prime_len_bits = 0;
  10526. +
  10527. + /* Input checks - check prime is a multiple of 8 bits to allow for
  10528. + allocation later */
  10529. + dh_prime_len_bits =
  10530. + (krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_nbits);
  10531. +
  10532. + /* LAC can reject prime lengths based on prime key sizes, we just
  10533. + need to make sure we can allocate space for the base and
  10534. + exponent buffers correctly */
  10535. + if ((dh_prime_len_bits % NUM_BITS_IN_BYTE) != 0) {
  10536. + APRINTK("%s(): Warning Prime number buffer size is not a "
  10537. + "multiple of 8 bits\n", __FUNCTION__);
  10538. + }
  10539. +
  10540. + /* Result storage space should be the same size as the prime as this
  10541. + value can take up the same amount of storage space */
  10542. + if (dh_prime_len_bits !=
  10543. + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits) {
  10544. + DPRINTK("%s(): Return Buffer must be the same size "
  10545. + "as the Prime buffer\n", __FUNCTION__);
  10546. + krp->krp_status = EINVAL;
  10547. + return EINVAL;
  10548. + }
  10549. + /* Switch to size in bytes */
  10550. + BITS_TO_BYTES(dh_prime_len_bytes, dh_prime_len_bits);
  10551. +
  10552. + callbackTag = krp;
  10553. +
  10554. +/*All allocations are set to ICP_M_NOWAIT due to the possibility of getting
  10555. +called in interrupt context*/
  10556. + pPhase1OpData = icp_kmem_cache_zalloc(drvDH_zone, ICP_M_NOWAIT);
  10557. + if (NULL == pPhase1OpData) {
  10558. + APRINTK("%s():Failed to get memory for key gen data\n",
  10559. + __FUNCTION__);
  10560. + krp->krp_status = ENOMEM;
  10561. + return ENOMEM;
  10562. + }
  10563. +
  10564. + pLocalOctetStringPV =
  10565. + icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  10566. + if (NULL == pLocalOctetStringPV) {
  10567. + APRINTK("%s():Failed to get memory for pLocalOctetStringPV\n",
  10568. + __FUNCTION__);
  10569. + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
  10570. + krp->krp_status = ENOMEM;
  10571. + return ENOMEM;
  10572. + }
  10573. +
  10574. + /* Link parameters */
  10575. + pPhase1OpData->primeP.pData =
  10576. + krp->krp_param[ICP_DH_KRP_PARAM_PRIME_INDEX].crp_p;
  10577. +
  10578. + pPhase1OpData->primeP.dataLenInBytes = dh_prime_len_bytes;
  10579. +
  10580. + icp_ocfDrvSwapBytes(pPhase1OpData->primeP.pData, dh_prime_len_bytes);
  10581. +
  10582. + pPhase1OpData->baseG.pData =
  10583. + krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_p;
  10584. +
  10585. + BITS_TO_BYTES(pPhase1OpData->baseG.dataLenInBytes,
  10586. + krp->krp_param[ICP_DH_KRP_PARAM_BASE_INDEX].crp_nbits);
  10587. +
  10588. + icp_ocfDrvSwapBytes(pPhase1OpData->baseG.pData,
  10589. + pPhase1OpData->baseG.dataLenInBytes);
  10590. +
  10591. + pPhase1OpData->privateValueX.pData =
  10592. + krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].crp_p;
  10593. +
  10594. + BITS_TO_BYTES(pPhase1OpData->privateValueX.dataLenInBytes,
  10595. + krp->krp_param[ICP_DH_KRP_PARAM_PRIVATE_VALUE_INDEX].
  10596. + crp_nbits);
  10597. +
  10598. + icp_ocfDrvSwapBytes(pPhase1OpData->privateValueX.pData,
  10599. + pPhase1OpData->privateValueX.dataLenInBytes);
  10600. +
  10601. + /* Output parameters */
  10602. + pLocalOctetStringPV->pData =
  10603. + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_p;
  10604. +
  10605. + BITS_TO_BYTES(pLocalOctetStringPV->dataLenInBytes,
  10606. + krp->krp_param[ICP_DH_KRP_PARAM_RESULT_INDEX].crp_nbits);
  10607. +
  10608. + lacStatus = cpaCyDhKeyGenPhase1(CPA_INSTANCE_HANDLE_SINGLE,
  10609. + icp_ocfDrvDhP1CallBack,
  10610. + callbackTag, pPhase1OpData,
  10611. + pLocalOctetStringPV);
  10612. +
  10613. + if (CPA_STATUS_SUCCESS != lacStatus) {
  10614. + EPRINTK("%s(): DH Phase 1 Key Gen failed (%d).\n",
  10615. + __FUNCTION__, lacStatus);
  10616. + icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);
  10617. + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
  10618. + }
  10619. +
  10620. + return lacStatus;
  10621. +}
  10622. +
  10623. +/* Name : icp_ocfDrvModExp
  10624. + *
  10625. + * Description : This function will map ordinary Modular Exponentiation calls
  10626. + * from OCF to the LAC API.
  10627. + *
  10628. + */
  10629. +static int icp_ocfDrvModExp(struct cryptkop *krp)
  10630. +{
  10631. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  10632. + void *callbackTag = NULL;
  10633. + CpaCyLnModExpOpData *pModExpOpData = NULL;
  10634. + CpaFlatBuffer *pResult = NULL;
  10635. +
  10636. + if ((krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits %
  10637. + NUM_BITS_IN_BYTE) != 0) {
  10638. + DPRINTK("%s(): Warning - modulus buffer size (%d) is not a "
  10639. + "multiple of 8 bits\n", __FUNCTION__,
  10640. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].
  10641. + crp_nbits);
  10642. + }
  10643. +
  10644. + /* Result storage space should be the same size as the prime as this
  10645. + value can take up the same amount of storage space */
  10646. + if (krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_nbits >
  10647. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_nbits) {
  10648. + APRINTK("%s(): Return Buffer size must be the same or"
  10649. + " greater than the Modulus buffer\n", __FUNCTION__);
  10650. + krp->krp_status = EINVAL;
  10651. + return EINVAL;
  10652. + }
  10653. +
  10654. + callbackTag = krp;
  10655. +
  10656. + pModExpOpData = icp_kmem_cache_zalloc(drvLnModExp_zone, ICP_M_NOWAIT);
  10657. + if (NULL == pModExpOpData) {
  10658. + APRINTK("%s():Failed to get memory for key gen data\n",
  10659. + __FUNCTION__);
  10660. + krp->krp_status = ENOMEM;
  10661. + return ENOMEM;
  10662. + }
  10663. +
  10664. + pResult = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  10665. + if (NULL == pResult) {
  10666. + APRINTK("%s():Failed to get memory for ModExp result\n",
  10667. + __FUNCTION__);
  10668. + ICP_CACHE_FREE(drvLnModExp_zone, pModExpOpData);
  10669. + krp->krp_status = ENOMEM;
  10670. + return ENOMEM;
  10671. + }
  10672. +
  10673. + /* Link parameters */
  10674. + pModExpOpData->modulus.pData =
  10675. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].crp_p;
  10676. + BITS_TO_BYTES(pModExpOpData->modulus.dataLenInBytes,
  10677. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_MODULUS_INDEX].
  10678. + crp_nbits);
  10679. +
  10680. + icp_ocfDrvSwapBytes(pModExpOpData->modulus.pData,
  10681. + pModExpOpData->modulus.dataLenInBytes);
  10682. +
  10683. + DPRINTK("%s : base (%d)\n", __FUNCTION__, krp->
  10684. + krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_nbits);
  10685. + pModExpOpData->base.pData =
  10686. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].crp_p;
  10687. + BITS_TO_BYTES(pModExpOpData->base.dataLenInBytes,
  10688. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
  10689. + crp_nbits);
  10690. + icp_ocfDrvSwapBytes(pModExpOpData->base.pData,
  10691. + pModExpOpData->base.dataLenInBytes);
  10692. +
  10693. + pModExpOpData->exponent.pData =
  10694. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].crp_p;
  10695. + BITS_TO_BYTES(pModExpOpData->exponent.dataLenInBytes,
  10696. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_EXPONENT_INDEX].
  10697. + crp_nbits);
  10698. +
  10699. + icp_ocfDrvSwapBytes(pModExpOpData->exponent.pData,
  10700. + pModExpOpData->exponent.dataLenInBytes);
  10701. + /* Output parameters */
  10702. + pResult->pData =
  10703. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].crp_p,
  10704. + BITS_TO_BYTES(pResult->dataLenInBytes,
  10705. + krp->krp_param[ICP_MOD_EXP_KRP_PARAM_RESULT_INDEX].
  10706. + crp_nbits);
  10707. +
  10708. + lacStatus = cpaCyLnModExp(CPA_INSTANCE_HANDLE_SINGLE,
  10709. + icp_ocfDrvModExpCallBack,
  10710. + callbackTag, pModExpOpData, pResult);
  10711. +
  10712. + if (CPA_STATUS_SUCCESS != lacStatus) {
  10713. + EPRINTK("%s(): Mod Exp Operation failed (%d).\n",
  10714. + __FUNCTION__, lacStatus);
  10715. + krp->krp_status = ECANCELED;
  10716. + icp_ocfDrvFreeFlatBuffer(pResult);
  10717. + ICP_CACHE_FREE(drvLnModExp_zone, pModExpOpData);
  10718. + }
  10719. +
  10720. + return lacStatus;
  10721. +}
  10722. +
  10723. +/* Name : icp_ocfDrvModExpCRT
  10724. + *
  10725. + * Description : This function will map ordinary Modular Exponentiation Chinese
  10726. + * Remainder Theorem implementaion calls from OCF to the LAC API.
  10727. + *
  10728. + * Note : Mod Exp CRT for this driver is accelerated through LAC RSA type 2
  10729. + * decrypt operation. Therefore P and Q input values must always be prime
  10730. + * numbers. Although basic primality checks are done in LAC, it is up to the
  10731. + * user to do any correct prime number checking before passing the inputs.
  10732. + */
  10733. +static int icp_ocfDrvModExpCRT(struct cryptkop *krp)
  10734. +{
  10735. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  10736. + CpaCyRsaDecryptOpData *rsaDecryptOpData = NULL;
  10737. + void *callbackTag = NULL;
  10738. + CpaFlatBuffer *pOutputData = NULL;
  10739. +
  10740. + /*Parameter input checks are all done by LAC, no need to repeat
  10741. + them here. */
  10742. + callbackTag = krp;
  10743. +
  10744. + rsaDecryptOpData =
  10745. + icp_kmem_cache_zalloc(drvRSADecrypt_zone, ICP_M_NOWAIT);
  10746. + if (NULL == rsaDecryptOpData) {
  10747. + APRINTK("%s():Failed to get memory"
  10748. + " for MOD EXP CRT Op data struct\n", __FUNCTION__);
  10749. + krp->krp_status = ENOMEM;
  10750. + return ENOMEM;
  10751. + }
  10752. +
  10753. + rsaDecryptOpData->pRecipientPrivateKey
  10754. + = icp_kmem_cache_zalloc(drvRSAPrivateKey_zone, ICP_M_NOWAIT);
  10755. + if (NULL == rsaDecryptOpData->pRecipientPrivateKey) {
  10756. + APRINTK("%s():Failed to get memory for MOD EXP CRT"
  10757. + " private key values struct\n", __FUNCTION__);
  10758. + ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);
  10759. + krp->krp_status = ENOMEM;
  10760. + return ENOMEM;
  10761. + }
  10762. +
  10763. + rsaDecryptOpData->pRecipientPrivateKey->
  10764. + version = CPA_CY_RSA_VERSION_TWO_PRIME;
  10765. + rsaDecryptOpData->pRecipientPrivateKey->
  10766. + privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
  10767. +
  10768. + pOutputData = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  10769. + if (NULL == pOutputData) {
  10770. + APRINTK("%s():Failed to get memory"
  10771. + " for MOD EXP CRT output data\n", __FUNCTION__);
  10772. + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
  10773. + rsaDecryptOpData->pRecipientPrivateKey);
  10774. + ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);
  10775. + krp->krp_status = ENOMEM;
  10776. + return ENOMEM;
  10777. + }
  10778. +
  10779. + rsaDecryptOpData->pRecipientPrivateKey->
  10780. + version = CPA_CY_RSA_VERSION_TWO_PRIME;
  10781. + rsaDecryptOpData->pRecipientPrivateKey->
  10782. + privateKeyRepType = CPA_CY_RSA_PRIVATE_KEY_REP_TYPE_2;
  10783. +
  10784. + /* Link parameters */
  10785. + rsaDecryptOpData->inputData.pData =
  10786. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].crp_p;
  10787. + BITS_TO_BYTES(rsaDecryptOpData->inputData.dataLenInBytes,
  10788. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_I_INDEX].
  10789. + crp_nbits);
  10790. +
  10791. + icp_ocfDrvSwapBytes(rsaDecryptOpData->inputData.pData,
  10792. + rsaDecryptOpData->inputData.dataLenInBytes);
  10793. +
  10794. + rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime1P.pData =
  10795. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].crp_p;
  10796. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
  10797. + prime1P.dataLenInBytes,
  10798. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_P_INDEX].
  10799. + crp_nbits);
  10800. +
  10801. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  10802. + privateKeyRep2.prime1P.pData,
  10803. + rsaDecryptOpData->pRecipientPrivateKey->
  10804. + privateKeyRep2.prime1P.dataLenInBytes);
  10805. +
  10806. + rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.prime2Q.pData =
  10807. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].crp_p;
  10808. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
  10809. + prime2Q.dataLenInBytes,
  10810. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_PRIME_Q_INDEX].
  10811. + crp_nbits);
  10812. +
  10813. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  10814. + privateKeyRep2.prime2Q.pData,
  10815. + rsaDecryptOpData->pRecipientPrivateKey->
  10816. + privateKeyRep2.prime2Q.dataLenInBytes);
  10817. +
  10818. + rsaDecryptOpData->pRecipientPrivateKey->
  10819. + privateKeyRep2.exponent1Dp.pData =
  10820. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].crp_p;
  10821. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->privateKeyRep2.
  10822. + exponent1Dp.dataLenInBytes,
  10823. + krp->
  10824. + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DP_INDEX].
  10825. + crp_nbits);
  10826. +
  10827. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  10828. + privateKeyRep2.exponent1Dp.pData,
  10829. + rsaDecryptOpData->pRecipientPrivateKey->
  10830. + privateKeyRep2.exponent1Dp.dataLenInBytes);
  10831. +
  10832. + rsaDecryptOpData->pRecipientPrivateKey->
  10833. + privateKeyRep2.exponent2Dq.pData =
  10834. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].crp_p;
  10835. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->
  10836. + privateKeyRep2.exponent2Dq.dataLenInBytes,
  10837. + krp->
  10838. + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_EXPONENT_DQ_INDEX].
  10839. + crp_nbits);
  10840. +
  10841. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  10842. + privateKeyRep2.exponent2Dq.pData,
  10843. + rsaDecryptOpData->pRecipientPrivateKey->
  10844. + privateKeyRep2.exponent2Dq.dataLenInBytes);
  10845. +
  10846. + rsaDecryptOpData->pRecipientPrivateKey->
  10847. + privateKeyRep2.coefficientQInv.pData =
  10848. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].crp_p;
  10849. + BITS_TO_BYTES(rsaDecryptOpData->pRecipientPrivateKey->
  10850. + privateKeyRep2.coefficientQInv.dataLenInBytes,
  10851. + krp->
  10852. + krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_COEFF_QINV_INDEX].
  10853. + crp_nbits);
  10854. +
  10855. + icp_ocfDrvSwapBytes(rsaDecryptOpData->pRecipientPrivateKey->
  10856. + privateKeyRep2.coefficientQInv.pData,
  10857. + rsaDecryptOpData->pRecipientPrivateKey->
  10858. + privateKeyRep2.coefficientQInv.dataLenInBytes);
  10859. +
  10860. + /* Output Parameter */
  10861. + pOutputData->pData =
  10862. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].crp_p;
  10863. + BITS_TO_BYTES(pOutputData->dataLenInBytes,
  10864. + krp->krp_param[ICP_MOD_EXP_CRT_KRP_PARAM_RESULT_INDEX].
  10865. + crp_nbits);
  10866. +
  10867. + lacStatus = cpaCyRsaDecrypt(CPA_INSTANCE_HANDLE_SINGLE,
  10868. + icp_ocfDrvModExpCRTCallBack,
  10869. + callbackTag, rsaDecryptOpData, pOutputData);
  10870. +
  10871. + if (CPA_STATUS_SUCCESS != lacStatus) {
  10872. + EPRINTK("%s(): Mod Exp CRT Operation failed (%d).\n",
  10873. + __FUNCTION__, lacStatus);
  10874. + krp->krp_status = ECANCELED;
  10875. + icp_ocfDrvFreeFlatBuffer(pOutputData);
  10876. + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
  10877. + rsaDecryptOpData->pRecipientPrivateKey);
  10878. + ICP_CACHE_FREE(drvRSADecrypt_zone, rsaDecryptOpData);
  10879. + }
  10880. +
  10881. + return lacStatus;
  10882. +}
  10883. +
  10884. +/* Name : icp_ocfDrvCheckALessThanB
  10885. + *
  10886. + * Description : This function will check whether the first argument is less
  10887. + * than the second. It is used to check whether the DSA RS sign Random K
  10888. + * value is less than the Prime Q value (as defined in the specification)
  10889. + *
  10890. + */
  10891. +static int
  10892. +icp_ocfDrvCheckALessThanB(CpaFlatBuffer * pK, CpaFlatBuffer * pQ, int *doCheck)
  10893. +{
  10894. +
  10895. + uint8_t *MSB_K = pK->pData;
  10896. + uint8_t *MSB_Q = pQ->pData;
  10897. + uint32_t buffer_lengths_in_bytes = pQ->dataLenInBytes;
  10898. +
  10899. + if (DONT_RUN_LESS_THAN_CHECK == *doCheck) {
  10900. + return FAIL_A_IS_GREATER_THAN_B;
  10901. + }
  10902. +
  10903. +/*Check MSBs
  10904. +if A == B, check next MSB
  10905. +if A > B, return A_IS_GREATER_THAN_B
  10906. +if A < B, return A_IS_LESS_THAN_B (success)
  10907. +*/
  10908. + while (*MSB_K == *MSB_Q) {
  10909. + MSB_K++;
  10910. + MSB_Q++;
  10911. +
  10912. + buffer_lengths_in_bytes--;
  10913. + if (0 == buffer_lengths_in_bytes) {
  10914. + DPRINTK("%s() Buffers have equal value!!\n",
  10915. + __FUNCTION__);
  10916. + return FAIL_A_IS_EQUAL_TO_B;
  10917. + }
  10918. +
  10919. + }
  10920. +
  10921. + if (*MSB_K < *MSB_Q) {
  10922. + return SUCCESS_A_IS_LESS_THAN_B;
  10923. + } else {
  10924. + return FAIL_A_IS_GREATER_THAN_B;
  10925. + }
  10926. +
  10927. +}
  10928. +
  10929. +/* Name : icp_ocfDrvDsaSign
  10930. + *
  10931. + * Description : This function will map DSA RS Sign from OCF to the LAC API.
  10932. + *
  10933. + * NOTE: From looking at OCF patch to OpenSSL and even the number of input
  10934. + * parameters, OCF expects us to generate the random seed value. This value
  10935. + * is generated and passed to LAC, however the number is discared in the
  10936. + * callback and not returned to the user.
  10937. + */
  10938. +static int icp_ocfDrvDsaSign(struct cryptkop *krp)
  10939. +{
  10940. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  10941. + CpaCyDsaRSSignOpData *dsaRsSignOpData = NULL;
  10942. + void *callbackTag = NULL;
  10943. + CpaCyRandGenOpData randGenOpData;
  10944. + int primeQSizeInBytes = 0;
  10945. + int doCheck = 0;
  10946. + CpaFlatBuffer randData;
  10947. + CpaBoolean protocolStatus = CPA_FALSE;
  10948. + CpaFlatBuffer *pR = NULL;
  10949. + CpaFlatBuffer *pS = NULL;
  10950. +
  10951. + callbackTag = krp;
  10952. +
  10953. + BITS_TO_BYTES(primeQSizeInBytes,
  10954. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].
  10955. + crp_nbits);
  10956. +
  10957. + if (DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES != primeQSizeInBytes) {
  10958. + APRINTK("%s(): DSA PRIME Q size not equal to the "
  10959. + "FIPS defined 20bytes, = %d\n",
  10960. + __FUNCTION__, primeQSizeInBytes);
  10961. + krp->krp_status = EDOM;
  10962. + return EDOM;
  10963. + }
  10964. +
  10965. + dsaRsSignOpData =
  10966. + icp_kmem_cache_zalloc(drvDSARSSign_zone, ICP_M_NOWAIT);
  10967. + if (NULL == dsaRsSignOpData) {
  10968. + APRINTK("%s():Failed to get memory"
  10969. + " for DSA RS Sign Op data struct\n", __FUNCTION__);
  10970. + krp->krp_status = ENOMEM;
  10971. + return ENOMEM;
  10972. + }
  10973. +
  10974. + dsaRsSignOpData->K.pData =
  10975. + icp_kmem_cache_alloc(drvDSARSSignKValue_zone, ICP_M_NOWAIT);
  10976. +
  10977. + if (NULL == dsaRsSignOpData->K.pData) {
  10978. + APRINTK("%s():Failed to get memory"
  10979. + " for DSA RS Sign Op Random value\n", __FUNCTION__);
  10980. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  10981. + krp->krp_status = ENOMEM;
  10982. + return ENOMEM;
  10983. + }
  10984. +
  10985. + pR = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  10986. + if (NULL == pR) {
  10987. + APRINTK("%s():Failed to get memory"
  10988. + " for DSA signature R\n", __FUNCTION__);
  10989. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  10990. + dsaRsSignOpData->K.pData);
  10991. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  10992. + krp->krp_status = ENOMEM;
  10993. + return ENOMEM;
  10994. + }
  10995. +
  10996. + pS = icp_kmem_cache_zalloc(drvFlatBuffer_zone, ICP_M_NOWAIT);
  10997. + if (NULL == pS) {
  10998. + APRINTK("%s():Failed to get memory"
  10999. + " for DSA signature S\n", __FUNCTION__);
  11000. + icp_ocfDrvFreeFlatBuffer(pR);
  11001. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  11002. + dsaRsSignOpData->K.pData);
  11003. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  11004. + krp->krp_status = ENOMEM;
  11005. + return ENOMEM;
  11006. + }
  11007. +
  11008. + /*link prime number parameter for ease of processing */
  11009. + dsaRsSignOpData->P.pData =
  11010. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].crp_p;
  11011. + BITS_TO_BYTES(dsaRsSignOpData->P.dataLenInBytes,
  11012. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_P_INDEX].
  11013. + crp_nbits);
  11014. +
  11015. + icp_ocfDrvSwapBytes(dsaRsSignOpData->P.pData,
  11016. + dsaRsSignOpData->P.dataLenInBytes);
  11017. +
  11018. + dsaRsSignOpData->Q.pData =
  11019. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].crp_p;
  11020. + BITS_TO_BYTES(dsaRsSignOpData->Q.dataLenInBytes,
  11021. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_PRIME_Q_INDEX].
  11022. + crp_nbits);
  11023. +
  11024. + icp_ocfDrvSwapBytes(dsaRsSignOpData->Q.pData,
  11025. + dsaRsSignOpData->Q.dataLenInBytes);
  11026. +
  11027. + /*generate random number with equal buffer size to Prime value Q,
  11028. + but value less than Q */
  11029. + dsaRsSignOpData->K.dataLenInBytes = dsaRsSignOpData->Q.dataLenInBytes;
  11030. +
  11031. + randGenOpData.generateBits = CPA_TRUE;
  11032. + randGenOpData.lenInBytes = dsaRsSignOpData->K.dataLenInBytes;
  11033. +
  11034. + icp_ocfDrvPtrAndLenToFlatBuffer(dsaRsSignOpData->K.pData,
  11035. + dsaRsSignOpData->K.dataLenInBytes,
  11036. + &randData);
  11037. +
  11038. + doCheck = 0;
  11039. + while (icp_ocfDrvCheckALessThanB(&(dsaRsSignOpData->K),
  11040. + &(dsaRsSignOpData->Q), &doCheck)) {
  11041. +
  11042. + if (CPA_STATUS_SUCCESS
  11043. + != cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
  11044. + NULL, NULL, &randGenOpData, &randData)) {
  11045. + APRINTK("%s(): ERROR - Failed to generate DSA RS Sign K"
  11046. + "value\n", __FUNCTION__);
  11047. + icp_ocfDrvFreeFlatBuffer(pS);
  11048. + icp_ocfDrvFreeFlatBuffer(pR);
  11049. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  11050. + dsaRsSignOpData->K.pData);
  11051. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  11052. + krp->krp_status = EAGAIN;
  11053. + return EAGAIN;
  11054. + }
  11055. +
  11056. + doCheck++;
  11057. + if (DSA_SIGN_RAND_GEN_VAL_CHECK_MAX_ITERATIONS == doCheck) {
  11058. + APRINTK("%s(): ERROR - Failed to find DSA RS Sign K "
  11059. + "value less than Q value\n", __FUNCTION__);
  11060. + icp_ocfDrvFreeFlatBuffer(pS);
  11061. + icp_ocfDrvFreeFlatBuffer(pR);
  11062. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  11063. + dsaRsSignOpData->K.pData);
  11064. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  11065. + krp->krp_status = EAGAIN;
  11066. + return EAGAIN;
  11067. + }
  11068. +
  11069. + }
  11070. + /*Rand Data - no need to swap bytes for pK */
  11071. +
  11072. + /* Link parameters */
  11073. + dsaRsSignOpData->G.pData =
  11074. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_p;
  11075. + BITS_TO_BYTES(dsaRsSignOpData->G.dataLenInBytes,
  11076. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_G_INDEX].crp_nbits);
  11077. +
  11078. + icp_ocfDrvSwapBytes(dsaRsSignOpData->G.pData,
  11079. + dsaRsSignOpData->G.dataLenInBytes);
  11080. +
  11081. + dsaRsSignOpData->X.pData =
  11082. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_p;
  11083. + BITS_TO_BYTES(dsaRsSignOpData->X.dataLenInBytes,
  11084. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_X_INDEX].crp_nbits);
  11085. + icp_ocfDrvSwapBytes(dsaRsSignOpData->X.pData,
  11086. + dsaRsSignOpData->X.dataLenInBytes);
  11087. +
  11088. + /*OpenSSL dgst parameter is left in big endian byte order,
  11089. + therefore no byte swap is required */
  11090. + dsaRsSignOpData->M.pData =
  11091. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].crp_p;
  11092. + BITS_TO_BYTES(dsaRsSignOpData->M.dataLenInBytes,
  11093. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_DGST_INDEX].
  11094. + crp_nbits);
  11095. +
  11096. + /* Output Parameters */
  11097. + pS->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].crp_p;
  11098. + BITS_TO_BYTES(pS->dataLenInBytes,
  11099. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_S_RESULT_INDEX].
  11100. + crp_nbits);
  11101. +
  11102. + pR->pData = krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].crp_p;
  11103. + BITS_TO_BYTES(pR->dataLenInBytes,
  11104. + krp->krp_param[ICP_DSA_SIGN_KRP_PARAM_R_RESULT_INDEX].
  11105. + crp_nbits);
  11106. +
  11107. + lacStatus = cpaCyDsaSignRS(CPA_INSTANCE_HANDLE_SINGLE,
  11108. + icp_ocfDrvDsaRSSignCallBack,
  11109. + callbackTag, dsaRsSignOpData,
  11110. + &protocolStatus, pR, pS);
  11111. +
  11112. + if (CPA_STATUS_SUCCESS != lacStatus) {
  11113. + EPRINTK("%s(): DSA RS Sign Operation failed (%d).\n",
  11114. + __FUNCTION__, lacStatus);
  11115. + krp->krp_status = ECANCELED;
  11116. + icp_ocfDrvFreeFlatBuffer(pS);
  11117. + icp_ocfDrvFreeFlatBuffer(pR);
  11118. + ICP_CACHE_FREE(drvDSARSSignKValue_zone,
  11119. + dsaRsSignOpData->K.pData);
  11120. + ICP_CACHE_FREE(drvDSARSSign_zone, dsaRsSignOpData);
  11121. + }
  11122. +
  11123. + return lacStatus;
  11124. +}
  11125. +
  11126. +/* Name : icp_ocfDrvDsaVerify
  11127. + *
  11128. + * Description : This function will map DSA RS Verify from OCF to the LAC API.
  11129. + *
  11130. + */
  11131. +static int icp_ocfDrvDsaVerify(struct cryptkop *krp)
  11132. +{
  11133. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  11134. + CpaCyDsaVerifyOpData *dsaVerifyOpData = NULL;
  11135. + void *callbackTag = NULL;
  11136. + CpaBoolean verifyStatus = CPA_FALSE;
  11137. +
  11138. + callbackTag = krp;
  11139. +
  11140. + dsaVerifyOpData =
  11141. + icp_kmem_cache_zalloc(drvDSAVerify_zone, ICP_M_NOWAIT);
  11142. + if (NULL == dsaVerifyOpData) {
  11143. + APRINTK("%s():Failed to get memory"
  11144. + " for DSA Verify Op data struct\n", __FUNCTION__);
  11145. + krp->krp_status = ENOMEM;
  11146. + return ENOMEM;
  11147. + }
  11148. +
  11149. + /* Link parameters */
  11150. + dsaVerifyOpData->P.pData =
  11151. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].crp_p;
  11152. + BITS_TO_BYTES(dsaVerifyOpData->P.dataLenInBytes,
  11153. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_P_INDEX].
  11154. + crp_nbits);
  11155. + icp_ocfDrvSwapBytes(dsaVerifyOpData->P.pData,
  11156. + dsaVerifyOpData->P.dataLenInBytes);
  11157. +
  11158. + dsaVerifyOpData->Q.pData =
  11159. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].crp_p;
  11160. + BITS_TO_BYTES(dsaVerifyOpData->Q.dataLenInBytes,
  11161. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PRIME_Q_INDEX].
  11162. + crp_nbits);
  11163. + icp_ocfDrvSwapBytes(dsaVerifyOpData->Q.pData,
  11164. + dsaVerifyOpData->Q.dataLenInBytes);
  11165. +
  11166. + dsaVerifyOpData->G.pData =
  11167. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].crp_p;
  11168. + BITS_TO_BYTES(dsaVerifyOpData->G.dataLenInBytes,
  11169. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_G_INDEX].
  11170. + crp_nbits);
  11171. + icp_ocfDrvSwapBytes(dsaVerifyOpData->G.pData,
  11172. + dsaVerifyOpData->G.dataLenInBytes);
  11173. +
  11174. + dsaVerifyOpData->Y.pData =
  11175. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].crp_p;
  11176. + BITS_TO_BYTES(dsaVerifyOpData->Y.dataLenInBytes,
  11177. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_PUBKEY_INDEX].
  11178. + crp_nbits);
  11179. + icp_ocfDrvSwapBytes(dsaVerifyOpData->Y.pData,
  11180. + dsaVerifyOpData->Y.dataLenInBytes);
  11181. +
  11182. + /*OpenSSL dgst parameter is left in big endian byte order,
  11183. + therefore no byte swap is required */
  11184. + dsaVerifyOpData->M.pData =
  11185. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].crp_p;
  11186. + BITS_TO_BYTES(dsaVerifyOpData->M.dataLenInBytes,
  11187. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_DGST_INDEX].
  11188. + crp_nbits);
  11189. +
  11190. + dsaVerifyOpData->R.pData =
  11191. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].crp_p;
  11192. + BITS_TO_BYTES(dsaVerifyOpData->R.dataLenInBytes,
  11193. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_R_INDEX].
  11194. + crp_nbits);
  11195. + icp_ocfDrvSwapBytes(dsaVerifyOpData->R.pData,
  11196. + dsaVerifyOpData->R.dataLenInBytes);
  11197. +
  11198. + dsaVerifyOpData->S.pData =
  11199. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].crp_p;
  11200. + BITS_TO_BYTES(dsaVerifyOpData->S.dataLenInBytes,
  11201. + krp->krp_param[ICP_DSA_VERIFY_KRP_PARAM_SIG_S_INDEX].
  11202. + crp_nbits);
  11203. + icp_ocfDrvSwapBytes(dsaVerifyOpData->S.pData,
  11204. + dsaVerifyOpData->S.dataLenInBytes);
  11205. +
  11206. + lacStatus = cpaCyDsaVerify(CPA_INSTANCE_HANDLE_SINGLE,
  11207. + icp_ocfDrvDsaVerifyCallBack,
  11208. + callbackTag, dsaVerifyOpData, &verifyStatus);
  11209. +
  11210. + if (CPA_STATUS_SUCCESS != lacStatus) {
  11211. + EPRINTK("%s(): DSA Verify Operation failed (%d).\n",
  11212. + __FUNCTION__, lacStatus);
  11213. + ICP_CACHE_FREE(drvDSAVerify_zone, dsaVerifyOpData);
  11214. + krp->krp_status = ECANCELED;
  11215. + }
  11216. +
  11217. + return lacStatus;
  11218. +}
  11219. +
  11220. +/* Name : icp_ocfDrvDhP1Callback
  11221. + *
  11222. + * Description : When this function returns it signifies that the LAC
  11223. + * component has completed the DH operation.
  11224. + */
  11225. +static void
  11226. +icp_ocfDrvDhP1CallBack(void *callbackTag,
  11227. + CpaStatus status,
  11228. + void *pOpData, CpaFlatBuffer * pLocalOctetStringPV)
  11229. +{
  11230. + struct cryptkop *krp = NULL;
  11231. + CpaCyDhPhase1KeyGenOpData *pPhase1OpData = NULL;
  11232. +
  11233. + if (NULL == callbackTag) {
  11234. + DPRINTK("%s(): Invalid input parameters - "
  11235. + "callbackTag data is NULL\n", __FUNCTION__);
  11236. + return;
  11237. + }
  11238. + krp = (struct cryptkop *)callbackTag;
  11239. +
  11240. + if (NULL == pOpData) {
  11241. + DPRINTK("%s(): Invalid input parameters - "
  11242. + "Operation Data is NULL\n", __FUNCTION__);
  11243. + krp->krp_status = ECANCELED;
  11244. + crypto_kdone(krp);
  11245. + return;
  11246. + }
  11247. + pPhase1OpData = (CpaCyDhPhase1KeyGenOpData *) pOpData;
  11248. +
  11249. + if (NULL == pLocalOctetStringPV) {
  11250. + DPRINTK("%s(): Invalid input parameters - "
  11251. + "pLocalOctetStringPV Data is NULL\n", __FUNCTION__);
  11252. + memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));
  11253. + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
  11254. + krp->krp_status = ECANCELED;
  11255. + crypto_kdone(krp);
  11256. + return;
  11257. + }
  11258. +
  11259. + if (CPA_STATUS_SUCCESS == status) {
  11260. + krp->krp_status = CRYPTO_OP_SUCCESS;
  11261. + } else {
  11262. + APRINTK("%s(): Diffie Hellman Phase1 Key Gen failed - "
  11263. + "Operation Status = %d\n", __FUNCTION__, status);
  11264. + krp->krp_status = ECANCELED;
  11265. + }
  11266. +
  11267. + icp_ocfDrvSwapBytes(pLocalOctetStringPV->pData,
  11268. + pLocalOctetStringPV->dataLenInBytes);
  11269. +
  11270. + icp_ocfDrvFreeFlatBuffer(pLocalOctetStringPV);
  11271. + memset(pPhase1OpData, 0, sizeof(CpaCyDhPhase1KeyGenOpData));
  11272. + ICP_CACHE_FREE(drvDH_zone, pPhase1OpData);
  11273. +
  11274. + crypto_kdone(krp);
  11275. +
  11276. + return;
  11277. +}
  11278. +
  11279. +/* Name : icp_ocfDrvModExpCallBack
  11280. + *
  11281. + * Description : When this function returns it signifies that the LAC
  11282. + * component has completed the Mod Exp operation.
  11283. + */
  11284. +static void
  11285. +icp_ocfDrvModExpCallBack(void *callbackTag,
  11286. + CpaStatus status,
  11287. + void *pOpdata, CpaFlatBuffer * pResult)
  11288. +{
  11289. + struct cryptkop *krp = NULL;
  11290. + CpaCyLnModExpOpData *pLnModExpOpData = NULL;
  11291. +
  11292. + if (NULL == callbackTag) {
  11293. + DPRINTK("%s(): Invalid input parameters - "
  11294. + "callbackTag data is NULL\n", __FUNCTION__);
  11295. + return;
  11296. + }
  11297. + krp = (struct cryptkop *)callbackTag;
  11298. +
  11299. + if (NULL == pOpdata) {
  11300. + DPRINTK("%s(): Invalid Mod Exp input parameters - "
  11301. + "Operation Data is NULL\n", __FUNCTION__);
  11302. + krp->krp_status = ECANCELED;
  11303. + crypto_kdone(krp);
  11304. + return;
  11305. + }
  11306. + pLnModExpOpData = (CpaCyLnModExpOpData *) pOpdata;
  11307. +
  11308. + if (NULL == pResult) {
  11309. + DPRINTK("%s(): Invalid input parameters - "
  11310. + "pResult data is NULL\n", __FUNCTION__);
  11311. + krp->krp_status = ECANCELED;
  11312. + memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));
  11313. + ICP_CACHE_FREE(drvLnModExp_zone, pLnModExpOpData);
  11314. + crypto_kdone(krp);
  11315. + return;
  11316. + }
  11317. +
  11318. + if (CPA_STATUS_SUCCESS == status) {
  11319. + krp->krp_status = CRYPTO_OP_SUCCESS;
  11320. + } else {
  11321. + APRINTK("%s(): LAC Mod Exp Operation failed - "
  11322. + "Operation Status = %d\n", __FUNCTION__, status);
  11323. + krp->krp_status = ECANCELED;
  11324. + }
  11325. +
  11326. + icp_ocfDrvSwapBytes(pResult->pData, pResult->dataLenInBytes);
  11327. +
  11328. + /*switch base size value back to original */
  11329. + if (pLnModExpOpData->base.pData ==
  11330. + (uint8_t *) & (krp->
  11331. + krp_param[ICP_MOD_EXP_KRP_PARAM_BASE_INDEX].
  11332. + crp_nbits)) {
  11333. + *((uint32_t *) pLnModExpOpData->base.pData) =
  11334. + ntohl(*((uint32_t *) pLnModExpOpData->base.pData));
  11335. + }
  11336. + icp_ocfDrvFreeFlatBuffer(pResult);
  11337. + memset(pLnModExpOpData, 0, sizeof(CpaCyLnModExpOpData));
  11338. + ICP_CACHE_FREE(drvLnModExp_zone, pLnModExpOpData);
  11339. +
  11340. + crypto_kdone(krp);
  11341. +
  11342. + return;
  11343. +
  11344. +}
  11345. +
  11346. +/* Name : icp_ocfDrvModExpCRTCallBack
  11347. + *
  11348. + * Description : When this function returns it signifies that the LAC
  11349. + * component has completed the Mod Exp CRT operation.
  11350. + */
  11351. +static void
  11352. +icp_ocfDrvModExpCRTCallBack(void *callbackTag,
  11353. + CpaStatus status,
  11354. + void *pOpData, CpaFlatBuffer * pOutputData)
  11355. +{
  11356. + struct cryptkop *krp = NULL;
  11357. + CpaCyRsaDecryptOpData *pDecryptData = NULL;
  11358. +
  11359. + if (NULL == callbackTag) {
  11360. + DPRINTK("%s(): Invalid input parameters - "
  11361. + "callbackTag data is NULL\n", __FUNCTION__);
  11362. + return;
  11363. + }
  11364. +
  11365. + krp = (struct cryptkop *)callbackTag;
  11366. +
  11367. + if (NULL == pOpData) {
  11368. + DPRINTK("%s(): Invalid input parameters - "
  11369. + "Operation Data is NULL\n", __FUNCTION__);
  11370. + krp->krp_status = ECANCELED;
  11371. + crypto_kdone(krp);
  11372. + return;
  11373. + }
  11374. + pDecryptData = (CpaCyRsaDecryptOpData *) pOpData;
  11375. +
  11376. + if (NULL == pOutputData) {
  11377. + DPRINTK("%s(): Invalid input parameter - "
  11378. + "pOutputData is NULL\n", __FUNCTION__);
  11379. + memset(pDecryptData->pRecipientPrivateKey, 0,
  11380. + sizeof(CpaCyRsaPrivateKey));
  11381. + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
  11382. + pDecryptData->pRecipientPrivateKey);
  11383. + memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));
  11384. + ICP_CACHE_FREE(drvRSADecrypt_zone, pDecryptData);
  11385. + krp->krp_status = ECANCELED;
  11386. + crypto_kdone(krp);
  11387. + return;
  11388. + }
  11389. +
  11390. + if (CPA_STATUS_SUCCESS == status) {
  11391. + krp->krp_status = CRYPTO_OP_SUCCESS;
  11392. + } else {
  11393. + APRINTK("%s(): LAC Mod Exp CRT operation failed - "
  11394. + "Operation Status = %d\n", __FUNCTION__, status);
  11395. + krp->krp_status = ECANCELED;
  11396. + }
  11397. +
  11398. + icp_ocfDrvSwapBytes(pOutputData->pData, pOutputData->dataLenInBytes);
  11399. +
  11400. + icp_ocfDrvFreeFlatBuffer(pOutputData);
  11401. + memset(pDecryptData->pRecipientPrivateKey, 0,
  11402. + sizeof(CpaCyRsaPrivateKey));
  11403. + ICP_CACHE_FREE(drvRSAPrivateKey_zone,
  11404. + pDecryptData->pRecipientPrivateKey);
  11405. + memset(pDecryptData, 0, sizeof(CpaCyRsaDecryptOpData));
  11406. + ICP_CACHE_FREE(drvRSADecrypt_zone, pDecryptData);
  11407. +
  11408. + crypto_kdone(krp);
  11409. +
  11410. + return;
  11411. +}
  11412. +
  11413. +/* Name : icp_ocfDrvDsaRSSignCallBack
  11414. + *
  11415. + * Description : When this function returns it signifies that the LAC
  11416. + * component has completed the DSA RS sign operation.
  11417. + */
  11418. +static void
  11419. +icp_ocfDrvDsaRSSignCallBack(void *callbackTag,
  11420. + CpaStatus status,
  11421. + void *pOpData,
  11422. + CpaBoolean protocolStatus,
  11423. + CpaFlatBuffer * pR, CpaFlatBuffer * pS)
  11424. +{
  11425. + struct cryptkop *krp = NULL;
  11426. + CpaCyDsaRSSignOpData *pSignData = NULL;
  11427. +
  11428. + if (NULL == callbackTag) {
  11429. + DPRINTK("%s(): Invalid input parameters - "
  11430. + "callbackTag data is NULL\n", __FUNCTION__);
  11431. + return;
  11432. + }
  11433. +
  11434. + krp = (struct cryptkop *)callbackTag;
  11435. +
  11436. + if (NULL == pOpData) {
  11437. + DPRINTK("%s(): Invalid input parameters - "
  11438. + "Operation Data is NULL\n", __FUNCTION__);
  11439. + krp->krp_status = ECANCELED;
  11440. + crypto_kdone(krp);
  11441. + return;
  11442. + }
  11443. + pSignData = (CpaCyDsaRSSignOpData *) pOpData;
  11444. +
  11445. + if (NULL == pR) {
  11446. + DPRINTK("%s(): Invalid input parameter - "
  11447. + "pR sign is NULL\n", __FUNCTION__);
  11448. + icp_ocfDrvFreeFlatBuffer(pS);
  11449. + ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);
  11450. + krp->krp_status = ECANCELED;
  11451. + crypto_kdone(krp);
  11452. + return;
  11453. + }
  11454. +
  11455. + if (NULL == pS) {
  11456. + DPRINTK("%s(): Invalid input parameter - "
  11457. + "pS sign is NULL\n", __FUNCTION__);
  11458. + icp_ocfDrvFreeFlatBuffer(pR);
  11459. + ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);
  11460. + krp->krp_status = ECANCELED;
  11461. + crypto_kdone(krp);
  11462. + return;
  11463. + }
  11464. +
  11465. + if (CPA_STATUS_SUCCESS != status) {
  11466. + APRINTK("%s(): LAC DSA RS Sign operation failed - "
  11467. + "Operation Status = %d\n", __FUNCTION__, status);
  11468. + krp->krp_status = ECANCELED;
  11469. + } else {
  11470. + krp->krp_status = CRYPTO_OP_SUCCESS;
  11471. +
  11472. + if (CPA_TRUE != protocolStatus) {
  11473. + DPRINTK("%s(): LAC DSA RS Sign operation failed due "
  11474. + "to protocol error\n", __FUNCTION__);
  11475. + krp->krp_status = EIO;
  11476. + }
  11477. + }
  11478. +
  11479. + /* Swap bytes only when the callback status is successful and
  11480. + protocolStatus is set to true */
  11481. + if (CPA_STATUS_SUCCESS == status && CPA_TRUE == protocolStatus) {
  11482. + icp_ocfDrvSwapBytes(pR->pData, pR->dataLenInBytes);
  11483. + icp_ocfDrvSwapBytes(pS->pData, pS->dataLenInBytes);
  11484. + }
  11485. +
  11486. + icp_ocfDrvFreeFlatBuffer(pR);
  11487. + icp_ocfDrvFreeFlatBuffer(pS);
  11488. + memset(pSignData->K.pData, 0, pSignData->K.dataLenInBytes);
  11489. + ICP_CACHE_FREE(drvDSARSSignKValue_zone, pSignData->K.pData);
  11490. + memset(pSignData, 0, sizeof(CpaCyDsaRSSignOpData));
  11491. + ICP_CACHE_FREE(drvDSARSSign_zone, pSignData);
  11492. + crypto_kdone(krp);
  11493. +
  11494. + return;
  11495. +}
  11496. +
  11497. +/* Name : icp_ocfDrvDsaVerifyCallback
  11498. + *
  11499. + * Description : When this function returns it signifies that the LAC
  11500. + * component has completed the DSA Verify operation.
  11501. + */
  11502. +static void
  11503. +icp_ocfDrvDsaVerifyCallBack(void *callbackTag,
  11504. + CpaStatus status,
  11505. + void *pOpData, CpaBoolean verifyStatus)
  11506. +{
  11507. +
  11508. + struct cryptkop *krp = NULL;
  11509. + CpaCyDsaVerifyOpData *pVerData = NULL;
  11510. +
  11511. + if (NULL == callbackTag) {
  11512. + DPRINTK("%s(): Invalid input parameters - "
  11513. + "callbackTag data is NULL\n", __FUNCTION__);
  11514. + return;
  11515. + }
  11516. +
  11517. + krp = (struct cryptkop *)callbackTag;
  11518. +
  11519. + if (NULL == pOpData) {
  11520. + DPRINTK("%s(): Invalid input parameters - "
  11521. + "Operation Data is NULL\n", __FUNCTION__);
  11522. + krp->krp_status = ECANCELED;
  11523. + crypto_kdone(krp);
  11524. + return;
  11525. + }
  11526. + pVerData = (CpaCyDsaVerifyOpData *) pOpData;
  11527. +
  11528. + if (CPA_STATUS_SUCCESS != status) {
  11529. + APRINTK("%s(): LAC DSA Verify operation failed - "
  11530. + "Operation Status = %d\n", __FUNCTION__, status);
  11531. + krp->krp_status = ECANCELED;
  11532. + } else {
  11533. + krp->krp_status = CRYPTO_OP_SUCCESS;
  11534. +
  11535. + if (CPA_TRUE != verifyStatus) {
  11536. + DPRINTK("%s(): DSA signature invalid\n", __FUNCTION__);
  11537. + krp->krp_status = EIO;
  11538. + }
  11539. + }
  11540. +
  11541. + /* Swap bytes only when the callback status is successful and
  11542. + verifyStatus is set to true */
  11543. + /*Just swapping back the key values for now. Possibly all
  11544. + swapped buffers need to be reverted */
  11545. + if (CPA_STATUS_SUCCESS == status && CPA_TRUE == verifyStatus) {
  11546. + icp_ocfDrvSwapBytes(pVerData->R.pData,
  11547. + pVerData->R.dataLenInBytes);
  11548. + icp_ocfDrvSwapBytes(pVerData->S.pData,
  11549. + pVerData->S.dataLenInBytes);
  11550. + }
  11551. +
  11552. + memset(pVerData, 0, sizeof(CpaCyDsaVerifyOpData));
  11553. + ICP_CACHE_FREE(drvDSAVerify_zone, pVerData);
  11554. + crypto_kdone(krp);
  11555. +
  11556. + return;
  11557. +}
  11558. diff -Nur linux-2.6.39.orig/crypto/ocf/ep80579/icp_common.c linux-2.6.39/crypto/ocf/ep80579/icp_common.c
  11559. --- linux-2.6.39.orig/crypto/ocf/ep80579/icp_common.c 1970-01-01 01:00:00.000000000 +0100
  11560. +++ linux-2.6.39/crypto/ocf/ep80579/icp_common.c 2011-08-01 14:38:18.000000000 +0200
  11561. @@ -0,0 +1,773 @@
  11562. +/*************************************************************************
  11563. + *
  11564. + * This file is provided under a dual BSD/GPLv2 license. When using or
  11565. + * redistributing this file, you may do so under either license.
  11566. + *
  11567. + * GPL LICENSE SUMMARY
  11568. + *
  11569. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  11570. + *
  11571. + * This program is free software; you can redistribute it and/or modify
  11572. + * it under the terms of version 2 of the GNU General Public License as
  11573. + * published by the Free Software Foundation.
  11574. + *
  11575. + * This program is distributed in the hope that it will be useful, but
  11576. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  11577. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11578. + * General Public License for more details.
  11579. + *
  11580. + * You should have received a copy of the GNU General Public License
  11581. + * along with this program; if not, write to the Free Software
  11582. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  11583. + * The full GNU General Public License is included in this distribution
  11584. + * in the file called LICENSE.GPL.
  11585. + *
  11586. + * Contact Information:
  11587. + * Intel Corporation
  11588. + *
  11589. + * BSD LICENSE
  11590. + *
  11591. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  11592. + * All rights reserved.
  11593. + *
  11594. + * Redistribution and use in source and binary forms, with or without
  11595. + * modification, are permitted provided that the following conditions
  11596. + * are met:
  11597. + *
  11598. + * * Redistributions of source code must retain the above copyright
  11599. + * notice, this list of conditions and the following disclaimer.
  11600. + * * Redistributions in binary form must reproduce the above copyright
  11601. + * notice, this list of conditions and the following disclaimer in
  11602. + * the documentation and/or other materials provided with the
  11603. + * distribution.
  11604. + * * Neither the name of Intel Corporation nor the names of its
  11605. + * contributors may be used to endorse or promote products derived
  11606. + * from this software without specific prior written permission.
  11607. + *
  11608. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  11609. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  11610. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  11611. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  11612. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  11613. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  11614. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  11615. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  11616. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  11617. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  11618. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  11619. + *
  11620. + *
  11621. + * version: Security.L.1.0.2-229
  11622. + *
  11623. + ***************************************************************************/
  11624. +
  11625. +/*
  11626. + * An OCF module that uses Intel® QuickAssist Integrated Accelerator to do the
  11627. + * crypto.
  11628. + *
  11629. + * This driver requires the ICP Access Library that is available from Intel in
  11630. + * order to operate.
  11631. + */
  11632. +
  11633. +#include "icp_ocf.h"
  11634. +
  11635. +#define ICP_OCF_COMP_NAME "ICP_OCF"
  11636. +#define ICP_OCF_VER_MAIN (2)
  11637. +#define ICP_OCF_VER_MJR (1)
  11638. +#define ICP_OCF_VER_MNR (0)
  11639. +
  11640. +#define MAX_DEREG_RETRIES (100)
  11641. +#define DEFAULT_DEREG_RETRIES (10)
  11642. +#define DEFAULT_DEREG_DELAY_IN_JIFFIES (10)
  11643. +
  11644. +/* This defines the maximum number of sessions possible between OCF
  11645. + and the OCF EP80579 Driver. If set to zero, there is no limit. */
  11646. +#define DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT (0)
  11647. +#define NUM_SUPPORTED_CAPABILITIES (21)
  11648. +
  11649. +/*Slab zone names*/
  11650. +#define ICP_SESSION_DATA_NAME "icp_ocf.SesDat"
  11651. +#define ICP_OP_DATA_NAME "icp_ocf.OpDat"
  11652. +#define ICP_DH_NAME "icp_ocf.DH"
  11653. +#define ICP_MODEXP_NAME "icp_ocf.ModExp"
  11654. +#define ICP_RSA_DECRYPT_NAME "icp_ocf.RSAdec"
  11655. +#define ICP_RSA_PKEY_NAME "icp_ocf.RSApk"
  11656. +#define ICP_DSA_SIGN_NAME "icp_ocf.DSAsg"
  11657. +#define ICP_DSA_VER_NAME "icp_ocf.DSAver"
  11658. +#define ICP_RAND_VAL_NAME "icp_ocf.DSArnd"
  11659. +#define ICP_FLAT_BUFF_NAME "icp_ocf.FB"
  11660. +
  11661. +/*Slabs zones*/
  11662. +icp_kmem_cache drvSessionData_zone = NULL;
  11663. +icp_kmem_cache drvOpData_zone = NULL;
  11664. +icp_kmem_cache drvDH_zone = NULL;
  11665. +icp_kmem_cache drvLnModExp_zone = NULL;
  11666. +icp_kmem_cache drvRSADecrypt_zone = NULL;
  11667. +icp_kmem_cache drvRSAPrivateKey_zone = NULL;
  11668. +icp_kmem_cache drvDSARSSign_zone = NULL;
  11669. +icp_kmem_cache drvDSARSSignKValue_zone = NULL;
  11670. +icp_kmem_cache drvDSAVerify_zone = NULL;
  11671. +
  11672. +/*Slab zones for flatbuffers and bufferlist*/
  11673. +icp_kmem_cache drvFlatBuffer_zone = NULL;
  11674. +
  11675. +static inline int icp_cache_null_check(void)
  11676. +{
  11677. + return (drvSessionData_zone && drvOpData_zone
  11678. + && drvDH_zone && drvLnModExp_zone && drvRSADecrypt_zone
  11679. + && drvRSAPrivateKey_zone && drvDSARSSign_zone
  11680. + && drvDSARSSign_zone && drvDSARSSignKValue_zone
  11681. + && drvDSAVerify_zone && drvFlatBuffer_zone);
  11682. +}
  11683. +
  11684. +/*Function to free all allocated slab caches before exiting the module*/
  11685. +static void icp_ocfDrvFreeCaches(void);
  11686. +
  11687. +int32_t icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  11688. +
  11689. +/* Module parameter - gives the number of times LAC deregistration shall be
  11690. + re-tried */
  11691. +int num_dereg_retries = DEFAULT_DEREG_RETRIES;
  11692. +
  11693. +/* Module parameter - gives the delay time in jiffies before a LAC session
  11694. + shall be attempted to be deregistered again */
  11695. +int dereg_retry_delay_in_jiffies = DEFAULT_DEREG_DELAY_IN_JIFFIES;
  11696. +
  11697. +/* Module parameter - gives the maximum number of sessions possible between
  11698. + OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/
  11699. +int max_sessions = DEFAULT_OCF_TO_DRV_MAX_SESSION_COUNT;
  11700. +
  11701. +/* This is set when the module is removed from the system, no further
  11702. + processing can take place if this is set */
  11703. +icp_atomic_t icp_ocfDrvIsExiting = ICP_ATOMIC_INIT(0);
  11704. +
  11705. +/* This is used to show how many lac sessions were not deregistered*/
  11706. +icp_atomic_t lac_session_failed_dereg_count = ICP_ATOMIC_INIT(0);
  11707. +
  11708. +/* This is used to track the number of registered sessions between OCF and
  11709. + * and the OCF EP80579 driver, when max_session is set to value other than
  11710. + * zero. This ensures that the max_session set for the OCF and the driver
  11711. + * is equal to the LAC registered sessions */
  11712. +icp_atomic_t num_ocf_to_drv_registered_sessions = ICP_ATOMIC_INIT(0);
  11713. +
  11714. +/* Head of linked list used to store session data */
  11715. +icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead;
  11716. +icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList;
  11717. +
  11718. +icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock;
  11719. +
  11720. +/*Below pointer is only used in linux, FreeBSD uses the name to
  11721. +create its own variable name*/
  11722. +icp_workqueue *icp_ocfDrvFreeLacSessionWorkQ = NULL;
  11723. +ICP_WORKQUEUE_DEFINE_THREAD(icp_ocfDrvFreeLacSessionWorkQ);
  11724. +
  11725. +struct icp_drvBuffListInfo defBuffListInfo;
  11726. +
  11727. +/* Name : icp_ocfDrvInit
  11728. + *
  11729. + * Description : This function will register all the symmetric and asymmetric
  11730. + * functionality that will be accelerated by the hardware. It will also
  11731. + * get a unique driver ID from the OCF and initialise all slab caches
  11732. + */
  11733. +ICP_MODULE_INIT_FUNC(icp_ocfDrvInit)
  11734. +{
  11735. + int ocfStatus = 0;
  11736. +
  11737. + IPRINTK("=== %s ver %d.%d.%d ===\n", ICP_OCF_COMP_NAME,
  11738. + ICP_OCF_VER_MAIN, ICP_OCF_VER_MJR, ICP_OCF_VER_MNR);
  11739. +
  11740. + if (MAX_DEREG_RETRIES < num_dereg_retries) {
  11741. + EPRINTK("Session deregistration retry count set to greater "
  11742. + "than %d", MAX_DEREG_RETRIES);
  11743. + icp_module_return_code(EINVAL);
  11744. + }
  11745. +
  11746. + /* Initialize and Start the Cryptographic component */
  11747. + if (CPA_STATUS_SUCCESS !=
  11748. + cpaCyStartInstance(CPA_INSTANCE_HANDLE_SINGLE)) {
  11749. + EPRINTK("Failed to initialize and start the instance "
  11750. + "of the Cryptographic component.\n");
  11751. + return icp_module_return_code(EINVAL);
  11752. + }
  11753. +
  11754. + icp_spin_lock_init(&icp_ocfDrvSymSessInfoListSpinlock);
  11755. +
  11756. + /* Set the default size of BufferList to allocate */
  11757. + memset(&defBuffListInfo, 0, sizeof(struct icp_drvBuffListInfo));
  11758. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  11759. + icp_ocfDrvBufferListMemInfo(ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS,
  11760. + &defBuffListInfo)) {
  11761. + EPRINTK("Failed to get bufferlist memory info.\n");
  11762. + return icp_module_return_code(ENOMEM);
  11763. + }
  11764. +
  11765. + /*Register OCF EP80579 Driver with OCF */
  11766. + icp_ocfDrvDriverId = ICP_CRYPTO_GET_DRIVERID();
  11767. +
  11768. + if (icp_ocfDrvDriverId < 0) {
  11769. + EPRINTK("%s : ICP driver failed to register with OCF!\n",
  11770. + __FUNCTION__);
  11771. + return icp_module_return_code(ENODEV);
  11772. + }
  11773. +
  11774. + /*Create all the slab caches used by the OCF EP80579 Driver */
  11775. + drvSessionData_zone =
  11776. + ICP_CACHE_CREATE(ICP_SESSION_DATA_NAME, struct icp_drvSessionData);
  11777. +
  11778. + /*
  11779. + * Allocation of the OpData includes the allocation space for meta data.
  11780. + * The memory after the opData structure is reserved for this meta data.
  11781. + */
  11782. + drvOpData_zone =
  11783. + icp_kmem_cache_create(ICP_OP_DATA_NAME,
  11784. + sizeof(struct icp_drvOpData) +
  11785. + defBuffListInfo.metaSize,
  11786. + ICP_KERNEL_CACHE_ALIGN,
  11787. + ICP_KERNEL_CACHE_NOINIT);
  11788. +
  11789. + drvDH_zone = ICP_CACHE_CREATE(ICP_DH_NAME, CpaCyDhPhase1KeyGenOpData);
  11790. +
  11791. + drvLnModExp_zone =
  11792. + ICP_CACHE_CREATE(ICP_MODEXP_NAME, CpaCyLnModExpOpData);
  11793. +
  11794. + drvRSADecrypt_zone =
  11795. + ICP_CACHE_CREATE(ICP_RSA_DECRYPT_NAME, CpaCyRsaDecryptOpData);
  11796. +
  11797. + drvRSAPrivateKey_zone =
  11798. + ICP_CACHE_CREATE(ICP_RSA_PKEY_NAME, CpaCyRsaPrivateKey);
  11799. +
  11800. + drvDSARSSign_zone =
  11801. + ICP_CACHE_CREATE(ICP_DSA_SIGN_NAME, CpaCyDsaRSSignOpData);
  11802. +
  11803. + /*too awkward to use a macro here */
  11804. + drvDSARSSignKValue_zone =
  11805. + ICP_CACHE_CREATE(ICP_RAND_VAL_NAME,
  11806. + DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES);
  11807. +
  11808. + drvDSAVerify_zone =
  11809. + ICP_CACHE_CREATE(ICP_DSA_VER_NAME, CpaCyDsaVerifyOpData);
  11810. +
  11811. + drvFlatBuffer_zone =
  11812. + ICP_CACHE_CREATE(ICP_FLAT_BUFF_NAME, CpaFlatBuffer);
  11813. +
  11814. + if (0 == icp_cache_null_check()) {
  11815. + icp_ocfDrvFreeCaches();
  11816. + EPRINTK("%s() line %d: Not enough memory!\n",
  11817. + __FUNCTION__, __LINE__);
  11818. + return ENOMEM;
  11819. + }
  11820. +
  11821. + /* Register the ICP symmetric crypto support. */
  11822. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_NULL_CBC, ocfStatus);
  11823. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_DES_CBC, ocfStatus);
  11824. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_3DES_CBC, ocfStatus);
  11825. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_AES_CBC, ocfStatus);
  11826. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_ARC4, ocfStatus);
  11827. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5, ocfStatus);
  11828. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_MD5_HMAC, ocfStatus);
  11829. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1, ocfStatus);
  11830. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA1_HMAC, ocfStatus);
  11831. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256, ocfStatus);
  11832. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_256_HMAC,
  11833. + ocfStatus);
  11834. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384, ocfStatus);
  11835. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_384_HMAC,
  11836. + ocfStatus);
  11837. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512, ocfStatus);
  11838. + ICP_REG_SYM_WITH_OCF(icp_ocfDrvDriverId, CRYPTO_SHA2_512_HMAC,
  11839. + ocfStatus);
  11840. +
  11841. + /* Register the ICP asymmetric algorithm support */
  11842. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DH_COMPUTE_KEY,
  11843. + ocfStatus);
  11844. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP, ocfStatus);
  11845. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_MOD_EXP_CRT, ocfStatus);
  11846. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_SIGN, ocfStatus);
  11847. + ICP_REG_ASYM_WITH_OCF(icp_ocfDrvDriverId, CRK_DSA_VERIFY, ocfStatus);
  11848. +
  11849. + /* Register the ICP random number generator support */
  11850. + ICP_REG_RAND_WITH_OCF(icp_ocfDrvDriverId,
  11851. + icp_ocfDrvReadRandom, NULL, ocfStatus);
  11852. +
  11853. + if (OCF_ZERO_FUNCTIONALITY_REGISTERED == ocfStatus) {
  11854. + DPRINTK("%s: Failed to register any device capabilities\n",
  11855. + __FUNCTION__);
  11856. + icp_ocfDrvFreeCaches();
  11857. + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  11858. + return icp_module_return_code(ECANCELED);
  11859. + }
  11860. +
  11861. + DPRINTK("%s: Registered %d of %d device capabilities\n",
  11862. + __FUNCTION__, ocfStatus, NUM_SUPPORTED_CAPABILITIES);
  11863. +
  11864. + /*Session data linked list used during module exit */
  11865. + ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead);
  11866. + ICP_INIT_LIST_HEAD(&icp_ocfDrvGlobalSymListHead_FreeMemList);
  11867. +
  11868. + ICP_WORKQUEUE_CREATE(icp_ocfDrvFreeLacSessionWorkQ, "icpwq");
  11869. + if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {
  11870. + EPRINTK("%s: Failed to create single "
  11871. + "thread workqueue\n", __FUNCTION__);
  11872. + icp_ocfDrvFreeCaches();
  11873. + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  11874. + return icp_module_return_code(ENOMEM);
  11875. + }
  11876. +
  11877. + return icp_module_return_code(0);
  11878. +}
  11879. +
  11880. +/* Name : icp_ocfDrvExit
  11881. + *
  11882. + * Description : This function will deregister all the symmetric sessions
  11883. + * registered with the LAC component. It will also deregister all symmetric
  11884. + * and asymmetric functionality that can be accelerated by the hardware via OCF
  11885. + * and random number generation if it is enabled.
  11886. + */
  11887. +ICP_MODULE_EXIT_FUNC(icp_ocfDrvExit)
  11888. +{
  11889. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  11890. + struct icp_drvSessionData *sessionData = NULL;
  11891. + struct icp_drvSessionData *tempSessionData = NULL;
  11892. + int i, remaining_delay_time_in_jiffies = 0;
  11893. +
  11894. + /* For FreeBSD the invariant macro below makes function to return */
  11895. + /* with EBUSY value in the case of any session which has been regi- */
  11896. + /* stered with LAC not being deregistered. */
  11897. + /* The Linux implementation is empty since it is purely to compensate */
  11898. + /* for a limitation of the FreeBSD 7.1 Opencrypto framework. */
  11899. +
  11900. + ICP_MODULE_EXIT_INV();
  11901. +
  11902. + /* There is a possibility of a process or new session command being */
  11903. + /* sent before this variable is incremented. The aim of this variable */
  11904. + /* is to stop a loop of calls creating a deadlock situation which */
  11905. + /* would prevent the driver from exiting. */
  11906. + icp_atomic_set(&icp_ocfDrvIsExiting, 1);
  11907. +
  11908. + /*Existing sessions will be routed to another driver after these calls */
  11909. + crypto_unregister_all(icp_ocfDrvDriverId);
  11910. + crypto_runregister_all(icp_ocfDrvDriverId);
  11911. +
  11912. + if (ICP_WORKQUEUE_NULL_CHECK(icp_ocfDrvFreeLacSessionWorkQ)) {
  11913. + DPRINTK("%s: workqueue already "
  11914. + "destroyed, therefore module exit "
  11915. + " function already called. Exiting.\n", __FUNCTION__);
  11916. + return ICP_MODULE_EXIT_FUNC_RETURN_VAL;
  11917. + }
  11918. + /*If any sessions are waiting to be deregistered, do that. This also
  11919. + flushes the work queue */
  11920. + ICP_WORKQUEUE_DESTROY(icp_ocfDrvFreeLacSessionWorkQ);
  11921. +
  11922. + /*ENTER CRITICAL SECTION */
  11923. + icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
  11924. +
  11925. + ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,
  11926. + &icp_ocfDrvGlobalSymListHead, listNode) {
  11927. + for (i = 0; i < num_dereg_retries; i++) {
  11928. + /*No harm if bad input - LAC will handle error cases */
  11929. + if (ICP_SESSION_RUNNING == tempSessionData->inUse) {
  11930. + lacStatus =
  11931. + cpaCySymRemoveSession
  11932. + (CPA_INSTANCE_HANDLE_SINGLE,
  11933. + tempSessionData->sessHandle);
  11934. + if (CPA_STATUS_SUCCESS == lacStatus) {
  11935. + /* Succesfully deregistered */
  11936. + break;
  11937. + } else if (CPA_STATUS_RETRY != lacStatus) {
  11938. + icp_atomic_inc
  11939. + (&lac_session_failed_dereg_count);
  11940. + break;
  11941. + }
  11942. +
  11943. + /*schedule_timout returns the time left for completion if
  11944. + * this task is set to TASK_INTERRUPTIBLE */
  11945. + remaining_delay_time_in_jiffies =
  11946. + dereg_retry_delay_in_jiffies;
  11947. + while (0 > remaining_delay_time_in_jiffies) {
  11948. + remaining_delay_time_in_jiffies =
  11949. + icp_schedule_timeout
  11950. + (&icp_ocfDrvSymSessInfoListSpinlock,
  11951. + remaining_delay_time_in_jiffies);
  11952. + }
  11953. +
  11954. + DPRINTK
  11955. + ("%s(): Retry %d to deregistrate the session\n",
  11956. + __FUNCTION__, i);
  11957. + }
  11958. + }
  11959. +
  11960. + /*remove from current list */
  11961. + ICP_LIST_DEL(tempSessionData, listNode);
  11962. + /*add to free mem linked list */
  11963. + ICP_LIST_ADD(tempSessionData,
  11964. + &icp_ocfDrvGlobalSymListHead_FreeMemList,
  11965. + listNode);
  11966. +
  11967. + }
  11968. +
  11969. + /*EXIT CRITICAL SECTION */
  11970. + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  11971. +
  11972. + /*set back to initial values */
  11973. + sessionData = NULL;
  11974. + /*still have a reference in our list! */
  11975. + tempSessionData = NULL;
  11976. + /*free memory */
  11977. +
  11978. + ICP_LIST_FOR_EACH_ENTRY_SAFE(tempSessionData, sessionData,
  11979. + &icp_ocfDrvGlobalSymListHead_FreeMemList,
  11980. + listNode) {
  11981. +
  11982. + ICP_LIST_DEL(tempSessionData, listNode);
  11983. + /* Free allocated CpaCySymSessionCtx */
  11984. + if (NULL != tempSessionData->sessHandle) {
  11985. + icp_kfree(tempSessionData->sessHandle);
  11986. + }
  11987. + memset(tempSessionData, 0, sizeof(struct icp_drvSessionData));
  11988. + ICP_CACHE_FREE(drvSessionData_zone, tempSessionData);
  11989. + }
  11990. +
  11991. + if (0 != icp_atomic_read(&lac_session_failed_dereg_count)) {
  11992. + DPRINTK("%s(): %d LAC sessions were not deregistered "
  11993. + "correctly. This is not a clean exit! \n",
  11994. + __FUNCTION__,
  11995. + icp_atomic_read(&lac_session_failed_dereg_count));
  11996. + }
  11997. +
  11998. + icp_ocfDrvFreeCaches();
  11999. + icp_ocfDrvDriverId = INVALID_DRIVER_ID;
  12000. +
  12001. + icp_spin_lock_destroy(&icp_ocfDrvSymSessInfoListSpinlock);
  12002. +
  12003. + /* Shutdown the Cryptographic component */
  12004. + lacStatus = cpaCyStopInstance(CPA_INSTANCE_HANDLE_SINGLE);
  12005. + if (CPA_STATUS_SUCCESS != lacStatus) {
  12006. + DPRINTK("%s(): Failed to stop instance of the "
  12007. + "Cryptographic component.(status == %d)\n",
  12008. + __FUNCTION__, lacStatus);
  12009. + }
  12010. +
  12011. + return ICP_MODULE_EXIT_FUNC_RETURN_VAL;
  12012. +}
  12013. +
  12014. +/* Name : icp_ocfDrvFreeCaches
  12015. + *
  12016. + * Description : This function deregisters all slab caches
  12017. + */
  12018. +static void icp_ocfDrvFreeCaches(void)
  12019. +{
  12020. + icp_atomic_set(&icp_ocfDrvIsExiting, 1);
  12021. +
  12022. + /*Sym Zones */
  12023. + ICP_CACHE_DESTROY(drvSessionData_zone);
  12024. + ICP_CACHE_DESTROY(drvOpData_zone);
  12025. +
  12026. + /*Asym zones */
  12027. + ICP_CACHE_DESTROY(drvDH_zone);
  12028. + ICP_CACHE_DESTROY(drvLnModExp_zone);
  12029. + ICP_CACHE_DESTROY(drvRSADecrypt_zone);
  12030. + ICP_CACHE_DESTROY(drvRSAPrivateKey_zone);
  12031. + ICP_CACHE_DESTROY(drvDSARSSignKValue_zone);
  12032. + ICP_CACHE_DESTROY(drvDSARSSign_zone);
  12033. + ICP_CACHE_DESTROY(drvDSAVerify_zone);
  12034. +
  12035. + /*FlatBuffer and BufferList Zones */
  12036. + ICP_CACHE_DESTROY(drvFlatBuffer_zone);
  12037. +
  12038. +}
  12039. +
  12040. +/* Name : icp_ocfDrvDeregRetry
  12041. + *
  12042. + * Description : This function will try to farm the session deregistration
  12043. + * off to a work queue. If it fails, nothing more can be done and it
  12044. + * returns an error
  12045. + */
  12046. +int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister)
  12047. +{
  12048. + struct icp_ocfDrvFreeLacSession *workstore = NULL;
  12049. +
  12050. + DPRINTK("%s(): Retry - Deregistering session (%p)\n",
  12051. + __FUNCTION__, sessionToDeregister);
  12052. +
  12053. + /*make sure the session is not available to be allocated during this
  12054. + process */
  12055. + icp_atomic_inc(&lac_session_failed_dereg_count);
  12056. +
  12057. + /*Farm off to work queue */
  12058. + workstore =
  12059. + icp_kmalloc(sizeof(struct icp_ocfDrvFreeLacSession), ICP_M_NOWAIT);
  12060. + if (NULL == workstore) {
  12061. + DPRINTK("%s(): unable to free session - no memory available "
  12062. + "for work queue\n", __FUNCTION__);
  12063. + return ENOMEM;
  12064. + }
  12065. +
  12066. + workstore->sessionToDeregister = sessionToDeregister;
  12067. +
  12068. + icp_init_work(&(workstore->work),
  12069. + icp_ocfDrvDeferedFreeLacSessionTaskFn, workstore);
  12070. +
  12071. + ICP_WORKQUEUE_ENQUEUE(icp_ocfDrvFreeLacSessionWorkQ,
  12072. + &(workstore->work));
  12073. +
  12074. + return ICP_OCF_DRV_STATUS_SUCCESS;
  12075. +
  12076. +}
  12077. +
  12078. +/* Name : icp_ocfDrvDeferedFreeLacSessionProcess
  12079. + *
  12080. + * Description : This function will retry (module input parameter)
  12081. + * 'num_dereg_retries' times to deregister any symmetric session that recieves a
  12082. + * CPA_STATUS_RETRY message from the LAC component. This function is run in
  12083. + * Thread context because it is called from a worker thread
  12084. + */
  12085. +void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg)
  12086. +{
  12087. + struct icp_ocfDrvFreeLacSession *workstore = NULL;
  12088. + CpaCySymSessionCtx sessionToDeregister = NULL;
  12089. + int i = 0;
  12090. + int remaining_delay_time_in_jiffies = 0;
  12091. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  12092. +
  12093. + workstore = (struct icp_ocfDrvFreeLacSession *)arg;
  12094. + if (NULL == workstore) {
  12095. + DPRINTK("%s() function called with null parameter \n",
  12096. + __FUNCTION__);
  12097. + return;
  12098. + }
  12099. +
  12100. + sessionToDeregister = workstore->sessionToDeregister;
  12101. + icp_kfree(workstore);
  12102. +
  12103. + /*if exiting, give deregistration one more blast only */
  12104. + if (icp_atomic_read(&icp_ocfDrvIsExiting) == CPA_TRUE) {
  12105. + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  12106. + sessionToDeregister);
  12107. +
  12108. + if (lacStatus != CPA_STATUS_SUCCESS) {
  12109. + DPRINTK("%s() Failed to Dereg LAC session %p "
  12110. + "during module exit\n", __FUNCTION__,
  12111. + sessionToDeregister);
  12112. + return;
  12113. + }
  12114. +
  12115. + icp_atomic_dec(&lac_session_failed_dereg_count);
  12116. + return;
  12117. + }
  12118. +
  12119. + for (i = 0; i <= num_dereg_retries; i++) {
  12120. + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  12121. + sessionToDeregister);
  12122. +
  12123. + if (lacStatus == CPA_STATUS_SUCCESS) {
  12124. + icp_atomic_dec(&lac_session_failed_dereg_count);
  12125. + return;
  12126. + }
  12127. + if (lacStatus != CPA_STATUS_RETRY) {
  12128. + DPRINTK("%s() Failed to deregister session - lacStatus "
  12129. + " = %d", __FUNCTION__, lacStatus);
  12130. + break;
  12131. + }
  12132. +
  12133. + /*schedule_timout returns the time left for completion if this
  12134. + task is set to TASK_INTERRUPTIBLE */
  12135. + remaining_delay_time_in_jiffies = dereg_retry_delay_in_jiffies;
  12136. + while (0 < remaining_delay_time_in_jiffies) {
  12137. + remaining_delay_time_in_jiffies =
  12138. + icp_schedule_timeout(NULL,
  12139. + remaining_delay_time_in_jiffies);
  12140. + }
  12141. +
  12142. + }
  12143. +
  12144. + DPRINTK("%s(): Unable to deregister session\n", __FUNCTION__);
  12145. + DPRINTK("%s(): Number of unavailable LAC sessions = %d\n", __FUNCTION__,
  12146. + icp_atomic_read(&lac_session_failed_dereg_count));
  12147. +}
  12148. +
  12149. +/* Name : icp_ocfDrvPtrAndLenToFlatBuffer
  12150. + *
  12151. + * Description : This function converts a "pointer and length" buffer
  12152. + * structure to Fredericksburg Flat Buffer (CpaFlatBuffer) format.
  12153. + *
  12154. + * This function assumes that the data passed in are valid.
  12155. + */
  12156. +inline void
  12157. +icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
  12158. + CpaFlatBuffer * pFlatBuffer)
  12159. +{
  12160. + pFlatBuffer->pData = pData;
  12161. + pFlatBuffer->dataLenInBytes = len;
  12162. +}
  12163. +
  12164. +/* Name : icp_ocfDrvPtrAndLenToBufferList
  12165. + *
  12166. + * Description : This function converts a "pointer and length" buffer
  12167. + * structure to Fredericksburg Scatter/Gather Buffer (CpaBufferList) format.
  12168. + *
  12169. + * This function assumes that the data passed in are valid.
  12170. + */
  12171. +inline void
  12172. +icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
  12173. + CpaBufferList * pBufferList)
  12174. +{
  12175. + pBufferList->numBuffers = 1;
  12176. + pBufferList->pBuffers->pData = pDataIn;
  12177. + pBufferList->pBuffers->dataLenInBytes = length;
  12178. +}
  12179. +
  12180. +/* Name : icp_ocfDrvBufferListToPtrAndLen
  12181. + *
  12182. + * Description : This function converts Fredericksburg Scatter/Gather Buffer
  12183. + * (CpaBufferList) format to a "pointer and length" buffer structure.
  12184. + *
  12185. + * This function assumes that the data passed in are valid.
  12186. + */
  12187. +inline void
  12188. +icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
  12189. + void **ppDataOut, uint32_t * pLength)
  12190. +{
  12191. + *ppDataOut = pBufferList->pBuffers->pData;
  12192. + *pLength = pBufferList->pBuffers->dataLenInBytes;
  12193. +}
  12194. +
  12195. +/* Name : icp_ocfDrvBufferListMemInfo
  12196. + *
  12197. + * Description : This function will set the number of flat buffers in
  12198. + * bufferlist, the size of memory to allocate for the pPrivateMetaData
  12199. + * member of the CpaBufferList.
  12200. + */
  12201. +int
  12202. +icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
  12203. + struct icp_drvBuffListInfo *buffListInfo)
  12204. +{
  12205. + buffListInfo->numBuffers = numBuffers;
  12206. +
  12207. + if (CPA_STATUS_SUCCESS !=
  12208. + cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
  12209. + buffListInfo->numBuffers,
  12210. + &(buffListInfo->metaSize))) {
  12211. + EPRINTK("%s() Failed to get buffer list meta size.\n",
  12212. + __FUNCTION__);
  12213. + return ICP_OCF_DRV_STATUS_FAIL;
  12214. + }
  12215. +
  12216. + return ICP_OCF_DRV_STATUS_SUCCESS;
  12217. +}
  12218. +
  12219. +/* Name : icp_ocfDrvFreeFlatBuffer
  12220. + *
  12221. + * Description : This function will deallocate flat buffer.
  12222. + */
  12223. +inline void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer)
  12224. +{
  12225. + if (pFlatBuffer != NULL) {
  12226. + memset(pFlatBuffer, 0, sizeof(CpaFlatBuffer));
  12227. + ICP_CACHE_FREE(drvFlatBuffer_zone, pFlatBuffer);
  12228. + }
  12229. +}
  12230. +
  12231. +/* Name : icp_ocfDrvAllocMetaData
  12232. + *
  12233. + * Description : This function will allocate memory for the
  12234. + * pPrivateMetaData member of CpaBufferList.
  12235. + */
  12236. +inline int
  12237. +icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
  12238. + struct icp_drvOpData *pOpData)
  12239. +{
  12240. + Cpa32U metaSize = 0;
  12241. +
  12242. + if (pBufferList->numBuffers <= ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  12243. + uint8_t *pOpDataStartAddr = (uint8_t *) pOpData;
  12244. +
  12245. + if (0 == defBuffListInfo.metaSize) {
  12246. + pBufferList->pPrivateMetaData = NULL;
  12247. + return ICP_OCF_DRV_STATUS_SUCCESS;
  12248. + }
  12249. + /*
  12250. + * The meta data allocation has been included as part of the
  12251. + * op data. It has been pre-allocated in memory just after the
  12252. + * icp_drvOpData structure.
  12253. + */
  12254. + pBufferList->pPrivateMetaData = (void *)(pOpDataStartAddr +
  12255. + sizeof(struct
  12256. + icp_drvOpData));
  12257. + } else {
  12258. + if (CPA_STATUS_SUCCESS !=
  12259. + cpaCyBufferListGetMetaSize(CPA_INSTANCE_HANDLE_SINGLE,
  12260. + pBufferList->numBuffers,
  12261. + &metaSize)) {
  12262. + EPRINTK("%s() Failed to get buffer list meta size.\n",
  12263. + __FUNCTION__);
  12264. + return ICP_OCF_DRV_STATUS_FAIL;
  12265. + }
  12266. +
  12267. + if (0 == metaSize) {
  12268. + pBufferList->pPrivateMetaData = NULL;
  12269. + return ICP_OCF_DRV_STATUS_SUCCESS;
  12270. + }
  12271. +
  12272. + pBufferList->pPrivateMetaData =
  12273. + icp_kmalloc(metaSize, ICP_M_NOWAIT);
  12274. + }
  12275. + if (NULL == pBufferList->pPrivateMetaData) {
  12276. + EPRINTK("%s() Failed to allocate pPrivateMetaData.\n",
  12277. + __FUNCTION__);
  12278. + return ICP_OCF_DRV_STATUS_FAIL;
  12279. + }
  12280. +
  12281. + return ICP_OCF_DRV_STATUS_SUCCESS;
  12282. +}
  12283. +
  12284. +/* Name : icp_ocfDrvFreeMetaData
  12285. + *
  12286. + * Description : This function will deallocate pPrivateMetaData memory.
  12287. + */
  12288. +inline void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList)
  12289. +{
  12290. + if (NULL == pBufferList->pPrivateMetaData) {
  12291. + return;
  12292. + }
  12293. +
  12294. + /*
  12295. + * Only free the meta data if the BufferList has more than
  12296. + * ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS number of buffers.
  12297. + * Otherwise, the meta data shall be freed when the icp_drvOpData is
  12298. + * freed.
  12299. + */
  12300. + if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS < pBufferList->numBuffers) {
  12301. + icp_kfree(pBufferList->pPrivateMetaData);
  12302. + }
  12303. +}
  12304. +
  12305. +/* Module declaration, init and exit functions */
  12306. +ICP_DECLARE_MODULE(icp_ocf, icp_ocfDrvInit, icp_ocfDrvExit);
  12307. +ICP_MODULE_DESCRIPTION("OCF Driver for Intel Quick Assist crypto acceleration");
  12308. +ICP_MODULE_VERSION(icp_ocf, ICP_OCF_VER_MJR);
  12309. +ICP_MODULE_LICENSE("Dual BSD/GPL");
  12310. +ICP_MODULE_AUTHOR("Intel");
  12311. +
  12312. +/* Module parameters */
  12313. +ICP_MODULE_PARAM_INT(icp_ocf, num_dereg_retries,
  12314. + "Number of times to retry LAC Sym Session Deregistration. "
  12315. + "Default 10, Max 100");
  12316. +ICP_MODULE_PARAM_INT(icp_ocf, dereg_retry_delay_in_jiffies, "Delay in jiffies "
  12317. + "(added to a schedule() function call) before a LAC Sym "
  12318. + "Session Dereg is retried. Default 10");
  12319. +ICP_MODULE_PARAM_INT(icp_ocf, max_sessions,
  12320. + "This sets the maximum number of sessions "
  12321. + "between OCF and this driver. If this value is set to zero,"
  12322. + "max session count checking is disabled. Default is zero(0)");
  12323. +
  12324. +/* Module dependencies */
  12325. +#define MODULE_MIN_VER 1
  12326. +#define CRYPTO_MAX_VER 3
  12327. +#define LAC_MAX_VER 2
  12328. +
  12329. +ICP_MODULE_DEPEND(icp_ocf, crypto, MODULE_MIN_VER, MODULE_MIN_VER,
  12330. + CRYPTO_MAX_VER);
  12331. +ICP_MODULE_DEPEND(icp_ocf, cryptodev, MODULE_MIN_VER, MODULE_MIN_VER,
  12332. + CRYPTO_MAX_VER);
  12333. +ICP_MODULE_DEPEND(icp_ocf, icp_crypto, MODULE_MIN_VER, MODULE_MIN_VER,
  12334. + LAC_MAX_VER);
  12335. diff -Nur linux-2.6.39.orig/crypto/ocf/ep80579/icp_ocf.h linux-2.6.39/crypto/ocf/ep80579/icp_ocf.h
  12336. --- linux-2.6.39.orig/crypto/ocf/ep80579/icp_ocf.h 1970-01-01 01:00:00.000000000 +0100
  12337. +++ linux-2.6.39/crypto/ocf/ep80579/icp_ocf.h 2011-08-01 14:38:18.000000000 +0200
  12338. @@ -0,0 +1,376 @@
  12339. +/***************************************************************************
  12340. + *
  12341. + * This file is provided under a dual BSD/GPLv2 license. When using or
  12342. + * redistributing this file, you may do so under either license.
  12343. + *
  12344. + * GPL LICENSE SUMMARY
  12345. + *
  12346. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  12347. + *
  12348. + * This program is free software; you can redistribute it and/or modify
  12349. + * it under the terms of version 2 of the GNU General Public License as
  12350. + * published by the Free Software Foundation.
  12351. + *
  12352. + * This program is distributed in the hope that it will be useful, but
  12353. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  12354. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12355. + * General Public License for more details.
  12356. + *
  12357. + * You should have received a copy of the GNU General Public License
  12358. + * along with this program; if not, write to the Free Software
  12359. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  12360. + * The full GNU General Public License is included in this distribution
  12361. + * in the file called LICENSE.GPL.
  12362. + *
  12363. + * Contact Information:
  12364. + * Intel Corporation
  12365. + *
  12366. + * BSD LICENSE
  12367. + *
  12368. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  12369. + * All rights reserved.
  12370. + *
  12371. + * Redistribution and use in source and binary forms, with or without
  12372. + * modification, are permitted provided that the following conditions
  12373. + * are met:
  12374. + *
  12375. + * * Redistributions of source code must retain the above copyright
  12376. + * notice, this list of conditions and the following disclaimer.
  12377. + * * Redistributions in binary form must reproduce the above copyright
  12378. + * notice, this list of conditions and the following disclaimer in
  12379. + * the documentation and/or other materials provided with the
  12380. + * distribution.
  12381. + * * Neither the name of Intel Corporation nor the names of its
  12382. + * contributors may be used to endorse or promote products derived
  12383. + * from this software without specific prior written permission.
  12384. + *
  12385. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  12386. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  12387. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  12388. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  12389. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  12390. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  12391. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12392. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  12393. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12394. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  12395. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  12396. + *
  12397. + *
  12398. + * version: Security.L.1.0.2-229
  12399. + *
  12400. + ***************************************************************************/
  12401. +
  12402. +/*
  12403. + * OCF driver header file for the Intel ICP processor.
  12404. + */
  12405. +
  12406. +#ifndef ICP_OCF_H_
  12407. +#define ICP_OCF_H_
  12408. +
  12409. +#include <cpa.h>
  12410. +#include <cpa_cy_im.h>
  12411. +#include <cpa_cy_sym.h>
  12412. +#include <cpa_cy_rand.h>
  12413. +#include <cpa_cy_dh.h>
  12414. +#include <cpa_cy_rsa.h>
  12415. +#include <cpa_cy_ln.h>
  12416. +#include <cpa_cy_common.h>
  12417. +#include <cpa_cy_dsa.h>
  12418. +
  12419. +#include "icp_os.h"
  12420. +
  12421. +#define NUM_BITS_IN_BYTE (8)
  12422. +#define NUM_BITS_IN_BYTE_MINUS_ONE (NUM_BITS_IN_BYTE -1)
  12423. +#define INVALID_DRIVER_ID (-1)
  12424. +#define RETURN_RAND_NUM_GEN_FAILED (-1)
  12425. +
  12426. +/*This is the max block cipher initialisation vector*/
  12427. +#define MAX_IV_LEN_IN_BYTES (20)
  12428. +/*This is used to check whether the OCF to this driver session limit has
  12429. + been disabled*/
  12430. +#define NO_OCF_TO_DRV_MAX_SESSIONS (0)
  12431. +
  12432. +/*OCF values mapped here*/
  12433. +#define ICP_SHA1_DIGEST_SIZE_IN_BYTES (SHA1_HASH_LEN)
  12434. +#define ICP_SHA256_DIGEST_SIZE_IN_BYTES (SHA2_256_HASH_LEN)
  12435. +#define ICP_SHA384_DIGEST_SIZE_IN_BYTES (SHA2_384_HASH_LEN)
  12436. +#define ICP_SHA512_DIGEST_SIZE_IN_BYTES (SHA2_512_HASH_LEN)
  12437. +#define ICP_MD5_DIGEST_SIZE_IN_BYTES (MD5_HASH_LEN)
  12438. +#define ARC4_COUNTER_LEN (ARC4_BLOCK_LEN)
  12439. +
  12440. +#define OCF_REGISTRATION_STATUS_SUCCESS (0)
  12441. +#define OCF_ZERO_FUNCTIONALITY_REGISTERED (0)
  12442. +#define ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR (0)
  12443. +#define ICP_OCF_DRV_STATUS_SUCCESS (0)
  12444. +#define ICP_OCF_DRV_STATUS_FAIL (1)
  12445. +
  12446. +/*Turn on/off debug options*/
  12447. +#define ICP_OCF_PRINT_DEBUG_MESSAGES (0)
  12448. +#define ICP_OCF_PRINT_KERN_ALERT (1)
  12449. +#define ICP_OCF_PRINT_KERN_ERRS (1)
  12450. +
  12451. +#if ICP_OCF_PRINT_DEBUG_MESSAGES == 1
  12452. +#define DPRINTK(args...) \
  12453. +{ \
  12454. + ICP_IPRINTK(args); \
  12455. +}
  12456. +
  12457. +#else //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
  12458. +
  12459. +#define DPRINTK(args...)
  12460. +
  12461. +#endif //ICP_OCF_PRINT_DEBUG_MESSAGES == 1
  12462. +
  12463. +#if ICP_OCF_PRINT_KERN_ALERT == 1
  12464. +#define APRINTK(args...) \
  12465. +{ \
  12466. + ICP_APRINTK(args); \
  12467. +}
  12468. +
  12469. +#else //ICP_OCF_PRINT_KERN_ALERT == 1
  12470. +
  12471. +#define APRINTK(args...)
  12472. +
  12473. +#endif //ICP_OCF_PRINT_KERN_ALERT == 1
  12474. +
  12475. +#if ICP_OCF_PRINT_KERN_ERRS == 1
  12476. +#define EPRINTK(args...) \
  12477. +{ \
  12478. + ICP_EPRINTK(args); \
  12479. +}
  12480. +
  12481. +#else //ICP_OCF_PRINT_KERN_ERRS == 1
  12482. +
  12483. +#define EPRINTK(args...)
  12484. +
  12485. +#endif //ICP_OCF_PRINT_KERN_ERRS == 1
  12486. +
  12487. +#define IPRINTK(args...) \
  12488. +{ \
  12489. + ICP_IPRINTK(args); \
  12490. +}
  12491. +
  12492. +/*DSA Prime Q size in bytes (as defined in the standard) */
  12493. +#define DSA_RS_SIGN_PRIMEQ_SIZE_IN_BYTES (20)
  12494. +
  12495. +#define BITS_TO_BYTES(bytes, bits) \
  12496. + bytes = (bits + NUM_BITS_IN_BYTE_MINUS_ONE) / NUM_BITS_IN_BYTE
  12497. +
  12498. +typedef enum {
  12499. + ICP_OCF_DRV_ALG_CIPHER = 0,
  12500. + ICP_OCF_DRV_ALG_HASH
  12501. +} icp_ocf_drv_alg_type_t;
  12502. +
  12503. +typedef ICP_LIST_HEAD(icp_drvSessionListHead_s,
  12504. + icp_drvSessionData) icp_drvSessionListHead_t;
  12505. +
  12506. +/*Values used to derisk chances of performs being called against
  12507. +deregistered sessions (for which the slab page has been reclaimed)
  12508. +This is not a fix - since page frames are reclaimed from a slab, one cannot
  12509. +rely on that memory not being re-used by another app.*/
  12510. +typedef enum {
  12511. + ICP_SESSION_INITIALISED = 0x5C5C5C,
  12512. + ICP_SESSION_RUNNING = 0x005C00,
  12513. + ICP_SESSION_DEREGISTERED = 0xC5C5C5
  12514. +} usage_derisk;
  12515. +
  12516. +/* This struct is required for deferred session
  12517. + deregistration as a work queue function can
  12518. + only have one argument*/
  12519. +struct icp_ocfDrvFreeLacSession {
  12520. + CpaCySymSessionCtx sessionToDeregister;
  12521. + icp_workstruct work;
  12522. +};
  12523. +
  12524. +/*
  12525. +This is the OCF<->OCF_DRV session object:
  12526. +
  12527. +1.listNode
  12528. + The first member is a listNode. These session objects are added to a linked
  12529. + list in order to make it easier to remove them all at session exit time.
  12530. +
  12531. +2.inUse
  12532. + The second member is used to give the session object state and derisk the
  12533. + possibility of OCF batch calls executing against a deregistered session (as
  12534. + described above).
  12535. +
  12536. +3.sessHandle
  12537. + The third member is a LAC<->OCF_DRV session handle (initialised with the first
  12538. + perform request for that session).
  12539. +
  12540. +4.lacSessCtx
  12541. + The fourth is the LAC session context. All the parameters for this structure
  12542. + are only known when the first perform request for this session occurs. That is
  12543. + why the OCF EP80579 Driver only registers a new LAC session at perform time
  12544. +*/
  12545. +struct icp_drvSessionData {
  12546. + ICP_LIST_ENTRY(icp_drvSessionData) listNode;
  12547. + usage_derisk inUse;
  12548. + CpaCySymSessionCtx sessHandle;
  12549. + CpaCySymSessionSetupData lacSessCtx;
  12550. +};
  12551. +
  12552. +/* These are all defined in icp_common.c */
  12553. +extern icp_atomic_t lac_session_failed_dereg_count;
  12554. +extern icp_atomic_t icp_ocfDrvIsExiting;
  12555. +extern icp_atomic_t num_ocf_to_drv_registered_sessions;
  12556. +
  12557. +extern int32_t icp_ocfDrvDriverId;
  12558. +
  12559. +extern icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead;
  12560. +extern icp_drvSessionListHead_t icp_ocfDrvGlobalSymListHead_FreeMemList;
  12561. +extern icp_workqueue *icp_ocfDrvFreeLacSessionWorkQ;
  12562. +extern icp_spinlock_t icp_ocfDrvSymSessInfoListSpinlock;
  12563. +
  12564. +/*Slab zones for symettric functionality, instantiated in icp_common.c*/
  12565. +extern icp_kmem_cache drvSessionData_zone;
  12566. +extern icp_kmem_cache drvOpData_zone;
  12567. +
  12568. +/*Slabs zones for asymettric functionality, instantiated in icp_common.c*/
  12569. +extern icp_kmem_cache drvDH_zone;
  12570. +extern icp_kmem_cache drvLnModExp_zone;
  12571. +extern icp_kmem_cache drvRSADecrypt_zone;
  12572. +extern icp_kmem_cache drvRSAPrivateKey_zone;
  12573. +extern icp_kmem_cache drvDSARSSign_zone;
  12574. +extern icp_kmem_cache drvDSARSSignKValue_zone;
  12575. +extern icp_kmem_cache drvDSAVerify_zone;
  12576. +
  12577. +/* Module parameters defined in icp_cpmmon.c*/
  12578. +
  12579. +/* Module parameters - gives the number of times LAC deregistration shall be
  12580. + re-tried */
  12581. +extern int num_dereg_retries;
  12582. +
  12583. +/* Module parameter - gives the delay time in jiffies before a LAC session
  12584. + shall be attempted to be deregistered again */
  12585. +extern int dereg_retry_delay_in_jiffies;
  12586. +
  12587. +/* Module parameter - gives the maximum number of sessions possible between
  12588. + OCF and the OCF EP80579 Driver. If set to zero, there is no limit.*/
  12589. +extern int max_sessions;
  12590. +
  12591. +/*Slab zones for flatbuffers and bufferlist*/
  12592. +extern icp_kmem_cache drvFlatBuffer_zone;
  12593. +
  12594. +#define ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS (16)
  12595. +
  12596. +struct icp_drvBuffListInfo {
  12597. + Cpa16U numBuffers;
  12598. + Cpa32U metaSize;
  12599. + Cpa32U metaOffset;
  12600. + Cpa32U buffListSize;
  12601. +};
  12602. +
  12603. +extern struct icp_drvBuffListInfo defBuffListInfo;
  12604. +
  12605. +/* This struct is used to keep a reference to the relevant node in the list
  12606. + of sessionData structs, to the buffer type required by OCF and to the OCF
  12607. + provided crp struct that needs to be returned. All this info is needed in
  12608. + the callback function.*/
  12609. +struct icp_drvOpData {
  12610. + CpaCySymOpData lacOpData;
  12611. + uint32_t digestSizeInBytes;
  12612. + struct cryptop *crp;
  12613. + uint8_t bufferType;
  12614. + uint8_t ivData[MAX_IV_LEN_IN_BYTES];
  12615. + uint16_t numBufferListArray;
  12616. + CpaBufferList srcBuffer;
  12617. + CpaFlatBuffer bufferListArray[ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS];
  12618. + CpaBoolean verifyResult;
  12619. +};
  12620. +
  12621. +/* Create a new session between OCF and this driver*/
  12622. +int icp_ocfDrvNewSession(icp_device_t dev, uint32_t * sild,
  12623. + struct cryptoini *cri);
  12624. +
  12625. +/* Free a session between this driver and the Quick Assist Framework*/
  12626. +int icp_ocfDrvFreeLACSession(icp_device_t dev, uint64_t sid);
  12627. +
  12628. +/* Defer freeing a Quick Assist session*/
  12629. +void icp_ocfDrvDeferedFreeLacSessionProcess(void *arg);
  12630. +
  12631. +/* Process OCF cryptographic request for a symmetric algorithm*/
  12632. +int icp_ocfDrvSymProcess(icp_device_t dev, struct cryptop *crp, int hint);
  12633. +
  12634. +/* Process OCF cryptographic request for an asymmetric algorithm*/
  12635. +int icp_ocfDrvPkeProcess(icp_device_t dev, struct cryptkop *krp, int hint);
  12636. +
  12637. +/* Populate a buffer with random data*/
  12638. +int icp_ocfDrvReadRandom(void *arg, uint32_t * buf, int maxwords);
  12639. +
  12640. +/* Retry Quick Assist session deregistration*/
  12641. +int icp_ocfDrvDeregRetry(CpaCySymSessionCtx sessionToDeregister);
  12642. +
  12643. +/* Convert an OS scatter gather list to a CPA buffer list*/
  12644. +int icp_ocfDrvPacketBuffToBufferList(icp_packet_buffer_t * pPacketBuffer,
  12645. + CpaBufferList * bufferList);
  12646. +
  12647. +/* Convert a CPA buffer list to an OS scatter gather list*/
  12648. +int icp_ocfDrvBufferListToPacketBuff(CpaBufferList * bufferList,
  12649. + icp_packet_buffer_t ** pPacketBuffer);
  12650. +
  12651. +/* Get the number of buffers in an OS scatter gather list*/
  12652. +uint16_t icp_ocfDrvGetPacketBuffFrags(icp_packet_buffer_t * pPacketBuffer);
  12653. +
  12654. +/* Convert a single OS buffer to a CPA Flat Buffer*/
  12655. +void icp_ocfDrvSinglePacketBuffToFlatBuffer(icp_packet_buffer_t * pPacketBuffer,
  12656. + CpaFlatBuffer * pFlatBuffer);
  12657. +
  12658. +/* Add pointer and length to a CPA Flat Buffer structure*/
  12659. +void icp_ocfDrvPtrAndLenToFlatBuffer(void *pData, uint32_t len,
  12660. + CpaFlatBuffer * pFlatBuffer);
  12661. +
  12662. +/* Convert pointer and length values to a CPA buffer list*/
  12663. +void icp_ocfDrvPtrAndLenToBufferList(void *pDataIn, uint32_t length,
  12664. + CpaBufferList * pBufferList);
  12665. +
  12666. +/* Convert a CPA buffer list to pointer and length values*/
  12667. +void icp_ocfDrvBufferListToPtrAndLen(CpaBufferList * pBufferList,
  12668. + void **ppDataOut, uint32_t * pLength);
  12669. +
  12670. +/* Set the number of flat buffers in bufferlist and the size of memory
  12671. + to allocate for the pPrivateMetaData member of the CpaBufferList.*/
  12672. +int icp_ocfDrvBufferListMemInfo(uint16_t numBuffers,
  12673. + struct icp_drvBuffListInfo *buffListInfo);
  12674. +
  12675. +/* Find pointer position of the digest within an OS scatter gather list*/
  12676. +uint8_t *icp_ocfDrvPacketBufferDigestPointerFind(struct icp_drvOpData
  12677. + *drvOpData,
  12678. + int offsetInBytes,
  12679. + uint32_t digestSizeInBytes);
  12680. +
  12681. +/*This top level function is used to find a pointer to where a digest is
  12682. + stored/needs to be inserted. */
  12683. +uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData *drvOpData,
  12684. + struct cryptodesc *crp_desc);
  12685. +
  12686. +/* Free a CPA flat buffer*/
  12687. +void icp_ocfDrvFreeFlatBuffer(CpaFlatBuffer * pFlatBuffer);
  12688. +
  12689. +/* This function will allocate memory for the pPrivateMetaData
  12690. + member of CpaBufferList. */
  12691. +int icp_ocfDrvAllocMetaData(CpaBufferList * pBufferList,
  12692. + struct icp_drvOpData *pOpData);
  12693. +
  12694. +/* Free data allocated for the pPrivateMetaData
  12695. + member of CpaBufferList.*/
  12696. +void icp_ocfDrvFreeMetaData(CpaBufferList * pBufferList);
  12697. +
  12698. +#define ICP_CACHE_CREATE(cache_ID, cache_name) \
  12699. + icp_kmem_cache_create(cache_ID, sizeof(cache_name),ICP_KERNEL_CACHE_ALIGN,\
  12700. + ICP_KERNEL_CACHE_NOINIT)
  12701. +
  12702. +#define ICP_CACHE_FREE(args...) \
  12703. + icp_kmem_cache_free (args)
  12704. +
  12705. +#define ICP_CACHE_DESTROY(slab_zone)\
  12706. +{\
  12707. + if(NULL != slab_zone){\
  12708. + icp_kmem_cache_destroy(slab_zone);\
  12709. + slab_zone = NULL;\
  12710. + }\
  12711. +}
  12712. +
  12713. +#endif
  12714. +/* ICP_OCF_H_ */
  12715. diff -Nur linux-2.6.39.orig/crypto/ocf/ep80579/icp_sym.c linux-2.6.39/crypto/ocf/ep80579/icp_sym.c
  12716. --- linux-2.6.39.orig/crypto/ocf/ep80579/icp_sym.c 1970-01-01 01:00:00.000000000 +0100
  12717. +++ linux-2.6.39/crypto/ocf/ep80579/icp_sym.c 2011-08-01 14:38:18.000000000 +0200
  12718. @@ -0,0 +1,1153 @@
  12719. +/***************************************************************************
  12720. + *
  12721. + * This file is provided under a dual BSD/GPLv2 license. When using or
  12722. + * redistributing this file, you may do so under either license.
  12723. + *
  12724. + * GPL LICENSE SUMMARY
  12725. + *
  12726. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  12727. + *
  12728. + * This program is free software; you can redistribute it and/or modify
  12729. + * it under the terms of version 2 of the GNU General Public License as
  12730. + * published by the Free Software Foundation.
  12731. + *
  12732. + * This program is distributed in the hope that it will be useful, but
  12733. + * WITHOUT ANY WARRANTY; without even the implied warranty of
  12734. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12735. + * General Public License for more details.
  12736. + *
  12737. + * You should have received a copy of the GNU General Public License
  12738. + * along with this program; if not, write to the Free Software
  12739. + * Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  12740. + * The full GNU General Public License is included in this distribution
  12741. + * in the file called LICENSE.GPL.
  12742. + *
  12743. + * Contact Information:
  12744. + * Intel Corporation
  12745. + *
  12746. + * BSD LICENSE
  12747. + *
  12748. + * Copyright(c) 2007,2008,2009 Intel Corporation. All rights reserved.
  12749. + * All rights reserved.
  12750. + *
  12751. + * Redistribution and use in source and binary forms, with or without
  12752. + * modification, are permitted provided that the following conditions
  12753. + * are met:
  12754. + *
  12755. + * * Redistributions of source code must retain the above copyright
  12756. + * notice, this list of conditions and the following disclaimer.
  12757. + * * Redistributions in binary form must reproduce the above copyright
  12758. + * notice, this list of conditions and the following disclaimer in
  12759. + * the documentation and/or other materials provided with the
  12760. + * distribution.
  12761. + * * Neither the name of Intel Corporation nor the names of its
  12762. + * contributors may be used to endorse or promote products derived
  12763. + * from this software without specific prior written permission.
  12764. + *
  12765. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  12766. + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  12767. + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  12768. + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  12769. + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  12770. + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  12771. + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  12772. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  12773. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  12774. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  12775. + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  12776. + *
  12777. + *
  12778. + * version: Security.L.1.0.2-229
  12779. + *
  12780. + ***************************************************************************/
  12781. +/*
  12782. + * An OCF module that uses the API for Intel® QuickAssist Technology to do the
  12783. + * cryptography.
  12784. + *
  12785. + * This driver requires the ICP Access Library that is available from Intel in
  12786. + * order to operate.
  12787. + */
  12788. +
  12789. +#include "icp_ocf.h"
  12790. +
  12791. +/*This is the call back function for all symmetric cryptographic processes.
  12792. + Its main functionality is to free driver crypto operation structure and to
  12793. + call back to OCF*/
  12794. +static void
  12795. +icp_ocfDrvSymCallBack(void *callbackTag,
  12796. + CpaStatus status,
  12797. + const CpaCySymOp operationType,
  12798. + void *pOpData,
  12799. + CpaBufferList * pDstBuffer, CpaBoolean verifyResult);
  12800. +
  12801. +/*This function is used to extract crypto processing information from the OCF
  12802. + inputs, so as that it may be passed onto LAC*/
  12803. +static int
  12804. +icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
  12805. + struct cryptodesc *crp_desc);
  12806. +
  12807. +/*This function checks whether the crp_desc argument pertains to a digest or a
  12808. + cipher operation*/
  12809. +static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc);
  12810. +
  12811. +/*This function copies all the passed in session context information and stores
  12812. + it in a LAC context structure*/
  12813. +static int
  12814. +icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
  12815. + CpaCySymSessionSetupData * lacSessCtx);
  12816. +
  12817. +/*This function is used to free an OCF->OCF_DRV session object*/
  12818. +static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData);
  12819. +
  12820. +/*max IOV buffs supported in a UIO structure*/
  12821. +#define NUM_IOV_SUPPORTED (1)
  12822. +
  12823. +/* Name : icp_ocfDrvSymCallBack
  12824. + *
  12825. + * Description : When this function returns it signifies that the LAC
  12826. + * component has completed the relevant symmetric operation.
  12827. + *
  12828. + * Notes : The callbackTag is a pointer to an icp_drvOpData. This memory
  12829. + * object was passed to LAC for the cryptographic processing and contains all
  12830. + * the relevant information for cleaning up buffer handles etc. so that the
  12831. + * OCF EP80579 Driver portion of this crypto operation can be fully completed.
  12832. + */
  12833. +static void
  12834. +icp_ocfDrvSymCallBack(void *callbackTag,
  12835. + CpaStatus status,
  12836. + const CpaCySymOp operationType,
  12837. + void *pOpData,
  12838. + CpaBufferList * pDstBuffer, CpaBoolean verifyResult)
  12839. +{
  12840. + struct cryptop *crp = NULL;
  12841. + struct icp_drvOpData *temp_drvOpData =
  12842. + (struct icp_drvOpData *)callbackTag;
  12843. + uint64_t *tempBasePtr = NULL;
  12844. + uint32_t tempLen = 0;
  12845. +
  12846. + if (NULL == temp_drvOpData) {
  12847. + DPRINTK("%s(): The callback from the LAC component"
  12848. + " has failed due to Null userOpaque data"
  12849. + "(status == %d).\n", __FUNCTION__, status);
  12850. + DPRINTK("%s(): Unable to call OCF back! \n", __FUNCTION__);
  12851. + return;
  12852. + }
  12853. +
  12854. + crp = temp_drvOpData->crp;
  12855. + crp->crp_etype = ICP_OCF_DRV_NO_CRYPTO_PROCESS_ERROR;
  12856. +
  12857. + if (NULL == pOpData) {
  12858. + DPRINTK("%s(): The callback from the LAC component"
  12859. + " has failed due to Null Symmetric Op data"
  12860. + "(status == %d).\n", __FUNCTION__, status);
  12861. + crp->crp_etype = ECANCELED;
  12862. + crypto_done(crp);
  12863. + return;
  12864. + }
  12865. +
  12866. + if (NULL == pDstBuffer) {
  12867. + DPRINTK("%s(): The callback from the LAC component"
  12868. + " has failed due to Null Dst Bufferlist data"
  12869. + "(status == %d).\n", __FUNCTION__, status);
  12870. + crp->crp_etype = ECANCELED;
  12871. + crypto_done(crp);
  12872. + return;
  12873. + }
  12874. +
  12875. + if (CPA_STATUS_SUCCESS == status) {
  12876. +
  12877. + if (temp_drvOpData->bufferType == ICP_CRYPTO_F_PACKET_BUF) {
  12878. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  12879. + icp_ocfDrvBufferListToPacketBuff(pDstBuffer,
  12880. + (icp_packet_buffer_t
  12881. + **)
  12882. + & (crp->crp_buf))) {
  12883. + EPRINTK("%s(): BufferList to SkBuff "
  12884. + "conversion error.\n", __FUNCTION__);
  12885. + crp->crp_etype = EPERM;
  12886. + }
  12887. + } else {
  12888. + icp_ocfDrvBufferListToPtrAndLen(pDstBuffer,
  12889. + (void **)&tempBasePtr,
  12890. + &tempLen);
  12891. + crp->crp_olen = (int)tempLen;
  12892. + }
  12893. +
  12894. + } else {
  12895. + DPRINTK("%s(): The callback from the LAC component has failed"
  12896. + "(status == %d).\n", __FUNCTION__, status);
  12897. +
  12898. + crp->crp_etype = ECANCELED;
  12899. + }
  12900. +
  12901. + if (temp_drvOpData->numBufferListArray >
  12902. + ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  12903. + icp_kfree(pDstBuffer->pBuffers);
  12904. + }
  12905. + icp_ocfDrvFreeMetaData(pDstBuffer);
  12906. + ICP_CACHE_FREE(drvOpData_zone, temp_drvOpData);
  12907. +
  12908. + /* Invoke the OCF callback function */
  12909. + crypto_done(crp);
  12910. +
  12911. + return;
  12912. +}
  12913. +
  12914. +/* Name : icp_ocfDrvNewSession
  12915. + *
  12916. + * Description : This function will create a new Driver<->OCF session
  12917. + *
  12918. + * Notes : LAC session registration happens during the first perform call.
  12919. + * That is the first time we know all information about a given session.
  12920. + */
  12921. +int icp_ocfDrvNewSession(icp_device_t dev, uint32_t * sid,
  12922. + struct cryptoini *cri)
  12923. +{
  12924. + struct icp_drvSessionData *sessionData = NULL;
  12925. + uint32_t delete_session = 0;
  12926. +
  12927. + /* The SID passed in should be our driver ID. We can return the */
  12928. + /* local ID (LID) which is a unique identifier which we can use */
  12929. + /* to differentiate between the encrypt/decrypt LAC session handles */
  12930. + if (NULL == sid) {
  12931. + EPRINTK("%s(): Invalid input parameters - NULL sid.\n",
  12932. + __FUNCTION__);
  12933. + return EINVAL;
  12934. + }
  12935. +
  12936. + if (NULL == cri) {
  12937. + EPRINTK("%s(): Invalid input parameters - NULL cryptoini.\n",
  12938. + __FUNCTION__);
  12939. + return EINVAL;
  12940. + }
  12941. +
  12942. + if (icp_ocfDrvDriverId != *sid) {
  12943. + EPRINTK("%s(): Invalid input parameters - bad driver ID\n",
  12944. + __FUNCTION__);
  12945. + EPRINTK("\t sid = 0x08%p \n \t cri = 0x08%p \n", sid, cri);
  12946. + return EINVAL;
  12947. + }
  12948. +
  12949. + sessionData = icp_kmem_cache_zalloc(drvSessionData_zone, ICP_M_NOWAIT);
  12950. + if (NULL == sessionData) {
  12951. + DPRINTK("%s():No memory for Session Data\n", __FUNCTION__);
  12952. + return ENOMEM;
  12953. + }
  12954. +
  12955. + /*ENTER CRITICAL SECTION */
  12956. + icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
  12957. + /*put this check in the spinlock so no new sessions can be added to the
  12958. + linked list when we are exiting */
  12959. + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  12960. + delete_session++;
  12961. +
  12962. + } else if (NO_OCF_TO_DRV_MAX_SESSIONS != max_sessions) {
  12963. + if (icp_atomic_read(&num_ocf_to_drv_registered_sessions) >=
  12964. + (max_sessions -
  12965. + icp_atomic_read(&lac_session_failed_dereg_count))) {
  12966. + delete_session++;
  12967. + } else {
  12968. + icp_atomic_inc(&num_ocf_to_drv_registered_sessions);
  12969. + /* Add to session data linked list */
  12970. + ICP_LIST_ADD(sessionData, &icp_ocfDrvGlobalSymListHead,
  12971. + listNode);
  12972. + }
  12973. +
  12974. + } else if (NO_OCF_TO_DRV_MAX_SESSIONS == max_sessions) {
  12975. + ICP_LIST_ADD(sessionData, &icp_ocfDrvGlobalSymListHead,
  12976. + listNode);
  12977. + }
  12978. +
  12979. + sessionData->inUse = ICP_SESSION_INITIALISED;
  12980. +
  12981. + /*EXIT CRITICAL SECTION */
  12982. + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  12983. +
  12984. + if (delete_session) {
  12985. + DPRINTK("%s():No Session handles available\n", __FUNCTION__);
  12986. + ICP_CACHE_FREE(drvSessionData_zone, sessionData);
  12987. + return EPERM;
  12988. + }
  12989. +
  12990. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  12991. + icp_ocfDrvAlgorithmSetup(cri, &(sessionData->lacSessCtx))) {
  12992. + DPRINTK("%s():algorithm not supported\n", __FUNCTION__);
  12993. + icp_ocfDrvFreeOCFSession(sessionData);
  12994. + return EINVAL;
  12995. + }
  12996. +
  12997. + if (cri->cri_next) {
  12998. + if (cri->cri_next->cri_next != NULL) {
  12999. + DPRINTK("%s():only two chained algorithms supported\n",
  13000. + __FUNCTION__);
  13001. + icp_ocfDrvFreeOCFSession(sessionData);
  13002. + return EPERM;
  13003. + }
  13004. +
  13005. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  13006. + icp_ocfDrvAlgorithmSetup(cri->cri_next,
  13007. + &(sessionData->lacSessCtx))) {
  13008. + DPRINTK("%s():second algorithm not supported\n",
  13009. + __FUNCTION__);
  13010. + icp_ocfDrvFreeOCFSession(sessionData);
  13011. + return EINVAL;
  13012. + }
  13013. +
  13014. + sessionData->lacSessCtx.symOperation =
  13015. + CPA_CY_SYM_OP_ALGORITHM_CHAINING;
  13016. + }
  13017. +
  13018. + *sid = (uint32_t) sessionData;
  13019. +
  13020. + return ICP_OCF_DRV_STATUS_SUCCESS;
  13021. +}
  13022. +
  13023. +/* Name : icp_ocfDrvAlgorithmSetup
  13024. + *
  13025. + * Description : This function builds the session context data from the
  13026. + * information supplied through OCF. Algorithm chain order and whether the
  13027. + * session is Encrypt/Decrypt can only be found out at perform time however, so
  13028. + * the session is registered with LAC at that time.
  13029. + */
  13030. +static int
  13031. +icp_ocfDrvAlgorithmSetup(struct cryptoini *cri,
  13032. + CpaCySymSessionSetupData * lacSessCtx)
  13033. +{
  13034. +
  13035. + lacSessCtx->sessionPriority = CPA_CY_PRIORITY_NORMAL;
  13036. +
  13037. + switch (cri->cri_alg) {
  13038. +
  13039. + case CRYPTO_NULL_CBC:
  13040. + DPRINTK("%s(): NULL CBC\n", __FUNCTION__);
  13041. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  13042. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  13043. + CPA_CY_SYM_CIPHER_NULL;
  13044. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  13045. + cri->cri_klen / NUM_BITS_IN_BYTE;
  13046. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  13047. + break;
  13048. +
  13049. + case CRYPTO_DES_CBC:
  13050. + DPRINTK("%s(): DES CBC\n", __FUNCTION__);
  13051. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  13052. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  13053. + CPA_CY_SYM_CIPHER_DES_CBC;
  13054. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  13055. + cri->cri_klen / NUM_BITS_IN_BYTE;
  13056. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  13057. + break;
  13058. +
  13059. + case CRYPTO_3DES_CBC:
  13060. + DPRINTK("%s(): 3DES CBC\n", __FUNCTION__);
  13061. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  13062. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  13063. + CPA_CY_SYM_CIPHER_3DES_CBC;
  13064. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  13065. + cri->cri_klen / NUM_BITS_IN_BYTE;
  13066. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  13067. + break;
  13068. +
  13069. + case CRYPTO_AES_CBC:
  13070. + DPRINTK("%s(): AES CBC\n", __FUNCTION__);
  13071. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  13072. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  13073. + CPA_CY_SYM_CIPHER_AES_CBC;
  13074. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  13075. + cri->cri_klen / NUM_BITS_IN_BYTE;
  13076. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  13077. + break;
  13078. +
  13079. + case CRYPTO_ARC4:
  13080. + DPRINTK("%s(): ARC4\n", __FUNCTION__);
  13081. + lacSessCtx->symOperation = CPA_CY_SYM_OP_CIPHER;
  13082. + lacSessCtx->cipherSetupData.cipherAlgorithm =
  13083. + CPA_CY_SYM_CIPHER_ARC4;
  13084. + lacSessCtx->cipherSetupData.cipherKeyLenInBytes =
  13085. + cri->cri_klen / NUM_BITS_IN_BYTE;
  13086. + lacSessCtx->cipherSetupData.pCipherKey = cri->cri_key;
  13087. + break;
  13088. +
  13089. + case CRYPTO_SHA1:
  13090. + DPRINTK("%s(): SHA1\n", __FUNCTION__);
  13091. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  13092. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
  13093. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  13094. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  13095. + (cri->cri_mlen ?
  13096. + cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
  13097. +
  13098. + break;
  13099. +
  13100. + case CRYPTO_SHA1_HMAC:
  13101. + DPRINTK("%s(): SHA1_HMAC\n", __FUNCTION__);
  13102. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  13103. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_SHA1;
  13104. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  13105. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  13106. + (cri->cri_mlen ?
  13107. + cri->cri_mlen : ICP_SHA1_DIGEST_SIZE_IN_BYTES);
  13108. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  13109. + cri->cri_key;
  13110. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  13111. + cri->cri_klen / NUM_BITS_IN_BYTE;
  13112. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  13113. +
  13114. + break;
  13115. +
  13116. + case CRYPTO_SHA2_256:
  13117. + DPRINTK("%s(): SHA256\n", __FUNCTION__);
  13118. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  13119. + lacSessCtx->hashSetupData.hashAlgorithm =
  13120. + CPA_CY_SYM_HASH_SHA256;
  13121. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  13122. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  13123. + (cri->cri_mlen ?
  13124. + cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
  13125. +
  13126. + break;
  13127. +
  13128. + case CRYPTO_SHA2_256_HMAC:
  13129. + DPRINTK("%s(): SHA256_HMAC\n", __FUNCTION__);
  13130. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  13131. + lacSessCtx->hashSetupData.hashAlgorithm =
  13132. + CPA_CY_SYM_HASH_SHA256;
  13133. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  13134. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  13135. + (cri->cri_mlen ?
  13136. + cri->cri_mlen : ICP_SHA256_DIGEST_SIZE_IN_BYTES);
  13137. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  13138. + cri->cri_key;
  13139. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  13140. + cri->cri_klen / NUM_BITS_IN_BYTE;
  13141. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  13142. +
  13143. + break;
  13144. +
  13145. + case CRYPTO_SHA2_384:
  13146. + DPRINTK("%s(): SHA384\n", __FUNCTION__);
  13147. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  13148. + lacSessCtx->hashSetupData.hashAlgorithm =
  13149. + CPA_CY_SYM_HASH_SHA384;
  13150. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  13151. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  13152. + (cri->cri_mlen ?
  13153. + cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
  13154. +
  13155. + break;
  13156. +
  13157. + case CRYPTO_SHA2_384_HMAC:
  13158. + DPRINTK("%s(): SHA384_HMAC\n", __FUNCTION__);
  13159. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  13160. + lacSessCtx->hashSetupData.hashAlgorithm =
  13161. + CPA_CY_SYM_HASH_SHA384;
  13162. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  13163. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  13164. + (cri->cri_mlen ?
  13165. + cri->cri_mlen : ICP_SHA384_DIGEST_SIZE_IN_BYTES);
  13166. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  13167. + cri->cri_key;
  13168. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  13169. + cri->cri_klen / NUM_BITS_IN_BYTE;
  13170. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  13171. +
  13172. + break;
  13173. +
  13174. + case CRYPTO_SHA2_512:
  13175. + DPRINTK("%s(): SHA512\n", __FUNCTION__);
  13176. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  13177. + lacSessCtx->hashSetupData.hashAlgorithm =
  13178. + CPA_CY_SYM_HASH_SHA512;
  13179. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  13180. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  13181. + (cri->cri_mlen ?
  13182. + cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
  13183. +
  13184. + break;
  13185. +
  13186. + case CRYPTO_SHA2_512_HMAC:
  13187. + DPRINTK("%s(): SHA512_HMAC\n", __FUNCTION__);
  13188. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  13189. + lacSessCtx->hashSetupData.hashAlgorithm =
  13190. + CPA_CY_SYM_HASH_SHA512;
  13191. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  13192. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  13193. + (cri->cri_mlen ?
  13194. + cri->cri_mlen : ICP_SHA512_DIGEST_SIZE_IN_BYTES);
  13195. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  13196. + cri->cri_key;
  13197. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  13198. + cri->cri_klen / NUM_BITS_IN_BYTE;
  13199. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  13200. +
  13201. + break;
  13202. +
  13203. + case CRYPTO_MD5:
  13204. + DPRINTK("%s(): MD5\n", __FUNCTION__);
  13205. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  13206. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
  13207. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_PLAIN;
  13208. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  13209. + (cri->cri_mlen ?
  13210. + cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
  13211. +
  13212. + break;
  13213. +
  13214. + case CRYPTO_MD5_HMAC:
  13215. + DPRINTK("%s(): MD5_HMAC\n", __FUNCTION__);
  13216. + lacSessCtx->symOperation = CPA_CY_SYM_OP_HASH;
  13217. + lacSessCtx->hashSetupData.hashAlgorithm = CPA_CY_SYM_HASH_MD5;
  13218. + lacSessCtx->hashSetupData.hashMode = CPA_CY_SYM_HASH_MODE_AUTH;
  13219. + lacSessCtx->hashSetupData.digestResultLenInBytes =
  13220. + (cri->cri_mlen ?
  13221. + cri->cri_mlen : ICP_MD5_DIGEST_SIZE_IN_BYTES);
  13222. + lacSessCtx->hashSetupData.authModeSetupData.authKey =
  13223. + cri->cri_key;
  13224. + lacSessCtx->hashSetupData.authModeSetupData.authKeyLenInBytes =
  13225. + cri->cri_klen / NUM_BITS_IN_BYTE;
  13226. + lacSessCtx->hashSetupData.authModeSetupData.aadLenInBytes = 0;
  13227. +
  13228. + break;
  13229. +
  13230. + default:
  13231. + DPRINTK("%s(): ALG Setup FAIL\n", __FUNCTION__);
  13232. + return ICP_OCF_DRV_STATUS_FAIL;
  13233. + }
  13234. +
  13235. + return ICP_OCF_DRV_STATUS_SUCCESS;
  13236. +}
  13237. +
  13238. +/* Name : icp_ocfDrvFreeOCFSession
  13239. + *
  13240. + * Description : This function deletes all existing Session data representing
  13241. + * the Cryptographic session established between OCF and this driver. This
  13242. + * also includes freeing the memory allocated for the session context. The
  13243. + * session object is also removed from the session linked list.
  13244. + */
  13245. +static void icp_ocfDrvFreeOCFSession(struct icp_drvSessionData *sessionData)
  13246. +{
  13247. +
  13248. + sessionData->inUse = ICP_SESSION_DEREGISTERED;
  13249. +
  13250. + /*ENTER CRITICAL SECTION */
  13251. + icp_spin_lockbh_lock(&icp_ocfDrvSymSessInfoListSpinlock);
  13252. +
  13253. + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  13254. + /*If the Driver is exiting, allow that process to
  13255. + handle any deletions */
  13256. + /*EXIT CRITICAL SECTION */
  13257. + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  13258. + return;
  13259. + }
  13260. +
  13261. + icp_atomic_dec(&num_ocf_to_drv_registered_sessions);
  13262. +
  13263. + ICP_LIST_DEL(sessionData, listNode);
  13264. +
  13265. + /*EXIT CRITICAL SECTION */
  13266. + icp_spin_lockbh_unlock(&icp_ocfDrvSymSessInfoListSpinlock);
  13267. +
  13268. + if (NULL != sessionData->sessHandle) {
  13269. + icp_kfree(sessionData->sessHandle);
  13270. + }
  13271. + ICP_CACHE_FREE(drvSessionData_zone, sessionData);
  13272. +}
  13273. +
  13274. +/* Name : icp_ocfDrvFreeLACSession
  13275. + *
  13276. + * Description : This attempts to deregister a LAC session. If it fails, the
  13277. + * deregistation retry function is called.
  13278. + */
  13279. +int icp_ocfDrvFreeLACSession(icp_device_t dev, uint64_t sid)
  13280. +{
  13281. + CpaCySymSessionCtx sessionToDeregister = NULL;
  13282. + struct icp_drvSessionData *sessionData = NULL;
  13283. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  13284. + int retval = 0;
  13285. +
  13286. + sessionData = (struct icp_drvSessionData *)CRYPTO_SESID2LID(sid);
  13287. + if (NULL == sessionData) {
  13288. + EPRINTK("%s(): OCF Free session called with Null Session ID.\n",
  13289. + __FUNCTION__);
  13290. + return EINVAL;
  13291. + }
  13292. +
  13293. + sessionToDeregister = sessionData->sessHandle;
  13294. +
  13295. + if ((ICP_SESSION_INITIALISED != sessionData->inUse) &&
  13296. + (ICP_SESSION_RUNNING != sessionData->inUse) &&
  13297. + (ICP_SESSION_DEREGISTERED != sessionData->inUse)) {
  13298. + DPRINTK("%s() Session not initialised.\n", __FUNCTION__);
  13299. + return EINVAL;
  13300. + }
  13301. +
  13302. + if (ICP_SESSION_RUNNING == sessionData->inUse) {
  13303. + lacStatus = cpaCySymRemoveSession(CPA_INSTANCE_HANDLE_SINGLE,
  13304. + sessionToDeregister);
  13305. + if (CPA_STATUS_RETRY == lacStatus) {
  13306. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  13307. + icp_ocfDrvDeregRetry(&sessionToDeregister)) {
  13308. + /* the retry function increments the
  13309. + dereg failed count */
  13310. + DPRINTK("%s(): LAC failed to deregister the "
  13311. + "session. (localSessionId= %p)\n",
  13312. + __FUNCTION__, sessionToDeregister);
  13313. + retval = EPERM;
  13314. + }
  13315. +
  13316. + } else if (CPA_STATUS_SUCCESS != lacStatus) {
  13317. + DPRINTK("%s(): LAC failed to deregister the session. "
  13318. + "localSessionId= %p, lacStatus = %d\n",
  13319. + __FUNCTION__, sessionToDeregister, lacStatus);
  13320. + icp_atomic_inc(&lac_session_failed_dereg_count);
  13321. + retval = EPERM;
  13322. + }
  13323. + } else {
  13324. + DPRINTK("%s() Session not registered with LAC.\n",
  13325. + __FUNCTION__);
  13326. + }
  13327. +
  13328. + icp_ocfDrvFreeOCFSession(sessionData);
  13329. + return retval;
  13330. +
  13331. +}
  13332. +
  13333. +/* Name : icp_ocfDrvAlgCheck
  13334. + *
  13335. + * Description : This function checks whether the cryptodesc argument pertains
  13336. + * to a sym or hash function
  13337. + */
  13338. +static int icp_ocfDrvAlgCheck(struct cryptodesc *crp_desc)
  13339. +{
  13340. +
  13341. + if (crp_desc->crd_alg == CRYPTO_3DES_CBC ||
  13342. + crp_desc->crd_alg == CRYPTO_AES_CBC ||
  13343. + crp_desc->crd_alg == CRYPTO_DES_CBC ||
  13344. + crp_desc->crd_alg == CRYPTO_NULL_CBC ||
  13345. + crp_desc->crd_alg == CRYPTO_ARC4) {
  13346. + return ICP_OCF_DRV_ALG_CIPHER;
  13347. + }
  13348. +
  13349. + return ICP_OCF_DRV_ALG_HASH;
  13350. +}
  13351. +
  13352. +/* Name : icp_ocfDrvSymProcess
  13353. + *
  13354. + * Description : This function will map symmetric functionality calls from OCF
  13355. + * to the LAC API. It will also allocate memory to store the session context.
  13356. + *
  13357. + * Notes: If it is the first perform call for a given session, then a LAC
  13358. + * session is registered. After the session is registered, no checks as
  13359. + * to whether session paramaters have changed (e.g. alg chain order) are
  13360. + * done.
  13361. + */
  13362. +int icp_ocfDrvSymProcess(icp_device_t dev, struct cryptop *crp, int hint)
  13363. +{
  13364. + struct icp_drvSessionData *sessionData = NULL;
  13365. + struct icp_drvOpData *drvOpData = NULL;
  13366. + CpaStatus lacStatus = CPA_STATUS_SUCCESS;
  13367. + Cpa32U sessionCtxSizeInBytes = 0;
  13368. +
  13369. + if (NULL == crp) {
  13370. + DPRINTK("%s(): Invalid input parameters, cryptop is NULL\n",
  13371. + __FUNCTION__);
  13372. + return EINVAL;
  13373. + }
  13374. +
  13375. + if (NULL == crp->crp_desc) {
  13376. + DPRINTK("%s(): Invalid input parameters, no crp_desc attached "
  13377. + "to crp\n", __FUNCTION__);
  13378. + crp->crp_etype = EINVAL;
  13379. + return EINVAL;
  13380. + }
  13381. +
  13382. + if (NULL == crp->crp_buf) {
  13383. + DPRINTK("%s(): Invalid input parameters, no buffer attached "
  13384. + "to crp\n", __FUNCTION__);
  13385. + crp->crp_etype = EINVAL;
  13386. + return EINVAL;
  13387. + }
  13388. +
  13389. + if (CPA_TRUE == icp_atomic_read(&icp_ocfDrvIsExiting)) {
  13390. + crp->crp_etype = EFAULT;
  13391. + return EFAULT;
  13392. + }
  13393. +
  13394. + sessionData = (struct icp_drvSessionData *)
  13395. + (CRYPTO_SESID2LID(crp->crp_sid));
  13396. + if (NULL == sessionData) {
  13397. + DPRINTK("%s(): Invalid input parameters, Null Session ID \n",
  13398. + __FUNCTION__);
  13399. + crp->crp_etype = EINVAL;
  13400. + return EINVAL;
  13401. + }
  13402. +
  13403. +/*If we get a request against a deregisted session, cancel operation*/
  13404. + if (ICP_SESSION_DEREGISTERED == sessionData->inUse) {
  13405. + DPRINTK("%s(): Session ID %d was deregistered \n",
  13406. + __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));
  13407. + crp->crp_etype = EFAULT;
  13408. + return EFAULT;
  13409. + }
  13410. +
  13411. +/*If none of the session states are set, then the session structure was either
  13412. + not initialised properly or we are reading from a freed memory area (possible
  13413. + due to OCF batch mode not removing queued requests against deregistered
  13414. + sessions*/
  13415. + if (ICP_SESSION_INITIALISED != sessionData->inUse &&
  13416. + ICP_SESSION_RUNNING != sessionData->inUse) {
  13417. + DPRINTK("%s(): Session - ID %d - not properly initialised or "
  13418. + "memory freed back to the kernel \n",
  13419. + __FUNCTION__, (int)(CRYPTO_SESID2LID(crp->crp_sid)));
  13420. + crp->crp_etype = EINVAL;
  13421. + return EINVAL;
  13422. + }
  13423. +
  13424. + /*For the below checks, remember error checking is already done in LAC.
  13425. + We're not validating inputs subsequent to registration */
  13426. + if (sessionData->inUse == ICP_SESSION_INITIALISED) {
  13427. + DPRINTK("%s(): Initialising session\n", __FUNCTION__);
  13428. +
  13429. + if (NULL != crp->crp_desc->crd_next) {
  13430. + if (ICP_OCF_DRV_ALG_CIPHER ==
  13431. + icp_ocfDrvAlgCheck(crp->crp_desc)) {
  13432. +
  13433. + sessionData->lacSessCtx.algChainOrder =
  13434. + CPA_CY_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH;
  13435. +
  13436. + if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
  13437. + sessionData->lacSessCtx.cipherSetupData.
  13438. + cipherDirection =
  13439. + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  13440. + } else {
  13441. + sessionData->lacSessCtx.cipherSetupData.
  13442. + cipherDirection =
  13443. + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  13444. + }
  13445. + } else {
  13446. + sessionData->lacSessCtx.algChainOrder =
  13447. + CPA_CY_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER;
  13448. +
  13449. + if (crp->crp_desc->crd_next->crd_flags &
  13450. + CRD_F_ENCRYPT) {
  13451. + sessionData->lacSessCtx.cipherSetupData.
  13452. + cipherDirection =
  13453. + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  13454. + } else {
  13455. + sessionData->lacSessCtx.cipherSetupData.
  13456. + cipherDirection =
  13457. + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  13458. + }
  13459. +
  13460. + }
  13461. +
  13462. + } else if (ICP_OCF_DRV_ALG_CIPHER ==
  13463. + icp_ocfDrvAlgCheck(crp->crp_desc)) {
  13464. + if (crp->crp_desc->crd_flags & CRD_F_ENCRYPT) {
  13465. + sessionData->lacSessCtx.cipherSetupData.
  13466. + cipherDirection =
  13467. + CPA_CY_SYM_CIPHER_DIRECTION_ENCRYPT;
  13468. + } else {
  13469. + sessionData->lacSessCtx.cipherSetupData.
  13470. + cipherDirection =
  13471. + CPA_CY_SYM_CIPHER_DIRECTION_DECRYPT;
  13472. + }
  13473. +
  13474. + }
  13475. +
  13476. + /*No action required for standalone Auth here */
  13477. +
  13478. + /* Allocate memory for SymSessionCtx before the Session Registration */
  13479. + lacStatus =
  13480. + cpaCySymSessionCtxGetSize(CPA_INSTANCE_HANDLE_SINGLE,
  13481. + &(sessionData->lacSessCtx),
  13482. + &sessionCtxSizeInBytes);
  13483. + if (CPA_STATUS_SUCCESS != lacStatus) {
  13484. + EPRINTK("%s(): cpaCySymSessionCtxGetSize failed - %d\n",
  13485. + __FUNCTION__, lacStatus);
  13486. + crp->crp_etype = EINVAL;
  13487. + return EINVAL;
  13488. + }
  13489. + sessionData->sessHandle =
  13490. + icp_kmalloc(sessionCtxSizeInBytes, ICP_M_NOWAIT);
  13491. + if (NULL == sessionData->sessHandle) {
  13492. + EPRINTK
  13493. + ("%s(): Failed to get memory for SymSessionCtx\n",
  13494. + __FUNCTION__);
  13495. + crp->crp_etype = ENOMEM;
  13496. + return ENOMEM;
  13497. + }
  13498. +
  13499. + lacStatus = cpaCySymInitSession(CPA_INSTANCE_HANDLE_SINGLE,
  13500. + icp_ocfDrvSymCallBack,
  13501. + &(sessionData->lacSessCtx),
  13502. + sessionData->sessHandle);
  13503. +
  13504. + if (CPA_STATUS_SUCCESS != lacStatus) {
  13505. + EPRINTK("%s(): cpaCySymInitSession failed -%d \n",
  13506. + __FUNCTION__, lacStatus);
  13507. + crp->crp_etype = EFAULT;
  13508. + return EFAULT;
  13509. + }
  13510. +
  13511. + sessionData->inUse = ICP_SESSION_RUNNING;
  13512. + }
  13513. +
  13514. + drvOpData = icp_kmem_cache_zalloc(drvOpData_zone, ICP_M_NOWAIT);
  13515. + if (NULL == drvOpData) {
  13516. + EPRINTK("%s():Failed to get memory for drvOpData\n",
  13517. + __FUNCTION__);
  13518. + crp->crp_etype = ENOMEM;
  13519. + return ENOMEM;
  13520. + }
  13521. +
  13522. + drvOpData->lacOpData.pSessionCtx = sessionData->sessHandle;
  13523. + drvOpData->digestSizeInBytes = sessionData->lacSessCtx.hashSetupData.
  13524. + digestResultLenInBytes;
  13525. + drvOpData->crp = crp;
  13526. +
  13527. + /* Set the default buffer list array memory allocation */
  13528. + drvOpData->srcBuffer.pBuffers = drvOpData->bufferListArray;
  13529. + drvOpData->numBufferListArray = ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS;
  13530. +
  13531. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  13532. + icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->crp_desc)) {
  13533. + crp->crp_etype = EINVAL;
  13534. + goto err;
  13535. + }
  13536. +
  13537. + if (drvOpData->crp->crp_desc->crd_next != NULL) {
  13538. + if (icp_ocfDrvProcessDataSetup(drvOpData, drvOpData->crp->
  13539. + crp_desc->crd_next)) {
  13540. + crp->crp_etype = EINVAL;
  13541. + goto err;
  13542. + }
  13543. +
  13544. + }
  13545. +
  13546. + /*
  13547. + * Allocate buffer list array memory if the data fragment is more than
  13548. + * the default number (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) and not
  13549. + * calculated already
  13550. + */
  13551. + if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
  13552. + if (NULL == drvOpData->lacOpData.pDigestResult) {
  13553. + drvOpData->numBufferListArray =
  13554. + icp_ocfDrvGetPacketBuffFrags((icp_packet_buffer_t *)
  13555. + crp->crp_buf);
  13556. + }
  13557. +
  13558. + if (ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS <
  13559. + drvOpData->numBufferListArray) {
  13560. + DPRINTK("%s() numBufferListArray more than default\n",
  13561. + __FUNCTION__);
  13562. + drvOpData->srcBuffer.pBuffers = NULL;
  13563. + drvOpData->srcBuffer.pBuffers =
  13564. + icp_kmalloc(drvOpData->numBufferListArray *
  13565. + sizeof(CpaFlatBuffer), ICP_M_NOWAIT);
  13566. + if (NULL == drvOpData->srcBuffer.pBuffers) {
  13567. + EPRINTK("%s() Failed to get memory for "
  13568. + "pBuffers\n", __FUNCTION__);
  13569. + ICP_CACHE_FREE(drvOpData_zone, drvOpData);
  13570. + crp->crp_etype = ENOMEM;
  13571. + return ENOMEM;
  13572. + }
  13573. + }
  13574. + }
  13575. +
  13576. + /*
  13577. + * Check the type of buffer structure we got and convert it into
  13578. + * CpaBufferList format.
  13579. + */
  13580. + if (crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
  13581. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  13582. + icp_ocfDrvPacketBuffToBufferList((icp_packet_buffer_t *)
  13583. + crp->crp_buf,
  13584. + &(drvOpData->srcBuffer))) {
  13585. + EPRINTK("%s():Failed to translate from packet buffer "
  13586. + "to bufferlist\n", __FUNCTION__);
  13587. + crp->crp_etype = EINVAL;
  13588. + goto err;
  13589. + }
  13590. +
  13591. + drvOpData->bufferType = ICP_CRYPTO_F_PACKET_BUF;
  13592. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  13593. + /* OCF only supports IOV of one entry. */
  13594. + if (NUM_IOV_SUPPORTED ==
  13595. + ((struct uio *)(crp->crp_buf))->uio_iovcnt) {
  13596. +
  13597. + icp_ocfDrvPtrAndLenToBufferList(((struct uio *)(crp->
  13598. + crp_buf))->
  13599. + uio_iov[0].iov_base,
  13600. + ((struct uio *)(crp->
  13601. + crp_buf))->
  13602. + uio_iov[0].iov_len,
  13603. + &(drvOpData->
  13604. + srcBuffer));
  13605. +
  13606. + drvOpData->bufferType = CRYPTO_F_IOV;
  13607. +
  13608. + } else {
  13609. + DPRINTK("%s():Unable to handle IOVs with lengths of "
  13610. + "greater than one!\n", __FUNCTION__);
  13611. + crp->crp_etype = EINVAL;
  13612. + goto err;
  13613. + }
  13614. +
  13615. + } else {
  13616. + icp_ocfDrvPtrAndLenToBufferList(crp->crp_buf,
  13617. + crp->crp_ilen,
  13618. + &(drvOpData->srcBuffer));
  13619. +
  13620. + drvOpData->bufferType = CRYPTO_BUF_CONTIG;
  13621. + }
  13622. +
  13623. + /* Allocate srcBuffer's private meta data */
  13624. + if (ICP_OCF_DRV_STATUS_SUCCESS !=
  13625. + icp_ocfDrvAllocMetaData(&(drvOpData->srcBuffer), drvOpData)) {
  13626. + EPRINTK("%s() icp_ocfDrvAllocMetaData failed\n", __FUNCTION__);
  13627. + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  13628. + crp->crp_etype = EINVAL;
  13629. + goto err;
  13630. + }
  13631. +
  13632. + /* Perform "in-place" crypto operation */
  13633. + lacStatus = cpaCySymPerformOp(CPA_INSTANCE_HANDLE_SINGLE,
  13634. + (void *)drvOpData,
  13635. + &(drvOpData->lacOpData),
  13636. + &(drvOpData->srcBuffer),
  13637. + &(drvOpData->srcBuffer),
  13638. + &(drvOpData->verifyResult));
  13639. + if (CPA_STATUS_RETRY == lacStatus) {
  13640. + DPRINTK("%s(): cpaCySymPerformOp retry, lacStatus = %d\n",
  13641. + __FUNCTION__, lacStatus);
  13642. + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  13643. + crp->crp_etype = ERESTART;
  13644. + goto err;
  13645. + }
  13646. + if (CPA_STATUS_SUCCESS != lacStatus) {
  13647. + EPRINTK("%s(): cpaCySymPerformOp failed, lacStatus = %d\n",
  13648. + __FUNCTION__, lacStatus);
  13649. + memset(&(drvOpData->lacOpData), 0, sizeof(CpaCySymOpData));
  13650. + crp->crp_etype = EINVAL;
  13651. + goto err;
  13652. + }
  13653. +
  13654. + return 0; //OCF success status value
  13655. +
  13656. + err:
  13657. + if (drvOpData->numBufferListArray > ICP_OCF_DRV_DEFAULT_BUFFLIST_ARRAYS) {
  13658. + icp_kfree(drvOpData->srcBuffer.pBuffers);
  13659. + }
  13660. + icp_ocfDrvFreeMetaData(&(drvOpData->srcBuffer));
  13661. + ICP_CACHE_FREE(drvOpData_zone, drvOpData);
  13662. +
  13663. + return crp->crp_etype;
  13664. +}
  13665. +
  13666. +/* Name : icp_ocfDrvProcessDataSetup
  13667. + *
  13668. + * Description : This function will setup all the cryptographic operation data
  13669. + * that is required by LAC to execute the operation.
  13670. + */
  13671. +static int icp_ocfDrvProcessDataSetup(struct icp_drvOpData *drvOpData,
  13672. + struct cryptodesc *crp_desc)
  13673. +{
  13674. + CpaCyRandGenOpData randGenOpData;
  13675. + CpaFlatBuffer randData;
  13676. +
  13677. + drvOpData->lacOpData.packetType = CPA_CY_SYM_PACKET_TYPE_FULL;
  13678. +
  13679. + /* Convert from the cryptop to the ICP LAC crypto parameters */
  13680. + switch (crp_desc->crd_alg) {
  13681. + case CRYPTO_NULL_CBC:
  13682. + drvOpData->lacOpData.
  13683. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  13684. + drvOpData->lacOpData.
  13685. + messageLenToCipherInBytes = crp_desc->crd_len;
  13686. + drvOpData->verifyResult = CPA_FALSE;
  13687. + drvOpData->lacOpData.ivLenInBytes = NULL_BLOCK_LEN;
  13688. + break;
  13689. + case CRYPTO_DES_CBC:
  13690. + drvOpData->lacOpData.
  13691. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  13692. + drvOpData->lacOpData.
  13693. + messageLenToCipherInBytes = crp_desc->crd_len;
  13694. + drvOpData->verifyResult = CPA_FALSE;
  13695. + drvOpData->lacOpData.ivLenInBytes = DES_BLOCK_LEN;
  13696. + break;
  13697. + case CRYPTO_3DES_CBC:
  13698. + drvOpData->lacOpData.
  13699. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  13700. + drvOpData->lacOpData.
  13701. + messageLenToCipherInBytes = crp_desc->crd_len;
  13702. + drvOpData->verifyResult = CPA_FALSE;
  13703. + drvOpData->lacOpData.ivLenInBytes = DES3_BLOCK_LEN;
  13704. + break;
  13705. + case CRYPTO_ARC4:
  13706. + drvOpData->lacOpData.
  13707. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  13708. + drvOpData->lacOpData.
  13709. + messageLenToCipherInBytes = crp_desc->crd_len;
  13710. + drvOpData->verifyResult = CPA_FALSE;
  13711. + drvOpData->lacOpData.ivLenInBytes = ARC4_COUNTER_LEN;
  13712. + break;
  13713. + case CRYPTO_AES_CBC:
  13714. + drvOpData->lacOpData.
  13715. + cryptoStartSrcOffsetInBytes = crp_desc->crd_skip;
  13716. + drvOpData->lacOpData.
  13717. + messageLenToCipherInBytes = crp_desc->crd_len;
  13718. + drvOpData->verifyResult = CPA_FALSE;
  13719. + drvOpData->lacOpData.ivLenInBytes = RIJNDAEL128_BLOCK_LEN;
  13720. + break;
  13721. + case CRYPTO_SHA1:
  13722. + case CRYPTO_SHA1_HMAC:
  13723. + case CRYPTO_SHA2_256:
  13724. + case CRYPTO_SHA2_256_HMAC:
  13725. + case CRYPTO_SHA2_384:
  13726. + case CRYPTO_SHA2_384_HMAC:
  13727. + case CRYPTO_SHA2_512:
  13728. + case CRYPTO_SHA2_512_HMAC:
  13729. + case CRYPTO_MD5:
  13730. + case CRYPTO_MD5_HMAC:
  13731. + drvOpData->lacOpData.
  13732. + hashStartSrcOffsetInBytes = crp_desc->crd_skip;
  13733. + drvOpData->lacOpData.
  13734. + messageLenToHashInBytes = crp_desc->crd_len;
  13735. + drvOpData->lacOpData.
  13736. + pDigestResult =
  13737. + icp_ocfDrvDigestPointerFind(drvOpData, crp_desc);
  13738. +
  13739. + if (NULL == drvOpData->lacOpData.pDigestResult) {
  13740. + DPRINTK("%s(): ERROR - could not calculate "
  13741. + "Digest Result memory address\n", __FUNCTION__);
  13742. + return ICP_OCF_DRV_STATUS_FAIL;
  13743. + }
  13744. +
  13745. + drvOpData->lacOpData.digestVerify = CPA_FALSE;
  13746. + break;
  13747. + default:
  13748. + DPRINTK("%s(): Crypto process error - algorithm not "
  13749. + "found \n", __FUNCTION__);
  13750. + return ICP_OCF_DRV_STATUS_FAIL;
  13751. + }
  13752. +
  13753. + /* Figure out what the IV is supposed to be */
  13754. + if ((crp_desc->crd_alg == CRYPTO_DES_CBC) ||
  13755. + (crp_desc->crd_alg == CRYPTO_3DES_CBC) ||
  13756. + (crp_desc->crd_alg == CRYPTO_AES_CBC)) {
  13757. + /*ARC4 doesn't use an IV */
  13758. + if (crp_desc->crd_flags & CRD_F_IV_EXPLICIT) {
  13759. + /* Explicit IV provided to OCF */
  13760. + drvOpData->lacOpData.pIv = crp_desc->crd_iv;
  13761. + } else {
  13762. + /* IV is not explicitly provided to OCF */
  13763. +
  13764. + /* Point the LAC OP Data IV pointer to our allocated
  13765. + storage location for this session. */
  13766. + drvOpData->lacOpData.pIv = drvOpData->ivData;
  13767. +
  13768. + if ((crp_desc->crd_flags & CRD_F_ENCRYPT) &&
  13769. + ((crp_desc->crd_flags & CRD_F_IV_PRESENT) == 0)) {
  13770. +
  13771. + /* Encrypting - need to create IV */
  13772. + randGenOpData.generateBits = CPA_TRUE;
  13773. + randGenOpData.lenInBytes = MAX_IV_LEN_IN_BYTES;
  13774. +
  13775. + icp_ocfDrvPtrAndLenToFlatBuffer((Cpa8U *)
  13776. + drvOpData->
  13777. + ivData,
  13778. + MAX_IV_LEN_IN_BYTES,
  13779. + &randData);
  13780. +
  13781. + if (CPA_STATUS_SUCCESS !=
  13782. + cpaCyRandGen(CPA_INSTANCE_HANDLE_SINGLE,
  13783. + NULL, NULL,
  13784. + &randGenOpData, &randData)) {
  13785. + DPRINTK("%s(): ERROR - Failed to"
  13786. + " generate"
  13787. + " Initialisation Vector\n",
  13788. + __FUNCTION__);
  13789. + return ICP_OCF_DRV_STATUS_FAIL;
  13790. + }
  13791. +
  13792. + crypto_copyback(drvOpData->crp->
  13793. + crp_flags,
  13794. + drvOpData->crp->crp_buf,
  13795. + crp_desc->crd_inject,
  13796. + drvOpData->lacOpData.
  13797. + ivLenInBytes,
  13798. + (caddr_t) (drvOpData->lacOpData.
  13799. + pIv));
  13800. + } else {
  13801. + /* Reading IV from buffer */
  13802. + crypto_copydata(drvOpData->crp->
  13803. + crp_flags,
  13804. + drvOpData->crp->crp_buf,
  13805. + crp_desc->crd_inject,
  13806. + drvOpData->lacOpData.
  13807. + ivLenInBytes,
  13808. + (caddr_t) (drvOpData->lacOpData.
  13809. + pIv));
  13810. + }
  13811. +
  13812. + }
  13813. +
  13814. + }
  13815. +
  13816. + return ICP_OCF_DRV_STATUS_SUCCESS;
  13817. +}
  13818. +
  13819. +/* Name : icp_ocfDrvDigestPointerFind
  13820. + *
  13821. + * Description : This function is used to find the memory address of where the
  13822. + * digest information shall be stored in. Input buffer types are an skbuff, iov
  13823. + * or flat buffer. The address is found using the buffer data start address and
  13824. + * an offset.
  13825. + *
  13826. + * Note: In the case of a linux skbuff, the digest address may exist within
  13827. + * a memory space linked to from the start buffer. These linked memory spaces
  13828. + * must be traversed by the data length offset in order to find the digest start
  13829. + * address. Whether there is enough space for the digest must also be checked.
  13830. + */
  13831. +uint8_t *icp_ocfDrvDigestPointerFind(struct icp_drvOpData * drvOpData,
  13832. + struct cryptodesc * crp_desc)
  13833. +{
  13834. +
  13835. + int offsetInBytes = crp_desc->crd_inject;
  13836. + uint32_t digestSizeInBytes = drvOpData->digestSizeInBytes;
  13837. + uint8_t *flat_buffer_base = NULL;
  13838. + int flat_buffer_length = 0;
  13839. +
  13840. + if (drvOpData->crp->crp_flags & ICP_CRYPTO_F_PACKET_BUF) {
  13841. +
  13842. + return icp_ocfDrvPacketBufferDigestPointerFind(drvOpData,
  13843. + offsetInBytes,
  13844. + digestSizeInBytes);
  13845. +
  13846. + } else {
  13847. + /* IOV or flat buffer */
  13848. + if (drvOpData->crp->crp_flags & CRYPTO_F_IOV) {
  13849. + /*single IOV check has already been done */
  13850. + flat_buffer_base = ((struct uio *)
  13851. + (drvOpData->crp->crp_buf))->
  13852. + uio_iov[0].iov_base;
  13853. + flat_buffer_length = ((struct uio *)
  13854. + (drvOpData->crp->crp_buf))->
  13855. + uio_iov[0].iov_len;
  13856. + } else {
  13857. + flat_buffer_base = (uint8_t *) drvOpData->crp->crp_buf;
  13858. + flat_buffer_length = drvOpData->crp->crp_ilen;
  13859. + }
  13860. +
  13861. + if (flat_buffer_length < (offsetInBytes + digestSizeInBytes)) {
  13862. + DPRINTK("%s() Not enough space for Digest "
  13863. + "(IOV/Flat Buffer) \n", __FUNCTION__);
  13864. + return NULL;
  13865. + } else {
  13866. + return (uint8_t *) (flat_buffer_base + offsetInBytes);
  13867. + }
  13868. + }
  13869. + DPRINTK("%s() Should not reach this point\n", __FUNCTION__);
  13870. + return NULL;
  13871. +}
  13872. diff -Nur linux-2.6.39.orig/crypto/ocf/hifn/Makefile linux-2.6.39/crypto/ocf/hifn/Makefile
  13873. --- linux-2.6.39.orig/crypto/ocf/hifn/Makefile 1970-01-01 01:00:00.000000000 +0100
  13874. +++ linux-2.6.39/crypto/ocf/hifn/Makefile 2011-08-01 14:38:18.000000000 +0200
  13875. @@ -0,0 +1,13 @@
  13876. +# for SGlinux builds
  13877. +-include $(ROOTDIR)/modules/.config
  13878. +
  13879. +obj-$(CONFIG_OCF_HIFN) += hifn7751.o
  13880. +obj-$(CONFIG_OCF_HIFNHIPP) += hifnHIPP.o
  13881. +
  13882. +obj ?= .
  13883. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  13884. +
  13885. +ifdef TOPDIR
  13886. +-include $(TOPDIR)/Rules.make
  13887. +endif
  13888. +
  13889. diff -Nur linux-2.6.39.orig/crypto/ocf/hifn/hifn7751.c linux-2.6.39/crypto/ocf/hifn/hifn7751.c
  13890. --- linux-2.6.39.orig/crypto/ocf/hifn/hifn7751.c 1970-01-01 01:00:00.000000000 +0100
  13891. +++ linux-2.6.39/crypto/ocf/hifn/hifn7751.c 2011-08-01 14:39:27.000000000 +0200
  13892. @@ -0,0 +1,2973 @@
  13893. +/* $OpenBSD: hifn7751.c,v 1.120 2002/05/17 00:33:34 deraadt Exp $ */
  13894. +
  13895. +/*-
  13896. + * Invertex AEON / Hifn 7751 driver
  13897. + * Copyright (c) 1999 Invertex Inc. All rights reserved.
  13898. + * Copyright (c) 1999 Theo de Raadt
  13899. + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  13900. + * http://www.netsec.net
  13901. + * Copyright (c) 2003 Hifn Inc.
  13902. + *
  13903. + * This driver is based on a previous driver by Invertex, for which they
  13904. + * requested: Please send any comments, feedback, bug-fixes, or feature
  13905. + * requests to software@invertex.com.
  13906. + *
  13907. + * Redistribution and use in source and binary forms, with or without
  13908. + * modification, are permitted provided that the following conditions
  13909. + * are met:
  13910. + *
  13911. + * 1. Redistributions of source code must retain the above copyright
  13912. + * notice, this list of conditions and the following disclaimer.
  13913. + * 2. Redistributions in binary form must reproduce the above copyright
  13914. + * notice, this list of conditions and the following disclaimer in the
  13915. + * documentation and/or other materials provided with the distribution.
  13916. + * 3. The name of the author may not be used to endorse or promote products
  13917. + * derived from this software without specific prior written permission.
  13918. + *
  13919. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  13920. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  13921. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  13922. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  13923. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  13924. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  13925. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  13926. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  13927. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  13928. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  13929. + *
  13930. + * Effort sponsored in part by the Defense Advanced Research Projects
  13931. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  13932. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  13933. + *
  13934. + *
  13935. +__FBSDID("$FreeBSD: src/sys/dev/hifn/hifn7751.c,v 1.40 2007/03/21 03:42:49 sam Exp $");
  13936. + */
  13937. +
  13938. +/*
  13939. + * Driver for various Hifn encryption processors.
  13940. + */
  13941. +#include <linux/module.h>
  13942. +#include <linux/init.h>
  13943. +#include <linux/list.h>
  13944. +#include <linux/slab.h>
  13945. +#include <linux/wait.h>
  13946. +#include <linux/sched.h>
  13947. +#include <linux/pci.h>
  13948. +#include <linux/delay.h>
  13949. +#include <linux/interrupt.h>
  13950. +#include <linux/spinlock.h>
  13951. +#include <linux/random.h>
  13952. +#include <linux/version.h>
  13953. +#include <linux/skbuff.h>
  13954. +#include <asm/io.h>
  13955. +
  13956. +#include <cryptodev.h>
  13957. +#include <uio.h>
  13958. +#include <hifn/hifn7751reg.h>
  13959. +#include <hifn/hifn7751var.h>
  13960. +
  13961. +#if 1
  13962. +#define DPRINTF(a...) if (hifn_debug) { \
  13963. + printk("%s: ", sc ? \
  13964. + device_get_nameunit(sc->sc_dev) : "hifn"); \
  13965. + printk(a); \
  13966. + } else
  13967. +#else
  13968. +#define DPRINTF(a...)
  13969. +#endif
  13970. +
  13971. +static inline int
  13972. +pci_get_revid(struct pci_dev *dev)
  13973. +{
  13974. + u8 rid = 0;
  13975. + pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
  13976. + return rid;
  13977. +}
  13978. +
  13979. +static struct hifn_stats hifnstats;
  13980. +
  13981. +#define debug hifn_debug
  13982. +int hifn_debug = 0;
  13983. +module_param(hifn_debug, int, 0644);
  13984. +MODULE_PARM_DESC(hifn_debug, "Enable debug");
  13985. +
  13986. +int hifn_maxbatch = 1;
  13987. +module_param(hifn_maxbatch, int, 0644);
  13988. +MODULE_PARM_DESC(hifn_maxbatch, "max ops to batch w/o interrupt");
  13989. +
  13990. +int hifn_cache_linesize = 0x10;
  13991. +module_param(hifn_cache_linesize, int, 0444);
  13992. +MODULE_PARM_DESC(hifn_cache_linesize, "PCI config cache line size");
  13993. +
  13994. +#ifdef MODULE_PARM
  13995. +char *hifn_pllconfig = NULL;
  13996. +MODULE_PARM(hifn_pllconfig, "s");
  13997. +#else
  13998. +char hifn_pllconfig[32]; /* This setting is RO after loading */
  13999. +module_param_string(hifn_pllconfig, hifn_pllconfig, 32, 0444);
  14000. +#endif
  14001. +MODULE_PARM_DESC(hifn_pllconfig, "PLL config, ie., pci66, ext33, ...");
  14002. +
  14003. +#ifdef HIFN_VULCANDEV
  14004. +#include <sys/conf.h>
  14005. +#include <sys/uio.h>
  14006. +
  14007. +static struct cdevsw vulcanpk_cdevsw; /* forward declaration */
  14008. +#endif
  14009. +
  14010. +/*
  14011. + * Prototypes and count for the pci_device structure
  14012. + */
  14013. +static int hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent);
  14014. +static void hifn_remove(struct pci_dev *dev);
  14015. +
  14016. +static int hifn_newsession(device_t, u_int32_t *, struct cryptoini *);
  14017. +static int hifn_freesession(device_t, u_int64_t);
  14018. +static int hifn_process(device_t, struct cryptop *, int);
  14019. +
  14020. +static device_method_t hifn_methods = {
  14021. + /* crypto device methods */
  14022. + DEVMETHOD(cryptodev_newsession, hifn_newsession),
  14023. + DEVMETHOD(cryptodev_freesession,hifn_freesession),
  14024. + DEVMETHOD(cryptodev_process, hifn_process),
  14025. +};
  14026. +
  14027. +static void hifn_reset_board(struct hifn_softc *, int);
  14028. +static void hifn_reset_puc(struct hifn_softc *);
  14029. +static void hifn_puc_wait(struct hifn_softc *);
  14030. +static int hifn_enable_crypto(struct hifn_softc *);
  14031. +static void hifn_set_retry(struct hifn_softc *sc);
  14032. +static void hifn_init_dma(struct hifn_softc *);
  14033. +static void hifn_init_pci_registers(struct hifn_softc *);
  14034. +static int hifn_sramsize(struct hifn_softc *);
  14035. +static int hifn_dramsize(struct hifn_softc *);
  14036. +static int hifn_ramtype(struct hifn_softc *);
  14037. +static void hifn_sessions(struct hifn_softc *);
  14038. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  14039. +static irqreturn_t hifn_intr(int irq, void *arg);
  14040. +#else
  14041. +static irqreturn_t hifn_intr(int irq, void *arg, struct pt_regs *regs);
  14042. +#endif
  14043. +static u_int hifn_write_command(struct hifn_command *, u_int8_t *);
  14044. +static u_int32_t hifn_next_signature(u_int32_t a, u_int cnt);
  14045. +static void hifn_callback(struct hifn_softc *, struct hifn_command *, u_int8_t *);
  14046. +static int hifn_crypto(struct hifn_softc *, struct hifn_command *, struct cryptop *, int);
  14047. +static int hifn_readramaddr(struct hifn_softc *, int, u_int8_t *);
  14048. +static int hifn_writeramaddr(struct hifn_softc *, int, u_int8_t *);
  14049. +static int hifn_dmamap_load_src(struct hifn_softc *, struct hifn_command *);
  14050. +static int hifn_dmamap_load_dst(struct hifn_softc *, struct hifn_command *);
  14051. +static int hifn_init_pubrng(struct hifn_softc *);
  14052. +static void hifn_tick(unsigned long arg);
  14053. +static void hifn_abort(struct hifn_softc *);
  14054. +static void hifn_alloc_slot(struct hifn_softc *, int *, int *, int *, int *);
  14055. +
  14056. +static void hifn_write_reg_0(struct hifn_softc *, bus_size_t, u_int32_t);
  14057. +static void hifn_write_reg_1(struct hifn_softc *, bus_size_t, u_int32_t);
  14058. +
  14059. +#ifdef CONFIG_OCF_RANDOMHARVEST
  14060. +static int hifn_read_random(void *arg, u_int32_t *buf, int len);
  14061. +#endif
  14062. +
  14063. +#define HIFN_MAX_CHIPS 8
  14064. +static struct hifn_softc *hifn_chip_idx[HIFN_MAX_CHIPS];
  14065. +
  14066. +static __inline u_int32_t
  14067. +READ_REG_0(struct hifn_softc *sc, bus_size_t reg)
  14068. +{
  14069. + u_int32_t v = readl(sc->sc_bar0 + reg);
  14070. + sc->sc_bar0_lastreg = (bus_size_t) -1;
  14071. + return (v);
  14072. +}
  14073. +#define WRITE_REG_0(sc, reg, val) hifn_write_reg_0(sc, reg, val)
  14074. +
  14075. +static __inline u_int32_t
  14076. +READ_REG_1(struct hifn_softc *sc, bus_size_t reg)
  14077. +{
  14078. + u_int32_t v = readl(sc->sc_bar1 + reg);
  14079. + sc->sc_bar1_lastreg = (bus_size_t) -1;
  14080. + return (v);
  14081. +}
  14082. +#define WRITE_REG_1(sc, reg, val) hifn_write_reg_1(sc, reg, val)
  14083. +
  14084. +/*
  14085. + * map in a given buffer (great on some arches :-)
  14086. + */
  14087. +
  14088. +static int
  14089. +pci_map_uio(struct hifn_softc *sc, struct hifn_operand *buf, struct uio *uio)
  14090. +{
  14091. + struct iovec *iov = uio->uio_iov;
  14092. +
  14093. + DPRINTF("%s()\n", __FUNCTION__);
  14094. +
  14095. + buf->mapsize = 0;
  14096. + for (buf->nsegs = 0; buf->nsegs < uio->uio_iovcnt; ) {
  14097. + buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
  14098. + iov->iov_base, iov->iov_len,
  14099. + PCI_DMA_BIDIRECTIONAL);
  14100. + buf->segs[buf->nsegs].ds_len = iov->iov_len;
  14101. + buf->mapsize += iov->iov_len;
  14102. + iov++;
  14103. + buf->nsegs++;
  14104. + }
  14105. + /* identify this buffer by the first segment */
  14106. + buf->map = (void *) buf->segs[0].ds_addr;
  14107. + return(0);
  14108. +}
  14109. +
  14110. +/*
  14111. + * map in a given sk_buff
  14112. + */
  14113. +
  14114. +static int
  14115. +pci_map_skb(struct hifn_softc *sc,struct hifn_operand *buf,struct sk_buff *skb)
  14116. +{
  14117. + int i;
  14118. +
  14119. + DPRINTF("%s()\n", __FUNCTION__);
  14120. +
  14121. + buf->mapsize = 0;
  14122. +
  14123. + buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
  14124. + skb->data, skb_headlen(skb), PCI_DMA_BIDIRECTIONAL);
  14125. + buf->segs[0].ds_len = skb_headlen(skb);
  14126. + buf->mapsize += buf->segs[0].ds_len;
  14127. +
  14128. + buf->nsegs = 1;
  14129. +
  14130. + for (i = 0; i < skb_shinfo(skb)->nr_frags; ) {
  14131. + buf->segs[buf->nsegs].ds_len = skb_shinfo(skb)->frags[i].size;
  14132. + buf->segs[buf->nsegs].ds_addr = pci_map_single(sc->sc_pcidev,
  14133. + page_address(skb_shinfo(skb)->frags[i].page) +
  14134. + skb_shinfo(skb)->frags[i].page_offset,
  14135. + buf->segs[buf->nsegs].ds_len, PCI_DMA_BIDIRECTIONAL);
  14136. + buf->mapsize += buf->segs[buf->nsegs].ds_len;
  14137. + buf->nsegs++;
  14138. + }
  14139. +
  14140. + /* identify this buffer by the first segment */
  14141. + buf->map = (void *) buf->segs[0].ds_addr;
  14142. + return(0);
  14143. +}
  14144. +
  14145. +/*
  14146. + * map in a given contiguous buffer
  14147. + */
  14148. +
  14149. +static int
  14150. +pci_map_buf(struct hifn_softc *sc,struct hifn_operand *buf, void *b, int len)
  14151. +{
  14152. + DPRINTF("%s()\n", __FUNCTION__);
  14153. +
  14154. + buf->mapsize = 0;
  14155. + buf->segs[0].ds_addr = pci_map_single(sc->sc_pcidev,
  14156. + b, len, PCI_DMA_BIDIRECTIONAL);
  14157. + buf->segs[0].ds_len = len;
  14158. + buf->mapsize += buf->segs[0].ds_len;
  14159. + buf->nsegs = 1;
  14160. +
  14161. + /* identify this buffer by the first segment */
  14162. + buf->map = (void *) buf->segs[0].ds_addr;
  14163. + return(0);
  14164. +}
  14165. +
  14166. +#if 0 /* not needed at this time */
  14167. +static void
  14168. +pci_sync_iov(struct hifn_softc *sc, struct hifn_operand *buf)
  14169. +{
  14170. + int i;
  14171. +
  14172. + DPRINTF("%s()\n", __FUNCTION__);
  14173. + for (i = 0; i < buf->nsegs; i++)
  14174. + pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
  14175. + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
  14176. +}
  14177. +#endif
  14178. +
  14179. +static void
  14180. +pci_unmap_buf(struct hifn_softc *sc, struct hifn_operand *buf)
  14181. +{
  14182. + int i;
  14183. + DPRINTF("%s()\n", __FUNCTION__);
  14184. + for (i = 0; i < buf->nsegs; i++) {
  14185. + pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
  14186. + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
  14187. + buf->segs[i].ds_addr = 0;
  14188. + buf->segs[i].ds_len = 0;
  14189. + }
  14190. + buf->nsegs = 0;
  14191. + buf->mapsize = 0;
  14192. + buf->map = 0;
  14193. +}
  14194. +
  14195. +static const char*
  14196. +hifn_partname(struct hifn_softc *sc)
  14197. +{
  14198. + /* XXX sprintf numbers when not decoded */
  14199. + switch (pci_get_vendor(sc->sc_pcidev)) {
  14200. + case PCI_VENDOR_HIFN:
  14201. + switch (pci_get_device(sc->sc_pcidev)) {
  14202. + case PCI_PRODUCT_HIFN_6500: return "Hifn 6500";
  14203. + case PCI_PRODUCT_HIFN_7751: return "Hifn 7751";
  14204. + case PCI_PRODUCT_HIFN_7811: return "Hifn 7811";
  14205. + case PCI_PRODUCT_HIFN_7951: return "Hifn 7951";
  14206. + case PCI_PRODUCT_HIFN_7955: return "Hifn 7955";
  14207. + case PCI_PRODUCT_HIFN_7956: return "Hifn 7956";
  14208. + }
  14209. + return "Hifn unknown-part";
  14210. + case PCI_VENDOR_INVERTEX:
  14211. + switch (pci_get_device(sc->sc_pcidev)) {
  14212. + case PCI_PRODUCT_INVERTEX_AEON: return "Invertex AEON";
  14213. + }
  14214. + return "Invertex unknown-part";
  14215. + case PCI_VENDOR_NETSEC:
  14216. + switch (pci_get_device(sc->sc_pcidev)) {
  14217. + case PCI_PRODUCT_NETSEC_7751: return "NetSec 7751";
  14218. + }
  14219. + return "NetSec unknown-part";
  14220. + }
  14221. + return "Unknown-vendor unknown-part";
  14222. +}
  14223. +
  14224. +static u_int
  14225. +checkmaxmin(struct pci_dev *dev, const char *what, u_int v, u_int min, u_int max)
  14226. +{
  14227. + struct hifn_softc *sc = pci_get_drvdata(dev);
  14228. + if (v > max) {
  14229. + device_printf(sc->sc_dev, "Warning, %s %u out of range, "
  14230. + "using max %u\n", what, v, max);
  14231. + v = max;
  14232. + } else if (v < min) {
  14233. + device_printf(sc->sc_dev, "Warning, %s %u out of range, "
  14234. + "using min %u\n", what, v, min);
  14235. + v = min;
  14236. + }
  14237. + return v;
  14238. +}
  14239. +
  14240. +/*
  14241. + * Select PLL configuration for 795x parts. This is complicated in
  14242. + * that we cannot determine the optimal parameters without user input.
  14243. + * The reference clock is derived from an external clock through a
  14244. + * multiplier. The external clock is either the host bus (i.e. PCI)
  14245. + * or an external clock generator. When using the PCI bus we assume
  14246. + * the clock is either 33 or 66 MHz; for an external source we cannot
  14247. + * tell the speed.
  14248. + *
  14249. + * PLL configuration is done with a string: "pci" for PCI bus, or "ext"
  14250. + * for an external source, followed by the frequency. We calculate
  14251. + * the appropriate multiplier and PLL register contents accordingly.
  14252. + * When no configuration is given we default to "pci66" since that
  14253. + * always will allow the card to work. If a card is using the PCI
  14254. + * bus clock and in a 33MHz slot then it will be operating at half
  14255. + * speed until the correct information is provided.
  14256. + *
  14257. + * We use a default setting of "ext66" because according to Mike Ham
  14258. + * of HiFn, almost every board in existence has an external crystal
  14259. + * populated at 66Mhz. Using PCI can be a problem on modern motherboards,
  14260. + * because PCI33 can have clocks from 0 to 33Mhz, and some have
  14261. + * non-PCI-compliant spread-spectrum clocks, which can confuse the pll.
  14262. + */
  14263. +static void
  14264. +hifn_getpllconfig(struct pci_dev *dev, u_int *pll)
  14265. +{
  14266. + const char *pllspec = hifn_pllconfig;
  14267. + u_int freq, mul, fl, fh;
  14268. + u_int32_t pllconfig;
  14269. + char *nxt;
  14270. +
  14271. + if (pllspec == NULL)
  14272. + pllspec = "ext66";
  14273. + fl = 33, fh = 66;
  14274. + pllconfig = 0;
  14275. + if (strncmp(pllspec, "ext", 3) == 0) {
  14276. + pllspec += 3;
  14277. + pllconfig |= HIFN_PLL_REF_SEL;
  14278. + switch (pci_get_device(dev)) {
  14279. + case PCI_PRODUCT_HIFN_7955:
  14280. + case PCI_PRODUCT_HIFN_7956:
  14281. + fl = 20, fh = 100;
  14282. + break;
  14283. +#ifdef notyet
  14284. + case PCI_PRODUCT_HIFN_7954:
  14285. + fl = 20, fh = 66;
  14286. + break;
  14287. +#endif
  14288. + }
  14289. + } else if (strncmp(pllspec, "pci", 3) == 0)
  14290. + pllspec += 3;
  14291. + freq = strtoul(pllspec, &nxt, 10);
  14292. + if (nxt == pllspec)
  14293. + freq = 66;
  14294. + else
  14295. + freq = checkmaxmin(dev, "frequency", freq, fl, fh);
  14296. + /*
  14297. + * Calculate multiplier. We target a Fck of 266 MHz,
  14298. + * allowing only even values, possibly rounded down.
  14299. + * Multipliers > 8 must set the charge pump current.
  14300. + */
  14301. + mul = checkmaxmin(dev, "PLL divisor", (266 / freq) &~ 1, 2, 12);
  14302. + pllconfig |= (mul / 2 - 1) << HIFN_PLL_ND_SHIFT;
  14303. + if (mul > 8)
  14304. + pllconfig |= HIFN_PLL_IS;
  14305. + *pll = pllconfig;
  14306. +}
  14307. +
  14308. +/*
  14309. + * Attach an interface that successfully probed.
  14310. + */
  14311. +static int
  14312. +hifn_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  14313. +{
  14314. + struct hifn_softc *sc = NULL;
  14315. + char rbase;
  14316. + u_int16_t ena, rev;
  14317. + int rseg, rc;
  14318. + unsigned long mem_start, mem_len;
  14319. + static int num_chips = 0;
  14320. +
  14321. + DPRINTF("%s()\n", __FUNCTION__);
  14322. +
  14323. + if (pci_enable_device(dev) < 0)
  14324. + return(-ENODEV);
  14325. +
  14326. + if (pci_set_mwi(dev))
  14327. + return(-ENODEV);
  14328. +
  14329. + if (!dev->irq) {
  14330. + printk("hifn: found device with no IRQ assigned. check BIOS settings!");
  14331. + pci_disable_device(dev);
  14332. + return(-ENODEV);
  14333. + }
  14334. +
  14335. + sc = (struct hifn_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  14336. + if (!sc)
  14337. + return(-ENOMEM);
  14338. + memset(sc, 0, sizeof(*sc));
  14339. +
  14340. + softc_device_init(sc, "hifn", num_chips, hifn_methods);
  14341. +
  14342. + sc->sc_pcidev = dev;
  14343. + sc->sc_irq = -1;
  14344. + sc->sc_cid = -1;
  14345. + sc->sc_num = num_chips++;
  14346. + if (sc->sc_num < HIFN_MAX_CHIPS)
  14347. + hifn_chip_idx[sc->sc_num] = sc;
  14348. +
  14349. + pci_set_drvdata(sc->sc_pcidev, sc);
  14350. +
  14351. + spin_lock_init(&sc->sc_mtx);
  14352. +
  14353. + /* XXX handle power management */
  14354. +
  14355. + /*
  14356. + * The 7951 and 795x have a random number generator and
  14357. + * public key support; note this.
  14358. + */
  14359. + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
  14360. + (pci_get_device(dev) == PCI_PRODUCT_HIFN_7951 ||
  14361. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
  14362. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7956))
  14363. + sc->sc_flags = HIFN_HAS_RNG | HIFN_HAS_PUBLIC;
  14364. + /*
  14365. + * The 7811 has a random number generator and
  14366. + * we also note it's identity 'cuz of some quirks.
  14367. + */
  14368. + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
  14369. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7811)
  14370. + sc->sc_flags |= HIFN_IS_7811 | HIFN_HAS_RNG;
  14371. +
  14372. + /*
  14373. + * The 795x parts support AES.
  14374. + */
  14375. + if (pci_get_vendor(dev) == PCI_VENDOR_HIFN &&
  14376. + (pci_get_device(dev) == PCI_PRODUCT_HIFN_7955 ||
  14377. + pci_get_device(dev) == PCI_PRODUCT_HIFN_7956)) {
  14378. + sc->sc_flags |= HIFN_IS_7956 | HIFN_HAS_AES;
  14379. + /*
  14380. + * Select PLL configuration. This depends on the
  14381. + * bus and board design and must be manually configured
  14382. + * if the default setting is unacceptable.
  14383. + */
  14384. + hifn_getpllconfig(dev, &sc->sc_pllconfig);
  14385. + }
  14386. +
  14387. + /*
  14388. + * Setup PCI resources. Note that we record the bus
  14389. + * tag and handle for each register mapping, this is
  14390. + * used by the READ_REG_0, WRITE_REG_0, READ_REG_1,
  14391. + * and WRITE_REG_1 macros throughout the driver.
  14392. + */
  14393. + mem_start = pci_resource_start(sc->sc_pcidev, 0);
  14394. + mem_len = pci_resource_len(sc->sc_pcidev, 0);
  14395. + sc->sc_bar0 = (ocf_iomem_t) ioremap(mem_start, mem_len);
  14396. + if (!sc->sc_bar0) {
  14397. + device_printf(sc->sc_dev, "cannot map bar%d register space\n", 0);
  14398. + goto fail;
  14399. + }
  14400. + sc->sc_bar0_lastreg = (bus_size_t) -1;
  14401. +
  14402. + mem_start = pci_resource_start(sc->sc_pcidev, 1);
  14403. + mem_len = pci_resource_len(sc->sc_pcidev, 1);
  14404. + sc->sc_bar1 = (ocf_iomem_t) ioremap(mem_start, mem_len);
  14405. + if (!sc->sc_bar1) {
  14406. + device_printf(sc->sc_dev, "cannot map bar%d register space\n", 1);
  14407. + goto fail;
  14408. + }
  14409. + sc->sc_bar1_lastreg = (bus_size_t) -1;
  14410. +
  14411. + /* fix up the bus size */
  14412. + if (pci_set_dma_mask(dev, DMA_32BIT_MASK)) {
  14413. + device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
  14414. + goto fail;
  14415. + }
  14416. + if (pci_set_consistent_dma_mask(dev, DMA_32BIT_MASK)) {
  14417. + device_printf(sc->sc_dev,
  14418. + "No usable consistent DMA configuration, aborting.\n");
  14419. + goto fail;
  14420. + }
  14421. +
  14422. + hifn_set_retry(sc);
  14423. +
  14424. + /*
  14425. + * Setup the area where the Hifn DMA's descriptors
  14426. + * and associated data structures.
  14427. + */
  14428. + sc->sc_dma = (struct hifn_dma *) pci_alloc_consistent(dev,
  14429. + sizeof(*sc->sc_dma),
  14430. + &sc->sc_dma_physaddr);
  14431. + if (!sc->sc_dma) {
  14432. + device_printf(sc->sc_dev, "cannot alloc sc_dma\n");
  14433. + goto fail;
  14434. + }
  14435. + bzero(sc->sc_dma, sizeof(*sc->sc_dma));
  14436. +
  14437. + /*
  14438. + * Reset the board and do the ``secret handshake''
  14439. + * to enable the crypto support. Then complete the
  14440. + * initialization procedure by setting up the interrupt
  14441. + * and hooking in to the system crypto support so we'll
  14442. + * get used for system services like the crypto device,
  14443. + * IPsec, RNG device, etc.
  14444. + */
  14445. + hifn_reset_board(sc, 0);
  14446. +
  14447. + if (hifn_enable_crypto(sc) != 0) {
  14448. + device_printf(sc->sc_dev, "crypto enabling failed\n");
  14449. + goto fail;
  14450. + }
  14451. + hifn_reset_puc(sc);
  14452. +
  14453. + hifn_init_dma(sc);
  14454. + hifn_init_pci_registers(sc);
  14455. +
  14456. + pci_set_master(sc->sc_pcidev);
  14457. +
  14458. + /* XXX can't dynamically determine ram type for 795x; force dram */
  14459. + if (sc->sc_flags & HIFN_IS_7956)
  14460. + sc->sc_drammodel = 1;
  14461. + else if (hifn_ramtype(sc))
  14462. + goto fail;
  14463. +
  14464. + if (sc->sc_drammodel == 0)
  14465. + hifn_sramsize(sc);
  14466. + else
  14467. + hifn_dramsize(sc);
  14468. +
  14469. + /*
  14470. + * Workaround for NetSec 7751 rev A: half ram size because two
  14471. + * of the address lines were left floating
  14472. + */
  14473. + if (pci_get_vendor(dev) == PCI_VENDOR_NETSEC &&
  14474. + pci_get_device(dev) == PCI_PRODUCT_NETSEC_7751 &&
  14475. + pci_get_revid(dev) == 0x61) /*XXX???*/
  14476. + sc->sc_ramsize >>= 1;
  14477. +
  14478. + /*
  14479. + * Arrange the interrupt line.
  14480. + */
  14481. + rc = request_irq(dev->irq, hifn_intr, IRQF_SHARED, "hifn", sc);
  14482. + if (rc) {
  14483. + device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
  14484. + goto fail;
  14485. + }
  14486. + sc->sc_irq = dev->irq;
  14487. +
  14488. + hifn_sessions(sc);
  14489. +
  14490. + /*
  14491. + * NB: Keep only the low 16 bits; this masks the chip id
  14492. + * from the 7951.
  14493. + */
  14494. + rev = READ_REG_1(sc, HIFN_1_REVID) & 0xffff;
  14495. +
  14496. + rseg = sc->sc_ramsize / 1024;
  14497. + rbase = 'K';
  14498. + if (sc->sc_ramsize >= (1024 * 1024)) {
  14499. + rbase = 'M';
  14500. + rseg /= 1024;
  14501. + }
  14502. + device_printf(sc->sc_dev, "%s, rev %u, %d%cB %cram",
  14503. + hifn_partname(sc), rev,
  14504. + rseg, rbase, sc->sc_drammodel ? 'd' : 's');
  14505. + if (sc->sc_flags & HIFN_IS_7956)
  14506. + printf(", pll=0x%x<%s clk, %ux mult>",
  14507. + sc->sc_pllconfig,
  14508. + sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
  14509. + 2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
  14510. + printf("\n");
  14511. +
  14512. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
  14513. + if (sc->sc_cid < 0) {
  14514. + device_printf(sc->sc_dev, "could not get crypto driver id\n");
  14515. + goto fail;
  14516. + }
  14517. +
  14518. + WRITE_REG_0(sc, HIFN_0_PUCNFG,
  14519. + READ_REG_0(sc, HIFN_0_PUCNFG) | HIFN_PUCNFG_CHIPID);
  14520. + ena = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
  14521. +
  14522. + switch (ena) {
  14523. + case HIFN_PUSTAT_ENA_2:
  14524. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  14525. + crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
  14526. + if (sc->sc_flags & HIFN_HAS_AES)
  14527. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  14528. + /*FALLTHROUGH*/
  14529. + case HIFN_PUSTAT_ENA_1:
  14530. + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
  14531. + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
  14532. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  14533. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  14534. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  14535. + break;
  14536. + }
  14537. +
  14538. + if (sc->sc_flags & (HIFN_HAS_PUBLIC | HIFN_HAS_RNG))
  14539. + hifn_init_pubrng(sc);
  14540. +
  14541. + init_timer(&sc->sc_tickto);
  14542. + sc->sc_tickto.function = hifn_tick;
  14543. + sc->sc_tickto.data = (unsigned long) sc->sc_num;
  14544. + mod_timer(&sc->sc_tickto, jiffies + HZ);
  14545. +
  14546. + return (0);
  14547. +
  14548. +fail:
  14549. + if (sc->sc_cid >= 0)
  14550. + crypto_unregister_all(sc->sc_cid);
  14551. + if (sc->sc_irq != -1)
  14552. + free_irq(sc->sc_irq, sc);
  14553. + if (sc->sc_dma) {
  14554. + /* Turn off DMA polling */
  14555. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  14556. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  14557. +
  14558. + pci_free_consistent(sc->sc_pcidev,
  14559. + sizeof(*sc->sc_dma),
  14560. + sc->sc_dma, sc->sc_dma_physaddr);
  14561. + }
  14562. + kfree(sc);
  14563. + return (-ENXIO);
  14564. +}
  14565. +
  14566. +/*
  14567. + * Detach an interface that successfully probed.
  14568. + */
  14569. +static void
  14570. +hifn_remove(struct pci_dev *dev)
  14571. +{
  14572. + struct hifn_softc *sc = pci_get_drvdata(dev);
  14573. + unsigned long l_flags;
  14574. +
  14575. + DPRINTF("%s()\n", __FUNCTION__);
  14576. +
  14577. + KASSERT(sc != NULL, ("hifn_detach: null software carrier!"));
  14578. +
  14579. + /* disable interrupts */
  14580. + HIFN_LOCK(sc);
  14581. + WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
  14582. + HIFN_UNLOCK(sc);
  14583. +
  14584. + /*XXX other resources */
  14585. + del_timer_sync(&sc->sc_tickto);
  14586. +
  14587. + /* Turn off DMA polling */
  14588. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  14589. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  14590. +
  14591. + crypto_unregister_all(sc->sc_cid);
  14592. +
  14593. + free_irq(sc->sc_irq, sc);
  14594. +
  14595. + pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
  14596. + sc->sc_dma, sc->sc_dma_physaddr);
  14597. +}
  14598. +
  14599. +
  14600. +static int
  14601. +hifn_init_pubrng(struct hifn_softc *sc)
  14602. +{
  14603. + int i;
  14604. +
  14605. + DPRINTF("%s()\n", __FUNCTION__);
  14606. +
  14607. + if ((sc->sc_flags & HIFN_IS_7811) == 0) {
  14608. + /* Reset 7951 public key/rng engine */
  14609. + WRITE_REG_1(sc, HIFN_1_PUB_RESET,
  14610. + READ_REG_1(sc, HIFN_1_PUB_RESET) | HIFN_PUBRST_RESET);
  14611. +
  14612. + for (i = 0; i < 100; i++) {
  14613. + DELAY(1000);
  14614. + if ((READ_REG_1(sc, HIFN_1_PUB_RESET) &
  14615. + HIFN_PUBRST_RESET) == 0)
  14616. + break;
  14617. + }
  14618. +
  14619. + if (i == 100) {
  14620. + device_printf(sc->sc_dev, "public key init failed\n");
  14621. + return (1);
  14622. + }
  14623. + }
  14624. +
  14625. + /* Enable the rng, if available */
  14626. +#ifdef CONFIG_OCF_RANDOMHARVEST
  14627. + if (sc->sc_flags & HIFN_HAS_RNG) {
  14628. + if (sc->sc_flags & HIFN_IS_7811) {
  14629. + u_int32_t r;
  14630. + r = READ_REG_1(sc, HIFN_1_7811_RNGENA);
  14631. + if (r & HIFN_7811_RNGENA_ENA) {
  14632. + r &= ~HIFN_7811_RNGENA_ENA;
  14633. + WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
  14634. + }
  14635. + WRITE_REG_1(sc, HIFN_1_7811_RNGCFG,
  14636. + HIFN_7811_RNGCFG_DEFL);
  14637. + r |= HIFN_7811_RNGENA_ENA;
  14638. + WRITE_REG_1(sc, HIFN_1_7811_RNGENA, r);
  14639. + } else
  14640. + WRITE_REG_1(sc, HIFN_1_RNG_CONFIG,
  14641. + READ_REG_1(sc, HIFN_1_RNG_CONFIG) |
  14642. + HIFN_RNGCFG_ENA);
  14643. +
  14644. + sc->sc_rngfirst = 1;
  14645. + crypto_rregister(sc->sc_cid, hifn_read_random, sc);
  14646. + }
  14647. +#endif
  14648. +
  14649. + /* Enable public key engine, if available */
  14650. + if (sc->sc_flags & HIFN_HAS_PUBLIC) {
  14651. + WRITE_REG_1(sc, HIFN_1_PUB_IEN, HIFN_PUBIEN_DONE);
  14652. + sc->sc_dmaier |= HIFN_DMAIER_PUBDONE;
  14653. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  14654. +#ifdef HIFN_VULCANDEV
  14655. + sc->sc_pkdev = make_dev(&vulcanpk_cdevsw, 0,
  14656. + UID_ROOT, GID_WHEEL, 0666,
  14657. + "vulcanpk");
  14658. + sc->sc_pkdev->si_drv1 = sc;
  14659. +#endif
  14660. + }
  14661. +
  14662. + return (0);
  14663. +}
  14664. +
  14665. +#ifdef CONFIG_OCF_RANDOMHARVEST
  14666. +static int
  14667. +hifn_read_random(void *arg, u_int32_t *buf, int len)
  14668. +{
  14669. + struct hifn_softc *sc = (struct hifn_softc *) arg;
  14670. + u_int32_t sts;
  14671. + int i, rc = 0;
  14672. +
  14673. + if (len <= 0)
  14674. + return rc;
  14675. +
  14676. + if (sc->sc_flags & HIFN_IS_7811) {
  14677. + /* ONLY VALID ON 7811!!!! */
  14678. + for (i = 0; i < 5; i++) {
  14679. + sts = READ_REG_1(sc, HIFN_1_7811_RNGSTS);
  14680. + if (sts & HIFN_7811_RNGSTS_UFL) {
  14681. + device_printf(sc->sc_dev,
  14682. + "RNG underflow: disabling\n");
  14683. + /* DAVIDM perhaps return -1 */
  14684. + break;
  14685. + }
  14686. + if ((sts & HIFN_7811_RNGSTS_RDY) == 0)
  14687. + break;
  14688. +
  14689. + /*
  14690. + * There are at least two words in the RNG FIFO
  14691. + * at this point.
  14692. + */
  14693. + if (rc < len)
  14694. + buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
  14695. + if (rc < len)
  14696. + buf[rc++] = READ_REG_1(sc, HIFN_1_7811_RNGDAT);
  14697. + }
  14698. + } else
  14699. + buf[rc++] = READ_REG_1(sc, HIFN_1_RNG_DATA);
  14700. +
  14701. + /* NB: discard first data read */
  14702. + if (sc->sc_rngfirst) {
  14703. + sc->sc_rngfirst = 0;
  14704. + rc = 0;
  14705. + }
  14706. +
  14707. + return(rc);
  14708. +}
  14709. +#endif /* CONFIG_OCF_RANDOMHARVEST */
  14710. +
  14711. +static void
  14712. +hifn_puc_wait(struct hifn_softc *sc)
  14713. +{
  14714. + int i;
  14715. + int reg = HIFN_0_PUCTRL;
  14716. +
  14717. + if (sc->sc_flags & HIFN_IS_7956) {
  14718. + reg = HIFN_0_PUCTRL2;
  14719. + }
  14720. +
  14721. + for (i = 5000; i > 0; i--) {
  14722. + DELAY(1);
  14723. + if (!(READ_REG_0(sc, reg) & HIFN_PUCTRL_RESET))
  14724. + break;
  14725. + }
  14726. + if (!i)
  14727. + device_printf(sc->sc_dev, "proc unit did not reset(0x%x)\n",
  14728. + READ_REG_0(sc, HIFN_0_PUCTRL));
  14729. +}
  14730. +
  14731. +/*
  14732. + * Reset the processing unit.
  14733. + */
  14734. +static void
  14735. +hifn_reset_puc(struct hifn_softc *sc)
  14736. +{
  14737. + /* Reset processing unit */
  14738. + int reg = HIFN_0_PUCTRL;
  14739. +
  14740. + if (sc->sc_flags & HIFN_IS_7956) {
  14741. + reg = HIFN_0_PUCTRL2;
  14742. + }
  14743. + WRITE_REG_0(sc, reg, HIFN_PUCTRL_DMAENA);
  14744. +
  14745. + hifn_puc_wait(sc);
  14746. +}
  14747. +
  14748. +/*
  14749. + * Set the Retry and TRDY registers; note that we set them to
  14750. + * zero because the 7811 locks up when forced to retry (section
  14751. + * 3.6 of "Specification Update SU-0014-04". Not clear if we
  14752. + * should do this for all Hifn parts, but it doesn't seem to hurt.
  14753. + */
  14754. +static void
  14755. +hifn_set_retry(struct hifn_softc *sc)
  14756. +{
  14757. + DPRINTF("%s()\n", __FUNCTION__);
  14758. + /* NB: RETRY only responds to 8-bit reads/writes */
  14759. + pci_write_config_byte(sc->sc_pcidev, HIFN_RETRY_TIMEOUT, 0);
  14760. + pci_write_config_dword(sc->sc_pcidev, HIFN_TRDY_TIMEOUT, 0);
  14761. + /* piggy back the cache line setting here */
  14762. + pci_write_config_byte(sc->sc_pcidev, PCI_CACHE_LINE_SIZE, hifn_cache_linesize);
  14763. +}
  14764. +
  14765. +/*
  14766. + * Resets the board. Values in the regesters are left as is
  14767. + * from the reset (i.e. initial values are assigned elsewhere).
  14768. + */
  14769. +static void
  14770. +hifn_reset_board(struct hifn_softc *sc, int full)
  14771. +{
  14772. + u_int32_t reg;
  14773. +
  14774. + DPRINTF("%s()\n", __FUNCTION__);
  14775. + /*
  14776. + * Set polling in the DMA configuration register to zero. 0x7 avoids
  14777. + * resetting the board and zeros out the other fields.
  14778. + */
  14779. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  14780. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  14781. +
  14782. + /*
  14783. + * Now that polling has been disabled, we have to wait 1 ms
  14784. + * before resetting the board.
  14785. + */
  14786. + DELAY(1000);
  14787. +
  14788. + /* Reset the DMA unit */
  14789. + if (full) {
  14790. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MODE);
  14791. + DELAY(1000);
  14792. + } else {
  14793. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG,
  14794. + HIFN_DMACNFG_MODE | HIFN_DMACNFG_MSTRESET);
  14795. + hifn_reset_puc(sc);
  14796. + }
  14797. +
  14798. + KASSERT(sc->sc_dma != NULL, ("hifn_reset_board: null DMA tag!"));
  14799. + bzero(sc->sc_dma, sizeof(*sc->sc_dma));
  14800. +
  14801. + /* Bring dma unit out of reset */
  14802. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  14803. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  14804. +
  14805. + hifn_puc_wait(sc);
  14806. + hifn_set_retry(sc);
  14807. +
  14808. + if (sc->sc_flags & HIFN_IS_7811) {
  14809. + for (reg = 0; reg < 1000; reg++) {
  14810. + if (READ_REG_1(sc, HIFN_1_7811_MIPSRST) &
  14811. + HIFN_MIPSRST_CRAMINIT)
  14812. + break;
  14813. + DELAY(1000);
  14814. + }
  14815. + if (reg == 1000)
  14816. + device_printf(sc->sc_dev, ": cram init timeout\n");
  14817. + } else {
  14818. + /* set up DMA configuration register #2 */
  14819. + /* turn off all PK and BAR0 swaps */
  14820. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG2,
  14821. + (3 << HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT)|
  14822. + (3 << HIFN_DMACNFG2_INIT_READ_BURST_SHIFT)|
  14823. + (2 << HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT)|
  14824. + (2 << HIFN_DMACNFG2_TGT_READ_BURST_SHIFT));
  14825. + }
  14826. +}
  14827. +
  14828. +static u_int32_t
  14829. +hifn_next_signature(u_int32_t a, u_int cnt)
  14830. +{
  14831. + int i;
  14832. + u_int32_t v;
  14833. +
  14834. + for (i = 0; i < cnt; i++) {
  14835. +
  14836. + /* get the parity */
  14837. + v = a & 0x80080125;
  14838. + v ^= v >> 16;
  14839. + v ^= v >> 8;
  14840. + v ^= v >> 4;
  14841. + v ^= v >> 2;
  14842. + v ^= v >> 1;
  14843. +
  14844. + a = (v & 1) ^ (a << 1);
  14845. + }
  14846. +
  14847. + return a;
  14848. +}
  14849. +
  14850. +
  14851. +/*
  14852. + * Checks to see if crypto is already enabled. If crypto isn't enable,
  14853. + * "hifn_enable_crypto" is called to enable it. The check is important,
  14854. + * as enabling crypto twice will lock the board.
  14855. + */
  14856. +static int
  14857. +hifn_enable_crypto(struct hifn_softc *sc)
  14858. +{
  14859. + u_int32_t dmacfg, ramcfg, encl, addr, i;
  14860. + char offtbl[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  14861. + 0x00, 0x00, 0x00, 0x00 };
  14862. +
  14863. + DPRINTF("%s()\n", __FUNCTION__);
  14864. +
  14865. + ramcfg = READ_REG_0(sc, HIFN_0_PUCNFG);
  14866. + dmacfg = READ_REG_1(sc, HIFN_1_DMA_CNFG);
  14867. +
  14868. + /*
  14869. + * The RAM config register's encrypt level bit needs to be set before
  14870. + * every read performed on the encryption level register.
  14871. + */
  14872. + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
  14873. +
  14874. + encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
  14875. +
  14876. + /*
  14877. + * Make sure we don't re-unlock. Two unlocks kills chip until the
  14878. + * next reboot.
  14879. + */
  14880. + if (encl == HIFN_PUSTAT_ENA_1 || encl == HIFN_PUSTAT_ENA_2) {
  14881. +#ifdef HIFN_DEBUG
  14882. + if (hifn_debug)
  14883. + device_printf(sc->sc_dev,
  14884. + "Strong crypto already enabled!\n");
  14885. +#endif
  14886. + goto report;
  14887. + }
  14888. +
  14889. + if (encl != 0 && encl != HIFN_PUSTAT_ENA_0) {
  14890. +#ifdef HIFN_DEBUG
  14891. + if (hifn_debug)
  14892. + device_printf(sc->sc_dev,
  14893. + "Unknown encryption level 0x%x\n", encl);
  14894. +#endif
  14895. + return 1;
  14896. + }
  14897. +
  14898. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_UNLOCK |
  14899. + HIFN_DMACNFG_MSTRESET | HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  14900. + DELAY(1000);
  14901. + addr = READ_REG_1(sc, HIFN_UNLOCK_SECRET1);
  14902. + DELAY(1000);
  14903. + WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, 0);
  14904. + DELAY(1000);
  14905. +
  14906. + for (i = 0; i <= 12; i++) {
  14907. + addr = hifn_next_signature(addr, offtbl[i] + 0x101);
  14908. + WRITE_REG_1(sc, HIFN_UNLOCK_SECRET2, addr);
  14909. +
  14910. + DELAY(1000);
  14911. + }
  14912. +
  14913. + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg | HIFN_PUCNFG_CHIPID);
  14914. + encl = READ_REG_0(sc, HIFN_0_PUSTAT) & HIFN_PUSTAT_CHIPENA;
  14915. +
  14916. +#ifdef HIFN_DEBUG
  14917. + if (hifn_debug) {
  14918. + if (encl != HIFN_PUSTAT_ENA_1 && encl != HIFN_PUSTAT_ENA_2)
  14919. + device_printf(sc->sc_dev, "Engine is permanently "
  14920. + "locked until next system reset!\n");
  14921. + else
  14922. + device_printf(sc->sc_dev, "Engine enabled "
  14923. + "successfully!\n");
  14924. + }
  14925. +#endif
  14926. +
  14927. +report:
  14928. + WRITE_REG_0(sc, HIFN_0_PUCNFG, ramcfg);
  14929. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, dmacfg);
  14930. +
  14931. + switch (encl) {
  14932. + case HIFN_PUSTAT_ENA_1:
  14933. + case HIFN_PUSTAT_ENA_2:
  14934. + break;
  14935. + case HIFN_PUSTAT_ENA_0:
  14936. + default:
  14937. + device_printf(sc->sc_dev, "disabled\n");
  14938. + break;
  14939. + }
  14940. +
  14941. + return 0;
  14942. +}
  14943. +
  14944. +/*
  14945. + * Give initial values to the registers listed in the "Register Space"
  14946. + * section of the HIFN Software Development reference manual.
  14947. + */
  14948. +static void
  14949. +hifn_init_pci_registers(struct hifn_softc *sc)
  14950. +{
  14951. + DPRINTF("%s()\n", __FUNCTION__);
  14952. +
  14953. + /* write fixed values needed by the Initialization registers */
  14954. + WRITE_REG_0(sc, HIFN_0_PUCTRL, HIFN_PUCTRL_DMAENA);
  14955. + WRITE_REG_0(sc, HIFN_0_FIFOCNFG, HIFN_FIFOCNFG_THRESHOLD);
  14956. + WRITE_REG_0(sc, HIFN_0_PUIER, HIFN_PUIER_DSTOVER);
  14957. +
  14958. + /* write all 4 ring address registers */
  14959. + WRITE_REG_1(sc, HIFN_1_DMA_CRAR, sc->sc_dma_physaddr +
  14960. + offsetof(struct hifn_dma, cmdr[0]));
  14961. + WRITE_REG_1(sc, HIFN_1_DMA_SRAR, sc->sc_dma_physaddr +
  14962. + offsetof(struct hifn_dma, srcr[0]));
  14963. + WRITE_REG_1(sc, HIFN_1_DMA_DRAR, sc->sc_dma_physaddr +
  14964. + offsetof(struct hifn_dma, dstr[0]));
  14965. + WRITE_REG_1(sc, HIFN_1_DMA_RRAR, sc->sc_dma_physaddr +
  14966. + offsetof(struct hifn_dma, resr[0]));
  14967. +
  14968. + DELAY(2000);
  14969. +
  14970. + /* write status register */
  14971. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  14972. + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS |
  14973. + HIFN_DMACSR_S_CTRL_DIS | HIFN_DMACSR_C_CTRL_DIS |
  14974. + HIFN_DMACSR_D_ABORT | HIFN_DMACSR_D_DONE | HIFN_DMACSR_D_LAST |
  14975. + HIFN_DMACSR_D_WAIT | HIFN_DMACSR_D_OVER |
  14976. + HIFN_DMACSR_R_ABORT | HIFN_DMACSR_R_DONE | HIFN_DMACSR_R_LAST |
  14977. + HIFN_DMACSR_R_WAIT | HIFN_DMACSR_R_OVER |
  14978. + HIFN_DMACSR_S_ABORT | HIFN_DMACSR_S_DONE | HIFN_DMACSR_S_LAST |
  14979. + HIFN_DMACSR_S_WAIT |
  14980. + HIFN_DMACSR_C_ABORT | HIFN_DMACSR_C_DONE | HIFN_DMACSR_C_LAST |
  14981. + HIFN_DMACSR_C_WAIT |
  14982. + HIFN_DMACSR_ENGINE |
  14983. + ((sc->sc_flags & HIFN_HAS_PUBLIC) ?
  14984. + HIFN_DMACSR_PUBDONE : 0) |
  14985. + ((sc->sc_flags & HIFN_IS_7811) ?
  14986. + HIFN_DMACSR_ILLW | HIFN_DMACSR_ILLR : 0));
  14987. +
  14988. + sc->sc_d_busy = sc->sc_r_busy = sc->sc_s_busy = sc->sc_c_busy = 0;
  14989. + sc->sc_dmaier |= HIFN_DMAIER_R_DONE | HIFN_DMAIER_C_ABORT |
  14990. + HIFN_DMAIER_D_OVER | HIFN_DMAIER_R_OVER |
  14991. + HIFN_DMAIER_S_ABORT | HIFN_DMAIER_D_ABORT | HIFN_DMAIER_R_ABORT |
  14992. + ((sc->sc_flags & HIFN_IS_7811) ?
  14993. + HIFN_DMAIER_ILLW | HIFN_DMAIER_ILLR : 0);
  14994. + sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
  14995. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  14996. +
  14997. +
  14998. + if (sc->sc_flags & HIFN_IS_7956) {
  14999. + u_int32_t pll;
  15000. +
  15001. + WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
  15002. + HIFN_PUCNFG_TCALLPHASES |
  15003. + HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32);
  15004. +
  15005. + /* turn off the clocks and insure bypass is set */
  15006. + pll = READ_REG_1(sc, HIFN_1_PLL);
  15007. + pll = (pll &~ (HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL))
  15008. + | HIFN_PLL_BP | HIFN_PLL_MBSET;
  15009. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  15010. + DELAY(10*1000); /* 10ms */
  15011. +
  15012. + /* change configuration */
  15013. + pll = (pll &~ HIFN_PLL_CONFIG) | sc->sc_pllconfig;
  15014. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  15015. + DELAY(10*1000); /* 10ms */
  15016. +
  15017. + /* disable bypass */
  15018. + pll &= ~HIFN_PLL_BP;
  15019. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  15020. + /* enable clocks with new configuration */
  15021. + pll |= HIFN_PLL_PK_CLK_SEL | HIFN_PLL_PE_CLK_SEL;
  15022. + WRITE_REG_1(sc, HIFN_1_PLL, pll);
  15023. + } else {
  15024. + WRITE_REG_0(sc, HIFN_0_PUCNFG, HIFN_PUCNFG_COMPSING |
  15025. + HIFN_PUCNFG_DRFR_128 | HIFN_PUCNFG_TCALLPHASES |
  15026. + HIFN_PUCNFG_TCDRVTOTEM | HIFN_PUCNFG_BUS32 |
  15027. + (sc->sc_drammodel ? HIFN_PUCNFG_DRAM : HIFN_PUCNFG_SRAM));
  15028. + }
  15029. +
  15030. + WRITE_REG_0(sc, HIFN_0_PUISR, HIFN_PUISR_DSTOVER);
  15031. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  15032. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE | HIFN_DMACNFG_LAST |
  15033. + ((HIFN_POLL_FREQUENCY << 16 ) & HIFN_DMACNFG_POLLFREQ) |
  15034. + ((HIFN_POLL_SCALAR << 8) & HIFN_DMACNFG_POLLINVAL));
  15035. +}
  15036. +
  15037. +/*
  15038. + * The maximum number of sessions supported by the card
  15039. + * is dependent on the amount of context ram, which
  15040. + * encryption algorithms are enabled, and how compression
  15041. + * is configured. This should be configured before this
  15042. + * routine is called.
  15043. + */
  15044. +static void
  15045. +hifn_sessions(struct hifn_softc *sc)
  15046. +{
  15047. + u_int32_t pucnfg;
  15048. + int ctxsize;
  15049. +
  15050. + DPRINTF("%s()\n", __FUNCTION__);
  15051. +
  15052. + pucnfg = READ_REG_0(sc, HIFN_0_PUCNFG);
  15053. +
  15054. + if (pucnfg & HIFN_PUCNFG_COMPSING) {
  15055. + if (pucnfg & HIFN_PUCNFG_ENCCNFG)
  15056. + ctxsize = 128;
  15057. + else
  15058. + ctxsize = 512;
  15059. + /*
  15060. + * 7955/7956 has internal context memory of 32K
  15061. + */
  15062. + if (sc->sc_flags & HIFN_IS_7956)
  15063. + sc->sc_maxses = 32768 / ctxsize;
  15064. + else
  15065. + sc->sc_maxses = 1 +
  15066. + ((sc->sc_ramsize - 32768) / ctxsize);
  15067. + } else
  15068. + sc->sc_maxses = sc->sc_ramsize / 16384;
  15069. +
  15070. + if (sc->sc_maxses > 2048)
  15071. + sc->sc_maxses = 2048;
  15072. +}
  15073. +
  15074. +/*
  15075. + * Determine ram type (sram or dram). Board should be just out of a reset
  15076. + * state when this is called.
  15077. + */
  15078. +static int
  15079. +hifn_ramtype(struct hifn_softc *sc)
  15080. +{
  15081. + u_int8_t data[8], dataexpect[8];
  15082. + int i;
  15083. +
  15084. + for (i = 0; i < sizeof(data); i++)
  15085. + data[i] = dataexpect[i] = 0x55;
  15086. + if (hifn_writeramaddr(sc, 0, data))
  15087. + return (-1);
  15088. + if (hifn_readramaddr(sc, 0, data))
  15089. + return (-1);
  15090. + if (bcmp(data, dataexpect, sizeof(data)) != 0) {
  15091. + sc->sc_drammodel = 1;
  15092. + return (0);
  15093. + }
  15094. +
  15095. + for (i = 0; i < sizeof(data); i++)
  15096. + data[i] = dataexpect[i] = 0xaa;
  15097. + if (hifn_writeramaddr(sc, 0, data))
  15098. + return (-1);
  15099. + if (hifn_readramaddr(sc, 0, data))
  15100. + return (-1);
  15101. + if (bcmp(data, dataexpect, sizeof(data)) != 0) {
  15102. + sc->sc_drammodel = 1;
  15103. + return (0);
  15104. + }
  15105. +
  15106. + return (0);
  15107. +}
  15108. +
  15109. +#define HIFN_SRAM_MAX (32 << 20)
  15110. +#define HIFN_SRAM_STEP_SIZE 16384
  15111. +#define HIFN_SRAM_GRANULARITY (HIFN_SRAM_MAX / HIFN_SRAM_STEP_SIZE)
  15112. +
  15113. +static int
  15114. +hifn_sramsize(struct hifn_softc *sc)
  15115. +{
  15116. + u_int32_t a;
  15117. + u_int8_t data[8];
  15118. + u_int8_t dataexpect[sizeof(data)];
  15119. + int32_t i;
  15120. +
  15121. + for (i = 0; i < sizeof(data); i++)
  15122. + data[i] = dataexpect[i] = i ^ 0x5a;
  15123. +
  15124. + for (i = HIFN_SRAM_GRANULARITY - 1; i >= 0; i--) {
  15125. + a = i * HIFN_SRAM_STEP_SIZE;
  15126. + bcopy(&i, data, sizeof(i));
  15127. + hifn_writeramaddr(sc, a, data);
  15128. + }
  15129. +
  15130. + for (i = 0; i < HIFN_SRAM_GRANULARITY; i++) {
  15131. + a = i * HIFN_SRAM_STEP_SIZE;
  15132. + bcopy(&i, dataexpect, sizeof(i));
  15133. + if (hifn_readramaddr(sc, a, data) < 0)
  15134. + return (0);
  15135. + if (bcmp(data, dataexpect, sizeof(data)) != 0)
  15136. + return (0);
  15137. + sc->sc_ramsize = a + HIFN_SRAM_STEP_SIZE;
  15138. + }
  15139. +
  15140. + return (0);
  15141. +}
  15142. +
  15143. +/*
  15144. + * XXX For dram boards, one should really try all of the
  15145. + * HIFN_PUCNFG_DSZ_*'s. This just assumes that PUCNFG
  15146. + * is already set up correctly.
  15147. + */
  15148. +static int
  15149. +hifn_dramsize(struct hifn_softc *sc)
  15150. +{
  15151. + u_int32_t cnfg;
  15152. +
  15153. + if (sc->sc_flags & HIFN_IS_7956) {
  15154. + /*
  15155. + * 7955/7956 have a fixed internal ram of only 32K.
  15156. + */
  15157. + sc->sc_ramsize = 32768;
  15158. + } else {
  15159. + cnfg = READ_REG_0(sc, HIFN_0_PUCNFG) &
  15160. + HIFN_PUCNFG_DRAMMASK;
  15161. + sc->sc_ramsize = 1 << ((cnfg >> 13) + 18);
  15162. + }
  15163. + return (0);
  15164. +}
  15165. +
  15166. +static void
  15167. +hifn_alloc_slot(struct hifn_softc *sc, int *cmdp, int *srcp, int *dstp, int *resp)
  15168. +{
  15169. + struct hifn_dma *dma = sc->sc_dma;
  15170. +
  15171. + DPRINTF("%s()\n", __FUNCTION__);
  15172. +
  15173. + if (dma->cmdi == HIFN_D_CMD_RSIZE) {
  15174. + dma->cmdi = 0;
  15175. + dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  15176. + wmb();
  15177. + dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
  15178. + HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
  15179. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  15180. + }
  15181. + *cmdp = dma->cmdi++;
  15182. + dma->cmdk = dma->cmdi;
  15183. +
  15184. + if (dma->srci == HIFN_D_SRC_RSIZE) {
  15185. + dma->srci = 0;
  15186. + dma->srcr[HIFN_D_SRC_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  15187. + wmb();
  15188. + dma->srcr[HIFN_D_SRC_RSIZE].l |= htole32(HIFN_D_VALID);
  15189. + HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
  15190. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  15191. + }
  15192. + *srcp = dma->srci++;
  15193. + dma->srck = dma->srci;
  15194. +
  15195. + if (dma->dsti == HIFN_D_DST_RSIZE) {
  15196. + dma->dsti = 0;
  15197. + dma->dstr[HIFN_D_DST_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  15198. + wmb();
  15199. + dma->dstr[HIFN_D_DST_RSIZE].l |= htole32(HIFN_D_VALID);
  15200. + HIFN_DSTR_SYNC(sc, HIFN_D_DST_RSIZE,
  15201. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  15202. + }
  15203. + *dstp = dma->dsti++;
  15204. + dma->dstk = dma->dsti;
  15205. +
  15206. + if (dma->resi == HIFN_D_RES_RSIZE) {
  15207. + dma->resi = 0;
  15208. + dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  15209. + wmb();
  15210. + dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
  15211. + HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
  15212. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  15213. + }
  15214. + *resp = dma->resi++;
  15215. + dma->resk = dma->resi;
  15216. +}
  15217. +
  15218. +static int
  15219. +hifn_writeramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
  15220. +{
  15221. + struct hifn_dma *dma = sc->sc_dma;
  15222. + hifn_base_command_t wc;
  15223. + const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
  15224. + int r, cmdi, resi, srci, dsti;
  15225. +
  15226. + DPRINTF("%s()\n", __FUNCTION__);
  15227. +
  15228. + wc.masks = htole16(3 << 13);
  15229. + wc.session_num = htole16(addr >> 14);
  15230. + wc.total_source_count = htole16(8);
  15231. + wc.total_dest_count = htole16(addr & 0x3fff);
  15232. +
  15233. + hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
  15234. +
  15235. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  15236. + HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
  15237. + HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
  15238. +
  15239. + /* build write command */
  15240. + bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
  15241. + *(hifn_base_command_t *)dma->command_bufs[cmdi] = wc;
  15242. + bcopy(data, &dma->test_src, sizeof(dma->test_src));
  15243. +
  15244. + dma->srcr[srci].p = htole32(sc->sc_dma_physaddr
  15245. + + offsetof(struct hifn_dma, test_src));
  15246. + dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr
  15247. + + offsetof(struct hifn_dma, test_dst));
  15248. +
  15249. + dma->cmdr[cmdi].l = htole32(16 | masks);
  15250. + dma->srcr[srci].l = htole32(8 | masks);
  15251. + dma->dstr[dsti].l = htole32(4 | masks);
  15252. + dma->resr[resi].l = htole32(4 | masks);
  15253. +
  15254. + for (r = 10000; r >= 0; r--) {
  15255. + DELAY(10);
  15256. + if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
  15257. + break;
  15258. + }
  15259. + if (r == 0) {
  15260. + device_printf(sc->sc_dev, "writeramaddr -- "
  15261. + "result[%d](addr %d) still valid\n", resi, addr);
  15262. + r = -1;
  15263. + return (-1);
  15264. + } else
  15265. + r = 0;
  15266. +
  15267. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  15268. + HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
  15269. + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
  15270. +
  15271. + return (r);
  15272. +}
  15273. +
  15274. +static int
  15275. +hifn_readramaddr(struct hifn_softc *sc, int addr, u_int8_t *data)
  15276. +{
  15277. + struct hifn_dma *dma = sc->sc_dma;
  15278. + hifn_base_command_t rc;
  15279. + const u_int32_t masks = HIFN_D_VALID | HIFN_D_LAST | HIFN_D_MASKDONEIRQ;
  15280. + int r, cmdi, srci, dsti, resi;
  15281. +
  15282. + DPRINTF("%s()\n", __FUNCTION__);
  15283. +
  15284. + rc.masks = htole16(2 << 13);
  15285. + rc.session_num = htole16(addr >> 14);
  15286. + rc.total_source_count = htole16(addr & 0x3fff);
  15287. + rc.total_dest_count = htole16(8);
  15288. +
  15289. + hifn_alloc_slot(sc, &cmdi, &srci, &dsti, &resi);
  15290. +
  15291. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  15292. + HIFN_DMACSR_C_CTRL_ENA | HIFN_DMACSR_S_CTRL_ENA |
  15293. + HIFN_DMACSR_D_CTRL_ENA | HIFN_DMACSR_R_CTRL_ENA);
  15294. +
  15295. + bzero(dma->command_bufs[cmdi], HIFN_MAX_COMMAND);
  15296. + *(hifn_base_command_t *)dma->command_bufs[cmdi] = rc;
  15297. +
  15298. + dma->srcr[srci].p = htole32(sc->sc_dma_physaddr +
  15299. + offsetof(struct hifn_dma, test_src));
  15300. + dma->test_src = 0;
  15301. + dma->dstr[dsti].p = htole32(sc->sc_dma_physaddr +
  15302. + offsetof(struct hifn_dma, test_dst));
  15303. + dma->test_dst = 0;
  15304. + dma->cmdr[cmdi].l = htole32(8 | masks);
  15305. + dma->srcr[srci].l = htole32(8 | masks);
  15306. + dma->dstr[dsti].l = htole32(8 | masks);
  15307. + dma->resr[resi].l = htole32(HIFN_MAX_RESULT | masks);
  15308. +
  15309. + for (r = 10000; r >= 0; r--) {
  15310. + DELAY(10);
  15311. + if ((dma->resr[resi].l & htole32(HIFN_D_VALID)) == 0)
  15312. + break;
  15313. + }
  15314. + if (r == 0) {
  15315. + device_printf(sc->sc_dev, "readramaddr -- "
  15316. + "result[%d](addr %d) still valid\n", resi, addr);
  15317. + r = -1;
  15318. + } else {
  15319. + r = 0;
  15320. + bcopy(&dma->test_dst, data, sizeof(dma->test_dst));
  15321. + }
  15322. +
  15323. + WRITE_REG_1(sc, HIFN_1_DMA_CSR,
  15324. + HIFN_DMACSR_C_CTRL_DIS | HIFN_DMACSR_S_CTRL_DIS |
  15325. + HIFN_DMACSR_D_CTRL_DIS | HIFN_DMACSR_R_CTRL_DIS);
  15326. +
  15327. + return (r);
  15328. +}
  15329. +
  15330. +/*
  15331. + * Initialize the descriptor rings.
  15332. + */
  15333. +static void
  15334. +hifn_init_dma(struct hifn_softc *sc)
  15335. +{
  15336. + struct hifn_dma *dma = sc->sc_dma;
  15337. + int i;
  15338. +
  15339. + DPRINTF("%s()\n", __FUNCTION__);
  15340. +
  15341. + hifn_set_retry(sc);
  15342. +
  15343. + /* initialize static pointer values */
  15344. + for (i = 0; i < HIFN_D_CMD_RSIZE; i++)
  15345. + dma->cmdr[i].p = htole32(sc->sc_dma_physaddr +
  15346. + offsetof(struct hifn_dma, command_bufs[i][0]));
  15347. + for (i = 0; i < HIFN_D_RES_RSIZE; i++)
  15348. + dma->resr[i].p = htole32(sc->sc_dma_physaddr +
  15349. + offsetof(struct hifn_dma, result_bufs[i][0]));
  15350. +
  15351. + dma->cmdr[HIFN_D_CMD_RSIZE].p =
  15352. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, cmdr[0]));
  15353. + dma->srcr[HIFN_D_SRC_RSIZE].p =
  15354. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, srcr[0]));
  15355. + dma->dstr[HIFN_D_DST_RSIZE].p =
  15356. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, dstr[0]));
  15357. + dma->resr[HIFN_D_RES_RSIZE].p =
  15358. + htole32(sc->sc_dma_physaddr + offsetof(struct hifn_dma, resr[0]));
  15359. +
  15360. + dma->cmdu = dma->srcu = dma->dstu = dma->resu = 0;
  15361. + dma->cmdi = dma->srci = dma->dsti = dma->resi = 0;
  15362. + dma->cmdk = dma->srck = dma->dstk = dma->resk = 0;
  15363. +}
  15364. +
  15365. +/*
  15366. + * Writes out the raw command buffer space. Returns the
  15367. + * command buffer size.
  15368. + */
  15369. +static u_int
  15370. +hifn_write_command(struct hifn_command *cmd, u_int8_t *buf)
  15371. +{
  15372. + struct hifn_softc *sc = NULL;
  15373. + u_int8_t *buf_pos;
  15374. + hifn_base_command_t *base_cmd;
  15375. + hifn_mac_command_t *mac_cmd;
  15376. + hifn_crypt_command_t *cry_cmd;
  15377. + int using_mac, using_crypt, len, ivlen;
  15378. + u_int32_t dlen, slen;
  15379. +
  15380. + DPRINTF("%s()\n", __FUNCTION__);
  15381. +
  15382. + buf_pos = buf;
  15383. + using_mac = cmd->base_masks & HIFN_BASE_CMD_MAC;
  15384. + using_crypt = cmd->base_masks & HIFN_BASE_CMD_CRYPT;
  15385. +
  15386. + base_cmd = (hifn_base_command_t *)buf_pos;
  15387. + base_cmd->masks = htole16(cmd->base_masks);
  15388. + slen = cmd->src_mapsize;
  15389. + if (cmd->sloplen)
  15390. + dlen = cmd->dst_mapsize - cmd->sloplen + sizeof(u_int32_t);
  15391. + else
  15392. + dlen = cmd->dst_mapsize;
  15393. + base_cmd->total_source_count = htole16(slen & HIFN_BASE_CMD_LENMASK_LO);
  15394. + base_cmd->total_dest_count = htole16(dlen & HIFN_BASE_CMD_LENMASK_LO);
  15395. + dlen >>= 16;
  15396. + slen >>= 16;
  15397. + base_cmd->session_num = htole16(
  15398. + ((slen << HIFN_BASE_CMD_SRCLEN_S) & HIFN_BASE_CMD_SRCLEN_M) |
  15399. + ((dlen << HIFN_BASE_CMD_DSTLEN_S) & HIFN_BASE_CMD_DSTLEN_M));
  15400. + buf_pos += sizeof(hifn_base_command_t);
  15401. +
  15402. + if (using_mac) {
  15403. + mac_cmd = (hifn_mac_command_t *)buf_pos;
  15404. + dlen = cmd->maccrd->crd_len;
  15405. + mac_cmd->source_count = htole16(dlen & 0xffff);
  15406. + dlen >>= 16;
  15407. + mac_cmd->masks = htole16(cmd->mac_masks |
  15408. + ((dlen << HIFN_MAC_CMD_SRCLEN_S) & HIFN_MAC_CMD_SRCLEN_M));
  15409. + mac_cmd->header_skip = htole16(cmd->maccrd->crd_skip);
  15410. + mac_cmd->reserved = 0;
  15411. + buf_pos += sizeof(hifn_mac_command_t);
  15412. + }
  15413. +
  15414. + if (using_crypt) {
  15415. + cry_cmd = (hifn_crypt_command_t *)buf_pos;
  15416. + dlen = cmd->enccrd->crd_len;
  15417. + cry_cmd->source_count = htole16(dlen & 0xffff);
  15418. + dlen >>= 16;
  15419. + cry_cmd->masks = htole16(cmd->cry_masks |
  15420. + ((dlen << HIFN_CRYPT_CMD_SRCLEN_S) & HIFN_CRYPT_CMD_SRCLEN_M));
  15421. + cry_cmd->header_skip = htole16(cmd->enccrd->crd_skip);
  15422. + cry_cmd->reserved = 0;
  15423. + buf_pos += sizeof(hifn_crypt_command_t);
  15424. + }
  15425. +
  15426. + if (using_mac && cmd->mac_masks & HIFN_MAC_CMD_NEW_KEY) {
  15427. + bcopy(cmd->mac, buf_pos, HIFN_MAC_KEY_LENGTH);
  15428. + buf_pos += HIFN_MAC_KEY_LENGTH;
  15429. + }
  15430. +
  15431. + if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_KEY) {
  15432. + switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
  15433. + case HIFN_CRYPT_CMD_ALG_3DES:
  15434. + bcopy(cmd->ck, buf_pos, HIFN_3DES_KEY_LENGTH);
  15435. + buf_pos += HIFN_3DES_KEY_LENGTH;
  15436. + break;
  15437. + case HIFN_CRYPT_CMD_ALG_DES:
  15438. + bcopy(cmd->ck, buf_pos, HIFN_DES_KEY_LENGTH);
  15439. + buf_pos += HIFN_DES_KEY_LENGTH;
  15440. + break;
  15441. + case HIFN_CRYPT_CMD_ALG_RC4:
  15442. + len = 256;
  15443. + do {
  15444. + int clen;
  15445. +
  15446. + clen = MIN(cmd->cklen, len);
  15447. + bcopy(cmd->ck, buf_pos, clen);
  15448. + len -= clen;
  15449. + buf_pos += clen;
  15450. + } while (len > 0);
  15451. + bzero(buf_pos, 4);
  15452. + buf_pos += 4;
  15453. + break;
  15454. + case HIFN_CRYPT_CMD_ALG_AES:
  15455. + /*
  15456. + * AES keys are variable 128, 192 and
  15457. + * 256 bits (16, 24 and 32 bytes).
  15458. + */
  15459. + bcopy(cmd->ck, buf_pos, cmd->cklen);
  15460. + buf_pos += cmd->cklen;
  15461. + break;
  15462. + }
  15463. + }
  15464. +
  15465. + if (using_crypt && cmd->cry_masks & HIFN_CRYPT_CMD_NEW_IV) {
  15466. + switch (cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) {
  15467. + case HIFN_CRYPT_CMD_ALG_AES:
  15468. + ivlen = HIFN_AES_IV_LENGTH;
  15469. + break;
  15470. + default:
  15471. + ivlen = HIFN_IV_LENGTH;
  15472. + break;
  15473. + }
  15474. + bcopy(cmd->iv, buf_pos, ivlen);
  15475. + buf_pos += ivlen;
  15476. + }
  15477. +
  15478. + if ((cmd->base_masks & (HIFN_BASE_CMD_MAC|HIFN_BASE_CMD_CRYPT)) == 0) {
  15479. + bzero(buf_pos, 8);
  15480. + buf_pos += 8;
  15481. + }
  15482. +
  15483. + return (buf_pos - buf);
  15484. +}
  15485. +
  15486. +static int
  15487. +hifn_dmamap_aligned(struct hifn_operand *op)
  15488. +{
  15489. + struct hifn_softc *sc = NULL;
  15490. + int i;
  15491. +
  15492. + DPRINTF("%s()\n", __FUNCTION__);
  15493. +
  15494. + for (i = 0; i < op->nsegs; i++) {
  15495. + if (op->segs[i].ds_addr & 3)
  15496. + return (0);
  15497. + if ((i != (op->nsegs - 1)) && (op->segs[i].ds_len & 3))
  15498. + return (0);
  15499. + }
  15500. + return (1);
  15501. +}
  15502. +
  15503. +static __inline int
  15504. +hifn_dmamap_dstwrap(struct hifn_softc *sc, int idx)
  15505. +{
  15506. + struct hifn_dma *dma = sc->sc_dma;
  15507. +
  15508. + if (++idx == HIFN_D_DST_RSIZE) {
  15509. + dma->dstr[idx].l = htole32(HIFN_D_VALID | HIFN_D_JUMP |
  15510. + HIFN_D_MASKDONEIRQ);
  15511. + HIFN_DSTR_SYNC(sc, idx,
  15512. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  15513. + idx = 0;
  15514. + }
  15515. + return (idx);
  15516. +}
  15517. +
  15518. +static int
  15519. +hifn_dmamap_load_dst(struct hifn_softc *sc, struct hifn_command *cmd)
  15520. +{
  15521. + struct hifn_dma *dma = sc->sc_dma;
  15522. + struct hifn_operand *dst = &cmd->dst;
  15523. + u_int32_t p, l;
  15524. + int idx, used = 0, i;
  15525. +
  15526. + DPRINTF("%s()\n", __FUNCTION__);
  15527. +
  15528. + idx = dma->dsti;
  15529. + for (i = 0; i < dst->nsegs - 1; i++) {
  15530. + dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
  15531. + dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ | dst->segs[i].ds_len);
  15532. + wmb();
  15533. + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
  15534. + HIFN_DSTR_SYNC(sc, idx,
  15535. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  15536. + used++;
  15537. +
  15538. + idx = hifn_dmamap_dstwrap(sc, idx);
  15539. + }
  15540. +
  15541. + if (cmd->sloplen == 0) {
  15542. + p = dst->segs[i].ds_addr;
  15543. + l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
  15544. + dst->segs[i].ds_len;
  15545. + } else {
  15546. + p = sc->sc_dma_physaddr +
  15547. + offsetof(struct hifn_dma, slop[cmd->slopidx]);
  15548. + l = HIFN_D_MASKDONEIRQ | HIFN_D_LAST |
  15549. + sizeof(u_int32_t);
  15550. +
  15551. + if ((dst->segs[i].ds_len - cmd->sloplen) != 0) {
  15552. + dma->dstr[idx].p = htole32(dst->segs[i].ds_addr);
  15553. + dma->dstr[idx].l = htole32(HIFN_D_MASKDONEIRQ |
  15554. + (dst->segs[i].ds_len - cmd->sloplen));
  15555. + wmb();
  15556. + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
  15557. + HIFN_DSTR_SYNC(sc, idx,
  15558. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  15559. + used++;
  15560. +
  15561. + idx = hifn_dmamap_dstwrap(sc, idx);
  15562. + }
  15563. + }
  15564. + dma->dstr[idx].p = htole32(p);
  15565. + dma->dstr[idx].l = htole32(l);
  15566. + wmb();
  15567. + dma->dstr[idx].l |= htole32(HIFN_D_VALID);
  15568. + HIFN_DSTR_SYNC(sc, idx, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  15569. + used++;
  15570. +
  15571. + idx = hifn_dmamap_dstwrap(sc, idx);
  15572. +
  15573. + dma->dsti = idx;
  15574. + dma->dstu += used;
  15575. + return (idx);
  15576. +}
  15577. +
  15578. +static __inline int
  15579. +hifn_dmamap_srcwrap(struct hifn_softc *sc, int idx)
  15580. +{
  15581. + struct hifn_dma *dma = sc->sc_dma;
  15582. +
  15583. + if (++idx == HIFN_D_SRC_RSIZE) {
  15584. + dma->srcr[idx].l = htole32(HIFN_D_VALID |
  15585. + HIFN_D_JUMP | HIFN_D_MASKDONEIRQ);
  15586. + HIFN_SRCR_SYNC(sc, HIFN_D_SRC_RSIZE,
  15587. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  15588. + idx = 0;
  15589. + }
  15590. + return (idx);
  15591. +}
  15592. +
  15593. +static int
  15594. +hifn_dmamap_load_src(struct hifn_softc *sc, struct hifn_command *cmd)
  15595. +{
  15596. + struct hifn_dma *dma = sc->sc_dma;
  15597. + struct hifn_operand *src = &cmd->src;
  15598. + int idx, i;
  15599. + u_int32_t last = 0;
  15600. +
  15601. + DPRINTF("%s()\n", __FUNCTION__);
  15602. +
  15603. + idx = dma->srci;
  15604. + for (i = 0; i < src->nsegs; i++) {
  15605. + if (i == src->nsegs - 1)
  15606. + last = HIFN_D_LAST;
  15607. +
  15608. + dma->srcr[idx].p = htole32(src->segs[i].ds_addr);
  15609. + dma->srcr[idx].l = htole32(src->segs[i].ds_len |
  15610. + HIFN_D_MASKDONEIRQ | last);
  15611. + wmb();
  15612. + dma->srcr[idx].l |= htole32(HIFN_D_VALID);
  15613. + HIFN_SRCR_SYNC(sc, idx,
  15614. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  15615. +
  15616. + idx = hifn_dmamap_srcwrap(sc, idx);
  15617. + }
  15618. + dma->srci = idx;
  15619. + dma->srcu += src->nsegs;
  15620. + return (idx);
  15621. +}
  15622. +
  15623. +
  15624. +static int
  15625. +hifn_crypto(
  15626. + struct hifn_softc *sc,
  15627. + struct hifn_command *cmd,
  15628. + struct cryptop *crp,
  15629. + int hint)
  15630. +{
  15631. + struct hifn_dma *dma = sc->sc_dma;
  15632. + u_int32_t cmdlen, csr;
  15633. + int cmdi, resi, err = 0;
  15634. + unsigned long l_flags;
  15635. +
  15636. + DPRINTF("%s()\n", __FUNCTION__);
  15637. +
  15638. + /*
  15639. + * need 1 cmd, and 1 res
  15640. + *
  15641. + * NB: check this first since it's easy.
  15642. + */
  15643. + HIFN_LOCK(sc);
  15644. + if ((dma->cmdu + 1) > HIFN_D_CMD_RSIZE ||
  15645. + (dma->resu + 1) > HIFN_D_RES_RSIZE) {
  15646. +#ifdef HIFN_DEBUG
  15647. + if (hifn_debug) {
  15648. + device_printf(sc->sc_dev,
  15649. + "cmd/result exhaustion, cmdu %u resu %u\n",
  15650. + dma->cmdu, dma->resu);
  15651. + }
  15652. +#endif
  15653. + hifnstats.hst_nomem_cr++;
  15654. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  15655. + HIFN_UNLOCK(sc);
  15656. + return (ERESTART);
  15657. + }
  15658. +
  15659. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  15660. + if (pci_map_skb(sc, &cmd->src, cmd->src_skb)) {
  15661. + hifnstats.hst_nomem_load++;
  15662. + err = ENOMEM;
  15663. + goto err_srcmap1;
  15664. + }
  15665. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  15666. + if (pci_map_uio(sc, &cmd->src, cmd->src_io)) {
  15667. + hifnstats.hst_nomem_load++;
  15668. + err = ENOMEM;
  15669. + goto err_srcmap1;
  15670. + }
  15671. + } else {
  15672. + if (pci_map_buf(sc, &cmd->src, cmd->src_buf, crp->crp_ilen)) {
  15673. + hifnstats.hst_nomem_load++;
  15674. + err = ENOMEM;
  15675. + goto err_srcmap1;
  15676. + }
  15677. + }
  15678. +
  15679. + if (hifn_dmamap_aligned(&cmd->src)) {
  15680. + cmd->sloplen = cmd->src_mapsize & 3;
  15681. + cmd->dst = cmd->src;
  15682. + } else {
  15683. + if (crp->crp_flags & CRYPTO_F_IOV) {
  15684. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  15685. + err = EINVAL;
  15686. + goto err_srcmap;
  15687. + } else if (crp->crp_flags & CRYPTO_F_SKBUF) {
  15688. +#ifdef NOTYET
  15689. + int totlen, len;
  15690. + struct mbuf *m, *m0, *mlast;
  15691. +
  15692. + KASSERT(cmd->dst_m == cmd->src_m,
  15693. + ("hifn_crypto: dst_m initialized improperly"));
  15694. + hifnstats.hst_unaligned++;
  15695. + /*
  15696. + * Source is not aligned on a longword boundary.
  15697. + * Copy the data to insure alignment. If we fail
  15698. + * to allocate mbufs or clusters while doing this
  15699. + * we return ERESTART so the operation is requeued
  15700. + * at the crypto later, but only if there are
  15701. + * ops already posted to the hardware; otherwise we
  15702. + * have no guarantee that we'll be re-entered.
  15703. + */
  15704. + totlen = cmd->src_mapsize;
  15705. + if (cmd->src_m->m_flags & M_PKTHDR) {
  15706. + len = MHLEN;
  15707. + MGETHDR(m0, M_DONTWAIT, MT_DATA);
  15708. + if (m0 && !m_dup_pkthdr(m0, cmd->src_m, M_DONTWAIT)) {
  15709. + m_free(m0);
  15710. + m0 = NULL;
  15711. + }
  15712. + } else {
  15713. + len = MLEN;
  15714. + MGET(m0, M_DONTWAIT, MT_DATA);
  15715. + }
  15716. + if (m0 == NULL) {
  15717. + hifnstats.hst_nomem_mbuf++;
  15718. + err = dma->cmdu ? ERESTART : ENOMEM;
  15719. + goto err_srcmap;
  15720. + }
  15721. + if (totlen >= MINCLSIZE) {
  15722. + MCLGET(m0, M_DONTWAIT);
  15723. + if ((m0->m_flags & M_EXT) == 0) {
  15724. + hifnstats.hst_nomem_mcl++;
  15725. + err = dma->cmdu ? ERESTART : ENOMEM;
  15726. + m_freem(m0);
  15727. + goto err_srcmap;
  15728. + }
  15729. + len = MCLBYTES;
  15730. + }
  15731. + totlen -= len;
  15732. + m0->m_pkthdr.len = m0->m_len = len;
  15733. + mlast = m0;
  15734. +
  15735. + while (totlen > 0) {
  15736. + MGET(m, M_DONTWAIT, MT_DATA);
  15737. + if (m == NULL) {
  15738. + hifnstats.hst_nomem_mbuf++;
  15739. + err = dma->cmdu ? ERESTART : ENOMEM;
  15740. + m_freem(m0);
  15741. + goto err_srcmap;
  15742. + }
  15743. + len = MLEN;
  15744. + if (totlen >= MINCLSIZE) {
  15745. + MCLGET(m, M_DONTWAIT);
  15746. + if ((m->m_flags & M_EXT) == 0) {
  15747. + hifnstats.hst_nomem_mcl++;
  15748. + err = dma->cmdu ? ERESTART : ENOMEM;
  15749. + mlast->m_next = m;
  15750. + m_freem(m0);
  15751. + goto err_srcmap;
  15752. + }
  15753. + len = MCLBYTES;
  15754. + }
  15755. +
  15756. + m->m_len = len;
  15757. + m0->m_pkthdr.len += len;
  15758. + totlen -= len;
  15759. +
  15760. + mlast->m_next = m;
  15761. + mlast = m;
  15762. + }
  15763. + cmd->dst_m = m0;
  15764. +#else
  15765. + device_printf(sc->sc_dev,
  15766. + "%s,%d: CRYPTO_F_SKBUF unaligned not implemented\n",
  15767. + __FILE__, __LINE__);
  15768. + err = EINVAL;
  15769. + goto err_srcmap;
  15770. +#endif
  15771. + } else {
  15772. + device_printf(sc->sc_dev,
  15773. + "%s,%d: unaligned contig buffers not implemented\n",
  15774. + __FILE__, __LINE__);
  15775. + err = EINVAL;
  15776. + goto err_srcmap;
  15777. + }
  15778. + }
  15779. +
  15780. + if (cmd->dst_map == NULL) {
  15781. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  15782. + if (pci_map_skb(sc, &cmd->dst, cmd->dst_skb)) {
  15783. + hifnstats.hst_nomem_map++;
  15784. + err = ENOMEM;
  15785. + goto err_dstmap1;
  15786. + }
  15787. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  15788. + if (pci_map_uio(sc, &cmd->dst, cmd->dst_io)) {
  15789. + hifnstats.hst_nomem_load++;
  15790. + err = ENOMEM;
  15791. + goto err_dstmap1;
  15792. + }
  15793. + } else {
  15794. + if (pci_map_buf(sc, &cmd->dst, cmd->dst_buf, crp->crp_ilen)) {
  15795. + hifnstats.hst_nomem_load++;
  15796. + err = ENOMEM;
  15797. + goto err_dstmap1;
  15798. + }
  15799. + }
  15800. + }
  15801. +
  15802. +#ifdef HIFN_DEBUG
  15803. + if (hifn_debug) {
  15804. + device_printf(sc->sc_dev,
  15805. + "Entering cmd: stat %8x ien %8x u %d/%d/%d/%d n %d/%d\n",
  15806. + READ_REG_1(sc, HIFN_1_DMA_CSR),
  15807. + READ_REG_1(sc, HIFN_1_DMA_IER),
  15808. + dma->cmdu, dma->srcu, dma->dstu, dma->resu,
  15809. + cmd->src_nsegs, cmd->dst_nsegs);
  15810. + }
  15811. +#endif
  15812. +
  15813. +#if 0
  15814. + if (cmd->src_map == cmd->dst_map) {
  15815. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  15816. + BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD);
  15817. + } else {
  15818. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  15819. + BUS_DMASYNC_PREWRITE);
  15820. + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
  15821. + BUS_DMASYNC_PREREAD);
  15822. + }
  15823. +#endif
  15824. +
  15825. + /*
  15826. + * need N src, and N dst
  15827. + */
  15828. + if ((dma->srcu + cmd->src_nsegs) > HIFN_D_SRC_RSIZE ||
  15829. + (dma->dstu + cmd->dst_nsegs + 1) > HIFN_D_DST_RSIZE) {
  15830. +#ifdef HIFN_DEBUG
  15831. + if (hifn_debug) {
  15832. + device_printf(sc->sc_dev,
  15833. + "src/dst exhaustion, srcu %u+%u dstu %u+%u\n",
  15834. + dma->srcu, cmd->src_nsegs,
  15835. + dma->dstu, cmd->dst_nsegs);
  15836. + }
  15837. +#endif
  15838. + hifnstats.hst_nomem_sd++;
  15839. + err = ERESTART;
  15840. + goto err_dstmap;
  15841. + }
  15842. +
  15843. + if (dma->cmdi == HIFN_D_CMD_RSIZE) {
  15844. + dma->cmdi = 0;
  15845. + dma->cmdr[HIFN_D_CMD_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  15846. + wmb();
  15847. + dma->cmdr[HIFN_D_CMD_RSIZE].l |= htole32(HIFN_D_VALID);
  15848. + HIFN_CMDR_SYNC(sc, HIFN_D_CMD_RSIZE,
  15849. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  15850. + }
  15851. + cmdi = dma->cmdi++;
  15852. + cmdlen = hifn_write_command(cmd, dma->command_bufs[cmdi]);
  15853. + HIFN_CMD_SYNC(sc, cmdi, BUS_DMASYNC_PREWRITE);
  15854. +
  15855. + /* .p for command/result already set */
  15856. + dma->cmdr[cmdi].l = htole32(cmdlen | HIFN_D_LAST |
  15857. + HIFN_D_MASKDONEIRQ);
  15858. + wmb();
  15859. + dma->cmdr[cmdi].l |= htole32(HIFN_D_VALID);
  15860. + HIFN_CMDR_SYNC(sc, cmdi,
  15861. + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
  15862. + dma->cmdu++;
  15863. +
  15864. + /*
  15865. + * We don't worry about missing an interrupt (which a "command wait"
  15866. + * interrupt salvages us from), unless there is more than one command
  15867. + * in the queue.
  15868. + */
  15869. + if (dma->cmdu > 1) {
  15870. + sc->sc_dmaier |= HIFN_DMAIER_C_WAIT;
  15871. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  15872. + }
  15873. +
  15874. + hifnstats.hst_ipackets++;
  15875. + hifnstats.hst_ibytes += cmd->src_mapsize;
  15876. +
  15877. + hifn_dmamap_load_src(sc, cmd);
  15878. +
  15879. + /*
  15880. + * Unlike other descriptors, we don't mask done interrupt from
  15881. + * result descriptor.
  15882. + */
  15883. +#ifdef HIFN_DEBUG
  15884. + if (hifn_debug)
  15885. + device_printf(sc->sc_dev, "load res\n");
  15886. +#endif
  15887. + if (dma->resi == HIFN_D_RES_RSIZE) {
  15888. + dma->resi = 0;
  15889. + dma->resr[HIFN_D_RES_RSIZE].l = htole32(HIFN_D_JUMP|HIFN_D_MASKDONEIRQ);
  15890. + wmb();
  15891. + dma->resr[HIFN_D_RES_RSIZE].l |= htole32(HIFN_D_VALID);
  15892. + HIFN_RESR_SYNC(sc, HIFN_D_RES_RSIZE,
  15893. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  15894. + }
  15895. + resi = dma->resi++;
  15896. + KASSERT(dma->hifn_commands[resi] == NULL,
  15897. + ("hifn_crypto: command slot %u busy", resi));
  15898. + dma->hifn_commands[resi] = cmd;
  15899. + HIFN_RES_SYNC(sc, resi, BUS_DMASYNC_PREREAD);
  15900. + if ((hint & CRYPTO_HINT_MORE) && sc->sc_curbatch < hifn_maxbatch) {
  15901. + dma->resr[resi].l = htole32(HIFN_MAX_RESULT |
  15902. + HIFN_D_LAST | HIFN_D_MASKDONEIRQ);
  15903. + wmb();
  15904. + dma->resr[resi].l |= htole32(HIFN_D_VALID);
  15905. + sc->sc_curbatch++;
  15906. + if (sc->sc_curbatch > hifnstats.hst_maxbatch)
  15907. + hifnstats.hst_maxbatch = sc->sc_curbatch;
  15908. + hifnstats.hst_totbatch++;
  15909. + } else {
  15910. + dma->resr[resi].l = htole32(HIFN_MAX_RESULT | HIFN_D_LAST);
  15911. + wmb();
  15912. + dma->resr[resi].l |= htole32(HIFN_D_VALID);
  15913. + sc->sc_curbatch = 0;
  15914. + }
  15915. + HIFN_RESR_SYNC(sc, resi,
  15916. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  15917. + dma->resu++;
  15918. +
  15919. + if (cmd->sloplen)
  15920. + cmd->slopidx = resi;
  15921. +
  15922. + hifn_dmamap_load_dst(sc, cmd);
  15923. +
  15924. + csr = 0;
  15925. + if (sc->sc_c_busy == 0) {
  15926. + csr |= HIFN_DMACSR_C_CTRL_ENA;
  15927. + sc->sc_c_busy = 1;
  15928. + }
  15929. + if (sc->sc_s_busy == 0) {
  15930. + csr |= HIFN_DMACSR_S_CTRL_ENA;
  15931. + sc->sc_s_busy = 1;
  15932. + }
  15933. + if (sc->sc_r_busy == 0) {
  15934. + csr |= HIFN_DMACSR_R_CTRL_ENA;
  15935. + sc->sc_r_busy = 1;
  15936. + }
  15937. + if (sc->sc_d_busy == 0) {
  15938. + csr |= HIFN_DMACSR_D_CTRL_ENA;
  15939. + sc->sc_d_busy = 1;
  15940. + }
  15941. + if (csr)
  15942. + WRITE_REG_1(sc, HIFN_1_DMA_CSR, csr);
  15943. +
  15944. +#ifdef HIFN_DEBUG
  15945. + if (hifn_debug) {
  15946. + device_printf(sc->sc_dev, "command: stat %8x ier %8x\n",
  15947. + READ_REG_1(sc, HIFN_1_DMA_CSR),
  15948. + READ_REG_1(sc, HIFN_1_DMA_IER));
  15949. + }
  15950. +#endif
  15951. +
  15952. + sc->sc_active = 5;
  15953. + HIFN_UNLOCK(sc);
  15954. + KASSERT(err == 0, ("hifn_crypto: success with error %u", err));
  15955. + return (err); /* success */
  15956. +
  15957. +err_dstmap:
  15958. + if (cmd->src_map != cmd->dst_map)
  15959. + pci_unmap_buf(sc, &cmd->dst);
  15960. +err_dstmap1:
  15961. +err_srcmap:
  15962. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  15963. + if (cmd->src_skb != cmd->dst_skb)
  15964. +#ifdef NOTYET
  15965. + m_freem(cmd->dst_m);
  15966. +#else
  15967. + device_printf(sc->sc_dev,
  15968. + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
  15969. + __FILE__, __LINE__);
  15970. +#endif
  15971. + }
  15972. + pci_unmap_buf(sc, &cmd->src);
  15973. +err_srcmap1:
  15974. + HIFN_UNLOCK(sc);
  15975. + return (err);
  15976. +}
  15977. +
  15978. +static void
  15979. +hifn_tick(unsigned long arg)
  15980. +{
  15981. + struct hifn_softc *sc;
  15982. + unsigned long l_flags;
  15983. +
  15984. + if (arg >= HIFN_MAX_CHIPS)
  15985. + return;
  15986. + sc = hifn_chip_idx[arg];
  15987. + if (!sc)
  15988. + return;
  15989. +
  15990. + HIFN_LOCK(sc);
  15991. + if (sc->sc_active == 0) {
  15992. + struct hifn_dma *dma = sc->sc_dma;
  15993. + u_int32_t r = 0;
  15994. +
  15995. + if (dma->cmdu == 0 && sc->sc_c_busy) {
  15996. + sc->sc_c_busy = 0;
  15997. + r |= HIFN_DMACSR_C_CTRL_DIS;
  15998. + }
  15999. + if (dma->srcu == 0 && sc->sc_s_busy) {
  16000. + sc->sc_s_busy = 0;
  16001. + r |= HIFN_DMACSR_S_CTRL_DIS;
  16002. + }
  16003. + if (dma->dstu == 0 && sc->sc_d_busy) {
  16004. + sc->sc_d_busy = 0;
  16005. + r |= HIFN_DMACSR_D_CTRL_DIS;
  16006. + }
  16007. + if (dma->resu == 0 && sc->sc_r_busy) {
  16008. + sc->sc_r_busy = 0;
  16009. + r |= HIFN_DMACSR_R_CTRL_DIS;
  16010. + }
  16011. + if (r)
  16012. + WRITE_REG_1(sc, HIFN_1_DMA_CSR, r);
  16013. + } else
  16014. + sc->sc_active--;
  16015. + HIFN_UNLOCK(sc);
  16016. + mod_timer(&sc->sc_tickto, jiffies + HZ);
  16017. +}
  16018. +
  16019. +static irqreturn_t
  16020. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  16021. +hifn_intr(int irq, void *arg)
  16022. +#else
  16023. +hifn_intr(int irq, void *arg, struct pt_regs *regs)
  16024. +#endif
  16025. +{
  16026. + struct hifn_softc *sc = arg;
  16027. + struct hifn_dma *dma;
  16028. + u_int32_t dmacsr, restart;
  16029. + int i, u;
  16030. + unsigned long l_flags;
  16031. +
  16032. + dmacsr = READ_REG_1(sc, HIFN_1_DMA_CSR);
  16033. +
  16034. + /* Nothing in the DMA unit interrupted */
  16035. + if ((dmacsr & sc->sc_dmaier) == 0)
  16036. + return IRQ_NONE;
  16037. +
  16038. + HIFN_LOCK(sc);
  16039. +
  16040. + dma = sc->sc_dma;
  16041. +
  16042. +#ifdef HIFN_DEBUG
  16043. + if (hifn_debug) {
  16044. + device_printf(sc->sc_dev,
  16045. + "irq: stat %08x ien %08x damier %08x i %d/%d/%d/%d k %d/%d/%d/%d u %d/%d/%d/%d\n",
  16046. + dmacsr, READ_REG_1(sc, HIFN_1_DMA_IER), sc->sc_dmaier,
  16047. + dma->cmdi, dma->srci, dma->dsti, dma->resi,
  16048. + dma->cmdk, dma->srck, dma->dstk, dma->resk,
  16049. + dma->cmdu, dma->srcu, dma->dstu, dma->resu);
  16050. + }
  16051. +#endif
  16052. +
  16053. + WRITE_REG_1(sc, HIFN_1_DMA_CSR, dmacsr & sc->sc_dmaier);
  16054. +
  16055. + if ((sc->sc_flags & HIFN_HAS_PUBLIC) &&
  16056. + (dmacsr & HIFN_DMACSR_PUBDONE))
  16057. + WRITE_REG_1(sc, HIFN_1_PUB_STATUS,
  16058. + READ_REG_1(sc, HIFN_1_PUB_STATUS) | HIFN_PUBSTS_DONE);
  16059. +
  16060. + restart = dmacsr & (HIFN_DMACSR_D_OVER | HIFN_DMACSR_R_OVER);
  16061. + if (restart)
  16062. + device_printf(sc->sc_dev, "overrun %x\n", dmacsr);
  16063. +
  16064. + if (sc->sc_flags & HIFN_IS_7811) {
  16065. + if (dmacsr & HIFN_DMACSR_ILLR)
  16066. + device_printf(sc->sc_dev, "illegal read\n");
  16067. + if (dmacsr & HIFN_DMACSR_ILLW)
  16068. + device_printf(sc->sc_dev, "illegal write\n");
  16069. + }
  16070. +
  16071. + restart = dmacsr & (HIFN_DMACSR_C_ABORT | HIFN_DMACSR_S_ABORT |
  16072. + HIFN_DMACSR_D_ABORT | HIFN_DMACSR_R_ABORT);
  16073. + if (restart) {
  16074. + device_printf(sc->sc_dev, "abort, resetting.\n");
  16075. + hifnstats.hst_abort++;
  16076. + hifn_abort(sc);
  16077. + HIFN_UNLOCK(sc);
  16078. + return IRQ_HANDLED;
  16079. + }
  16080. +
  16081. + if ((dmacsr & HIFN_DMACSR_C_WAIT) && (dma->cmdu == 0)) {
  16082. + /*
  16083. + * If no slots to process and we receive a "waiting on
  16084. + * command" interrupt, we disable the "waiting on command"
  16085. + * (by clearing it).
  16086. + */
  16087. + sc->sc_dmaier &= ~HIFN_DMAIER_C_WAIT;
  16088. + WRITE_REG_1(sc, HIFN_1_DMA_IER, sc->sc_dmaier);
  16089. + }
  16090. +
  16091. + /* clear the rings */
  16092. + i = dma->resk; u = dma->resu;
  16093. + while (u != 0) {
  16094. + HIFN_RESR_SYNC(sc, i,
  16095. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  16096. + if (dma->resr[i].l & htole32(HIFN_D_VALID)) {
  16097. + HIFN_RESR_SYNC(sc, i,
  16098. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  16099. + break;
  16100. + }
  16101. +
  16102. + if (i != HIFN_D_RES_RSIZE) {
  16103. + struct hifn_command *cmd;
  16104. + u_int8_t *macbuf = NULL;
  16105. +
  16106. + HIFN_RES_SYNC(sc, i, BUS_DMASYNC_POSTREAD);
  16107. + cmd = dma->hifn_commands[i];
  16108. + KASSERT(cmd != NULL,
  16109. + ("hifn_intr: null command slot %u", i));
  16110. + dma->hifn_commands[i] = NULL;
  16111. +
  16112. + if (cmd->base_masks & HIFN_BASE_CMD_MAC) {
  16113. + macbuf = dma->result_bufs[i];
  16114. + macbuf += 12;
  16115. + }
  16116. +
  16117. + hifn_callback(sc, cmd, macbuf);
  16118. + hifnstats.hst_opackets++;
  16119. + u--;
  16120. + }
  16121. +
  16122. + if (++i == (HIFN_D_RES_RSIZE + 1))
  16123. + i = 0;
  16124. + }
  16125. + dma->resk = i; dma->resu = u;
  16126. +
  16127. + i = dma->srck; u = dma->srcu;
  16128. + while (u != 0) {
  16129. + if (i == HIFN_D_SRC_RSIZE)
  16130. + i = 0;
  16131. + HIFN_SRCR_SYNC(sc, i,
  16132. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  16133. + if (dma->srcr[i].l & htole32(HIFN_D_VALID)) {
  16134. + HIFN_SRCR_SYNC(sc, i,
  16135. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  16136. + break;
  16137. + }
  16138. + i++, u--;
  16139. + }
  16140. + dma->srck = i; dma->srcu = u;
  16141. +
  16142. + i = dma->cmdk; u = dma->cmdu;
  16143. + while (u != 0) {
  16144. + HIFN_CMDR_SYNC(sc, i,
  16145. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  16146. + if (dma->cmdr[i].l & htole32(HIFN_D_VALID)) {
  16147. + HIFN_CMDR_SYNC(sc, i,
  16148. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  16149. + break;
  16150. + }
  16151. + if (i != HIFN_D_CMD_RSIZE) {
  16152. + u--;
  16153. + HIFN_CMD_SYNC(sc, i, BUS_DMASYNC_POSTWRITE);
  16154. + }
  16155. + if (++i == (HIFN_D_CMD_RSIZE + 1))
  16156. + i = 0;
  16157. + }
  16158. + dma->cmdk = i; dma->cmdu = u;
  16159. +
  16160. + HIFN_UNLOCK(sc);
  16161. +
  16162. + if (sc->sc_needwakeup) { /* XXX check high watermark */
  16163. + int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
  16164. +#ifdef HIFN_DEBUG
  16165. + if (hifn_debug)
  16166. + device_printf(sc->sc_dev,
  16167. + "wakeup crypto (%x) u %d/%d/%d/%d\n",
  16168. + sc->sc_needwakeup,
  16169. + dma->cmdu, dma->srcu, dma->dstu, dma->resu);
  16170. +#endif
  16171. + sc->sc_needwakeup &= ~wakeup;
  16172. + crypto_unblock(sc->sc_cid, wakeup);
  16173. + }
  16174. +
  16175. + return IRQ_HANDLED;
  16176. +}
  16177. +
  16178. +/*
  16179. + * Allocate a new 'session' and return an encoded session id. 'sidp'
  16180. + * contains our registration id, and should contain an encoded session
  16181. + * id on successful allocation.
  16182. + */
  16183. +static int
  16184. +hifn_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  16185. +{
  16186. + struct hifn_softc *sc = device_get_softc(dev);
  16187. + struct cryptoini *c;
  16188. + int mac = 0, cry = 0, sesn;
  16189. + struct hifn_session *ses = NULL;
  16190. + unsigned long l_flags;
  16191. +
  16192. + DPRINTF("%s()\n", __FUNCTION__);
  16193. +
  16194. + KASSERT(sc != NULL, ("hifn_newsession: null softc"));
  16195. + if (sidp == NULL || cri == NULL || sc == NULL) {
  16196. + DPRINTF("%s,%d: %s - EINVAL\n", __FILE__, __LINE__, __FUNCTION__);
  16197. + return (EINVAL);
  16198. + }
  16199. +
  16200. + HIFN_LOCK(sc);
  16201. + if (sc->sc_sessions == NULL) {
  16202. + ses = sc->sc_sessions = (struct hifn_session *)kmalloc(sizeof(*ses),
  16203. + SLAB_ATOMIC);
  16204. + if (ses == NULL) {
  16205. + HIFN_UNLOCK(sc);
  16206. + return (ENOMEM);
  16207. + }
  16208. + sesn = 0;
  16209. + sc->sc_nsessions = 1;
  16210. + } else {
  16211. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  16212. + if (!sc->sc_sessions[sesn].hs_used) {
  16213. + ses = &sc->sc_sessions[sesn];
  16214. + break;
  16215. + }
  16216. + }
  16217. +
  16218. + if (ses == NULL) {
  16219. + sesn = sc->sc_nsessions;
  16220. + ses = (struct hifn_session *)kmalloc((sesn + 1) * sizeof(*ses),
  16221. + SLAB_ATOMIC);
  16222. + if (ses == NULL) {
  16223. + HIFN_UNLOCK(sc);
  16224. + return (ENOMEM);
  16225. + }
  16226. + bcopy(sc->sc_sessions, ses, sesn * sizeof(*ses));
  16227. + bzero(sc->sc_sessions, sesn * sizeof(*ses));
  16228. + kfree(sc->sc_sessions);
  16229. + sc->sc_sessions = ses;
  16230. + ses = &sc->sc_sessions[sesn];
  16231. + sc->sc_nsessions++;
  16232. + }
  16233. + }
  16234. + HIFN_UNLOCK(sc);
  16235. +
  16236. + bzero(ses, sizeof(*ses));
  16237. + ses->hs_used = 1;
  16238. +
  16239. + for (c = cri; c != NULL; c = c->cri_next) {
  16240. + switch (c->cri_alg) {
  16241. + case CRYPTO_MD5:
  16242. + case CRYPTO_SHA1:
  16243. + case CRYPTO_MD5_HMAC:
  16244. + case CRYPTO_SHA1_HMAC:
  16245. + if (mac) {
  16246. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  16247. + return (EINVAL);
  16248. + }
  16249. + mac = 1;
  16250. + ses->hs_mlen = c->cri_mlen;
  16251. + if (ses->hs_mlen == 0) {
  16252. + switch (c->cri_alg) {
  16253. + case CRYPTO_MD5:
  16254. + case CRYPTO_MD5_HMAC:
  16255. + ses->hs_mlen = 16;
  16256. + break;
  16257. + case CRYPTO_SHA1:
  16258. + case CRYPTO_SHA1_HMAC:
  16259. + ses->hs_mlen = 20;
  16260. + break;
  16261. + }
  16262. + }
  16263. + break;
  16264. + case CRYPTO_DES_CBC:
  16265. + case CRYPTO_3DES_CBC:
  16266. + case CRYPTO_AES_CBC:
  16267. + /* XXX this may read fewer, does it matter? */
  16268. + read_random(ses->hs_iv,
  16269. + c->cri_alg == CRYPTO_AES_CBC ?
  16270. + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
  16271. + /*FALLTHROUGH*/
  16272. + case CRYPTO_ARC4:
  16273. + if (cry) {
  16274. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  16275. + return (EINVAL);
  16276. + }
  16277. + cry = 1;
  16278. + break;
  16279. + default:
  16280. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  16281. + return (EINVAL);
  16282. + }
  16283. + }
  16284. + if (mac == 0 && cry == 0) {
  16285. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  16286. + return (EINVAL);
  16287. + }
  16288. +
  16289. + *sidp = HIFN_SID(device_get_unit(sc->sc_dev), sesn);
  16290. +
  16291. + return (0);
  16292. +}
  16293. +
  16294. +/*
  16295. + * Deallocate a session.
  16296. + * XXX this routine should run a zero'd mac/encrypt key into context ram.
  16297. + * XXX to blow away any keys already stored there.
  16298. + */
  16299. +static int
  16300. +hifn_freesession(device_t dev, u_int64_t tid)
  16301. +{
  16302. + struct hifn_softc *sc = device_get_softc(dev);
  16303. + int session, error;
  16304. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  16305. + unsigned long l_flags;
  16306. +
  16307. + DPRINTF("%s()\n", __FUNCTION__);
  16308. +
  16309. + KASSERT(sc != NULL, ("hifn_freesession: null softc"));
  16310. + if (sc == NULL) {
  16311. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  16312. + return (EINVAL);
  16313. + }
  16314. +
  16315. + HIFN_LOCK(sc);
  16316. + session = HIFN_SESSION(sid);
  16317. + if (session < sc->sc_nsessions) {
  16318. + bzero(&sc->sc_sessions[session], sizeof(struct hifn_session));
  16319. + error = 0;
  16320. + } else {
  16321. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  16322. + error = EINVAL;
  16323. + }
  16324. + HIFN_UNLOCK(sc);
  16325. +
  16326. + return (error);
  16327. +}
  16328. +
  16329. +static int
  16330. +hifn_process(device_t dev, struct cryptop *crp, int hint)
  16331. +{
  16332. + struct hifn_softc *sc = device_get_softc(dev);
  16333. + struct hifn_command *cmd = NULL;
  16334. + int session, err, ivlen;
  16335. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  16336. +
  16337. + DPRINTF("%s()\n", __FUNCTION__);
  16338. +
  16339. + if (crp == NULL || crp->crp_callback == NULL) {
  16340. + hifnstats.hst_invalid++;
  16341. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  16342. + return (EINVAL);
  16343. + }
  16344. + session = HIFN_SESSION(crp->crp_sid);
  16345. +
  16346. + if (sc == NULL || session >= sc->sc_nsessions) {
  16347. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  16348. + err = EINVAL;
  16349. + goto errout;
  16350. + }
  16351. +
  16352. + cmd = kmalloc(sizeof(struct hifn_command), SLAB_ATOMIC);
  16353. + if (cmd == NULL) {
  16354. + hifnstats.hst_nomem++;
  16355. + err = ENOMEM;
  16356. + goto errout;
  16357. + }
  16358. + memset(cmd, 0, sizeof(*cmd));
  16359. +
  16360. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  16361. + cmd->src_skb = (struct sk_buff *)crp->crp_buf;
  16362. + cmd->dst_skb = (struct sk_buff *)crp->crp_buf;
  16363. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  16364. + cmd->src_io = (struct uio *)crp->crp_buf;
  16365. + cmd->dst_io = (struct uio *)crp->crp_buf;
  16366. + } else {
  16367. + cmd->src_buf = crp->crp_buf;
  16368. + cmd->dst_buf = crp->crp_buf;
  16369. + }
  16370. +
  16371. + crd1 = crp->crp_desc;
  16372. + if (crd1 == NULL) {
  16373. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  16374. + err = EINVAL;
  16375. + goto errout;
  16376. + }
  16377. + crd2 = crd1->crd_next;
  16378. +
  16379. + if (crd2 == NULL) {
  16380. + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
  16381. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  16382. + crd1->crd_alg == CRYPTO_SHA1 ||
  16383. + crd1->crd_alg == CRYPTO_MD5) {
  16384. + maccrd = crd1;
  16385. + enccrd = NULL;
  16386. + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
  16387. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  16388. + crd1->crd_alg == CRYPTO_AES_CBC ||
  16389. + crd1->crd_alg == CRYPTO_ARC4) {
  16390. + if ((crd1->crd_flags & CRD_F_ENCRYPT) == 0)
  16391. + cmd->base_masks |= HIFN_BASE_CMD_DECODE;
  16392. + maccrd = NULL;
  16393. + enccrd = crd1;
  16394. + } else {
  16395. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  16396. + err = EINVAL;
  16397. + goto errout;
  16398. + }
  16399. + } else {
  16400. + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
  16401. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  16402. + crd1->crd_alg == CRYPTO_MD5 ||
  16403. + crd1->crd_alg == CRYPTO_SHA1) &&
  16404. + (crd2->crd_alg == CRYPTO_DES_CBC ||
  16405. + crd2->crd_alg == CRYPTO_3DES_CBC ||
  16406. + crd2->crd_alg == CRYPTO_AES_CBC ||
  16407. + crd2->crd_alg == CRYPTO_ARC4) &&
  16408. + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
  16409. + cmd->base_masks = HIFN_BASE_CMD_DECODE;
  16410. + maccrd = crd1;
  16411. + enccrd = crd2;
  16412. + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
  16413. + crd1->crd_alg == CRYPTO_ARC4 ||
  16414. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  16415. + crd1->crd_alg == CRYPTO_AES_CBC) &&
  16416. + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
  16417. + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
  16418. + crd2->crd_alg == CRYPTO_MD5 ||
  16419. + crd2->crd_alg == CRYPTO_SHA1) &&
  16420. + (crd1->crd_flags & CRD_F_ENCRYPT)) {
  16421. + enccrd = crd1;
  16422. + maccrd = crd2;
  16423. + } else {
  16424. + /*
  16425. + * We cannot order the 7751 as requested
  16426. + */
  16427. + DPRINTF("%s,%d: %s %d,%d,%d - EINVAL\n",__FILE__,__LINE__,__FUNCTION__, crd1->crd_alg, crd2->crd_alg, crd1->crd_flags & CRD_F_ENCRYPT);
  16428. + err = EINVAL;
  16429. + goto errout;
  16430. + }
  16431. + }
  16432. +
  16433. + if (enccrd) {
  16434. + cmd->enccrd = enccrd;
  16435. + cmd->base_masks |= HIFN_BASE_CMD_CRYPT;
  16436. + switch (enccrd->crd_alg) {
  16437. + case CRYPTO_ARC4:
  16438. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_RC4;
  16439. + break;
  16440. + case CRYPTO_DES_CBC:
  16441. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_DES |
  16442. + HIFN_CRYPT_CMD_MODE_CBC |
  16443. + HIFN_CRYPT_CMD_NEW_IV;
  16444. + break;
  16445. + case CRYPTO_3DES_CBC:
  16446. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_3DES |
  16447. + HIFN_CRYPT_CMD_MODE_CBC |
  16448. + HIFN_CRYPT_CMD_NEW_IV;
  16449. + break;
  16450. + case CRYPTO_AES_CBC:
  16451. + cmd->cry_masks |= HIFN_CRYPT_CMD_ALG_AES |
  16452. + HIFN_CRYPT_CMD_MODE_CBC |
  16453. + HIFN_CRYPT_CMD_NEW_IV;
  16454. + break;
  16455. + default:
  16456. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  16457. + err = EINVAL;
  16458. + goto errout;
  16459. + }
  16460. + if (enccrd->crd_alg != CRYPTO_ARC4) {
  16461. + ivlen = ((enccrd->crd_alg == CRYPTO_AES_CBC) ?
  16462. + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
  16463. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  16464. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  16465. + bcopy(enccrd->crd_iv, cmd->iv, ivlen);
  16466. + else
  16467. + bcopy(sc->sc_sessions[session].hs_iv,
  16468. + cmd->iv, ivlen);
  16469. +
  16470. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT)
  16471. + == 0) {
  16472. + crypto_copyback(crp->crp_flags,
  16473. + crp->crp_buf, enccrd->crd_inject,
  16474. + ivlen, cmd->iv);
  16475. + }
  16476. + } else {
  16477. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  16478. + bcopy(enccrd->crd_iv, cmd->iv, ivlen);
  16479. + else {
  16480. + crypto_copydata(crp->crp_flags,
  16481. + crp->crp_buf, enccrd->crd_inject,
  16482. + ivlen, cmd->iv);
  16483. + }
  16484. + }
  16485. + }
  16486. +
  16487. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
  16488. + cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
  16489. + cmd->ck = enccrd->crd_key;
  16490. + cmd->cklen = enccrd->crd_klen >> 3;
  16491. + cmd->cry_masks |= HIFN_CRYPT_CMD_NEW_KEY;
  16492. +
  16493. + /*
  16494. + * Need to specify the size for the AES key in the masks.
  16495. + */
  16496. + if ((cmd->cry_masks & HIFN_CRYPT_CMD_ALG_MASK) ==
  16497. + HIFN_CRYPT_CMD_ALG_AES) {
  16498. + switch (cmd->cklen) {
  16499. + case 16:
  16500. + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_128;
  16501. + break;
  16502. + case 24:
  16503. + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_192;
  16504. + break;
  16505. + case 32:
  16506. + cmd->cry_masks |= HIFN_CRYPT_CMD_KSZ_256;
  16507. + break;
  16508. + default:
  16509. + DPRINTF("%s,%d: %s - EINVAL\n",__FILE__,__LINE__,__FUNCTION__);
  16510. + err = EINVAL;
  16511. + goto errout;
  16512. + }
  16513. + }
  16514. + }
  16515. +
  16516. + if (maccrd) {
  16517. + cmd->maccrd = maccrd;
  16518. + cmd->base_masks |= HIFN_BASE_CMD_MAC;
  16519. +
  16520. + switch (maccrd->crd_alg) {
  16521. + case CRYPTO_MD5:
  16522. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |
  16523. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |
  16524. + HIFN_MAC_CMD_POS_IPSEC;
  16525. + break;
  16526. + case CRYPTO_MD5_HMAC:
  16527. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_MD5 |
  16528. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |
  16529. + HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;
  16530. + break;
  16531. + case CRYPTO_SHA1:
  16532. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |
  16533. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HASH |
  16534. + HIFN_MAC_CMD_POS_IPSEC;
  16535. + break;
  16536. + case CRYPTO_SHA1_HMAC:
  16537. + cmd->mac_masks |= HIFN_MAC_CMD_ALG_SHA1 |
  16538. + HIFN_MAC_CMD_RESULT | HIFN_MAC_CMD_MODE_HMAC |
  16539. + HIFN_MAC_CMD_POS_IPSEC | HIFN_MAC_CMD_TRUNC;
  16540. + break;
  16541. + }
  16542. +
  16543. + if (maccrd->crd_alg == CRYPTO_SHA1_HMAC ||
  16544. + maccrd->crd_alg == CRYPTO_MD5_HMAC) {
  16545. + cmd->mac_masks |= HIFN_MAC_CMD_NEW_KEY;
  16546. + bcopy(maccrd->crd_key, cmd->mac, maccrd->crd_klen >> 3);
  16547. + bzero(cmd->mac + (maccrd->crd_klen >> 3),
  16548. + HIFN_MAC_KEY_LENGTH - (maccrd->crd_klen >> 3));
  16549. + }
  16550. + }
  16551. +
  16552. + cmd->crp = crp;
  16553. + cmd->session_num = session;
  16554. + cmd->softc = sc;
  16555. +
  16556. + err = hifn_crypto(sc, cmd, crp, hint);
  16557. + if (!err) {
  16558. + return 0;
  16559. + } else if (err == ERESTART) {
  16560. + /*
  16561. + * There weren't enough resources to dispatch the request
  16562. + * to the part. Notify the caller so they'll requeue this
  16563. + * request and resubmit it again soon.
  16564. + */
  16565. +#ifdef HIFN_DEBUG
  16566. + if (hifn_debug)
  16567. + device_printf(sc->sc_dev, "requeue request\n");
  16568. +#endif
  16569. + kfree(cmd);
  16570. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  16571. + return (err);
  16572. + }
  16573. +
  16574. +errout:
  16575. + if (cmd != NULL)
  16576. + kfree(cmd);
  16577. + if (err == EINVAL)
  16578. + hifnstats.hst_invalid++;
  16579. + else
  16580. + hifnstats.hst_nomem++;
  16581. + crp->crp_etype = err;
  16582. + crypto_done(crp);
  16583. + return (err);
  16584. +}
  16585. +
  16586. +static void
  16587. +hifn_abort(struct hifn_softc *sc)
  16588. +{
  16589. + struct hifn_dma *dma = sc->sc_dma;
  16590. + struct hifn_command *cmd;
  16591. + struct cryptop *crp;
  16592. + int i, u;
  16593. +
  16594. + DPRINTF("%s()\n", __FUNCTION__);
  16595. +
  16596. + i = dma->resk; u = dma->resu;
  16597. + while (u != 0) {
  16598. + cmd = dma->hifn_commands[i];
  16599. + KASSERT(cmd != NULL, ("hifn_abort: null command slot %u", i));
  16600. + dma->hifn_commands[i] = NULL;
  16601. + crp = cmd->crp;
  16602. +
  16603. + if ((dma->resr[i].l & htole32(HIFN_D_VALID)) == 0) {
  16604. + /* Salvage what we can. */
  16605. + u_int8_t *macbuf;
  16606. +
  16607. + if (cmd->base_masks & HIFN_BASE_CMD_MAC) {
  16608. + macbuf = dma->result_bufs[i];
  16609. + macbuf += 12;
  16610. + } else
  16611. + macbuf = NULL;
  16612. + hifnstats.hst_opackets++;
  16613. + hifn_callback(sc, cmd, macbuf);
  16614. + } else {
  16615. +#if 0
  16616. + if (cmd->src_map == cmd->dst_map) {
  16617. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  16618. + BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
  16619. + } else {
  16620. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  16621. + BUS_DMASYNC_POSTWRITE);
  16622. + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
  16623. + BUS_DMASYNC_POSTREAD);
  16624. + }
  16625. +#endif
  16626. +
  16627. + if (cmd->src_skb != cmd->dst_skb) {
  16628. +#ifdef NOTYET
  16629. + m_freem(cmd->src_m);
  16630. + crp->crp_buf = (caddr_t)cmd->dst_m;
  16631. +#else
  16632. + device_printf(sc->sc_dev,
  16633. + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
  16634. + __FILE__, __LINE__);
  16635. +#endif
  16636. + }
  16637. +
  16638. + /* non-shared buffers cannot be restarted */
  16639. + if (cmd->src_map != cmd->dst_map) {
  16640. + /*
  16641. + * XXX should be EAGAIN, delayed until
  16642. + * after the reset.
  16643. + */
  16644. + crp->crp_etype = ENOMEM;
  16645. + pci_unmap_buf(sc, &cmd->dst);
  16646. + } else
  16647. + crp->crp_etype = ENOMEM;
  16648. +
  16649. + pci_unmap_buf(sc, &cmd->src);
  16650. +
  16651. + kfree(cmd);
  16652. + if (crp->crp_etype != EAGAIN)
  16653. + crypto_done(crp);
  16654. + }
  16655. +
  16656. + if (++i == HIFN_D_RES_RSIZE)
  16657. + i = 0;
  16658. + u--;
  16659. + }
  16660. + dma->resk = i; dma->resu = u;
  16661. +
  16662. + hifn_reset_board(sc, 1);
  16663. + hifn_init_dma(sc);
  16664. + hifn_init_pci_registers(sc);
  16665. +}
  16666. +
  16667. +static void
  16668. +hifn_callback(struct hifn_softc *sc, struct hifn_command *cmd, u_int8_t *macbuf)
  16669. +{
  16670. + struct hifn_dma *dma = sc->sc_dma;
  16671. + struct cryptop *crp = cmd->crp;
  16672. + struct cryptodesc *crd;
  16673. + int i, u, ivlen;
  16674. +
  16675. + DPRINTF("%s()\n", __FUNCTION__);
  16676. +
  16677. +#if 0
  16678. + if (cmd->src_map == cmd->dst_map) {
  16679. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  16680. + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD);
  16681. + } else {
  16682. + bus_dmamap_sync(sc->sc_dmat, cmd->src_map,
  16683. + BUS_DMASYNC_POSTWRITE);
  16684. + bus_dmamap_sync(sc->sc_dmat, cmd->dst_map,
  16685. + BUS_DMASYNC_POSTREAD);
  16686. + }
  16687. +#endif
  16688. +
  16689. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  16690. + if (cmd->src_skb != cmd->dst_skb) {
  16691. +#ifdef NOTYET
  16692. + crp->crp_buf = (caddr_t)cmd->dst_m;
  16693. + totlen = cmd->src_mapsize;
  16694. + for (m = cmd->dst_m; m != NULL; m = m->m_next) {
  16695. + if (totlen < m->m_len) {
  16696. + m->m_len = totlen;
  16697. + totlen = 0;
  16698. + } else
  16699. + totlen -= m->m_len;
  16700. + }
  16701. + cmd->dst_m->m_pkthdr.len = cmd->src_m->m_pkthdr.len;
  16702. + m_freem(cmd->src_m);
  16703. +#else
  16704. + device_printf(sc->sc_dev,
  16705. + "%s,%d: CRYPTO_F_SKBUF src != dst not implemented\n",
  16706. + __FILE__, __LINE__);
  16707. +#endif
  16708. + }
  16709. + }
  16710. +
  16711. + if (cmd->sloplen != 0) {
  16712. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  16713. + cmd->src_mapsize - cmd->sloplen, cmd->sloplen,
  16714. + (caddr_t)&dma->slop[cmd->slopidx]);
  16715. + }
  16716. +
  16717. + i = dma->dstk; u = dma->dstu;
  16718. + while (u != 0) {
  16719. + if (i == HIFN_D_DST_RSIZE)
  16720. + i = 0;
  16721. +#if 0
  16722. + bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
  16723. + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
  16724. +#endif
  16725. + if (dma->dstr[i].l & htole32(HIFN_D_VALID)) {
  16726. +#if 0
  16727. + bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap,
  16728. + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
  16729. +#endif
  16730. + break;
  16731. + }
  16732. + i++, u--;
  16733. + }
  16734. + dma->dstk = i; dma->dstu = u;
  16735. +
  16736. + hifnstats.hst_obytes += cmd->dst_mapsize;
  16737. +
  16738. + if ((cmd->base_masks & (HIFN_BASE_CMD_CRYPT | HIFN_BASE_CMD_DECODE)) ==
  16739. + HIFN_BASE_CMD_CRYPT) {
  16740. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  16741. + if (crd->crd_alg != CRYPTO_DES_CBC &&
  16742. + crd->crd_alg != CRYPTO_3DES_CBC &&
  16743. + crd->crd_alg != CRYPTO_AES_CBC)
  16744. + continue;
  16745. + ivlen = ((crd->crd_alg == CRYPTO_AES_CBC) ?
  16746. + HIFN_AES_IV_LENGTH : HIFN_IV_LENGTH);
  16747. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  16748. + crd->crd_skip + crd->crd_len - ivlen, ivlen,
  16749. + cmd->softc->sc_sessions[cmd->session_num].hs_iv);
  16750. + break;
  16751. + }
  16752. + }
  16753. +
  16754. + if (macbuf != NULL) {
  16755. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  16756. + int len;
  16757. +
  16758. + if (crd->crd_alg != CRYPTO_MD5 &&
  16759. + crd->crd_alg != CRYPTO_SHA1 &&
  16760. + crd->crd_alg != CRYPTO_MD5_HMAC &&
  16761. + crd->crd_alg != CRYPTO_SHA1_HMAC) {
  16762. + continue;
  16763. + }
  16764. + len = cmd->softc->sc_sessions[cmd->session_num].hs_mlen;
  16765. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  16766. + crd->crd_inject, len, macbuf);
  16767. + break;
  16768. + }
  16769. + }
  16770. +
  16771. + if (cmd->src_map != cmd->dst_map)
  16772. + pci_unmap_buf(sc, &cmd->dst);
  16773. + pci_unmap_buf(sc, &cmd->src);
  16774. + kfree(cmd);
  16775. + crypto_done(crp);
  16776. +}
  16777. +
  16778. +/*
  16779. + * 7811 PB3 rev/2 parts lock-up on burst writes to Group 0
  16780. + * and Group 1 registers; avoid conditions that could create
  16781. + * burst writes by doing a read in between the writes.
  16782. + *
  16783. + * NB: The read we interpose is always to the same register;
  16784. + * we do this because reading from an arbitrary (e.g. last)
  16785. + * register may not always work.
  16786. + */
  16787. +static void
  16788. +hifn_write_reg_0(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
  16789. +{
  16790. + if (sc->sc_flags & HIFN_IS_7811) {
  16791. + if (sc->sc_bar0_lastreg == reg - 4)
  16792. + readl(sc->sc_bar0 + HIFN_0_PUCNFG);
  16793. + sc->sc_bar0_lastreg = reg;
  16794. + }
  16795. + writel(val, sc->sc_bar0 + reg);
  16796. +}
  16797. +
  16798. +static void
  16799. +hifn_write_reg_1(struct hifn_softc *sc, bus_size_t reg, u_int32_t val)
  16800. +{
  16801. + if (sc->sc_flags & HIFN_IS_7811) {
  16802. + if (sc->sc_bar1_lastreg == reg - 4)
  16803. + readl(sc->sc_bar1 + HIFN_1_REVID);
  16804. + sc->sc_bar1_lastreg = reg;
  16805. + }
  16806. + writel(val, sc->sc_bar1 + reg);
  16807. +}
  16808. +
  16809. +
  16810. +static struct pci_device_id hifn_pci_tbl[] = {
  16811. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7951,
  16812. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  16813. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7955,
  16814. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  16815. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7956,
  16816. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  16817. + { PCI_VENDOR_NETSEC, PCI_PRODUCT_NETSEC_7751,
  16818. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  16819. + { PCI_VENDOR_INVERTEX, PCI_PRODUCT_INVERTEX_AEON,
  16820. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  16821. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7811,
  16822. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  16823. + /*
  16824. + * Other vendors share this PCI ID as well, such as
  16825. + * http://www.powercrypt.com, and obviously they also
  16826. + * use the same key.
  16827. + */
  16828. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7751,
  16829. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  16830. + { 0, 0, 0, 0, 0, 0, }
  16831. +};
  16832. +MODULE_DEVICE_TABLE(pci, hifn_pci_tbl);
  16833. +
  16834. +static struct pci_driver hifn_driver = {
  16835. + .name = "hifn",
  16836. + .id_table = hifn_pci_tbl,
  16837. + .probe = hifn_probe,
  16838. + .remove = hifn_remove,
  16839. + /* add PM stuff here one day */
  16840. +};
  16841. +
  16842. +static int __init hifn_init (void)
  16843. +{
  16844. + struct hifn_softc *sc = NULL;
  16845. + int rc;
  16846. +
  16847. + DPRINTF("%s(%p)\n", __FUNCTION__, hifn_init);
  16848. +
  16849. + rc = pci_register_driver(&hifn_driver);
  16850. + pci_register_driver_compat(&hifn_driver, rc);
  16851. +
  16852. + return rc;
  16853. +}
  16854. +
  16855. +static void __exit hifn_exit (void)
  16856. +{
  16857. + pci_unregister_driver(&hifn_driver);
  16858. +}
  16859. +
  16860. +module_init(hifn_init);
  16861. +module_exit(hifn_exit);
  16862. +
  16863. +MODULE_LICENSE("BSD");
  16864. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  16865. +MODULE_DESCRIPTION("OCF driver for hifn PCI crypto devices");
  16866. diff -Nur linux-2.6.39.orig/crypto/ocf/hifn/hifn7751reg.h linux-2.6.39/crypto/ocf/hifn/hifn7751reg.h
  16867. --- linux-2.6.39.orig/crypto/ocf/hifn/hifn7751reg.h 1970-01-01 01:00:00.000000000 +0100
  16868. +++ linux-2.6.39/crypto/ocf/hifn/hifn7751reg.h 2011-08-01 14:38:18.000000000 +0200
  16869. @@ -0,0 +1,540 @@
  16870. +/* $FreeBSD: src/sys/dev/hifn/hifn7751reg.h,v 1.7 2007/03/21 03:42:49 sam Exp $ */
  16871. +/* $OpenBSD: hifn7751reg.h,v 1.35 2002/04/08 17:49:42 jason Exp $ */
  16872. +
  16873. +/*-
  16874. + * Invertex AEON / Hifn 7751 driver
  16875. + * Copyright (c) 1999 Invertex Inc. All rights reserved.
  16876. + * Copyright (c) 1999 Theo de Raadt
  16877. + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  16878. + * http://www.netsec.net
  16879. + *
  16880. + * Please send any comments, feedback, bug-fixes, or feature requests to
  16881. + * software@invertex.com.
  16882. + *
  16883. + * Redistribution and use in source and binary forms, with or without
  16884. + * modification, are permitted provided that the following conditions
  16885. + * are met:
  16886. + *
  16887. + * 1. Redistributions of source code must retain the above copyright
  16888. + * notice, this list of conditions and the following disclaimer.
  16889. + * 2. Redistributions in binary form must reproduce the above copyright
  16890. + * notice, this list of conditions and the following disclaimer in the
  16891. + * documentation and/or other materials provided with the distribution.
  16892. + * 3. The name of the author may not be used to endorse or promote products
  16893. + * derived from this software without specific prior written permission.
  16894. + *
  16895. + *
  16896. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  16897. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16898. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  16899. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  16900. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  16901. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  16902. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  16903. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  16904. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  16905. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  16906. + *
  16907. + * Effort sponsored in part by the Defense Advanced Research Projects
  16908. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  16909. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  16910. + *
  16911. + */
  16912. +#ifndef __HIFN_H__
  16913. +#define __HIFN_H__
  16914. +
  16915. +/*
  16916. + * Some PCI configuration space offset defines. The names were made
  16917. + * identical to the names used by the Linux kernel.
  16918. + */
  16919. +#define HIFN_BAR0 PCIR_BAR(0) /* PUC register map */
  16920. +#define HIFN_BAR1 PCIR_BAR(1) /* DMA register map */
  16921. +#define HIFN_TRDY_TIMEOUT 0x40
  16922. +#define HIFN_RETRY_TIMEOUT 0x41
  16923. +
  16924. +/*
  16925. + * PCI vendor and device identifiers
  16926. + * (the names are preserved from their OpenBSD source).
  16927. + */
  16928. +#define PCI_VENDOR_HIFN 0x13a3 /* Hifn */
  16929. +#define PCI_PRODUCT_HIFN_7751 0x0005 /* 7751 */
  16930. +#define PCI_PRODUCT_HIFN_6500 0x0006 /* 6500 */
  16931. +#define PCI_PRODUCT_HIFN_7811 0x0007 /* 7811 */
  16932. +#define PCI_PRODUCT_HIFN_7855 0x001f /* 7855 */
  16933. +#define PCI_PRODUCT_HIFN_7951 0x0012 /* 7951 */
  16934. +#define PCI_PRODUCT_HIFN_7955 0x0020 /* 7954/7955 */
  16935. +#define PCI_PRODUCT_HIFN_7956 0x001d /* 7956 */
  16936. +
  16937. +#define PCI_VENDOR_INVERTEX 0x14e1 /* Invertex */
  16938. +#define PCI_PRODUCT_INVERTEX_AEON 0x0005 /* AEON */
  16939. +
  16940. +#define PCI_VENDOR_NETSEC 0x1660 /* NetSec */
  16941. +#define PCI_PRODUCT_NETSEC_7751 0x7751 /* 7751 */
  16942. +
  16943. +/*
  16944. + * The values below should multiple of 4 -- and be large enough to handle
  16945. + * any command the driver implements.
  16946. + *
  16947. + * MAX_COMMAND = base command + mac command + encrypt command +
  16948. + * mac-key + rc4-key
  16949. + * MAX_RESULT = base result + mac result + mac + encrypt result
  16950. + *
  16951. + *
  16952. + */
  16953. +#define HIFN_MAX_COMMAND (8 + 8 + 8 + 64 + 260)
  16954. +#define HIFN_MAX_RESULT (8 + 4 + 20 + 4)
  16955. +
  16956. +/*
  16957. + * hifn_desc_t
  16958. + *
  16959. + * Holds an individual descriptor for any of the rings.
  16960. + */
  16961. +typedef struct hifn_desc {
  16962. + volatile u_int32_t l; /* length and status bits */
  16963. + volatile u_int32_t p;
  16964. +} hifn_desc_t;
  16965. +
  16966. +/*
  16967. + * Masks for the "length" field of struct hifn_desc.
  16968. + */
  16969. +#define HIFN_D_LENGTH 0x0000ffff /* length bit mask */
  16970. +#define HIFN_D_MASKDONEIRQ 0x02000000 /* mask the done interrupt */
  16971. +#define HIFN_D_DESTOVER 0x04000000 /* destination overflow */
  16972. +#define HIFN_D_OVER 0x08000000 /* overflow */
  16973. +#define HIFN_D_LAST 0x20000000 /* last descriptor in chain */
  16974. +#define HIFN_D_JUMP 0x40000000 /* jump descriptor */
  16975. +#define HIFN_D_VALID 0x80000000 /* valid bit */
  16976. +
  16977. +
  16978. +/*
  16979. + * Processing Unit Registers (offset from BASEREG0)
  16980. + */
  16981. +#define HIFN_0_PUDATA 0x00 /* Processing Unit Data */
  16982. +#define HIFN_0_PUCTRL 0x04 /* Processing Unit Control */
  16983. +#define HIFN_0_PUISR 0x08 /* Processing Unit Interrupt Status */
  16984. +#define HIFN_0_PUCNFG 0x0c /* Processing Unit Configuration */
  16985. +#define HIFN_0_PUIER 0x10 /* Processing Unit Interrupt Enable */
  16986. +#define HIFN_0_PUSTAT 0x14 /* Processing Unit Status/Chip ID */
  16987. +#define HIFN_0_FIFOSTAT 0x18 /* FIFO Status */
  16988. +#define HIFN_0_FIFOCNFG 0x1c /* FIFO Configuration */
  16989. +#define HIFN_0_PUCTRL2 0x28 /* Processing Unit Control (2nd map) */
  16990. +#define HIFN_0_MUTE1 0x80
  16991. +#define HIFN_0_MUTE2 0x90
  16992. +#define HIFN_0_SPACESIZE 0x100 /* Register space size */
  16993. +
  16994. +/* Processing Unit Control Register (HIFN_0_PUCTRL) */
  16995. +#define HIFN_PUCTRL_CLRSRCFIFO 0x0010 /* clear source fifo */
  16996. +#define HIFN_PUCTRL_STOP 0x0008 /* stop pu */
  16997. +#define HIFN_PUCTRL_LOCKRAM 0x0004 /* lock ram */
  16998. +#define HIFN_PUCTRL_DMAENA 0x0002 /* enable dma */
  16999. +#define HIFN_PUCTRL_RESET 0x0001 /* Reset processing unit */
  17000. +
  17001. +/* Processing Unit Interrupt Status Register (HIFN_0_PUISR) */
  17002. +#define HIFN_PUISR_CMDINVAL 0x8000 /* Invalid command interrupt */
  17003. +#define HIFN_PUISR_DATAERR 0x4000 /* Data error interrupt */
  17004. +#define HIFN_PUISR_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
  17005. +#define HIFN_PUISR_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
  17006. +#define HIFN_PUISR_DSTOVER 0x0200 /* Destination overrun interrupt */
  17007. +#define HIFN_PUISR_SRCCMD 0x0080 /* Source command interrupt */
  17008. +#define HIFN_PUISR_SRCCTX 0x0040 /* Source context interrupt */
  17009. +#define HIFN_PUISR_SRCDATA 0x0020 /* Source data interrupt */
  17010. +#define HIFN_PUISR_DSTDATA 0x0010 /* Destination data interrupt */
  17011. +#define HIFN_PUISR_DSTRESULT 0x0004 /* Destination result interrupt */
  17012. +
  17013. +/* Processing Unit Configuration Register (HIFN_0_PUCNFG) */
  17014. +#define HIFN_PUCNFG_DRAMMASK 0xe000 /* DRAM size mask */
  17015. +#define HIFN_PUCNFG_DSZ_256K 0x0000 /* 256k dram */
  17016. +#define HIFN_PUCNFG_DSZ_512K 0x2000 /* 512k dram */
  17017. +#define HIFN_PUCNFG_DSZ_1M 0x4000 /* 1m dram */
  17018. +#define HIFN_PUCNFG_DSZ_2M 0x6000 /* 2m dram */
  17019. +#define HIFN_PUCNFG_DSZ_4M 0x8000 /* 4m dram */
  17020. +#define HIFN_PUCNFG_DSZ_8M 0xa000 /* 8m dram */
  17021. +#define HIFN_PUNCFG_DSZ_16M 0xc000 /* 16m dram */
  17022. +#define HIFN_PUCNFG_DSZ_32M 0xe000 /* 32m dram */
  17023. +#define HIFN_PUCNFG_DRAMREFRESH 0x1800 /* DRAM refresh rate mask */
  17024. +#define HIFN_PUCNFG_DRFR_512 0x0000 /* 512 divisor of ECLK */
  17025. +#define HIFN_PUCNFG_DRFR_256 0x0800 /* 256 divisor of ECLK */
  17026. +#define HIFN_PUCNFG_DRFR_128 0x1000 /* 128 divisor of ECLK */
  17027. +#define HIFN_PUCNFG_TCALLPHASES 0x0200 /* your guess is as good as mine... */
  17028. +#define HIFN_PUCNFG_TCDRVTOTEM 0x0100 /* your guess is as good as mine... */
  17029. +#define HIFN_PUCNFG_BIGENDIAN 0x0080 /* DMA big endian mode */
  17030. +#define HIFN_PUCNFG_BUS32 0x0040 /* Bus width 32bits */
  17031. +#define HIFN_PUCNFG_BUS16 0x0000 /* Bus width 16 bits */
  17032. +#define HIFN_PUCNFG_CHIPID 0x0020 /* Allow chipid from PUSTAT */
  17033. +#define HIFN_PUCNFG_DRAM 0x0010 /* Context RAM is DRAM */
  17034. +#define HIFN_PUCNFG_SRAM 0x0000 /* Context RAM is SRAM */
  17035. +#define HIFN_PUCNFG_COMPSING 0x0004 /* Enable single compression context */
  17036. +#define HIFN_PUCNFG_ENCCNFG 0x0002 /* Encryption configuration */
  17037. +
  17038. +/* Processing Unit Interrupt Enable Register (HIFN_0_PUIER) */
  17039. +#define HIFN_PUIER_CMDINVAL 0x8000 /* Invalid command interrupt */
  17040. +#define HIFN_PUIER_DATAERR 0x4000 /* Data error interrupt */
  17041. +#define HIFN_PUIER_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
  17042. +#define HIFN_PUIER_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
  17043. +#define HIFN_PUIER_DSTOVER 0x0200 /* Destination overrun interrupt */
  17044. +#define HIFN_PUIER_SRCCMD 0x0080 /* Source command interrupt */
  17045. +#define HIFN_PUIER_SRCCTX 0x0040 /* Source context interrupt */
  17046. +#define HIFN_PUIER_SRCDATA 0x0020 /* Source data interrupt */
  17047. +#define HIFN_PUIER_DSTDATA 0x0010 /* Destination data interrupt */
  17048. +#define HIFN_PUIER_DSTRESULT 0x0004 /* Destination result interrupt */
  17049. +
  17050. +/* Processing Unit Status Register/Chip ID (HIFN_0_PUSTAT) */
  17051. +#define HIFN_PUSTAT_CMDINVAL 0x8000 /* Invalid command interrupt */
  17052. +#define HIFN_PUSTAT_DATAERR 0x4000 /* Data error interrupt */
  17053. +#define HIFN_PUSTAT_SRCFIFO 0x2000 /* Source FIFO ready interrupt */
  17054. +#define HIFN_PUSTAT_DSTFIFO 0x1000 /* Destination FIFO ready interrupt */
  17055. +#define HIFN_PUSTAT_DSTOVER 0x0200 /* Destination overrun interrupt */
  17056. +#define HIFN_PUSTAT_SRCCMD 0x0080 /* Source command interrupt */
  17057. +#define HIFN_PUSTAT_SRCCTX 0x0040 /* Source context interrupt */
  17058. +#define HIFN_PUSTAT_SRCDATA 0x0020 /* Source data interrupt */
  17059. +#define HIFN_PUSTAT_DSTDATA 0x0010 /* Destination data interrupt */
  17060. +#define HIFN_PUSTAT_DSTRESULT 0x0004 /* Destination result interrupt */
  17061. +#define HIFN_PUSTAT_CHIPREV 0x00ff /* Chip revision mask */
  17062. +#define HIFN_PUSTAT_CHIPENA 0xff00 /* Chip enabled mask */
  17063. +#define HIFN_PUSTAT_ENA_2 0x1100 /* Level 2 enabled */
  17064. +#define HIFN_PUSTAT_ENA_1 0x1000 /* Level 1 enabled */
  17065. +#define HIFN_PUSTAT_ENA_0 0x3000 /* Level 0 enabled */
  17066. +#define HIFN_PUSTAT_REV_2 0x0020 /* 7751 PT6/2 */
  17067. +#define HIFN_PUSTAT_REV_3 0x0030 /* 7751 PT6/3 */
  17068. +
  17069. +/* FIFO Status Register (HIFN_0_FIFOSTAT) */
  17070. +#define HIFN_FIFOSTAT_SRC 0x7f00 /* Source FIFO available */
  17071. +#define HIFN_FIFOSTAT_DST 0x007f /* Destination FIFO available */
  17072. +
  17073. +/* FIFO Configuration Register (HIFN_0_FIFOCNFG) */
  17074. +#define HIFN_FIFOCNFG_THRESHOLD 0x0400 /* must be written as this value */
  17075. +
  17076. +/*
  17077. + * DMA Interface Registers (offset from BASEREG1)
  17078. + */
  17079. +#define HIFN_1_DMA_CRAR 0x0c /* DMA Command Ring Address */
  17080. +#define HIFN_1_DMA_SRAR 0x1c /* DMA Source Ring Address */
  17081. +#define HIFN_1_DMA_RRAR 0x2c /* DMA Result Ring Address */
  17082. +#define HIFN_1_DMA_DRAR 0x3c /* DMA Destination Ring Address */
  17083. +#define HIFN_1_DMA_CSR 0x40 /* DMA Status and Control */
  17084. +#define HIFN_1_DMA_IER 0x44 /* DMA Interrupt Enable */
  17085. +#define HIFN_1_DMA_CNFG 0x48 /* DMA Configuration */
  17086. +#define HIFN_1_PLL 0x4c /* 7955/7956: PLL config */
  17087. +#define HIFN_1_7811_RNGENA 0x60 /* 7811: rng enable */
  17088. +#define HIFN_1_7811_RNGCFG 0x64 /* 7811: rng config */
  17089. +#define HIFN_1_7811_RNGDAT 0x68 /* 7811: rng data */
  17090. +#define HIFN_1_7811_RNGSTS 0x6c /* 7811: rng status */
  17091. +#define HIFN_1_DMA_CNFG2 0x6c /* 7955/7956: dma config #2 */
  17092. +#define HIFN_1_7811_MIPSRST 0x94 /* 7811: MIPS reset */
  17093. +#define HIFN_1_REVID 0x98 /* Revision ID */
  17094. +
  17095. +#define HIFN_1_PUB_RESET 0x204 /* Public/RNG Reset */
  17096. +#define HIFN_1_PUB_BASE 0x300 /* Public Base Address */
  17097. +#define HIFN_1_PUB_OPLEN 0x304 /* 7951-compat Public Operand Length */
  17098. +#define HIFN_1_PUB_OP 0x308 /* 7951-compat Public Operand */
  17099. +#define HIFN_1_PUB_STATUS 0x30c /* 7951-compat Public Status */
  17100. +#define HIFN_1_PUB_IEN 0x310 /* Public Interrupt enable */
  17101. +#define HIFN_1_RNG_CONFIG 0x314 /* RNG config */
  17102. +#define HIFN_1_RNG_DATA 0x318 /* RNG data */
  17103. +#define HIFN_1_PUB_MODE 0x320 /* PK mode */
  17104. +#define HIFN_1_PUB_FIFO_OPLEN 0x380 /* first element of oplen fifo */
  17105. +#define HIFN_1_PUB_FIFO_OP 0x384 /* first element of op fifo */
  17106. +#define HIFN_1_PUB_MEM 0x400 /* start of Public key memory */
  17107. +#define HIFN_1_PUB_MEMEND 0xbff /* end of Public key memory */
  17108. +
  17109. +/* DMA Status and Control Register (HIFN_1_DMA_CSR) */
  17110. +#define HIFN_DMACSR_D_CTRLMASK 0xc0000000 /* Destinition Ring Control */
  17111. +#define HIFN_DMACSR_D_CTRL_NOP 0x00000000 /* Dest. Control: no-op */
  17112. +#define HIFN_DMACSR_D_CTRL_DIS 0x40000000 /* Dest. Control: disable */
  17113. +#define HIFN_DMACSR_D_CTRL_ENA 0x80000000 /* Dest. Control: enable */
  17114. +#define HIFN_DMACSR_D_ABORT 0x20000000 /* Destinition Ring PCIAbort */
  17115. +#define HIFN_DMACSR_D_DONE 0x10000000 /* Destinition Ring Done */
  17116. +#define HIFN_DMACSR_D_LAST 0x08000000 /* Destinition Ring Last */
  17117. +#define HIFN_DMACSR_D_WAIT 0x04000000 /* Destinition Ring Waiting */
  17118. +#define HIFN_DMACSR_D_OVER 0x02000000 /* Destinition Ring Overflow */
  17119. +#define HIFN_DMACSR_R_CTRL 0x00c00000 /* Result Ring Control */
  17120. +#define HIFN_DMACSR_R_CTRL_NOP 0x00000000 /* Result Control: no-op */
  17121. +#define HIFN_DMACSR_R_CTRL_DIS 0x00400000 /* Result Control: disable */
  17122. +#define HIFN_DMACSR_R_CTRL_ENA 0x00800000 /* Result Control: enable */
  17123. +#define HIFN_DMACSR_R_ABORT 0x00200000 /* Result Ring PCI Abort */
  17124. +#define HIFN_DMACSR_R_DONE 0x00100000 /* Result Ring Done */
  17125. +#define HIFN_DMACSR_R_LAST 0x00080000 /* Result Ring Last */
  17126. +#define HIFN_DMACSR_R_WAIT 0x00040000 /* Result Ring Waiting */
  17127. +#define HIFN_DMACSR_R_OVER 0x00020000 /* Result Ring Overflow */
  17128. +#define HIFN_DMACSR_S_CTRL 0x0000c000 /* Source Ring Control */
  17129. +#define HIFN_DMACSR_S_CTRL_NOP 0x00000000 /* Source Control: no-op */
  17130. +#define HIFN_DMACSR_S_CTRL_DIS 0x00004000 /* Source Control: disable */
  17131. +#define HIFN_DMACSR_S_CTRL_ENA 0x00008000 /* Source Control: enable */
  17132. +#define HIFN_DMACSR_S_ABORT 0x00002000 /* Source Ring PCI Abort */
  17133. +#define HIFN_DMACSR_S_DONE 0x00001000 /* Source Ring Done */
  17134. +#define HIFN_DMACSR_S_LAST 0x00000800 /* Source Ring Last */
  17135. +#define HIFN_DMACSR_S_WAIT 0x00000400 /* Source Ring Waiting */
  17136. +#define HIFN_DMACSR_ILLW 0x00000200 /* Illegal write (7811 only) */
  17137. +#define HIFN_DMACSR_ILLR 0x00000100 /* Illegal read (7811 only) */
  17138. +#define HIFN_DMACSR_C_CTRL 0x000000c0 /* Command Ring Control */
  17139. +#define HIFN_DMACSR_C_CTRL_NOP 0x00000000 /* Command Control: no-op */
  17140. +#define HIFN_DMACSR_C_CTRL_DIS 0x00000040 /* Command Control: disable */
  17141. +#define HIFN_DMACSR_C_CTRL_ENA 0x00000080 /* Command Control: enable */
  17142. +#define HIFN_DMACSR_C_ABORT 0x00000020 /* Command Ring PCI Abort */
  17143. +#define HIFN_DMACSR_C_DONE 0x00000010 /* Command Ring Done */
  17144. +#define HIFN_DMACSR_C_LAST 0x00000008 /* Command Ring Last */
  17145. +#define HIFN_DMACSR_C_WAIT 0x00000004 /* Command Ring Waiting */
  17146. +#define HIFN_DMACSR_PUBDONE 0x00000002 /* Public op done (7951 only) */
  17147. +#define HIFN_DMACSR_ENGINE 0x00000001 /* Command Ring Engine IRQ */
  17148. +
  17149. +/* DMA Interrupt Enable Register (HIFN_1_DMA_IER) */
  17150. +#define HIFN_DMAIER_D_ABORT 0x20000000 /* Destination Ring PCIAbort */
  17151. +#define HIFN_DMAIER_D_DONE 0x10000000 /* Destination Ring Done */
  17152. +#define HIFN_DMAIER_D_LAST 0x08000000 /* Destination Ring Last */
  17153. +#define HIFN_DMAIER_D_WAIT 0x04000000 /* Destination Ring Waiting */
  17154. +#define HIFN_DMAIER_D_OVER 0x02000000 /* Destination Ring Overflow */
  17155. +#define HIFN_DMAIER_R_ABORT 0x00200000 /* Result Ring PCI Abort */
  17156. +#define HIFN_DMAIER_R_DONE 0x00100000 /* Result Ring Done */
  17157. +#define HIFN_DMAIER_R_LAST 0x00080000 /* Result Ring Last */
  17158. +#define HIFN_DMAIER_R_WAIT 0x00040000 /* Result Ring Waiting */
  17159. +#define HIFN_DMAIER_R_OVER 0x00020000 /* Result Ring Overflow */
  17160. +#define HIFN_DMAIER_S_ABORT 0x00002000 /* Source Ring PCI Abort */
  17161. +#define HIFN_DMAIER_S_DONE 0x00001000 /* Source Ring Done */
  17162. +#define HIFN_DMAIER_S_LAST 0x00000800 /* Source Ring Last */
  17163. +#define HIFN_DMAIER_S_WAIT 0x00000400 /* Source Ring Waiting */
  17164. +#define HIFN_DMAIER_ILLW 0x00000200 /* Illegal write (7811 only) */
  17165. +#define HIFN_DMAIER_ILLR 0x00000100 /* Illegal read (7811 only) */
  17166. +#define HIFN_DMAIER_C_ABORT 0x00000020 /* Command Ring PCI Abort */
  17167. +#define HIFN_DMAIER_C_DONE 0x00000010 /* Command Ring Done */
  17168. +#define HIFN_DMAIER_C_LAST 0x00000008 /* Command Ring Last */
  17169. +#define HIFN_DMAIER_C_WAIT 0x00000004 /* Command Ring Waiting */
  17170. +#define HIFN_DMAIER_PUBDONE 0x00000002 /* public op done (7951 only) */
  17171. +#define HIFN_DMAIER_ENGINE 0x00000001 /* Engine IRQ */
  17172. +
  17173. +/* DMA Configuration Register (HIFN_1_DMA_CNFG) */
  17174. +#define HIFN_DMACNFG_BIGENDIAN 0x10000000 /* big endian mode */
  17175. +#define HIFN_DMACNFG_POLLFREQ 0x00ff0000 /* Poll frequency mask */
  17176. +#define HIFN_DMACNFG_UNLOCK 0x00000800
  17177. +#define HIFN_DMACNFG_POLLINVAL 0x00000700 /* Invalid Poll Scalar */
  17178. +#define HIFN_DMACNFG_LAST 0x00000010 /* Host control LAST bit */
  17179. +#define HIFN_DMACNFG_MODE 0x00000004 /* DMA mode */
  17180. +#define HIFN_DMACNFG_DMARESET 0x00000002 /* DMA Reset # */
  17181. +#define HIFN_DMACNFG_MSTRESET 0x00000001 /* Master Reset # */
  17182. +
  17183. +/* DMA Configuration Register (HIFN_1_DMA_CNFG2) */
  17184. +#define HIFN_DMACNFG2_PKSWAP32 (1 << 19) /* swap the OPLEN/OP reg */
  17185. +#define HIFN_DMACNFG2_PKSWAP8 (1 << 18) /* swap the bits of OPLEN/OP */
  17186. +#define HIFN_DMACNFG2_BAR0_SWAP32 (1<<17) /* swap the bytes of BAR0 */
  17187. +#define HIFN_DMACNFG2_BAR1_SWAP8 (1<<16) /* swap the bits of BAR0 */
  17188. +#define HIFN_DMACNFG2_INIT_WRITE_BURST_SHIFT 12
  17189. +#define HIFN_DMACNFG2_INIT_READ_BURST_SHIFT 8
  17190. +#define HIFN_DMACNFG2_TGT_WRITE_BURST_SHIFT 4
  17191. +#define HIFN_DMACNFG2_TGT_READ_BURST_SHIFT 0
  17192. +
  17193. +/* 7811 RNG Enable Register (HIFN_1_7811_RNGENA) */
  17194. +#define HIFN_7811_RNGENA_ENA 0x00000001 /* enable RNG */
  17195. +
  17196. +/* 7811 RNG Config Register (HIFN_1_7811_RNGCFG) */
  17197. +#define HIFN_7811_RNGCFG_PRE1 0x00000f00 /* first prescalar */
  17198. +#define HIFN_7811_RNGCFG_OPRE 0x00000080 /* output prescalar */
  17199. +#define HIFN_7811_RNGCFG_DEFL 0x00000f80 /* 2 words/ 1/100 sec */
  17200. +
  17201. +/* 7811 RNG Status Register (HIFN_1_7811_RNGSTS) */
  17202. +#define HIFN_7811_RNGSTS_RDY 0x00004000 /* two numbers in FIFO */
  17203. +#define HIFN_7811_RNGSTS_UFL 0x00001000 /* rng underflow */
  17204. +
  17205. +/* 7811 MIPS Reset Register (HIFN_1_7811_MIPSRST) */
  17206. +#define HIFN_MIPSRST_BAR2SIZE 0xffff0000 /* sdram size */
  17207. +#define HIFN_MIPSRST_GPRAMINIT 0x00008000 /* gpram can be accessed */
  17208. +#define HIFN_MIPSRST_CRAMINIT 0x00004000 /* ctxram can be accessed */
  17209. +#define HIFN_MIPSRST_LED2 0x00000400 /* external LED2 */
  17210. +#define HIFN_MIPSRST_LED1 0x00000200 /* external LED1 */
  17211. +#define HIFN_MIPSRST_LED0 0x00000100 /* external LED0 */
  17212. +#define HIFN_MIPSRST_MIPSDIS 0x00000004 /* disable MIPS */
  17213. +#define HIFN_MIPSRST_MIPSRST 0x00000002 /* warm reset MIPS */
  17214. +#define HIFN_MIPSRST_MIPSCOLD 0x00000001 /* cold reset MIPS */
  17215. +
  17216. +/* Public key reset register (HIFN_1_PUB_RESET) */
  17217. +#define HIFN_PUBRST_RESET 0x00000001 /* reset public/rng unit */
  17218. +
  17219. +/* Public operation register (HIFN_1_PUB_OP) */
  17220. +#define HIFN_PUBOP_AOFFSET 0x0000003e /* A offset */
  17221. +#define HIFN_PUBOP_BOFFSET 0x00000fc0 /* B offset */
  17222. +#define HIFN_PUBOP_MOFFSET 0x0003f000 /* M offset */
  17223. +#define HIFN_PUBOP_OP_MASK 0x003c0000 /* Opcode: */
  17224. +#define HIFN_PUBOP_OP_NOP 0x00000000 /* NOP */
  17225. +#define HIFN_PUBOP_OP_ADD 0x00040000 /* ADD */
  17226. +#define HIFN_PUBOP_OP_ADDC 0x00080000 /* ADD w/carry */
  17227. +#define HIFN_PUBOP_OP_SUB 0x000c0000 /* SUB */
  17228. +#define HIFN_PUBOP_OP_SUBC 0x00100000 /* SUB w/carry */
  17229. +#define HIFN_PUBOP_OP_MODADD 0x00140000 /* Modular ADD */
  17230. +#define HIFN_PUBOP_OP_MODSUB 0x00180000 /* Modular SUB */
  17231. +#define HIFN_PUBOP_OP_INCA 0x001c0000 /* INC A */
  17232. +#define HIFN_PUBOP_OP_DECA 0x00200000 /* DEC A */
  17233. +#define HIFN_PUBOP_OP_MULT 0x00240000 /* MULT */
  17234. +#define HIFN_PUBOP_OP_MODMULT 0x00280000 /* Modular MULT */
  17235. +#define HIFN_PUBOP_OP_MODRED 0x002c0000 /* Modular Red */
  17236. +#define HIFN_PUBOP_OP_MODEXP 0x00300000 /* Modular Exp */
  17237. +
  17238. +/* Public operand length register (HIFN_1_PUB_OPLEN) */
  17239. +#define HIFN_PUBOPLEN_MODLEN 0x0000007f
  17240. +#define HIFN_PUBOPLEN_EXPLEN 0x0003ff80
  17241. +#define HIFN_PUBOPLEN_REDLEN 0x003c0000
  17242. +
  17243. +/* Public status register (HIFN_1_PUB_STATUS) */
  17244. +#define HIFN_PUBSTS_DONE 0x00000001 /* operation done */
  17245. +#define HIFN_PUBSTS_CARRY 0x00000002 /* carry */
  17246. +#define HIFN_PUBSTS_FIFO_EMPTY 0x00000100 /* fifo empty */
  17247. +#define HIFN_PUBSTS_FIFO_FULL 0x00000200 /* fifo full */
  17248. +#define HIFN_PUBSTS_FIFO_OVFL 0x00000400 /* fifo overflow */
  17249. +#define HIFN_PUBSTS_FIFO_WRITE 0x000f0000 /* fifo write */
  17250. +#define HIFN_PUBSTS_FIFO_READ 0x0f000000 /* fifo read */
  17251. +
  17252. +/* Public interrupt enable register (HIFN_1_PUB_IEN) */
  17253. +#define HIFN_PUBIEN_DONE 0x00000001 /* operation done interrupt */
  17254. +
  17255. +/* Random number generator config register (HIFN_1_RNG_CONFIG) */
  17256. +#define HIFN_RNGCFG_ENA 0x00000001 /* enable rng */
  17257. +
  17258. +/*
  17259. + * Register offsets in register set 1
  17260. + */
  17261. +
  17262. +#define HIFN_UNLOCK_SECRET1 0xf4
  17263. +#define HIFN_UNLOCK_SECRET2 0xfc
  17264. +
  17265. +/*
  17266. + * PLL config register
  17267. + *
  17268. + * This register is present only on 7954/7955/7956 parts. It must be
  17269. + * programmed according to the bus interface method used by the h/w.
  17270. + * Note that the parts require a stable clock. Since the PCI clock
  17271. + * may vary the reference clock must usually be used. To avoid
  17272. + * overclocking the core logic, setup must be done carefully, refer
  17273. + * to the driver for details. The exact multiplier required varies
  17274. + * by part and system configuration; refer to the Hifn documentation.
  17275. + */
  17276. +#define HIFN_PLL_REF_SEL 0x00000001 /* REF/HBI clk selection */
  17277. +#define HIFN_PLL_BP 0x00000002 /* bypass (used during setup) */
  17278. +/* bit 2 reserved */
  17279. +#define HIFN_PLL_PK_CLK_SEL 0x00000008 /* public key clk select */
  17280. +#define HIFN_PLL_PE_CLK_SEL 0x00000010 /* packet engine clk select */
  17281. +/* bits 5-9 reserved */
  17282. +#define HIFN_PLL_MBSET 0x00000400 /* must be set to 1 */
  17283. +#define HIFN_PLL_ND 0x00003800 /* Fpll_ref multiplier select */
  17284. +#define HIFN_PLL_ND_SHIFT 11
  17285. +#define HIFN_PLL_ND_2 0x00000000 /* 2x */
  17286. +#define HIFN_PLL_ND_4 0x00000800 /* 4x */
  17287. +#define HIFN_PLL_ND_6 0x00001000 /* 6x */
  17288. +#define HIFN_PLL_ND_8 0x00001800 /* 8x */
  17289. +#define HIFN_PLL_ND_10 0x00002000 /* 10x */
  17290. +#define HIFN_PLL_ND_12 0x00002800 /* 12x */
  17291. +/* bits 14-15 reserved */
  17292. +#define HIFN_PLL_IS 0x00010000 /* charge pump current select */
  17293. +/* bits 17-31 reserved */
  17294. +
  17295. +/*
  17296. + * Board configuration specifies only these bits.
  17297. + */
  17298. +#define HIFN_PLL_CONFIG (HIFN_PLL_IS|HIFN_PLL_ND|HIFN_PLL_REF_SEL)
  17299. +
  17300. +/*
  17301. + * Public Key Engine Mode Register
  17302. + */
  17303. +#define HIFN_PKMODE_HOSTINVERT (1 << 0) /* HOST INVERT */
  17304. +#define HIFN_PKMODE_ENHANCED (1 << 1) /* Enable enhanced mode */
  17305. +
  17306. +
  17307. +/*********************************************************************
  17308. + * Structs for board commands
  17309. + *
  17310. + *********************************************************************/
  17311. +
  17312. +/*
  17313. + * Structure to help build up the command data structure.
  17314. + */
  17315. +typedef struct hifn_base_command {
  17316. + volatile u_int16_t masks;
  17317. + volatile u_int16_t session_num;
  17318. + volatile u_int16_t total_source_count;
  17319. + volatile u_int16_t total_dest_count;
  17320. +} hifn_base_command_t;
  17321. +
  17322. +#define HIFN_BASE_CMD_MAC 0x0400
  17323. +#define HIFN_BASE_CMD_CRYPT 0x0800
  17324. +#define HIFN_BASE_CMD_DECODE 0x2000
  17325. +#define HIFN_BASE_CMD_SRCLEN_M 0xc000
  17326. +#define HIFN_BASE_CMD_SRCLEN_S 14
  17327. +#define HIFN_BASE_CMD_DSTLEN_M 0x3000
  17328. +#define HIFN_BASE_CMD_DSTLEN_S 12
  17329. +#define HIFN_BASE_CMD_LENMASK_HI 0x30000
  17330. +#define HIFN_BASE_CMD_LENMASK_LO 0x0ffff
  17331. +
  17332. +/*
  17333. + * Structure to help build up the command data structure.
  17334. + */
  17335. +typedef struct hifn_crypt_command {
  17336. + volatile u_int16_t masks;
  17337. + volatile u_int16_t header_skip;
  17338. + volatile u_int16_t source_count;
  17339. + volatile u_int16_t reserved;
  17340. +} hifn_crypt_command_t;
  17341. +
  17342. +#define HIFN_CRYPT_CMD_ALG_MASK 0x0003 /* algorithm: */
  17343. +#define HIFN_CRYPT_CMD_ALG_DES 0x0000 /* DES */
  17344. +#define HIFN_CRYPT_CMD_ALG_3DES 0x0001 /* 3DES */
  17345. +#define HIFN_CRYPT_CMD_ALG_RC4 0x0002 /* RC4 */
  17346. +#define HIFN_CRYPT_CMD_ALG_AES 0x0003 /* AES */
  17347. +#define HIFN_CRYPT_CMD_MODE_MASK 0x0018 /* Encrypt mode: */
  17348. +#define HIFN_CRYPT_CMD_MODE_ECB 0x0000 /* ECB */
  17349. +#define HIFN_CRYPT_CMD_MODE_CBC 0x0008 /* CBC */
  17350. +#define HIFN_CRYPT_CMD_MODE_CFB 0x0010 /* CFB */
  17351. +#define HIFN_CRYPT_CMD_MODE_OFB 0x0018 /* OFB */
  17352. +#define HIFN_CRYPT_CMD_CLR_CTX 0x0040 /* clear context */
  17353. +#define HIFN_CRYPT_CMD_NEW_KEY 0x0800 /* expect new key */
  17354. +#define HIFN_CRYPT_CMD_NEW_IV 0x1000 /* expect new iv */
  17355. +
  17356. +#define HIFN_CRYPT_CMD_SRCLEN_M 0xc000
  17357. +#define HIFN_CRYPT_CMD_SRCLEN_S 14
  17358. +
  17359. +#define HIFN_CRYPT_CMD_KSZ_MASK 0x0600 /* AES key size: */
  17360. +#define HIFN_CRYPT_CMD_KSZ_128 0x0000 /* 128 bit */
  17361. +#define HIFN_CRYPT_CMD_KSZ_192 0x0200 /* 192 bit */
  17362. +#define HIFN_CRYPT_CMD_KSZ_256 0x0400 /* 256 bit */
  17363. +
  17364. +/*
  17365. + * Structure to help build up the command data structure.
  17366. + */
  17367. +typedef struct hifn_mac_command {
  17368. + volatile u_int16_t masks;
  17369. + volatile u_int16_t header_skip;
  17370. + volatile u_int16_t source_count;
  17371. + volatile u_int16_t reserved;
  17372. +} hifn_mac_command_t;
  17373. +
  17374. +#define HIFN_MAC_CMD_ALG_MASK 0x0001
  17375. +#define HIFN_MAC_CMD_ALG_SHA1 0x0000
  17376. +#define HIFN_MAC_CMD_ALG_MD5 0x0001
  17377. +#define HIFN_MAC_CMD_MODE_MASK 0x000c
  17378. +#define HIFN_MAC_CMD_MODE_HMAC 0x0000
  17379. +#define HIFN_MAC_CMD_MODE_SSL_MAC 0x0004
  17380. +#define HIFN_MAC_CMD_MODE_HASH 0x0008
  17381. +#define HIFN_MAC_CMD_MODE_FULL 0x0004
  17382. +#define HIFN_MAC_CMD_TRUNC 0x0010
  17383. +#define HIFN_MAC_CMD_RESULT 0x0020
  17384. +#define HIFN_MAC_CMD_APPEND 0x0040
  17385. +#define HIFN_MAC_CMD_SRCLEN_M 0xc000
  17386. +#define HIFN_MAC_CMD_SRCLEN_S 14
  17387. +
  17388. +/*
  17389. + * MAC POS IPsec initiates authentication after encryption on encodes
  17390. + * and before decryption on decodes.
  17391. + */
  17392. +#define HIFN_MAC_CMD_POS_IPSEC 0x0200
  17393. +#define HIFN_MAC_CMD_NEW_KEY 0x0800
  17394. +
  17395. +/*
  17396. + * The poll frequency and poll scalar defines are unshifted values used
  17397. + * to set fields in the DMA Configuration Register.
  17398. + */
  17399. +#ifndef HIFN_POLL_FREQUENCY
  17400. +#define HIFN_POLL_FREQUENCY 0x1
  17401. +#endif
  17402. +
  17403. +#ifndef HIFN_POLL_SCALAR
  17404. +#define HIFN_POLL_SCALAR 0x0
  17405. +#endif
  17406. +
  17407. +#define HIFN_MAX_SEGLEN 0xffff /* maximum dma segment len */
  17408. +#define HIFN_MAX_DMALEN 0x3ffff /* maximum dma length */
  17409. +#endif /* __HIFN_H__ */
  17410. diff -Nur linux-2.6.39.orig/crypto/ocf/hifn/hifn7751var.h linux-2.6.39/crypto/ocf/hifn/hifn7751var.h
  17411. --- linux-2.6.39.orig/crypto/ocf/hifn/hifn7751var.h 1970-01-01 01:00:00.000000000 +0100
  17412. +++ linux-2.6.39/crypto/ocf/hifn/hifn7751var.h 2011-08-01 14:38:18.000000000 +0200
  17413. @@ -0,0 +1,369 @@
  17414. +/* $FreeBSD: src/sys/dev/hifn/hifn7751var.h,v 1.9 2007/03/21 03:42:49 sam Exp $ */
  17415. +/* $OpenBSD: hifn7751var.h,v 1.42 2002/04/08 17:49:42 jason Exp $ */
  17416. +
  17417. +/*-
  17418. + * Invertex AEON / Hifn 7751 driver
  17419. + * Copyright (c) 1999 Invertex Inc. All rights reserved.
  17420. + * Copyright (c) 1999 Theo de Raadt
  17421. + * Copyright (c) 2000-2001 Network Security Technologies, Inc.
  17422. + * http://www.netsec.net
  17423. + *
  17424. + * Please send any comments, feedback, bug-fixes, or feature requests to
  17425. + * software@invertex.com.
  17426. + *
  17427. + * Redistribution and use in source and binary forms, with or without
  17428. + * modification, are permitted provided that the following conditions
  17429. + * are met:
  17430. + *
  17431. + * 1. Redistributions of source code must retain the above copyright
  17432. + * notice, this list of conditions and the following disclaimer.
  17433. + * 2. Redistributions in binary form must reproduce the above copyright
  17434. + * notice, this list of conditions and the following disclaimer in the
  17435. + * documentation and/or other materials provided with the distribution.
  17436. + * 3. The name of the author may not be used to endorse or promote products
  17437. + * derived from this software without specific prior written permission.
  17438. + *
  17439. + *
  17440. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17441. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  17442. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17443. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  17444. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  17445. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  17446. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  17447. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  17448. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  17449. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  17450. + *
  17451. + * Effort sponsored in part by the Defense Advanced Research Projects
  17452. + * Agency (DARPA) and Air Force Research Laboratory, Air Force
  17453. + * Materiel Command, USAF, under agreement number F30602-01-2-0537.
  17454. + *
  17455. + */
  17456. +
  17457. +#ifndef __HIFN7751VAR_H__
  17458. +#define __HIFN7751VAR_H__
  17459. +
  17460. +#ifdef __KERNEL__
  17461. +
  17462. +/*
  17463. + * Some configurable values for the driver. By default command+result
  17464. + * descriptor rings are the same size. The src+dst descriptor rings
  17465. + * are sized at 3.5x the number of potential commands. Slower parts
  17466. + * (e.g. 7951) tend to run out of src descriptors; faster parts (7811)
  17467. + * src+cmd/result descriptors. It's not clear that increasing the size
  17468. + * of the descriptor rings helps performance significantly as other
  17469. + * factors tend to come into play (e.g. copying misaligned packets).
  17470. + */
  17471. +#define HIFN_D_CMD_RSIZE 24 /* command descriptors */
  17472. +#define HIFN_D_SRC_RSIZE ((HIFN_D_CMD_RSIZE * 7) / 2) /* source descriptors */
  17473. +#define HIFN_D_RES_RSIZE HIFN_D_CMD_RSIZE /* result descriptors */
  17474. +#define HIFN_D_DST_RSIZE HIFN_D_SRC_RSIZE /* destination descriptors */
  17475. +
  17476. +/*
  17477. + * Length values for cryptography
  17478. + */
  17479. +#define HIFN_DES_KEY_LENGTH 8
  17480. +#define HIFN_3DES_KEY_LENGTH 24
  17481. +#define HIFN_MAX_CRYPT_KEY_LENGTH HIFN_3DES_KEY_LENGTH
  17482. +#define HIFN_IV_LENGTH 8
  17483. +#define HIFN_AES_IV_LENGTH 16
  17484. +#define HIFN_MAX_IV_LENGTH HIFN_AES_IV_LENGTH
  17485. +
  17486. +/*
  17487. + * Length values for authentication
  17488. + */
  17489. +#define HIFN_MAC_KEY_LENGTH 64
  17490. +#define HIFN_MD5_LENGTH 16
  17491. +#define HIFN_SHA1_LENGTH 20
  17492. +#define HIFN_MAC_TRUNC_LENGTH 12
  17493. +
  17494. +#define MAX_SCATTER 64
  17495. +
  17496. +/*
  17497. + * Data structure to hold all 4 rings and any other ring related data.
  17498. + */
  17499. +struct hifn_dma {
  17500. + /*
  17501. + * Descriptor rings. We add +1 to the size to accomidate the
  17502. + * jump descriptor.
  17503. + */
  17504. + struct hifn_desc cmdr[HIFN_D_CMD_RSIZE+1];
  17505. + struct hifn_desc srcr[HIFN_D_SRC_RSIZE+1];
  17506. + struct hifn_desc dstr[HIFN_D_DST_RSIZE+1];
  17507. + struct hifn_desc resr[HIFN_D_RES_RSIZE+1];
  17508. +
  17509. + struct hifn_command *hifn_commands[HIFN_D_RES_RSIZE];
  17510. +
  17511. + u_char command_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_COMMAND];
  17512. + u_char result_bufs[HIFN_D_CMD_RSIZE][HIFN_MAX_RESULT];
  17513. + u_int32_t slop[HIFN_D_CMD_RSIZE];
  17514. +
  17515. + u_int64_t test_src, test_dst;
  17516. +
  17517. + /*
  17518. + * Our current positions for insertion and removal from the desriptor
  17519. + * rings.
  17520. + */
  17521. + int cmdi, srci, dsti, resi;
  17522. + volatile int cmdu, srcu, dstu, resu;
  17523. + int cmdk, srck, dstk, resk;
  17524. +};
  17525. +
  17526. +struct hifn_session {
  17527. + int hs_used;
  17528. + int hs_mlen;
  17529. + u_int8_t hs_iv[HIFN_MAX_IV_LENGTH];
  17530. +};
  17531. +
  17532. +#define HIFN_RING_SYNC(sc, r, i, f) \
  17533. + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
  17534. +
  17535. +#define HIFN_CMDR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), cmdr, (i), (f))
  17536. +#define HIFN_RESR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), resr, (i), (f))
  17537. +#define HIFN_SRCR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), srcr, (i), (f))
  17538. +#define HIFN_DSTR_SYNC(sc, i, f) HIFN_RING_SYNC((sc), dstr, (i), (f))
  17539. +
  17540. +#define HIFN_CMD_SYNC(sc, i, f) \
  17541. + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
  17542. +
  17543. +#define HIFN_RES_SYNC(sc, i, f) \
  17544. + /* DAVIDM bus_dmamap_sync((sc)->sc_dmat, (sc)->sc_dmamap, (f)) */
  17545. +
  17546. +typedef int bus_size_t;
  17547. +
  17548. +/*
  17549. + * Holds data specific to a single HIFN board.
  17550. + */
  17551. +struct hifn_softc {
  17552. + softc_device_decl sc_dev;
  17553. +
  17554. + struct pci_dev *sc_pcidev; /* PCI device pointer */
  17555. + spinlock_t sc_mtx; /* per-instance lock */
  17556. +
  17557. + int sc_num; /* for multiple devs */
  17558. +
  17559. + ocf_iomem_t sc_bar0;
  17560. + bus_size_t sc_bar0_lastreg;/* bar0 last reg written */
  17561. + ocf_iomem_t sc_bar1;
  17562. + bus_size_t sc_bar1_lastreg;/* bar1 last reg written */
  17563. +
  17564. + int sc_irq;
  17565. +
  17566. + u_int32_t sc_dmaier;
  17567. + u_int32_t sc_drammodel; /* 1=dram, 0=sram */
  17568. + u_int32_t sc_pllconfig; /* 7954/7955/7956 PLL config */
  17569. +
  17570. + struct hifn_dma *sc_dma;
  17571. + dma_addr_t sc_dma_physaddr;/* physical address of sc_dma */
  17572. +
  17573. + int sc_dmansegs;
  17574. + int32_t sc_cid;
  17575. + int sc_maxses;
  17576. + int sc_nsessions;
  17577. + struct hifn_session *sc_sessions;
  17578. + int sc_ramsize;
  17579. + int sc_flags;
  17580. +#define HIFN_HAS_RNG 0x1 /* includes random number generator */
  17581. +#define HIFN_HAS_PUBLIC 0x2 /* includes public key support */
  17582. +#define HIFN_HAS_AES 0x4 /* includes AES support */
  17583. +#define HIFN_IS_7811 0x8 /* Hifn 7811 part */
  17584. +#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
  17585. +
  17586. + struct timer_list sc_tickto; /* for managing DMA */
  17587. +
  17588. + int sc_rngfirst;
  17589. + int sc_rnghz; /* RNG polling frequency */
  17590. +
  17591. + int sc_c_busy; /* command ring busy */
  17592. + int sc_s_busy; /* source data ring busy */
  17593. + int sc_d_busy; /* destination data ring busy */
  17594. + int sc_r_busy; /* result ring busy */
  17595. + int sc_active; /* for initial countdown */
  17596. + int sc_needwakeup; /* ops q'd wating on resources */
  17597. + int sc_curbatch; /* # ops submitted w/o int */
  17598. + int sc_suspended;
  17599. +#ifdef HIFN_VULCANDEV
  17600. + struct cdev *sc_pkdev;
  17601. +#endif
  17602. +};
  17603. +
  17604. +#define HIFN_LOCK(_sc) spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
  17605. +#define HIFN_UNLOCK(_sc) spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
  17606. +
  17607. +/*
  17608. + * hifn_command_t
  17609. + *
  17610. + * This is the control structure used to pass commands to hifn_encrypt().
  17611. + *
  17612. + * flags
  17613. + * -----
  17614. + * Flags is the bitwise "or" values for command configuration. A single
  17615. + * encrypt direction needs to be set:
  17616. + *
  17617. + * HIFN_ENCODE or HIFN_DECODE
  17618. + *
  17619. + * To use cryptography, a single crypto algorithm must be included:
  17620. + *
  17621. + * HIFN_CRYPT_3DES or HIFN_CRYPT_DES
  17622. + *
  17623. + * To use authentication is used, a single MAC algorithm must be included:
  17624. + *
  17625. + * HIFN_MAC_MD5 or HIFN_MAC_SHA1
  17626. + *
  17627. + * By default MD5 uses a 16 byte hash and SHA-1 uses a 20 byte hash.
  17628. + * If the value below is set, hash values are truncated or assumed
  17629. + * truncated to 12 bytes:
  17630. + *
  17631. + * HIFN_MAC_TRUNC
  17632. + *
  17633. + * Keys for encryption and authentication can be sent as part of a command,
  17634. + * or the last key value used with a particular session can be retrieved
  17635. + * and used again if either of these flags are not specified.
  17636. + *
  17637. + * HIFN_CRYPT_NEW_KEY, HIFN_MAC_NEW_KEY
  17638. + *
  17639. + * session_num
  17640. + * -----------
  17641. + * A number between 0 and 2048 (for DRAM models) or a number between
  17642. + * 0 and 768 (for SRAM models). Those who don't want to use session
  17643. + * numbers should leave value at zero and send a new crypt key and/or
  17644. + * new MAC key on every command. If you use session numbers and
  17645. + * don't send a key with a command, the last key sent for that same
  17646. + * session number will be used.
  17647. + *
  17648. + * Warning: Using session numbers and multiboard at the same time
  17649. + * is currently broken.
  17650. + *
  17651. + * mbuf
  17652. + * ----
  17653. + * Either fill in the mbuf pointer and npa=0 or
  17654. + * fill packp[] and packl[] and set npa to > 0
  17655. + *
  17656. + * mac_header_skip
  17657. + * ---------------
  17658. + * The number of bytes of the source_buf that are skipped over before
  17659. + * authentication begins. This must be a number between 0 and 2^16-1
  17660. + * and can be used by IPsec implementers to skip over IP headers.
  17661. + * *** Value ignored if authentication not used ***
  17662. + *
  17663. + * crypt_header_skip
  17664. + * -----------------
  17665. + * The number of bytes of the source_buf that are skipped over before
  17666. + * the cryptographic operation begins. This must be a number between 0
  17667. + * and 2^16-1. For IPsec, this number will always be 8 bytes larger
  17668. + * than the auth_header_skip (to skip over the ESP header).
  17669. + * *** Value ignored if cryptography not used ***
  17670. + *
  17671. + */
  17672. +struct hifn_operand {
  17673. + union {
  17674. + struct sk_buff *skb;
  17675. + struct uio *io;
  17676. + unsigned char *buf;
  17677. + } u;
  17678. + void *map;
  17679. + bus_size_t mapsize;
  17680. + int nsegs;
  17681. + struct {
  17682. + dma_addr_t ds_addr;
  17683. + int ds_len;
  17684. + } segs[MAX_SCATTER];
  17685. +};
  17686. +
  17687. +struct hifn_command {
  17688. + u_int16_t session_num;
  17689. + u_int16_t base_masks, cry_masks, mac_masks;
  17690. + u_int8_t iv[HIFN_MAX_IV_LENGTH], *ck, mac[HIFN_MAC_KEY_LENGTH];
  17691. + int cklen;
  17692. + int sloplen, slopidx;
  17693. +
  17694. + struct hifn_operand src;
  17695. + struct hifn_operand dst;
  17696. +
  17697. + struct hifn_softc *softc;
  17698. + struct cryptop *crp;
  17699. + struct cryptodesc *enccrd, *maccrd;
  17700. +};
  17701. +
  17702. +#define src_skb src.u.skb
  17703. +#define src_io src.u.io
  17704. +#define src_map src.map
  17705. +#define src_mapsize src.mapsize
  17706. +#define src_segs src.segs
  17707. +#define src_nsegs src.nsegs
  17708. +#define src_buf src.u.buf
  17709. +
  17710. +#define dst_skb dst.u.skb
  17711. +#define dst_io dst.u.io
  17712. +#define dst_map dst.map
  17713. +#define dst_mapsize dst.mapsize
  17714. +#define dst_segs dst.segs
  17715. +#define dst_nsegs dst.nsegs
  17716. +#define dst_buf dst.u.buf
  17717. +
  17718. +/*
  17719. + * Return values for hifn_crypto()
  17720. + */
  17721. +#define HIFN_CRYPTO_SUCCESS 0
  17722. +#define HIFN_CRYPTO_BAD_INPUT (-1)
  17723. +#define HIFN_CRYPTO_RINGS_FULL (-2)
  17724. +
  17725. +/**************************************************************************
  17726. + *
  17727. + * Function: hifn_crypto
  17728. + *
  17729. + * Purpose: Called by external drivers to begin an encryption on the
  17730. + * HIFN board.
  17731. + *
  17732. + * Blocking/Non-blocking Issues
  17733. + * ============================
  17734. + * The driver cannot block in hifn_crypto (no calls to tsleep) currently.
  17735. + * hifn_crypto() returns HIFN_CRYPTO_RINGS_FULL if there is not enough
  17736. + * room in any of the rings for the request to proceed.
  17737. + *
  17738. + * Return Values
  17739. + * =============
  17740. + * 0 for success, negative values on error
  17741. + *
  17742. + * Defines for negative error codes are:
  17743. + *
  17744. + * HIFN_CRYPTO_BAD_INPUT : The passed in command had invalid settings.
  17745. + * HIFN_CRYPTO_RINGS_FULL : All DMA rings were full and non-blocking
  17746. + * behaviour was requested.
  17747. + *
  17748. + *************************************************************************/
  17749. +
  17750. +/*
  17751. + * Convert back and forth from 'sid' to 'card' and 'session'
  17752. + */
  17753. +#define HIFN_CARD(sid) (((sid) & 0xf0000000) >> 28)
  17754. +#define HIFN_SESSION(sid) ((sid) & 0x000007ff)
  17755. +#define HIFN_SID(crd,ses) (((crd) << 28) | ((ses) & 0x7ff))
  17756. +
  17757. +#endif /* _KERNEL */
  17758. +
  17759. +struct hifn_stats {
  17760. + u_int64_t hst_ibytes;
  17761. + u_int64_t hst_obytes;
  17762. + u_int32_t hst_ipackets;
  17763. + u_int32_t hst_opackets;
  17764. + u_int32_t hst_invalid;
  17765. + u_int32_t hst_nomem; /* malloc or one of hst_nomem_* */
  17766. + u_int32_t hst_abort;
  17767. + u_int32_t hst_noirq; /* IRQ for no reason */
  17768. + u_int32_t hst_totbatch; /* ops submitted w/o interrupt */
  17769. + u_int32_t hst_maxbatch; /* max ops submitted together */
  17770. + u_int32_t hst_unaligned; /* unaligned src caused copy */
  17771. + /*
  17772. + * The following divides hst_nomem into more specific buckets.
  17773. + */
  17774. + u_int32_t hst_nomem_map; /* bus_dmamap_create failed */
  17775. + u_int32_t hst_nomem_load; /* bus_dmamap_load_* failed */
  17776. + u_int32_t hst_nomem_mbuf; /* MGET* failed */
  17777. + u_int32_t hst_nomem_mcl; /* MCLGET* failed */
  17778. + u_int32_t hst_nomem_cr; /* out of command/result descriptor */
  17779. + u_int32_t hst_nomem_sd; /* out of src/dst descriptors */
  17780. +};
  17781. +
  17782. +#endif /* __HIFN7751VAR_H__ */
  17783. diff -Nur linux-2.6.39.orig/crypto/ocf/hifn/hifnHIPP.c linux-2.6.39/crypto/ocf/hifn/hifnHIPP.c
  17784. --- linux-2.6.39.orig/crypto/ocf/hifn/hifnHIPP.c 1970-01-01 01:00:00.000000000 +0100
  17785. +++ linux-2.6.39/crypto/ocf/hifn/hifnHIPP.c 2011-08-01 14:38:18.000000000 +0200
  17786. @@ -0,0 +1,420 @@
  17787. +/*-
  17788. + * Driver for Hifn HIPP-I/II chipset
  17789. + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
  17790. + *
  17791. + * Redistribution and use in source and binary forms, with or without
  17792. + * modification, are permitted provided that the following conditions
  17793. + * are met:
  17794. + *
  17795. + * 1. Redistributions of source code must retain the above copyright
  17796. + * notice, this list of conditions and the following disclaimer.
  17797. + * 2. Redistributions in binary form must reproduce the above copyright
  17798. + * notice, this list of conditions and the following disclaimer in the
  17799. + * documentation and/or other materials provided with the distribution.
  17800. + * 3. The name of the author may not be used to endorse or promote products
  17801. + * derived from this software without specific prior written permission.
  17802. + *
  17803. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  17804. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  17805. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17806. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  17807. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  17808. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  17809. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  17810. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  17811. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  17812. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  17813. + *
  17814. + * Effort sponsored by Hifn Inc.
  17815. + *
  17816. + */
  17817. +
  17818. +/*
  17819. + * Driver for various Hifn encryption processors.
  17820. + */
  17821. +#ifndef AUTOCONF_INCLUDED
  17822. +#include <linux/config.h>
  17823. +#endif
  17824. +#include <linux/module.h>
  17825. +#include <linux/init.h>
  17826. +#include <linux/list.h>
  17827. +#include <linux/slab.h>
  17828. +#include <linux/wait.h>
  17829. +#include <linux/sched.h>
  17830. +#include <linux/pci.h>
  17831. +#include <linux/delay.h>
  17832. +#include <linux/interrupt.h>
  17833. +#include <linux/spinlock.h>
  17834. +#include <linux/random.h>
  17835. +#include <linux/version.h>
  17836. +#include <linux/skbuff.h>
  17837. +#include <linux/uio.h>
  17838. +#include <linux/sysfs.h>
  17839. +#include <linux/miscdevice.h>
  17840. +#include <asm/io.h>
  17841. +
  17842. +#include <cryptodev.h>
  17843. +
  17844. +#include "hifnHIPPreg.h"
  17845. +#include "hifnHIPPvar.h"
  17846. +
  17847. +#if 1
  17848. +#define DPRINTF(a...) if (hipp_debug) { \
  17849. + printk("%s: ", sc ? \
  17850. + device_get_nameunit(sc->sc_dev) : "hifn"); \
  17851. + printk(a); \
  17852. + } else
  17853. +#else
  17854. +#define DPRINTF(a...)
  17855. +#endif
  17856. +
  17857. +typedef int bus_size_t;
  17858. +
  17859. +static inline int
  17860. +pci_get_revid(struct pci_dev *dev)
  17861. +{
  17862. + u8 rid = 0;
  17863. + pci_read_config_byte(dev, PCI_REVISION_ID, &rid);
  17864. + return rid;
  17865. +}
  17866. +
  17867. +#define debug hipp_debug
  17868. +int hipp_debug = 0;
  17869. +module_param(hipp_debug, int, 0644);
  17870. +MODULE_PARM_DESC(hipp_debug, "Enable debug");
  17871. +
  17872. +int hipp_maxbatch = 1;
  17873. +module_param(hipp_maxbatch, int, 0644);
  17874. +MODULE_PARM_DESC(hipp_maxbatch, "max ops to batch w/o interrupt");
  17875. +
  17876. +static int hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent);
  17877. +static void hipp_remove(struct pci_dev *dev);
  17878. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  17879. +static irqreturn_t hipp_intr(int irq, void *arg);
  17880. +#else
  17881. +static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs);
  17882. +#endif
  17883. +
  17884. +static int hipp_num_chips = 0;
  17885. +static struct hipp_softc *hipp_chip_idx[HIPP_MAX_CHIPS];
  17886. +
  17887. +static int hipp_newsession(device_t, u_int32_t *, struct cryptoini *);
  17888. +static int hipp_freesession(device_t, u_int64_t);
  17889. +static int hipp_process(device_t, struct cryptop *, int);
  17890. +
  17891. +static device_method_t hipp_methods = {
  17892. + /* crypto device methods */
  17893. + DEVMETHOD(cryptodev_newsession, hipp_newsession),
  17894. + DEVMETHOD(cryptodev_freesession,hipp_freesession),
  17895. + DEVMETHOD(cryptodev_process, hipp_process),
  17896. +};
  17897. +
  17898. +static __inline u_int32_t
  17899. +READ_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg)
  17900. +{
  17901. + u_int32_t v = readl(sc->sc_bar[barno] + reg);
  17902. + //sc->sc_bar0_lastreg = (bus_size_t) -1;
  17903. + return (v);
  17904. +}
  17905. +static __inline void
  17906. +WRITE_REG(struct hipp_softc *sc, unsigned int barno, bus_size_t reg, u_int32_t val)
  17907. +{
  17908. + writel(val, sc->sc_bar[barno] + reg);
  17909. +}
  17910. +
  17911. +#define READ_REG_0(sc, reg) READ_REG(sc, 0, reg)
  17912. +#define WRITE_REG_0(sc, reg, val) WRITE_REG(sc,0, reg, val)
  17913. +#define READ_REG_1(sc, reg) READ_REG(sc, 1, reg)
  17914. +#define WRITE_REG_1(sc, reg, val) WRITE_REG(sc,1, reg, val)
  17915. +
  17916. +static int
  17917. +hipp_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  17918. +{
  17919. + return EINVAL;
  17920. +}
  17921. +
  17922. +static int
  17923. +hipp_freesession(device_t dev, u_int64_t tid)
  17924. +{
  17925. + return EINVAL;
  17926. +}
  17927. +
  17928. +static int
  17929. +hipp_process(device_t dev, struct cryptop *crp, int hint)
  17930. +{
  17931. + return EINVAL;
  17932. +}
  17933. +
  17934. +static const char*
  17935. +hipp_partname(struct hipp_softc *sc, char buf[128], size_t blen)
  17936. +{
  17937. + char *n = NULL;
  17938. +
  17939. + switch (pci_get_vendor(sc->sc_pcidev)) {
  17940. + case PCI_VENDOR_HIFN:
  17941. + switch (pci_get_device(sc->sc_pcidev)) {
  17942. + case PCI_PRODUCT_HIFN_7855: n = "Hifn 7855";
  17943. + case PCI_PRODUCT_HIFN_8155: n = "Hifn 8155";
  17944. + case PCI_PRODUCT_HIFN_6500: n = "Hifn 6500";
  17945. + }
  17946. + }
  17947. +
  17948. + if(n==NULL) {
  17949. + snprintf(buf, blen, "VID=%02x,PID=%02x",
  17950. + pci_get_vendor(sc->sc_pcidev),
  17951. + pci_get_device(sc->sc_pcidev));
  17952. + } else {
  17953. + buf[0]='\0';
  17954. + strncat(buf, n, blen);
  17955. + }
  17956. + return buf;
  17957. +}
  17958. +
  17959. +struct hipp_fs_entry {
  17960. + struct attribute attr;
  17961. + /* other stuff */
  17962. +};
  17963. +
  17964. +
  17965. +static ssize_t
  17966. +cryptoid_show(struct device *dev,
  17967. + struct device_attribute *attr,
  17968. + char *buf)
  17969. +{
  17970. + struct hipp_softc *sc;
  17971. +
  17972. + sc = pci_get_drvdata(to_pci_dev (dev));
  17973. + return sprintf (buf, "%d\n", sc->sc_cid);
  17974. +}
  17975. +
  17976. +struct device_attribute hipp_dev_cryptoid = __ATTR_RO(cryptoid);
  17977. +
  17978. +/*
  17979. + * Attach an interface that successfully probed.
  17980. + */
  17981. +static int
  17982. +hipp_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  17983. +{
  17984. + struct hipp_softc *sc = NULL;
  17985. + int i;
  17986. + //char rbase;
  17987. + //u_int16_t ena;
  17988. + int rev;
  17989. + //int rseg;
  17990. + int rc;
  17991. +
  17992. + DPRINTF("%s()\n", __FUNCTION__);
  17993. +
  17994. + if (pci_enable_device(dev) < 0)
  17995. + return(-ENODEV);
  17996. +
  17997. + if (pci_set_mwi(dev))
  17998. + return(-ENODEV);
  17999. +
  18000. + if (!dev->irq) {
  18001. + printk("hifn: found device with no IRQ assigned. check BIOS settings!");
  18002. + pci_disable_device(dev);
  18003. + return(-ENODEV);
  18004. + }
  18005. +
  18006. + sc = (struct hipp_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  18007. + if (!sc)
  18008. + return(-ENOMEM);
  18009. + memset(sc, 0, sizeof(*sc));
  18010. +
  18011. + softc_device_init(sc, "hifn-hipp", hipp_num_chips, hipp_methods);
  18012. +
  18013. + sc->sc_pcidev = dev;
  18014. + sc->sc_irq = -1;
  18015. + sc->sc_cid = -1;
  18016. + sc->sc_num = hipp_num_chips++;
  18017. +
  18018. + if (sc->sc_num < HIPP_MAX_CHIPS)
  18019. + hipp_chip_idx[sc->sc_num] = sc;
  18020. +
  18021. + pci_set_drvdata(sc->sc_pcidev, sc);
  18022. +
  18023. + spin_lock_init(&sc->sc_mtx);
  18024. +
  18025. + /*
  18026. + * Setup PCI resources.
  18027. + * The READ_REG_0, WRITE_REG_0, READ_REG_1,
  18028. + * and WRITE_REG_1 macros throughout the driver are used
  18029. + * to permit better debugging.
  18030. + */
  18031. + for(i=0; i<4; i++) {
  18032. + unsigned long mem_start, mem_len;
  18033. + mem_start = pci_resource_start(sc->sc_pcidev, i);
  18034. + mem_len = pci_resource_len(sc->sc_pcidev, i);
  18035. + sc->sc_barphy[i] = (caddr_t)mem_start;
  18036. + sc->sc_bar[i] = (ocf_iomem_t) ioremap(mem_start, mem_len);
  18037. + if (!sc->sc_bar[i]) {
  18038. + device_printf(sc->sc_dev, "cannot map bar%d register space\n", i);
  18039. + goto fail;
  18040. + }
  18041. + }
  18042. +
  18043. + //hipp_reset_board(sc, 0);
  18044. + pci_set_master(sc->sc_pcidev);
  18045. +
  18046. + /*
  18047. + * Arrange the interrupt line.
  18048. + */
  18049. + rc = request_irq(dev->irq, hipp_intr, IRQF_SHARED, "hifn", sc);
  18050. + if (rc) {
  18051. + device_printf(sc->sc_dev, "could not map interrupt: %d\n", rc);
  18052. + goto fail;
  18053. + }
  18054. + sc->sc_irq = dev->irq;
  18055. +
  18056. + rev = READ_REG_1(sc, HIPP_1_REVID) & 0xffff;
  18057. +
  18058. + {
  18059. + char b[32];
  18060. + device_printf(sc->sc_dev, "%s, rev %u",
  18061. + hipp_partname(sc, b, sizeof(b)), rev);
  18062. + }
  18063. +
  18064. +#if 0
  18065. + if (sc->sc_flags & HIFN_IS_7956)
  18066. + printf(", pll=0x%x<%s clk, %ux mult>",
  18067. + sc->sc_pllconfig,
  18068. + sc->sc_pllconfig & HIFN_PLL_REF_SEL ? "ext" : "pci",
  18069. + 2 + 2*((sc->sc_pllconfig & HIFN_PLL_ND) >> 11));
  18070. +#endif
  18071. + printf("\n");
  18072. +
  18073. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
  18074. + if (sc->sc_cid < 0) {
  18075. + device_printf(sc->sc_dev, "could not get crypto driver id\n");
  18076. + goto fail;
  18077. + }
  18078. +
  18079. +#if 0 /* cannot work with a non-GPL module */
  18080. + /* make a sysfs entry to let the world know what entry we got */
  18081. + sysfs_create_file(&sc->sc_pcidev->dev.kobj, &hipp_dev_cryptoid.attr);
  18082. +#endif
  18083. +
  18084. +#if 0
  18085. + init_timer(&sc->sc_tickto);
  18086. + sc->sc_tickto.function = hifn_tick;
  18087. + sc->sc_tickto.data = (unsigned long) sc->sc_num;
  18088. + mod_timer(&sc->sc_tickto, jiffies + HZ);
  18089. +#endif
  18090. +
  18091. +#if 0 /* no code here yet ?? */
  18092. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  18093. +#endif
  18094. +
  18095. + return (0);
  18096. +
  18097. +fail:
  18098. + if (sc->sc_cid >= 0)
  18099. + crypto_unregister_all(sc->sc_cid);
  18100. + if (sc->sc_irq != -1)
  18101. + free_irq(sc->sc_irq, sc);
  18102. +
  18103. +#if 0
  18104. + if (sc->sc_dma) {
  18105. + /* Turn off DMA polling */
  18106. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  18107. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  18108. +
  18109. + pci_free_consistent(sc->sc_pcidev,
  18110. + sizeof(*sc->sc_dma),
  18111. + sc->sc_dma, sc->sc_dma_physaddr);
  18112. + }
  18113. +#endif
  18114. + kfree(sc);
  18115. + return (-ENXIO);
  18116. +}
  18117. +
  18118. +/*
  18119. + * Detach an interface that successfully probed.
  18120. + */
  18121. +static void
  18122. +hipp_remove(struct pci_dev *dev)
  18123. +{
  18124. + struct hipp_softc *sc = pci_get_drvdata(dev);
  18125. + unsigned long l_flags;
  18126. +
  18127. + DPRINTF("%s()\n", __FUNCTION__);
  18128. +
  18129. + /* disable interrupts */
  18130. + HIPP_LOCK(sc);
  18131. +
  18132. +#if 0
  18133. + WRITE_REG_1(sc, HIFN_1_DMA_IER, 0);
  18134. + HIFN_UNLOCK(sc);
  18135. +
  18136. + /*XXX other resources */
  18137. + del_timer_sync(&sc->sc_tickto);
  18138. +
  18139. + /* Turn off DMA polling */
  18140. + WRITE_REG_1(sc, HIFN_1_DMA_CNFG, HIFN_DMACNFG_MSTRESET |
  18141. + HIFN_DMACNFG_DMARESET | HIFN_DMACNFG_MODE);
  18142. +#endif
  18143. +
  18144. + crypto_unregister_all(sc->sc_cid);
  18145. +
  18146. + free_irq(sc->sc_irq, sc);
  18147. +
  18148. +#if 0
  18149. + pci_free_consistent(sc->sc_pcidev, sizeof(*sc->sc_dma),
  18150. + sc->sc_dma, sc->sc_dma_physaddr);
  18151. +#endif
  18152. +}
  18153. +
  18154. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  18155. +static irqreturn_t hipp_intr(int irq, void *arg)
  18156. +#else
  18157. +static irqreturn_t hipp_intr(int irq, void *arg, struct pt_regs *regs)
  18158. +#endif
  18159. +{
  18160. + struct hipp_softc *sc = arg;
  18161. +
  18162. + sc = sc; /* shut up compiler */
  18163. +
  18164. + return IRQ_HANDLED;
  18165. +}
  18166. +
  18167. +static struct pci_device_id hipp_pci_tbl[] = {
  18168. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_7855,
  18169. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  18170. + { PCI_VENDOR_HIFN, PCI_PRODUCT_HIFN_8155,
  18171. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  18172. +};
  18173. +MODULE_DEVICE_TABLE(pci, hipp_pci_tbl);
  18174. +
  18175. +static struct pci_driver hipp_driver = {
  18176. + .name = "hipp",
  18177. + .id_table = hipp_pci_tbl,
  18178. + .probe = hipp_probe,
  18179. + .remove = hipp_remove,
  18180. + /* add PM stuff here one day */
  18181. +};
  18182. +
  18183. +static int __init hipp_init (void)
  18184. +{
  18185. + struct hipp_softc *sc = NULL;
  18186. + int rc;
  18187. +
  18188. + DPRINTF("%s(%p)\n", __FUNCTION__, hipp_init);
  18189. +
  18190. + rc = pci_register_driver(&hipp_driver);
  18191. + pci_register_driver_compat(&hipp_driver, rc);
  18192. +
  18193. + return rc;
  18194. +}
  18195. +
  18196. +static void __exit hipp_exit (void)
  18197. +{
  18198. + pci_unregister_driver(&hipp_driver);
  18199. +}
  18200. +
  18201. +module_init(hipp_init);
  18202. +module_exit(hipp_exit);
  18203. +
  18204. +MODULE_LICENSE("BSD");
  18205. +MODULE_AUTHOR("Michael Richardson <mcr@xelerance.com>");
  18206. +MODULE_DESCRIPTION("OCF driver for hifn HIPP-I/II PCI crypto devices");
  18207. diff -Nur linux-2.6.39.orig/crypto/ocf/hifn/hifnHIPPreg.h linux-2.6.39/crypto/ocf/hifn/hifnHIPPreg.h
  18208. --- linux-2.6.39.orig/crypto/ocf/hifn/hifnHIPPreg.h 1970-01-01 01:00:00.000000000 +0100
  18209. +++ linux-2.6.39/crypto/ocf/hifn/hifnHIPPreg.h 2011-08-01 14:38:18.000000000 +0200
  18210. @@ -0,0 +1,46 @@
  18211. +/*-
  18212. + * Hifn HIPP-I/HIPP-II (7855/8155) driver.
  18213. + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com>
  18214. + *
  18215. + * Redistribution and use in source and binary forms, with or without
  18216. + * modification, are permitted provided that the following conditions
  18217. + * are met:
  18218. + *
  18219. + * 1. Redistributions of source code must retain the above copyright
  18220. + * notice, this list of conditions and the following disclaimer.
  18221. + * 2. Redistributions in binary form must reproduce the above copyright
  18222. + * notice, this list of conditions and the following disclaimer in the
  18223. + * documentation and/or other materials provided with the distribution.
  18224. + * 3. The name of the author may not be used to endorse or promote products
  18225. + * derived from this software without specific prior written permission.
  18226. + *
  18227. + *
  18228. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18229. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  18230. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  18231. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  18232. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  18233. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  18234. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  18235. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  18236. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  18237. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  18238. + *
  18239. + * Effort sponsored by Hifn inc.
  18240. + *
  18241. + */
  18242. +
  18243. +#ifndef __HIFNHIPP_H__
  18244. +#define __HIFNHIPP_H__
  18245. +
  18246. +/*
  18247. + * PCI vendor and device identifiers
  18248. + */
  18249. +#define PCI_VENDOR_HIFN 0x13a3 /* Hifn */
  18250. +#define PCI_PRODUCT_HIFN_6500 0x0006 /* 6500 */
  18251. +#define PCI_PRODUCT_HIFN_7855 0x001f /* 7855 */
  18252. +#define PCI_PRODUCT_HIFN_8155 0x999 /* XXX 8155 */
  18253. +
  18254. +#define HIPP_1_REVID 0x01 /* BOGUS */
  18255. +
  18256. +#endif /* __HIPP_H__ */
  18257. diff -Nur linux-2.6.39.orig/crypto/ocf/hifn/hifnHIPPvar.h linux-2.6.39/crypto/ocf/hifn/hifnHIPPvar.h
  18258. --- linux-2.6.39.orig/crypto/ocf/hifn/hifnHIPPvar.h 1970-01-01 01:00:00.000000000 +0100
  18259. +++ linux-2.6.39/crypto/ocf/hifn/hifnHIPPvar.h 2011-08-01 14:38:18.000000000 +0200
  18260. @@ -0,0 +1,93 @@
  18261. +/*
  18262. + * Hifn HIPP-I/HIPP-II (7855/8155) driver.
  18263. + * Copyright (c) 2006 Michael Richardson <mcr@xelerance.com> *
  18264. + *
  18265. + * Redistribution and use in source and binary forms, with or without
  18266. + * modification, are permitted provided that the following conditions
  18267. + * are met:
  18268. + *
  18269. + * 1. Redistributions of source code must retain the above copyright
  18270. + * notice, this list of conditions and the following disclaimer.
  18271. + * 2. Redistributions in binary form must reproduce the above copyright
  18272. + * notice, this list of conditions and the following disclaimer in the
  18273. + * documentation and/or other materials provided with the distribution.
  18274. + * 3. The name of the author may not be used to endorse or promote products
  18275. + * derived from this software without specific prior written permission.
  18276. + *
  18277. + *
  18278. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18279. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  18280. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  18281. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  18282. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  18283. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  18284. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  18285. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  18286. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  18287. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  18288. + *
  18289. + * Effort sponsored by Hifn inc.
  18290. + *
  18291. + */
  18292. +
  18293. +#ifndef __HIFNHIPPVAR_H__
  18294. +#define __HIFNHIPPVAR_H__
  18295. +
  18296. +#define HIPP_MAX_CHIPS 8
  18297. +
  18298. +/*
  18299. + * Holds data specific to a single Hifn HIPP-I board.
  18300. + */
  18301. +struct hipp_softc {
  18302. + softc_device_decl sc_dev;
  18303. +
  18304. + struct pci_dev *sc_pcidev; /* device backpointer */
  18305. + ocf_iomem_t sc_bar[5];
  18306. + caddr_t sc_barphy[5]; /* physical address */
  18307. + int sc_num; /* for multiple devs */
  18308. + spinlock_t sc_mtx; /* per-instance lock */
  18309. + int32_t sc_cid;
  18310. + int sc_irq;
  18311. +
  18312. +#if 0
  18313. +
  18314. + u_int32_t sc_dmaier;
  18315. + u_int32_t sc_drammodel; /* 1=dram, 0=sram */
  18316. + u_int32_t sc_pllconfig; /* 7954/7955/7956 PLL config */
  18317. +
  18318. + struct hifn_dma *sc_dma;
  18319. + dma_addr_t sc_dma_physaddr;/* physical address of sc_dma */
  18320. +
  18321. + int sc_dmansegs;
  18322. + int sc_maxses;
  18323. + int sc_nsessions;
  18324. + struct hifn_session *sc_sessions;
  18325. + int sc_ramsize;
  18326. + int sc_flags;
  18327. +#define HIFN_HAS_RNG 0x1 /* includes random number generator */
  18328. +#define HIFN_HAS_PUBLIC 0x2 /* includes public key support */
  18329. +#define HIFN_HAS_AES 0x4 /* includes AES support */
  18330. +#define HIFN_IS_7811 0x8 /* Hifn 7811 part */
  18331. +#define HIFN_IS_7956 0x10 /* Hifn 7956/7955 don't have SDRAM */
  18332. +
  18333. + struct timer_list sc_tickto; /* for managing DMA */
  18334. +
  18335. + int sc_rngfirst;
  18336. + int sc_rnghz; /* RNG polling frequency */
  18337. +
  18338. + int sc_c_busy; /* command ring busy */
  18339. + int sc_s_busy; /* source data ring busy */
  18340. + int sc_d_busy; /* destination data ring busy */
  18341. + int sc_r_busy; /* result ring busy */
  18342. + int sc_active; /* for initial countdown */
  18343. + int sc_needwakeup; /* ops q'd wating on resources */
  18344. + int sc_curbatch; /* # ops submitted w/o int */
  18345. + int sc_suspended;
  18346. + struct miscdevice sc_miscdev;
  18347. +#endif
  18348. +};
  18349. +
  18350. +#define HIPP_LOCK(_sc) spin_lock_irqsave(&(_sc)->sc_mtx, l_flags)
  18351. +#define HIPP_UNLOCK(_sc) spin_unlock_irqrestore(&(_sc)->sc_mtx, l_flags)
  18352. +
  18353. +#endif /* __HIFNHIPPVAR_H__ */
  18354. diff -Nur linux-2.6.39.orig/crypto/ocf/ixp4xx/Makefile linux-2.6.39/crypto/ocf/ixp4xx/Makefile
  18355. --- linux-2.6.39.orig/crypto/ocf/ixp4xx/Makefile 1970-01-01 01:00:00.000000000 +0100
  18356. +++ linux-2.6.39/crypto/ocf/ixp4xx/Makefile 2011-08-01 14:38:18.000000000 +0200
  18357. @@ -0,0 +1,104 @@
  18358. +# for SGlinux builds
  18359. +-include $(ROOTDIR)/modules/.config
  18360. +
  18361. +#
  18362. +# You will need to point this at your Intel ixp425 includes, this portion
  18363. +# of the Makefile only really works under SGLinux with the appropriate libs
  18364. +# installed. They can be downloaded from http://www.snapgear.org/
  18365. +#
  18366. +ifeq ($(CONFIG_CPU_IXP46X),y)
  18367. +IXPLATFORM = ixp46X
  18368. +else
  18369. +ifeq ($(CONFIG_CPU_IXP43X),y)
  18370. +IXPLATFORM = ixp43X
  18371. +else
  18372. +IXPLATFORM = ixp42X
  18373. +endif
  18374. +endif
  18375. +
  18376. +ifdef CONFIG_IXP400_LIB_2_4
  18377. +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp400_xscale_sw
  18378. +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.4/ixp_osal
  18379. +endif
  18380. +ifdef CONFIG_IXP400_LIB_2_1
  18381. +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp400_xscale_sw
  18382. +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.1/ixp_osal
  18383. +endif
  18384. +ifdef CONFIG_IXP400_LIB_2_0
  18385. +IX_XSCALE_SW = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp400_xscale_sw
  18386. +OSAL_DIR = $(ROOTDIR)/modules/ixp425/ixp400-2.0/ixp_osal
  18387. +endif
  18388. +ifdef IX_XSCALE_SW
  18389. +ifdef CONFIG_IXP400_LIB_2_4
  18390. +IXP_CFLAGS = \
  18391. + -I$(ROOTDIR)/. \
  18392. + -I$(IX_XSCALE_SW)/src/include \
  18393. + -I$(OSAL_DIR)/common/include/ \
  18394. + -I$(OSAL_DIR)/common/include/modules/ \
  18395. + -I$(OSAL_DIR)/common/include/modules/ddk/ \
  18396. + -I$(OSAL_DIR)/common/include/modules/bufferMgt/ \
  18397. + -I$(OSAL_DIR)/common/include/modules/ioMem/ \
  18398. + -I$(OSAL_DIR)/common/os/linux/include/ \
  18399. + -I$(OSAL_DIR)/common/os/linux/include/core/ \
  18400. + -I$(OSAL_DIR)/common/os/linux/include/modules/ \
  18401. + -I$(OSAL_DIR)/common/os/linux/include/modules/ddk/ \
  18402. + -I$(OSAL_DIR)/common/os/linux/include/modules/bufferMgt/ \
  18403. + -I$(OSAL_DIR)/common/os/linux/include/modules/ioMem/ \
  18404. + -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/include/ \
  18405. + -I$(OSAL_DIR)/platforms/$(IXPLATFORM)/os/linux/include/ \
  18406. + -DENABLE_IOMEM -DENABLE_BUFFERMGT -DENABLE_DDK \
  18407. + -DUSE_IXP4XX_CRYPTO
  18408. +else
  18409. +IXP_CFLAGS = \
  18410. + -I$(ROOTDIR)/. \
  18411. + -I$(IX_XSCALE_SW)/src/include \
  18412. + -I$(OSAL_DIR)/ \
  18413. + -I$(OSAL_DIR)/os/linux/include/ \
  18414. + -I$(OSAL_DIR)/os/linux/include/modules/ \
  18415. + -I$(OSAL_DIR)/os/linux/include/modules/ioMem/ \
  18416. + -I$(OSAL_DIR)/os/linux/include/modules/bufferMgt/ \
  18417. + -I$(OSAL_DIR)/os/linux/include/core/ \
  18418. + -I$(OSAL_DIR)/os/linux/include/platforms/ \
  18419. + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ \
  18420. + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp425 \
  18421. + -I$(OSAL_DIR)/os/linux/include/platforms/ixp400/ixp465 \
  18422. + -I$(OSAL_DIR)/os/linux/include/core/ \
  18423. + -I$(OSAL_DIR)/include/ \
  18424. + -I$(OSAL_DIR)/include/modules/ \
  18425. + -I$(OSAL_DIR)/include/modules/bufferMgt/ \
  18426. + -I$(OSAL_DIR)/include/modules/ioMem/ \
  18427. + -I$(OSAL_DIR)/include/platforms/ \
  18428. + -I$(OSAL_DIR)/include/platforms/ixp400/ \
  18429. + -DUSE_IXP4XX_CRYPTO
  18430. +endif
  18431. +endif
  18432. +ifdef CONFIG_IXP400_LIB_1_4
  18433. +IXP_CFLAGS = \
  18434. + -I$(ROOTDIR)/. \
  18435. + -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/include \
  18436. + -I$(ROOTDIR)/modules/ixp425/ixp400-1.4/ixp400_xscale_sw/src/linux \
  18437. + -DUSE_IXP4XX_CRYPTO
  18438. +endif
  18439. +ifndef IXPDIR
  18440. +IXPDIR = ixp-version-is-not-supported
  18441. +endif
  18442. +
  18443. +ifeq ($(CONFIG_CPU_IXP46X),y)
  18444. +IXP_CFLAGS += -D__ixp46X
  18445. +else
  18446. +ifeq ($(CONFIG_CPU_IXP43X),y)
  18447. +IXP_CFLAGS += -D__ixp43X
  18448. +else
  18449. +IXP_CFLAGS += -D__ixp42X
  18450. +endif
  18451. +endif
  18452. +
  18453. +obj-$(CONFIG_OCF_IXP4XX) += ixp4xx.o
  18454. +
  18455. +obj ?= .
  18456. +EXTRA_CFLAGS += $(IXP_CFLAGS) -I$(obj)/.. -I$(obj)/.
  18457. +
  18458. +ifdef TOPDIR
  18459. +-include $(TOPDIR)/Rules.make
  18460. +endif
  18461. +
  18462. diff -Nur linux-2.6.39.orig/crypto/ocf/ixp4xx/ixp4xx.c linux-2.6.39/crypto/ocf/ixp4xx/ixp4xx.c
  18463. --- linux-2.6.39.orig/crypto/ocf/ixp4xx/ixp4xx.c 1970-01-01 01:00:00.000000000 +0100
  18464. +++ linux-2.6.39/crypto/ocf/ixp4xx/ixp4xx.c 2011-08-01 14:38:18.000000000 +0200
  18465. @@ -0,0 +1,1324 @@
  18466. +/*
  18467. + * An OCF module that uses Intels IXP CryptACC API to do the crypto.
  18468. + * This driver requires the IXP400 Access Library that is available
  18469. + * from Intel in order to operate (or compile).
  18470. + *
  18471. + * Written by David McCullough <david_mccullough@mcafee.com>
  18472. + * Copyright (C) 2006-2010 David McCullough
  18473. + * Copyright (C) 2004-2005 Intel Corporation.
  18474. + *
  18475. + * LICENSE TERMS
  18476. + *
  18477. + * The free distribution and use of this software in both source and binary
  18478. + * form is allowed (with or without changes) provided that:
  18479. + *
  18480. + * 1. distributions of this source code include the above copyright
  18481. + * notice, this list of conditions and the following disclaimer;
  18482. + *
  18483. + * 2. distributions in binary form include the above copyright
  18484. + * notice, this list of conditions and the following disclaimer
  18485. + * in the documentation and/or other associated materials;
  18486. + *
  18487. + * 3. the copyright holder's name is not used to endorse products
  18488. + * built using this software without specific written permission.
  18489. + *
  18490. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  18491. + * may be distributed under the terms of the GNU General Public License (GPL),
  18492. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  18493. + *
  18494. + * DISCLAIMER
  18495. + *
  18496. + * This software is provided 'as is' with no explicit or implied warranties
  18497. + * in respect of its properties, including, but not limited to, correctness
  18498. + * and/or fitness for purpose.
  18499. + */
  18500. +
  18501. +#ifndef AUTOCONF_INCLUDED
  18502. +#include <linux/config.h>
  18503. +#endif
  18504. +#include <linux/module.h>
  18505. +#include <linux/init.h>
  18506. +#include <linux/list.h>
  18507. +#include <linux/slab.h>
  18508. +#include <linux/sched.h>
  18509. +#include <linux/wait.h>
  18510. +#include <linux/crypto.h>
  18511. +#include <linux/interrupt.h>
  18512. +#include <asm/scatterlist.h>
  18513. +
  18514. +#include <IxTypes.h>
  18515. +#include <IxOsBuffMgt.h>
  18516. +#include <IxNpeDl.h>
  18517. +#include <IxCryptoAcc.h>
  18518. +#include <IxQMgr.h>
  18519. +#include <IxOsServices.h>
  18520. +#include <IxOsCacheMMU.h>
  18521. +
  18522. +#include <cryptodev.h>
  18523. +#include <uio.h>
  18524. +
  18525. +#ifndef IX_MBUF_PRIV
  18526. +#define IX_MBUF_PRIV(x) ((x)->priv)
  18527. +#endif
  18528. +
  18529. +struct ixp_data;
  18530. +
  18531. +struct ixp_q {
  18532. + struct list_head ixp_q_list;
  18533. + struct ixp_data *ixp_q_data;
  18534. + struct cryptop *ixp_q_crp;
  18535. + struct cryptodesc *ixp_q_ccrd;
  18536. + struct cryptodesc *ixp_q_acrd;
  18537. + IX_MBUF ixp_q_mbuf;
  18538. + UINT8 *ixp_hash_dest; /* Location for hash in client buffer */
  18539. + UINT8 *ixp_hash_src; /* Location of hash in internal buffer */
  18540. + unsigned char ixp_q_iv_data[IX_CRYPTO_ACC_MAX_CIPHER_IV_LENGTH];
  18541. + unsigned char *ixp_q_iv;
  18542. +};
  18543. +
  18544. +struct ixp_data {
  18545. + int ixp_registered; /* is the context registered */
  18546. + int ixp_crd_flags; /* detect direction changes */
  18547. +
  18548. + int ixp_cipher_alg;
  18549. + int ixp_auth_alg;
  18550. +
  18551. + UINT32 ixp_ctx_id;
  18552. + UINT32 ixp_hash_key_id; /* used when hashing */
  18553. + IxCryptoAccCtx ixp_ctx;
  18554. + IX_MBUF ixp_pri_mbuf;
  18555. + IX_MBUF ixp_sec_mbuf;
  18556. +
  18557. + struct work_struct ixp_pending_work;
  18558. + struct work_struct ixp_registration_work;
  18559. + struct list_head ixp_q; /* unprocessed requests */
  18560. +};
  18561. +
  18562. +#ifdef __ixp46X
  18563. +
  18564. +#define MAX_IOP_SIZE 64 /* words */
  18565. +#define MAX_OOP_SIZE 128
  18566. +
  18567. +#define MAX_PARAMS 3
  18568. +
  18569. +struct ixp_pkq {
  18570. + struct list_head pkq_list;
  18571. + struct cryptkop *pkq_krp;
  18572. +
  18573. + IxCryptoAccPkeEauInOperands pkq_op;
  18574. + IxCryptoAccPkeEauOpResult pkq_result;
  18575. +
  18576. + UINT32 pkq_ibuf0[MAX_IOP_SIZE];
  18577. + UINT32 pkq_ibuf1[MAX_IOP_SIZE];
  18578. + UINT32 pkq_ibuf2[MAX_IOP_SIZE];
  18579. + UINT32 pkq_obuf[MAX_OOP_SIZE];
  18580. +};
  18581. +
  18582. +static LIST_HEAD(ixp_pkq); /* current PK wait list */
  18583. +static struct ixp_pkq *ixp_pk_cur;
  18584. +static spinlock_t ixp_pkq_lock;
  18585. +
  18586. +#endif /* __ixp46X */
  18587. +
  18588. +static int ixp_blocked = 0;
  18589. +
  18590. +static int32_t ixp_id = -1;
  18591. +static struct ixp_data **ixp_sessions = NULL;
  18592. +static u_int32_t ixp_sesnum = 0;
  18593. +
  18594. +static int ixp_process(device_t, struct cryptop *, int);
  18595. +static int ixp_newsession(device_t, u_int32_t *, struct cryptoini *);
  18596. +static int ixp_freesession(device_t, u_int64_t);
  18597. +#ifdef __ixp46X
  18598. +static int ixp_kprocess(device_t, struct cryptkop *krp, int hint);
  18599. +#endif
  18600. +
  18601. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)
  18602. +static kmem_cache_t *qcache;
  18603. +#else
  18604. +static struct kmem_cache *qcache;
  18605. +#endif
  18606. +
  18607. +#define debug ixp_debug
  18608. +static int ixp_debug = 0;
  18609. +module_param(ixp_debug, int, 0644);
  18610. +MODULE_PARM_DESC(ixp_debug, "Enable debug");
  18611. +
  18612. +static int ixp_init_crypto = 1;
  18613. +module_param(ixp_init_crypto, int, 0444); /* RO after load/boot */
  18614. +MODULE_PARM_DESC(ixp_init_crypto, "Call ixCryptoAccInit (default is 1)");
  18615. +
  18616. +static void ixp_process_pending(void *arg);
  18617. +static void ixp_registration(void *arg);
  18618. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  18619. +static void ixp_process_pending_wq(struct work_struct *work);
  18620. +static void ixp_registration_wq(struct work_struct *work);
  18621. +#endif
  18622. +
  18623. +/*
  18624. + * dummy device structure
  18625. + */
  18626. +
  18627. +static struct {
  18628. + softc_device_decl sc_dev;
  18629. +} ixpdev;
  18630. +
  18631. +static device_method_t ixp_methods = {
  18632. + /* crypto device methods */
  18633. + DEVMETHOD(cryptodev_newsession, ixp_newsession),
  18634. + DEVMETHOD(cryptodev_freesession,ixp_freesession),
  18635. + DEVMETHOD(cryptodev_process, ixp_process),
  18636. +#ifdef __ixp46X
  18637. + DEVMETHOD(cryptodev_kprocess, ixp_kprocess),
  18638. +#endif
  18639. +};
  18640. +
  18641. +/*
  18642. + * Generate a new software session.
  18643. + */
  18644. +static int
  18645. +ixp_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  18646. +{
  18647. + struct ixp_data *ixp;
  18648. + u_int32_t i;
  18649. +#define AUTH_LEN(cri, def) \
  18650. + (cri->cri_mlen ? cri->cri_mlen : (def))
  18651. +
  18652. + dprintk("%s():alg %d\n", __FUNCTION__,cri->cri_alg);
  18653. + if (sid == NULL || cri == NULL) {
  18654. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  18655. + return EINVAL;
  18656. + }
  18657. +
  18658. + if (ixp_sessions) {
  18659. + for (i = 1; i < ixp_sesnum; i++)
  18660. + if (ixp_sessions[i] == NULL)
  18661. + break;
  18662. + } else
  18663. + i = 1; /* NB: to silence compiler warning */
  18664. +
  18665. + if (ixp_sessions == NULL || i == ixp_sesnum) {
  18666. + struct ixp_data **ixpd;
  18667. +
  18668. + if (ixp_sessions == NULL) {
  18669. + i = 1; /* We leave ixp_sessions[0] empty */
  18670. + ixp_sesnum = CRYPTO_SW_SESSIONS;
  18671. + } else
  18672. + ixp_sesnum *= 2;
  18673. +
  18674. + ixpd = kmalloc(ixp_sesnum * sizeof(struct ixp_data *), SLAB_ATOMIC);
  18675. + if (ixpd == NULL) {
  18676. + /* Reset session number */
  18677. + if (ixp_sesnum == CRYPTO_SW_SESSIONS)
  18678. + ixp_sesnum = 0;
  18679. + else
  18680. + ixp_sesnum /= 2;
  18681. + dprintk("%s,%d: ENOBUFS\n", __FILE__, __LINE__);
  18682. + return ENOBUFS;
  18683. + }
  18684. + memset(ixpd, 0, ixp_sesnum * sizeof(struct ixp_data *));
  18685. +
  18686. + /* Copy existing sessions */
  18687. + if (ixp_sessions) {
  18688. + memcpy(ixpd, ixp_sessions,
  18689. + (ixp_sesnum / 2) * sizeof(struct ixp_data *));
  18690. + kfree(ixp_sessions);
  18691. + }
  18692. +
  18693. + ixp_sessions = ixpd;
  18694. + }
  18695. +
  18696. + ixp_sessions[i] = (struct ixp_data *) kmalloc(sizeof(struct ixp_data),
  18697. + SLAB_ATOMIC);
  18698. + if (ixp_sessions[i] == NULL) {
  18699. + ixp_freesession(NULL, i);
  18700. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  18701. + return ENOBUFS;
  18702. + }
  18703. +
  18704. + *sid = i;
  18705. +
  18706. + ixp = ixp_sessions[i];
  18707. + memset(ixp, 0, sizeof(*ixp));
  18708. +
  18709. + ixp->ixp_cipher_alg = -1;
  18710. + ixp->ixp_auth_alg = -1;
  18711. + ixp->ixp_ctx_id = -1;
  18712. + INIT_LIST_HEAD(&ixp->ixp_q);
  18713. +
  18714. + ixp->ixp_ctx.useDifferentSrcAndDestMbufs = 0;
  18715. +
  18716. + while (cri) {
  18717. + switch (cri->cri_alg) {
  18718. + case CRYPTO_DES_CBC:
  18719. + ixp->ixp_cipher_alg = cri->cri_alg;
  18720. + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_DES;
  18721. + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  18722. + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
  18723. + ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
  18724. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =
  18725. + IX_CRYPTO_ACC_DES_IV_64;
  18726. + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
  18727. + cri->cri_key, (cri->cri_klen + 7) / 8);
  18728. + break;
  18729. +
  18730. + case CRYPTO_3DES_CBC:
  18731. + ixp->ixp_cipher_alg = cri->cri_alg;
  18732. + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
  18733. + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  18734. + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
  18735. + ixp->ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
  18736. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen =
  18737. + IX_CRYPTO_ACC_DES_IV_64;
  18738. + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
  18739. + cri->cri_key, (cri->cri_klen + 7) / 8);
  18740. + break;
  18741. +
  18742. + case CRYPTO_RIJNDAEL128_CBC:
  18743. + ixp->ixp_cipher_alg = cri->cri_alg;
  18744. + ixp->ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_AES;
  18745. + ixp->ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  18746. + ixp->ixp_ctx.cipherCtx.cipherKeyLen = (cri->cri_klen + 7) / 8;
  18747. + ixp->ixp_ctx.cipherCtx.cipherBlockLen = 16;
  18748. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen = 16;
  18749. + memcpy(ixp->ixp_ctx.cipherCtx.key.cipherKey,
  18750. + cri->cri_key, (cri->cri_klen + 7) / 8);
  18751. + break;
  18752. +
  18753. + case CRYPTO_MD5:
  18754. + case CRYPTO_MD5_HMAC:
  18755. + ixp->ixp_auth_alg = cri->cri_alg;
  18756. + ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_MD5;
  18757. + ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, MD5_HASH_LEN);
  18758. + ixp->ixp_ctx.authCtx.aadLen = 0;
  18759. + /* Only MD5_HMAC needs a key */
  18760. + if (cri->cri_alg == CRYPTO_MD5_HMAC) {
  18761. + ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;
  18762. + if (ixp->ixp_ctx.authCtx.authKeyLen >
  18763. + sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {
  18764. + printk(
  18765. + "ixp4xx: Invalid key length for MD5_HMAC - %d bits\n",
  18766. + cri->cri_klen);
  18767. + ixp_freesession(NULL, i);
  18768. + return EINVAL;
  18769. + }
  18770. + memcpy(ixp->ixp_ctx.authCtx.key.authKey,
  18771. + cri->cri_key, (cri->cri_klen + 7) / 8);
  18772. + }
  18773. + break;
  18774. +
  18775. + case CRYPTO_SHA1:
  18776. + case CRYPTO_SHA1_HMAC:
  18777. + ixp->ixp_auth_alg = cri->cri_alg;
  18778. + ixp->ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
  18779. + ixp->ixp_ctx.authCtx.authDigestLen = AUTH_LEN(cri, SHA1_HASH_LEN);
  18780. + ixp->ixp_ctx.authCtx.aadLen = 0;
  18781. + /* Only SHA1_HMAC needs a key */
  18782. + if (cri->cri_alg == CRYPTO_SHA1_HMAC) {
  18783. + ixp->ixp_ctx.authCtx.authKeyLen = (cri->cri_klen + 7) / 8;
  18784. + if (ixp->ixp_ctx.authCtx.authKeyLen >
  18785. + sizeof(ixp->ixp_ctx.authCtx.key.authKey)) {
  18786. + printk(
  18787. + "ixp4xx: Invalid key length for SHA1_HMAC - %d bits\n",
  18788. + cri->cri_klen);
  18789. + ixp_freesession(NULL, i);
  18790. + return EINVAL;
  18791. + }
  18792. + memcpy(ixp->ixp_ctx.authCtx.key.authKey,
  18793. + cri->cri_key, (cri->cri_klen + 7) / 8);
  18794. + }
  18795. + break;
  18796. +
  18797. + default:
  18798. + printk("ixp: unknown algo 0x%x\n", cri->cri_alg);
  18799. + ixp_freesession(NULL, i);
  18800. + return EINVAL;
  18801. + }
  18802. + cri = cri->cri_next;
  18803. + }
  18804. +
  18805. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  18806. + INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending_wq);
  18807. + INIT_WORK(&ixp->ixp_registration_work, ixp_registration_wq);
  18808. +#else
  18809. + INIT_WORK(&ixp->ixp_pending_work, ixp_process_pending, ixp);
  18810. + INIT_WORK(&ixp->ixp_registration_work, ixp_registration, ixp);
  18811. +#endif
  18812. +
  18813. + return 0;
  18814. +}
  18815. +
  18816. +
  18817. +/*
  18818. + * Free a session.
  18819. + */
  18820. +static int
  18821. +ixp_freesession(device_t dev, u_int64_t tid)
  18822. +{
  18823. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  18824. +
  18825. + dprintk("%s()\n", __FUNCTION__);
  18826. + if (sid > ixp_sesnum || ixp_sessions == NULL ||
  18827. + ixp_sessions[sid] == NULL) {
  18828. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  18829. + return EINVAL;
  18830. + }
  18831. +
  18832. + /* Silently accept and return */
  18833. + if (sid == 0)
  18834. + return 0;
  18835. +
  18836. + if (ixp_sessions[sid]) {
  18837. + if (ixp_sessions[sid]->ixp_ctx_id != -1) {
  18838. + ixCryptoAccCtxUnregister(ixp_sessions[sid]->ixp_ctx_id);
  18839. + ixp_sessions[sid]->ixp_ctx_id = -1;
  18840. + }
  18841. + kfree(ixp_sessions[sid]);
  18842. + }
  18843. + ixp_sessions[sid] = NULL;
  18844. + if (ixp_blocked) {
  18845. + ixp_blocked = 0;
  18846. + crypto_unblock(ixp_id, CRYPTO_SYMQ);
  18847. + }
  18848. + return 0;
  18849. +}
  18850. +
  18851. +
  18852. +/*
  18853. + * callback for when hash processing is complete
  18854. + */
  18855. +
  18856. +static void
  18857. +ixp_hash_perform_cb(
  18858. + UINT32 hash_key_id,
  18859. + IX_MBUF *bufp,
  18860. + IxCryptoAccStatus status)
  18861. +{
  18862. + struct ixp_q *q;
  18863. +
  18864. + dprintk("%s(%u, %p, 0x%x)\n", __FUNCTION__, hash_key_id, bufp, status);
  18865. +
  18866. + if (bufp == NULL) {
  18867. + printk("ixp: NULL buf in %s\n", __FUNCTION__);
  18868. + return;
  18869. + }
  18870. +
  18871. + q = IX_MBUF_PRIV(bufp);
  18872. + if (q == NULL) {
  18873. + printk("ixp: NULL priv in %s\n", __FUNCTION__);
  18874. + return;
  18875. + }
  18876. +
  18877. + if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
  18878. + /* On success, need to copy hash back into original client buffer */
  18879. + memcpy(q->ixp_hash_dest, q->ixp_hash_src,
  18880. + (q->ixp_q_data->ixp_auth_alg == CRYPTO_SHA1) ?
  18881. + SHA1_HASH_LEN : MD5_HASH_LEN);
  18882. + }
  18883. + else {
  18884. + printk("ixp: hash perform failed status=%d\n", status);
  18885. + q->ixp_q_crp->crp_etype = EINVAL;
  18886. + }
  18887. +
  18888. + /* Free internal buffer used for hashing */
  18889. + kfree(IX_MBUF_MDATA(&q->ixp_q_mbuf));
  18890. +
  18891. + crypto_done(q->ixp_q_crp);
  18892. + kmem_cache_free(qcache, q);
  18893. +}
  18894. +
  18895. +/*
  18896. + * setup a request and perform it
  18897. + */
  18898. +static void
  18899. +ixp_q_process(struct ixp_q *q)
  18900. +{
  18901. + IxCryptoAccStatus status;
  18902. + struct ixp_data *ixp = q->ixp_q_data;
  18903. + int auth_off = 0;
  18904. + int auth_len = 0;
  18905. + int crypt_off = 0;
  18906. + int crypt_len = 0;
  18907. + int icv_off = 0;
  18908. + char *crypt_func;
  18909. +
  18910. + dprintk("%s(%p)\n", __FUNCTION__, q);
  18911. +
  18912. + if (q->ixp_q_ccrd) {
  18913. + if (q->ixp_q_ccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  18914. + q->ixp_q_iv = q->ixp_q_ccrd->crd_iv;
  18915. + } else {
  18916. + q->ixp_q_iv = q->ixp_q_iv_data;
  18917. + crypto_copydata(q->ixp_q_crp->crp_flags, q->ixp_q_crp->crp_buf,
  18918. + q->ixp_q_ccrd->crd_inject,
  18919. + ixp->ixp_ctx.cipherCtx.cipherInitialVectorLen,
  18920. + (caddr_t) q->ixp_q_iv);
  18921. + }
  18922. +
  18923. + if (q->ixp_q_acrd) {
  18924. + auth_off = q->ixp_q_acrd->crd_skip;
  18925. + auth_len = q->ixp_q_acrd->crd_len;
  18926. + icv_off = q->ixp_q_acrd->crd_inject;
  18927. + }
  18928. +
  18929. + crypt_off = q->ixp_q_ccrd->crd_skip;
  18930. + crypt_len = q->ixp_q_ccrd->crd_len;
  18931. + } else { /* if (q->ixp_q_acrd) */
  18932. + auth_off = q->ixp_q_acrd->crd_skip;
  18933. + auth_len = q->ixp_q_acrd->crd_len;
  18934. + icv_off = q->ixp_q_acrd->crd_inject;
  18935. + }
  18936. +
  18937. + if (q->ixp_q_crp->crp_flags & CRYPTO_F_SKBUF) {
  18938. + struct sk_buff *skb = (struct sk_buff *) q->ixp_q_crp->crp_buf;
  18939. + if (skb_shinfo(skb)->nr_frags) {
  18940. + /*
  18941. + * DAVIDM fix this limitation one day by using
  18942. + * a buffer pool and chaining, it is not currently
  18943. + * needed for current user/kernel space acceleration
  18944. + */
  18945. + printk("ixp: Cannot handle fragmented skb's yet !\n");
  18946. + q->ixp_q_crp->crp_etype = ENOENT;
  18947. + goto done;
  18948. + }
  18949. + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
  18950. + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = skb->len;
  18951. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = skb->data;
  18952. + } else if (q->ixp_q_crp->crp_flags & CRYPTO_F_IOV) {
  18953. + struct uio *uiop = (struct uio *) q->ixp_q_crp->crp_buf;
  18954. + if (uiop->uio_iovcnt != 1) {
  18955. + /*
  18956. + * DAVIDM fix this limitation one day by using
  18957. + * a buffer pool and chaining, it is not currently
  18958. + * needed for current user/kernel space acceleration
  18959. + */
  18960. + printk("ixp: Cannot handle more than 1 iovec yet !\n");
  18961. + q->ixp_q_crp->crp_etype = ENOENT;
  18962. + goto done;
  18963. + }
  18964. + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
  18965. + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_len;
  18966. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = uiop->uio_iov[0].iov_base;
  18967. + } else /* contig buffer */ {
  18968. + IX_MBUF_MLEN(&q->ixp_q_mbuf) =
  18969. + IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_ilen;
  18970. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = q->ixp_q_crp->crp_buf;
  18971. + }
  18972. +
  18973. + IX_MBUF_PRIV(&q->ixp_q_mbuf) = q;
  18974. +
  18975. + if (ixp->ixp_auth_alg == CRYPTO_SHA1 || ixp->ixp_auth_alg == CRYPTO_MD5) {
  18976. + /*
  18977. + * For SHA1 and MD5 hash, need to create an internal buffer that is big
  18978. + * enough to hold the original data + the appropriate padding for the
  18979. + * hash algorithm.
  18980. + */
  18981. + UINT8 *tbuf = NULL;
  18982. +
  18983. + IX_MBUF_MLEN(&q->ixp_q_mbuf) = IX_MBUF_PKT_LEN(&q->ixp_q_mbuf) =
  18984. + ((IX_MBUF_MLEN(&q->ixp_q_mbuf) * 8) + 72 + 511) / 8;
  18985. + tbuf = kmalloc(IX_MBUF_MLEN(&q->ixp_q_mbuf), SLAB_ATOMIC);
  18986. +
  18987. + if (IX_MBUF_MDATA(&q->ixp_q_mbuf) == NULL) {
  18988. + printk("ixp: kmalloc(%u, SLAB_ATOMIC) failed\n",
  18989. + IX_MBUF_MLEN(&q->ixp_q_mbuf));
  18990. + q->ixp_q_crp->crp_etype = ENOMEM;
  18991. + goto done;
  18992. + }
  18993. + memcpy(tbuf, &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off], auth_len);
  18994. +
  18995. + /* Set location in client buffer to copy hash into */
  18996. + q->ixp_hash_dest =
  18997. + &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_off + auth_len];
  18998. +
  18999. + IX_MBUF_MDATA(&q->ixp_q_mbuf) = tbuf;
  19000. +
  19001. + /* Set location in internal buffer for where hash starts */
  19002. + q->ixp_hash_src = &(IX_MBUF_MDATA(&q->ixp_q_mbuf))[auth_len];
  19003. +
  19004. + crypt_func = "ixCryptoAccHashPerform";
  19005. + status = ixCryptoAccHashPerform(ixp->ixp_ctx.authCtx.authAlgo,
  19006. + &q->ixp_q_mbuf, ixp_hash_perform_cb, 0, auth_len, auth_len,
  19007. + &ixp->ixp_hash_key_id);
  19008. + }
  19009. + else {
  19010. + crypt_func = "ixCryptoAccAuthCryptPerform";
  19011. + status = ixCryptoAccAuthCryptPerform(ixp->ixp_ctx_id, &q->ixp_q_mbuf,
  19012. + NULL, auth_off, auth_len, crypt_off, crypt_len, icv_off,
  19013. + q->ixp_q_iv);
  19014. + }
  19015. +
  19016. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  19017. + return;
  19018. +
  19019. + if (IX_CRYPTO_ACC_STATUS_QUEUE_FULL == status) {
  19020. + q->ixp_q_crp->crp_etype = ENOMEM;
  19021. + goto done;
  19022. + }
  19023. +
  19024. + printk("ixp: %s failed %u\n", crypt_func, status);
  19025. + q->ixp_q_crp->crp_etype = EINVAL;
  19026. +
  19027. +done:
  19028. + crypto_done(q->ixp_q_crp);
  19029. + kmem_cache_free(qcache, q);
  19030. +}
  19031. +
  19032. +
  19033. +/*
  19034. + * because we cannot process the Q from the Register callback
  19035. + * we do it here on a task Q.
  19036. + */
  19037. +
  19038. +static void
  19039. +ixp_process_pending(void *arg)
  19040. +{
  19041. + struct ixp_data *ixp = arg;
  19042. + struct ixp_q *q = NULL;
  19043. +
  19044. + dprintk("%s(%p)\n", __FUNCTION__, arg);
  19045. +
  19046. + if (!ixp)
  19047. + return;
  19048. +
  19049. + while (!list_empty(&ixp->ixp_q)) {
  19050. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  19051. + list_del(&q->ixp_q_list);
  19052. + ixp_q_process(q);
  19053. + }
  19054. +}
  19055. +
  19056. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  19057. +static void
  19058. +ixp_process_pending_wq(struct work_struct *work)
  19059. +{
  19060. + struct ixp_data *ixp = container_of(work, struct ixp_data, ixp_pending_work);
  19061. + ixp_process_pending(ixp);
  19062. +}
  19063. +#endif
  19064. +
  19065. +/*
  19066. + * callback for when context registration is complete
  19067. + */
  19068. +
  19069. +static void
  19070. +ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
  19071. +{
  19072. + int i;
  19073. + struct ixp_data *ixp;
  19074. + struct ixp_q *q;
  19075. +
  19076. + dprintk("%s(%d, %p, %d)\n", __FUNCTION__, ctx_id, bufp, status);
  19077. +
  19078. + /*
  19079. + * free any buffer passed in to this routine
  19080. + */
  19081. + if (bufp) {
  19082. + IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
  19083. + kfree(IX_MBUF_MDATA(bufp));
  19084. + IX_MBUF_MDATA(bufp) = NULL;
  19085. + }
  19086. +
  19087. + for (i = 0; i < ixp_sesnum; i++) {
  19088. + ixp = ixp_sessions[i];
  19089. + if (ixp && ixp->ixp_ctx_id == ctx_id)
  19090. + break;
  19091. + }
  19092. + if (i >= ixp_sesnum) {
  19093. + printk("ixp: invalid context id %d\n", ctx_id);
  19094. + return;
  19095. + }
  19096. +
  19097. + if (IX_CRYPTO_ACC_STATUS_WAIT == status) {
  19098. + /* this is normal to free the first of two buffers */
  19099. + dprintk("ixp: register not finished yet.\n");
  19100. + return;
  19101. + }
  19102. +
  19103. + if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
  19104. + printk("ixp: register failed 0x%x\n", status);
  19105. + while (!list_empty(&ixp->ixp_q)) {
  19106. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  19107. + list_del(&q->ixp_q_list);
  19108. + q->ixp_q_crp->crp_etype = EINVAL;
  19109. + crypto_done(q->ixp_q_crp);
  19110. + kmem_cache_free(qcache, q);
  19111. + }
  19112. + return;
  19113. + }
  19114. +
  19115. + /*
  19116. + * we are now registered, we cannot start processing the Q here
  19117. + * or we get strange errors with AES (DES/3DES seem to be ok).
  19118. + */
  19119. + ixp->ixp_registered = 1;
  19120. + schedule_work(&ixp->ixp_pending_work);
  19121. +}
  19122. +
  19123. +
  19124. +/*
  19125. + * callback for when data processing is complete
  19126. + */
  19127. +
  19128. +static void
  19129. +ixp_perform_cb(
  19130. + UINT32 ctx_id,
  19131. + IX_MBUF *sbufp,
  19132. + IX_MBUF *dbufp,
  19133. + IxCryptoAccStatus status)
  19134. +{
  19135. + struct ixp_q *q;
  19136. +
  19137. + dprintk("%s(%d, %p, %p, 0x%x)\n", __FUNCTION__, ctx_id, sbufp,
  19138. + dbufp, status);
  19139. +
  19140. + if (sbufp == NULL) {
  19141. + printk("ixp: NULL sbuf in ixp_perform_cb\n");
  19142. + return;
  19143. + }
  19144. +
  19145. + q = IX_MBUF_PRIV(sbufp);
  19146. + if (q == NULL) {
  19147. + printk("ixp: NULL priv in ixp_perform_cb\n");
  19148. + return;
  19149. + }
  19150. +
  19151. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  19152. + printk("ixp: perform failed status=%d\n", status);
  19153. + q->ixp_q_crp->crp_etype = EINVAL;
  19154. + }
  19155. +
  19156. + crypto_done(q->ixp_q_crp);
  19157. + kmem_cache_free(qcache, q);
  19158. +}
  19159. +
  19160. +
  19161. +/*
  19162. + * registration is not callable at IRQ time, so we defer
  19163. + * to a task queue, this routines completes the registration for us
  19164. + * when the task queue runs
  19165. + *
  19166. + * Unfortunately this means we cannot tell OCF that the driver is blocked,
  19167. + * we do that on the next request.
  19168. + */
  19169. +
  19170. +static void
  19171. +ixp_registration(void *arg)
  19172. +{
  19173. + struct ixp_data *ixp = arg;
  19174. + struct ixp_q *q = NULL;
  19175. + IX_MBUF *pri = NULL, *sec = NULL;
  19176. + int status = IX_CRYPTO_ACC_STATUS_SUCCESS;
  19177. +
  19178. + if (!ixp) {
  19179. + printk("ixp: ixp_registration with no arg\n");
  19180. + return;
  19181. + }
  19182. +
  19183. + if (ixp->ixp_ctx_id != -1) {
  19184. + ixCryptoAccCtxUnregister(ixp->ixp_ctx_id);
  19185. + ixp->ixp_ctx_id = -1;
  19186. + }
  19187. +
  19188. + if (list_empty(&ixp->ixp_q)) {
  19189. + printk("ixp: ixp_registration with no Q\n");
  19190. + return;
  19191. + }
  19192. +
  19193. + /*
  19194. + * setup the primary and secondary buffers
  19195. + */
  19196. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  19197. + if (q->ixp_q_acrd) {
  19198. + pri = &ixp->ixp_pri_mbuf;
  19199. + sec = &ixp->ixp_sec_mbuf;
  19200. + IX_MBUF_MLEN(pri) = IX_MBUF_PKT_LEN(pri) = 128;
  19201. + IX_MBUF_MDATA(pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  19202. + IX_MBUF_MLEN(sec) = IX_MBUF_PKT_LEN(sec) = 128;
  19203. + IX_MBUF_MDATA(sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  19204. + }
  19205. +
  19206. + /* Only need to register if a crypt op or HMAC op */
  19207. + if (!(ixp->ixp_auth_alg == CRYPTO_SHA1 ||
  19208. + ixp->ixp_auth_alg == CRYPTO_MD5)) {
  19209. + status = ixCryptoAccCtxRegister(
  19210. + &ixp->ixp_ctx,
  19211. + pri, sec,
  19212. + ixp_register_cb,
  19213. + ixp_perform_cb,
  19214. + &ixp->ixp_ctx_id);
  19215. + }
  19216. + else {
  19217. + /* Otherwise we start processing pending q */
  19218. + schedule_work(&ixp->ixp_pending_work);
  19219. + }
  19220. +
  19221. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  19222. + return;
  19223. +
  19224. + if (IX_CRYPTO_ACC_STATUS_EXCEED_MAX_TUNNELS == status) {
  19225. + printk("ixp: ixCryptoAccCtxRegister failed (out of tunnels)\n");
  19226. + ixp_blocked = 1;
  19227. + /* perhaps we should return EGAIN on queued ops ? */
  19228. + return;
  19229. + }
  19230. +
  19231. + printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
  19232. + ixp->ixp_ctx_id = -1;
  19233. +
  19234. + /*
  19235. + * everything waiting is toasted
  19236. + */
  19237. + while (!list_empty(&ixp->ixp_q)) {
  19238. + q = list_entry(ixp->ixp_q.next, struct ixp_q, ixp_q_list);
  19239. + list_del(&q->ixp_q_list);
  19240. + q->ixp_q_crp->crp_etype = ENOENT;
  19241. + crypto_done(q->ixp_q_crp);
  19242. + kmem_cache_free(qcache, q);
  19243. + }
  19244. +}
  19245. +
  19246. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  19247. +static void
  19248. +ixp_registration_wq(struct work_struct *work)
  19249. +{
  19250. + struct ixp_data *ixp = container_of(work, struct ixp_data,
  19251. + ixp_registration_work);
  19252. + ixp_registration(ixp);
  19253. +}
  19254. +#endif
  19255. +
  19256. +/*
  19257. + * Process a request.
  19258. + */
  19259. +static int
  19260. +ixp_process(device_t dev, struct cryptop *crp, int hint)
  19261. +{
  19262. + struct ixp_data *ixp;
  19263. + unsigned int lid;
  19264. + struct ixp_q *q = NULL;
  19265. + int status;
  19266. +
  19267. + dprintk("%s()\n", __FUNCTION__);
  19268. +
  19269. + /* Sanity check */
  19270. + if (crp == NULL) {
  19271. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  19272. + return EINVAL;
  19273. + }
  19274. +
  19275. + crp->crp_etype = 0;
  19276. +
  19277. + if (ixp_blocked)
  19278. + return ERESTART;
  19279. +
  19280. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  19281. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  19282. + crp->crp_etype = EINVAL;
  19283. + goto done;
  19284. + }
  19285. +
  19286. + /*
  19287. + * find the session we are using
  19288. + */
  19289. +
  19290. + lid = crp->crp_sid & 0xffffffff;
  19291. + if (lid >= ixp_sesnum || lid == 0 || ixp_sessions == NULL ||
  19292. + ixp_sessions[lid] == NULL) {
  19293. + crp->crp_etype = ENOENT;
  19294. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  19295. + goto done;
  19296. + }
  19297. + ixp = ixp_sessions[lid];
  19298. +
  19299. + /*
  19300. + * setup a new request ready for queuing
  19301. + */
  19302. + q = kmem_cache_alloc(qcache, SLAB_ATOMIC);
  19303. + if (q == NULL) {
  19304. + dprintk("%s,%d: ENOMEM\n", __FILE__, __LINE__);
  19305. + crp->crp_etype = ENOMEM;
  19306. + goto done;
  19307. + }
  19308. + /*
  19309. + * save some cycles by only zeroing the important bits
  19310. + */
  19311. + memset(&q->ixp_q_mbuf, 0, sizeof(q->ixp_q_mbuf));
  19312. + q->ixp_q_ccrd = NULL;
  19313. + q->ixp_q_acrd = NULL;
  19314. + q->ixp_q_crp = crp;
  19315. + q->ixp_q_data = ixp;
  19316. +
  19317. + /*
  19318. + * point the cipher and auth descriptors appropriately
  19319. + * check that we have something to do
  19320. + */
  19321. + if (crp->crp_desc->crd_alg == ixp->ixp_cipher_alg)
  19322. + q->ixp_q_ccrd = crp->crp_desc;
  19323. + else if (crp->crp_desc->crd_alg == ixp->ixp_auth_alg)
  19324. + q->ixp_q_acrd = crp->crp_desc;
  19325. + else {
  19326. + crp->crp_etype = ENOENT;
  19327. + dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);
  19328. + goto done;
  19329. + }
  19330. + if (crp->crp_desc->crd_next) {
  19331. + if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_cipher_alg)
  19332. + q->ixp_q_ccrd = crp->crp_desc->crd_next;
  19333. + else if (crp->crp_desc->crd_next->crd_alg == ixp->ixp_auth_alg)
  19334. + q->ixp_q_acrd = crp->crp_desc->crd_next;
  19335. + else {
  19336. + crp->crp_etype = ENOENT;
  19337. + dprintk("%s,%d: bad desc match: ENOENT\n", __FILE__, __LINE__);
  19338. + goto done;
  19339. + }
  19340. + }
  19341. +
  19342. + /*
  19343. + * If there is a direction change for this context then we mark it as
  19344. + * unregistered and re-register is for the new direction. This is not
  19345. + * a very expensive operation and currently only tends to happen when
  19346. + * user-space application are doing benchmarks
  19347. + *
  19348. + * DM - we should be checking for pending requests before unregistering.
  19349. + */
  19350. + if (q->ixp_q_ccrd && ixp->ixp_registered &&
  19351. + ixp->ixp_crd_flags != (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT)) {
  19352. + dprintk("%s - detected direction change on session\n", __FUNCTION__);
  19353. + ixp->ixp_registered = 0;
  19354. + }
  19355. +
  19356. + /*
  19357. + * if we are registered, call straight into the perform code
  19358. + */
  19359. + if (ixp->ixp_registered) {
  19360. + ixp_q_process(q);
  19361. + return 0;
  19362. + }
  19363. +
  19364. + /*
  19365. + * the only part of the context not set in newsession is the direction
  19366. + * dependent parts
  19367. + */
  19368. + if (q->ixp_q_ccrd) {
  19369. + ixp->ixp_crd_flags = (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT);
  19370. + if (q->ixp_q_ccrd->crd_flags & CRD_F_ENCRYPT) {
  19371. + ixp->ixp_ctx.operation = q->ixp_q_acrd ?
  19372. + IX_CRYPTO_ACC_OP_ENCRYPT_AUTH : IX_CRYPTO_ACC_OP_ENCRYPT;
  19373. + } else {
  19374. + ixp->ixp_ctx.operation = q->ixp_q_acrd ?
  19375. + IX_CRYPTO_ACC_OP_AUTH_DECRYPT : IX_CRYPTO_ACC_OP_DECRYPT;
  19376. + }
  19377. + } else {
  19378. + /* q->ixp_q_acrd must be set if we are here */
  19379. + ixp->ixp_ctx.operation = IX_CRYPTO_ACC_OP_AUTH_CALC;
  19380. + }
  19381. +
  19382. + status = list_empty(&ixp->ixp_q);
  19383. + list_add_tail(&q->ixp_q_list, &ixp->ixp_q);
  19384. + if (status)
  19385. + schedule_work(&ixp->ixp_registration_work);
  19386. + return 0;
  19387. +
  19388. +done:
  19389. + if (q)
  19390. + kmem_cache_free(qcache, q);
  19391. + crypto_done(crp);
  19392. + return 0;
  19393. +}
  19394. +
  19395. +
  19396. +#ifdef __ixp46X
  19397. +/*
  19398. + * key processing support for the ixp465
  19399. + */
  19400. +
  19401. +
  19402. +/*
  19403. + * copy a BN (LE) into a buffer (BE) an fill out the op appropriately
  19404. + * assume zeroed and only copy bits that are significant
  19405. + */
  19406. +
  19407. +static int
  19408. +ixp_copy_ibuf(struct crparam *p, IxCryptoAccPkeEauOperand *op, UINT32 *buf)
  19409. +{
  19410. + unsigned char *src = (unsigned char *) p->crp_p;
  19411. + unsigned char *dst;
  19412. + int len, bits = p->crp_nbits;
  19413. +
  19414. + dprintk("%s()\n", __FUNCTION__);
  19415. +
  19416. + if (bits > MAX_IOP_SIZE * sizeof(UINT32) * 8) {
  19417. + dprintk("%s - ibuf too big (%d > %d)\n", __FUNCTION__,
  19418. + bits, MAX_IOP_SIZE * sizeof(UINT32) * 8);
  19419. + return -1;
  19420. + }
  19421. +
  19422. + len = (bits + 31) / 32; /* the number UINT32's needed */
  19423. +
  19424. + dst = (unsigned char *) &buf[len];
  19425. + dst--;
  19426. +
  19427. + while (bits > 0) {
  19428. + *dst-- = *src++;
  19429. + bits -= 8;
  19430. + }
  19431. +
  19432. +#if 0 /* no need to zero remaining bits as it is done during request alloc */
  19433. + while (dst > (unsigned char *) buf)
  19434. + *dst-- = '\0';
  19435. +#endif
  19436. +
  19437. + op->pData = buf;
  19438. + op->dataLen = len;
  19439. + return 0;
  19440. +}
  19441. +
  19442. +/*
  19443. + * copy out the result, be as forgiving as we can about small output buffers
  19444. + */
  19445. +
  19446. +static int
  19447. +ixp_copy_obuf(struct crparam *p, IxCryptoAccPkeEauOpResult *op, UINT32 *buf)
  19448. +{
  19449. + unsigned char *dst = (unsigned char *) p->crp_p;
  19450. + unsigned char *src = (unsigned char *) buf;
  19451. + int len, z, bits = p->crp_nbits;
  19452. +
  19453. + dprintk("%s()\n", __FUNCTION__);
  19454. +
  19455. + len = op->dataLen * sizeof(UINT32);
  19456. +
  19457. + /* skip leading zeroes to be small buffer friendly */
  19458. + z = 0;
  19459. + while (z < len && src[z] == '\0')
  19460. + z++;
  19461. +
  19462. + src += len;
  19463. + src--;
  19464. + len -= z;
  19465. +
  19466. + while (len > 0 && bits > 0) {
  19467. + *dst++ = *src--;
  19468. + len--;
  19469. + bits -= 8;
  19470. + }
  19471. +
  19472. + while (bits > 0) {
  19473. + *dst++ = '\0';
  19474. + bits -= 8;
  19475. + }
  19476. +
  19477. + if (len > 0) {
  19478. + dprintk("%s - obuf is %d (z=%d, ob=%d) bytes too small\n",
  19479. + __FUNCTION__, len, z, p->crp_nbits / 8);
  19480. + return -1;
  19481. + }
  19482. +
  19483. + return 0;
  19484. +}
  19485. +
  19486. +
  19487. +/*
  19488. + * the parameter offsets for exp_mod
  19489. + */
  19490. +
  19491. +#define IXP_PARAM_BASE 0
  19492. +#define IXP_PARAM_EXP 1
  19493. +#define IXP_PARAM_MOD 2
  19494. +#define IXP_PARAM_RES 3
  19495. +
  19496. +/*
  19497. + * key processing complete callback, is also used to start processing
  19498. + * by passing a NULL for pResult
  19499. + */
  19500. +
  19501. +static void
  19502. +ixp_kperform_cb(
  19503. + IxCryptoAccPkeEauOperation operation,
  19504. + IxCryptoAccPkeEauOpResult *pResult,
  19505. + BOOL carryOrBorrow,
  19506. + IxCryptoAccStatus status)
  19507. +{
  19508. + struct ixp_pkq *q, *tmp;
  19509. + unsigned long flags;
  19510. +
  19511. + dprintk("%s(0x%x, %p, %d, 0x%x)\n", __FUNCTION__, operation, pResult,
  19512. + carryOrBorrow, status);
  19513. +
  19514. + /* handle a completed request */
  19515. + if (pResult) {
  19516. + if (ixp_pk_cur && &ixp_pk_cur->pkq_result == pResult) {
  19517. + q = ixp_pk_cur;
  19518. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  19519. + dprintk("%s() - op failed 0x%x\n", __FUNCTION__, status);
  19520. + q->pkq_krp->krp_status = ERANGE; /* could do better */
  19521. + } else {
  19522. + /* copy out the result */
  19523. + if (ixp_copy_obuf(&q->pkq_krp->krp_param[IXP_PARAM_RES],
  19524. + &q->pkq_result, q->pkq_obuf))
  19525. + q->pkq_krp->krp_status = ERANGE;
  19526. + }
  19527. + crypto_kdone(q->pkq_krp);
  19528. + kfree(q);
  19529. + ixp_pk_cur = NULL;
  19530. + } else
  19531. + printk("%s - callback with invalid result pointer\n", __FUNCTION__);
  19532. + }
  19533. +
  19534. + spin_lock_irqsave(&ixp_pkq_lock, flags);
  19535. + if (ixp_pk_cur || list_empty(&ixp_pkq)) {
  19536. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  19537. + return;
  19538. + }
  19539. +
  19540. + list_for_each_entry_safe(q, tmp, &ixp_pkq, pkq_list) {
  19541. +
  19542. + list_del(&q->pkq_list);
  19543. + ixp_pk_cur = q;
  19544. +
  19545. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  19546. +
  19547. + status = ixCryptoAccPkeEauPerform(
  19548. + IX_CRYPTO_ACC_OP_EAU_MOD_EXP,
  19549. + &q->pkq_op,
  19550. + ixp_kperform_cb,
  19551. + &q->pkq_result);
  19552. +
  19553. + if (status == IX_CRYPTO_ACC_STATUS_SUCCESS) {
  19554. + dprintk("%s() - ixCryptoAccPkeEauPerform SUCCESS\n", __FUNCTION__);
  19555. + return; /* callback will return here for callback */
  19556. + } else if (status == IX_CRYPTO_ACC_STATUS_RETRY) {
  19557. + printk("%s() - ixCryptoAccPkeEauPerform RETRY\n", __FUNCTION__);
  19558. + } else {
  19559. + printk("%s() - ixCryptoAccPkeEauPerform failed %d\n",
  19560. + __FUNCTION__, status);
  19561. + }
  19562. + q->pkq_krp->krp_status = ERANGE; /* could do better */
  19563. + crypto_kdone(q->pkq_krp);
  19564. + kfree(q);
  19565. + spin_lock_irqsave(&ixp_pkq_lock, flags);
  19566. + }
  19567. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  19568. +}
  19569. +
  19570. +
  19571. +static int
  19572. +ixp_kprocess(device_t dev, struct cryptkop *krp, int hint)
  19573. +{
  19574. + struct ixp_pkq *q;
  19575. + int rc = 0;
  19576. + unsigned long flags;
  19577. +
  19578. + dprintk("%s l1=%d l2=%d l3=%d l4=%d\n", __FUNCTION__,
  19579. + krp->krp_param[IXP_PARAM_BASE].crp_nbits,
  19580. + krp->krp_param[IXP_PARAM_EXP].crp_nbits,
  19581. + krp->krp_param[IXP_PARAM_MOD].crp_nbits,
  19582. + krp->krp_param[IXP_PARAM_RES].crp_nbits);
  19583. +
  19584. +
  19585. + if (krp->krp_op != CRK_MOD_EXP) {
  19586. + krp->krp_status = EOPNOTSUPP;
  19587. + goto err;
  19588. + }
  19589. +
  19590. + q = (struct ixp_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);
  19591. + if (q == NULL) {
  19592. + krp->krp_status = ENOMEM;
  19593. + goto err;
  19594. + }
  19595. +
  19596. + /*
  19597. + * The PKE engine does not appear to zero the output buffer
  19598. + * appropriately, so we need to do it all here.
  19599. + */
  19600. + memset(q, 0, sizeof(*q));
  19601. +
  19602. + q->pkq_krp = krp;
  19603. + INIT_LIST_HEAD(&q->pkq_list);
  19604. +
  19605. + if (ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_BASE], &q->pkq_op.modExpOpr.M,
  19606. + q->pkq_ibuf0))
  19607. + rc = 1;
  19608. + if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_EXP],
  19609. + &q->pkq_op.modExpOpr.e, q->pkq_ibuf1))
  19610. + rc = 2;
  19611. + if (!rc && ixp_copy_ibuf(&krp->krp_param[IXP_PARAM_MOD],
  19612. + &q->pkq_op.modExpOpr.N, q->pkq_ibuf2))
  19613. + rc = 3;
  19614. +
  19615. + if (rc) {
  19616. + kfree(q);
  19617. + krp->krp_status = ERANGE;
  19618. + goto err;
  19619. + }
  19620. +
  19621. + q->pkq_result.pData = q->pkq_obuf;
  19622. + q->pkq_result.dataLen =
  19623. + (krp->krp_param[IXP_PARAM_RES].crp_nbits + 31) / 32;
  19624. +
  19625. + spin_lock_irqsave(&ixp_pkq_lock, flags);
  19626. + list_add_tail(&q->pkq_list, &ixp_pkq);
  19627. + spin_unlock_irqrestore(&ixp_pkq_lock, flags);
  19628. +
  19629. + if (!ixp_pk_cur)
  19630. + ixp_kperform_cb(0, NULL, 0, 0);
  19631. + return (0);
  19632. +
  19633. +err:
  19634. + crypto_kdone(krp);
  19635. + return (0);
  19636. +}
  19637. +
  19638. +
  19639. +
  19640. +#ifdef CONFIG_OCF_RANDOMHARVEST
  19641. +/*
  19642. + * We run the random number generator output through SHA so that it
  19643. + * is FIPS compliant.
  19644. + */
  19645. +
  19646. +static volatile int sha_done = 0;
  19647. +static unsigned char sha_digest[20];
  19648. +
  19649. +static void
  19650. +ixp_hash_cb(UINT8 *digest, IxCryptoAccStatus status)
  19651. +{
  19652. + dprintk("%s(%p, %d)\n", __FUNCTION__, digest, status);
  19653. + if (sha_digest != digest)
  19654. + printk("digest error\n");
  19655. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  19656. + sha_done = 1;
  19657. + else
  19658. + sha_done = -status;
  19659. +}
  19660. +
  19661. +static int
  19662. +ixp_read_random(void *arg, u_int32_t *buf, int maxwords)
  19663. +{
  19664. + IxCryptoAccStatus status;
  19665. + int i, n, rc;
  19666. +
  19667. + dprintk("%s(%p, %d)\n", __FUNCTION__, buf, maxwords);
  19668. + memset(buf, 0, maxwords * sizeof(*buf));
  19669. + status = ixCryptoAccPkePseudoRandomNumberGet(maxwords, buf);
  19670. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  19671. + dprintk("%s: ixCryptoAccPkePseudoRandomNumberGet failed %d\n",
  19672. + __FUNCTION__, status);
  19673. + return 0;
  19674. + }
  19675. +
  19676. + /*
  19677. + * run the random data through SHA to make it look more random
  19678. + */
  19679. +
  19680. + n = sizeof(sha_digest); /* process digest bytes at a time */
  19681. +
  19682. + rc = 0;
  19683. + for (i = 0; i < maxwords; i += n / sizeof(*buf)) {
  19684. + if ((maxwords - i) * sizeof(*buf) < n)
  19685. + n = (maxwords - i) * sizeof(*buf);
  19686. + sha_done = 0;
  19687. + status = ixCryptoAccPkeHashPerform(IX_CRYPTO_ACC_AUTH_SHA1,
  19688. + (UINT8 *) &buf[i], n, ixp_hash_cb, sha_digest);
  19689. + if (status != IX_CRYPTO_ACC_STATUS_SUCCESS) {
  19690. + dprintk("ixCryptoAccPkeHashPerform failed %d\n", status);
  19691. + return -EIO;
  19692. + }
  19693. + while (!sha_done)
  19694. + schedule();
  19695. + if (sha_done < 0) {
  19696. + dprintk("ixCryptoAccPkeHashPerform failed CB %d\n", -sha_done);
  19697. + return 0;
  19698. + }
  19699. + memcpy(&buf[i], sha_digest, n);
  19700. + rc += n / sizeof(*buf);;
  19701. + }
  19702. +
  19703. + return rc;
  19704. +}
  19705. +#endif /* CONFIG_OCF_RANDOMHARVEST */
  19706. +
  19707. +#endif /* __ixp46X */
  19708. +
  19709. +
  19710. +
  19711. +/*
  19712. + * our driver startup and shutdown routines
  19713. + */
  19714. +
  19715. +static int
  19716. +ixp_init(void)
  19717. +{
  19718. + dprintk("%s(%p)\n", __FUNCTION__, ixp_init);
  19719. +
  19720. + if (ixp_init_crypto && ixCryptoAccInit() != IX_CRYPTO_ACC_STATUS_SUCCESS)
  19721. + printk("ixCryptoAccInit failed, assuming already initialised!\n");
  19722. +
  19723. + qcache = kmem_cache_create("ixp4xx_q", sizeof(struct ixp_q), 0,
  19724. + SLAB_HWCACHE_ALIGN, NULL
  19725. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23)
  19726. + , NULL
  19727. +#endif
  19728. + );
  19729. + if (!qcache) {
  19730. + printk("failed to create Qcache\n");
  19731. + return -ENOENT;
  19732. + }
  19733. +
  19734. + memset(&ixpdev, 0, sizeof(ixpdev));
  19735. + softc_device_init(&ixpdev, "ixp4xx", 0, ixp_methods);
  19736. +
  19737. + ixp_id = crypto_get_driverid(softc_get_device(&ixpdev),
  19738. + CRYPTOCAP_F_HARDWARE);
  19739. + if (ixp_id < 0)
  19740. + panic("IXP/OCF crypto device cannot initialize!");
  19741. +
  19742. +#define REGISTER(alg) \
  19743. + crypto_register(ixp_id,alg,0,0)
  19744. +
  19745. + REGISTER(CRYPTO_DES_CBC);
  19746. + REGISTER(CRYPTO_3DES_CBC);
  19747. + REGISTER(CRYPTO_RIJNDAEL128_CBC);
  19748. +#ifdef CONFIG_OCF_IXP4XX_SHA1_MD5
  19749. + REGISTER(CRYPTO_MD5);
  19750. + REGISTER(CRYPTO_SHA1);
  19751. +#endif
  19752. + REGISTER(CRYPTO_MD5_HMAC);
  19753. + REGISTER(CRYPTO_SHA1_HMAC);
  19754. +#undef REGISTER
  19755. +
  19756. +#ifdef __ixp46X
  19757. + spin_lock_init(&ixp_pkq_lock);
  19758. + /*
  19759. + * we do not enable the go fast options here as they can potentially
  19760. + * allow timing based attacks
  19761. + *
  19762. + * http://www.openssl.org/news/secadv_20030219.txt
  19763. + */
  19764. + ixCryptoAccPkeEauExpConfig(0, 0);
  19765. + crypto_kregister(ixp_id, CRK_MOD_EXP, 0);
  19766. +#ifdef CONFIG_OCF_RANDOMHARVEST
  19767. + crypto_rregister(ixp_id, ixp_read_random, NULL);
  19768. +#endif
  19769. +#endif
  19770. +
  19771. + return 0;
  19772. +}
  19773. +
  19774. +static void
  19775. +ixp_exit(void)
  19776. +{
  19777. + dprintk("%s()\n", __FUNCTION__);
  19778. + crypto_unregister_all(ixp_id);
  19779. + ixp_id = -1;
  19780. + kmem_cache_destroy(qcache);
  19781. + qcache = NULL;
  19782. +}
  19783. +
  19784. +module_init(ixp_init);
  19785. +module_exit(ixp_exit);
  19786. +
  19787. +MODULE_LICENSE("Dual BSD/GPL");
  19788. +MODULE_AUTHOR("David McCullough <dmccullough@cyberguard.com>");
  19789. +MODULE_DESCRIPTION("ixp (OCF module for IXP4xx crypto)");
  19790. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/Makefile linux-2.6.39/crypto/ocf/kirkwood/Makefile
  19791. --- linux-2.6.39.orig/crypto/ocf/kirkwood/Makefile 1970-01-01 01:00:00.000000000 +0100
  19792. +++ linux-2.6.39/crypto/ocf/kirkwood/Makefile 2011-08-01 14:38:19.000000000 +0200
  19793. @@ -0,0 +1,19 @@
  19794. +# for SGlinux builds
  19795. +-include $(ROOTDIR)/modules/.config
  19796. +
  19797. +obj-$(CONFIG_OCF_KIRKWOOD) += mv_cesa.o
  19798. +
  19799. +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
  19800. +
  19801. +# Extra objects required by the CESA driver
  19802. +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
  19803. +
  19804. +ifdef src
  19805. +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)
  19806. +endif
  19807. +
  19808. +EXTRA_CFLAGS += -DMV_LINUX -DMV_CPU_LE -DMV_ARM -DMV_INCLUDE_CESA -DMV_INCLUDE_PEX -DMV_CACHE_COHERENCY=3
  19809. +ifdef TOPDIR
  19810. +-include $(TOPDIR)/Rules.make
  19811. +endif
  19812. +
  19813. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/AES/mvAes.h linux-2.6.39/crypto/ocf/kirkwood/cesa/AES/mvAes.h
  19814. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/AES/mvAes.h 1970-01-01 01:00:00.000000000 +0100
  19815. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/AES/mvAes.h 2011-08-01 14:38:18.000000000 +0200
  19816. @@ -0,0 +1,62 @@
  19817. +/* mvAes.h v2.0 August '99
  19818. + * Reference ANSI C code
  19819. + */
  19820. +
  19821. +/* AES Cipher header file for ANSI C Submissions
  19822. + Lawrence E. Bassham III
  19823. + Computer Security Division
  19824. + National Institute of Standards and Technology
  19825. +
  19826. + April 15, 1998
  19827. +
  19828. + This sample is to assist implementers developing to the Cryptographic
  19829. +API Profile for AES Candidate Algorithm Submissions. Please consult this
  19830. +document as a cross-reference.
  19831. +
  19832. + ANY CHANGES, WHERE APPROPRIATE, TO INFORMATION PROVIDED IN THIS FILE
  19833. +MUST BE DOCUMENTED. CHANGES ARE ONLY APPROPRIATE WHERE SPECIFIED WITH
  19834. +THE STRING "CHANGE POSSIBLE". FUNCTION CALLS AND THEIR PARAMETERS CANNOT
  19835. +BE CHANGED. STRUCTURES CAN BE ALTERED TO ALLOW IMPLEMENTERS TO INCLUDE
  19836. +IMPLEMENTATION SPECIFIC INFORMATION.
  19837. +*/
  19838. +
  19839. +/* Includes:
  19840. + Standard include files
  19841. +*/
  19842. +
  19843. +#include "mvOs.h"
  19844. +
  19845. +
  19846. +/* Error Codes - CHANGE POSSIBLE: inclusion of additional error codes */
  19847. +
  19848. +/* Key direction is invalid, e.g., unknown value */
  19849. +#define AES_BAD_KEY_DIR -1
  19850. +
  19851. +/* Key material not of correct length */
  19852. +#define AES_BAD_KEY_MAT -2
  19853. +
  19854. +/* Key passed is not valid */
  19855. +#define AES_BAD_KEY_INSTANCE -3
  19856. +
  19857. +/* Params struct passed to cipherInit invalid */
  19858. +#define AES_BAD_CIPHER_MODE -4
  19859. +
  19860. +/* Cipher in wrong state (e.g., not initialized) */
  19861. +#define AES_BAD_CIPHER_STATE -5
  19862. +
  19863. +#define AES_BAD_CIPHER_INSTANCE -7
  19864. +
  19865. +
  19866. +/* Function protoypes */
  19867. +/* CHANGED: makeKey(): parameter blockLen added
  19868. + this parameter is absolutely necessary if you want to
  19869. + setup the round keys in a variable block length setting
  19870. + cipherInit(): parameter blockLen added (for obvious reasons)
  19871. + */
  19872. +int aesMakeKey(MV_U8 *expandedKey, MV_U8 *keyMaterial, int keyLen, int blockLen);
  19873. +int aesBlockEncrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
  19874. + MV_U32 *plain, int numBlocks, MV_U32 *cipher);
  19875. +int aesBlockDecrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
  19876. + MV_U32 *plain, int numBlocks, MV_U32 *cipher);
  19877. +
  19878. +
  19879. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c linux-2.6.39/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c
  19880. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c 1970-01-01 01:00:00.000000000 +0100
  19881. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.c 2011-08-01 14:38:18.000000000 +0200
  19882. @@ -0,0 +1,317 @@
  19883. +/* rijndael-alg-ref.c v2.0 August '99
  19884. + * Reference ANSI C code
  19885. + * authors: Paulo Barreto
  19886. + * Vincent Rijmen, K.U.Leuven
  19887. + *
  19888. + * This code is placed in the public domain.
  19889. + */
  19890. +
  19891. +#include "mvOs.h"
  19892. +
  19893. +#include "mvAesAlg.h"
  19894. +
  19895. +#include "mvAesBoxes.dat"
  19896. +
  19897. +
  19898. +MV_U8 mul1(MV_U8 aa, MV_U8 bb);
  19899. +void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC);
  19900. +void ShiftRow128Enc(MV_U8 a[4][MAXBC]);
  19901. +void ShiftRow128Dec(MV_U8 a[4][MAXBC]);
  19902. +void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]);
  19903. +void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]);
  19904. +void InvMixColumn(MV_U8 a[4][MAXBC]);
  19905. +
  19906. +
  19907. +#define mul(aa, bb) (mask[bb] & Alogtable[aa + Logtable[bb]])
  19908. +
  19909. +MV_U8 mul1(MV_U8 aa, MV_U8 bb)
  19910. +{
  19911. + return mask[bb] & Alogtable[aa + Logtable[bb]];
  19912. +}
  19913. +
  19914. +
  19915. +void KeyAddition(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC], MV_U8 BC)
  19916. +{
  19917. + /* Exor corresponding text input and round key input bytes
  19918. + */
  19919. + ((MV_U32*)(&(a[0][0])))[0] ^= ((MV_U32*)(&(rk[0][0])))[0];
  19920. + ((MV_U32*)(&(a[1][0])))[0] ^= ((MV_U32*)(&(rk[1][0])))[0];
  19921. + ((MV_U32*)(&(a[2][0])))[0] ^= ((MV_U32*)(&(rk[2][0])))[0];
  19922. + ((MV_U32*)(&(a[3][0])))[0] ^= ((MV_U32*)(&(rk[3][0])))[0];
  19923. +
  19924. +}
  19925. +
  19926. +void ShiftRow128Enc(MV_U8 a[4][MAXBC]) {
  19927. + /* Row 0 remains unchanged
  19928. + * The other three rows are shifted a variable amount
  19929. + */
  19930. + MV_U8 tmp[MAXBC];
  19931. +
  19932. + tmp[0] = a[1][1];
  19933. + tmp[1] = a[1][2];
  19934. + tmp[2] = a[1][3];
  19935. + tmp[3] = a[1][0];
  19936. +
  19937. + ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  19938. + /*
  19939. + a[1][0] = tmp[0];
  19940. + a[1][1] = tmp[1];
  19941. + a[1][2] = tmp[2];
  19942. + a[1][3] = tmp[3];
  19943. + */
  19944. + tmp[0] = a[2][2];
  19945. + tmp[1] = a[2][3];
  19946. + tmp[2] = a[2][0];
  19947. + tmp[3] = a[2][1];
  19948. +
  19949. + ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  19950. + /*
  19951. + a[2][0] = tmp[0];
  19952. + a[2][1] = tmp[1];
  19953. + a[2][2] = tmp[2];
  19954. + a[2][3] = tmp[3];
  19955. + */
  19956. + tmp[0] = a[3][3];
  19957. + tmp[1] = a[3][0];
  19958. + tmp[2] = a[3][1];
  19959. + tmp[3] = a[3][2];
  19960. +
  19961. + ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  19962. + /*
  19963. + a[3][0] = tmp[0];
  19964. + a[3][1] = tmp[1];
  19965. + a[3][2] = tmp[2];
  19966. + a[3][3] = tmp[3];
  19967. + */
  19968. +}
  19969. +
  19970. +void ShiftRow128Dec(MV_U8 a[4][MAXBC]) {
  19971. + /* Row 0 remains unchanged
  19972. + * The other three rows are shifted a variable amount
  19973. + */
  19974. + MV_U8 tmp[MAXBC];
  19975. +
  19976. + tmp[0] = a[1][3];
  19977. + tmp[1] = a[1][0];
  19978. + tmp[2] = a[1][1];
  19979. + tmp[3] = a[1][2];
  19980. +
  19981. + ((MV_U32*)(&(a[1][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  19982. + /*
  19983. + a[1][0] = tmp[0];
  19984. + a[1][1] = tmp[1];
  19985. + a[1][2] = tmp[2];
  19986. + a[1][3] = tmp[3];
  19987. + */
  19988. +
  19989. + tmp[0] = a[2][2];
  19990. + tmp[1] = a[2][3];
  19991. + tmp[2] = a[2][0];
  19992. + tmp[3] = a[2][1];
  19993. +
  19994. + ((MV_U32*)(&(a[2][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  19995. + /*
  19996. + a[2][0] = tmp[0];
  19997. + a[2][1] = tmp[1];
  19998. + a[2][2] = tmp[2];
  19999. + a[2][3] = tmp[3];
  20000. + */
  20001. +
  20002. + tmp[0] = a[3][1];
  20003. + tmp[1] = a[3][2];
  20004. + tmp[2] = a[3][3];
  20005. + tmp[3] = a[3][0];
  20006. +
  20007. + ((MV_U32*)(&(a[3][0])))[0] = ((MV_U32*)(&(tmp[0])))[0];
  20008. + /*
  20009. + a[3][0] = tmp[0];
  20010. + a[3][1] = tmp[1];
  20011. + a[3][2] = tmp[2];
  20012. + a[3][3] = tmp[3];
  20013. + */
  20014. +}
  20015. +
  20016. +void Substitution(MV_U8 a[4][MAXBC], MV_U8 box[256]) {
  20017. + /* Replace every byte of the input by the byte at that place
  20018. + * in the nonlinear S-box
  20019. + */
  20020. + int i, j;
  20021. +
  20022. + for(i = 0; i < 4; i++)
  20023. + for(j = 0; j < 4; j++) a[i][j] = box[a[i][j]] ;
  20024. +}
  20025. +
  20026. +void MixColumn(MV_U8 a[4][MAXBC], MV_U8 rk[4][MAXBC]) {
  20027. + /* Mix the four bytes of every column in a linear way
  20028. + */
  20029. + MV_U8 b[4][MAXBC];
  20030. + int i, j;
  20031. +
  20032. + for(j = 0; j < 4; j++){
  20033. + b[0][j] = mul(25,a[0][j]) ^ mul(1,a[1][j]) ^ a[2][j] ^ a[3][j];
  20034. + b[1][j] = mul(25,a[1][j]) ^ mul(1,a[2][j]) ^ a[3][j] ^ a[0][j];
  20035. + b[2][j] = mul(25,a[2][j]) ^ mul(1,a[3][j]) ^ a[0][j] ^ a[1][j];
  20036. + b[3][j] = mul(25,a[3][j]) ^ mul(1,a[0][j]) ^ a[1][j] ^ a[2][j];
  20037. + }
  20038. + for(i = 0; i < 4; i++)
  20039. + /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/
  20040. + ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0] ^ ((MV_U32*)(&(rk[i][0])))[0];;
  20041. +}
  20042. +
  20043. +void InvMixColumn(MV_U8 a[4][MAXBC]) {
  20044. + /* Mix the four bytes of every column in a linear way
  20045. + * This is the opposite operation of Mixcolumn
  20046. + */
  20047. + MV_U8 b[4][MAXBC];
  20048. + int i, j;
  20049. +
  20050. + for(j = 0; j < 4; j++){
  20051. + b[0][j] = mul(223,a[0][j]) ^ mul(104,a[1][j]) ^ mul(238,a[2][j]) ^ mul(199,a[3][j]);
  20052. + b[1][j] = mul(223,a[1][j]) ^ mul(104,a[2][j]) ^ mul(238,a[3][j]) ^ mul(199,a[0][j]);
  20053. + b[2][j] = mul(223,a[2][j]) ^ mul(104,a[3][j]) ^ mul(238,a[0][j]) ^ mul(199,a[1][j]);
  20054. + b[3][j] = mul(223,a[3][j]) ^ mul(104,a[0][j]) ^ mul(238,a[1][j]) ^ mul(199,a[2][j]);
  20055. + }
  20056. + for(i = 0; i < 4; i++)
  20057. + /*for(j = 0; j < BC; j++) a[i][j] = b[i][j];*/
  20058. + ((MV_U32*)(&(a[i][0])))[0] = ((MV_U32*)(&(b[i][0])))[0];
  20059. +}
  20060. +
  20061. +int rijndaelKeySched (MV_U8 k[4][MAXKC], int keyBits, int blockBits, MV_U8 W[MAXROUNDS+1][4][MAXBC])
  20062. +{
  20063. + /* Calculate the necessary round keys
  20064. + * The number of calculations depends on keyBits and blockBits
  20065. + */
  20066. + int KC, BC, ROUNDS;
  20067. + int i, j, t, rconpointer = 0;
  20068. + MV_U8 tk[4][MAXKC];
  20069. +
  20070. + switch (keyBits) {
  20071. + case 128: KC = 4; break;
  20072. + case 192: KC = 6; break;
  20073. + case 256: KC = 8; break;
  20074. + default : return (-1);
  20075. + }
  20076. +
  20077. + switch (blockBits) {
  20078. + case 128: BC = 4; break;
  20079. + case 192: BC = 6; break;
  20080. + case 256: BC = 8; break;
  20081. + default : return (-2);
  20082. + }
  20083. +
  20084. + switch (keyBits >= blockBits ? keyBits : blockBits) {
  20085. + case 128: ROUNDS = 10; break;
  20086. + case 192: ROUNDS = 12; break;
  20087. + case 256: ROUNDS = 14; break;
  20088. + default : return (-3); /* this cannot happen */
  20089. + }
  20090. +
  20091. +
  20092. + for(j = 0; j < KC; j++)
  20093. + for(i = 0; i < 4; i++)
  20094. + tk[i][j] = k[i][j];
  20095. + t = 0;
  20096. + /* copy values into round key array */
  20097. + for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
  20098. + for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
  20099. +
  20100. + while (t < (ROUNDS+1)*BC) { /* while not enough round key material calculated */
  20101. + /* calculate new values */
  20102. + for(i = 0; i < 4; i++)
  20103. + tk[i][0] ^= S[tk[(i+1)%4][KC-1]];
  20104. + tk[0][0] ^= rcon[rconpointer++];
  20105. +
  20106. + if (KC != 8)
  20107. + for(j = 1; j < KC; j++)
  20108. + for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
  20109. + else {
  20110. + for(j = 1; j < KC/2; j++)
  20111. + for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
  20112. + for(i = 0; i < 4; i++) tk[i][KC/2] ^= S[tk[i][KC/2 - 1]];
  20113. + for(j = KC/2 + 1; j < KC; j++)
  20114. + for(i = 0; i < 4; i++) tk[i][j] ^= tk[i][j-1];
  20115. + }
  20116. + /* copy values into round key array */
  20117. + for(j = 0; (j < KC) && (t < (ROUNDS+1)*BC); j++, t++)
  20118. + for(i = 0; i < 4; i++) W[t / BC][i][t % BC] = tk[i][j];
  20119. + }
  20120. +
  20121. + return 0;
  20122. +}
  20123. +
  20124. +
  20125. +
  20126. +int rijndaelEncrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
  20127. +{
  20128. + /* Encryption of one block.
  20129. + */
  20130. + int r, BC, ROUNDS;
  20131. +
  20132. + BC = 4;
  20133. + ROUNDS = rounds;
  20134. +
  20135. + /* begin with a key addition
  20136. + */
  20137. +
  20138. + KeyAddition(a,rk[0],BC);
  20139. +
  20140. + /* ROUNDS-1 ordinary rounds
  20141. + */
  20142. + for(r = 1; r < ROUNDS; r++) {
  20143. + Substitution(a,S);
  20144. + ShiftRow128Enc(a);
  20145. + MixColumn(a, rk[r]);
  20146. + /*KeyAddition(a,rk[r],BC);*/
  20147. + }
  20148. +
  20149. + /* Last round is special: there is no MixColumn
  20150. + */
  20151. + Substitution(a,S);
  20152. + ShiftRow128Enc(a);
  20153. + KeyAddition(a,rk[ROUNDS],BC);
  20154. +
  20155. + return 0;
  20156. +}
  20157. +
  20158. +
  20159. +int rijndaelDecrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds)
  20160. +{
  20161. + int r, BC, ROUNDS;
  20162. +
  20163. + BC = 4;
  20164. + ROUNDS = rounds;
  20165. +
  20166. + /* To decrypt: apply the inverse operations of the encrypt routine,
  20167. + * in opposite order
  20168. + *
  20169. + * (KeyAddition is an involution: it 's equal to its inverse)
  20170. + * (the inverse of Substitution with table S is Substitution with the inverse table of S)
  20171. + * (the inverse of Shiftrow is Shiftrow over a suitable distance)
  20172. + */
  20173. +
  20174. + /* First the special round:
  20175. + * without InvMixColumn
  20176. + * with extra KeyAddition
  20177. + */
  20178. + KeyAddition(a,rk[ROUNDS],BC);
  20179. + ShiftRow128Dec(a);
  20180. + Substitution(a,Si);
  20181. +
  20182. + /* ROUNDS-1 ordinary rounds
  20183. + */
  20184. + for(r = ROUNDS-1; r > 0; r--) {
  20185. + KeyAddition(a,rk[r],BC);
  20186. + InvMixColumn(a);
  20187. + ShiftRow128Dec(a);
  20188. + Substitution(a,Si);
  20189. +
  20190. + }
  20191. +
  20192. + /* End with the extra key addition
  20193. + */
  20194. +
  20195. + KeyAddition(a,rk[0],BC);
  20196. +
  20197. + return 0;
  20198. +}
  20199. +
  20200. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h linux-2.6.39/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h
  20201. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h 1970-01-01 01:00:00.000000000 +0100
  20202. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/AES/mvAesAlg.h 2011-08-01 14:38:18.000000000 +0200
  20203. @@ -0,0 +1,19 @@
  20204. +/* rijndael-alg-ref.h v2.0 August '99
  20205. + * Reference ANSI C code
  20206. + * authors: Paulo Barreto
  20207. + * Vincent Rijmen, K.U.Leuven
  20208. + */
  20209. +#ifndef __RIJNDAEL_ALG_H
  20210. +#define __RIJNDAEL_ALG_H
  20211. +
  20212. +#define MAXBC (128/32)
  20213. +#define MAXKC (256/32)
  20214. +#define MAXROUNDS 14
  20215. +
  20216. +
  20217. +int rijndaelKeySched (MV_U8 k[4][MAXKC], int keyBits, int blockBits, MV_U8 rk[MAXROUNDS+1][4][MAXBC]);
  20218. +
  20219. +int rijndaelEncrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds);
  20220. +int rijndaelDecrypt128(MV_U8 a[4][MAXBC], MV_U8 rk[MAXROUNDS+1][4][MAXBC], int rounds);
  20221. +
  20222. +#endif /* __RIJNDAEL_ALG_H */
  20223. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c linux-2.6.39/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c
  20224. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c 1970-01-01 01:00:00.000000000 +0100
  20225. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/AES/mvAesApi.c 2011-08-01 14:38:18.000000000 +0200
  20226. @@ -0,0 +1,312 @@
  20227. +/* rijndael-api-ref.c v2.1 April 2000
  20228. + * Reference ANSI C code
  20229. + * authors: v2.0 Paulo Barreto
  20230. + * Vincent Rijmen, K.U.Leuven
  20231. + * v2.1 Vincent Rijmen, K.U.Leuven
  20232. + *
  20233. + * This code is placed in the public domain.
  20234. + */
  20235. +#include "mvOs.h"
  20236. +
  20237. +#include "mvAes.h"
  20238. +#include "mvAesAlg.h"
  20239. +
  20240. +
  20241. +/* Defines:
  20242. + Add any additional defines you need
  20243. +*/
  20244. +
  20245. +#define MODE_ECB 1 /* Are we ciphering in ECB mode? */
  20246. +#define MODE_CBC 2 /* Are we ciphering in CBC mode? */
  20247. +#define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */
  20248. +
  20249. +
  20250. +int aesMakeKey(MV_U8 *expandedKey, MV_U8 *keyMaterial, int keyLen, int blockLen)
  20251. +{
  20252. + MV_U8 W[MAXROUNDS+1][4][MAXBC];
  20253. + MV_U8 k[4][MAXKC];
  20254. + MV_U8 j;
  20255. + int i, rounds, KC;
  20256. +
  20257. + if (expandedKey == NULL)
  20258. + {
  20259. + return AES_BAD_KEY_INSTANCE;
  20260. + }
  20261. +
  20262. + if (!((keyLen == 128) || (keyLen == 192) || (keyLen == 256)))
  20263. + {
  20264. + return AES_BAD_KEY_MAT;
  20265. + }
  20266. +
  20267. + if (keyMaterial == NULL)
  20268. + {
  20269. + return AES_BAD_KEY_MAT;
  20270. + }
  20271. +
  20272. + /* initialize key schedule: */
  20273. + for(i=0; i<keyLen/8; i++)
  20274. + {
  20275. + j = keyMaterial[i];
  20276. + k[i % 4][i / 4] = j;
  20277. + }
  20278. +
  20279. + rijndaelKeySched (k, keyLen, blockLen, W);
  20280. +#ifdef MV_AES_DEBUG
  20281. + {
  20282. + MV_U8* pW = &W[0][0][0];
  20283. + int x;
  20284. +
  20285. + mvOsPrintf("Expended Key: size = %d\n", sizeof(W));
  20286. + for(i=0; i<sizeof(W); i++)
  20287. + {
  20288. + mvOsPrintf("%02x ", pW[i]);
  20289. + }
  20290. + for(i=0; i<MAXROUNDS+1; i++)
  20291. + {
  20292. + mvOsPrintf("\n Round #%02d: ", i);
  20293. + for(x=0; x<MAXBC; x++)
  20294. + {
  20295. + mvOsPrintf("%02x%02x%02x%02x ",
  20296. + W[i][0][x], W[i][1][x], W[i][2][x], W[i][3][x]);
  20297. + }
  20298. + mvOsPrintf("\n");
  20299. + }
  20300. + }
  20301. +#endif /* MV_AES_DEBUG */
  20302. + switch (keyLen)
  20303. + {
  20304. + case 128:
  20305. + rounds = 10;
  20306. + KC = 4;
  20307. + break;
  20308. + case 192:
  20309. + rounds = 12;
  20310. + KC = 6;
  20311. + break;
  20312. + case 256:
  20313. + rounds = 14;
  20314. + KC = 8;
  20315. + break;
  20316. + default :
  20317. + return (-1);
  20318. + }
  20319. +
  20320. + for(i=0; i<MAXBC; i++)
  20321. + {
  20322. + for(j=0; j<4; j++)
  20323. + {
  20324. + expandedKey[i*4+j] = W[rounds][j][i];
  20325. + }
  20326. + }
  20327. + for(; i<KC; i++)
  20328. + {
  20329. + for(j=0; j<4; j++)
  20330. + {
  20331. + expandedKey[i*4+j] = W[rounds-1][j][i+MAXBC-KC];
  20332. + }
  20333. + }
  20334. +
  20335. +
  20336. + return 0;
  20337. +}
  20338. +
  20339. +int aesBlockEncrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
  20340. + MV_U32 *plain, int numBlocks, MV_U32 *cipher)
  20341. +{
  20342. + int i, j, t;
  20343. + MV_U8 block[4][MAXBC];
  20344. + int rounds;
  20345. + char *input, *outBuffer;
  20346. +
  20347. + input = (char*)plain;
  20348. + outBuffer = (char*)cipher;
  20349. +
  20350. + /* check parameter consistency: */
  20351. + if( (expandedKey == NULL) || ((keyLen != 128) && (keyLen != 192) && (keyLen != 256)))
  20352. + {
  20353. + return AES_BAD_KEY_MAT;
  20354. + }
  20355. + if ((mode != MODE_ECB && mode != MODE_CBC))
  20356. + {
  20357. + return AES_BAD_CIPHER_STATE;
  20358. + }
  20359. +
  20360. + switch (keyLen)
  20361. + {
  20362. + case 128: rounds = 10; break;
  20363. + case 192: rounds = 12; break;
  20364. + case 256: rounds = 14; break;
  20365. + default : return (-3); /* this cannot happen */
  20366. + }
  20367. +
  20368. +
  20369. + switch (mode)
  20370. + {
  20371. + case MODE_ECB:
  20372. + for (i = 0; i < numBlocks; i++)
  20373. + {
  20374. + for (j = 0; j < 4; j++)
  20375. + {
  20376. + for(t = 0; t < 4; t++)
  20377. + /* parse input stream into rectangular array */
  20378. + block[t][j] = input[16*i+4*j+t] & 0xFF;
  20379. + }
  20380. + rijndaelEncrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  20381. + for (j = 0; j < 4; j++)
  20382. + {
  20383. + /* parse rectangular array into output ciphertext bytes */
  20384. + for(t = 0; t < 4; t++)
  20385. + outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];
  20386. +
  20387. + }
  20388. + }
  20389. + break;
  20390. +
  20391. + case MODE_CBC:
  20392. + for (j = 0; j < 4; j++)
  20393. + {
  20394. + for(t = 0; t < 4; t++)
  20395. + /* parse initial value into rectangular array */
  20396. + block[t][j] = IV[t+4*j] & 0xFF;
  20397. + }
  20398. + for (i = 0; i < numBlocks; i++)
  20399. + {
  20400. + for (j = 0; j < 4; j++)
  20401. + {
  20402. + for(t = 0; t < 4; t++)
  20403. + /* parse input stream into rectangular array and exor with
  20404. + IV or the previous ciphertext */
  20405. + block[t][j] ^= input[16*i+4*j+t] & 0xFF;
  20406. + }
  20407. + rijndaelEncrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  20408. + for (j = 0; j < 4; j++)
  20409. + {
  20410. + /* parse rectangular array into output ciphertext bytes */
  20411. + for(t = 0; t < 4; t++)
  20412. + outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];
  20413. + }
  20414. + }
  20415. + break;
  20416. +
  20417. + default: return AES_BAD_CIPHER_STATE;
  20418. + }
  20419. +
  20420. + return 0;
  20421. +}
  20422. +
  20423. +int aesBlockDecrypt128(MV_U8 mode, MV_U8 *IV, MV_U8 *expandedKey, int keyLen,
  20424. + MV_U32 *srcData, int numBlocks, MV_U32 *dstData)
  20425. +{
  20426. + int i, j, t;
  20427. + MV_U8 block[4][MAXBC];
  20428. + MV_U8 iv[4][MAXBC];
  20429. + int rounds;
  20430. + char *input, *outBuffer;
  20431. +
  20432. + input = (char*)srcData;
  20433. + outBuffer = (char*)dstData;
  20434. +
  20435. + if (expandedKey == NULL)
  20436. + {
  20437. + return AES_BAD_KEY_MAT;
  20438. + }
  20439. +
  20440. + /* check parameter consistency: */
  20441. + if (keyLen != 128 && keyLen != 192 && keyLen != 256)
  20442. + {
  20443. + return AES_BAD_KEY_MAT;
  20444. + }
  20445. + if ((mode != MODE_ECB && mode != MODE_CBC))
  20446. + {
  20447. + return AES_BAD_CIPHER_STATE;
  20448. + }
  20449. +
  20450. + switch (keyLen)
  20451. + {
  20452. + case 128: rounds = 10; break;
  20453. + case 192: rounds = 12; break;
  20454. + case 256: rounds = 14; break;
  20455. + default : return (-3); /* this cannot happen */
  20456. + }
  20457. +
  20458. +
  20459. + switch (mode)
  20460. + {
  20461. + case MODE_ECB:
  20462. + for (i = 0; i < numBlocks; i++)
  20463. + {
  20464. + for (j = 0; j < 4; j++)
  20465. + {
  20466. + for(t = 0; t < 4; t++)
  20467. + {
  20468. + /* parse input stream into rectangular array */
  20469. + block[t][j] = input[16*i+4*j+t] & 0xFF;
  20470. + }
  20471. + }
  20472. + rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  20473. + for (j = 0; j < 4; j++)
  20474. + {
  20475. + /* parse rectangular array into output ciphertext bytes */
  20476. + for(t = 0; t < 4; t++)
  20477. + outBuffer[16*i+4*j+t] = (MV_U8) block[t][j];
  20478. + }
  20479. + }
  20480. + break;
  20481. +
  20482. + case MODE_CBC:
  20483. + /* first block */
  20484. + for (j = 0; j < 4; j++)
  20485. + {
  20486. + for(t = 0; t < 4; t++)
  20487. + {
  20488. + /* parse input stream into rectangular array */
  20489. + block[t][j] = input[4*j+t] & 0xFF;
  20490. + iv[t][j] = block[t][j];
  20491. + }
  20492. + }
  20493. + rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  20494. +
  20495. + for (j = 0; j < 4; j++)
  20496. + {
  20497. + /* exor the IV and parse rectangular array into output ciphertext bytes */
  20498. + for(t = 0; t < 4; t++)
  20499. + {
  20500. + outBuffer[4*j+t] = (MV_U8) (block[t][j] ^ IV[t+4*j]);
  20501. + IV[t+4*j] = iv[t][j];
  20502. + }
  20503. + }
  20504. +
  20505. + /* next blocks */
  20506. + for (i = 1; i < numBlocks; i++)
  20507. + {
  20508. + for (j = 0; j < 4; j++)
  20509. + {
  20510. + for(t = 0; t < 4; t++)
  20511. + {
  20512. + /* parse input stream into rectangular array */
  20513. + iv[t][j] = input[16*i+4*j+t] & 0xFF;
  20514. + block[t][j] = iv[t][j];
  20515. + }
  20516. + }
  20517. + rijndaelDecrypt128(block, (MV_U8 (*)[4][MAXBC])expandedKey, rounds);
  20518. +
  20519. + for (j = 0; j < 4; j++)
  20520. + {
  20521. + /* exor previous ciphertext block and parse rectangular array
  20522. + into output ciphertext bytes */
  20523. + for(t = 0; t < 4; t++)
  20524. + {
  20525. + outBuffer[16*i+4*j+t] = (MV_U8) (block[t][j] ^ IV[t+4*j]);
  20526. + IV[t+4*j] = iv[t][j];
  20527. + }
  20528. + }
  20529. + }
  20530. + break;
  20531. +
  20532. + default: return AES_BAD_CIPHER_STATE;
  20533. + }
  20534. +
  20535. + return 0;
  20536. +}
  20537. +
  20538. +
  20539. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesa.c linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesa.c
  20540. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesa.c 1970-01-01 01:00:00.000000000 +0100
  20541. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesa.c 2011-08-01 14:38:18.000000000 +0200
  20542. @@ -0,0 +1,3126 @@
  20543. +/*******************************************************************************
  20544. +Copyright (C) Marvell International Ltd. and its affiliates
  20545. +
  20546. +This software file (the "File") is owned and distributed by Marvell
  20547. +International Ltd. and/or its affiliates ("Marvell") under the following
  20548. +alternative licensing terms. Once you have made an election to distribute the
  20549. +File under one of the following license alternatives, please (i) delete this
  20550. +introductory statement regarding license alternatives, (ii) delete the two
  20551. +license alternatives that you have not elected to use and (iii) preserve the
  20552. +Marvell copyright notice above.
  20553. +
  20554. +********************************************************************************
  20555. +Marvell Commercial License Option
  20556. +
  20557. +If you received this File from Marvell and you have entered into a commercial
  20558. +license agreement (a "Commercial License") with Marvell, the File is licensed
  20559. +to you under the terms of the applicable Commercial License.
  20560. +
  20561. +********************************************************************************
  20562. +Marvell GPL License Option
  20563. +
  20564. +If you received this File from Marvell, you may opt to use, redistribute and/or
  20565. +modify this File in accordance with the terms and conditions of the General
  20566. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  20567. +available along with the File in the license.txt file or by writing to the Free
  20568. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  20569. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  20570. +
  20571. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  20572. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  20573. +DISCLAIMED. The GPL License provides additional details about this warranty
  20574. +disclaimer.
  20575. +********************************************************************************
  20576. +Marvell BSD License Option
  20577. +
  20578. +If you received this File from Marvell, you may opt to use, redistribute and/or
  20579. +modify this File under the following licensing terms.
  20580. +Redistribution and use in source and binary forms, with or without modification,
  20581. +are permitted provided that the following conditions are met:
  20582. +
  20583. + * Redistributions of source code must retain the above copyright notice,
  20584. + this list of conditions and the following disclaimer.
  20585. +
  20586. + * Redistributions in binary form must reproduce the above copyright
  20587. + notice, this list of conditions and the following disclaimer in the
  20588. + documentation and/or other materials provided with the distribution.
  20589. +
  20590. + * Neither the name of Marvell nor the names of its contributors may be
  20591. + used to endorse or promote products derived from this software without
  20592. + specific prior written permission.
  20593. +
  20594. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  20595. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20596. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20597. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  20598. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  20599. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  20600. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  20601. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  20602. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  20603. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  20604. +
  20605. +*******************************************************************************/
  20606. +
  20607. +#include "cesa/mvCesa.h"
  20608. +
  20609. +#include "ctrlEnv/mvCtrlEnvLib.h"
  20610. +#undef CESA_DEBUG
  20611. +
  20612. +
  20613. +/********** Global variables **********/
  20614. +
  20615. +/* If request size is more than MV_CESA_MAX_BUF_SIZE the
  20616. + * request is processed as fragmented request.
  20617. + */
  20618. +
  20619. +MV_CESA_STATS cesaStats;
  20620. +
  20621. +MV_BUF_INFO cesaSramSaBuf;
  20622. +short cesaLastSid = -1;
  20623. +MV_CESA_SA* pCesaSAD = NULL;
  20624. +MV_U16 cesaMaxSA = 0;
  20625. +
  20626. +MV_CESA_REQ* pCesaReqFirst = NULL;
  20627. +MV_CESA_REQ* pCesaReqLast = NULL;
  20628. +MV_CESA_REQ* pCesaReqEmpty = NULL;
  20629. +MV_CESA_REQ* pCesaReqProcess = NULL;
  20630. +int cesaQueueDepth = 0;
  20631. +int cesaReqResources = 0;
  20632. +
  20633. +MV_CESA_SRAM_MAP* cesaSramVirtPtr = NULL;
  20634. +MV_U32 cesaCryptEngBase = 0;
  20635. +void *cesaOsHandle = NULL;
  20636. +#if (MV_CESA_VERSION >= 3)
  20637. +MV_U32 cesaChainLength = 0;
  20638. +int chainReqNum = 0;
  20639. +MV_U32 chainIndex = 0;
  20640. +MV_CESA_REQ* pNextActiveChain = 0;
  20641. +MV_CESA_REQ* pEndCurrChain = 0;
  20642. +MV_BOOL isFirstReq = MV_TRUE;
  20643. +#endif
  20644. +
  20645. +static INLINE MV_U8* mvCesaSramAddrGet(void)
  20646. +{
  20647. +#ifdef MV_CESA_NO_SRAM
  20648. + return (MV_U8*)cesaSramVirtPtr;
  20649. +#else
  20650. + return (MV_U8*)cesaCryptEngBase;
  20651. +#endif /* MV_CESA_NO_SRAM */
  20652. +}
  20653. +
  20654. +static INLINE MV_ULONG mvCesaSramVirtToPhys(void* pDev, MV_U8* pSramVirt)
  20655. +{
  20656. +#ifdef MV_CESA_NO_SRAM
  20657. + return (MV_ULONG)mvOsIoVirtToPhy(NULL, pSramVirt);
  20658. +#else
  20659. + return (MV_ULONG)pSramVirt;
  20660. +#endif /* MV_CESA_NO_SRAM */
  20661. +}
  20662. +
  20663. +/* Internal Function prototypes */
  20664. +
  20665. +static INLINE void mvCesaSramDescrBuild(MV_U32 config, int frag,
  20666. + int cryptoOffset, int ivOffset, int cryptoLength,
  20667. + int macOffset, int digestOffset, int macLength, int macTotalLen,
  20668. + MV_CESA_REQ *pCesaReq, MV_DMA_DESC* pDmaDesc);
  20669. +
  20670. +static INLINE void mvCesaSramSaUpdate(short sid, MV_DMA_DESC *pDmaDesc);
  20671. +
  20672. +static INLINE int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,
  20673. + MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,
  20674. + int offset, int copySize, MV_BOOL skipFlush);
  20675. +
  20676. +static void mvCesaHmacIvGet(MV_CESA_MAC_MODE macMode, unsigned char key[], int keyLength,
  20677. + unsigned char innerIV[], unsigned char outerIV[]);
  20678. +
  20679. +static MV_STATUS mvCesaFragAuthComplete(MV_CESA_REQ* pReq, MV_CESA_SA* pSA,
  20680. + int macDataSize);
  20681. +
  20682. +static MV_CESA_COMMAND* mvCesaCtrModeInit(void);
  20683. +
  20684. +static MV_STATUS mvCesaCtrModePrepare(MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd);
  20685. +static MV_STATUS mvCesaCtrModeComplete(MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd);
  20686. +static void mvCesaCtrModeFinish(MV_CESA_COMMAND *pCmd);
  20687. +
  20688. +static INLINE MV_STATUS mvCesaReqProcess(MV_CESA_REQ* pReq);
  20689. +static MV_STATUS mvCesaFragReqProcess(MV_CESA_REQ* pReq, MV_U8 frag);
  20690. +
  20691. +static INLINE MV_STATUS mvCesaParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, MV_U8* pFixOffset);
  20692. +static INLINE MV_STATUS mvCesaFragParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd);
  20693. +
  20694. +static INLINE void mvCesaFragSizeFind(MV_CESA_SA* pSA, MV_CESA_REQ* pReq,
  20695. + int cryptoOffset, int macOffset,
  20696. + int* pCopySize, int* pCryptoDataSize, int* pMacDataSize);
  20697. +static MV_STATUS mvCesaMbufCacheUnmap(MV_CESA_MBUF* pMbuf, int offset, int size);
  20698. +
  20699. +
  20700. +/* Go to the next request in the request queue */
  20701. +static INLINE MV_CESA_REQ* MV_CESA_REQ_NEXT_PTR(MV_CESA_REQ* pReq)
  20702. +{
  20703. + if(pReq == pCesaReqLast)
  20704. + return pCesaReqFirst;
  20705. +
  20706. + return pReq+1;
  20707. +}
  20708. +
  20709. +#if (MV_CESA_VERSION >= 3)
  20710. +/* Go to the previous request in the request queue */
  20711. +static INLINE MV_CESA_REQ* MV_CESA_REQ_PREV_PTR(MV_CESA_REQ* pReq)
  20712. +{
  20713. + if(pReq == pCesaReqFirst)
  20714. + return pCesaReqLast;
  20715. +
  20716. + return pReq-1;
  20717. +}
  20718. +
  20719. +#endif
  20720. +
  20721. +
  20722. +static INLINE void mvCesaReqProcessStart(MV_CESA_REQ* pReq)
  20723. +{
  20724. + int frag;
  20725. +
  20726. +#if (MV_CESA_VERSION >= 3)
  20727. + pReq->state = MV_CESA_CHAIN;
  20728. +#else
  20729. + pReq->state = MV_CESA_PROCESS;
  20730. +#endif
  20731. + cesaStats.startCount++;
  20732. +
  20733. + if(pReq->fragMode == MV_CESA_FRAG_NONE)
  20734. + {
  20735. + frag = 0;
  20736. + }
  20737. + else
  20738. + {
  20739. + frag = pReq->frags.nextFrag;
  20740. + pReq->frags.nextFrag++;
  20741. + }
  20742. +#if (MV_CESA_VERSION >= 2)
  20743. + /* Enable TDMA engine */
  20744. + MV_REG_WRITE(MV_CESA_TDMA_CURR_DESC_PTR_REG, 0);
  20745. + MV_REG_WRITE(MV_CESA_TDMA_NEXT_DESC_PTR_REG,
  20746. + (MV_U32)mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));
  20747. +#else
  20748. + /* Enable IDMA engine */
  20749. + MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(0), 0);
  20750. + MV_REG_WRITE(IDMA_NEXT_DESC_PTR_REG(0),
  20751. + (MV_U32)mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));
  20752. +#endif /* MV_CESA_VERSION >= 2 */
  20753. +
  20754. +#if defined(MV_BRIDGE_SYNC_REORDER)
  20755. + mvOsBridgeReorderWA();
  20756. +#endif
  20757. +
  20758. + /* Start Accelerator */
  20759. + MV_REG_WRITE(MV_CESA_CMD_REG, MV_CESA_CMD_CHAN_ENABLE_MASK);
  20760. +}
  20761. +
  20762. +
  20763. +/*******************************************************************************
  20764. +* mvCesaHalInit - Initialize the CESA driver
  20765. +*
  20766. +* DESCRIPTION:
  20767. +* This function initialize the CESA driver.
  20768. +* 1) Session database
  20769. +* 2) Request queue
  20770. +* 4) DMA descriptor lists - one list per request. Each list
  20771. +* has MV_CESA_MAX_DMA_DESC descriptors.
  20772. +*
  20773. +* INPUT:
  20774. +* numOfSession - maximum number of supported sessions
  20775. +* queueDepth - number of elements in the request queue.
  20776. +* pSramBase - virtual address of Sram
  20777. +* osHandle - A handle used by the OS to allocate memory for the
  20778. +* module (Passed to the OS Services layer)
  20779. +*
  20780. +* RETURN:
  20781. +* MV_OK - Success
  20782. +* MV_NO_RESOURCE - Fail, can't allocate resources:
  20783. +* Session database, request queue,
  20784. +* DMA descriptors list, LRU cache database.
  20785. +* MV_NOT_ALIGNED - Sram base address is not 8 byte aligned.
  20786. +*
  20787. +*******************************************************************************/
  20788. +MV_STATUS mvCesaHalInit (int numOfSession, int queueDepth, char* pSramBase, MV_U32 cryptEngBase,
  20789. + void *osHandle)
  20790. +{
  20791. + int i, req;
  20792. + MV_U32 descOffsetReg, configReg;
  20793. + MV_CESA_SRAM_SA *pSramSA;
  20794. +
  20795. +
  20796. + mvOsPrintf("mvCesaInit: sessions=%d, queue=%d, pSram=%p\n",
  20797. + numOfSession, queueDepth, pSramBase);
  20798. +
  20799. + cesaOsHandle = osHandle;
  20800. + /* Create Session database */
  20801. + pCesaSAD = mvOsMalloc(sizeof(MV_CESA_SA)*numOfSession);
  20802. + if(pCesaSAD == NULL)
  20803. + {
  20804. + mvOsPrintf("mvCesaInit: Can't allocate %u bytes for %d SAs\n",
  20805. + sizeof(MV_CESA_SA)*numOfSession, numOfSession);
  20806. + mvCesaFinish();
  20807. + return MV_NO_RESOURCE;
  20808. + }
  20809. + memset(pCesaSAD, 0, sizeof(MV_CESA_SA)*numOfSession);
  20810. + cesaMaxSA = numOfSession;
  20811. +
  20812. + /* Allocate imag of sramSA in the DRAM */
  20813. + cesaSramSaBuf.bufSize = sizeof(MV_CESA_SRAM_SA)*numOfSession +
  20814. + CPU_D_CACHE_LINE_SIZE;
  20815. +
  20816. + cesaSramSaBuf.bufVirtPtr = mvOsIoCachedMalloc(osHandle,cesaSramSaBuf.bufSize,
  20817. + &cesaSramSaBuf.bufPhysAddr,
  20818. + &cesaSramSaBuf.memHandle);
  20819. +
  20820. + if(cesaSramSaBuf.bufVirtPtr == NULL)
  20821. + {
  20822. + mvOsPrintf("mvCesaInit: Can't allocate %d bytes for sramSA structures\n",
  20823. + cesaSramSaBuf.bufSize);
  20824. + mvCesaFinish();
  20825. + return MV_NO_RESOURCE;
  20826. + }
  20827. + memset(cesaSramSaBuf.bufVirtPtr, 0, cesaSramSaBuf.bufSize);
  20828. + pSramSA = (MV_CESA_SRAM_SA*)MV_ALIGN_UP((MV_ULONG)cesaSramSaBuf.bufVirtPtr,
  20829. + CPU_D_CACHE_LINE_SIZE);
  20830. + for(i=0; i<numOfSession; i++)
  20831. + {
  20832. + pCesaSAD[i].pSramSA = &pSramSA[i];
  20833. + }
  20834. +
  20835. + /* Create request queue */
  20836. + pCesaReqFirst = mvOsMalloc(sizeof(MV_CESA_REQ)*queueDepth);
  20837. + if(pCesaReqFirst == NULL)
  20838. + {
  20839. + mvOsPrintf("mvCesaInit: Can't allocate %u bytes for %d requests\n",
  20840. + sizeof(MV_CESA_REQ)*queueDepth, queueDepth);
  20841. + mvCesaFinish();
  20842. + return MV_NO_RESOURCE;
  20843. + }
  20844. + memset(pCesaReqFirst, 0, sizeof(MV_CESA_REQ)*queueDepth);
  20845. + pCesaReqEmpty = pCesaReqFirst;
  20846. + pCesaReqLast = pCesaReqFirst + (queueDepth-1);
  20847. + pCesaReqProcess = pCesaReqEmpty;
  20848. + cesaQueueDepth = queueDepth;
  20849. + cesaReqResources = queueDepth;
  20850. +#if (MV_CESA_VERSION >= 3)
  20851. + cesaChainLength = MAX_CESA_CHAIN_LENGTH;
  20852. +#endif
  20853. + /* pSramBase must be 8 byte aligned */
  20854. + if( MV_IS_NOT_ALIGN((MV_ULONG)pSramBase, 8) )
  20855. + {
  20856. + mvOsPrintf("mvCesaInit: pSramBase (%p) must be 8 byte aligned\n",
  20857. + pSramBase);
  20858. + mvCesaFinish();
  20859. + return MV_NOT_ALIGNED;
  20860. + }
  20861. + cesaSramVirtPtr = (MV_CESA_SRAM_MAP*)pSramBase;
  20862. +
  20863. + cesaCryptEngBase = cryptEngBase;
  20864. +
  20865. + /*memset(cesaSramVirtPtr, 0, sizeof(MV_CESA_SRAM_MAP));*/
  20866. +
  20867. + /* Clear registers */
  20868. + MV_REG_WRITE( MV_CESA_CFG_REG, 0);
  20869. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  20870. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
  20871. +
  20872. + /* Initialize DMA descriptor lists for all requests in Request queue */
  20873. + descOffsetReg = configReg = 0;
  20874. + for(req=0; req<queueDepth; req++)
  20875. + {
  20876. + int frag;
  20877. + MV_CESA_REQ* pReq;
  20878. + MV_DMA_DESC* pDmaDesc;
  20879. +
  20880. + pReq = &pCesaReqFirst[req];
  20881. +
  20882. + pReq->cesaDescBuf.bufSize = sizeof(MV_CESA_DESC)*MV_CESA_MAX_REQ_FRAGS +
  20883. + CPU_D_CACHE_LINE_SIZE;
  20884. +
  20885. + pReq->cesaDescBuf.bufVirtPtr =
  20886. + mvOsIoCachedMalloc(osHandle,pReq->cesaDescBuf.bufSize,
  20887. + &pReq->cesaDescBuf.bufPhysAddr,
  20888. + &pReq->cesaDescBuf.memHandle);
  20889. +
  20890. + if(pReq->cesaDescBuf.bufVirtPtr == NULL)
  20891. + {
  20892. + mvOsPrintf("mvCesaInit: req=%d, Can't allocate %d bytes for CESA descriptors\n",
  20893. + req, pReq->cesaDescBuf.bufSize);
  20894. + mvCesaFinish();
  20895. + return MV_NO_RESOURCE;
  20896. + }
  20897. + memset(pReq->cesaDescBuf.bufVirtPtr, 0, pReq->cesaDescBuf.bufSize);
  20898. + pReq->pCesaDesc = (MV_CESA_DESC*)MV_ALIGN_UP((MV_ULONG)pReq->cesaDescBuf.bufVirtPtr,
  20899. + CPU_D_CACHE_LINE_SIZE);
  20900. +
  20901. + pReq->dmaDescBuf.bufSize = sizeof(MV_DMA_DESC)*MV_CESA_MAX_DMA_DESC*MV_CESA_MAX_REQ_FRAGS +
  20902. + CPU_D_CACHE_LINE_SIZE;
  20903. +
  20904. + pReq->dmaDescBuf.bufVirtPtr =
  20905. + mvOsIoCachedMalloc(osHandle,pReq->dmaDescBuf.bufSize,
  20906. + &pReq->dmaDescBuf.bufPhysAddr,
  20907. + &pReq->dmaDescBuf.memHandle);
  20908. +
  20909. + if(pReq->dmaDescBuf.bufVirtPtr == NULL)
  20910. + {
  20911. + mvOsPrintf("mvCesaInit: req=%d, Can't allocate %d bytes for DMA descriptor list\n",
  20912. + req, pReq->dmaDescBuf.bufSize);
  20913. + mvCesaFinish();
  20914. + return MV_NO_RESOURCE;
  20915. + }
  20916. + memset(pReq->dmaDescBuf.bufVirtPtr, 0, pReq->dmaDescBuf.bufSize);
  20917. + pDmaDesc = (MV_DMA_DESC*)MV_ALIGN_UP((MV_ULONG)pReq->dmaDescBuf.bufVirtPtr,
  20918. + CPU_D_CACHE_LINE_SIZE);
  20919. +
  20920. + for(frag=0; frag<MV_CESA_MAX_REQ_FRAGS; frag++)
  20921. + {
  20922. + MV_CESA_DMA* pDma = &pReq->dma[frag];
  20923. +
  20924. + pDma->pDmaFirst = pDmaDesc;
  20925. + pDma->pDmaLast = NULL;
  20926. +
  20927. + for(i=0; i<MV_CESA_MAX_DMA_DESC-1; i++)
  20928. + {
  20929. + /* link all DMA descriptors together */
  20930. + pDma->pDmaFirst[i].phyNextDescPtr =
  20931. + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pDmaDesc[i+1]));
  20932. + }
  20933. + pDma->pDmaFirst[i].phyNextDescPtr = 0;
  20934. + mvOsCacheFlush(NULL, &pDma->pDmaFirst[0], MV_CESA_MAX_DMA_DESC*sizeof(MV_DMA_DESC));
  20935. +
  20936. + pDmaDesc += MV_CESA_MAX_DMA_DESC;
  20937. + }
  20938. + }
  20939. + /*mvCesaCryptoIvSet(NULL, MV_CESA_MAX_IV_LENGTH);*/
  20940. + descOffsetReg = (MV_U16)((MV_U8*)&cesaSramVirtPtr->desc - mvCesaSramAddrGet());
  20941. + MV_REG_WRITE(MV_CESA_CHAN_DESC_OFFSET_REG, descOffsetReg);
  20942. +
  20943. + configReg |= (MV_CESA_CFG_WAIT_DMA_MASK | MV_CESA_CFG_ACT_DMA_MASK);
  20944. +#if (MV_CESA_VERSION >= 3)
  20945. + configReg |= MV_CESA_CFG_CHAIN_MODE_MASK;
  20946. +#endif
  20947. +
  20948. +#if (MV_CESA_VERSION >= 2)
  20949. + /* Initialize TDMA engine */
  20950. + MV_REG_WRITE(MV_CESA_TDMA_CTRL_REG, MV_CESA_TDMA_CTRL_VALUE);
  20951. + MV_REG_WRITE(MV_CESA_TDMA_BYTE_COUNT_REG, 0);
  20952. + MV_REG_WRITE(MV_CESA_TDMA_CURR_DESC_PTR_REG, 0);
  20953. +#else
  20954. + /* Initialize IDMA #0 engine */
  20955. + MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), 0);
  20956. + MV_REG_WRITE(IDMA_BYTE_COUNT_REG(0), 0);
  20957. + MV_REG_WRITE(IDMA_CURR_DESC_PTR_REG(0), 0);
  20958. + MV_REG_WRITE(IDMA_CTRL_HIGH_REG(0), ICCHR_ENDIAN_LITTLE
  20959. +#ifdef MV_CPU_LE
  20960. + | ICCHR_DESC_BYTE_SWAP_EN
  20961. +#endif
  20962. + );
  20963. + /* Clear Cause Byte of IDMA channel to be used */
  20964. + MV_REG_WRITE( IDMA_CAUSE_REG, ~ICICR_CAUSE_MASK_ALL(0));
  20965. + MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), MV_CESA_IDMA_CTRL_LOW_VALUE);
  20966. +#endif /* (MV_CESA_VERSION >= 2) */
  20967. +
  20968. + /* Set CESA configuration registers */
  20969. + MV_REG_WRITE( MV_CESA_CFG_REG, configReg);
  20970. + mvCesaDebugStatsClear();
  20971. +
  20972. + return MV_OK;
  20973. +}
  20974. +
  20975. +/*******************************************************************************
  20976. +* mvCesaFinish - Shutdown the CESA driver
  20977. +*
  20978. +* DESCRIPTION:
  20979. +* This function shutdown the CESA driver and free all allocted resources.
  20980. +*
  20981. +* INPUT: None
  20982. +*
  20983. +* RETURN:
  20984. +* MV_OK - Success
  20985. +* Other - Fail
  20986. +*
  20987. +*******************************************************************************/
  20988. +MV_STATUS mvCesaFinish (void)
  20989. +{
  20990. + int req;
  20991. + MV_CESA_REQ* pReq;
  20992. +
  20993. + mvOsPrintf("mvCesaFinish: \n");
  20994. +
  20995. + cesaSramVirtPtr = NULL;
  20996. +
  20997. + /* Free all resources: DMA list, etc. */
  20998. + for(req=0; req<cesaQueueDepth; req++)
  20999. + {
  21000. + pReq = &pCesaReqFirst[req];
  21001. + if(pReq->dmaDescBuf.bufVirtPtr != NULL)
  21002. + {
  21003. + mvOsIoCachedFree(cesaOsHandle,pReq->dmaDescBuf.bufSize,
  21004. + pReq->dmaDescBuf.bufPhysAddr,
  21005. + pReq->dmaDescBuf.bufVirtPtr,
  21006. + pReq->dmaDescBuf.memHandle);
  21007. + }
  21008. + if(pReq->cesaDescBuf.bufVirtPtr != NULL)
  21009. + {
  21010. + mvOsIoCachedFree(cesaOsHandle,pReq->cesaDescBuf.bufSize,
  21011. + pReq->cesaDescBuf.bufPhysAddr,
  21012. + pReq->cesaDescBuf.bufVirtPtr,
  21013. + pReq->cesaDescBuf.memHandle);
  21014. + }
  21015. + }
  21016. +#if (MV_CESA_VERSION < 2)
  21017. + MV_REG_WRITE(IDMA_CTRL_LOW_REG(0), 0);
  21018. +#endif /* (MV_CESA_VERSION < 2) */
  21019. +
  21020. + /* Free request queue */
  21021. + if(pCesaReqFirst != NULL)
  21022. + {
  21023. + mvOsFree(pCesaReqFirst);
  21024. + pCesaReqFirst = pCesaReqLast = NULL;
  21025. + pCesaReqEmpty = pCesaReqProcess = NULL;
  21026. + cesaQueueDepth = cesaReqResources = 0;
  21027. + }
  21028. + /* Free SA database */
  21029. + if(pCesaSAD != NULL)
  21030. + {
  21031. + mvOsFree(pCesaSAD);
  21032. + pCesaSAD = NULL;
  21033. + cesaMaxSA = 0;
  21034. + }
  21035. + MV_REG_WRITE( MV_CESA_CFG_REG, 0);
  21036. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  21037. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
  21038. +
  21039. + return MV_OK;
  21040. +}
  21041. +
  21042. +/*******************************************************************************
  21043. +* mvCesaCryptoIvSet - Set IV value for Crypto algorithm working in CBC mode
  21044. +*
  21045. +* DESCRIPTION:
  21046. +* This function set IV value using by Crypto algorithms in CBC mode.
  21047. +* Each channel has its own IV value.
  21048. +* This function gets IV value from the caller. If no IV value passed from
  21049. +* the caller or only part of IV passed, the function will init the rest part
  21050. +* of IV value (or the whole IV) by random value.
  21051. +*
  21052. +* INPUT:
  21053. +* MV_U8* pIV - Pointer to IV value supplied by user. If pIV==NULL
  21054. +* the function will generate random IV value.
  21055. +* int ivSize - size (in bytes) of IV provided by user. If ivSize is
  21056. +* smaller than maximum IV size, the function will complete
  21057. +* IV by random value.
  21058. +*
  21059. +* RETURN:
  21060. +* MV_OK - Success
  21061. +* Other - Fail
  21062. +*
  21063. +*******************************************************************************/
  21064. +MV_STATUS mvCesaCryptoIvSet(MV_U8* pIV, int ivSize)
  21065. +{
  21066. + MV_U8* pSramIV;
  21067. +#if defined(MV646xx)
  21068. + mvOsPrintf("mvCesaCryptoIvSet: ERR. shouldn't use this call on MV64660\n");
  21069. +#endif
  21070. + pSramIV = cesaSramVirtPtr->cryptoIV;
  21071. + if(ivSize > MV_CESA_MAX_IV_LENGTH)
  21072. + {
  21073. + mvOsPrintf("mvCesaCryptoIvSet: ivSize (%d) is too large\n", ivSize);
  21074. + ivSize = MV_CESA_MAX_IV_LENGTH;
  21075. + }
  21076. + if(pIV != NULL)
  21077. + {
  21078. + memcpy(pSramIV, pIV, ivSize);
  21079. + ivSize = MV_CESA_MAX_IV_LENGTH - ivSize;
  21080. + pSramIV += ivSize;
  21081. + }
  21082. +
  21083. + while(ivSize > 0)
  21084. + {
  21085. + int size, mv_random = mvOsRand();
  21086. +
  21087. + size = MV_MIN(ivSize, sizeof(mv_random));
  21088. + memcpy(pSramIV, (void*)&mv_random, size);
  21089. +
  21090. + pSramIV += size;
  21091. + ivSize -= size;
  21092. + }
  21093. +/*
  21094. + mvOsCacheFlush(NULL, cesaSramVirtPtr->cryptoIV,
  21095. + MV_CESA_MAX_IV_LENGTH);
  21096. + mvOsCacheInvalidate(NULL, cesaSramVirtPtr->cryptoIV,
  21097. + MV_CESA_MAX_IV_LENGTH);
  21098. +*/
  21099. + return MV_OK;
  21100. +}
  21101. +
  21102. +/*******************************************************************************
  21103. +* mvCesaSessionOpen - Open new uni-directional crypto session
  21104. +*
  21105. +* DESCRIPTION:
  21106. +* This function open new session.
  21107. +*
  21108. +* INPUT:
  21109. +* MV_CESA_OPEN_SESSION *pSession - pointer to new session input parameters
  21110. +*
  21111. +* OUTPUT:
  21112. +* short *pSid - session ID, should be used for all future
  21113. +* requests over this session.
  21114. +*
  21115. +* RETURN:
  21116. +* MV_OK - Session opend successfully.
  21117. +* MV_FULL - All sessions are in use, no free place in
  21118. +* SA database.
  21119. +* MV_BAD_PARAM - One of session input parameters is invalid.
  21120. +*
  21121. +*******************************************************************************/
  21122. +MV_STATUS mvCesaSessionOpen(MV_CESA_OPEN_SESSION *pSession, short* pSid)
  21123. +{
  21124. + short sid;
  21125. + MV_U32 config = 0;
  21126. + int digestSize;
  21127. +
  21128. + cesaStats.openedCount++;
  21129. +
  21130. + /* Find free entry in SAD */
  21131. + for(sid=0; sid<cesaMaxSA; sid++)
  21132. + {
  21133. + if(pCesaSAD[sid].valid == 0)
  21134. + {
  21135. + break;
  21136. + }
  21137. + }
  21138. + if(sid == cesaMaxSA)
  21139. + {
  21140. + mvOsPrintf("mvCesaSessionOpen: SA Database is FULL\n");
  21141. + return MV_FULL;
  21142. + }
  21143. +
  21144. + /* Check Input parameters for Open session */
  21145. + if (pSession->operation >= MV_CESA_MAX_OPERATION)
  21146. + {
  21147. + mvOsPrintf("mvCesaSessionOpen: Unexpected operation %d\n",
  21148. + pSession->operation);
  21149. + return MV_BAD_PARAM;
  21150. + }
  21151. + config |= (pSession->operation << MV_CESA_OPERATION_OFFSET);
  21152. +
  21153. + if( (pSession->direction != MV_CESA_DIR_ENCODE) &&
  21154. + (pSession->direction != MV_CESA_DIR_DECODE) )
  21155. + {
  21156. + mvOsPrintf("mvCesaSessionOpen: Unexpected direction %d\n",
  21157. + pSession->direction);
  21158. + return MV_BAD_PARAM;
  21159. + }
  21160. + config |= (pSession->direction << MV_CESA_DIRECTION_BIT);
  21161. + /* Clear SA entry */
  21162. + /* memset(&pCesaSAD[sid], 0, sizeof(pCesaSAD[sid])); */
  21163. +
  21164. + /* Check AUTH parameters and update SA entry */
  21165. + if(pSession->operation != MV_CESA_CRYPTO_ONLY)
  21166. + {
  21167. + /* For HMAC (MD5 and SHA1) - Maximum Key size is 64 bytes */
  21168. + if( (pSession->macMode == MV_CESA_MAC_HMAC_MD5) ||
  21169. + (pSession->macMode == MV_CESA_MAC_HMAC_SHA1) )
  21170. + {
  21171. + if(pSession->macKeyLength > MV_CESA_MAX_MAC_KEY_LENGTH)
  21172. + {
  21173. + mvOsPrintf("mvCesaSessionOpen: macKeyLength %d is too large\n",
  21174. + pSession->macKeyLength);
  21175. + return MV_BAD_PARAM;
  21176. + }
  21177. + mvCesaHmacIvGet(pSession->macMode, pSession->macKey, pSession->macKeyLength,
  21178. + pCesaSAD[sid].pSramSA->macInnerIV,
  21179. + pCesaSAD[sid].pSramSA->macOuterIV);
  21180. + pCesaSAD[sid].macKeyLength = pSession->macKeyLength;
  21181. + }
  21182. + switch(pSession->macMode)
  21183. + {
  21184. + case MV_CESA_MAC_MD5:
  21185. + case MV_CESA_MAC_HMAC_MD5:
  21186. + digestSize = MV_CESA_MD5_DIGEST_SIZE;
  21187. + break;
  21188. +
  21189. + case MV_CESA_MAC_SHA1:
  21190. + case MV_CESA_MAC_HMAC_SHA1:
  21191. + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
  21192. + break;
  21193. +
  21194. + default:
  21195. + mvOsPrintf("mvCesaSessionOpen: Unexpected macMode %d\n",
  21196. + pSession->macMode);
  21197. + return MV_BAD_PARAM;
  21198. + }
  21199. + config |= (pSession->macMode << MV_CESA_MAC_MODE_OFFSET);
  21200. +
  21201. + /* Supported digest sizes: MD5 - 16 bytes (128 bits), */
  21202. + /* SHA1 - 20 bytes (160 bits) or 12 bytes (96 bits) for both */
  21203. + if( (pSession->digestSize != digestSize) && (pSession->digestSize != 12))
  21204. + {
  21205. + mvOsPrintf("mvCesaSessionOpen: Unexpected digest size %d\n",
  21206. + pSession->digestSize);
  21207. + mvOsPrintf("\t Valid values [bytes]: MD5-16, SHA1-20, Both-12\n");
  21208. + return MV_BAD_PARAM;
  21209. + }
  21210. + pCesaSAD[sid].digestSize = pSession->digestSize;
  21211. +
  21212. + if(pCesaSAD[sid].digestSize == 12)
  21213. + {
  21214. + /* Set MV_CESA_MAC_DIGEST_SIZE_BIT if digest size is 96 bits */
  21215. + config |= (MV_CESA_MAC_DIGEST_96B << MV_CESA_MAC_DIGEST_SIZE_BIT);
  21216. + }
  21217. + }
  21218. +
  21219. + /* Check CRYPTO parameters and update SA entry */
  21220. + if(pSession->operation != MV_CESA_MAC_ONLY)
  21221. + {
  21222. + switch(pSession->cryptoAlgorithm)
  21223. + {
  21224. + case MV_CESA_CRYPTO_DES:
  21225. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_DES_KEY_LENGTH;
  21226. + pCesaSAD[sid].cryptoBlockSize = MV_CESA_DES_BLOCK_SIZE;
  21227. + break;
  21228. +
  21229. + case MV_CESA_CRYPTO_3DES:
  21230. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_3DES_KEY_LENGTH;
  21231. + pCesaSAD[sid].cryptoBlockSize = MV_CESA_DES_BLOCK_SIZE;
  21232. + /* Only EDE mode is supported */
  21233. + config |= (MV_CESA_CRYPTO_3DES_EDE <<
  21234. + MV_CESA_CRYPTO_3DES_MODE_BIT);
  21235. + break;
  21236. +
  21237. + case MV_CESA_CRYPTO_AES:
  21238. + switch(pSession->cryptoKeyLength)
  21239. + {
  21240. + case 16:
  21241. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_128_KEY_LENGTH;
  21242. + config |= (MV_CESA_CRYPTO_AES_KEY_128 <<
  21243. + MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);
  21244. + break;
  21245. +
  21246. + case 24:
  21247. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_192_KEY_LENGTH;
  21248. + config |= (MV_CESA_CRYPTO_AES_KEY_192 <<
  21249. + MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);
  21250. + break;
  21251. +
  21252. + case 32:
  21253. + default:
  21254. + pCesaSAD[sid].cryptoKeyLength = MV_CESA_AES_256_KEY_LENGTH;
  21255. + config |= (MV_CESA_CRYPTO_AES_KEY_256 <<
  21256. + MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET);
  21257. + break;
  21258. + }
  21259. + pCesaSAD[sid].cryptoBlockSize = MV_CESA_AES_BLOCK_SIZE;
  21260. + break;
  21261. +
  21262. + default:
  21263. + mvOsPrintf("mvCesaSessionOpen: Unexpected cryptoAlgorithm %d\n",
  21264. + pSession->cryptoAlgorithm);
  21265. + return MV_BAD_PARAM;
  21266. + }
  21267. + config |= (pSession->cryptoAlgorithm << MV_CESA_CRYPTO_ALG_OFFSET);
  21268. +
  21269. + if(pSession->cryptoKeyLength != pCesaSAD[sid].cryptoKeyLength)
  21270. + {
  21271. + mvOsPrintf("cesaSessionOpen: Wrong CryptoKeySize %d != %d\n",
  21272. + pSession->cryptoKeyLength, pCesaSAD[sid].cryptoKeyLength);
  21273. + return MV_BAD_PARAM;
  21274. + }
  21275. +
  21276. + /* Copy Crypto key */
  21277. + if( (pSession->cryptoAlgorithm == MV_CESA_CRYPTO_AES) &&
  21278. + (pSession->direction == MV_CESA_DIR_DECODE))
  21279. + {
  21280. + /* Crypto Key for AES decode is computed from original key material */
  21281. + /* and depend on cryptoKeyLength (128/192/256 bits) */
  21282. + aesMakeKey(pCesaSAD[sid].pSramSA->cryptoKey, pSession->cryptoKey,
  21283. + pSession->cryptoKeyLength*8, MV_CESA_AES_BLOCK_SIZE*8);
  21284. + }
  21285. + else
  21286. + {
  21287. + /*panic("mvCesaSessionOpen2");*/
  21288. + memcpy(pCesaSAD[sid].pSramSA->cryptoKey, pSession->cryptoKey,
  21289. + pCesaSAD[sid].cryptoKeyLength);
  21290. +
  21291. + }
  21292. +
  21293. + switch(pSession->cryptoMode)
  21294. + {
  21295. + case MV_CESA_CRYPTO_ECB:
  21296. + pCesaSAD[sid].cryptoIvSize = 0;
  21297. + break;
  21298. +
  21299. + case MV_CESA_CRYPTO_CBC:
  21300. + pCesaSAD[sid].cryptoIvSize = pCesaSAD[sid].cryptoBlockSize;
  21301. + break;
  21302. +
  21303. + case MV_CESA_CRYPTO_CTR:
  21304. + /* Supported only for AES algorithm */
  21305. + if(pSession->cryptoAlgorithm != MV_CESA_CRYPTO_AES)
  21306. + {
  21307. + mvOsPrintf("mvCesaSessionOpen: CRYPTO CTR mode supported for AES only\n");
  21308. + return MV_BAD_PARAM;
  21309. + }
  21310. + pCesaSAD[sid].cryptoIvSize = 0;
  21311. + pCesaSAD[sid].ctrMode = 1;
  21312. + /* Replace to ECB mode for HW */
  21313. + pSession->cryptoMode = MV_CESA_CRYPTO_ECB;
  21314. + break;
  21315. +
  21316. + default:
  21317. + mvOsPrintf("mvCesaSessionOpen: Unexpected cryptoMode %d\n",
  21318. + pSession->cryptoMode);
  21319. + return MV_BAD_PARAM;
  21320. + }
  21321. +
  21322. + config |= (pSession->cryptoMode << MV_CESA_CRYPTO_MODE_BIT);
  21323. + }
  21324. + pCesaSAD[sid].config = config;
  21325. +
  21326. + mvOsCacheFlush(NULL, pCesaSAD[sid].pSramSA, sizeof(MV_CESA_SRAM_SA));
  21327. + if(pSid != NULL)
  21328. + *pSid = sid;
  21329. +
  21330. + pCesaSAD[sid].valid = 1;
  21331. + return MV_OK;
  21332. +}
  21333. +
  21334. +/*******************************************************************************
  21335. +* mvCesaSessionClose - Close active crypto session
  21336. +*
  21337. +* DESCRIPTION:
  21338. +* This function closes existing session
  21339. +*
  21340. +* INPUT:
  21341. +* short sid - Unique identifier of the session to be closed
  21342. +*
  21343. +* RETURN:
  21344. +* MV_OK - Session closed successfully.
  21345. +* MV_BAD_PARAM - Session identifier is out of valid range.
  21346. +* MV_NOT_FOUND - There is no active session with such ID.
  21347. +*
  21348. +*******************************************************************************/
  21349. +MV_STATUS mvCesaSessionClose(short sid)
  21350. +{
  21351. + cesaStats.closedCount++;
  21352. +
  21353. + if(sid >= cesaMaxSA)
  21354. + {
  21355. + mvOsPrintf("CESA Error: sid (%d) is too big\n", sid);
  21356. + return MV_BAD_PARAM;
  21357. + }
  21358. + if(pCesaSAD[sid].valid == 0)
  21359. + {
  21360. + mvOsPrintf("CESA Warning: Session (sid=%d) is invalid\n", sid);
  21361. + return MV_NOT_FOUND;
  21362. + }
  21363. + if(cesaLastSid == sid)
  21364. + cesaLastSid = -1;
  21365. +
  21366. + pCesaSAD[sid].valid = 0;
  21367. + return MV_OK;
  21368. +}
  21369. +
  21370. +/*******************************************************************************
  21371. +* mvCesaAction - Perform crypto operation
  21372. +*
  21373. +* DESCRIPTION:
  21374. +* This function set new CESA request FIFO queue for further HW processing.
  21375. +* The function checks request parameters before set new request to the queue.
  21376. +* If one of the CESA channels is ready for processing the request will be
  21377. +* passed to HW. When request processing is finished the CESA interrupt will
  21378. +* be generated by HW. The caller should call mvCesaReadyGet() function to
  21379. +* complete request processing and get result.
  21380. +*
  21381. +* INPUT:
  21382. +* MV_CESA_COMMAND *pCmd - pointer to new CESA request.
  21383. +* It includes pointers to Source and Destination
  21384. +* buffers, session identifier get from
  21385. +* mvCesaSessionOpen() function, pointer to caller
  21386. +* private data and all needed crypto parameters.
  21387. +*
  21388. +* RETURN:
  21389. +* MV_OK - request successfully added to request queue
  21390. +* and will be processed.
  21391. +* MV_NO_MORE - request successfully added to request queue and will
  21392. +* be processed, but request queue became Full and next
  21393. +* request will not be accepted.
  21394. +* MV_NO_RESOURCE - request queue is FULL and the request can not
  21395. +* be processed.
  21396. +* MV_OUT_OF_CPU_MEM - memory allocation needed for request processing is
  21397. +* failed. Request can not be processed.
  21398. +* MV_NOT_ALLOWED - This mixed request (CRYPTO+MAC) can not be processed
  21399. +* as one request and should be splitted for two requests:
  21400. +* CRYPTO_ONLY and MAC_ONLY.
  21401. +* MV_BAD_PARAM - One of the request parameters is out of valid range.
  21402. +* The request can not be processed.
  21403. +*
  21404. +*******************************************************************************/
  21405. +MV_STATUS mvCesaAction (MV_CESA_COMMAND *pCmd)
  21406. +{
  21407. + MV_STATUS status;
  21408. + MV_CESA_REQ* pReq = pCesaReqEmpty;
  21409. + int sid = pCmd->sessionId;
  21410. + MV_CESA_SA* pSA = &pCesaSAD[sid];
  21411. +#if (MV_CESA_VERSION >= 3)
  21412. + MV_CESA_REQ* pFromReq;
  21413. + MV_CESA_REQ* pToReq;
  21414. +#endif
  21415. + cesaStats.reqCount++;
  21416. +
  21417. + /* Check that the request queue is not FULL */
  21418. + if(cesaReqResources == 0)
  21419. + return MV_NO_RESOURCE;
  21420. +
  21421. + if( (sid >= cesaMaxSA) || (!pSA->valid) )
  21422. + {
  21423. + mvOsPrintf("CESA Action Error: Session sid=%d is INVALID\n", sid);
  21424. + return MV_BAD_PARAM;
  21425. + }
  21426. + pSA->count++;
  21427. +
  21428. + if(pSA->ctrMode)
  21429. + {
  21430. + /* AES in CTR mode can't be mixed with Authentication */
  21431. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  21432. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  21433. + {
  21434. + mvOsPrintf("mvCesaAction : CRYPTO CTR mode can't be mixed with AUTH\n");
  21435. + return MV_NOT_ALLOWED;
  21436. + }
  21437. + /* All other request parameters should not be checked because key stream */
  21438. + /* (not user data) processed by AES HW engine */
  21439. + pReq->pOrgCmd = pCmd;
  21440. + /* Allocate temporary pCmd structure for Key stream */
  21441. + pCmd = mvCesaCtrModeInit();
  21442. + if(pCmd == NULL)
  21443. + return MV_OUT_OF_CPU_MEM;
  21444. +
  21445. + /* Prepare Key stream */
  21446. + mvCesaCtrModePrepare(pCmd, pReq->pOrgCmd);
  21447. + pReq->fixOffset = 0;
  21448. + }
  21449. + else
  21450. + {
  21451. + /* Check request parameters and calculae fixOffset */
  21452. + status = mvCesaParamCheck(pSA, pCmd, &pReq->fixOffset);
  21453. + if(status != MV_OK)
  21454. + {
  21455. + return status;
  21456. + }
  21457. + }
  21458. + pReq->pCmd = pCmd;
  21459. +
  21460. + /* Check if the packet need fragmentation */
  21461. + if(pCmd->pSrc->mbufSize <= sizeof(cesaSramVirtPtr->buf) )
  21462. + {
  21463. + /* request size is smaller than single buffer size */
  21464. + pReq->fragMode = MV_CESA_FRAG_NONE;
  21465. +
  21466. + /* Prepare NOT fragmented packets */
  21467. + status = mvCesaReqProcess(pReq);
  21468. + if(status != MV_OK)
  21469. + {
  21470. + mvOsPrintf("CesaReady: ReqProcess error: pReq=%p, status=0x%x\n",
  21471. + pReq, status);
  21472. + }
  21473. +#if (MV_CESA_VERSION >= 3)
  21474. + pReq->frags.numFrag = 1;
  21475. +#endif
  21476. + }
  21477. + else
  21478. + {
  21479. + MV_U8 frag = 0;
  21480. +
  21481. + /* request size is larger than buffer size - needs fragmentation */
  21482. +
  21483. + /* Check restrictions for processing fragmented packets */
  21484. + status = mvCesaFragParamCheck(pSA, pCmd);
  21485. + if(status != MV_OK)
  21486. + return status;
  21487. +
  21488. + pReq->fragMode = MV_CESA_FRAG_FIRST;
  21489. + pReq->frags.nextFrag = 0;
  21490. +
  21491. + /* Prepare Process Fragmented packets */
  21492. + while(pReq->fragMode != MV_CESA_FRAG_LAST)
  21493. + {
  21494. + if(frag >= MV_CESA_MAX_REQ_FRAGS)
  21495. + {
  21496. + mvOsPrintf("mvCesaAction Error: Too large request frag=%d\n", frag);
  21497. + return MV_OUT_OF_CPU_MEM;
  21498. + }
  21499. + status = mvCesaFragReqProcess(pReq, frag);
  21500. + if(status == MV_OK) {
  21501. +#if (MV_CESA_VERSION >= 3)
  21502. + if(frag) {
  21503. + pReq->dma[frag-1].pDmaLast->phyNextDescPtr =
  21504. + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, pReq->dma[frag].pDmaFirst));
  21505. + mvOsCacheFlush(NULL, pReq->dma[frag-1].pDmaLast, sizeof(MV_DMA_DESC));
  21506. + }
  21507. +#endif
  21508. + frag++;
  21509. + }
  21510. + }
  21511. + pReq->frags.numFrag = frag;
  21512. +#if (MV_CESA_VERSION >= 3)
  21513. + if(chainReqNum) {
  21514. + chainReqNum += pReq->frags.numFrag;
  21515. + if(chainReqNum >= MAX_CESA_CHAIN_LENGTH)
  21516. + chainReqNum = MAX_CESA_CHAIN_LENGTH;
  21517. + }
  21518. +#endif
  21519. + }
  21520. +
  21521. + pReq->state = MV_CESA_PENDING;
  21522. +
  21523. + pCesaReqEmpty = MV_CESA_REQ_NEXT_PTR(pReq);
  21524. + cesaReqResources -= 1;
  21525. +
  21526. +/* #ifdef CESA_DEBUG */
  21527. + if( (cesaQueueDepth - cesaReqResources) > cesaStats.maxReqCount)
  21528. + cesaStats.maxReqCount = (cesaQueueDepth - cesaReqResources);
  21529. +/* #endif CESA_DEBUG */
  21530. +
  21531. + cesaLastSid = sid;
  21532. +
  21533. +#if (MV_CESA_VERSION >= 3)
  21534. + /* Are we within chain bounderies and follows the first request ? */
  21535. + if((chainReqNum > 0) && (chainReqNum < MAX_CESA_CHAIN_LENGTH)) {
  21536. + if(chainIndex) {
  21537. + pFromReq = MV_CESA_REQ_PREV_PTR(pReq);
  21538. + pToReq = pReq;
  21539. + pReq->state = MV_CESA_CHAIN;
  21540. + /* assume concatenating is possible */
  21541. + pFromReq->dma[pFromReq->frags.numFrag-1].pDmaLast->phyNextDescPtr =
  21542. + MV_32BIT_LE(mvCesaVirtToPhys(&pToReq->dmaDescBuf, pToReq->dma[0].pDmaFirst));
  21543. + mvOsCacheFlush(NULL, pFromReq->dma[pFromReq->frags.numFrag-1].pDmaLast, sizeof(MV_DMA_DESC));
  21544. +
  21545. + /* align active & next pointers */
  21546. + if(pNextActiveChain->state != MV_CESA_PENDING)
  21547. + pEndCurrChain = pNextActiveChain = MV_CESA_REQ_NEXT_PTR(pReq);
  21548. + }
  21549. + else { /* we have only one chain, start new one */
  21550. + chainReqNum = 0;
  21551. + chainIndex++;
  21552. + /* align active & next pointers */
  21553. + if(pNextActiveChain->state != MV_CESA_PENDING)
  21554. + pEndCurrChain = pNextActiveChain = pReq;
  21555. + }
  21556. + }
  21557. + else {
  21558. + /* In case we concatenate full chain */
  21559. + if(chainReqNum == MAX_CESA_CHAIN_LENGTH) {
  21560. + chainIndex++;
  21561. + if(pNextActiveChain->state != MV_CESA_PENDING)
  21562. + pEndCurrChain = pNextActiveChain = pReq;
  21563. + chainReqNum = 0;
  21564. + }
  21565. +
  21566. + pReq = pCesaReqProcess;
  21567. + if(pReq->state == MV_CESA_PENDING) {
  21568. + pNextActiveChain = pReq;
  21569. + pEndCurrChain = MV_CESA_REQ_NEXT_PTR(pReq);
  21570. + /* Start Process new request */
  21571. + mvCesaReqProcessStart(pReq);
  21572. + }
  21573. + }
  21574. +
  21575. + chainReqNum++;
  21576. +
  21577. + if((chainIndex < MAX_CESA_CHAIN_LENGTH) && (chainReqNum > cesaStats.maxChainUsage))
  21578. + cesaStats.maxChainUsage = chainReqNum;
  21579. +
  21580. +#else
  21581. +
  21582. + /* Check status of CESA channels and process requests if possible */
  21583. + pReq = pCesaReqProcess;
  21584. + if(pReq->state == MV_CESA_PENDING)
  21585. + {
  21586. + /* Start Process new request */
  21587. + mvCesaReqProcessStart(pReq);
  21588. + }
  21589. +#endif
  21590. + /* If request queue became FULL - return MV_NO_MORE */
  21591. + if(cesaReqResources == 0)
  21592. + return MV_NO_MORE;
  21593. +
  21594. + return MV_OK;
  21595. +
  21596. +}
  21597. +
  21598. +/*******************************************************************************
  21599. +* mvCesaReadyGet - Get crypto request that processing is finished
  21600. +*
  21601. +* DESCRIPTION:
  21602. +* This function complete request processing and return ready request to
  21603. +* caller. To don't miss interrupts the caller must call this function
  21604. +* while MV_OK or MV_TERMINATE values returned.
  21605. +*
  21606. +* INPUT:
  21607. +* MV_U32 chanMap - map of CESA channels finished thier job
  21608. +* accordingly with CESA Cause register.
  21609. +* MV_CESA_RESULT* pResult - pointer to structure contains information
  21610. +* about ready request. It includes pointer to
  21611. +* user private structure "pReqPrv", session identifier
  21612. +* for this request "sessionId" and return code.
  21613. +* Return code set to MV_FAIL if calculated digest value
  21614. +* on decode direction is different than digest value
  21615. +* in the packet.
  21616. +*
  21617. +* RETURN:
  21618. +* MV_OK - Success, ready request is returned.
  21619. +* MV_NOT_READY - Next request is not ready yet. New interrupt will
  21620. +* be generated for futher request processing.
  21621. +* MV_EMPTY - There is no more request for processing.
  21622. +* MV_BUSY - Fragmented request is not ready yet.
  21623. +* MV_TERMINATE - Call this function once more to complete processing
  21624. +* of fragmented request.
  21625. +*
  21626. +*******************************************************************************/
  21627. +MV_STATUS mvCesaReadyGet(MV_CESA_RESULT* pResult)
  21628. +{
  21629. + MV_STATUS status, readyStatus = MV_NOT_READY;
  21630. + MV_U32 statusReg;
  21631. + MV_CESA_REQ* pReq;
  21632. + MV_CESA_SA* pSA;
  21633. +
  21634. +#if (MV_CESA_VERSION >= 3)
  21635. + if(isFirstReq == MV_TRUE) {
  21636. + if(chainIndex == 0)
  21637. + chainReqNum = 0;
  21638. +
  21639. + isFirstReq = MV_FALSE;
  21640. +
  21641. + if(pNextActiveChain->state == MV_CESA_PENDING) {
  21642. + /* Start request Process */
  21643. + mvCesaReqProcessStart(pNextActiveChain);
  21644. + pEndCurrChain = pNextActiveChain;
  21645. + if(chainIndex > 0)
  21646. + chainIndex--;
  21647. + /* Update pNextActiveChain to next chain head */
  21648. + while(pNextActiveChain->state == MV_CESA_CHAIN)
  21649. + pNextActiveChain = MV_CESA_REQ_NEXT_PTR(pNextActiveChain);
  21650. + }
  21651. + }
  21652. +
  21653. + /* Check if there are more processed requests - can we remove pEndCurrChain ??? */
  21654. + if(pCesaReqProcess == pEndCurrChain) {
  21655. + isFirstReq = MV_TRUE;
  21656. + pEndCurrChain = pNextActiveChain;
  21657. +#else
  21658. + if(pCesaReqProcess->state != MV_CESA_PROCESS) {
  21659. +#endif
  21660. + return MV_EMPTY;
  21661. + }
  21662. +
  21663. +#ifdef CESA_DEBUG
  21664. + statusReg = MV_REG_READ(MV_CESA_STATUS_REG);
  21665. + if( statusReg & MV_CESA_STATUS_ACTIVE_MASK )
  21666. + {
  21667. + mvOsPrintf("mvCesaReadyGet: Not Ready, Status = 0x%x\n", statusReg);
  21668. + cesaStats.notReadyCount++;
  21669. + return MV_NOT_READY;
  21670. + }
  21671. +#endif /* CESA_DEBUG */
  21672. +
  21673. + cesaStats.readyCount++;
  21674. +
  21675. + pReq = pCesaReqProcess;
  21676. + pSA = &pCesaSAD[pReq->pCmd->sessionId];
  21677. +
  21678. + pResult->retCode = MV_OK;
  21679. + if(pReq->fragMode != MV_CESA_FRAG_NONE)
  21680. + {
  21681. + MV_U8* pNewDigest;
  21682. + int frag;
  21683. +#if (MV_CESA_VERSION >= 3)
  21684. + pReq->frags.nextFrag = 1;
  21685. + while(pReq->frags.nextFrag <= pReq->frags.numFrag) {
  21686. +#endif
  21687. + frag = (pReq->frags.nextFrag - 1);
  21688. +
  21689. + /* Restore DMA descriptor list */
  21690. + pReq->dma[frag].pDmaLast->phyNextDescPtr =
  21691. + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pReq->dma[frag].pDmaLast[1]));
  21692. + pReq->dma[frag].pDmaLast = NULL;
  21693. +
  21694. + /* Special processing for finished fragmented request */
  21695. + if(pReq->frags.nextFrag >= pReq->frags.numFrag)
  21696. + {
  21697. + mvCesaMbufCacheUnmap(pReq->pCmd->pDst, 0, pReq->pCmd->pDst->mbufSize);
  21698. +
  21699. + /* Fragmented packet is ready */
  21700. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  21701. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  21702. + {
  21703. + int macDataSize = pReq->pCmd->macLength - pReq->frags.macSize;
  21704. +
  21705. + if(macDataSize != 0)
  21706. + {
  21707. + /* Calculate all other blocks by SW */
  21708. + mvCesaFragAuthComplete(pReq, pSA, macDataSize);
  21709. + }
  21710. +
  21711. + /* Copy new digest from SRAM to the Destination buffer */
  21712. + pNewDigest = cesaSramVirtPtr->buf + pReq->frags.newDigestOffset;
  21713. + status = mvCesaCopyToMbuf(pNewDigest, pReq->pCmd->pDst,
  21714. + pReq->pCmd->digestOffset, pSA->digestSize);
  21715. +
  21716. + /* For decryption: Compare new digest value with original one */
  21717. + if((pSA->config & MV_CESA_DIRECTION_MASK) ==
  21718. + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))
  21719. + {
  21720. + if( memcmp(pNewDigest, pReq->frags.orgDigest, pSA->digestSize) != 0)
  21721. + {
  21722. +/*
  21723. + mvOsPrintf("Digest error: chan=%d, newDigest=%p, orgDigest=%p, status = 0x%x\n",
  21724. + chan, pNewDigest, pReq->frags.orgDigest, MV_REG_READ(MV_CESA_STATUS_REG));
  21725. +*/
  21726. + /* Signiture verification is failed */
  21727. + pResult->retCode = MV_FAIL;
  21728. + }
  21729. + }
  21730. + }
  21731. + readyStatus = MV_OK;
  21732. + }
  21733. +#if (MV_CESA_VERSION >= 3)
  21734. + pReq->frags.nextFrag++;
  21735. + }
  21736. +#endif
  21737. + }
  21738. + else
  21739. + {
  21740. + mvCesaMbufCacheUnmap(pReq->pCmd->pDst, 0, pReq->pCmd->pDst->mbufSize);
  21741. +
  21742. + /* Restore DMA descriptor list */
  21743. + pReq->dma[0].pDmaLast->phyNextDescPtr =
  21744. + MV_32BIT_LE(mvCesaVirtToPhys(&pReq->dmaDescBuf, &pReq->dma[0].pDmaLast[1]));
  21745. + pReq->dma[0].pDmaLast = NULL;
  21746. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  21747. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) ) &&
  21748. + ((pSA->config & MV_CESA_DIRECTION_MASK) ==
  21749. + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT)) )
  21750. + {
  21751. + /* For AUTH on decode : Check Digest result in Status register */
  21752. + statusReg = MV_REG_READ(MV_CESA_STATUS_REG);
  21753. + if(statusReg & MV_CESA_STATUS_DIGEST_ERR_MASK)
  21754. + {
  21755. +/*
  21756. + mvOsPrintf("Digest error: chan=%d, status = 0x%x\n",
  21757. + chan, statusReg);
  21758. +*/
  21759. + /* Signiture verification is failed */
  21760. + pResult->retCode = MV_FAIL;
  21761. + }
  21762. + }
  21763. + readyStatus = MV_OK;
  21764. + }
  21765. +
  21766. + if(readyStatus == MV_OK)
  21767. + {
  21768. + /* If Request is ready - Prepare pResult structure */
  21769. + pResult->pReqPrv = pReq->pCmd->pReqPrv;
  21770. + pResult->sessionId = pReq->pCmd->sessionId;
  21771. +
  21772. + pReq->state = MV_CESA_IDLE;
  21773. + pCesaReqProcess = MV_CESA_REQ_NEXT_PTR(pReq);
  21774. + cesaReqResources++;
  21775. +
  21776. + if(pSA->ctrMode)
  21777. + {
  21778. + /* For AES CTR mode - complete processing and free allocated resources */
  21779. + mvCesaCtrModeComplete(pReq->pOrgCmd, pReq->pCmd);
  21780. + mvCesaCtrModeFinish(pReq->pCmd);
  21781. + pReq->pOrgCmd = NULL;
  21782. + }
  21783. + }
  21784. +
  21785. +#if (MV_CESA_VERSION < 3)
  21786. + if(pCesaReqProcess->state == MV_CESA_PROCESS)
  21787. + {
  21788. + /* Start request Process */
  21789. + mvCesaReqProcessStart(pCesaReqProcess);
  21790. + if(readyStatus == MV_NOT_READY)
  21791. + readyStatus = MV_BUSY;
  21792. + }
  21793. + else if(pCesaReqProcess != pCesaReqEmpty)
  21794. + {
  21795. + /* Start process new request from the queue */
  21796. + mvCesaReqProcessStart(pCesaReqProcess);
  21797. + }
  21798. +#endif
  21799. + return readyStatus;
  21800. +}
  21801. +
  21802. +/***************** Functions to work with CESA_MBUF structure ******************/
  21803. +
  21804. +/*******************************************************************************
  21805. +* mvCesaMbufOffset - Locate offset in the Mbuf structure
  21806. +*
  21807. +* DESCRIPTION:
  21808. +* This function locates offset inside Multi-Bufeer structure.
  21809. +* It get fragment number and place in the fragment where the offset
  21810. +* is located.
  21811. +*
  21812. +*
  21813. +* INPUT:
  21814. +* MV_CESA_MBUF* pMbuf - Pointer to multi-buffer structure
  21815. +* int offset - Offset from the beginning of the data presented by
  21816. +* the Mbuf structure.
  21817. +*
  21818. +* OUTPUT:
  21819. +* int* pBufOffset - Offset from the beginning of the fragment where
  21820. +* the offset is located.
  21821. +*
  21822. +* RETURN:
  21823. +* int - Number of fragment, where the offset is located\
  21824. +*
  21825. +*******************************************************************************/
  21826. +int mvCesaMbufOffset(MV_CESA_MBUF* pMbuf, int offset, int* pBufOffset)
  21827. +{
  21828. + int frag = 0;
  21829. +
  21830. + while(offset > 0)
  21831. + {
  21832. + if(frag >= pMbuf->numFrags)
  21833. + {
  21834. + mvOsPrintf("mvCesaMbufOffset: Error: frag (%d) > numFrags (%d)\n",
  21835. + frag, pMbuf->numFrags);
  21836. + return MV_INVALID;
  21837. + }
  21838. + if(offset < pMbuf->pFrags[frag].bufSize)
  21839. + {
  21840. + break;
  21841. + }
  21842. + offset -= pMbuf->pFrags[frag].bufSize;
  21843. + frag++;
  21844. + }
  21845. + if(pBufOffset != NULL)
  21846. + *pBufOffset = offset;
  21847. +
  21848. + return frag;
  21849. +}
  21850. +
  21851. +/*******************************************************************************
  21852. +* mvCesaCopyFromMbuf - Copy data from the Mbuf structure to continuous buffer
  21853. +*
  21854. +* DESCRIPTION:
  21855. +*
  21856. +*
  21857. +* INPUT:
  21858. +* MV_U8* pDstBuf - Pointer to continuous buffer, where data is
  21859. +* copied to.
  21860. +* MV_CESA_MBUF* pSrcMbuf - Pointer to multi-buffer structure where data is
  21861. +* copied from.
  21862. +* int offset - Offset in the Mbuf structure where located first
  21863. +* byte of data should be copied.
  21864. +* int size - Size of data should be copied
  21865. +*
  21866. +* RETURN:
  21867. +* MV_OK - Success, all data is copied successfully.
  21868. +* MV_OUT_OF_RANGE - Failed, offset is out of Multi-buffer data range.
  21869. +* No data is copied.
  21870. +* MV_EMPTY - Multi-buffer structure has not enough data to copy
  21871. +* Data from the offset to end of Mbuf data is copied.
  21872. +*
  21873. +*******************************************************************************/
  21874. +MV_STATUS mvCesaCopyFromMbuf(MV_U8* pDstBuf, MV_CESA_MBUF* pSrcMbuf,
  21875. + int offset, int size)
  21876. +{
  21877. + int frag, fragOffset, bufSize;
  21878. + MV_U8* pBuf;
  21879. +
  21880. + if(size == 0)
  21881. + return MV_OK;
  21882. +
  21883. + frag = mvCesaMbufOffset(pSrcMbuf, offset, &fragOffset);
  21884. + if(frag == MV_INVALID)
  21885. + {
  21886. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  21887. + return MV_OUT_OF_RANGE;
  21888. + }
  21889. +
  21890. + bufSize = pSrcMbuf->pFrags[frag].bufSize - fragOffset;
  21891. + pBuf = pSrcMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  21892. + while(MV_TRUE)
  21893. + {
  21894. + if(size <= bufSize)
  21895. + {
  21896. + memcpy(pDstBuf, pBuf, size);
  21897. + return MV_OK;
  21898. + }
  21899. + memcpy(pDstBuf, pBuf, bufSize);
  21900. + size -= bufSize;
  21901. + frag++;
  21902. + pDstBuf += bufSize;
  21903. + if(frag >= pSrcMbuf->numFrags)
  21904. + break;
  21905. +
  21906. + bufSize = pSrcMbuf->pFrags[frag].bufSize;
  21907. + pBuf = pSrcMbuf->pFrags[frag].bufVirtPtr;
  21908. + }
  21909. + mvOsPrintf("mvCesaCopyFromMbuf: Mbuf is EMPTY - %d bytes isn't copied\n",
  21910. + size);
  21911. + return MV_EMPTY;
  21912. +}
  21913. +
  21914. +/*******************************************************************************
  21915. +* mvCesaCopyToMbuf - Copy data from continuous buffer to the Mbuf structure
  21916. +*
  21917. +* DESCRIPTION:
  21918. +*
  21919. +*
  21920. +* INPUT:
  21921. +* MV_U8* pSrcBuf - Pointer to continuous buffer, where data is
  21922. +* copied from.
  21923. +* MV_CESA_MBUF* pDstMbuf - Pointer to multi-buffer structure where data is
  21924. +* copied to.
  21925. +* int offset - Offset in the Mbuf structure where located first
  21926. +* byte of data should be copied.
  21927. +* int size - Size of data should be copied
  21928. +*
  21929. +* RETURN:
  21930. +* MV_OK - Success, all data is copied successfully.
  21931. +* MV_OUT_OF_RANGE - Failed, offset is out of Multi-buffer data range.
  21932. +* No data is copied.
  21933. +* MV_FULL - Multi-buffer structure has not enough place to copy
  21934. +* all data. Data from the offset to end of Mbuf data
  21935. +* is copied.
  21936. +*
  21937. +*******************************************************************************/
  21938. +MV_STATUS mvCesaCopyToMbuf(MV_U8* pSrcBuf, MV_CESA_MBUF* pDstMbuf,
  21939. + int offset, int size)
  21940. +{
  21941. + int frag, fragOffset, bufSize;
  21942. + MV_U8* pBuf;
  21943. +
  21944. + if(size == 0)
  21945. + return MV_OK;
  21946. +
  21947. + frag = mvCesaMbufOffset(pDstMbuf, offset, &fragOffset);
  21948. + if(frag == MV_INVALID)
  21949. + {
  21950. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  21951. + return MV_OUT_OF_RANGE;
  21952. + }
  21953. +
  21954. + bufSize = pDstMbuf->pFrags[frag].bufSize - fragOffset;
  21955. + pBuf = pDstMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  21956. + while(MV_TRUE)
  21957. + {
  21958. + if(size <= bufSize)
  21959. + {
  21960. + memcpy(pBuf, pSrcBuf, size);
  21961. + return MV_OK;
  21962. + }
  21963. + memcpy(pBuf, pSrcBuf, bufSize);
  21964. + size -= bufSize;
  21965. + frag++;
  21966. + pSrcBuf += bufSize;
  21967. + if(frag >= pDstMbuf->numFrags)
  21968. + break;
  21969. +
  21970. + bufSize = pDstMbuf->pFrags[frag].bufSize;
  21971. + pBuf = pDstMbuf->pFrags[frag].bufVirtPtr;
  21972. + }
  21973. + mvOsPrintf("mvCesaCopyToMbuf: Mbuf is FULL - %d bytes isn't copied\n",
  21974. + size);
  21975. + return MV_FULL;
  21976. +}
  21977. +
  21978. +/*******************************************************************************
  21979. +* mvCesaMbufCopy - Copy data from one Mbuf structure to the other Mbuf structure
  21980. +*
  21981. +* DESCRIPTION:
  21982. +*
  21983. +*
  21984. +* INPUT:
  21985. +*
  21986. +* MV_CESA_MBUF* pDstMbuf - Pointer to multi-buffer structure where data is
  21987. +* copied to.
  21988. +* int dstMbufOffset - Offset in the dstMbuf structure where first byte
  21989. +* of data should be copied to.
  21990. +* MV_CESA_MBUF* pSrcMbuf - Pointer to multi-buffer structure where data is
  21991. +* copied from.
  21992. +* int srcMbufOffset - Offset in the srcMbuf structure where first byte
  21993. +* of data should be copied from.
  21994. +* int size - Size of data should be copied
  21995. +*
  21996. +* RETURN:
  21997. +* MV_OK - Success, all data is copied successfully.
  21998. +* MV_OUT_OF_RANGE - Failed, srcMbufOffset or dstMbufOffset is out of
  21999. +* srcMbuf or dstMbuf structure correspondently.
  22000. +* No data is copied.
  22001. +* MV_BAD_SIZE - srcMbuf or dstMbuf structure is too small to copy
  22002. +* all data. Partial data is copied
  22003. +*
  22004. +*******************************************************************************/
  22005. +MV_STATUS mvCesaMbufCopy(MV_CESA_MBUF* pMbufDst, int dstMbufOffset,
  22006. + MV_CESA_MBUF* pMbufSrc, int srcMbufOffset, int size)
  22007. +{
  22008. + int srcFrag, dstFrag, srcSize, dstSize, srcOffset, dstOffset;
  22009. + int copySize;
  22010. + MV_U8 *pSrc, *pDst;
  22011. +
  22012. + if(size == 0)
  22013. + return MV_OK;
  22014. +
  22015. + srcFrag = mvCesaMbufOffset(pMbufSrc, srcMbufOffset, &srcOffset);
  22016. + if(srcFrag == MV_INVALID)
  22017. + {
  22018. + mvOsPrintf("CESA srcMbuf Error: offset (%d) out of range\n", srcMbufOffset);
  22019. + return MV_OUT_OF_RANGE;
  22020. + }
  22021. + pSrc = pMbufSrc->pFrags[srcFrag].bufVirtPtr + srcOffset;
  22022. + srcSize = pMbufSrc->pFrags[srcFrag].bufSize - srcOffset;
  22023. +
  22024. + dstFrag = mvCesaMbufOffset(pMbufDst, dstMbufOffset, &dstOffset);
  22025. + if(dstFrag == MV_INVALID)
  22026. + {
  22027. + mvOsPrintf("CESA dstMbuf Error: offset (%d) out of range\n", dstMbufOffset);
  22028. + return MV_OUT_OF_RANGE;
  22029. + }
  22030. + pDst = pMbufDst->pFrags[dstFrag].bufVirtPtr + dstOffset;
  22031. + dstSize = pMbufDst->pFrags[dstFrag].bufSize - dstOffset;
  22032. +
  22033. + while(size > 0)
  22034. + {
  22035. + copySize = MV_MIN(srcSize, dstSize);
  22036. + if(size <= copySize)
  22037. + {
  22038. + memcpy(pDst, pSrc, size);
  22039. + return MV_OK;
  22040. + }
  22041. + memcpy(pDst, pSrc, copySize);
  22042. + size -= copySize;
  22043. + srcSize -= copySize;
  22044. + dstSize -= copySize;
  22045. +
  22046. + if(srcSize == 0)
  22047. + {
  22048. + srcFrag++;
  22049. + if(srcFrag >= pMbufSrc->numFrags)
  22050. + break;
  22051. +
  22052. + pSrc = pMbufSrc->pFrags[srcFrag].bufVirtPtr;
  22053. + srcSize = pMbufSrc->pFrags[srcFrag].bufSize;
  22054. + }
  22055. +
  22056. + if(dstSize == 0)
  22057. + {
  22058. + dstFrag++;
  22059. + if(dstFrag >= pMbufDst->numFrags)
  22060. + break;
  22061. +
  22062. + pDst = pMbufDst->pFrags[dstFrag].bufVirtPtr;
  22063. + dstSize = pMbufDst->pFrags[dstFrag].bufSize;
  22064. + }
  22065. + }
  22066. + mvOsPrintf("mvCesaMbufCopy: BAD size - %d bytes isn't copied\n",
  22067. + size);
  22068. +
  22069. + return MV_BAD_SIZE;
  22070. +}
  22071. +
  22072. +static MV_STATUS mvCesaMbufCacheUnmap(MV_CESA_MBUF* pMbuf, int offset, int size)
  22073. +{
  22074. + int frag, fragOffset, bufSize;
  22075. + MV_U8* pBuf;
  22076. +
  22077. + if(size == 0)
  22078. + return MV_OK;
  22079. +
  22080. + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
  22081. + if(frag == MV_INVALID)
  22082. + {
  22083. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  22084. + return MV_OUT_OF_RANGE;
  22085. + }
  22086. +
  22087. + bufSize = pMbuf->pFrags[frag].bufSize - fragOffset;
  22088. + pBuf = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  22089. + while(MV_TRUE)
  22090. + {
  22091. + if(size <= bufSize)
  22092. + {
  22093. + mvOsCacheUnmap(NULL, mvOsIoVirtToPhy(NULL, pBuf), size);
  22094. + return MV_OK;
  22095. + }
  22096. +
  22097. + mvOsCacheUnmap(NULL, mvOsIoVirtToPhy(NULL, pBuf), bufSize);
  22098. + size -= bufSize;
  22099. + frag++;
  22100. + if(frag >= pMbuf->numFrags)
  22101. + break;
  22102. +
  22103. + bufSize = pMbuf->pFrags[frag].bufSize;
  22104. + pBuf = pMbuf->pFrags[frag].bufVirtPtr;
  22105. + }
  22106. + mvOsPrintf("%s: Mbuf is FULL - %d bytes isn't Unmapped\n",
  22107. + __FUNCTION__, size);
  22108. + return MV_FULL;
  22109. +}
  22110. +
  22111. +
  22112. +/*************************************** Local Functions ******************************/
  22113. +
  22114. +/*******************************************************************************
  22115. +* mvCesaFragReqProcess - Process fragmented request
  22116. +*
  22117. +* DESCRIPTION:
  22118. +* This function processes a fragment of fragmented request (First, Middle or Last)
  22119. +*
  22120. +*
  22121. +* INPUT:
  22122. +* MV_CESA_REQ* pReq - Pointer to the request in the request queue.
  22123. +*
  22124. +* RETURN:
  22125. +* MV_OK - The fragment is successfully passed to HW for processing.
  22126. +* MV_TERMINATE - Means, that HW finished its work on this packet and no more
  22127. +* interrupts will be generated for this request.
  22128. +* Function mvCesaReadyGet() must be called to complete request
  22129. +* processing and get request result.
  22130. +*
  22131. +*******************************************************************************/
  22132. +static MV_STATUS mvCesaFragReqProcess(MV_CESA_REQ* pReq, MV_U8 frag)
  22133. +{
  22134. + int i, copySize, cryptoDataSize, macDataSize, sid;
  22135. + int cryptoIvOffset, digestOffset;
  22136. + MV_U32 config;
  22137. + MV_CESA_COMMAND* pCmd = pReq->pCmd;
  22138. + MV_CESA_SA* pSA;
  22139. + MV_CESA_MBUF* pMbuf;
  22140. + MV_DMA_DESC* pDmaDesc = pReq->dma[frag].pDmaFirst;
  22141. + MV_U8* pSramBuf = cesaSramVirtPtr->buf;
  22142. + int macTotalLen = 0;
  22143. + int fixOffset, cryptoOffset, macOffset;
  22144. +
  22145. + cesaStats.fragCount++;
  22146. +
  22147. + sid = pReq->pCmd->sessionId;
  22148. +
  22149. + pSA = &pCesaSAD[sid];
  22150. +
  22151. + cryptoIvOffset = digestOffset = 0;
  22152. + i = macDataSize = 0;
  22153. + cryptoDataSize = 0;
  22154. +
  22155. + /* First fragment processing */
  22156. + if(pReq->fragMode == MV_CESA_FRAG_FIRST)
  22157. + {
  22158. + /* pReq->frags monitors processing of fragmented request between fragments */
  22159. + pReq->frags.bufOffset = 0;
  22160. + pReq->frags.cryptoSize = 0;
  22161. + pReq->frags.macSize = 0;
  22162. +
  22163. + config = pSA->config | (MV_CESA_FRAG_FIRST << MV_CESA_FRAG_MODE_OFFSET);
  22164. +
  22165. + /* fixOffset can be not equal to zero only for FIRST fragment */
  22166. + fixOffset = pReq->fixOffset;
  22167. + /* For FIRST fragment crypto and mac offsets are taken from pCmd */
  22168. + cryptoOffset = pCmd->cryptoOffset;
  22169. + macOffset = pCmd->macOffset;
  22170. +
  22171. + copySize = sizeof(cesaSramVirtPtr->buf) - pReq->fixOffset;
  22172. +
  22173. + /* Find fragment size: Must meet all requirements for CRYPTO and MAC
  22174. + * cryptoDataSize - size of data will be encrypted/decrypted in this fragment
  22175. + * macDataSize - size of data will be signed/verified in this fragment
  22176. + * copySize - size of data will be copied from srcMbuf to SRAM and
  22177. + * back to dstMbuf for this fragment
  22178. + */
  22179. + mvCesaFragSizeFind(pSA, pReq, cryptoOffset, macOffset,
  22180. + &copySize, &cryptoDataSize, &macDataSize);
  22181. +
  22182. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  22183. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET))
  22184. + {
  22185. + /* CryptoIV special processing */
  22186. + if( (pSA->config & MV_CESA_CRYPTO_MODE_MASK) ==
  22187. + (MV_CESA_CRYPTO_CBC << MV_CESA_CRYPTO_MODE_BIT) )
  22188. + {
  22189. + /* In CBC mode for encode direction when IV from user */
  22190. + if( (pCmd->ivFromUser) &&
  22191. + ((pSA->config & MV_CESA_DIRECTION_MASK) ==
  22192. + (MV_CESA_DIR_ENCODE << MV_CESA_DIRECTION_BIT)) )
  22193. + {
  22194. +
  22195. + /* For Crypto Encode in CBC mode HW always takes IV from SRAM IVPointer,
  22196. + * (not from IVBufPointer). So when ivFromUser==1, we should copy IV from user place
  22197. + * in the buffer to SRAM IVPointer
  22198. + */
  22199. + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],
  22200. + MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
  22201. + }
  22202. +
  22203. + /* Special processing when IV is not located in the first fragment */
  22204. + if(pCmd->ivOffset > (copySize - pSA->cryptoIvSize))
  22205. + {
  22206. + /* Prepare dummy place for cryptoIV in SRAM */
  22207. + cryptoIvOffset = cesaSramVirtPtr->tempCryptoIV - mvCesaSramAddrGet();
  22208. +
  22209. + /* For Decryption: Copy IV value from pCmd->ivOffset to Special SRAM place */
  22210. + if((pSA->config & MV_CESA_DIRECTION_MASK) ==
  22211. + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))
  22212. + {
  22213. + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->tempCryptoIV, &pDmaDesc[i],
  22214. + MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
  22215. + }
  22216. + else
  22217. + {
  22218. + /* For Encryption when IV is NOT from User: */
  22219. + /* Copy IV from SRAM to buffer (pCmd->ivOffset) */
  22220. + if(pCmd->ivFromUser == 0)
  22221. + {
  22222. + /* copy IV value from cryptoIV to Buffer (pCmd->ivOffset) */
  22223. + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],
  22224. + MV_TRUE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
  22225. + }
  22226. + }
  22227. + }
  22228. + else
  22229. + {
  22230. + cryptoIvOffset = pCmd->ivOffset;
  22231. + }
  22232. + }
  22233. + }
  22234. +
  22235. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  22236. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  22237. + {
  22238. + /* MAC digest special processing on Decode direction */
  22239. + if((pSA->config & MV_CESA_DIRECTION_MASK) ==
  22240. + (MV_CESA_DIR_DECODE << MV_CESA_DIRECTION_BIT))
  22241. + {
  22242. + /* Save digest from pCmd->digestOffset */
  22243. + mvCesaCopyFromMbuf(pReq->frags.orgDigest,
  22244. + pCmd->pSrc, pCmd->digestOffset, pSA->digestSize);
  22245. +
  22246. + /* If pCmd->digestOffset is not located on the first */
  22247. + if(pCmd->digestOffset > (copySize - pSA->digestSize))
  22248. + {
  22249. + MV_U8 digestZero[MV_CESA_MAX_DIGEST_SIZE];
  22250. +
  22251. + /* Set zeros to pCmd->digestOffset (DRAM) */
  22252. + memset(digestZero, 0, MV_CESA_MAX_DIGEST_SIZE);
  22253. + mvCesaCopyToMbuf(digestZero, pCmd->pSrc, pCmd->digestOffset, pSA->digestSize);
  22254. +
  22255. + /* Prepare dummy place for digest in SRAM */
  22256. + digestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();
  22257. + }
  22258. + else
  22259. + {
  22260. + digestOffset = pCmd->digestOffset;
  22261. + }
  22262. + }
  22263. + }
  22264. + /* Update SA in SRAM */
  22265. + if(cesaLastSid != sid)
  22266. + {
  22267. + mvCesaSramSaUpdate(sid, &pDmaDesc[i]);
  22268. + i++;
  22269. + }
  22270. +
  22271. + pReq->fragMode = MV_CESA_FRAG_MIDDLE;
  22272. + }
  22273. + else
  22274. + {
  22275. + /* Continue fragment */
  22276. + fixOffset = 0;
  22277. + cryptoOffset = 0;
  22278. + macOffset = 0;
  22279. + if( (pCmd->pSrc->mbufSize - pReq->frags.bufOffset) <= sizeof(cesaSramVirtPtr->buf))
  22280. + {
  22281. + /* Last fragment */
  22282. + config = pSA->config | (MV_CESA_FRAG_LAST << MV_CESA_FRAG_MODE_OFFSET);
  22283. + pReq->fragMode = MV_CESA_FRAG_LAST;
  22284. + copySize = pCmd->pSrc->mbufSize - pReq->frags.bufOffset;
  22285. +
  22286. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  22287. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  22288. + {
  22289. + macDataSize = pCmd->macLength - pReq->frags.macSize;
  22290. +
  22291. + /* If pCmd->digestOffset is not located on last fragment */
  22292. + if(pCmd->digestOffset < pReq->frags.bufOffset)
  22293. + {
  22294. + /* Prepare dummy place for digest in SRAM */
  22295. + digestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();
  22296. + }
  22297. + else
  22298. + {
  22299. + digestOffset = pCmd->digestOffset - pReq->frags.bufOffset;
  22300. + }
  22301. + pReq->frags.newDigestOffset = digestOffset;
  22302. + macTotalLen = pCmd->macLength;
  22303. +
  22304. + /* HW can't calculate the Digest correctly for fragmented packets
  22305. + * in the following cases:
  22306. + * - MV88F5182 ||
  22307. + * - MV88F5181L when total macLength more that 16 Kbytes ||
  22308. + * - total macLength more that 64 Kbytes
  22309. + */
  22310. + if( (mvCtrlModelGet() == MV_5182_DEV_ID) ||
  22311. + ( (mvCtrlModelGet() == MV_5181_DEV_ID) &&
  22312. + (mvCtrlRevGet() >= MV_5181L_A0_REV) &&
  22313. + (pCmd->macLength >= (1 << 14)) ) )
  22314. + {
  22315. + return MV_TERMINATE;
  22316. + }
  22317. + }
  22318. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  22319. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )
  22320. + {
  22321. + cryptoDataSize = pCmd->cryptoLength - pReq->frags.cryptoSize;
  22322. + }
  22323. +
  22324. + /* cryptoIvOffset - don't care */
  22325. + }
  22326. + else
  22327. + {
  22328. + /* WA for MV88F5182 SHA1 and MD5 fragmentation mode */
  22329. + if( (mvCtrlModelGet() == MV_5182_DEV_ID) &&
  22330. + (((pSA->config & MV_CESA_MAC_MODE_MASK) ==
  22331. + (MV_CESA_MAC_MD5 << MV_CESA_MAC_MODE_OFFSET)) ||
  22332. + ((pSA->config & MV_CESA_MAC_MODE_MASK) ==
  22333. + (MV_CESA_MAC_SHA1 << MV_CESA_MAC_MODE_OFFSET))) )
  22334. + {
  22335. + pReq->frags.newDigestOffset = cesaSramVirtPtr->tempDigest - mvCesaSramAddrGet();
  22336. + pReq->fragMode = MV_CESA_FRAG_LAST;
  22337. +
  22338. + return MV_TERMINATE;
  22339. + }
  22340. + /* Middle fragment */
  22341. + config = pSA->config | (MV_CESA_FRAG_MIDDLE << MV_CESA_FRAG_MODE_OFFSET);
  22342. + copySize = sizeof(cesaSramVirtPtr->buf);
  22343. + /* digestOffset and cryptoIvOffset - don't care */
  22344. +
  22345. + /* Find fragment size */
  22346. + mvCesaFragSizeFind(pSA, pReq, cryptoOffset, macOffset,
  22347. + &copySize, &cryptoDataSize, &macDataSize);
  22348. + }
  22349. + }
  22350. + /********* Prepare DMA descriptors to copy from pSrc to SRAM *********/
  22351. + pMbuf = pCmd->pSrc;
  22352. + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
  22353. + MV_FALSE, pReq->frags.bufOffset, copySize, pCmd->skipFlush);
  22354. +
  22355. + /* Prepare CESA descriptor to copy from DRAM to SRAM by DMA */
  22356. + mvCesaSramDescrBuild(config, frag,
  22357. + cryptoOffset + fixOffset, cryptoIvOffset + fixOffset,
  22358. + cryptoDataSize, macOffset + fixOffset,
  22359. + digestOffset + fixOffset, macDataSize, macTotalLen,
  22360. + pReq, &pDmaDesc[i]);
  22361. + i++;
  22362. +
  22363. + /* Add special descriptor Ownership for CPU */
  22364. + pDmaDesc[i].byteCnt = 0;
  22365. + pDmaDesc[i].phySrcAdd = 0;
  22366. + pDmaDesc[i].phyDestAdd = 0;
  22367. + i++;
  22368. +
  22369. + /********* Prepare DMA descriptors to copy from SRAM to pDst *********/
  22370. + pMbuf = pCmd->pDst;
  22371. + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
  22372. + MV_TRUE, pReq->frags.bufOffset, copySize, pCmd->skipFlush);
  22373. +
  22374. + /* Next field of Last DMA descriptor must be NULL */
  22375. + pDmaDesc[i-1].phyNextDescPtr = 0;
  22376. + pReq->dma[frag].pDmaLast = &pDmaDesc[i-1];
  22377. + mvOsCacheFlush(NULL, pReq->dma[frag].pDmaFirst,
  22378. + i*sizeof(MV_DMA_DESC));
  22379. +
  22380. + /*mvCesaDebugDescriptor(&cesaSramVirtPtr->desc[frag]);*/
  22381. +
  22382. + pReq->frags.bufOffset += copySize;
  22383. + pReq->frags.cryptoSize += cryptoDataSize;
  22384. + pReq->frags.macSize += macDataSize;
  22385. +
  22386. + return MV_OK;
  22387. +}
  22388. +
  22389. +
  22390. +/*******************************************************************************
  22391. +* mvCesaReqProcess - Process regular (Non-fragmented) request
  22392. +*
  22393. +* DESCRIPTION:
  22394. +* This function processes the whole (not fragmented) request
  22395. +*
  22396. +* INPUT:
  22397. +* MV_CESA_REQ* pReq - Pointer to the request in the request queue.
  22398. +*
  22399. +* RETURN:
  22400. +* MV_OK - The request is successfully passed to HW for processing.
  22401. +* Other - Failure. The request will not be processed
  22402. +*
  22403. +*******************************************************************************/
  22404. +static MV_STATUS mvCesaReqProcess(MV_CESA_REQ* pReq)
  22405. +{
  22406. + MV_CESA_MBUF *pMbuf;
  22407. + MV_DMA_DESC *pDmaDesc;
  22408. + MV_U8 *pSramBuf;
  22409. + int sid, i, fixOffset;
  22410. + MV_CESA_SA *pSA;
  22411. + MV_CESA_COMMAND *pCmd = pReq->pCmd;
  22412. +
  22413. + cesaStats.procCount++;
  22414. +
  22415. + sid = pCmd->sessionId;
  22416. + pSA = &pCesaSAD[sid];
  22417. + pDmaDesc = pReq->dma[0].pDmaFirst;
  22418. + pSramBuf = cesaSramVirtPtr->buf;
  22419. + fixOffset = pReq->fixOffset;
  22420. +
  22421. +/*
  22422. + mvOsPrintf("mvCesaReqProcess: sid=%d, pSA=%p, pDmaDesc=%p, pSramBuf=%p\n",
  22423. + sid, pSA, pDmaDesc, pSramBuf);
  22424. +*/
  22425. + i = 0;
  22426. +
  22427. + /* Crypto IV Special processing in CBC mode for Encryption direction */
  22428. + if( ((pSA->config & MV_CESA_OPERATION_MASK) != (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) &&
  22429. + ((pSA->config & MV_CESA_CRYPTO_MODE_MASK) == (MV_CESA_CRYPTO_CBC << MV_CESA_CRYPTO_MODE_BIT)) &&
  22430. + ((pSA->config & MV_CESA_DIRECTION_MASK) == (MV_CESA_DIR_ENCODE << MV_CESA_DIRECTION_BIT)) &&
  22431. + (pCmd->ivFromUser) )
  22432. + {
  22433. + /* For Crypto Encode in CBC mode HW always takes IV from SRAM IVPointer,
  22434. + * (not from IVBufPointer). So when ivFromUser==1, we should copy IV from user place
  22435. + * in the buffer to SRAM IVPointer
  22436. + */
  22437. + i += mvCesaDmaCopyPrepare(pCmd->pSrc, cesaSramVirtPtr->cryptoIV, &pDmaDesc[i],
  22438. + MV_FALSE, pCmd->ivOffset, pSA->cryptoIvSize, pCmd->skipFlush);
  22439. + }
  22440. +
  22441. + /* Update SA in SRAM */
  22442. + if(cesaLastSid != sid)
  22443. + {
  22444. + mvCesaSramSaUpdate(sid, &pDmaDesc[i]);
  22445. + i++;
  22446. + }
  22447. +
  22448. + /********* Prepare DMA descriptors to copy from pSrc to SRAM *********/
  22449. + pMbuf = pCmd->pSrc;
  22450. + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
  22451. + MV_FALSE, 0, pMbuf->mbufSize, pCmd->skipFlush);
  22452. +
  22453. + /* Prepare Security Accelerator descriptor to SRAM words 0 - 7 */
  22454. + mvCesaSramDescrBuild(pSA->config, 0, pCmd->cryptoOffset + fixOffset,
  22455. + pCmd->ivOffset + fixOffset, pCmd->cryptoLength,
  22456. + pCmd->macOffset + fixOffset, pCmd->digestOffset + fixOffset,
  22457. + pCmd->macLength, pCmd->macLength, pReq, &pDmaDesc[i]);
  22458. + i++;
  22459. +
  22460. + /* Add special descriptor Ownership for CPU */
  22461. + pDmaDesc[i].byteCnt = 0;
  22462. + pDmaDesc[i].phySrcAdd = 0;
  22463. + pDmaDesc[i].phyDestAdd = 0;
  22464. + i++;
  22465. +
  22466. + /********* Prepare DMA descriptors to copy from SRAM to pDst *********/
  22467. + pMbuf = pCmd->pDst;
  22468. + i += mvCesaDmaCopyPrepare(pMbuf, pSramBuf + fixOffset, &pDmaDesc[i],
  22469. + MV_TRUE, 0, pMbuf->mbufSize, pCmd->skipFlush);
  22470. +
  22471. + /* Next field of Last DMA descriptor must be NULL */
  22472. + pDmaDesc[i-1].phyNextDescPtr = 0;
  22473. + pReq->dma[0].pDmaLast = &pDmaDesc[i-1];
  22474. + mvOsCacheFlush(NULL, pReq->dma[0].pDmaFirst, i*sizeof(MV_DMA_DESC));
  22475. +
  22476. + return MV_OK;
  22477. +}
  22478. +
  22479. +
  22480. +/*******************************************************************************
  22481. +* mvCesaSramDescrBuild - Set CESA descriptor in SRAM
  22482. +*
  22483. +* DESCRIPTION:
  22484. +* This function builds CESA descriptor in SRAM from all Command parameters
  22485. +*
  22486. +*
  22487. +* INPUT:
  22488. +* int chan - CESA channel uses the descriptor
  22489. +* MV_U32 config - 32 bits of WORD_0 in CESA descriptor structure
  22490. +* int cryptoOffset - Offset from the beginning of SRAM buffer where
  22491. +* data for encryption/decription is started.
  22492. +* int ivOffset - Offset of crypto IV from the SRAM base. Valid only
  22493. +* for first fragment.
  22494. +* int cryptoLength - Size (in bytes) of data for encryption/descryption
  22495. +* operation on this fragment.
  22496. +* int macOffset - Offset from the beginning of SRAM buffer where
  22497. +* data for Authentication is started
  22498. +* int digestOffset - Offset from the beginning of SRAM buffer where
  22499. +* digest is located. Valid for first and last fragments.
  22500. +* int macLength - Size (in bytes) of data for Authentication
  22501. +* operation on this fragment.
  22502. +* int macTotalLen - Toatl size (in bytes) of data for Authentication
  22503. +* operation on the whole request (packet). Valid for
  22504. +* last fragment only.
  22505. +*
  22506. +* RETURN: None
  22507. +*
  22508. +*******************************************************************************/
  22509. +static void mvCesaSramDescrBuild(MV_U32 config, int frag,
  22510. + int cryptoOffset, int ivOffset, int cryptoLength,
  22511. + int macOffset, int digestOffset, int macLength,
  22512. + int macTotalLen, MV_CESA_REQ* pReq, MV_DMA_DESC* pDmaDesc)
  22513. +{
  22514. + MV_CESA_DESC* pCesaDesc = &pReq->pCesaDesc[frag];
  22515. + MV_CESA_DESC* pSramDesc = pSramDesc = &cesaSramVirtPtr->desc;
  22516. + MV_U16 sramBufOffset = (MV_U16)((MV_U8*)cesaSramVirtPtr->buf - mvCesaSramAddrGet());
  22517. +
  22518. + pCesaDesc->config = MV_32BIT_LE(config);
  22519. +
  22520. + if( (config & MV_CESA_OPERATION_MASK) !=
  22521. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )
  22522. + {
  22523. + /* word 1 */
  22524. + pCesaDesc->cryptoSrcOffset = MV_16BIT_LE(sramBufOffset + cryptoOffset);
  22525. + pCesaDesc->cryptoDstOffset = MV_16BIT_LE(sramBufOffset + cryptoOffset);
  22526. + /* word 2 */
  22527. + pCesaDesc->cryptoDataLen = MV_16BIT_LE(cryptoLength);
  22528. + /* word 3 */
  22529. + pCesaDesc->cryptoKeyOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.cryptoKey -
  22530. + mvCesaSramAddrGet()));
  22531. + /* word 4 */
  22532. + pCesaDesc->cryptoIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->cryptoIV -
  22533. + mvCesaSramAddrGet()));
  22534. + pCesaDesc->cryptoIvBufOffset = MV_16BIT_LE(sramBufOffset + ivOffset);
  22535. + }
  22536. +
  22537. + if( (config & MV_CESA_OPERATION_MASK) !=
  22538. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  22539. + {
  22540. + /* word 5 */
  22541. + pCesaDesc->macSrcOffset = MV_16BIT_LE(sramBufOffset + macOffset);
  22542. + pCesaDesc->macTotalLen = MV_16BIT_LE(macTotalLen);
  22543. +
  22544. + /* word 6 */
  22545. + pCesaDesc->macDigestOffset = MV_16BIT_LE(sramBufOffset + digestOffset);
  22546. + pCesaDesc->macDataLen = MV_16BIT_LE(macLength);
  22547. +
  22548. + /* word 7 */
  22549. + pCesaDesc->macInnerIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.macInnerIV -
  22550. + mvCesaSramAddrGet()));
  22551. + pCesaDesc->macOuterIvOffset = MV_16BIT_LE((MV_U16)(cesaSramVirtPtr->sramSA.macOuterIV -
  22552. + mvCesaSramAddrGet()));
  22553. + }
  22554. + /* Prepare DMA descriptor to CESA descriptor from DRAM to SRAM */
  22555. + pDmaDesc->phySrcAdd = MV_32BIT_LE(mvCesaVirtToPhys(&pReq->cesaDescBuf, pCesaDesc));
  22556. + pDmaDesc->phyDestAdd = MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (MV_U8*)pSramDesc));
  22557. + pDmaDesc->byteCnt = MV_32BIT_LE(sizeof(MV_CESA_DESC) | BIT31);
  22558. +
  22559. + /* flush Source buffer */
  22560. + mvOsCacheFlush(NULL, pCesaDesc, sizeof(MV_CESA_DESC));
  22561. +}
  22562. +
  22563. +/*******************************************************************************
  22564. +* mvCesaSramSaUpdate - Move required SA information to SRAM if needed.
  22565. +*
  22566. +* DESCRIPTION:
  22567. +* Copy to SRAM values of the required SA.
  22568. +*
  22569. +*
  22570. +* INPUT:
  22571. +* short sid - Session ID needs SRAM Cache update
  22572. +* MV_DMA_DESC *pDmaDesc - Pointer to DMA descriptor used to
  22573. +* copy SA values from DRAM to SRAM.
  22574. +*
  22575. +* RETURN:
  22576. +* MV_OK - Cache entry for this SA copied to SRAM.
  22577. +* MV_NO_CHANGE - Cache entry for this SA already exist in SRAM
  22578. +*
  22579. +*******************************************************************************/
  22580. +static INLINE void mvCesaSramSaUpdate(short sid, MV_DMA_DESC *pDmaDesc)
  22581. +{
  22582. + MV_CESA_SA *pSA = &pCesaSAD[sid];
  22583. +
  22584. + /* Prepare DMA descriptor to Copy CACHE_SA from SA database in DRAM to SRAM */
  22585. + pDmaDesc->byteCnt = MV_32BIT_LE(sizeof(MV_CESA_SRAM_SA) | BIT31);
  22586. + pDmaDesc->phySrcAdd = MV_32BIT_LE(mvCesaVirtToPhys(&cesaSramSaBuf, pSA->pSramSA));
  22587. + pDmaDesc->phyDestAdd =
  22588. + MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (MV_U8*)&cesaSramVirtPtr->sramSA));
  22589. +
  22590. + /* Source buffer is already flushed during OpenSession*/
  22591. + /*mvOsCacheFlush(NULL, &pSA->sramSA, sizeof(MV_CESA_SRAM_SA));*/
  22592. +}
  22593. +
  22594. +/*******************************************************************************
  22595. +* mvCesaDmaCopyPrepare - prepare DMA descriptor list to copy data presented by
  22596. +* Mbuf structure from DRAM to SRAM
  22597. +*
  22598. +* DESCRIPTION:
  22599. +*
  22600. +*
  22601. +* INPUT:
  22602. +* MV_CESA_MBUF* pMbuf - pointer to Mbuf structure contains request
  22603. +* data in DRAM
  22604. +* MV_U8* pSramBuf - pointer to buffer in SRAM where data should
  22605. +* be copied to.
  22606. +* MV_DMA_DESC* pDmaDesc - pointer to first DMA descriptor for this copy.
  22607. +* The function set number of DMA descriptors needed
  22608. +* to copy the copySize bytes from Mbuf.
  22609. +* MV_BOOL isToMbuf - Copy direction.
  22610. +* MV_TRUE means copy from SRAM buffer to Mbuf in DRAM.
  22611. +* MV_FALSE means copy from Mbuf in DRAM to SRAM buffer.
  22612. +* int offset - Offset in the Mbuf structure that copy should be
  22613. +* started from.
  22614. +* int copySize - Size of data should be copied.
  22615. +*
  22616. +* RETURN:
  22617. +* int - number of DMA descriptors used for the copy.
  22618. +*
  22619. +*******************************************************************************/
  22620. +#ifndef MV_NETBSD
  22621. +static INLINE int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,
  22622. + MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,
  22623. + int offset, int copySize, MV_BOOL skipFlush)
  22624. +{
  22625. + int bufOffset, bufSize, size, frag, i;
  22626. + MV_U8* pBuf;
  22627. +
  22628. + i = 0;
  22629. +
  22630. + /* Calculate start place for copy: fragment number and offset in the fragment */
  22631. + frag = mvCesaMbufOffset(pMbuf, offset, &bufOffset);
  22632. + bufSize = pMbuf->pFrags[frag].bufSize - bufOffset;
  22633. + pBuf = pMbuf->pFrags[frag].bufVirtPtr + bufOffset;
  22634. +
  22635. + /* Size accumulate total copy size */
  22636. + size = 0;
  22637. +
  22638. + /* Create DMA lists to copy mBuf from pSrc to SRAM */
  22639. + while(size < copySize)
  22640. + {
  22641. + /* Find copy size for each DMA descriptor */
  22642. + bufSize = MV_MIN(bufSize, (copySize - size));
  22643. + pDmaDesc[i].byteCnt = MV_32BIT_LE(bufSize | BIT31);
  22644. + if(isToMbuf)
  22645. + {
  22646. + pDmaDesc[i].phyDestAdd = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));
  22647. + pDmaDesc[i].phySrcAdd =
  22648. + MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (pSramBuf + size)));
  22649. + /* invalidate the buffer */
  22650. + if(skipFlush == MV_FALSE)
  22651. + mvOsCacheInvalidate(NULL, pBuf, bufSize);
  22652. + }
  22653. + else
  22654. + {
  22655. + pDmaDesc[i].phySrcAdd = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));
  22656. + pDmaDesc[i].phyDestAdd =
  22657. + MV_32BIT_LE(mvCesaSramVirtToPhys(NULL, (pSramBuf + size)));
  22658. + /* flush the buffer */
  22659. + if(skipFlush == MV_FALSE)
  22660. + mvOsCacheFlush(NULL, pBuf, bufSize);
  22661. + }
  22662. +
  22663. + /* Count number of used DMA descriptors */
  22664. + i++;
  22665. + size += bufSize;
  22666. +
  22667. + /* go to next fragment in the Mbuf */
  22668. + frag++;
  22669. + pBuf = pMbuf->pFrags[frag].bufVirtPtr;
  22670. + bufSize = pMbuf->pFrags[frag].bufSize;
  22671. + }
  22672. + return i;
  22673. +}
  22674. +#else /* MV_NETBSD */
  22675. +static int mvCesaDmaCopyPrepare(MV_CESA_MBUF* pMbuf, MV_U8* pSramBuf,
  22676. + MV_DMA_DESC* pDmaDesc, MV_BOOL isToMbuf,
  22677. + int offset, int copySize, MV_BOOL skipFlush)
  22678. +{
  22679. + int bufOffset, bufSize, thisSize, size, frag, i;
  22680. + MV_ULONG bufPhys, sramPhys;
  22681. + MV_U8* pBuf;
  22682. +
  22683. + /*
  22684. + * Calculate start place for copy: fragment number and offset in
  22685. + * the fragment
  22686. + */
  22687. + frag = mvCesaMbufOffset(pMbuf, offset, &bufOffset);
  22688. +
  22689. + /*
  22690. + * Get SRAM physical address only once. We can update it in-place
  22691. + * as we build the descriptor chain.
  22692. + */
  22693. + sramPhys = mvCesaSramVirtToPhys(NULL, pSramBuf);
  22694. +
  22695. + /*
  22696. + * 'size' accumulates total copy size, 'i' counts desccriptors.
  22697. + */
  22698. + size = i = 0;
  22699. +
  22700. + /* Create DMA lists to copy mBuf from pSrc to SRAM */
  22701. + while (size < copySize) {
  22702. + /*
  22703. + * Calculate # of bytes to copy from the current fragment,
  22704. + * and the pointer to the start of data
  22705. + */
  22706. + bufSize = pMbuf->pFrags[frag].bufSize - bufOffset;
  22707. + pBuf = pMbuf->pFrags[frag].bufVirtPtr + bufOffset;
  22708. + bufOffset = 0; /* First frag may be non-zero */
  22709. + frag++;
  22710. +
  22711. + /*
  22712. + * As long as there is data in the current fragment...
  22713. + */
  22714. + while (bufSize > 0) {
  22715. + /*
  22716. + * Ensure we don't cross an MMU page boundary.
  22717. + * XXX: This is NetBSD-specific, but it is a
  22718. + * quick and dirty way to fix the problem.
  22719. + * A true HAL would rely on the OS-specific
  22720. + * driver to do this...
  22721. + */
  22722. + thisSize = PAGE_SIZE -
  22723. + (((MV_ULONG)pBuf) & (PAGE_SIZE - 1));
  22724. + thisSize = MV_MIN(bufSize, thisSize);
  22725. + /*
  22726. + * Make sure we don't copy more than requested
  22727. + */
  22728. + if (thisSize > (copySize - size)) {
  22729. + thisSize = copySize - size;
  22730. + bufSize = 0;
  22731. + }
  22732. +
  22733. + /*
  22734. + * Physicall address of this fragment
  22735. + */
  22736. + bufPhys = MV_32BIT_LE(mvOsIoVirtToPhy(NULL, pBuf));
  22737. +
  22738. + /*
  22739. + * Set up the descriptor
  22740. + */
  22741. + pDmaDesc[i].byteCnt = MV_32BIT_LE(thisSize | BIT31);
  22742. + if(isToMbuf) {
  22743. + pDmaDesc[i].phyDestAdd = bufPhys;
  22744. + pDmaDesc[i].phySrcAdd = MV_32BIT_LE(sramPhys);
  22745. + /* invalidate the buffer */
  22746. + if(skipFlush == MV_FALSE)
  22747. + mvOsCacheInvalidate(NULL, pBuf, thisSize);
  22748. + } else {
  22749. + pDmaDesc[i].phySrcAdd = bufPhys;
  22750. + pDmaDesc[i].phyDestAdd = MV_32BIT_LE(sramPhys);
  22751. + /* flush the buffer */
  22752. + if(skipFlush == MV_FALSE)
  22753. + mvOsCacheFlush(NULL, pBuf, thisSize);
  22754. + }
  22755. +
  22756. + pDmaDesc[i].phyNextDescPtr =
  22757. + MV_32BIT_LE(mvOsIoVirtToPhy(NULL,(&pDmaDesc[i+1])));
  22758. +
  22759. + /* flush the DMA desc */
  22760. + mvOsCacheFlush(NULL, &pDmaDesc[i], sizeof(MV_DMA_DESC));
  22761. +
  22762. + /* Update state */
  22763. + bufSize -= thisSize;
  22764. + sramPhys += thisSize;
  22765. + pBuf += thisSize;
  22766. + size += thisSize;
  22767. + i++;
  22768. + }
  22769. + }
  22770. +
  22771. + return i;
  22772. +}
  22773. +#endif /* MV_NETBSD */
  22774. +/*******************************************************************************
  22775. +* mvCesaHmacIvGet - Calculate Inner and Outter values from HMAC key
  22776. +*
  22777. +* DESCRIPTION:
  22778. +* This function calculate Inner and Outer values used for HMAC algorithm.
  22779. +* This operation allows improve performance fro the whole HMAC processing.
  22780. +*
  22781. +* INPUT:
  22782. +* MV_CESA_MAC_MODE macMode - Authentication mode: HMAC_MD5 or HMAC_SHA1.
  22783. +* unsigned char key[] - Pointer to HMAC key.
  22784. +* int keyLength - Size of HMAC key (maximum 64 bytes)
  22785. +*
  22786. +* OUTPUT:
  22787. +* unsigned char innerIV[] - HASH(key^inner)
  22788. +* unsigned char outerIV[] - HASH(key^outter)
  22789. +*
  22790. +* RETURN: None
  22791. +*
  22792. +*******************************************************************************/
  22793. +static void mvCesaHmacIvGet(MV_CESA_MAC_MODE macMode, unsigned char key[], int keyLength,
  22794. + unsigned char innerIV[], unsigned char outerIV[])
  22795. +{
  22796. + unsigned char inner[MV_CESA_MAX_MAC_KEY_LENGTH];
  22797. + unsigned char outer[MV_CESA_MAX_MAC_KEY_LENGTH];
  22798. + int i, digestSize = 0;
  22799. +#if defined(MV_CPU_LE) || defined(MV_PPC)
  22800. + MV_U32 swapped32, val32, *pVal32;
  22801. +#endif
  22802. + for(i=0; i<keyLength; i++)
  22803. + {
  22804. + inner[i] = 0x36 ^ key[i];
  22805. + outer[i] = 0x5c ^ key[i];
  22806. + }
  22807. +
  22808. + for(i=keyLength; i<MV_CESA_MAX_MAC_KEY_LENGTH; i++)
  22809. + {
  22810. + inner[i] = 0x36;
  22811. + outer[i] = 0x5c;
  22812. + }
  22813. + if(macMode == MV_CESA_MAC_HMAC_MD5)
  22814. + {
  22815. + MV_MD5_CONTEXT ctx;
  22816. +
  22817. + mvMD5Init(&ctx);
  22818. + mvMD5Update(&ctx, inner, MV_CESA_MAX_MAC_KEY_LENGTH);
  22819. +
  22820. + memcpy(innerIV, ctx.buf, MV_CESA_MD5_DIGEST_SIZE);
  22821. + memset(&ctx, 0, sizeof(ctx));
  22822. +
  22823. + mvMD5Init(&ctx);
  22824. + mvMD5Update(&ctx, outer, MV_CESA_MAX_MAC_KEY_LENGTH);
  22825. + memcpy(outerIV, ctx.buf, MV_CESA_MD5_DIGEST_SIZE);
  22826. + memset(&ctx, 0, sizeof(ctx));
  22827. + digestSize = MV_CESA_MD5_DIGEST_SIZE;
  22828. + }
  22829. + else if(macMode == MV_CESA_MAC_HMAC_SHA1)
  22830. + {
  22831. + MV_SHA1_CTX ctx;
  22832. +
  22833. + mvSHA1Init(&ctx);
  22834. + mvSHA1Update(&ctx, inner, MV_CESA_MAX_MAC_KEY_LENGTH);
  22835. + memcpy(innerIV, ctx.state, MV_CESA_SHA1_DIGEST_SIZE);
  22836. + memset(&ctx, 0, sizeof(ctx));
  22837. +
  22838. + mvSHA1Init(&ctx);
  22839. + mvSHA1Update(&ctx, outer, MV_CESA_MAX_MAC_KEY_LENGTH);
  22840. + memcpy(outerIV, ctx.state, MV_CESA_SHA1_DIGEST_SIZE);
  22841. + memset(&ctx, 0, sizeof(ctx));
  22842. + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
  22843. + }
  22844. + else
  22845. + {
  22846. + mvOsPrintf("hmacGetIV: Unexpected macMode %d\n", macMode);
  22847. + }
  22848. +#if defined(MV_CPU_LE) || defined(MV_PPC)
  22849. + /* 32 bits Swap of Inner and Outer values */
  22850. + pVal32 = (MV_U32*)innerIV;
  22851. + for(i=0; i<digestSize/4; i++)
  22852. + {
  22853. + val32 = *pVal32;
  22854. + swapped32 = MV_BYTE_SWAP_32BIT(val32);
  22855. + *pVal32 = swapped32;
  22856. + pVal32++;
  22857. + }
  22858. + pVal32 = (MV_U32*)outerIV;
  22859. + for(i=0; i<digestSize/4; i++)
  22860. + {
  22861. + val32 = *pVal32;
  22862. + swapped32 = MV_BYTE_SWAP_32BIT(val32);
  22863. + *pVal32 = swapped32;
  22864. + pVal32++;
  22865. + }
  22866. +#endif /* defined(MV_CPU_LE) || defined(MV_PPC) */
  22867. +}
  22868. +
  22869. +
  22870. +/*******************************************************************************
  22871. +* mvCesaFragSha1Complete - Complete SHA1 authentication started by HW using SW
  22872. +*
  22873. +* DESCRIPTION:
  22874. +*
  22875. +*
  22876. +* INPUT:
  22877. +* MV_CESA_MBUF* pMbuf - Pointer to Mbuf structure where data
  22878. +* for SHA1 is placed.
  22879. +* int offset - Offset in the Mbuf structure where
  22880. +* unprocessed data for SHA1 is started.
  22881. +* MV_U8* pOuterIV - Pointer to OUTER for this session.
  22882. +* If pOuterIV==NULL - MAC mode is HASH_SHA1
  22883. +* If pOuterIV!=NULL - MAC mode is HMAC_SHA1
  22884. +* int macLeftSize - Size of unprocessed data for SHA1.
  22885. +* int macTotalSize - Total size of data for SHA1 in the
  22886. +* request (processed + unprocessed)
  22887. +*
  22888. +* OUTPUT:
  22889. +* MV_U8* pDigest - Pointer to place where calculated Digest will
  22890. +* be stored.
  22891. +*
  22892. +* RETURN: None
  22893. +*
  22894. +*******************************************************************************/
  22895. +static void mvCesaFragSha1Complete(MV_CESA_MBUF* pMbuf, int offset,
  22896. + MV_U8* pOuterIV, int macLeftSize,
  22897. + int macTotalSize, MV_U8* pDigest)
  22898. +{
  22899. + MV_SHA1_CTX ctx;
  22900. + MV_U8 *pData;
  22901. + int i, frag, fragOffset, size;
  22902. +
  22903. + /* Read temporary Digest from HW */
  22904. + for(i=0; i<MV_CESA_SHA1_DIGEST_SIZE/4; i++)
  22905. + {
  22906. + ctx.state[i] = MV_REG_READ(MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i));
  22907. + }
  22908. + /* Initialize MV_SHA1_CTX structure */
  22909. + memset(ctx.buffer, 0, 64);
  22910. + /* Set count[0] in bits. 32 bits is enough for 512 MBytes */
  22911. + /* so count[1] is always 0 */
  22912. + ctx.count[0] = ((macTotalSize - macLeftSize) * 8);
  22913. + ctx.count[1] = 0;
  22914. +
  22915. + /* If HMAC - add size of Inner block (64 bytes) ro count[0] */
  22916. + if(pOuterIV != NULL)
  22917. + ctx.count[0] += (64 * 8);
  22918. +
  22919. + /* Get place of unprocessed data in the Mbuf structure */
  22920. + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
  22921. + if(frag == MV_INVALID)
  22922. + {
  22923. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  22924. + return;
  22925. + }
  22926. +
  22927. + pData = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  22928. + size = pMbuf->pFrags[frag].bufSize - fragOffset;
  22929. +
  22930. + /* Complete Inner part */
  22931. + while(macLeftSize > 0)
  22932. + {
  22933. + if(macLeftSize <= size)
  22934. + {
  22935. + mvSHA1Update(&ctx, pData, macLeftSize);
  22936. + break;
  22937. + }
  22938. + mvSHA1Update(&ctx, pData, size);
  22939. + macLeftSize -= size;
  22940. + frag++;
  22941. + pData = pMbuf->pFrags[frag].bufVirtPtr;
  22942. + size = pMbuf->pFrags[frag].bufSize;
  22943. + }
  22944. + mvSHA1Final(pDigest, &ctx);
  22945. +/*
  22946. + mvOsPrintf("mvCesaFragSha1Complete: pOuterIV=%p, macLeftSize=%d, macTotalSize=%d\n",
  22947. + pOuterIV, macLeftSize, macTotalSize);
  22948. + mvDebugMemDump(pDigest, MV_CESA_SHA1_DIGEST_SIZE, 1);
  22949. +*/
  22950. +
  22951. + if(pOuterIV != NULL)
  22952. + {
  22953. + /* If HMAC - Complete Outer part */
  22954. + for(i=0; i<MV_CESA_SHA1_DIGEST_SIZE/4; i++)
  22955. + {
  22956. +#if defined(MV_CPU_LE) || defined(MV_ARM)
  22957. + ctx.state[i] = MV_BYTE_SWAP_32BIT(((MV_U32*)pOuterIV)[i]);
  22958. +#else
  22959. + ctx.state[i] = ((MV_U32*)pOuterIV)[i];
  22960. +#endif
  22961. + }
  22962. + memset(ctx.buffer, 0, 64);
  22963. +
  22964. + ctx.count[0] = 64*8;
  22965. + ctx.count[1] = 0;
  22966. + mvSHA1Update(&ctx, pDigest, MV_CESA_SHA1_DIGEST_SIZE);
  22967. + mvSHA1Final(pDigest, &ctx);
  22968. + }
  22969. +}
  22970. +
  22971. +/*******************************************************************************
  22972. +* mvCesaFragMd5Complete - Complete MD5 authentication started by HW using SW
  22973. +*
  22974. +* DESCRIPTION:
  22975. +*
  22976. +*
  22977. +* INPUT:
  22978. +* MV_CESA_MBUF* pMbuf - Pointer to Mbuf structure where data
  22979. +* for SHA1 is placed.
  22980. +* int offset - Offset in the Mbuf structure where
  22981. +* unprocessed data for MD5 is started.
  22982. +* MV_U8* pOuterIV - Pointer to OUTER for this session.
  22983. +* If pOuterIV==NULL - MAC mode is HASH_MD5
  22984. +* If pOuterIV!=NULL - MAC mode is HMAC_MD5
  22985. +* int macLeftSize - Size of unprocessed data for MD5.
  22986. +* int macTotalSize - Total size of data for MD5 in the
  22987. +* request (processed + unprocessed)
  22988. +*
  22989. +* OUTPUT:
  22990. +* MV_U8* pDigest - Pointer to place where calculated Digest will
  22991. +* be stored.
  22992. +*
  22993. +* RETURN: None
  22994. +*
  22995. +*******************************************************************************/
  22996. +static void mvCesaFragMd5Complete(MV_CESA_MBUF* pMbuf, int offset,
  22997. + MV_U8* pOuterIV, int macLeftSize,
  22998. + int macTotalSize, MV_U8* pDigest)
  22999. +{
  23000. + MV_MD5_CONTEXT ctx;
  23001. + MV_U8 *pData;
  23002. + int i, frag, fragOffset, size;
  23003. +
  23004. + /* Read temporary Digest from HW */
  23005. + for(i=0; i<MV_CESA_MD5_DIGEST_SIZE/4; i++)
  23006. + {
  23007. + ctx.buf[i] = MV_REG_READ(MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i));
  23008. + }
  23009. + memset(ctx.in, 0, 64);
  23010. +
  23011. + /* Set count[0] in bits. 32 bits is enough for 512 MBytes */
  23012. + /* so count[1] is always 0 */
  23013. + ctx.bits[0] = ((macTotalSize - macLeftSize) * 8);
  23014. + ctx.bits[1] = 0;
  23015. +
  23016. + /* If HMAC - add size of Inner block (64 bytes) ro count[0] */
  23017. + if(pOuterIV != NULL)
  23018. + ctx.bits[0] += (64 * 8);
  23019. +
  23020. + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
  23021. + if(frag == MV_INVALID)
  23022. + {
  23023. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  23024. + return;
  23025. + }
  23026. +
  23027. + pData = pMbuf->pFrags[frag].bufVirtPtr + fragOffset;
  23028. + size = pMbuf->pFrags[frag].bufSize - fragOffset;
  23029. +
  23030. + /* Complete Inner part */
  23031. + while(macLeftSize > 0)
  23032. + {
  23033. + if(macLeftSize <= size)
  23034. + {
  23035. + mvMD5Update(&ctx, pData, macLeftSize);
  23036. + break;
  23037. + }
  23038. + mvMD5Update(&ctx, pData, size);
  23039. + macLeftSize -= size;
  23040. + frag++;
  23041. + pData = pMbuf->pFrags[frag].bufVirtPtr;
  23042. + size = pMbuf->pFrags[frag].bufSize;
  23043. + }
  23044. + mvMD5Final(pDigest, &ctx);
  23045. +
  23046. +/*
  23047. + mvOsPrintf("mvCesaFragMd5Complete: pOuterIV=%p, macLeftSize=%d, macTotalSize=%d\n",
  23048. + pOuterIV, macLeftSize, macTotalSize);
  23049. + mvDebugMemDump(pDigest, MV_CESA_MD5_DIGEST_SIZE, 1);
  23050. +*/
  23051. + if(pOuterIV != NULL)
  23052. + {
  23053. + /* Complete Outer part */
  23054. + for(i=0; i<MV_CESA_MD5_DIGEST_SIZE/4; i++)
  23055. + {
  23056. +#if defined(MV_CPU_LE) || defined(MV_ARM)
  23057. + ctx.buf[i] = MV_BYTE_SWAP_32BIT(((MV_U32*)pOuterIV)[i]);
  23058. +#else
  23059. + ctx.buf[i] = ((MV_U32*)pOuterIV)[i];
  23060. +#endif
  23061. + }
  23062. + memset(ctx.in, 0, 64);
  23063. +
  23064. + ctx.bits[0] = 64*8;
  23065. + ctx.bits[1] = 0;
  23066. + mvMD5Update(&ctx, pDigest, MV_CESA_MD5_DIGEST_SIZE);
  23067. + mvMD5Final(pDigest, &ctx);
  23068. + }
  23069. +}
  23070. +
  23071. +/*******************************************************************************
  23072. +* mvCesaFragAuthComplete -
  23073. +*
  23074. +* DESCRIPTION:
  23075. +*
  23076. +*
  23077. +* INPUT:
  23078. +* MV_CESA_REQ* pReq,
  23079. +* MV_CESA_SA* pSA,
  23080. +* int macDataSize
  23081. +*
  23082. +* RETURN:
  23083. +* MV_STATUS
  23084. +*
  23085. +*******************************************************************************/
  23086. +static MV_STATUS mvCesaFragAuthComplete(MV_CESA_REQ* pReq, MV_CESA_SA* pSA,
  23087. + int macDataSize)
  23088. +{
  23089. + MV_CESA_COMMAND* pCmd = pReq->pCmd;
  23090. + MV_U8* pDigest;
  23091. + MV_CESA_MAC_MODE macMode;
  23092. + MV_U8* pOuterIV = NULL;
  23093. +
  23094. + /* Copy data from Source fragment to Destination */
  23095. + if(pCmd->pSrc != pCmd->pDst)
  23096. + {
  23097. + mvCesaMbufCopy(pCmd->pDst, pReq->frags.bufOffset,
  23098. + pCmd->pSrc, pReq->frags.bufOffset, macDataSize);
  23099. + }
  23100. +
  23101. +/*
  23102. + mvCesaCopyFromMbuf(cesaSramVirtPtr->buf[0], pCmd->pSrc, pReq->frags.bufOffset, macDataSize);
  23103. + mvCesaCopyToMbuf(cesaSramVirtPtr->buf[0], pCmd->pDst, pReq->frags.bufOffset, macDataSize);
  23104. +*/
  23105. + pDigest = (mvCesaSramAddrGet() + pReq->frags.newDigestOffset);
  23106. +
  23107. + macMode = (pSA->config & MV_CESA_MAC_MODE_MASK) >> MV_CESA_MAC_MODE_OFFSET;
  23108. +/*
  23109. + mvOsPrintf("macDataSize=%d, macLength=%d, digestOffset=%d, macMode=%d\n",
  23110. + macDataSize, pCmd->macLength, pCmd->digestOffset, macMode);
  23111. +*/
  23112. + switch(macMode)
  23113. + {
  23114. + case MV_CESA_MAC_HMAC_MD5:
  23115. + pOuterIV = pSA->pSramSA->macOuterIV;
  23116. +
  23117. + case MV_CESA_MAC_MD5:
  23118. + mvCesaFragMd5Complete(pCmd->pDst, pReq->frags.bufOffset, pOuterIV,
  23119. + macDataSize, pCmd->macLength, pDigest);
  23120. + break;
  23121. +
  23122. + case MV_CESA_MAC_HMAC_SHA1:
  23123. + pOuterIV = pSA->pSramSA->macOuterIV;
  23124. +
  23125. + case MV_CESA_MAC_SHA1:
  23126. + mvCesaFragSha1Complete(pCmd->pDst, pReq->frags.bufOffset, pOuterIV,
  23127. + macDataSize, pCmd->macLength, pDigest);
  23128. + break;
  23129. +
  23130. + default:
  23131. + mvOsPrintf("mvCesaFragAuthComplete: Unexpected macMode %d\n", macMode);
  23132. + return MV_BAD_PARAM;
  23133. + }
  23134. + return MV_OK;
  23135. +}
  23136. +
  23137. +/*******************************************************************************
  23138. +* mvCesaCtrModeInit -
  23139. +*
  23140. +* DESCRIPTION:
  23141. +*
  23142. +*
  23143. +* INPUT: NONE
  23144. +*
  23145. +*
  23146. +* RETURN:
  23147. +* MV_CESA_COMMAND*
  23148. +*
  23149. +*******************************************************************************/
  23150. +static MV_CESA_COMMAND* mvCesaCtrModeInit(void)
  23151. +{
  23152. + MV_CESA_MBUF *pMbuf;
  23153. + MV_U8 *pBuf;
  23154. + MV_CESA_COMMAND *pCmd;
  23155. +
  23156. + pBuf = mvOsMalloc(sizeof(MV_CESA_COMMAND) +
  23157. + sizeof(MV_CESA_MBUF) + sizeof(MV_BUF_INFO) + 100);
  23158. + if(pBuf == NULL)
  23159. + {
  23160. + mvOsPrintf("mvCesaSessionOpen: Can't allocate %u bytes for CTR Mode\n",
  23161. + sizeof(MV_CESA_COMMAND) + sizeof(MV_CESA_MBUF) + sizeof(MV_BUF_INFO) );
  23162. + return NULL;
  23163. + }
  23164. + pCmd = (MV_CESA_COMMAND*)pBuf;
  23165. + pBuf += sizeof(MV_CESA_COMMAND);
  23166. +
  23167. + pMbuf = (MV_CESA_MBUF*)pBuf;
  23168. + pBuf += sizeof(MV_CESA_MBUF);
  23169. +
  23170. + pMbuf->pFrags = (MV_BUF_INFO*)pBuf;
  23171. +
  23172. + pMbuf->numFrags = 1;
  23173. + pCmd->pSrc = pMbuf;
  23174. + pCmd->pDst = pMbuf;
  23175. +/*
  23176. + mvOsPrintf("CtrModeInit: pCmd=%p, pSrc=%p, pDst=%p, pFrags=%p\n",
  23177. + pCmd, pCmd->pSrc, pCmd->pDst,
  23178. + pMbuf->pFrags);
  23179. +*/
  23180. + return pCmd;
  23181. +}
  23182. +
  23183. +/*******************************************************************************
  23184. +* mvCesaCtrModePrepare -
  23185. +*
  23186. +* DESCRIPTION:
  23187. +*
  23188. +*
  23189. +* INPUT:
  23190. +* MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd
  23191. +*
  23192. +* RETURN:
  23193. +* MV_STATUS
  23194. +*
  23195. +*******************************************************************************/
  23196. +static MV_STATUS mvCesaCtrModePrepare(MV_CESA_COMMAND *pCtrModeCmd, MV_CESA_COMMAND *pCmd)
  23197. +{
  23198. + MV_CESA_MBUF *pMbuf;
  23199. + MV_U8 *pBuf, *pIV;
  23200. + MV_U32 counter, *pCounter;
  23201. + int cryptoSize = MV_ALIGN_UP(pCmd->cryptoLength, MV_CESA_AES_BLOCK_SIZE);
  23202. +/*
  23203. + mvOsPrintf("CtrModePrepare: pCmd=%p, pCtrSrc=%p, pCtrDst=%p, pOrgCmd=%p, pOrgSrc=%p, pOrgDst=%p\n",
  23204. + pCmd, pCmd->pSrc, pCmd->pDst,
  23205. + pCtrModeCmd, pCtrModeCmd->pSrc, pCtrModeCmd->pDst);
  23206. +*/
  23207. + pMbuf = pCtrModeCmd->pSrc;
  23208. +
  23209. + /* Allocate buffer for Key stream */
  23210. + pBuf = mvOsIoCachedMalloc(cesaOsHandle,cryptoSize,
  23211. + &pMbuf->pFrags[0].bufPhysAddr,
  23212. + &pMbuf->pFrags[0].memHandle);
  23213. + if(pBuf == NULL)
  23214. + {
  23215. + mvOsPrintf("mvCesaCtrModePrepare: Can't allocate %d bytes\n", cryptoSize);
  23216. + return MV_OUT_OF_CPU_MEM;
  23217. + }
  23218. + memset(pBuf, 0, cryptoSize);
  23219. + mvOsCacheFlush(NULL, pBuf, cryptoSize);
  23220. +
  23221. + pMbuf->pFrags[0].bufVirtPtr = pBuf;
  23222. + pMbuf->mbufSize = cryptoSize;
  23223. + pMbuf->pFrags[0].bufSize = cryptoSize;
  23224. +
  23225. + pCtrModeCmd->pReqPrv = pCmd->pReqPrv;
  23226. + pCtrModeCmd->sessionId = pCmd->sessionId;
  23227. +
  23228. + /* ivFromUser and ivOffset are don't care */
  23229. + pCtrModeCmd->cryptoOffset = 0;
  23230. + pCtrModeCmd->cryptoLength = cryptoSize;
  23231. +
  23232. + /* digestOffset, macOffset and macLength are don't care */
  23233. +
  23234. + mvCesaCopyFromMbuf(pBuf, pCmd->pSrc, pCmd->ivOffset, MV_CESA_AES_BLOCK_SIZE);
  23235. + pCounter = (MV_U32*)(pBuf + (MV_CESA_AES_BLOCK_SIZE - sizeof(counter)));
  23236. + counter = *pCounter;
  23237. + counter = MV_32BIT_BE(counter);
  23238. + pIV = pBuf;
  23239. + cryptoSize -= MV_CESA_AES_BLOCK_SIZE;
  23240. +
  23241. + /* fill key stream */
  23242. + while(cryptoSize > 0)
  23243. + {
  23244. + pBuf += MV_CESA_AES_BLOCK_SIZE;
  23245. + memcpy(pBuf, pIV, MV_CESA_AES_BLOCK_SIZE - sizeof(counter));
  23246. + pCounter = (MV_U32*)(pBuf + (MV_CESA_AES_BLOCK_SIZE - sizeof(counter)));
  23247. + counter++;
  23248. + *pCounter = MV_32BIT_BE(counter);
  23249. + cryptoSize -= MV_CESA_AES_BLOCK_SIZE;
  23250. + }
  23251. +
  23252. + return MV_OK;
  23253. +}
  23254. +
  23255. +/*******************************************************************************
  23256. +* mvCesaCtrModeComplete -
  23257. +*
  23258. +* DESCRIPTION:
  23259. +*
  23260. +*
  23261. +* INPUT:
  23262. +* MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd
  23263. +*
  23264. +* RETURN:
  23265. +* MV_STATUS
  23266. +*
  23267. +*******************************************************************************/
  23268. +static MV_STATUS mvCesaCtrModeComplete(MV_CESA_COMMAND *pOrgCmd, MV_CESA_COMMAND *pCmd)
  23269. +{
  23270. + int srcFrag, dstFrag, srcOffset, dstOffset, keyOffset, srcSize, dstSize;
  23271. + int cryptoSize = pCmd->cryptoLength;
  23272. + MV_U8 *pSrc, *pDst, *pKey;
  23273. + MV_STATUS status = MV_OK;
  23274. +/*
  23275. + mvOsPrintf("CtrModeComplete: pCmd=%p, pCtrSrc=%p, pCtrDst=%p, pOrgCmd=%p, pOrgSrc=%p, pOrgDst=%p\n",
  23276. + pCmd, pCmd->pSrc, pCmd->pDst,
  23277. + pOrgCmd, pOrgCmd->pSrc, pOrgCmd->pDst);
  23278. +*/
  23279. + /* XOR source data with key stream to destination data */
  23280. + pKey = pCmd->pDst->pFrags[0].bufVirtPtr;
  23281. + keyOffset = 0;
  23282. +
  23283. + if( (pOrgCmd->pSrc != pOrgCmd->pDst) &&
  23284. + (pOrgCmd->cryptoOffset > 0) )
  23285. + {
  23286. + /* Copy Prefix from source buffer to destination buffer */
  23287. +
  23288. + status = mvCesaMbufCopy(pOrgCmd->pDst, 0,
  23289. + pOrgCmd->pSrc, 0, pOrgCmd->cryptoOffset);
  23290. +/*
  23291. + status = mvCesaCopyFromMbuf(tempBuf, pOrgCmd->pSrc,
  23292. + 0, pOrgCmd->cryptoOffset);
  23293. + status = mvCesaCopyToMbuf(tempBuf, pOrgCmd->pDst,
  23294. + 0, pOrgCmd->cryptoOffset);
  23295. +*/
  23296. + }
  23297. +
  23298. + srcFrag = mvCesaMbufOffset(pOrgCmd->pSrc, pOrgCmd->cryptoOffset, &srcOffset);
  23299. + pSrc = pOrgCmd->pSrc->pFrags[srcFrag].bufVirtPtr;
  23300. + srcSize = pOrgCmd->pSrc->pFrags[srcFrag].bufSize;
  23301. +
  23302. + dstFrag = mvCesaMbufOffset(pOrgCmd->pDst, pOrgCmd->cryptoOffset, &dstOffset);
  23303. + pDst = pOrgCmd->pDst->pFrags[dstFrag].bufVirtPtr;
  23304. + dstSize = pOrgCmd->pDst->pFrags[dstFrag].bufSize;
  23305. +
  23306. + while(cryptoSize > 0)
  23307. + {
  23308. + pDst[dstOffset] = (pSrc[srcOffset] ^ pKey[keyOffset]);
  23309. +
  23310. + cryptoSize--;
  23311. + dstOffset++;
  23312. + srcOffset++;
  23313. + keyOffset++;
  23314. +
  23315. + if(srcOffset >= srcSize)
  23316. + {
  23317. + srcFrag++;
  23318. + srcOffset = 0;
  23319. + pSrc = pOrgCmd->pSrc->pFrags[srcFrag].bufVirtPtr;
  23320. + srcSize = pOrgCmd->pSrc->pFrags[srcFrag].bufSize;
  23321. + }
  23322. +
  23323. + if(dstOffset >= dstSize)
  23324. + {
  23325. + dstFrag++;
  23326. + dstOffset = 0;
  23327. + pDst = pOrgCmd->pDst->pFrags[dstFrag].bufVirtPtr;
  23328. + dstSize = pOrgCmd->pDst->pFrags[dstFrag].bufSize;
  23329. + }
  23330. + }
  23331. +
  23332. + if(pOrgCmd->pSrc != pOrgCmd->pDst)
  23333. + {
  23334. + /* Copy Suffix from source buffer to destination buffer */
  23335. + srcOffset = pOrgCmd->cryptoOffset + pOrgCmd->cryptoLength;
  23336. +
  23337. + if( (pOrgCmd->pDst->mbufSize - srcOffset) > 0)
  23338. + {
  23339. + status = mvCesaMbufCopy(pOrgCmd->pDst, srcOffset,
  23340. + pOrgCmd->pSrc, srcOffset,
  23341. + pOrgCmd->pDst->mbufSize - srcOffset);
  23342. + }
  23343. +
  23344. +/*
  23345. + status = mvCesaCopyFromMbuf(tempBuf, pOrgCmd->pSrc,
  23346. + srcOffset, pOrgCmd->pSrc->mbufSize - srcOffset);
  23347. + status = mvCesaCopyToMbuf(tempBuf, pOrgCmd->pDst,
  23348. + srcOffset, pOrgCmd->pDst->mbufSize - srcOffset);
  23349. +*/
  23350. + }
  23351. +
  23352. + /* Free buffer used for Key stream */
  23353. + mvOsIoCachedFree(cesaOsHandle,pCmd->pDst->pFrags[0].bufSize,
  23354. + pCmd->pDst->pFrags[0].bufPhysAddr,
  23355. + pCmd->pDst->pFrags[0].bufVirtPtr,
  23356. + pCmd->pDst->pFrags[0].memHandle);
  23357. +
  23358. + return MV_OK;
  23359. +}
  23360. +
  23361. +/*******************************************************************************
  23362. +* mvCesaCtrModeFinish -
  23363. +*
  23364. +* DESCRIPTION:
  23365. +*
  23366. +*
  23367. +* INPUT:
  23368. +* MV_CESA_COMMAND* pCmd
  23369. +*
  23370. +* RETURN:
  23371. +* MV_STATUS
  23372. +*
  23373. +*******************************************************************************/
  23374. +static void mvCesaCtrModeFinish(MV_CESA_COMMAND* pCmd)
  23375. +{
  23376. + mvOsFree(pCmd);
  23377. +}
  23378. +
  23379. +/*******************************************************************************
  23380. +* mvCesaParamCheck -
  23381. +*
  23382. +* DESCRIPTION:
  23383. +*
  23384. +*
  23385. +* INPUT:
  23386. +* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd, MV_U8* pFixOffset
  23387. +*
  23388. +* RETURN:
  23389. +* MV_STATUS
  23390. +*
  23391. +*******************************************************************************/
  23392. +static MV_STATUS mvCesaParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd,
  23393. + MV_U8* pFixOffset)
  23394. +{
  23395. + MV_U8 fixOffset = 0xFF;
  23396. +
  23397. + /* Check AUTH operation parameters */
  23398. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  23399. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET)) )
  23400. + {
  23401. + /* MAC offset should be at least 4 byte aligned */
  23402. + if( MV_IS_NOT_ALIGN(pCmd->macOffset, 4) )
  23403. + {
  23404. + mvOsPrintf("mvCesaAction: macOffset %d must be 4 byte aligned\n",
  23405. + pCmd->macOffset);
  23406. + return MV_BAD_PARAM;
  23407. + }
  23408. + /* Digest offset must be 4 byte aligned */
  23409. + if( MV_IS_NOT_ALIGN(pCmd->digestOffset, 4) )
  23410. + {
  23411. + mvOsPrintf("mvCesaAction: digestOffset %d must be 4 byte aligned\n",
  23412. + pCmd->digestOffset);
  23413. + return MV_BAD_PARAM;
  23414. + }
  23415. + /* In addition all offsets should be the same alignment: 8 or 4 */
  23416. + if(fixOffset == 0xFF)
  23417. + {
  23418. + fixOffset = (pCmd->macOffset % 8);
  23419. + }
  23420. + else
  23421. + {
  23422. + if( (pCmd->macOffset % 8) != fixOffset)
  23423. + {
  23424. + mvOsPrintf("mvCesaAction: macOffset %d mod 8 must be equal %d\n",
  23425. + pCmd->macOffset, fixOffset);
  23426. + return MV_BAD_PARAM;
  23427. + }
  23428. + }
  23429. + if( (pCmd->digestOffset % 8) != fixOffset)
  23430. + {
  23431. + mvOsPrintf("mvCesaAction: digestOffset %d mod 8 must be equal %d\n",
  23432. + pCmd->digestOffset, fixOffset);
  23433. + return MV_BAD_PARAM;
  23434. + }
  23435. + }
  23436. + /* Check CRYPTO operation parameters */
  23437. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  23438. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) )
  23439. + {
  23440. + /* CryptoOffset should be at least 4 byte aligned */
  23441. + if( MV_IS_NOT_ALIGN(pCmd->cryptoOffset, 4) )
  23442. + {
  23443. + mvOsPrintf("CesaAction: cryptoOffset=%d must be 4 byte aligned\n",
  23444. + pCmd->cryptoOffset);
  23445. + return MV_BAD_PARAM;
  23446. + }
  23447. + /* cryptoLength should be the whole number of blocks */
  23448. + if( MV_IS_NOT_ALIGN(pCmd->cryptoLength, pSA->cryptoBlockSize) )
  23449. + {
  23450. + mvOsPrintf("mvCesaAction: cryptoLength=%d must be %d byte aligned\n",
  23451. + pCmd->cryptoLength, pSA->cryptoBlockSize);
  23452. + return MV_BAD_PARAM;
  23453. + }
  23454. + if(fixOffset == 0xFF)
  23455. + {
  23456. + fixOffset = (pCmd->cryptoOffset % 8);
  23457. + }
  23458. + else
  23459. + {
  23460. + /* In addition all offsets should be the same alignment: 8 or 4 */
  23461. + if( (pCmd->cryptoOffset % 8) != fixOffset)
  23462. + {
  23463. + mvOsPrintf("mvCesaAction: cryptoOffset %d mod 8 must be equal %d \n",
  23464. + pCmd->cryptoOffset, fixOffset);
  23465. + return MV_BAD_PARAM;
  23466. + }
  23467. + }
  23468. +
  23469. + /* check for CBC mode */
  23470. + if(pSA->cryptoIvSize > 0)
  23471. + {
  23472. + /* cryptoIV must not be part of CryptoLength */
  23473. + if( ((pCmd->ivOffset + pSA->cryptoIvSize) > pCmd->cryptoOffset) &&
  23474. + (pCmd->ivOffset < (pCmd->cryptoOffset + pCmd->cryptoLength)) )
  23475. + {
  23476. + mvOsPrintf("mvCesaFragParamCheck: cryptoIvOffset (%d) is part of cryptoLength (%d+%d)\n",
  23477. + pCmd->ivOffset, pCmd->macOffset, pCmd->macLength);
  23478. + return MV_BAD_PARAM;
  23479. + }
  23480. +
  23481. + /* ivOffset must be 4 byte aligned */
  23482. + if( MV_IS_NOT_ALIGN(pCmd->ivOffset, 4) )
  23483. + {
  23484. + mvOsPrintf("CesaAction: ivOffset=%d must be 4 byte aligned\n",
  23485. + pCmd->ivOffset);
  23486. + return MV_BAD_PARAM;
  23487. + }
  23488. + /* In addition all offsets should be the same alignment: 8 or 4 */
  23489. + if( (pCmd->ivOffset % 8) != fixOffset)
  23490. + {
  23491. + mvOsPrintf("mvCesaAction: ivOffset %d mod 8 must be %d\n",
  23492. + pCmd->ivOffset, fixOffset);
  23493. + return MV_BAD_PARAM;
  23494. + }
  23495. + }
  23496. + }
  23497. + return MV_OK;
  23498. +}
  23499. +
  23500. +/*******************************************************************************
  23501. +* mvCesaFragParamCheck -
  23502. +*
  23503. +* DESCRIPTION:
  23504. +*
  23505. +*
  23506. +* INPUT:
  23507. +* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd
  23508. +*
  23509. +* RETURN:
  23510. +* MV_STATUS
  23511. +*
  23512. +*******************************************************************************/
  23513. +static MV_STATUS mvCesaFragParamCheck(MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd)
  23514. +{
  23515. + int offset;
  23516. +
  23517. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  23518. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET)) )
  23519. + {
  23520. + /* macOffset must be less that SRAM buffer size */
  23521. + if(pCmd->macOffset > (sizeof(cesaSramVirtPtr->buf) - MV_CESA_AUTH_BLOCK_SIZE))
  23522. + {
  23523. + mvOsPrintf("mvCesaFragParamCheck: macOffset is too large (%d)\n",
  23524. + pCmd->macOffset);
  23525. + return MV_BAD_PARAM;
  23526. + }
  23527. + /* macOffset+macSize must be more than mbufSize - SRAM buffer size */
  23528. + if( ((pCmd->macOffset + pCmd->macLength) > pCmd->pSrc->mbufSize) ||
  23529. + ((pCmd->pSrc->mbufSize - (pCmd->macOffset + pCmd->macLength)) >=
  23530. + sizeof(cesaSramVirtPtr->buf)) )
  23531. + {
  23532. + mvOsPrintf("mvCesaFragParamCheck: macLength is too large (%d), mbufSize=%d\n",
  23533. + pCmd->macLength, pCmd->pSrc->mbufSize);
  23534. + return MV_BAD_PARAM;
  23535. + }
  23536. + }
  23537. +
  23538. + if( ((pSA->config & MV_CESA_OPERATION_MASK) !=
  23539. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET)) )
  23540. + {
  23541. + /* cryptoOffset must be less that SRAM buffer size */
  23542. + /* 4 for possible fixOffset */
  23543. + if( (pCmd->cryptoOffset + 4) > (sizeof(cesaSramVirtPtr->buf) - pSA->cryptoBlockSize))
  23544. + {
  23545. + mvOsPrintf("mvCesaFragParamCheck: cryptoOffset is too large (%d)\n",
  23546. + pCmd->cryptoOffset);
  23547. + return MV_BAD_PARAM;
  23548. + }
  23549. +
  23550. + /* cryptoOffset+cryptoSize must be more than mbufSize - SRAM buffer size */
  23551. + if( ((pCmd->cryptoOffset + pCmd->cryptoLength) > pCmd->pSrc->mbufSize) ||
  23552. + ((pCmd->pSrc->mbufSize - (pCmd->cryptoOffset + pCmd->cryptoLength)) >=
  23553. + (sizeof(cesaSramVirtPtr->buf) - pSA->cryptoBlockSize)) )
  23554. + {
  23555. + mvOsPrintf("mvCesaFragParamCheck: cryptoLength is too large (%d), mbufSize=%d\n",
  23556. + pCmd->cryptoLength, pCmd->pSrc->mbufSize);
  23557. + return MV_BAD_PARAM;
  23558. + }
  23559. + }
  23560. +
  23561. + /* When MAC_THEN_CRYPTO or CRYPTO_THEN_MAC */
  23562. + if( ((pSA->config & MV_CESA_OPERATION_MASK) ==
  23563. + (MV_CESA_MAC_THEN_CRYPTO << MV_CESA_OPERATION_OFFSET)) ||
  23564. + ((pSA->config & MV_CESA_OPERATION_MASK) ==
  23565. + (MV_CESA_CRYPTO_THEN_MAC << MV_CESA_OPERATION_OFFSET)) )
  23566. + {
  23567. + if( (mvCtrlModelGet() == MV_5182_DEV_ID) ||
  23568. + ( (mvCtrlModelGet() == MV_5181_DEV_ID) &&
  23569. + (mvCtrlRevGet() >= MV_5181L_A0_REV) &&
  23570. + (pCmd->macLength >= (1 << 14)) ) )
  23571. + {
  23572. + return MV_NOT_ALLOWED;
  23573. + }
  23574. +
  23575. + /* abs(cryptoOffset-macOffset) must be aligned cryptoBlockSize */
  23576. + if(pCmd->cryptoOffset > pCmd->macOffset)
  23577. + {
  23578. + offset = pCmd->cryptoOffset - pCmd->macOffset;
  23579. + }
  23580. + else
  23581. + {
  23582. + offset = pCmd->macOffset - pCmd->cryptoOffset;
  23583. + }
  23584. +
  23585. + if( MV_IS_NOT_ALIGN(offset, pSA->cryptoBlockSize) )
  23586. + {
  23587. +/*
  23588. + mvOsPrintf("mvCesaFragParamCheck: (cryptoOffset - macOffset) must be %d byte aligned\n",
  23589. + pSA->cryptoBlockSize);
  23590. +*/
  23591. + return MV_NOT_ALLOWED;
  23592. + }
  23593. + /* Digest must not be part of CryptoLength */
  23594. + if( ((pCmd->digestOffset + pSA->digestSize) > pCmd->cryptoOffset) &&
  23595. + (pCmd->digestOffset < (pCmd->cryptoOffset + pCmd->cryptoLength)) )
  23596. + {
  23597. +/*
  23598. + mvOsPrintf("mvCesaFragParamCheck: digestOffset (%d) is part of cryptoLength (%d+%d)\n",
  23599. + pCmd->digestOffset, pCmd->cryptoOffset, pCmd->cryptoLength);
  23600. +*/
  23601. + return MV_NOT_ALLOWED;
  23602. + }
  23603. + }
  23604. + return MV_OK;
  23605. +}
  23606. +
  23607. +/*******************************************************************************
  23608. +* mvCesaFragSizeFind -
  23609. +*
  23610. +* DESCRIPTION:
  23611. +*
  23612. +*
  23613. +* INPUT:
  23614. +* MV_CESA_SA* pSA, MV_CESA_COMMAND *pCmd,
  23615. +* int cryptoOffset, int macOffset,
  23616. +*
  23617. +* OUTPUT:
  23618. +* int* pCopySize, int* pCryptoDataSize, int* pMacDataSize
  23619. +*
  23620. +* RETURN:
  23621. +* MV_STATUS
  23622. +*
  23623. +*******************************************************************************/
  23624. +static void mvCesaFragSizeFind(MV_CESA_SA* pSA, MV_CESA_REQ* pReq,
  23625. + int cryptoOffset, int macOffset,
  23626. + int* pCopySize, int* pCryptoDataSize, int* pMacDataSize)
  23627. +{
  23628. + MV_CESA_COMMAND *pCmd = pReq->pCmd;
  23629. + int cryptoDataSize, macDataSize, copySize;
  23630. +
  23631. + cryptoDataSize = macDataSize = 0;
  23632. + copySize = *pCopySize;
  23633. +
  23634. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  23635. + (MV_CESA_MAC_ONLY << MV_CESA_OPERATION_OFFSET) )
  23636. + {
  23637. + cryptoDataSize = MV_MIN( (copySize - cryptoOffset),
  23638. + (pCmd->cryptoLength - (pReq->frags.cryptoSize + 1)) );
  23639. +
  23640. + /* cryptoSize for each fragment must be the whole number of blocksSize */
  23641. + if( MV_IS_NOT_ALIGN(cryptoDataSize, pSA->cryptoBlockSize) )
  23642. + {
  23643. + cryptoDataSize = MV_ALIGN_DOWN(cryptoDataSize, pSA->cryptoBlockSize);
  23644. + copySize = cryptoOffset + cryptoDataSize;
  23645. + }
  23646. + }
  23647. + if( (pSA->config & MV_CESA_OPERATION_MASK) !=
  23648. + (MV_CESA_CRYPTO_ONLY << MV_CESA_OPERATION_OFFSET) )
  23649. + {
  23650. + macDataSize = MV_MIN( (copySize - macOffset),
  23651. + (pCmd->macLength - (pReq->frags.macSize + 1)));
  23652. +
  23653. + /* macSize for each fragment (except last) must be the whole number of blocksSize */
  23654. + if( MV_IS_NOT_ALIGN(macDataSize, MV_CESA_AUTH_BLOCK_SIZE) )
  23655. + {
  23656. + macDataSize = MV_ALIGN_DOWN(macDataSize, MV_CESA_AUTH_BLOCK_SIZE);
  23657. + copySize = macOffset + macDataSize;
  23658. + }
  23659. + cryptoDataSize = copySize - cryptoOffset;
  23660. + }
  23661. + *pCopySize = copySize;
  23662. +
  23663. + if(pCryptoDataSize != NULL)
  23664. + *pCryptoDataSize = cryptoDataSize;
  23665. +
  23666. + if(pMacDataSize != NULL)
  23667. + *pMacDataSize = macDataSize;
  23668. +}
  23669. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesa.h linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesa.h
  23670. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesa.h 1970-01-01 01:00:00.000000000 +0100
  23671. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesa.h 2011-08-01 14:38:18.000000000 +0200
  23672. @@ -0,0 +1,412 @@
  23673. +/*******************************************************************************
  23674. +Copyright (C) Marvell International Ltd. and its affiliates
  23675. +
  23676. +This software file (the "File") is owned and distributed by Marvell
  23677. +International Ltd. and/or its affiliates ("Marvell") under the following
  23678. +alternative licensing terms. Once you have made an election to distribute the
  23679. +File under one of the following license alternatives, please (i) delete this
  23680. +introductory statement regarding license alternatives, (ii) delete the two
  23681. +license alternatives that you have not elected to use and (iii) preserve the
  23682. +Marvell copyright notice above.
  23683. +
  23684. +********************************************************************************
  23685. +Marvell Commercial License Option
  23686. +
  23687. +If you received this File from Marvell and you have entered into a commercial
  23688. +license agreement (a "Commercial License") with Marvell, the File is licensed
  23689. +to you under the terms of the applicable Commercial License.
  23690. +
  23691. +********************************************************************************
  23692. +Marvell GPL License Option
  23693. +
  23694. +If you received this File from Marvell, you may opt to use, redistribute and/or
  23695. +modify this File in accordance with the terms and conditions of the General
  23696. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  23697. +available along with the File in the license.txt file or by writing to the Free
  23698. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  23699. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  23700. +
  23701. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  23702. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  23703. +DISCLAIMED. The GPL License provides additional details about this warranty
  23704. +disclaimer.
  23705. +********************************************************************************
  23706. +Marvell BSD License Option
  23707. +
  23708. +If you received this File from Marvell, you may opt to use, redistribute and/or
  23709. +modify this File under the following licensing terms.
  23710. +Redistribution and use in source and binary forms, with or without modification,
  23711. +are permitted provided that the following conditions are met:
  23712. +
  23713. + * Redistributions of source code must retain the above copyright notice,
  23714. + this list of conditions and the following disclaimer.
  23715. +
  23716. + * Redistributions in binary form must reproduce the above copyright
  23717. + notice, this list of conditions and the following disclaimer in the
  23718. + documentation and/or other materials provided with the distribution.
  23719. +
  23720. + * Neither the name of Marvell nor the names of its contributors may be
  23721. + used to endorse or promote products derived from this software without
  23722. + specific prior written permission.
  23723. +
  23724. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  23725. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  23726. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  23727. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  23728. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23729. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23730. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  23731. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  23732. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  23733. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23734. +
  23735. +*******************************************************************************/
  23736. +
  23737. +/*******************************************************************************
  23738. +* mvCesa.h - Header File for Cryptographic Engines and Security Accelerator
  23739. +*
  23740. +* DESCRIPTION:
  23741. +* This header file contains macros typedefs and function declaration for
  23742. +* the Marvell Cryptographic Engines and Security Accelerator.
  23743. +*
  23744. +*******************************************************************************/
  23745. +
  23746. +#ifndef __mvCesa_h__
  23747. +#define __mvCesa_h__
  23748. +
  23749. +#include "mvOs.h"
  23750. +#include "mvCommon.h"
  23751. +#include "mvDebug.h"
  23752. +
  23753. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  23754. +
  23755. +#include "cesa/mvMD5.h"
  23756. +#include "cesa/mvSHA1.h"
  23757. +
  23758. +#include "cesa/mvCesa.h"
  23759. +#include "cesa/AES/mvAes.h"
  23760. +#include "mvSysHwConfig.h"
  23761. +
  23762. +#ifdef MV_INCLUDE_IDMA
  23763. +#include "idma/mvIdma.h"
  23764. +#include "idma/mvIdmaRegs.h"
  23765. +#else
  23766. +/* Redefine MV_DMA_DESC structure */
  23767. +typedef struct _mvDmaDesc
  23768. +{
  23769. + MV_U32 byteCnt; /* The total number of bytes to transfer */
  23770. + MV_U32 phySrcAdd; /* The physical source address */
  23771. + MV_U32 phyDestAdd; /* The physical destination address */
  23772. + MV_U32 phyNextDescPtr; /* If we are using chain mode DMA transfer, */
  23773. + /* then this pointer should point to the */
  23774. + /* physical address of the next descriptor, */
  23775. + /* otherwise it should be NULL. */
  23776. +}MV_DMA_DESC;
  23777. +#endif /* MV_INCLUDE_IDMA */
  23778. +
  23779. +#include "cesa/mvCesaRegs.h"
  23780. +
  23781. +#define MV_CESA_AUTH_BLOCK_SIZE 64 /* bytes */
  23782. +
  23783. +#define MV_CESA_MD5_DIGEST_SIZE 16 /* bytes */
  23784. +#define MV_CESA_SHA1_DIGEST_SIZE 20 /* bytes */
  23785. +
  23786. +#define MV_CESA_MAX_DIGEST_SIZE MV_CESA_SHA1_DIGEST_SIZE
  23787. +
  23788. +#define MV_CESA_DES_KEY_LENGTH 8 /* bytes = 64 bits */
  23789. +#define MV_CESA_3DES_KEY_LENGTH 24 /* bytes = 192 bits */
  23790. +#define MV_CESA_AES_128_KEY_LENGTH 16 /* bytes = 128 bits */
  23791. +#define MV_CESA_AES_192_KEY_LENGTH 24 /* bytes = 192 bits */
  23792. +#define MV_CESA_AES_256_KEY_LENGTH 32 /* bytes = 256 bits */
  23793. +
  23794. +#define MV_CESA_MAX_CRYPTO_KEY_LENGTH MV_CESA_AES_256_KEY_LENGTH
  23795. +
  23796. +#define MV_CESA_DES_BLOCK_SIZE 8 /* bytes = 64 bits */
  23797. +#define MV_CESA_3DES_BLOCK_SIZE 8 /* bytes = 64 bits */
  23798. +
  23799. +#define MV_CESA_AES_BLOCK_SIZE 16 /* bytes = 128 bits */
  23800. +
  23801. +#define MV_CESA_MAX_IV_LENGTH MV_CESA_AES_BLOCK_SIZE
  23802. +
  23803. +#define MV_CESA_MAX_MAC_KEY_LENGTH 64 /* bytes */
  23804. +
  23805. +typedef struct
  23806. +{
  23807. + MV_U8 cryptoKey[MV_CESA_MAX_CRYPTO_KEY_LENGTH];
  23808. + MV_U8 macKey[MV_CESA_MAX_MAC_KEY_LENGTH];
  23809. + MV_CESA_OPERATION operation;
  23810. + MV_CESA_DIRECTION direction;
  23811. + MV_CESA_CRYPTO_ALG cryptoAlgorithm;
  23812. + MV_CESA_CRYPTO_MODE cryptoMode;
  23813. + MV_U8 cryptoKeyLength;
  23814. + MV_CESA_MAC_MODE macMode;
  23815. + MV_U8 macKeyLength;
  23816. + MV_U8 digestSize;
  23817. +
  23818. +} MV_CESA_OPEN_SESSION;
  23819. +
  23820. +typedef struct
  23821. +{
  23822. + MV_BUF_INFO *pFrags;
  23823. + MV_U16 numFrags;
  23824. + MV_U16 mbufSize;
  23825. +
  23826. +} MV_CESA_MBUF;
  23827. +
  23828. +typedef struct
  23829. +{
  23830. + void* pReqPrv; /* instead of reqId */
  23831. + MV_U32 retCode;
  23832. + MV_16 sessionId;
  23833. +
  23834. +} MV_CESA_RESULT;
  23835. +
  23836. +typedef void (*MV_CESA_CALLBACK) (MV_CESA_RESULT* pResult);
  23837. +
  23838. +
  23839. +typedef struct
  23840. +{
  23841. + void* pReqPrv; /* instead of reqId */
  23842. + MV_CESA_MBUF* pSrc;
  23843. + MV_CESA_MBUF* pDst;
  23844. + MV_CESA_CALLBACK* pFuncCB;
  23845. + MV_16 sessionId;
  23846. + MV_U16 ivFromUser;
  23847. + MV_U16 ivOffset;
  23848. + MV_U16 cryptoOffset;
  23849. + MV_U16 cryptoLength;
  23850. + MV_U16 digestOffset;
  23851. + MV_U16 macOffset;
  23852. + MV_U16 macLength;
  23853. + MV_BOOL skipFlush;
  23854. +} MV_CESA_COMMAND;
  23855. +
  23856. +
  23857. +
  23858. +MV_STATUS mvCesaHalInit (int numOfSession, int queueDepth, char* pSramBase, MV_U32 cryptEngBase, void *osHandle);
  23859. +MV_STATUS mvCesaFinish (void);
  23860. +MV_STATUS mvCesaSessionOpen(MV_CESA_OPEN_SESSION *pSession, short* pSid);
  23861. +MV_STATUS mvCesaSessionClose(short sid);
  23862. +MV_STATUS mvCesaCryptoIvSet(MV_U8* pIV, int ivSize);
  23863. +
  23864. +MV_STATUS mvCesaAction (MV_CESA_COMMAND* pCmd);
  23865. +
  23866. +MV_U32 mvCesaInProcessGet(void);
  23867. +MV_STATUS mvCesaReadyDispatch(void);
  23868. +MV_STATUS mvCesaReadyGet(MV_CESA_RESULT* pResult);
  23869. +MV_BOOL mvCesaIsReady(void);
  23870. +
  23871. +int mvCesaMbufOffset(MV_CESA_MBUF* pMbuf, int offset, int* pBufOffset);
  23872. +MV_STATUS mvCesaCopyFromMbuf(MV_U8* pDst, MV_CESA_MBUF* pSrcMbuf,
  23873. + int offset, int size);
  23874. +MV_STATUS mvCesaCopyToMbuf(MV_U8* pSrc, MV_CESA_MBUF* pDstMbuf,
  23875. + int offset, int size);
  23876. +MV_STATUS mvCesaMbufCopy(MV_CESA_MBUF* pMbufDst, int dstMbufOffset,
  23877. + MV_CESA_MBUF* pMbufSrc, int srcMbufOffset, int size);
  23878. +
  23879. +/********** Debug functions ********/
  23880. +
  23881. +void mvCesaDebugMbuf(const char* str, MV_CESA_MBUF *pMbuf, int offset, int size);
  23882. +void mvCesaDebugSA(short sid, int mode);
  23883. +void mvCesaDebugStats(void);
  23884. +void mvCesaDebugStatsClear(void);
  23885. +void mvCesaDebugRegs(void);
  23886. +void mvCesaDebugStatus(void);
  23887. +void mvCesaDebugQueue(int mode);
  23888. +void mvCesaDebugSram(int mode);
  23889. +void mvCesaDebugSAD(int mode);
  23890. +
  23891. +
  23892. +/******** CESA Private definitions ********/
  23893. +#if (MV_CESA_VERSION >= 2)
  23894. +#if (MV_CACHE_COHERENCY == MV_CACHE_COHER_SW)
  23895. +#define MV_CESA_TDMA_CTRL_VALUE MV_CESA_TDMA_DST_BURST_MASK(MV_CESA_TDMA_BURST_128B) \
  23896. + | MV_CESA_TDMA_SRC_BURST_MASK(MV_CESA_TDMA_BURST_128B) \
  23897. + | MV_CESA_TDMA_OUTSTAND_READ_EN_MASK \
  23898. + | MV_CESA_TDMA_NO_BYTE_SWAP_MASK \
  23899. + | MV_CESA_TDMA_ENABLE_MASK
  23900. +#else
  23901. +#define MV_CESA_TDMA_CTRL_VALUE MV_CESA_TDMA_DST_BURST_MASK(MV_CESA_TDMA_BURST_32B) \
  23902. + | MV_CESA_TDMA_SRC_BURST_MASK(MV_CESA_TDMA_BURST_128B) \
  23903. + /*| MV_CESA_TDMA_OUTSTAND_READ_EN_MASK */\
  23904. + | MV_CESA_TDMA_ENABLE_MASK
  23905. +
  23906. +#endif
  23907. +#else
  23908. +#define MV_CESA_IDMA_CTRL_LOW_VALUE ICCLR_DST_BURST_LIM_128BYTE \
  23909. + | ICCLR_SRC_BURST_LIM_128BYTE \
  23910. + | ICCLR_INT_MODE_MASK \
  23911. + | ICCLR_BLOCK_MODE \
  23912. + | ICCLR_CHAN_ENABLE \
  23913. + | ICCLR_DESC_MODE_16M
  23914. +#endif /* MV_CESA_VERSION >= 2 */
  23915. +
  23916. +#define MV_CESA_MAX_PKT_SIZE (64 * 1024)
  23917. +#define MV_CESA_MAX_MBUF_FRAGS 20
  23918. +
  23919. +#define MV_CESA_MAX_REQ_FRAGS ( (MV_CESA_MAX_PKT_SIZE / MV_CESA_MAX_BUF_SIZE) + 1)
  23920. +
  23921. +#define MV_CESA_MAX_DMA_DESC (MV_CESA_MAX_MBUF_FRAGS*2 + 5)
  23922. +
  23923. +#define MAX_CESA_CHAIN_LENGTH 20
  23924. +
  23925. +typedef enum
  23926. +{
  23927. + MV_CESA_IDLE = 0,
  23928. + MV_CESA_PENDING,
  23929. + MV_CESA_PROCESS,
  23930. + MV_CESA_READY,
  23931. +#if (MV_CESA_VERSION >= 3)
  23932. + MV_CESA_CHAIN,
  23933. +#endif
  23934. +} MV_CESA_STATE;
  23935. +
  23936. +
  23937. +/* Session database */
  23938. +
  23939. +/* Map of Key materials of the session in SRAM.
  23940. + * Each field must be 8 byte aligned
  23941. + * Total size: 32 + 24 + 24 = 80 bytes
  23942. + */
  23943. +typedef struct
  23944. +{
  23945. + MV_U8 cryptoKey[MV_CESA_MAX_CRYPTO_KEY_LENGTH];
  23946. + MV_U8 macInnerIV[MV_CESA_MAX_DIGEST_SIZE];
  23947. + MV_U8 reservedInner[4];
  23948. + MV_U8 macOuterIV[MV_CESA_MAX_DIGEST_SIZE];
  23949. + MV_U8 reservedOuter[4];
  23950. +
  23951. +} MV_CESA_SRAM_SA;
  23952. +
  23953. +typedef struct
  23954. +{
  23955. + MV_CESA_SRAM_SA* pSramSA;
  23956. + MV_U32 config;
  23957. + MV_U8 cryptoKeyLength;
  23958. + MV_U8 cryptoIvSize;
  23959. + MV_U8 cryptoBlockSize;
  23960. + MV_U8 digestSize;
  23961. + MV_U8 macKeyLength;
  23962. + MV_U8 valid;
  23963. + MV_U8 ctrMode;
  23964. + MV_U32 count;
  23965. +
  23966. +} MV_CESA_SA;
  23967. +
  23968. +/* DMA list management */
  23969. +typedef struct
  23970. +{
  23971. + MV_DMA_DESC* pDmaFirst;
  23972. + MV_DMA_DESC* pDmaLast;
  23973. +
  23974. +} MV_CESA_DMA;
  23975. +
  23976. +
  23977. +typedef struct
  23978. +{
  23979. + MV_U8 numFrag;
  23980. + MV_U8 nextFrag;
  23981. + int bufOffset;
  23982. + int cryptoSize;
  23983. + int macSize;
  23984. + int newDigestOffset;
  23985. + MV_U8 orgDigest[MV_CESA_MAX_DIGEST_SIZE];
  23986. +
  23987. +} MV_CESA_FRAGS;
  23988. +
  23989. +/* Request queue */
  23990. +typedef struct
  23991. +{
  23992. + MV_U8 state;
  23993. + MV_U8 fragMode;
  23994. + MV_U8 fixOffset;
  23995. + MV_CESA_COMMAND* pCmd;
  23996. + MV_CESA_COMMAND* pOrgCmd;
  23997. + MV_BUF_INFO dmaDescBuf;
  23998. + MV_CESA_DMA dma[MV_CESA_MAX_REQ_FRAGS];
  23999. + MV_BUF_INFO cesaDescBuf;
  24000. + MV_CESA_DESC* pCesaDesc;
  24001. + MV_CESA_FRAGS frags;
  24002. +
  24003. +
  24004. +} MV_CESA_REQ;
  24005. +
  24006. +
  24007. +/* SRAM map */
  24008. +/* Total SRAM size calculation */
  24009. +/* SRAM size =
  24010. + * MV_CESA_MAX_BUF_SIZE +
  24011. + * sizeof(MV_CESA_DESC) +
  24012. + * MV_CESA_MAX_IV_LENGTH +
  24013. + * MV_CESA_MAX_IV_LENGTH +
  24014. + * MV_CESA_MAX_DIGEST_SIZE +
  24015. + * sizeof(MV_CESA_SRAM_SA)
  24016. + * = 1600 + 32 + 16 + 16 + 24 + 80 + 280 (reserved) = 2048 bytes
  24017. + * = 3200 + 32 + 16 + 16 + 24 + 80 + 728 (reserved) = 4096 bytes
  24018. + */
  24019. +typedef struct
  24020. +{
  24021. + MV_U8 buf[MV_CESA_MAX_BUF_SIZE];
  24022. + MV_CESA_DESC desc;
  24023. + MV_U8 cryptoIV[MV_CESA_MAX_IV_LENGTH];
  24024. + MV_U8 tempCryptoIV[MV_CESA_MAX_IV_LENGTH];
  24025. + MV_U8 tempDigest[MV_CESA_MAX_DIGEST_SIZE+4];
  24026. + MV_CESA_SRAM_SA sramSA;
  24027. +
  24028. +} MV_CESA_SRAM_MAP;
  24029. +
  24030. +
  24031. +typedef struct
  24032. +{
  24033. + MV_U32 openedCount;
  24034. + MV_U32 closedCount;
  24035. + MV_U32 fragCount;
  24036. + MV_U32 reqCount;
  24037. + MV_U32 maxReqCount;
  24038. + MV_U32 procCount;
  24039. + MV_U32 readyCount;
  24040. + MV_U32 notReadyCount;
  24041. + MV_U32 startCount;
  24042. +#if (MV_CESA_VERSION >= 3)
  24043. + MV_U32 maxChainUsage;
  24044. +#endif
  24045. +
  24046. +} MV_CESA_STATS;
  24047. +
  24048. +
  24049. +/* External variables */
  24050. +
  24051. +extern MV_CESA_STATS cesaStats;
  24052. +extern MV_CESA_FRAGS cesaFrags;
  24053. +
  24054. +extern MV_BUF_INFO cesaSramSaBuf;
  24055. +
  24056. +extern MV_CESA_SA* pCesaSAD;
  24057. +extern MV_U16 cesaMaxSA;
  24058. +
  24059. +extern MV_CESA_REQ* pCesaReqFirst;
  24060. +extern MV_CESA_REQ* pCesaReqLast;
  24061. +extern MV_CESA_REQ* pCesaReqEmpty;
  24062. +extern MV_CESA_REQ* pCesaReqProcess;
  24063. +extern int cesaQueueDepth;
  24064. +extern int cesaReqResources;
  24065. +#if (MV_CESA_VERSION>= 3)
  24066. +extern MV_U32 cesaChainLength;
  24067. +#endif
  24068. +
  24069. +extern MV_CESA_SRAM_MAP* cesaSramVirtPtr;
  24070. +extern MV_U32 cesaSramPhysAddr;
  24071. +
  24072. +static INLINE MV_ULONG mvCesaVirtToPhys(MV_BUF_INFO* pBufInfo, void* pVirt)
  24073. +{
  24074. + return (pBufInfo->bufPhysAddr + ((MV_U8*)pVirt - pBufInfo->bufVirtPtr));
  24075. +}
  24076. +
  24077. +/* Additional DEBUG functions */
  24078. +void mvCesaDebugSramSA(MV_CESA_SRAM_SA* pSramSA, int mode);
  24079. +void mvCesaDebugCmd(MV_CESA_COMMAND* pCmd, int mode);
  24080. +void mvCesaDebugDescriptor(MV_CESA_DESC* pDesc);
  24081. +
  24082. +
  24083. +
  24084. +#endif /* __mvCesa_h__ */
  24085. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesaDebug.c linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesaDebug.c
  24086. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesaDebug.c 1970-01-01 01:00:00.000000000 +0100
  24087. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesaDebug.c 2011-08-01 14:38:18.000000000 +0200
  24088. @@ -0,0 +1,484 @@
  24089. +/*******************************************************************************
  24090. +Copyright (C) Marvell International Ltd. and its affiliates
  24091. +
  24092. +This software file (the "File") is owned and distributed by Marvell
  24093. +International Ltd. and/or its affiliates ("Marvell") under the following
  24094. +alternative licensing terms. Once you have made an election to distribute the
  24095. +File under one of the following license alternatives, please (i) delete this
  24096. +introductory statement regarding license alternatives, (ii) delete the two
  24097. +license alternatives that you have not elected to use and (iii) preserve the
  24098. +Marvell copyright notice above.
  24099. +
  24100. +********************************************************************************
  24101. +Marvell Commercial License Option
  24102. +
  24103. +If you received this File from Marvell and you have entered into a commercial
  24104. +license agreement (a "Commercial License") with Marvell, the File is licensed
  24105. +to you under the terms of the applicable Commercial License.
  24106. +
  24107. +********************************************************************************
  24108. +Marvell GPL License Option
  24109. +
  24110. +If you received this File from Marvell, you may opt to use, redistribute and/or
  24111. +modify this File in accordance with the terms and conditions of the General
  24112. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  24113. +available along with the File in the license.txt file or by writing to the Free
  24114. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  24115. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  24116. +
  24117. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  24118. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  24119. +DISCLAIMED. The GPL License provides additional details about this warranty
  24120. +disclaimer.
  24121. +********************************************************************************
  24122. +Marvell BSD License Option
  24123. +
  24124. +If you received this File from Marvell, you may opt to use, redistribute and/or
  24125. +modify this File under the following licensing terms.
  24126. +Redistribution and use in source and binary forms, with or without modification,
  24127. +are permitted provided that the following conditions are met:
  24128. +
  24129. + * Redistributions of source code must retain the above copyright notice,
  24130. + this list of conditions and the following disclaimer.
  24131. +
  24132. + * Redistributions in binary form must reproduce the above copyright
  24133. + notice, this list of conditions and the following disclaimer in the
  24134. + documentation and/or other materials provided with the distribution.
  24135. +
  24136. + * Neither the name of Marvell nor the names of its contributors may be
  24137. + used to endorse or promote products derived from this software without
  24138. + specific prior written permission.
  24139. +
  24140. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  24141. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  24142. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  24143. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  24144. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24145. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24146. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  24147. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24148. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24149. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24150. +
  24151. +*******************************************************************************/
  24152. +
  24153. +#include "mvOs.h"
  24154. +#include "mvDebug.h"
  24155. +
  24156. +#include "cesa/mvMD5.h"
  24157. +#include "cesa/mvSHA1.h"
  24158. +
  24159. +#include "cesa/mvCesa.h"
  24160. +#include "cesa/mvCesaRegs.h"
  24161. +#include "cesa/AES/mvAes.h"
  24162. +
  24163. +static const char* mvCesaDebugStateStr(MV_CESA_STATE state)
  24164. +{
  24165. + switch(state)
  24166. + {
  24167. + case MV_CESA_IDLE:
  24168. + return "Idle";
  24169. +
  24170. + case MV_CESA_PENDING:
  24171. + return "Pend";
  24172. +
  24173. + case MV_CESA_PROCESS:
  24174. + return "Proc";
  24175. +
  24176. + case MV_CESA_READY:
  24177. + return "Ready";
  24178. +
  24179. + default:
  24180. + break;
  24181. + }
  24182. + return "Unknown";
  24183. +}
  24184. +
  24185. +static const char* mvCesaDebugOperStr(MV_CESA_OPERATION oper)
  24186. +{
  24187. + switch(oper)
  24188. + {
  24189. + case MV_CESA_MAC_ONLY:
  24190. + return "MacOnly";
  24191. +
  24192. + case MV_CESA_CRYPTO_ONLY:
  24193. + return "CryptoOnly";
  24194. +
  24195. + case MV_CESA_MAC_THEN_CRYPTO:
  24196. + return "MacCrypto";
  24197. +
  24198. + case MV_CESA_CRYPTO_THEN_MAC:
  24199. + return "CryptoMac";
  24200. +
  24201. + default:
  24202. + break;
  24203. + }
  24204. + return "Null";
  24205. +}
  24206. +
  24207. +static const char* mvCesaDebugCryptoAlgStr(MV_CESA_CRYPTO_ALG cryptoAlg)
  24208. +{
  24209. + switch(cryptoAlg)
  24210. + {
  24211. + case MV_CESA_CRYPTO_DES:
  24212. + return "DES";
  24213. +
  24214. + case MV_CESA_CRYPTO_3DES:
  24215. + return "3DES";
  24216. +
  24217. + case MV_CESA_CRYPTO_AES:
  24218. + return "AES";
  24219. +
  24220. + default:
  24221. + break;
  24222. + }
  24223. + return "Null";
  24224. +}
  24225. +
  24226. +static const char* mvCesaDebugMacModeStr(MV_CESA_MAC_MODE macMode)
  24227. +{
  24228. + switch(macMode)
  24229. + {
  24230. + case MV_CESA_MAC_MD5:
  24231. + return "MD5";
  24232. +
  24233. + case MV_CESA_MAC_SHA1:
  24234. + return "SHA1";
  24235. +
  24236. + case MV_CESA_MAC_HMAC_MD5:
  24237. + return "HMAC-MD5";
  24238. +
  24239. + case MV_CESA_MAC_HMAC_SHA1:
  24240. + return "HMAC_SHA1";
  24241. +
  24242. + default:
  24243. + break;
  24244. + }
  24245. + return "Null";
  24246. +}
  24247. +
  24248. +void mvCesaDebugCmd(MV_CESA_COMMAND* pCmd, int mode)
  24249. +{
  24250. + mvOsPrintf("pCmd=%p, pReqPrv=%p, pSrc=%p, pDst=%p, pCB=%p, sid=%d\n",
  24251. + pCmd, pCmd->pReqPrv, pCmd->pSrc, pCmd->pDst,
  24252. + pCmd->pFuncCB, pCmd->sessionId);
  24253. + mvOsPrintf("isUser=%d, ivOffs=%d, crOffs=%d, crLen=%d, digest=%d, macOffs=%d, macLen=%d\n",
  24254. + pCmd->ivFromUser, pCmd->ivOffset, pCmd->cryptoOffset, pCmd->cryptoLength,
  24255. + pCmd->digestOffset, pCmd->macOffset, pCmd->macLength);
  24256. +}
  24257. +
  24258. +/* no need to use in tool */
  24259. +void mvCesaDebugMbuf(const char* str, MV_CESA_MBUF *pMbuf, int offset, int size)
  24260. +{
  24261. + int frag, len, fragOffset;
  24262. +
  24263. + if(str != NULL)
  24264. + mvOsPrintf("%s: pMbuf=%p, numFrags=%d, mbufSize=%d\n",
  24265. + str, pMbuf, pMbuf->numFrags, pMbuf->mbufSize);
  24266. +
  24267. + frag = mvCesaMbufOffset(pMbuf, offset, &fragOffset);
  24268. + if(frag == MV_INVALID)
  24269. + {
  24270. + mvOsPrintf("CESA Mbuf Error: offset (%d) out of range\n", offset);
  24271. + return;
  24272. + }
  24273. +
  24274. + for(; frag<pMbuf->numFrags; frag++)
  24275. + {
  24276. + mvOsPrintf("#%2d. bufVirt=%p, bufSize=%d\n",
  24277. + frag, pMbuf->pFrags[frag].bufVirtPtr,
  24278. + pMbuf->pFrags[frag].bufSize);
  24279. + if(size > 0)
  24280. + {
  24281. + len = MV_MIN(pMbuf->pFrags[frag].bufSize, size);
  24282. + mvDebugMemDump(pMbuf->pFrags[frag].bufVirtPtr+fragOffset, len, 1);
  24283. + size -= len;
  24284. + fragOffset = 0;
  24285. + }
  24286. + }
  24287. +}
  24288. +
  24289. +void mvCesaDebugRegs(void)
  24290. +{
  24291. + mvOsPrintf("\t CESA Registers:\n");
  24292. +
  24293. + mvOsPrintf("MV_CESA_CMD_REG : 0x%X = 0x%08x\n",
  24294. + MV_CESA_CMD_REG,
  24295. + MV_REG_READ( MV_CESA_CMD_REG ) );
  24296. +
  24297. + mvOsPrintf("MV_CESA_CHAN_DESC_OFFSET_REG : 0x%X = 0x%08x\n",
  24298. + MV_CESA_CHAN_DESC_OFFSET_REG,
  24299. + MV_REG_READ(MV_CESA_CHAN_DESC_OFFSET_REG) );
  24300. +
  24301. + mvOsPrintf("MV_CESA_CFG_REG : 0x%X = 0x%08x\n",
  24302. + MV_CESA_CFG_REG,
  24303. + MV_REG_READ( MV_CESA_CFG_REG ) );
  24304. +
  24305. + mvOsPrintf("MV_CESA_STATUS_REG : 0x%X = 0x%08x\n",
  24306. + MV_CESA_STATUS_REG,
  24307. + MV_REG_READ( MV_CESA_STATUS_REG ) );
  24308. +
  24309. + mvOsPrintf("MV_CESA_ISR_CAUSE_REG : 0x%X = 0x%08x\n",
  24310. + MV_CESA_ISR_CAUSE_REG,
  24311. + MV_REG_READ( MV_CESA_ISR_CAUSE_REG ) );
  24312. +
  24313. + mvOsPrintf("MV_CESA_ISR_MASK_REG : 0x%X = 0x%08x\n",
  24314. + MV_CESA_ISR_MASK_REG,
  24315. + MV_REG_READ( MV_CESA_ISR_MASK_REG ) );
  24316. +#if (MV_CESA_VERSION >= 2)
  24317. + mvOsPrintf("MV_CESA_TDMA_CTRL_REG : 0x%X = 0x%08x\n",
  24318. + MV_CESA_TDMA_CTRL_REG,
  24319. + MV_REG_READ( MV_CESA_TDMA_CTRL_REG ) );
  24320. +
  24321. + mvOsPrintf("MV_CESA_TDMA_BYTE_COUNT_REG : 0x%X = 0x%08x\n",
  24322. + MV_CESA_TDMA_BYTE_COUNT_REG,
  24323. + MV_REG_READ( MV_CESA_TDMA_BYTE_COUNT_REG ) );
  24324. +
  24325. + mvOsPrintf("MV_CESA_TDMA_SRC_ADDR_REG : 0x%X = 0x%08x\n",
  24326. + MV_CESA_TDMA_SRC_ADDR_REG,
  24327. + MV_REG_READ( MV_CESA_TDMA_SRC_ADDR_REG ) );
  24328. +
  24329. + mvOsPrintf("MV_CESA_TDMA_DST_ADDR_REG : 0x%X = 0x%08x\n",
  24330. + MV_CESA_TDMA_DST_ADDR_REG,
  24331. + MV_REG_READ( MV_CESA_TDMA_DST_ADDR_REG ) );
  24332. +
  24333. + mvOsPrintf("MV_CESA_TDMA_NEXT_DESC_PTR_REG : 0x%X = 0x%08x\n",
  24334. + MV_CESA_TDMA_NEXT_DESC_PTR_REG,
  24335. + MV_REG_READ( MV_CESA_TDMA_NEXT_DESC_PTR_REG ) );
  24336. +
  24337. + mvOsPrintf("MV_CESA_TDMA_CURR_DESC_PTR_REG : 0x%X = 0x%08x\n",
  24338. + MV_CESA_TDMA_CURR_DESC_PTR_REG,
  24339. + MV_REG_READ( MV_CESA_TDMA_CURR_DESC_PTR_REG ) );
  24340. +
  24341. + mvOsPrintf("MV_CESA_TDMA_ERROR_CAUSE_REG : 0x%X = 0x%08x\n",
  24342. + MV_CESA_TDMA_ERROR_CAUSE_REG,
  24343. + MV_REG_READ( MV_CESA_TDMA_ERROR_CAUSE_REG ) );
  24344. +
  24345. + mvOsPrintf("MV_CESA_TDMA_ERROR_MASK_REG : 0x%X = 0x%08x\n",
  24346. + MV_CESA_TDMA_ERROR_MASK_REG,
  24347. + MV_REG_READ( MV_CESA_TDMA_ERROR_CAUSE_REG ) );
  24348. +
  24349. +#endif
  24350. +}
  24351. +
  24352. +void mvCesaDebugStatus(void)
  24353. +{
  24354. + mvOsPrintf("\n\t CESA Status\n\n");
  24355. +
  24356. + mvOsPrintf("pReqQ=%p, qDepth=%d, reqSize=%ld bytes, qRes=%d, ",
  24357. + pCesaReqFirst, cesaQueueDepth, sizeof(MV_CESA_REQ),
  24358. + cesaReqResources);
  24359. +#if (MV_CESA_VERSION >= 3)
  24360. + mvOsPrintf("chainLength=%u\n",cesaChainLength);
  24361. +#else
  24362. + mvOsPrintf("\n");
  24363. +#endif
  24364. +
  24365. + mvOsPrintf("pSAD=%p, maxSA=%d, sizeSA=%ld bytes\n",
  24366. + pCesaSAD, cesaMaxSA, sizeof(MV_CESA_SA));
  24367. +
  24368. + mvOsPrintf("\n");
  24369. +
  24370. + mvCesaDebugRegs();
  24371. + mvCesaDebugStats();
  24372. + mvCesaDebugStatsClear();
  24373. +}
  24374. +
  24375. +void mvCesaDebugDescriptor(MV_CESA_DESC* pDesc)
  24376. +{
  24377. + mvOsPrintf("config=0x%08x, crSrcOffs=0x%04x, crDstOffs=0x%04x\n",
  24378. + pDesc->config, pDesc->cryptoSrcOffset, pDesc->cryptoDstOffset);
  24379. +
  24380. + mvOsPrintf("crLen=0x%04x, crKeyOffs=0x%04x, ivOffs=0x%04x, ivBufOffs=0x%04x\n",
  24381. + pDesc->cryptoDataLen, pDesc->cryptoKeyOffset,
  24382. + pDesc->cryptoIvOffset, pDesc->cryptoIvBufOffset);
  24383. +
  24384. + mvOsPrintf("macSrc=0x%04x, digest=0x%04x, macLen=0x%04x, inIv=0x%04x, outIv=0x%04x\n",
  24385. + pDesc->macSrcOffset, pDesc->macDigestOffset, pDesc->macDataLen,
  24386. + pDesc->macInnerIvOffset, pDesc->macOuterIvOffset);
  24387. +}
  24388. +
  24389. +void mvCesaDebugQueue(int mode)
  24390. +{
  24391. + mvOsPrintf("\n\t CESA Request Queue:\n\n");
  24392. +
  24393. + mvOsPrintf("pFirstReq=%p, pLastReq=%p, qDepth=%d, reqSize=%ld bytes\n",
  24394. + pCesaReqFirst, pCesaReqLast, cesaQueueDepth, sizeof(MV_CESA_REQ));
  24395. +
  24396. + mvOsPrintf("pEmpty=%p, pProcess=%p, qResources=%d\n",
  24397. + pCesaReqEmpty, pCesaReqProcess,
  24398. + cesaReqResources);
  24399. +
  24400. + if(mode != 0)
  24401. + {
  24402. + int count = 0;
  24403. + MV_CESA_REQ* pReq = pCesaReqFirst;
  24404. +
  24405. + for(count=0; count<cesaQueueDepth; count++)
  24406. + {
  24407. + /* Print out requsts */
  24408. + mvOsPrintf("%02d. pReq=%p, state=%s, frag=0x%x, pCmd=%p, pDma=%p, pDesc=%p\n",
  24409. + count, pReq, mvCesaDebugStateStr(pReq->state),
  24410. + pReq->fragMode, pReq->pCmd, pReq->dma[0].pDmaFirst, &pReq->pCesaDesc[0]);
  24411. + if(pReq->fragMode != MV_CESA_FRAG_NONE)
  24412. + {
  24413. + int frag;
  24414. +
  24415. + mvOsPrintf("pFrags=%p, num=%d, next=%d, bufOffset=%d, cryptoSize=%d, macSize=%d\n",
  24416. + &pReq->frags, pReq->frags.numFrag, pReq->frags.nextFrag,
  24417. + pReq->frags.bufOffset, pReq->frags.cryptoSize, pReq->frags.macSize);
  24418. + for(frag=0; frag<pReq->frags.numFrag; frag++)
  24419. + {
  24420. + mvOsPrintf("#%d: pDmaFirst=%p, pDesc=%p\n", frag,
  24421. + pReq->dma[frag].pDmaFirst, &pReq->pCesaDesc[frag]);
  24422. + }
  24423. + }
  24424. + if(mode > 1)
  24425. + {
  24426. + /* Print out Command */
  24427. + mvCesaDebugCmd(pReq->pCmd, mode);
  24428. +
  24429. + /* Print out Descriptor */
  24430. + mvCesaDebugDescriptor(&pReq->pCesaDesc[0]);
  24431. + }
  24432. + pReq++;
  24433. + }
  24434. + }
  24435. +}
  24436. +
  24437. +
  24438. +void mvCesaDebugSramSA(MV_CESA_SRAM_SA* pSramSA, int mode)
  24439. +{
  24440. + if(pSramSA == NULL)
  24441. + {
  24442. + mvOsPrintf("cesaSramSA: Unexpected pSramSA=%p\n", pSramSA);
  24443. + return;
  24444. + }
  24445. + mvOsPrintf("pSramSA=%p, sizeSramSA=%ld bytes\n",
  24446. + pSramSA, sizeof(MV_CESA_SRAM_SA));
  24447. +
  24448. + if(mode != 0)
  24449. + {
  24450. + mvOsPrintf("cryptoKey=%p, maxCryptoKey=%d bytes\n",
  24451. + pSramSA->cryptoKey, MV_CESA_MAX_CRYPTO_KEY_LENGTH);
  24452. + mvDebugMemDump(pSramSA->cryptoKey, MV_CESA_MAX_CRYPTO_KEY_LENGTH, 1);
  24453. +
  24454. + mvOsPrintf("macInnerIV=%p, maxInnerIV=%d bytes\n",
  24455. + pSramSA->macInnerIV, MV_CESA_MAX_DIGEST_SIZE);
  24456. + mvDebugMemDump(pSramSA->macInnerIV, MV_CESA_MAX_DIGEST_SIZE, 1);
  24457. +
  24458. + mvOsPrintf("macOuterIV=%p, maxOuterIV=%d bytes\n",
  24459. + pSramSA->macOuterIV, MV_CESA_MAX_DIGEST_SIZE);
  24460. + mvDebugMemDump(pSramSA->macOuterIV, MV_CESA_MAX_DIGEST_SIZE, 1);
  24461. + }
  24462. +}
  24463. +
  24464. +void mvCesaDebugSA(short sid, int mode)
  24465. +{
  24466. + MV_CESA_OPERATION oper;
  24467. + MV_CESA_DIRECTION dir;
  24468. + MV_CESA_CRYPTO_ALG cryptoAlg;
  24469. + MV_CESA_CRYPTO_MODE cryptoMode;
  24470. + MV_CESA_MAC_MODE macMode;
  24471. + MV_CESA_SA* pSA = &pCesaSAD[sid];
  24472. +
  24473. + if( (pSA->valid) || ((pSA->count != 0) && (mode > 0)) || (mode >= 2) )
  24474. + {
  24475. + mvOsPrintf("\n\nCESA SA Entry #%d (%p) - %s (count=%d)\n",
  24476. + sid, pSA,
  24477. + pSA->valid ? "Valid" : "Invalid", pSA->count);
  24478. +
  24479. + oper = (pSA->config & MV_CESA_OPERATION_MASK) >> MV_CESA_OPERATION_OFFSET;
  24480. + dir = (pSA->config & MV_CESA_DIRECTION_MASK) >> MV_CESA_DIRECTION_BIT;
  24481. + mvOsPrintf("%s - %s ", mvCesaDebugOperStr(oper),
  24482. + (dir == MV_CESA_DIR_ENCODE) ? "Encode" : "Decode");
  24483. + if(oper != MV_CESA_MAC_ONLY)
  24484. + {
  24485. + cryptoAlg = (pSA->config & MV_CESA_CRYPTO_ALG_MASK) >> MV_CESA_CRYPTO_ALG_OFFSET;
  24486. + cryptoMode = (pSA->config & MV_CESA_CRYPTO_MODE_MASK) >> MV_CESA_CRYPTO_MODE_BIT;
  24487. + mvOsPrintf("- %s - %s ", mvCesaDebugCryptoAlgStr(cryptoAlg),
  24488. + (cryptoMode == MV_CESA_CRYPTO_ECB) ? "ECB" : "CBC");
  24489. + }
  24490. + if(oper != MV_CESA_CRYPTO_ONLY)
  24491. + {
  24492. + macMode = (pSA->config & MV_CESA_MAC_MODE_MASK) >> MV_CESA_MAC_MODE_OFFSET;
  24493. + mvOsPrintf("- %s ", mvCesaDebugMacModeStr(macMode));
  24494. + }
  24495. + mvOsPrintf("\n");
  24496. +
  24497. + if(mode > 0)
  24498. + {
  24499. + mvOsPrintf("config=0x%08x, cryptoKeySize=%d, digestSize=%d\n",
  24500. + pCesaSAD[sid].config, pCesaSAD[sid].cryptoKeyLength,
  24501. + pCesaSAD[sid].digestSize);
  24502. +
  24503. + mvCesaDebugSramSA(pCesaSAD[sid].pSramSA, mode);
  24504. + }
  24505. + }
  24506. +}
  24507. +
  24508. +
  24509. +/**/
  24510. +void mvCesaDebugSram(int mode)
  24511. +{
  24512. + mvOsPrintf("\n\t SRAM contents: size=%ld, pVirt=%p\n\n",
  24513. + sizeof(MV_CESA_SRAM_MAP), cesaSramVirtPtr);
  24514. +
  24515. + mvOsPrintf("\n\t Sram buffer: size=%d, pVirt=%p\n",
  24516. + MV_CESA_MAX_BUF_SIZE, cesaSramVirtPtr->buf);
  24517. + if(mode != 0)
  24518. + mvDebugMemDump(cesaSramVirtPtr->buf, 64, 1);
  24519. +
  24520. + mvOsPrintf("\n");
  24521. + mvOsPrintf("\n\t Sram descriptor: size=%ld, pVirt=%p\n",
  24522. + sizeof(MV_CESA_DESC), &cesaSramVirtPtr->desc);
  24523. + if(mode != 0)
  24524. + {
  24525. + mvOsPrintf("\n");
  24526. + mvCesaDebugDescriptor(&cesaSramVirtPtr->desc);
  24527. + }
  24528. + mvOsPrintf("\n\t Sram IV: size=%d, pVirt=%p\n",
  24529. + MV_CESA_MAX_IV_LENGTH, &cesaSramVirtPtr->cryptoIV);
  24530. + if(mode != 0)
  24531. + {
  24532. + mvOsPrintf("\n");
  24533. + mvDebugMemDump(cesaSramVirtPtr->cryptoIV, MV_CESA_MAX_IV_LENGTH, 1);
  24534. + }
  24535. + mvOsPrintf("\n");
  24536. + mvCesaDebugSramSA(&cesaSramVirtPtr->sramSA, 0);
  24537. +}
  24538. +
  24539. +void mvCesaDebugSAD(int mode)
  24540. +{
  24541. + int sid;
  24542. +
  24543. + mvOsPrintf("\n\t Cesa SAD status: pSAD=%p, maxSA=%d\n",
  24544. + pCesaSAD, cesaMaxSA);
  24545. +
  24546. + for(sid=0; sid<cesaMaxSA; sid++)
  24547. + {
  24548. + mvCesaDebugSA(sid, mode);
  24549. + }
  24550. +}
  24551. +
  24552. +void mvCesaDebugStats(void)
  24553. +{
  24554. + mvOsPrintf("\n\t Cesa Statistics\n");
  24555. +
  24556. + mvOsPrintf("Opened=%u, Closed=%u\n",
  24557. + cesaStats.openedCount, cesaStats.closedCount);
  24558. + mvOsPrintf("Req=%u, maxReq=%u, frags=%u, start=%u\n",
  24559. + cesaStats.reqCount, cesaStats.maxReqCount,
  24560. + cesaStats.fragCount, cesaStats.startCount);
  24561. +#if (MV_CESA_VERSION >= 3)
  24562. + mvOsPrintf("maxChainUsage=%u\n",cesaStats.maxChainUsage);
  24563. +#endif
  24564. + mvOsPrintf("\n");
  24565. + mvOsPrintf("proc=%u, ready=%u, notReady=%u\n",
  24566. + cesaStats.procCount, cesaStats.readyCount, cesaStats.notReadyCount);
  24567. +}
  24568. +
  24569. +void mvCesaDebugStatsClear(void)
  24570. +{
  24571. + memset(&cesaStats, 0, sizeof(cesaStats));
  24572. +}
  24573. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesaRegs.h linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesaRegs.h
  24574. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesaRegs.h 1970-01-01 01:00:00.000000000 +0100
  24575. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesaRegs.h 2011-08-01 14:38:18.000000000 +0200
  24576. @@ -0,0 +1,357 @@
  24577. +/*******************************************************************************
  24578. +Copyright (C) Marvell International Ltd. and its affiliates
  24579. +
  24580. +This software file (the "File") is owned and distributed by Marvell
  24581. +International Ltd. and/or its affiliates ("Marvell") under the following
  24582. +alternative licensing terms. Once you have made an election to distribute the
  24583. +File under one of the following license alternatives, please (i) delete this
  24584. +introductory statement regarding license alternatives, (ii) delete the two
  24585. +license alternatives that you have not elected to use and (iii) preserve the
  24586. +Marvell copyright notice above.
  24587. +
  24588. +********************************************************************************
  24589. +Marvell Commercial License Option
  24590. +
  24591. +If you received this File from Marvell and you have entered into a commercial
  24592. +license agreement (a "Commercial License") with Marvell, the File is licensed
  24593. +to you under the terms of the applicable Commercial License.
  24594. +
  24595. +********************************************************************************
  24596. +Marvell GPL License Option
  24597. +
  24598. +If you received this File from Marvell, you may opt to use, redistribute and/or
  24599. +modify this File in accordance with the terms and conditions of the General
  24600. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  24601. +available along with the File in the license.txt file or by writing to the Free
  24602. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  24603. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  24604. +
  24605. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  24606. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  24607. +DISCLAIMED. The GPL License provides additional details about this warranty
  24608. +disclaimer.
  24609. +********************************************************************************
  24610. +Marvell BSD License Option
  24611. +
  24612. +If you received this File from Marvell, you may opt to use, redistribute and/or
  24613. +modify this File under the following licensing terms.
  24614. +Redistribution and use in source and binary forms, with or without modification,
  24615. +are permitted provided that the following conditions are met:
  24616. +
  24617. + * Redistributions of source code must retain the above copyright notice,
  24618. + this list of conditions and the following disclaimer.
  24619. +
  24620. + * Redistributions in binary form must reproduce the above copyright
  24621. + notice, this list of conditions and the following disclaimer in the
  24622. + documentation and/or other materials provided with the distribution.
  24623. +
  24624. + * Neither the name of Marvell nor the names of its contributors may be
  24625. + used to endorse or promote products derived from this software without
  24626. + specific prior written permission.
  24627. +
  24628. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  24629. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  24630. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  24631. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  24632. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24633. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24634. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  24635. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24636. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24637. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24638. +
  24639. +*******************************************************************************/
  24640. +
  24641. +#ifndef __mvCesaRegs_h__
  24642. +#define __mvCesaRegs_h__
  24643. +
  24644. +#include "mvTypes.h"
  24645. +
  24646. +typedef struct
  24647. +{
  24648. + /* word 0 */
  24649. + MV_U32 config;
  24650. + /* word 1 */
  24651. + MV_U16 cryptoSrcOffset;
  24652. + MV_U16 cryptoDstOffset;
  24653. + /* word 2 */
  24654. + MV_U16 cryptoDataLen;
  24655. + MV_U16 reserved1;
  24656. + /* word 3 */
  24657. + MV_U16 cryptoKeyOffset;
  24658. + MV_U16 reserved2;
  24659. + /* word 4 */
  24660. + MV_U16 cryptoIvOffset;
  24661. + MV_U16 cryptoIvBufOffset;
  24662. + /* word 5 */
  24663. + MV_U16 macSrcOffset;
  24664. + MV_U16 macTotalLen;
  24665. + /* word 6 */
  24666. + MV_U16 macDigestOffset;
  24667. + MV_U16 macDataLen;
  24668. + /* word 7 */
  24669. + MV_U16 macInnerIvOffset;
  24670. + MV_U16 macOuterIvOffset;
  24671. +
  24672. +} MV_CESA_DESC;
  24673. +
  24674. +/* operation */
  24675. +typedef enum
  24676. +{
  24677. + MV_CESA_MAC_ONLY = 0,
  24678. + MV_CESA_CRYPTO_ONLY = 1,
  24679. + MV_CESA_MAC_THEN_CRYPTO = 2,
  24680. + MV_CESA_CRYPTO_THEN_MAC = 3,
  24681. +
  24682. + MV_CESA_MAX_OPERATION
  24683. +
  24684. +} MV_CESA_OPERATION;
  24685. +
  24686. +#define MV_CESA_OPERATION_OFFSET 0
  24687. +#define MV_CESA_OPERATION_MASK (0x3 << MV_CESA_OPERATION_OFFSET)
  24688. +
  24689. +/* mac algorithm */
  24690. +typedef enum
  24691. +{
  24692. + MV_CESA_MAC_NULL = 0,
  24693. + MV_CESA_MAC_MD5 = 4,
  24694. + MV_CESA_MAC_SHA1 = 5,
  24695. + MV_CESA_MAC_HMAC_MD5 = 6,
  24696. + MV_CESA_MAC_HMAC_SHA1 = 7,
  24697. +
  24698. +} MV_CESA_MAC_MODE;
  24699. +
  24700. +#define MV_CESA_MAC_MODE_OFFSET 4
  24701. +#define MV_CESA_MAC_MODE_MASK (0x7 << MV_CESA_MAC_MODE_OFFSET)
  24702. +
  24703. +typedef enum
  24704. +{
  24705. + MV_CESA_MAC_DIGEST_FULL = 0,
  24706. + MV_CESA_MAC_DIGEST_96B = 1,
  24707. +
  24708. +} MV_CESA_MAC_DIGEST_SIZE;
  24709. +
  24710. +#define MV_CESA_MAC_DIGEST_SIZE_BIT 7
  24711. +#define MV_CESA_MAC_DIGEST_SIZE_MASK (1 << MV_CESA_MAC_DIGEST_SIZE_BIT)
  24712. +
  24713. +
  24714. +typedef enum
  24715. +{
  24716. + MV_CESA_CRYPTO_NULL = 0,
  24717. + MV_CESA_CRYPTO_DES = 1,
  24718. + MV_CESA_CRYPTO_3DES = 2,
  24719. + MV_CESA_CRYPTO_AES = 3,
  24720. +
  24721. +} MV_CESA_CRYPTO_ALG;
  24722. +
  24723. +#define MV_CESA_CRYPTO_ALG_OFFSET 8
  24724. +#define MV_CESA_CRYPTO_ALG_MASK (0x3 << MV_CESA_CRYPTO_ALG_OFFSET)
  24725. +
  24726. +
  24727. +/* direction */
  24728. +typedef enum
  24729. +{
  24730. + MV_CESA_DIR_ENCODE = 0,
  24731. + MV_CESA_DIR_DECODE = 1,
  24732. +
  24733. +} MV_CESA_DIRECTION;
  24734. +
  24735. +#define MV_CESA_DIRECTION_BIT 12
  24736. +#define MV_CESA_DIRECTION_MASK (1 << MV_CESA_DIRECTION_BIT)
  24737. +
  24738. +/* crypto IV mode */
  24739. +typedef enum
  24740. +{
  24741. + MV_CESA_CRYPTO_ECB = 0,
  24742. + MV_CESA_CRYPTO_CBC = 1,
  24743. +
  24744. + /* NO HW Support */
  24745. + MV_CESA_CRYPTO_CTR = 10,
  24746. +
  24747. +} MV_CESA_CRYPTO_MODE;
  24748. +
  24749. +#define MV_CESA_CRYPTO_MODE_BIT 16
  24750. +#define MV_CESA_CRYPTO_MODE_MASK (1 << MV_CESA_CRYPTO_MODE_BIT)
  24751. +
  24752. +/* 3DES mode */
  24753. +typedef enum
  24754. +{
  24755. + MV_CESA_CRYPTO_3DES_EEE = 0,
  24756. + MV_CESA_CRYPTO_3DES_EDE = 1,
  24757. +
  24758. +} MV_CESA_CRYPTO_3DES_MODE;
  24759. +
  24760. +#define MV_CESA_CRYPTO_3DES_MODE_BIT 20
  24761. +#define MV_CESA_CRYPTO_3DES_MODE_MASK (1 << MV_CESA_CRYPTO_3DES_MODE_BIT)
  24762. +
  24763. +
  24764. +/* AES Key Length */
  24765. +typedef enum
  24766. +{
  24767. + MV_CESA_CRYPTO_AES_KEY_128 = 0,
  24768. + MV_CESA_CRYPTO_AES_KEY_192 = 1,
  24769. + MV_CESA_CRYPTO_AES_KEY_256 = 2,
  24770. +
  24771. +} MV_CESA_CRYPTO_AES_KEY_LEN;
  24772. +
  24773. +#define MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET 24
  24774. +#define MV_CESA_CRYPTO_AES_KEY_LEN_MASK (0x3 << MV_CESA_CRYPTO_AES_KEY_LEN_OFFSET)
  24775. +
  24776. +/* Fragmentation mode */
  24777. +typedef enum
  24778. +{
  24779. + MV_CESA_FRAG_NONE = 0,
  24780. + MV_CESA_FRAG_FIRST = 1,
  24781. + MV_CESA_FRAG_LAST = 2,
  24782. + MV_CESA_FRAG_MIDDLE = 3,
  24783. +
  24784. +} MV_CESA_FRAG_MODE;
  24785. +
  24786. +#define MV_CESA_FRAG_MODE_OFFSET 30
  24787. +#define MV_CESA_FRAG_MODE_MASK (0x3 << MV_CESA_FRAG_MODE_OFFSET)
  24788. +/*---------------------------------------------------------------------------*/
  24789. +
  24790. +/********** Security Accelerator Command Register **************/
  24791. +#define MV_CESA_CMD_REG (MV_CESA_REG_BASE + 0xE00)
  24792. +
  24793. +#define MV_CESA_CMD_CHAN_ENABLE_BIT 0
  24794. +#define MV_CESA_CMD_CHAN_ENABLE_MASK (1 << MV_CESA_CMD_CHAN_ENABLE_BIT)
  24795. +
  24796. +#define MV_CESA_CMD_CHAN_DISABLE_BIT 2
  24797. +#define MV_CESA_CMD_CHAN_DISABLE_MASK (1 << MV_CESA_CMD_CHAN_DISABLE_BIT)
  24798. +
  24799. +/********** Security Accelerator Descriptor Pointers Register **********/
  24800. +#define MV_CESA_CHAN_DESC_OFFSET_REG (MV_CESA_REG_BASE + 0xE04)
  24801. +
  24802. +/********** Security Accelerator Configuration Register **********/
  24803. +#define MV_CESA_CFG_REG (MV_CESA_REG_BASE + 0xE08)
  24804. +
  24805. +#define MV_CESA_CFG_STOP_DIGEST_ERR_BIT 0
  24806. +#define MV_CESA_CFG_STOP_DIGEST_ERR_MASK (1 << MV_CESA_CFG_STOP_DIGEST_ERR_BIT)
  24807. +
  24808. +#define MV_CESA_CFG_WAIT_DMA_BIT 7
  24809. +#define MV_CESA_CFG_WAIT_DMA_MASK (1 << MV_CESA_CFG_WAIT_DMA_BIT)
  24810. +
  24811. +#define MV_CESA_CFG_ACT_DMA_BIT 9
  24812. +#define MV_CESA_CFG_ACT_DMA_MASK (1 << MV_CESA_CFG_ACT_DMA_BIT)
  24813. +
  24814. +#define MV_CESA_CFG_CHAIN_MODE_BIT 11
  24815. +#define MV_CESA_CFG_CHAIN_MODE_MASK (1 << MV_CESA_CFG_CHAIN_MODE_BIT)
  24816. +
  24817. +/********** Security Accelerator Status Register ***********/
  24818. +#define MV_CESA_STATUS_REG (MV_CESA_REG_BASE + 0xE0C)
  24819. +
  24820. +#define MV_CESA_STATUS_ACTIVE_BIT 0
  24821. +#define MV_CESA_STATUS_ACTIVE_MASK (1 << MV_CESA_STATUS_ACTIVE_BIT)
  24822. +
  24823. +#define MV_CESA_STATUS_DIGEST_ERR_BIT 8
  24824. +#define MV_CESA_STATUS_DIGEST_ERR_MASK (1 << MV_CESA_STATUS_DIGEST_ERR_BIT)
  24825. +
  24826. +
  24827. +/* Cryptographic Engines and Security Accelerator Interrupt Cause Register */
  24828. +#define MV_CESA_ISR_CAUSE_REG (MV_CESA_REG_BASE + 0xE20)
  24829. +
  24830. +/* Cryptographic Engines and Security Accelerator Interrupt Mask Register */
  24831. +#define MV_CESA_ISR_MASK_REG (MV_CESA_REG_BASE + 0xE24)
  24832. +
  24833. +#define MV_CESA_CAUSE_AUTH_MASK (1 << 0)
  24834. +#define MV_CESA_CAUSE_DES_MASK (1 << 1)
  24835. +#define MV_CESA_CAUSE_AES_ENCR_MASK (1 << 2)
  24836. +#define MV_CESA_CAUSE_AES_DECR_MASK (1 << 3)
  24837. +#define MV_CESA_CAUSE_DES_ALL_MASK (1 << 4)
  24838. +
  24839. +#define MV_CESA_CAUSE_ACC_BIT 5
  24840. +#define MV_CESA_CAUSE_ACC_MASK (1 << MV_CESA_CAUSE_ACC_BIT)
  24841. +
  24842. +#define MV_CESA_CAUSE_ACC_DMA_BIT 7
  24843. +#define MV_CESA_CAUSE_ACC_DMA_MASK (1 << MV_CESA_CAUSE_ACC_DMA_BIT)
  24844. +#define MV_CESA_CAUSE_ACC_DMA_ALL_MASK (3 << MV_CESA_CAUSE_ACC_DMA_BIT)
  24845. +
  24846. +#define MV_CESA_CAUSE_DMA_COMPL_BIT 9
  24847. +#define MV_CESA_CAUSE_DMA_COMPL_MASK (1 << MV_CESA_CAUSE_DMA_COMPL_BIT)
  24848. +
  24849. +#define MV_CESA_CAUSE_DMA_OWN_ERR_BIT 10
  24850. +#define MV_CESA_CAUSE_DMA_OWN_ERR_MASK (1 < MV_CESA_CAUSE_DMA_OWN_ERR_BIT)
  24851. +
  24852. +#define MV_CESA_CAUSE_DMA_CHAIN_PKT_BIT 11
  24853. +#define MV_CESA_CAUSE_DMA_CHAIN_PKT_MASK (1 < MV_CESA_CAUSE_DMA_CHAIN_PKT_BIT)
  24854. +
  24855. +
  24856. +#define MV_CESA_AUTH_DATA_IN_REG (MV_CESA_REG_BASE + 0xd38)
  24857. +#define MV_CESA_AUTH_BIT_COUNT_LOW_REG (MV_CESA_REG_BASE + 0xd20)
  24858. +#define MV_CESA_AUTH_BIT_COUNT_HIGH_REG (MV_CESA_REG_BASE + 0xd24)
  24859. +
  24860. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_REG(i) (MV_CESA_REG_BASE + 0xd00 + (i<<2))
  24861. +
  24862. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_A_REG (MV_CESA_REG_BASE + 0xd00)
  24863. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_B_REG (MV_CESA_REG_BASE + 0xd04)
  24864. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_C_REG (MV_CESA_REG_BASE + 0xd08)
  24865. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_D_REG (MV_CESA_REG_BASE + 0xd0c)
  24866. +#define MV_CESA_AUTH_INIT_VAL_DIGEST_E_REG (MV_CESA_REG_BASE + 0xd10)
  24867. +#define MV_CESA_AUTH_COMMAND_REG (MV_CESA_REG_BASE + 0xd18)
  24868. +
  24869. +#define MV_CESA_AUTH_ALGORITHM_BIT 0
  24870. +#define MV_CESA_AUTH_ALGORITHM_MD5 (0<<AUTH_ALGORITHM_BIT)
  24871. +#define MV_CESA_AUTH_ALGORITHM_SHA1 (1<<AUTH_ALGORITHM_BIT)
  24872. +
  24873. +#define MV_CESA_AUTH_IV_MODE_BIT 1
  24874. +#define MV_CESA_AUTH_IV_MODE_INIT (0<<AUTH_IV_MODE_BIT)
  24875. +#define MV_CESA_AUTH_IV_MODE_CONTINUE (1<<AUTH_IV_MODE_BIT)
  24876. +
  24877. +#define MV_CESA_AUTH_DATA_BYTE_SWAP_BIT 2
  24878. +#define MV_CESA_AUTH_DATA_BYTE_SWAP_MASK (1<<AUTH_DATA_BYTE_SWAP_BIT)
  24879. +
  24880. +
  24881. +#define MV_CESA_AUTH_IV_BYTE_SWAP_BIT 4
  24882. +#define MV_CESA_AUTH_IV_BYTE_SWAP_MASK (1<<AUTH_IV_BYTE_SWAP_BIT)
  24883. +
  24884. +#define MV_CESA_AUTH_TERMINATION_BIT 31
  24885. +#define MV_CESA_AUTH_TERMINATION_MASK (1<<AUTH_TERMINATION_BIT)
  24886. +
  24887. +
  24888. +/*************** TDMA Control Register ************************************************/
  24889. +#define MV_CESA_TDMA_CTRL_REG (MV_CESA_TDMA_REG_BASE + 0x840)
  24890. +
  24891. +#define MV_CESA_TDMA_BURST_32B 3
  24892. +#define MV_CESA_TDMA_BURST_128B 4
  24893. +
  24894. +#define MV_CESA_TDMA_DST_BURST_OFFSET 0
  24895. +#define MV_CESA_TDMA_DST_BURST_ALL_MASK (0x7<<MV_CESA_TDMA_DST_BURST_OFFSET)
  24896. +#define MV_CESA_TDMA_DST_BURST_MASK(burst) ((burst)<<MV_CESA_TDMA_DST_BURST_OFFSET)
  24897. +
  24898. +#define MV_CESA_TDMA_OUTSTAND_READ_EN_BIT 4
  24899. +#define MV_CESA_TDMA_OUTSTAND_READ_EN_MASK (1<<MV_CESA_TDMA_OUTSTAND_READ_EN_BIT)
  24900. +
  24901. +#define MV_CESA_TDMA_SRC_BURST_OFFSET 6
  24902. +#define MV_CESA_TDMA_SRC_BURST_ALL_MASK (0x7<<MV_CESA_TDMA_SRC_BURST_OFFSET)
  24903. +#define MV_CESA_TDMA_SRC_BURST_MASK(burst) ((burst)<<MV_CESA_TDMA_SRC_BURST_OFFSET)
  24904. +
  24905. +#define MV_CESA_TDMA_CHAIN_MODE_BIT 9
  24906. +#define MV_CESA_TDMA_NON_CHAIN_MODE_MASK (1<<MV_CESA_TDMA_CHAIN_MODE_BIT)
  24907. +
  24908. +#define MV_CESA_TDMA_BYTE_SWAP_BIT 11
  24909. +#define MV_CESA_TDMA_BYTE_SWAP_MASK (0 << MV_CESA_TDMA_BYTE_SWAP_BIT)
  24910. +#define MV_CESA_TDMA_NO_BYTE_SWAP_MASK (1 << MV_CESA_TDMA_BYTE_SWAP_BIT)
  24911. +
  24912. +#define MV_CESA_TDMA_ENABLE_BIT 12
  24913. +#define MV_CESA_TDMA_ENABLE_MASK (1<<MV_CESA_TDMA_ENABLE_BIT)
  24914. +
  24915. +#define MV_CESA_TDMA_FETCH_NEXT_DESC_BIT 13
  24916. +#define MV_CESA_TDMA_FETCH_NEXT_DESC_MASK (1<<MV_CESA_TDMA_FETCH_NEXT_DESC_BIT)
  24917. +
  24918. +#define MV_CESA_TDMA_CHAN_ACTIVE_BIT 14
  24919. +#define MV_CESA_TDMA_CHAN_ACTIVE_MASK (1<<MV_CESA_TDMA_CHAN_ACTIVE_BIT)
  24920. +/*------------------------------------------------------------------------------------*/
  24921. +
  24922. +#define MV_CESA_TDMA_BYTE_COUNT_REG (MV_CESA_TDMA_REG_BASE + 0x800)
  24923. +#define MV_CESA_TDMA_SRC_ADDR_REG (MV_CESA_TDMA_REG_BASE + 0x810)
  24924. +#define MV_CESA_TDMA_DST_ADDR_REG (MV_CESA_TDMA_REG_BASE + 0x820)
  24925. +#define MV_CESA_TDMA_NEXT_DESC_PTR_REG (MV_CESA_TDMA_REG_BASE + 0x830)
  24926. +#define MV_CESA_TDMA_CURR_DESC_PTR_REG (MV_CESA_TDMA_REG_BASE + 0x870)
  24927. +
  24928. +#define MV_CESA_TDMA_ERROR_CAUSE_REG (MV_CESA_TDMA_REG_BASE + 0x8C0)
  24929. +#define MV_CESA_TDMA_ERROR_MASK_REG (MV_CESA_TDMA_REG_BASE + 0x8C4)
  24930. +
  24931. +
  24932. +#endif /* __mvCesaRegs_h__ */
  24933. +
  24934. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesaTest.c linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesaTest.c
  24935. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvCesaTest.c 1970-01-01 01:00:00.000000000 +0100
  24936. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvCesaTest.c 2011-08-01 14:38:18.000000000 +0200
  24937. @@ -0,0 +1,3096 @@
  24938. +/*******************************************************************************
  24939. +Copyright (C) Marvell International Ltd. and its affiliates
  24940. +
  24941. +This software file (the "File") is owned and distributed by Marvell
  24942. +International Ltd. and/or its affiliates ("Marvell") under the following
  24943. +alternative licensing terms. Once you have made an election to distribute the
  24944. +File under one of the following license alternatives, please (i) delete this
  24945. +introductory statement regarding license alternatives, (ii) delete the two
  24946. +license alternatives that you have not elected to use and (iii) preserve the
  24947. +Marvell copyright notice above.
  24948. +
  24949. +********************************************************************************
  24950. +Marvell Commercial License Option
  24951. +
  24952. +If you received this File from Marvell and you have entered into a commercial
  24953. +license agreement (a "Commercial License") with Marvell, the File is licensed
  24954. +to you under the terms of the applicable Commercial License.
  24955. +
  24956. +********************************************************************************
  24957. +Marvell GPL License Option
  24958. +
  24959. +If you received this File from Marvell, you may opt to use, redistribute and/or
  24960. +modify this File in accordance with the terms and conditions of the General
  24961. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  24962. +available along with the File in the license.txt file or by writing to the Free
  24963. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  24964. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  24965. +
  24966. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  24967. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  24968. +DISCLAIMED. The GPL License provides additional details about this warranty
  24969. +disclaimer.
  24970. +********************************************************************************
  24971. +Marvell BSD License Option
  24972. +
  24973. +If you received this File from Marvell, you may opt to use, redistribute and/or
  24974. +modify this File under the following licensing terms.
  24975. +Redistribution and use in source and binary forms, with or without modification,
  24976. +are permitted provided that the following conditions are met:
  24977. +
  24978. + * Redistributions of source code must retain the above copyright notice,
  24979. + this list of conditions and the following disclaimer.
  24980. +
  24981. + * Redistributions in binary form must reproduce the above copyright
  24982. + notice, this list of conditions and the following disclaimer in the
  24983. + documentation and/or other materials provided with the distribution.
  24984. +
  24985. + * Neither the name of Marvell nor the names of its contributors may be
  24986. + used to endorse or promote products derived from this software without
  24987. + specific prior written permission.
  24988. +
  24989. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  24990. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  24991. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  24992. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  24993. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24994. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  24995. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  24996. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24997. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  24998. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24999. +
  25000. +*******************************************************************************/
  25001. +
  25002. +#include "mvOs.h"
  25003. +
  25004. +#if defined(MV_VXWORKS)
  25005. +
  25006. +#include "sysLib.h"
  25007. +#include "logLib.h"
  25008. +#include "tickLib.h"
  25009. +#include "intLib.h"
  25010. +#include "config.h"
  25011. +
  25012. +
  25013. +SEM_ID cesaSemId = NULL;
  25014. +SEM_ID cesaWaitSemId = NULL;
  25015. +
  25016. +#define CESA_TEST_LOCK(flags) flags = intLock()
  25017. +#define CESA_TEST_UNLOCK(flags) intUnlock(flags)
  25018. +
  25019. +#define CESA_TEST_WAIT_INIT() cesaWaitSemId = semBCreate(SEM_Q_PRIORITY, SEM_EMPTY)
  25020. +#define CESA_TEST_WAKE_UP() semGive(cesaWaitSemId)
  25021. +#define CESA_TEST_WAIT(cond, ms) semTake(cesaWaitSemId, (sysClkRateGet()*ms)/1000)
  25022. +
  25023. +#define CESA_TEST_TICK_GET() tickGet()
  25024. +#define CESA_TEST_TICK_TO_MS(tick) (((tick)*1000)/sysClkRateGet())
  25025. +
  25026. +#elif defined(MV_LINUX)
  25027. +
  25028. +#include <linux/wait.h>
  25029. +wait_queue_head_t cesaTest_waitq;
  25030. +spinlock_t cesaLock;
  25031. +
  25032. +#define CESA_TEST_LOCK(flags) spin_lock_irqsave( &cesaLock, flags)
  25033. +#define CESA_TEST_UNLOCK(flags) spin_unlock_irqrestore( &cesaLock, flags);
  25034. +
  25035. +#define CESA_TEST_WAIT_INIT() init_waitqueue_head(&cesaTest_waitq)
  25036. +#define CESA_TEST_WAKE_UP() wake_up(&cesaTest_waitq)
  25037. +#define CESA_TEST_WAIT(cond, ms) wait_event_timeout(cesaTest_waitq, (cond), msecs_to_jiffies(ms))
  25038. +
  25039. +#define CESA_TEST_TICK_GET() jiffies
  25040. +#define CESA_TEST_TICK_TO_MS(tick) jiffies_to_msecs(tick)
  25041. +
  25042. +#elif defined(MV_NETBSD)
  25043. +
  25044. +#include <sys/param.h>
  25045. +#include <sys/kernel.h>
  25046. +static int cesaLock;
  25047. +
  25048. +#define CESA_TEST_LOCK(flags) flags = splnet()
  25049. +#define CESA_TEST_UNLOCK(flags) splx(flags)
  25050. +
  25051. +#define CESA_TEST_WAIT_INIT() /* nothing */
  25052. +#define CESA_TEST_WAKE_UP() wakeup(&cesaLock)
  25053. +#define CESA_TEST_WAIT(cond, ms) \
  25054. +do { \
  25055. + while (!(cond)) \
  25056. + tsleep(&cesaLock, PWAIT, "cesatest",mstohz(ms)); \
  25057. +} while (/*CONSTCOND*/0)
  25058. +
  25059. +#define CESA_TEST_TICK_GET() hardclock_ticks
  25060. +#define CESA_TEST_TICK_TO_MS(tick) ((1000/hz)*(tick))
  25061. +
  25062. +#define request_irq(i,h,t,n,a) \
  25063. + !mv_intr_establish((i),IPL_NET,(int(*)(void *))(h),(a))
  25064. +
  25065. +#else
  25066. +#error "Only Linux, VxWorks, or NetBSD OS are supported"
  25067. +#endif
  25068. +
  25069. +#include "mvDebug.h"
  25070. +
  25071. +#include "mvSysHwConfig.h"
  25072. +#include "boardEnv/mvBoardEnvLib.h"
  25073. +#include "ctrlEnv/sys/mvCpuIf.h"
  25074. +#include "cntmr/mvCntmr.h"
  25075. +#include "cesa/mvCesa.h"
  25076. +#include "cesa/mvCesaRegs.h"
  25077. +#include "cesa/mvMD5.h"
  25078. +#include "cesa/mvSHA1.h"
  25079. +
  25080. +#if defined(CONFIG_MV646xx)
  25081. +#include "marvell_pic.h"
  25082. +#endif
  25083. +
  25084. +#define MV_CESA_USE_TIMER_ID 0
  25085. +#define CESA_DEF_BUF_SIZE 1500
  25086. +#define CESA_DEF_BUF_NUM 1
  25087. +#define CESA_DEF_SESSION_NUM 32
  25088. +
  25089. +#define CESA_DEF_ITER_NUM 100
  25090. +
  25091. +#define CESA_DEF_REQ_SIZE 256
  25092. +
  25093. +
  25094. +/* CESA Tests Debug */
  25095. +#undef CESA_TEST_DEBUG
  25096. +
  25097. +#ifdef CESA_TEST_DEBUG
  25098. +
  25099. +# define CESA_TEST_DEBUG_PRINT(msg) mvOsPrintf msg
  25100. +# define CESA_TEST_DEBUG_CODE(code) code
  25101. +
  25102. +typedef struct
  25103. +{
  25104. + int type; /* 0 - isrEmpty, 1 - cesaReadyGet, 2 - cesaAction */
  25105. + MV_U32 timeStamp;
  25106. + MV_U32 cause;
  25107. + MV_U32 realCause;
  25108. + MV_U32 dmaCause;
  25109. + int resources;
  25110. + MV_CESA_REQ* pReqReady;
  25111. + MV_CESA_REQ* pReqEmpty;
  25112. + MV_CESA_REQ* pReqProcess;
  25113. +} MV_CESA_TEST_TRACE;
  25114. +
  25115. +#define MV_CESA_TEST_TRACE_SIZE 25
  25116. +
  25117. +static int cesaTestTraceIdx = 0;
  25118. +static MV_CESA_TEST_TRACE cesaTestTrace[MV_CESA_TEST_TRACE_SIZE];
  25119. +
  25120. +static void cesaTestTraceAdd(int type, MV_U32 cause)
  25121. +{
  25122. + cesaTestTrace[cesaTestTraceIdx].type = type;
  25123. + cesaTestTrace[cesaTestTraceIdx].cause = cause;
  25124. + cesaTestTrace[cesaTestTraceIdx].realCause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  25125. + cesaTestTrace[cesaTestTraceIdx].dmaCause = MV_REG_READ(IDMA_CAUSE_REG);
  25126. + cesaTestTrace[cesaTestTraceIdx].resources = cesaReqResources;
  25127. + cesaTestTrace[cesaTestTraceIdx].pReqReady = pCesaReqReady;
  25128. + cesaTestTrace[cesaTestTraceIdx].pReqEmpty = pCesaReqEmpty;
  25129. + cesaTestTrace[cesaTestTraceIdx].pReqProcess = pCesaReqProcess;
  25130. + cesaTestTrace[cesaTestTraceIdx].timeStamp = mvCntmrRead(MV_CESA_USE_TIMER_ID);
  25131. + cesaTestTraceIdx++;
  25132. + if(cesaTestTraceIdx == MV_CESA_TEST_TRACE_SIZE)
  25133. + cesaTestTraceIdx = 0;
  25134. +}
  25135. +
  25136. +#else
  25137. +
  25138. +# define CESA_TEST_DEBUG_PRINT(msg)
  25139. +# define CESA_TEST_DEBUG_CODE(code)
  25140. +
  25141. +#endif /* CESA_TEST_DEBUG */
  25142. +
  25143. +int cesaExpReqId=0;
  25144. +int cesaCbIter=0;
  25145. +
  25146. +int cesaIdx;
  25147. +int cesaIteration;
  25148. +int cesaRateSize;
  25149. +int cesaReqSize;
  25150. +unsigned long cesaTaskId;
  25151. +int cesaBufNum;
  25152. +int cesaBufSize;
  25153. +int cesaCheckOffset;
  25154. +int cesaCheckSize;
  25155. +int cesaCheckMode;
  25156. +int cesaTestIdx;
  25157. +int cesaCaseIdx;
  25158. +
  25159. +
  25160. +MV_U32 cesaTestIsrCount = 0;
  25161. +MV_U32 cesaTestIsrMissCount = 0;
  25162. +
  25163. +MV_U32 cesaCryptoError = 0;
  25164. +MV_U32 cesaReqIdError = 0;
  25165. +MV_U32 cesaError = 0;
  25166. +
  25167. +char* cesaHexBuffer = NULL;
  25168. +
  25169. +char* cesaBinBuffer = NULL;
  25170. +char* cesaExpBinBuffer = NULL;
  25171. +
  25172. +char* cesaInputHexStr = NULL;
  25173. +char* cesaOutputHexStr = NULL;
  25174. +
  25175. +MV_BUF_INFO cesaReqBufs[CESA_DEF_REQ_SIZE];
  25176. +
  25177. +MV_CESA_COMMAND* cesaCmdRing;
  25178. +MV_CESA_RESULT cesaResult;
  25179. +
  25180. +int cesaTestFull = 0;
  25181. +
  25182. +MV_BOOL cesaIsReady = MV_FALSE;
  25183. +MV_U32 cesaCycles = 0;
  25184. +MV_U32 cesaBeginTicks = 0;
  25185. +MV_U32 cesaEndTicks = 0;
  25186. +MV_U32 cesaRate = 0;
  25187. +MV_U32 cesaRateAfterDot = 0;
  25188. +
  25189. +void *cesaTestOSHandle = NULL;
  25190. +
  25191. +enum
  25192. +{
  25193. + CESA_FAST_CHECK_MODE = 0,
  25194. + CESA_FULL_CHECK_MODE,
  25195. + CESA_NULL_CHECK_MODE,
  25196. + CESA_SHOW_CHECK_MODE,
  25197. + CESA_SW_SHOW_CHECK_MODE,
  25198. + CESA_SW_NULL_CHECK_MODE,
  25199. +
  25200. + CESA_MAX_CHECK_MODE
  25201. +};
  25202. +
  25203. +enum
  25204. +{
  25205. + DES_TEST_TYPE = 0,
  25206. + TRIPLE_DES_TEST_TYPE = 1,
  25207. + AES_TEST_TYPE = 2,
  25208. + MD5_TEST_TYPE = 3,
  25209. + SHA_TEST_TYPE = 4,
  25210. + COMBINED_TEST_TYPE = 5,
  25211. +
  25212. + MAX_TEST_TYPE
  25213. +};
  25214. +
  25215. +/* Tests data base */
  25216. +typedef struct
  25217. +{
  25218. + short sid;
  25219. + char cryptoAlgorithm; /* DES/3DES/AES */
  25220. + char cryptoMode; /* ECB or CBC */
  25221. + char macAlgorithm; /* MD5 / SHA1 */
  25222. + char operation; /* CRYPTO/HMAC/CRYPTO+HMAC/HMAC+CRYPTO */
  25223. + char direction; /* ENCODE(SIGN)/DECODE(VERIFY) */
  25224. + unsigned char* pCryptoKey;
  25225. + int cryptoKeySize;
  25226. + unsigned char* pMacKey;
  25227. + int macKeySize;
  25228. + const char* name;
  25229. +
  25230. +} MV_CESA_TEST_SESSION;
  25231. +
  25232. +typedef struct
  25233. +{
  25234. + MV_CESA_TEST_SESSION* pSessions;
  25235. + int numSessions;
  25236. +
  25237. +} MV_CESA_TEST_DB_ENTRY;
  25238. +
  25239. +typedef struct
  25240. +{
  25241. + char* plainHexStr;
  25242. + char* cipherHexStr;
  25243. + unsigned char* pCryptoIV;
  25244. + int cryptoLength;
  25245. + int macLength;
  25246. + int digestOffset;
  25247. +
  25248. +} MV_CESA_TEST_CASE;
  25249. +
  25250. +typedef struct
  25251. +{
  25252. + int size;
  25253. + const char* outputHexStr;
  25254. +
  25255. +} MV_CESA_SIZE_TEST;
  25256. +
  25257. +static unsigned char cryptoKey1[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
  25258. + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef,
  25259. + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
  25260. +
  25261. +static unsigned char cryptoKey7[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
  25262. +static unsigned char iv1[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef};
  25263. +
  25264. +
  25265. +static unsigned char cryptoKey2[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  25266. + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F};
  25267. +
  25268. +static unsigned char cryptoKey3[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  25269. + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
  25270. + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
  25271. +
  25272. +static unsigned char cryptoKey4[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  25273. + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
  25274. + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
  25275. + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
  25276. +
  25277. +static unsigned char cryptoKey5[] = {0x56, 0xe4, 0x7a, 0x38, 0xc5, 0x59, 0x89, 0x74,
  25278. + 0xbc, 0x46, 0x90, 0x3d, 0xba, 0x29, 0x03, 0x49};
  25279. +
  25280. +
  25281. +static unsigned char key3des1[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF,
  25282. + 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01,
  25283. + 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23};
  25284. +
  25285. +/* Input ASCII string: The quick brown fox jump */
  25286. +static char plain3des1[] = "54686520717566636B2062726F776E20666F78206A756D70";
  25287. +static char cipher3des1[] = "A826FD8CE53B855FCCE21C8112256FE668D5C05DD9B6B900";
  25288. +
  25289. +static unsigned char key3des2[] = {0x62, 0x7f, 0x46, 0x0e, 0x08, 0x10, 0x4a, 0x10,
  25290. + 0x43, 0xcd, 0x26, 0x5d, 0x58, 0x40, 0xea, 0xf1,
  25291. + 0x31, 0x3e, 0xdf, 0x97, 0xdf, 0x2a, 0x8a, 0x8c};
  25292. +
  25293. +static unsigned char iv3des2[] = {0x8e, 0x29, 0xf7, 0x5e, 0xa7, 0x7e, 0x54, 0x75};
  25294. +
  25295. +static char plain3des2[] = "326a494cd33fe756";
  25296. +
  25297. +static char cipher3desCbc2[] = "8e29f75ea77e5475"
  25298. + "b22b8d66de970692";
  25299. +
  25300. +static unsigned char key3des3[] = {0x37, 0xae, 0x5e, 0xbf, 0x46, 0xdf, 0xf2, 0xdc,
  25301. + 0x07, 0x54, 0xb9, 0x4f, 0x31, 0xcb, 0xb3, 0x85,
  25302. + 0x5e, 0x7f, 0xd3, 0x6d, 0xc8, 0x70, 0xbf, 0xae};
  25303. +
  25304. +static unsigned char iv3des3[] = {0x3d, 0x1d, 0xe3, 0xcc, 0x13, 0x2e, 0x3b, 0x65};
  25305. +
  25306. +static char plain3des3[] = "84401f78fe6c10876d8ea23094ea5309";
  25307. +
  25308. +static char cipher3desCbc3[] = "3d1de3cc132e3b65"
  25309. + "7b1f7c7e3b1c948ebd04a75ffba7d2f5";
  25310. +
  25311. +static unsigned char iv5[] = {0x8c, 0xe8, 0x2e, 0xef, 0xbe, 0xa0, 0xda, 0x3c,
  25312. + 0x44, 0x69, 0x9e, 0xd7, 0xdb, 0x51, 0xb7, 0xd9};
  25313. +
  25314. +static unsigned char aesCtrKey[] = {0x76, 0x91, 0xBE, 0x03, 0x5E, 0x50, 0x20, 0xA8,
  25315. + 0xAC, 0x6E, 0x61, 0x85, 0x29, 0xF9, 0xA0, 0xDC};
  25316. +
  25317. +static unsigned char mdKey1[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  25318. + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b};
  25319. +
  25320. +static unsigned char mdKey2[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  25321. + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa};
  25322. +
  25323. +static unsigned char shaKey1[] = {0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  25324. + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
  25325. + 0x0b, 0x0b, 0x0b, 0x0b};
  25326. +
  25327. +static unsigned char shaKey2[] = {0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  25328. + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  25329. + 0xaa, 0xaa, 0xaa, 0xaa};
  25330. +
  25331. +static unsigned char mdKey4[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  25332. + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10};
  25333. +
  25334. +static unsigned char shaKey4[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  25335. + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
  25336. + 0x11, 0x12, 0x13, 0x14};
  25337. +
  25338. +
  25339. +static MV_CESA_TEST_SESSION desTestSessions[] =
  25340. +{
  25341. +/*000*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
  25342. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25343. + MV_CESA_DIR_ENCODE,
  25344. + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
  25345. + NULL, 0,
  25346. + "DES ECB encode",
  25347. + },
  25348. +/*001*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
  25349. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25350. + MV_CESA_DIR_DECODE,
  25351. + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
  25352. + NULL, 0,
  25353. + "DES ECB decode",
  25354. + },
  25355. +/*002*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_CBC,
  25356. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25357. + MV_CESA_DIR_ENCODE,
  25358. + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
  25359. + NULL, 0,
  25360. + "DES CBC encode"
  25361. + },
  25362. +/*003*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_CBC,
  25363. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25364. + MV_CESA_DIR_DECODE,
  25365. + cryptoKey7, sizeof(cryptoKey7)/sizeof(cryptoKey7[0]),
  25366. + NULL, 0,
  25367. + "DES CBC decode"
  25368. + },
  25369. +/*004*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25370. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25371. + MV_CESA_DIR_ENCODE,
  25372. + NULL, 0, NULL, 0,
  25373. + "NULL Crypto Algorithm encode"
  25374. + },
  25375. +};
  25376. +
  25377. +
  25378. +static MV_CESA_TEST_SESSION tripleDesTestSessions[] =
  25379. +{
  25380. +/*100*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  25381. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25382. + MV_CESA_DIR_ENCODE,
  25383. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  25384. + NULL, 0,
  25385. + "3DES ECB encode",
  25386. + },
  25387. +/*101*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  25388. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25389. + MV_CESA_DIR_DECODE,
  25390. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  25391. + NULL, 0,
  25392. + "3DES ECB decode",
  25393. + },
  25394. +/*102*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  25395. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25396. + MV_CESA_DIR_ENCODE,
  25397. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  25398. + NULL, 0,
  25399. + "3DES CBC encode"
  25400. + },
  25401. +/*103*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  25402. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25403. + MV_CESA_DIR_DECODE,
  25404. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  25405. + NULL, 0,
  25406. + "3DES CBC decode"
  25407. + },
  25408. +/*104*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  25409. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25410. + MV_CESA_DIR_ENCODE,
  25411. + key3des1, sizeof(key3des1),
  25412. + NULL, 0,
  25413. + "3DES ECB encode"
  25414. + },
  25415. +/*105*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  25416. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25417. + MV_CESA_DIR_ENCODE,
  25418. + key3des2, sizeof(key3des2),
  25419. + NULL, 0,
  25420. + "3DES ECB encode"
  25421. + },
  25422. +/*106*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  25423. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25424. + MV_CESA_DIR_ENCODE,
  25425. + key3des3, sizeof(key3des3),
  25426. + NULL, 0,
  25427. + "3DES ECB encode"
  25428. + },
  25429. +};
  25430. +
  25431. +
  25432. +static MV_CESA_TEST_SESSION aesTestSessions[] =
  25433. +{
  25434. +/*200*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  25435. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25436. + MV_CESA_DIR_ENCODE,
  25437. + cryptoKey2, sizeof(cryptoKey2)/sizeof(cryptoKey2[0]),
  25438. + NULL, 0,
  25439. + "AES-128 ECB encode"
  25440. + },
  25441. +/*201*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  25442. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25443. + MV_CESA_DIR_DECODE,
  25444. + cryptoKey2, sizeof(cryptoKey2)/sizeof(cryptoKey2[0]),
  25445. + NULL, 0,
  25446. + "AES-128 ECB decode"
  25447. + },
  25448. +/*202*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
  25449. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25450. + MV_CESA_DIR_ENCODE,
  25451. + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
  25452. + NULL, 0,
  25453. + "AES-128 CBC encode"
  25454. + },
  25455. +/*203*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
  25456. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25457. + MV_CESA_DIR_DECODE,
  25458. + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
  25459. + NULL, 0,
  25460. + "AES-128 CBC decode"
  25461. + },
  25462. +/*204*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  25463. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25464. + MV_CESA_DIR_ENCODE,
  25465. + cryptoKey3, sizeof(cryptoKey3)/sizeof(cryptoKey3[0]),
  25466. + NULL, 0,
  25467. + "AES-192 ECB encode"
  25468. + },
  25469. +/*205*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  25470. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25471. + MV_CESA_DIR_DECODE,
  25472. + cryptoKey3, sizeof(cryptoKey3)/sizeof(cryptoKey3[0]),
  25473. + NULL, 0,
  25474. + "AES-192 ECB decode"
  25475. + },
  25476. +/*206*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  25477. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25478. + MV_CESA_DIR_ENCODE,
  25479. + cryptoKey4, sizeof(cryptoKey4)/sizeof(cryptoKey4[0]),
  25480. + NULL, 0,
  25481. + "AES-256 ECB encode"
  25482. + },
  25483. +/*207*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_ECB,
  25484. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25485. + MV_CESA_DIR_DECODE,
  25486. + cryptoKey4, sizeof(cryptoKey4)/sizeof(cryptoKey4[0]),
  25487. + NULL, 0,
  25488. + "AES-256 ECB decode"
  25489. + },
  25490. +/*208*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CTR,
  25491. + MV_CESA_MAC_NULL, MV_CESA_CRYPTO_ONLY,
  25492. + MV_CESA_DIR_ENCODE,
  25493. + aesCtrKey, sizeof(aesCtrKey)/sizeof(aesCtrKey[0]),
  25494. + NULL, 0,
  25495. + "AES-128 CTR encode"
  25496. + },
  25497. +};
  25498. +
  25499. +
  25500. +static MV_CESA_TEST_SESSION md5TestSessions[] =
  25501. +{
  25502. +/*300*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25503. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  25504. + MV_CESA_DIR_ENCODE,
  25505. + NULL, 0,
  25506. + mdKey1, sizeof(mdKey1),
  25507. + "HMAC-MD5 Generate Signature"
  25508. + },
  25509. +/*301*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25510. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  25511. + MV_CESA_DIR_DECODE,
  25512. + NULL, 0,
  25513. + mdKey1, sizeof(mdKey1),
  25514. + "HMAC-MD5 Verify Signature"
  25515. + },
  25516. +/*302*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25517. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  25518. + MV_CESA_DIR_ENCODE,
  25519. + NULL, 0,
  25520. + mdKey2, sizeof(mdKey2),
  25521. + "HMAC-MD5 Generate Signature"
  25522. + },
  25523. +/*303*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25524. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  25525. + MV_CESA_DIR_DECODE,
  25526. + NULL, 0,
  25527. + mdKey2, sizeof(mdKey2),
  25528. + "HMAC-MD5 Verify Signature"
  25529. + },
  25530. +/*304*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25531. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_ONLY,
  25532. + MV_CESA_DIR_ENCODE,
  25533. + NULL, 0,
  25534. + mdKey4, sizeof(mdKey4),
  25535. + "HMAC-MD5 Generate Signature"
  25536. + },
  25537. +/*305*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25538. + MV_CESA_MAC_MD5, MV_CESA_MAC_ONLY,
  25539. + MV_CESA_DIR_ENCODE,
  25540. + NULL, 0,
  25541. + NULL, 0,
  25542. + "HASH-MD5 Generate Signature"
  25543. + },
  25544. +};
  25545. +
  25546. +
  25547. +static MV_CESA_TEST_SESSION shaTestSessions[] =
  25548. +{
  25549. +/*400*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25550. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  25551. + MV_CESA_DIR_ENCODE,
  25552. + NULL, 0,
  25553. + shaKey1, sizeof(shaKey1),
  25554. + "HMAC-SHA1 Generate Signature"
  25555. + },
  25556. +/*401*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25557. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  25558. + MV_CESA_DIR_DECODE,
  25559. + NULL, 0,
  25560. + shaKey1, sizeof(shaKey1),
  25561. + "HMAC-SHA1 Verify Signature"
  25562. + },
  25563. +/*402*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25564. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  25565. + MV_CESA_DIR_ENCODE,
  25566. + NULL, 0,
  25567. + shaKey2, sizeof(shaKey2),
  25568. + "HMAC-SHA1 Generate Signature"
  25569. + },
  25570. +/*403*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25571. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  25572. + MV_CESA_DIR_DECODE,
  25573. + NULL, 0,
  25574. + shaKey2, sizeof(shaKey2),
  25575. + "HMAC-SHA1 Verify Signature"
  25576. + },
  25577. +/*404*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25578. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_MAC_ONLY,
  25579. + MV_CESA_DIR_ENCODE,
  25580. + NULL, 0,
  25581. + shaKey4, sizeof(shaKey4),
  25582. + "HMAC-SHA1 Generate Signature"
  25583. + },
  25584. +/*405*/ {-1, MV_CESA_CRYPTO_NULL, MV_CESA_CRYPTO_ECB,
  25585. + MV_CESA_MAC_SHA1, MV_CESA_MAC_ONLY,
  25586. + MV_CESA_DIR_ENCODE,
  25587. + NULL, 0,
  25588. + NULL, 0,
  25589. + "HASH-SHA1 Generate Signature"
  25590. + },
  25591. +};
  25592. +
  25593. +static MV_CESA_TEST_SESSION combinedTestSessions[] =
  25594. +{
  25595. +/*500*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
  25596. + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
  25597. + MV_CESA_DIR_ENCODE,
  25598. + cryptoKey1, MV_CESA_DES_KEY_LENGTH,
  25599. + mdKey4, sizeof(mdKey4),
  25600. + "DES + MD5 encode"
  25601. + },
  25602. +/*501*/ {-1, MV_CESA_CRYPTO_DES, MV_CESA_CRYPTO_ECB,
  25603. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
  25604. + MV_CESA_DIR_ENCODE,
  25605. + cryptoKey1, MV_CESA_DES_KEY_LENGTH,
  25606. + shaKey4, sizeof(shaKey4),
  25607. + "DES + SHA1 encode"
  25608. + },
  25609. +/*502*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  25610. + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
  25611. + MV_CESA_DIR_ENCODE,
  25612. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  25613. + mdKey4, sizeof(mdKey4),
  25614. + "3DES + MD5 encode"
  25615. + },
  25616. +/*503*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  25617. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
  25618. + MV_CESA_DIR_ENCODE,
  25619. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  25620. + shaKey4, sizeof(shaKey4),
  25621. + "3DES + SHA1 encode"
  25622. + },
  25623. +/*504*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  25624. + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
  25625. + MV_CESA_DIR_ENCODE,
  25626. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  25627. + mdKey4, sizeof(mdKey4),
  25628. + "3DES CBC + MD5 encode"
  25629. + },
  25630. +/*505*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_CBC,
  25631. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
  25632. + MV_CESA_DIR_ENCODE,
  25633. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  25634. + shaKey4, sizeof(shaKey4),
  25635. + "3DES CBC + SHA1 encode"
  25636. + },
  25637. +/*506*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
  25638. + MV_CESA_MAC_HMAC_MD5, MV_CESA_CRYPTO_THEN_MAC,
  25639. + MV_CESA_DIR_ENCODE,
  25640. + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
  25641. + mdKey4, sizeof(mdKey4),
  25642. + "AES-128 CBC + MD5 encode"
  25643. + },
  25644. +/*507*/ {-1, MV_CESA_CRYPTO_AES, MV_CESA_CRYPTO_CBC,
  25645. + MV_CESA_MAC_HMAC_SHA1, MV_CESA_CRYPTO_THEN_MAC,
  25646. + MV_CESA_DIR_ENCODE,
  25647. + cryptoKey5, sizeof(cryptoKey5)/sizeof(cryptoKey5[0]),
  25648. + shaKey4, sizeof(shaKey4),
  25649. + "AES-128 CBC + SHA1 encode"
  25650. + },
  25651. +/*508*/ {-1, MV_CESA_CRYPTO_3DES, MV_CESA_CRYPTO_ECB,
  25652. + MV_CESA_MAC_HMAC_MD5, MV_CESA_MAC_THEN_CRYPTO,
  25653. + MV_CESA_DIR_DECODE,
  25654. + cryptoKey1, sizeof(cryptoKey1)/sizeof(cryptoKey1[0]),
  25655. + mdKey4, sizeof(mdKey4),
  25656. + "HMAC-MD5 + 3DES decode"
  25657. + },
  25658. +};
  25659. +
  25660. +
  25661. +static MV_CESA_TEST_DB_ENTRY cesaTestsDB[MAX_TEST_TYPE+1] =
  25662. +{
  25663. + { desTestSessions, sizeof(desTestSessions)/sizeof(desTestSessions[0]) },
  25664. + { tripleDesTestSessions, sizeof(tripleDesTestSessions)/sizeof(tripleDesTestSessions[0]) },
  25665. + { aesTestSessions, sizeof(aesTestSessions)/sizeof(aesTestSessions[0]) },
  25666. + { md5TestSessions, sizeof(md5TestSessions)/sizeof(md5TestSessions[0]) },
  25667. + { shaTestSessions, sizeof(shaTestSessions)/sizeof(shaTestSessions[0]) },
  25668. + { combinedTestSessions, sizeof(combinedTestSessions)/sizeof(combinedTestSessions[0]) },
  25669. + { NULL, 0 }
  25670. +};
  25671. +
  25672. +
  25673. +char cesaNullPlainHexText[] = "000000000000000000000000000000000000000000000000";
  25674. +
  25675. +char cesaPlainAsciiText[] = "Now is the time for all ";
  25676. +char cesaPlainHexEbc[] = "4e6f77206973207468652074696d6520666f7220616c6c20";
  25677. +char cesaCipherHexEcb[] = "3fa40e8a984d48156a271787ab8883f9893d51ec4b563b53";
  25678. +char cesaPlainHexCbc[] = "1234567890abcdef4e6f77206973207468652074696d6520666f7220616c6c20";
  25679. +char cesaCipherHexCbc[] = "1234567890abcdefe5c7cdde872bf27c43e934008c389c0f683788499a7c05f6";
  25680. +
  25681. +char cesaAesPlainHexEcb[] = "000102030405060708090a0b0c0d0e0f";
  25682. +char cesaAes128cipherHexEcb[] = "0a940bb5416ef045f1c39458c653ea5a";
  25683. +char cesaAes192cipherHexEcb[] = "0060bffe46834bb8da5cf9a61ff220ae";
  25684. +char cesaAes256cipherHexEcb[] = "5a6e045708fb7196f02e553d02c3a692";
  25685. +
  25686. +char cesaAsciiStr1[] = "Hi There";
  25687. +char cesaDataHexStr1[] = "4869205468657265";
  25688. +char cesaHmacMd5digestHex1[] = "9294727a3638bb1c13f48ef8158bfc9d";
  25689. +char cesaHmacSha1digestHex1[] = "b617318655057264e28bc0b6fb378c8ef146be00";
  25690. +char cesaDataAndMd5digest1[] = "48692054686572659294727a3638bb1c13f48ef8158bfc9d";
  25691. +char cesaDataAndSha1digest1[] = "4869205468657265b617318655057264e28bc0b6fb378c8ef146be00";
  25692. +
  25693. +char cesaAesPlainText[] = "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
  25694. + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
  25695. + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
  25696. + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
  25697. +
  25698. +char cesaAes128CipherCbc[] = "c30e32ffedc0774e6aff6af0869f71aa"
  25699. + "0f3af07a9a31a9c684db207eb0ef8e4e"
  25700. + "35907aa632c3ffdf868bb7b29d3d46ad"
  25701. + "83ce9f9a102ee99d49a53e87f4c3da55";
  25702. +
  25703. +char cesaAesIvPlainText[] = "8ce82eefbea0da3c44699ed7db51b7d9"
  25704. + "a0a1a2a3a4a5a6a7a8a9aaabacadaeaf"
  25705. + "b0b1b2b3b4b5b6b7b8b9babbbcbdbebf"
  25706. + "c0c1c2c3c4c5c6c7c8c9cacbcccdcecf"
  25707. + "d0d1d2d3d4d5d6d7d8d9dadbdcdddedf";
  25708. +
  25709. +char cesaAes128IvCipherCbc[] = "8ce82eefbea0da3c44699ed7db51b7d9"
  25710. + "c30e32ffedc0774e6aff6af0869f71aa"
  25711. + "0f3af07a9a31a9c684db207eb0ef8e4e"
  25712. + "35907aa632c3ffdf868bb7b29d3d46ad"
  25713. + "83ce9f9a102ee99d49a53e87f4c3da55";
  25714. +
  25715. +char cesaAesCtrPlain[] = "00E0017B27777F3F4A1786F000000001"
  25716. + "000102030405060708090A0B0C0D0E0F"
  25717. + "101112131415161718191A1B1C1D1E1F"
  25718. + "20212223";
  25719. +
  25720. +char cesaAesCtrCipher[] = "00E0017B27777F3F4A1786F000000001"
  25721. + "C1CF48A89F2FFDD9CF4652E9EFDB72D7"
  25722. + "4540A42BDE6D7836D59A5CEAAEF31053"
  25723. + "25B2072F";
  25724. +
  25725. +
  25726. +
  25727. +/* Input cesaHmacHex3 is '0xdd' repeated 50 times */
  25728. +char cesaHmacMd5digestHex3[] = "56be34521d144c88dbb8c733f0e8b3f6";
  25729. +char cesaHmacSha1digestHex3[] = "125d7342b9ac11cd91a39af48aa17b4f63f175d3";
  25730. +char cesaDataHexStr3[50*2+1] = "";
  25731. +char cesaDataAndMd5digest3[sizeof(cesaDataHexStr3)+sizeof(cesaHmacMd5digestHex3)+8*2+1] = "";
  25732. +char cesaDataAndSha1digest3[sizeof(cesaDataHexStr3)+sizeof(cesaHmacSha1digestHex3)+8*2+1] = "";
  25733. +
  25734. +/* Ascii string is "abc" */
  25735. +char hashHexStr3[] = "616263";
  25736. +char hashMd5digest3[] = "900150983cd24fb0d6963f7d28e17f72";
  25737. +char hashSha1digest3[] = "a9993e364706816aba3e25717850c26c9cd0d89d";
  25738. +
  25739. +char hashHexStr80[] = "31323334353637383930"
  25740. + "31323334353637383930"
  25741. + "31323334353637383930"
  25742. + "31323334353637383930"
  25743. + "31323334353637383930"
  25744. + "31323334353637383930"
  25745. + "31323334353637383930"
  25746. + "31323334353637383930";
  25747. +
  25748. +char hashMd5digest80[] = "57edf4a22be3c955ac49da2e2107b67a";
  25749. +
  25750. +char tripleDesThenMd5digest80[] = "b7726a03aad490bd6c5a452a89a1b271";
  25751. +char tripleDesThenSha1digest80[] = "b2ddeaca91030eab5b95a234ef2c0f6e738ff883";
  25752. +
  25753. +char cbc3desThenMd5digest80[] = "6f463057e1a90e0e91ae505b527bcec0";
  25754. +char cbc3desThenSha1digest80[] = "1b002ed050be743aa98860cf35659646bb8efcc0";
  25755. +
  25756. +char cbcAes128ThenMd5digest80[] = "6b6e863ac5a71d15e3e9b1c86c9ba05f";
  25757. +char cbcAes128ThenSha1digest80[] = "13558472d1fc1c90dffec6e5136c7203452d509b";
  25758. +
  25759. +
  25760. +static MV_CESA_TEST_CASE cesaTestCases[] =
  25761. +{
  25762. + /* plainHexStr cipherHexStr IV crypto mac digest */
  25763. + /* Length Length Offset */
  25764. + /*0*/ { NULL, NULL, NULL, 0, 0, -1 },
  25765. + /*1*/ { cesaPlainHexEbc, cesaCipherHexEcb, NULL, 24, 0, -1 },
  25766. + /*2*/ { cesaPlainHexCbc, cesaCipherHexCbc, NULL, 24, 0, -1 },
  25767. + /*3*/ { cesaAesPlainHexEcb, cesaAes128cipherHexEcb, NULL, 16, 0, -1 },
  25768. + /*4*/ { cesaAesPlainHexEcb, cesaAes192cipherHexEcb, NULL, 16, 0, -1 },
  25769. + /*5*/ { cesaAesPlainHexEcb, cesaAes256cipherHexEcb, NULL, 16, 0, -1 },
  25770. + /*6*/ { cesaDataHexStr1, cesaHmacMd5digestHex1, NULL, 0, 8, -1 },
  25771. + /*7*/ { NULL, cesaDataAndMd5digest1, NULL, 0, 8, -1 },
  25772. + /*8*/ { cesaDataHexStr3, cesaHmacMd5digestHex3, NULL, 0, 50, -1 },
  25773. + /*9*/ { NULL, cesaDataAndMd5digest3, NULL, 0, 50, -1 },
  25774. +/*10*/ { cesaAesPlainText, cesaAes128IvCipherCbc, iv5, 64, 0, -1 },
  25775. +/*11*/ { cesaDataHexStr1, cesaHmacSha1digestHex1, NULL, 0, 8, -1 },
  25776. +/*12*/ { NULL, cesaDataAndSha1digest1, NULL, 0, 8, -1 },
  25777. +/*13*/ { cesaDataHexStr3, cesaHmacSha1digestHex3, NULL, 0, 50, -1 },
  25778. +/*14*/ { NULL, cesaDataAndSha1digest3, NULL, 0, 50, -1 },
  25779. +/*15*/ { hashHexStr3, hashMd5digest3, NULL, 0, 3, -1 },
  25780. +/*16*/ { hashHexStr3, hashSha1digest3, NULL, 0, 3, -1 },
  25781. +/*17*/ { hashHexStr80, tripleDesThenMd5digest80, NULL, 80, 80, -1 },
  25782. +/*18*/ { hashHexStr80, tripleDesThenSha1digest80, NULL, 80, 80, -1 },
  25783. +/*19*/ { hashHexStr80, cbc3desThenMd5digest80, iv1, 80, 80, -1 },
  25784. +/*20*/ { hashHexStr80, cbc3desThenSha1digest80, iv1, 80, 80, -1 },
  25785. +/*21*/ { hashHexStr80, cbcAes128ThenMd5digest80, iv5, 80, 80, -1 },
  25786. +/*22*/ { hashHexStr80, cbcAes128ThenSha1digest80, iv5, 80, 80, -1 },
  25787. +/*23*/ { cesaAesCtrPlain, cesaAesCtrCipher, NULL, 36, 0, -1 },
  25788. +/*24*/ { cesaAesIvPlainText, cesaAes128IvCipherCbc, NULL, 64, 0, -1 },
  25789. +/*25*/ { plain3des1, cipher3des1, NULL, 0, 0, -1 },
  25790. +/*26*/ { plain3des2, cipher3desCbc2, iv3des2,0, 0, -1 },
  25791. +/*27*/ { plain3des3, cipher3desCbc3, iv3des3,0, 0, -1 },
  25792. +};
  25793. +
  25794. +
  25795. +/* Key = 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  25796. + * 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
  25797. + * Input 0xdd repeated "size" times
  25798. + */
  25799. +static MV_CESA_SIZE_TEST mdMultiSizeTest302[] =
  25800. +{
  25801. + { 80, "7a031a640c14a4872814930b1ef3a5b2" },
  25802. + { 512, "5488e6c5a14dc72a79f28312ca5b939b" },
  25803. + { 1000, "d00814f586a8b78a05724239d2531821" },
  25804. + { 1001, "bf07df7b7f49d3f5b5ecacd4e9e63281" },
  25805. + { 1002, "1ed4a1a802e87817a819d4e37bb4d0f7" },
  25806. + { 1003, "5972ab64a4f265ee371dac2f2f137f90" },
  25807. + { 1004, "71f95e7ec3aa7df2548e90898abdb28e" },
  25808. + { 1005, "e082790b4857fcfc266e92e59e608814" },
  25809. + { 1006, "9500f02fd8ac7fde8b10e4fece9a920d" },
  25810. + { 1336, "e42edcce57d0b75b01aa09d71427948b" },
  25811. + { 1344, "bb5454ada0deb49ba0a97ffd60f57071" },
  25812. + { 1399, "0f44d793e744b24d53f44f295082ee8c" },
  25813. + { 1400, "359de8a03a9b707928c6c60e0e8d79f1" },
  25814. + { 1401, "e913858b484cbe2b384099ea88d8855b" },
  25815. + { 1402, "d9848a164af53620e0540c1d7d87629e" },
  25816. + { 1403, "0c9ee1c2c9ef45e9b625c26cbaf3e822" },
  25817. + { 1404, "12edd4f609416e3c936170360561b064" },
  25818. + { 1405, "7fc912718a05446395345009132bf562" },
  25819. + { 1406, "882f17425e579ff0d85a91a59f308aa0" },
  25820. + { 1407, "005cae408630a2fb5db82ad9db7e59da" },
  25821. + { 1408, "64655f8b404b3fea7a3e3e609bc5088f" },
  25822. + { 1409, "4a145284a7f74e01b6bb1a0ec6a0dd80" },
  25823. + { 2048, "67caf64475650732def374ebb8bde3fd" },
  25824. + { 2049, "6c84f11f472825f7e6cd125c2981884b" },
  25825. + { 2050, "8999586754a73a99efbe4dbad2816d41" },
  25826. + { 2051, "ba6946b610e098d286bc81091659dfff" },
  25827. + { 2052, "d0afa01c92d4d13def2b024f36faed83" },
  25828. + { 3072, "61d8beac61806afa2585d74a9a0e6974" },
  25829. + { 3074, "f6501a28dcc24d1e4770505c51a87ed3" },
  25830. + { 3075, "ea4a6929be67e33e61ff475369248b73" },
  25831. + { 4048, "aa8c4d68f282a07e7385acdfa69f4bed" },
  25832. + { 4052, "afb5ed2c0e1d430ea59e59ed5ed6b18a" },
  25833. + { 4058, "9e8553f9bdd43aebe0bd729f0e600c99" },
  25834. + { 6144, "f628f3e5d183fe5cdd3a5abee39cf872" },
  25835. + { 6150, "89a3efcea9a2f25f919168ad4a1fd292" },
  25836. + { 6400, "cdd176b7fb747873efa4da5e32bdf88f" },
  25837. + { 6528, "b1d707b027354aca152c45ee559ccd3f" },
  25838. + { 8192, "c600ea4429ac47f9941f09182166e51a" },
  25839. + {16384, "16e8754bfbeb4c649218422792267a37" },
  25840. + {18432, "0fd0607521b0aa8b52219cfbe215f63e" },
  25841. + { 0, NULL },
  25842. +};
  25843. +
  25844. +/* Key = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  25845. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  25846. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  25847. + */
  25848. +static MV_CESA_SIZE_TEST mdMultiSizeTest304[] =
  25849. +{
  25850. + { 80, "a456c4723fee6068530af5a2afa71627" },
  25851. + { 512, "f85c2a2344f5de68b432208ad13e5794" },
  25852. + { 1000, "35464d6821fd4a293a41eb84e274c8c5" },
  25853. + { 1001, "c08eedbdce60cceb54bc2d732bb32c8b" },
  25854. + { 1002, "5664f71800c011cc311cb6943339c1b8" },
  25855. + { 1003, "779c723b044c585dc7802b13e8501bdc" },
  25856. + { 1004, "55e500766a2c307bc5c5fdd15e4cacd4" },
  25857. + { 1005, "d5f978954f5c38529d1679d2b714f068" },
  25858. + { 1006, "cd3efc827ce628b7281b72172693abf9" },
  25859. + { 1336, "6f04479910785878ae6335b8d1e87edf" },
  25860. + { 1344, "b6d27b50c2bce1ba2a8e1b5cc4324368" },
  25861. + { 1399, "65f70a1d4c86e5eaeb0704c8a7816795" },
  25862. + { 1400, "3394b5adc4cb3ff98843ca260a44a88a" },
  25863. + { 1401, "3a06f3582033a66a4e57e0603ce94e74" },
  25864. + { 1402, "e4d97f5ed51edc48abfa46eeb5c31752" },
  25865. + { 1403, "3d05e40b080ee3bedf293cb87b7140e7" },
  25866. + { 1404, "8cf294fc3cd153ab18dccb2a52cbf244" },
  25867. + { 1405, "d1487bd42f6edd9b4dab316631159221" },
  25868. + { 1406, "0527123b6bf6936cf5d369dc18c6c70f" },
  25869. + { 1407, "3224a06639db70212a0cd1ae1fcc570a" },
  25870. + { 1408, "a9e13335612c0356f5e2c27086e86c43" },
  25871. + { 1409, "a86d1f37d1ed8a3552e9a4f04dceea98" },
  25872. + { 2048, "396905c9b961cd0f6152abfb69c4449c" },
  25873. + { 2049, "49f39bff85d9dcf059fadb89efc4a70f" },
  25874. + { 2050, "3a2b4823bc4d0415656550226a63e34a" },
  25875. + { 2051, "dec60580d406c782540f398ad0bcc7e0" },
  25876. + { 2052, "32f76610a14310309eb748fe025081bf" },
  25877. + { 3072, "45edc1a42bf9d708a621076b63b774da" },
  25878. + { 3074, "9be1b333fe7c0c9f835fb369dc45f778" },
  25879. + { 3075, "8c06fcac7bd0e7b7a17fd6508c09a549" },
  25880. + { 4048, "0ddaef848184bf0ad98507a10f1e90e4" },
  25881. + { 4052, "81976bcaeb274223983996c137875cb8" },
  25882. + { 4058, "0b0a7a1c82bc7cbc64d8b7cd2dc2bb22" },
  25883. + { 6144, "1c24056f52725ede2dff0d7f9fc9855f" },
  25884. + { 6150, "b7f4b65681c4e43ee68ca466ca9ca4ec" },
  25885. + { 6400, "443bbaab9f7331ddd4bf11b659cd43c8" },
  25886. + { 6528, "216f44f23047cfee03a7a64f88f9a995" },
  25887. + { 8192, "ac7a993b2cad54879dba1bde63e39097" },
  25888. + { 8320, "55ed7be9682d6c0025b3221a62088d08" },
  25889. + {16384, "c6c722087653b62007aea668277175e5" },
  25890. + {18432, "f1faca8e907872c809e14ffbd85792d6" },
  25891. + { 0, NULL },
  25892. +};
  25893. +
  25894. +/* HASH-MD5
  25895. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  25896. + * repeated "size" times
  25897. + */
  25898. +static MV_CESA_SIZE_TEST mdMultiSizeTest305[] =
  25899. +{
  25900. + { 80, "57edf4a22be3c955ac49da2e2107b67a" },
  25901. + { 512, "c729ae8f0736cc377a9767a660eaa04e" },
  25902. + { 1000, "f1257a8659eb92d36fe14c6bf3852a6a" },
  25903. + { 1001, "f8a46fe8ea04fdc8c7de0e84042d3878" },
  25904. + { 1002, "da188dd67bff87d58aa3c02af2d0cc0f" },
  25905. + { 1003, "961753017feee04c9b93a8e51658a829" },
  25906. + { 1004, "dd68c4338608dcc87807a711636bf2af" },
  25907. + { 1005, "e338d567d3ce66bf69ada29658a8759b" },
  25908. + { 1006, "443c9811e8b92599b0b149e8d7ec700a" },
  25909. + { 1336, "89a98511706008ba4cbd0b4a24fa5646" },
  25910. + { 1344, "335a919805f370b9e402a62c6fe01739" },
  25911. + { 1399, "5d18d0eddcd84212fe28d812b5e80e3b" },
  25912. + { 1400, "6b695c240d2dffd0dffc99459ca76db6" },
  25913. + { 1401, "49590f61298a76719bc93a57a30136f5" },
  25914. + { 1402, "94c2999fa3ef1910a683d69b2b8476f2" },
  25915. + { 1403, "37073a02ab00ecba2645c57c228860db" },
  25916. + { 1404, "1bcd06994fce28b624f0c5fdc2dcdd2b" },
  25917. + { 1405, "11b93671a64c95079e8cf9e7cddc8b3d" },
  25918. + { 1406, "4b6695772a4c66313fa4871017d05f36" },
  25919. + { 1407, "d1539b97fbfda1c075624e958de19c5b" },
  25920. + { 1408, "b801b9b69920907cd018e8063092ede9" },
  25921. + { 1409, "b765f1406cfe78e238273ed01bbcaf7e" },
  25922. + { 2048, "1d7e2c64ac29e2b3fb4c272844ed31f5" },
  25923. + { 2049, "71d38fac49c6b1f4478d8d88447bcdd0" },
  25924. + { 2050, "141c34a5592b1bebfa731e0b23d0cdba" },
  25925. + { 2051, "c5e1853f21c59f5d6039bd13d4b380d8" },
  25926. + { 2052, "dd44a0d128b63d4b5cccd967906472d7" },
  25927. + { 3072, "37d158e33b21390822739d13db7b87fe" },
  25928. + { 3074, "aef3b209d01d39d0597fe03634bbf441" },
  25929. + { 3075, "335ffb428eabf210bada96d74d5a4012" },
  25930. + { 4048, "2434c2b43d798d2819487a886261fc64" },
  25931. + { 4052, "ac2fa84a8a33065b2e92e36432e861f8" },
  25932. + { 4058, "856781f85616c341c3533d090c1e1e84" },
  25933. + { 6144, "e5d134c652c18bf19833e115f7a82e9b" },
  25934. + { 6150, "a09a353be7795fac2401dac5601872e6" },
  25935. + { 6400, "08b9033ac6a1821398f50af75a2dbc83" },
  25936. + { 6528, "3d47aa193a8540c091e7e02f779e6751" },
  25937. + { 8192, "d3164e710c0626f6f395b38f20141cb7" },
  25938. + { 8320, "b727589d9183ff4e8491dd24466974a3" },
  25939. + {16384, "3f54d970793d2274d5b20d10a69938ac" },
  25940. + {18432, "f558511dcf81985b7a1bb57fad970531" },
  25941. + { 0, NULL },
  25942. +};
  25943. +
  25944. +
  25945. +/* Key = 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
  25946. + * 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
  25947. + * 0xaa, 0xaa, 0xaa, 0xaa
  25948. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  25949. + */
  25950. +static MV_CESA_SIZE_TEST shaMultiSizeTest402[] =
  25951. +{
  25952. + { 80, "e812f370e659705a1649940d1f78cd7af18affd3" },
  25953. + { 512, "e547f886b2c15d995ed76a8a924cb408c8080f66" },
  25954. + { 1000, "239443194409f1a5342ecde1a092c8f3a3ed790a" },
  25955. + { 1001, "f278ab9a102850a9f48dc4e9e6822afe2d0c52b5" },
  25956. + { 1002, "8bcc667df5ab6ece988b3af361d09747c77f4e72" },
  25957. + { 1003, "0fae6046c7dc1d3e356b25af836f6077a363f338" },
  25958. + { 1004, "0ea48401cc92ae6bc92ae76685269cb0167fbe1a" },
  25959. + { 1005, "ecbcd7c879b295bafcd8766cbeac58cc371e31d1" },
  25960. + { 1006, "eb4a4a3d07d1e9a15e6f1ab8a9c47f243e27324c" },
  25961. + { 1336, "f5950ee1d77c10e9011d2149699c9366fe52529c" },
  25962. + { 1344, "b04263604a63c351b0b3b9cf1785b4bdba6c8838" },
  25963. + { 1399, "8cb1cff61d5b784045974a2fc69386e3b8d24218" },
  25964. + { 1400, "9bb2f3fcbeddb2b90f0be797cd647334a2816d51" },
  25965. + { 1401, "23ae462a7a0cb440f7445791079a5d75a535dd33" },
  25966. + { 1402, "832974b524a4d3f9cc2f45a3cabf5ccef65cd2aa" },
  25967. + { 1403, "d1c683742fe404c3c20d5704a5430e7832a7ec95" },
  25968. + { 1404, "867c79042e64f310628e219d8b85594cd0c7adc3" },
  25969. + { 1405, "c9d81d49d13d94358f56ccfd61af02b36c69f7c3" },
  25970. + { 1406, "0df43daab2786172f9b8d07d61f14a070cf1287a" },
  25971. + { 1407, "0fd8f3ad7f169534b274d4c66bbddd89f759e391" },
  25972. + { 1408, "3987511182b18473a564436003139b808fa46343" },
  25973. + { 1409, "ef667e063c9e9f539a8987a8d0bd3066ee85d901" },
  25974. + { 2048, "921109c99f3fedaca21727156d5f2b4460175327" },
  25975. + { 2049, "47188600dd165eb45f27c27196d3c46f4f042c1b" },
  25976. + { 2050, "8831939904009338de10e7fa670847041387807d" },
  25977. + { 2051, "2f8ebb5db2997d614e767be1050366f3641e7520" },
  25978. + { 2052, "669e51cd730dae158d3bef8adba075bd95a0d011" },
  25979. + { 3072, "cfee66cfd83abc8451af3c96c6b35a41cc6c55f5" },
  25980. + { 3074, "216ea26f02976a261b7d21a4dd3085157bedfabd" },
  25981. + { 3075, "bd612ebba021fd8e012b14c3bd60c8c5161fabc0" },
  25982. + { 4048, "c2564c1fdf2d5e9d7dde7aace2643428e90662e8" },
  25983. + { 4052, "91ce61fe924b445dfe7b5a1dcd10a27caec16df6" },
  25984. + { 4058, "db2a9be5ee8124f091c7ebd699266c5de223c164" },
  25985. + { 6144, "855109903feae2ba3a7a05a326b8a171116eb368" },
  25986. + { 6150, "37520bb3a668294d9c7b073e7e3daf8fee248a78" },
  25987. + { 6400, "60a353c841b6d2b1a05890349dad2fa33c7536b7" },
  25988. + { 6528, "9e53a43a69bb42d7c8522ca8bd632e421d5edb36" },
  25989. + { 8192, "a918cb0da862eaea0a33ee0efea50243e6b4927c" },
  25990. + { 8320, "29a5dcf55d1db29cd113fcf0572ae414f1c71329" },
  25991. + {16384, "6fb27966138e0c8d5a0d65ace817ebd53633cee1" },
  25992. + {18432, "ca09900d891c7c9ae2a559b10f63a217003341c1" },
  25993. + { 0, NULL },
  25994. +};
  25995. +
  25996. +/* Key = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  25997. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  25998. + * 0x11, 0x12, 0x13, 0x14
  25999. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  26000. + */
  26001. +static MV_CESA_SIZE_TEST shaMultiSizeTest404[] =
  26002. +{
  26003. + { 80, "beaf20a34b06a87558d156c0949bc3957d40222e" },
  26004. + { 512, "3353955358d886bc2940a3c7f337ff7dafb59c7b" },
  26005. + { 1000, "8737a542c5e9b2b6244b757ebb69d5bd602a829f" },
  26006. + { 1001, "fd9e7582d8a5d3c9fe3b923e4e6a41b07a1eb4d4" },
  26007. + { 1002, "a146d14a6fc3c274ff600568f4d75b977989e00d" },
  26008. + { 1003, "be22601bbc027ddef2dec97d30b3dc424fd803c5" },
  26009. + { 1004, "3e71fe99b2fe2b7bfdf4dbf0c7f3da25d7ea35e7" },
  26010. + { 1005, "2c422735d7295408fddd76f5e8a83a2a8da13df3" },
  26011. + { 1006, "6d875319049314b61855101a647b9ba3313428e6" },
  26012. + { 1336, "c1631ea80bad9dc43a180712461b65a0598c711c" },
  26013. + { 1344, "816069bf91d34581005746e2e0283d0f9c7b7605" },
  26014. + { 1399, "4e139866dc61cfcb8b67ca2ebd637b3a538593af" },
  26015. + { 1400, "ff2a0f8dd2b02c5417910f6f55d33a78e081a723" },
  26016. + { 1401, "ab00c12be62336964cbce31ae97fe2a0002984d5" },
  26017. + { 1402, "61349e7f999f3a1acc56c3e9a5060a9c4a7b05b6" },
  26018. + { 1403, "3edbc0f61e435bc1317fa27d840076093fb79353" },
  26019. + { 1404, "d052c6dfdbe63d45dab23ef9893e2aa4636aca1e" },
  26020. + { 1405, "0cc16b7388d67bf0add15a31e6e6c753cfae4987" },
  26021. + { 1406, "c96ba7eaad74253c38c22101b558d2850b1d1b90" },
  26022. + { 1407, "3445428a40d2c6556e7c55797ad8d323b61a48d9" },
  26023. + { 1408, "8d6444f937a09317c89834187b8ea9b8d3a8c56b" },
  26024. + { 1409, "c700acd3ecd19014ea2bdb4d42510c467e088475" },
  26025. + { 2048, "ee27d2a0cb77470c2f496212dfd68b5bb7b04e4b" },
  26026. + { 2049, "683762d7a02983b26a6d046e6451d9cd82c25932" },
  26027. + { 2050, "0fd20f1d55a9ee18363c2a6fd54aa13aee69992f" },
  26028. + { 2051, "86c267d8cc4bc8d59090e4f8b303da960fd228b7" },
  26029. + { 2052, "452395ae05b3ec503eea34f86fc0832485ad97c1" },
  26030. + { 3072, "75198e3cfd0b9bcff2dabdf8e38e6fdaa33ca49a" },
  26031. + { 3074, "4e24785ef080141ce4aab4675986d9acea624d7c" },
  26032. + { 3075, "3a20c5978dd637ec0e809bf84f0d9ccf30bc65bf" },
  26033. + { 4048, "3c32da256be7a7554922bf5fed51b0d2d09e59ad" },
  26034. + { 4052, "fff898426ea16e54325ae391a32c6c9bce4c23c0" },
  26035. + { 4058, "c800b9e562e1c91e1310116341a3c91d37f848ec" },
  26036. + { 6144, "d91d509d0cc4376c2d05bf9a5097717a373530e6" },
  26037. + { 6150, "d957030e0f13c5df07d9eec298542d8f94a07f12" },
  26038. + { 6400, "bb745313c3d7dc17b3f955e5534ad500a1082613" },
  26039. + { 6528, "77905f80d9ca82080bbb3e5654896dabfcfd1bdb" },
  26040. + { 8192, "5237fd9a81830c974396f99f32047586612ff3c0" },
  26041. + { 8320, "57668e28d5f2dba0839518a11db0f6af3d7e08bf" },
  26042. + {16384, "62e093fde467f0748087beea32e9af97d5c61241" },
  26043. + {18432, "845fb33130c7d6ea554fd5aacb9c50cf7ccb5929" },
  26044. + { 0, NULL },
  26045. +};
  26046. +
  26047. +/* HASH-SHA1
  26048. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  26049. + * repeated "size" times
  26050. + */
  26051. +static MV_CESA_SIZE_TEST shaMultiSizeTest405[] =
  26052. +{
  26053. + { 80, "50abf5706a150990a08b2c5ea40fa0e585554732" },
  26054. + { 512, "f14516a08948fa27917a974d219741a697ba0087" },
  26055. + { 1000, "0bd18c378d5788817eb4f1e5dc07d867efa5cbf4" },
  26056. + { 1001, "ca29b85c35db1b8aef83c977893a11159d1b7aa2" },
  26057. + { 1002, "d83bc973eaaedb8a31437994dabbb3304b0be086" },
  26058. + { 1003, "2cf7bbef0acd6c00536b5c58ca470df9a3a90b6c" },
  26059. + { 1004, "e4375d09b1223385a8a393066f8209acfd936a80" },
  26060. + { 1005, "1029b38043e027745d019ce1d2d68e3d8b9d8f99" },
  26061. + { 1006, "deea16dcebbd8ac137e2b984deb639b9fb5e9680" },
  26062. + { 1336, "ea031b065fff63dcfb6a41956e4777520cdbc55d" },
  26063. + { 1344, "b52096c6445e6c0a8355995c70dc36ae186c863c" },
  26064. + { 1399, "cde2f6f8379870db4b32cf17471dc828a8dbff2b" },
  26065. + { 1400, "e53ff664064bc09fe5054c650806bd42d8179518" },
  26066. + { 1401, "d1156db5ddafcace64cdb510ff0d4af9b9a8ad64" },
  26067. + { 1402, "34ede0e9a909dd84a2ae291539105c0507b958e1" },
  26068. + { 1403, "a772ca3536da77e6ad3251e4f9e1234a4d7b87c0" },
  26069. + { 1404, "29740fd2b04e7a8bfd32242db6233156ad699948" },
  26070. + { 1405, "65b17397495b70ce4865dad93bf991b74c97cce1" },
  26071. + { 1406, "a7ee89cd0754061fdb91af7ea6abad2c69d542e3" },
  26072. + { 1407, "3eebf82f7420188e23d328b7ce93580b279a5715" },
  26073. + { 1408, "e08d3363a8b9a490dfb3a4c453452b8f114deeec" },
  26074. + { 1409, "95d74df739181a4ff30b8c39e28793a36598e924" },
  26075. + { 2048, "aa40262509c2abf84aab0197f83187fc90056d91" },
  26076. + { 2049, "7dec28ef105bc313bade8d9a7cdeac58b99de5ea" },
  26077. + { 2050, "d2e30f77ec81197de20f56588a156094ecb88450" },
  26078. + { 2051, "6b22ccc874833e96551a39da0c0edcaa0d969d92" },
  26079. + { 2052, "f843141e57875cd669af58744bc60aa9ea59549c" },
  26080. + { 3072, "09c5fedeaa62c132e673cc3c608a00142273d086" },
  26081. + { 3074, "b09e95eea9c7b1b007a58accec488301901a7f3d" },
  26082. + { 3075, "e6226b77b4ada287a8c9bbcf4ed71eec5ce632dc" },
  26083. + { 4048, "e99394894f855821951ddddf5bfc628547435f5c" },
  26084. + { 4052, "32d2f1af38be9cfba6cd03d55a254d0b3e1eb382" },
  26085. + { 4058, "d906552a4f2aca3a22e1fecccbcd183d7289d0ef" },
  26086. + { 6144, "2e7f62d35a860988e1224dc0543204af19316041" },
  26087. + { 6150, "d6b89698ee133df46fec9d552fadc328aa5a1b51" },
  26088. + { 6400, "dff50e90c46853988fa3a4b4ce5dda6945aae976" },
  26089. + { 6528, "9e63ec0430b96db02d38bc78357a2f63de2ab7f8" },
  26090. + { 8192, "971eb71ed60394d5ab5abb12e88420bdd41b5992" },
  26091. + { 8320, "91606a31b46afeaac965cecf87297e791b211013" },
  26092. + {16384, "547f830a5ec1f5f170ce818f156b1002cabc7569" },
  26093. + {18432, "f16f272787f3b8d539652e4dc315af6ab4fda0ef" },
  26094. + { 0, NULL },
  26095. +};
  26096. +
  26097. +/* CryptoKey = 0x01234567, 0x89abcdef,
  26098. + * 0x01234567, 0x89abcdef,
  26099. + * 0x01234567, 0x89abcdef;
  26100. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  26101. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  26102. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  26103. + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
  26104. + */
  26105. +static MV_CESA_SIZE_TEST tripleDesMdMultiSizeTest502[] =
  26106. +{
  26107. + { 64, "9586962a2aaaef28803dec2e17807a7f" },
  26108. + { 80, "b7726a03aad490bd6c5a452a89a1b271" },
  26109. + { 352, "f1ed9563aecc3c0d2766eb2bed3b4e4c" },
  26110. + { 512, "0f9decb11ab40fe86f4d4d9397bc020e" },
  26111. + { 1000, "3ba69deac12cab8ff9dff7dbd9669927" },
  26112. + { 1336, "6cf47bf1e80e03e2c1d0945bc50d37d2" },
  26113. + { 1344, "4be388dab21ceb3fa1b8d302e9b821f7" },
  26114. + { 1400, "a58b79fb21dd9bfc6ec93e3b99fb0ef1" },
  26115. + { 1408, "8bc97379fc2ac3237effcdd4f7a86528" },
  26116. + { 2048, "1339f03ab3076f25a20bc4cba16eb5bf" },
  26117. + { 3072, "731204d2d90c4b36ae41f5e1fb874288" },
  26118. + { 4048, "c028d998cfda5642547b7e1ed5ea16e4" },
  26119. + { 6144, "b1b19cd910cc51bd22992f1e59f1e068" },
  26120. + { 6400, "44e4613496ba622deb0e7cb768135a2f" },
  26121. + { 6528, "3b06b0a86f8db9cd67f9448dfcf10549" },
  26122. + { 8192, "d581780b7163138a0f412be681457d82" },
  26123. + {16384, "03b8ac05527faaf1bed03df149c65ccf" },
  26124. + {18432, "677c8a86a41dab6c5d81b85b8fb10ff6" },
  26125. + { 0, NULL },
  26126. +};
  26127. +
  26128. +
  26129. +/* CryptoKey = 0x01234567, 0x89abcdef,
  26130. + * 0x01234567, 0x89abcdef,
  26131. + * 0x01234567, 0x89abcdef;
  26132. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  26133. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  26134. + * 0x11, 0x12, 0x13, 0x14
  26135. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  26136. + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
  26137. + */
  26138. +static MV_CESA_SIZE_TEST tripleDesShaMultiSizeTest503[] =
  26139. +{
  26140. + { 64, "44a1e9bcbfc1429630d9ea68b7a48b0427a684f2" },
  26141. + { 80, "b2ddeaca91030eab5b95a234ef2c0f6e738ff883" },
  26142. + { 352, "4b91864c7ff629bdff75d9726421f76705452aaf" },
  26143. + { 512, "6dd37faceeb2aa98ba74f4242ed6734a4d546af5" },
  26144. + { 1000, "463661c30300be512a9df40904f0757cde5f1141" },
  26145. + { 1336, "b931f831d9034fe59c65176400b039fe9c1f44a5" },
  26146. + { 1344, "af8866b1cd4a4887d6185bfe72470ffdfb3648e1" },
  26147. + { 1400, "49c6caf07296d5e31d2504d088bc5b20c3ee7cdb" },
  26148. + { 1408, "fcae8deedbc6ebf0763575dc7e9de075b448a0f4" },
  26149. + { 2048, "edece5012146c1faa0dd10f50b183ba5d2af58ac" },
  26150. + { 3072, "5b83625adb43a488b8d64fecf39bb766818547b7" },
  26151. + { 4048, "d2c533678d26c970293af60f14c8279dc708bfc9" },
  26152. + { 6144, "b8f67af4f991b08b725f969b049ebf813bfacc5c" },
  26153. + { 6400, "d9a6c7f746ac7a60ef2edbed2841cf851c25cfb0" },
  26154. + { 6528, "376792b8c8d18161d15579fb7829e6e3a27e9946" },
  26155. + { 8192, "d890eabdca195b34ef8724b28360cffa92ae5655" },
  26156. + {16384, "a167ee52639ec7bf19aee9c6e8f76667c14134b9" },
  26157. + {18432, "e4396ab56f67296b220985a12078f4a0e365d2cc" },
  26158. + { 0, NULL },
  26159. +};
  26160. +
  26161. +/* CryptoKey = 0x01234567, 0x89abcdef,
  26162. + * 0x01234567, 0x89abcdef,
  26163. + * 0x01234567, 0x89abcdef
  26164. + * IV = 0x12345678, 0x90abcdef
  26165. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  26166. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  26167. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  26168. + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
  26169. + */
  26170. +static MV_CESA_SIZE_TEST cbc3desMdMultiSizeTest504[] =
  26171. +{
  26172. + { 64, "8d10e00802460ede0058c139ba48bd2d" },
  26173. + { 80, "6f463057e1a90e0e91ae505b527bcec0" },
  26174. + { 352, "4938d48bdf86aece2c6851e7c6079788" },
  26175. + { 512, "516705d59f3cf810ebf2a13a23a7d42e" },
  26176. + { 1000, "a5a000ee5c830e67ddc6a2d2e5644b31" },
  26177. + { 1336, "44af60087b74ed07950088efbe3b126a" },
  26178. + { 1344, "1f5b39e0577920af731dabbfcf6dfc2a" },
  26179. + { 1400, "6804ea640e29b9cd39e08bc37dbce734" },
  26180. + { 1408, "4fb436624b02516fc9d1535466574bf9" },
  26181. + { 2048, "c909b0985c423d8d86719f701e9e83db" },
  26182. + { 3072, "cfe0bc34ef97213ee3d3f8b10122db21" },
  26183. + { 4048, "03ea10b5ae4ddeb20aed6af373082ed1" },
  26184. + { 6144, "b9a0ff4f87fc14b3c2dc6f0ed0998fdf" },
  26185. + { 6400, "6995f85d9d4985dd99e974ec7dda9dd6" },
  26186. + { 6528, "bbbb548ce2fa3d58467f6a6a5168a0e6" },
  26187. + { 8192, "afe101fbe745bb449ae4f50d10801456" },
  26188. + {16384, "9741706d0b1c923340c4660ff97cacdf" },
  26189. + {18432, "b0217becb73cb8f61fd79c7ce9d023fb" },
  26190. + { 0, NULL },
  26191. +};
  26192. +
  26193. +
  26194. +/* CryptoKey = 0x01234567, 0x89abcdef,
  26195. + * 0x01234567, 0x89abcdef,
  26196. + * 0x01234567, 0x89abcdef;
  26197. + * IV = 0x12345678, 0x90abcdef
  26198. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  26199. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  26200. + * 0x11, 0x12, 0x13, 0x14
  26201. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  26202. + * Note: only sizes aligned to 3DES block size (8 bytes) allowed
  26203. + */
  26204. +static MV_CESA_SIZE_TEST cbc3desShaMultiSizeTest505[] =
  26205. +{
  26206. + { 64, "409187e5bdb0be4a7754ca3747f7433dc4f01b98" },
  26207. + { 80, "1b002ed050be743aa98860cf35659646bb8efcc0" },
  26208. + { 352, "6cbf7ebe50fa4fa6eecc19eca23f9eae553ccfff" },
  26209. + { 512, "cfb5253fb4bf72b743320c30c7e48c54965853b0" },
  26210. + { 1000, "95e04e1ca2937e7c5a9aba9e42d2bcdb8a7af21f" },
  26211. + { 1336, "3b5c1f5eee5837ebf67b83ae01405542d77a6627" },
  26212. + { 1344, "2b3d42ab25615437f98a1ee310b81d07a02badc2" },
  26213. + { 1400, "7f8687df7c1af44e4baf3c934b6cca5ab6bc993e" },
  26214. + { 1408, "473a581c5f04f7527d50793c845471ac87e86430" },
  26215. + { 2048, "e41d20cae7ebe34e6e828ed62b1e5734019037bb" },
  26216. + { 3072, "275664afd7a561d804e6b0d204e53939cde653ae" },
  26217. + { 4048, "0d220cc5b34aeeb46bbbd637dde6290b5a8285a3" },
  26218. + { 6144, "cb393ddcc8b1c206060625b7d822ef9839e67bc5" },
  26219. + { 6400, "dd3317e2a627fc04800f74a4b05bfda00fab0347" },
  26220. + { 6528, "8a74c3b2441ab3f5a7e08895cc432566219a7c41" },
  26221. + { 8192, "b8e6ef3a549ed0e005bd5b8b1a5fe6689e9711a7" },
  26222. + {16384, "55f59404008276cdac0e2ba0d193af2d40eac5ce" },
  26223. + {18432, "86ae6c4fc72369a54cce39938e2d0296cd9c6ec5" },
  26224. + { 0, NULL },
  26225. +};
  26226. +
  26227. +
  26228. +/* CryptoKey = 0x01234567, 0x89abcdef,
  26229. + * 0x01234567, 0x89abcdef,
  26230. + * 0x01234567, 0x89abcdef
  26231. + * IV = 0x12345678, 0x90abcdef
  26232. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  26233. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  26234. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  26235. + * Note: only sizes aligned to AES block size (16 bytes) allowed
  26236. + */
  26237. +static MV_CESA_SIZE_TEST cbcAes128md5multiSizeTest506[] =
  26238. +{
  26239. + { 16, "7ca4c2ba866751598720c5c4aa0d6786" },
  26240. + { 64, "7dba7fb988e80da609b1fea7254bced8" },
  26241. + { 80, "6b6e863ac5a71d15e3e9b1c86c9ba05f" },
  26242. + { 352, "a1ceb9c2e3021002400d525187a9f38c" },
  26243. + { 512, "596c055c1c55db748379223164075641" },
  26244. + { 1008, "f920989c02f3b3603f53c99d89492377" },
  26245. + { 1344, "2e496b73759d77ed32ea222dbd2e7b41" },
  26246. + { 1408, "7178c046b3a8d772efdb6a71c4991ea4" },
  26247. + { 2048, "a917f0099c69eb94079a8421714b6aad" },
  26248. + { 3072, "693cd5033d7f5391d3c958519fa9e934" },
  26249. + { 4048, "139dca91bcff65b3c40771749052906b" },
  26250. + { 6144, "428d9cef6df4fb70a6e9b6bbe4819e55" },
  26251. + { 6400, "9c0b909e76daa811e12b1fc17000a0c4" },
  26252. + { 6528, "ad876f6297186a7be1f1b907ed860eda" },
  26253. + { 8192, "479cbbaca37dd3191ea1f3e8134a0ef4" },
  26254. + {16384, "60fda559c74f91df538100c9842f2f15" },
  26255. + {18432, "4a3eb1cba1fa45f3981270953f720c42" },
  26256. + { 0, NULL },
  26257. +};
  26258. +
  26259. +
  26260. +/* CryptoKey = 0x01234567, 0x89abcdef,
  26261. + * 0x01234567, 0x89abcdef,
  26262. + * 0x01234567, 0x89abcdef;
  26263. + * IV = 0x12345678, 0x90abcdef
  26264. + * MacKey = 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  26265. + * 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
  26266. + * 0x11, 0x12, 0x13, 0x14
  26267. + * InputHexStr = "31323334353637383930" (ASCII = "1234567890")
  26268. + * Note: only sizes aligned to AES block size (16 bytes) allowed
  26269. + */
  26270. +static MV_CESA_SIZE_TEST cbcAes128sha1multiSizeTest507[] =
  26271. +{
  26272. + { 16, "9aa8dc1c45f0946daf78057fa978759c625c1fee" },
  26273. + { 64, "9f588fc1ede851e5f8b20256abc9979465ae2189" },
  26274. + { 80, "13558472d1fc1c90dffec6e5136c7203452d509b" },
  26275. + { 352, "6b93518e006cfaa1f7adb24615e7291fb0a27e06" },
  26276. + { 512, "096874951a77fbbf333e49d80c096ee2016e09bd" },
  26277. + { 1008, "696fc203c2e4b5ae0ec5d1db3f623c490bc6dbac" },
  26278. + { 1344, "79bf77509935ccd3528caaac6a5eb6481f74029b" },
  26279. + { 1408, "627f9462b95fc188e8cfa7eec15119bdc5d4fcf1" },
  26280. + { 2048, "3d50d0c005feba92fe41502d609fced9c882b4d1" },
  26281. + { 3072, "758807e5b983e3a91c06fb218fe0f73f77111e94" },
  26282. + { 4048, "ca90e85242e33f005da3504416a52098d0d31fb2" },
  26283. + { 6144, "8044c1d4fd06642dfc46990b4f18b61ef1e972cf" },
  26284. + { 6400, "166f1f4ea57409f04feba9fb1e39af0e00bd6f43" },
  26285. + { 6528, "0389016a39485d6e330f8b4215ddf718b404f7e9" },
  26286. + { 8192, "6df7ee2a8b61d6f7f860ce8dbf778f0c2a5b508b" },
  26287. + {16384, "a70a6d8dfa1f91ded621c3dbaed34162bc48783f" },
  26288. + {18432, "8dfad627922ce15df1eed10bdbed49244efa57db" },
  26289. + { 0, NULL },
  26290. +};
  26291. +
  26292. +
  26293. +void cesaTestPrintStatus(void);
  26294. +
  26295. +
  26296. +/*------------------------- LOCAL FUNCTIONs ---------------------------------*/
  26297. +MV_STATUS testCmd(int sid, int iter, MV_CESA_COMMAND* pCmd,
  26298. + MV_CESA_TEST_SESSION* pTestSession, MV_U8* pIV, int ivSize);
  26299. +MV_STATUS testClose(int idx);
  26300. +MV_STATUS testOpen(int idx);
  26301. +void close_session(int sid);
  26302. +void cesaTestCheckReady(const MV_CESA_RESULT *r);
  26303. +void cesaCheckReady(MV_CESA_RESULT* r);
  26304. +void printTestResults(int idx, MV_STATUS status, int checkMode);
  26305. +void cesaLastResult(void);
  26306. +void cesaTestPrintReq(int req, int offset, int size);
  26307. +
  26308. +void cesaTestPrintStatus(void);
  26309. +void cesaTestPrintSession(int idx);
  26310. +void sizeTest(int testIdx, int iter, int checkMode);
  26311. +void multiTest(int iter, int reqSize, int checkMode);
  26312. +void oneTest(int testIdx, int caseIdx,int iter, int reqSize, int checkMode);
  26313. +void multiSizeTest(int idx, int iter, int checkMode, char* inputData);
  26314. +void cesaTest(int iter, int reqSize, int checkMode);
  26315. +void cesaOneTest(int testIdx, int caseIdx,int iter, int reqSize, int checkMode);
  26316. +void combiTest(int iter, int reqSize, int checkMode);
  26317. +void shaTest(int iter, int reqSize, int checkMode);
  26318. +void mdTest(int iter, int reqSize, int checkMode);
  26319. +void aesTest(int iter, int reqSize, int checkMode);
  26320. +void tripleDesTest(int iter, int reqSize, int checkMode);
  26321. +void desTest(int iter, int reqSize, int checkMode);
  26322. +void cesaTestStop(void);
  26323. +MV_STATUS testRun(int idx, int caseIdx, int iter,int reqSize, int checkMode);
  26324. +void cesaTestStart(int bufNum, int bufSize);
  26325. +
  26326. +
  26327. +static MV_U32 getRate(MV_U32* remainder)
  26328. +{
  26329. + MV_U32 kBits, milliSec, rate;
  26330. +
  26331. + milliSec = 0;
  26332. + if( (cesaEndTicks - cesaBeginTicks) > 0)
  26333. + {
  26334. + milliSec = CESA_TEST_TICK_TO_MS(cesaEndTicks - cesaBeginTicks);
  26335. + }
  26336. + if(milliSec == 0)
  26337. + {
  26338. + if(remainder != NULL)
  26339. + *remainder = 0;
  26340. + return 0;
  26341. + }
  26342. +
  26343. + kBits = (cesaIteration*cesaRateSize*8)/1000;
  26344. + rate = kBits/milliSec;
  26345. + if(remainder != NULL)
  26346. + *remainder = ((kBits % milliSec)*10)/milliSec;
  26347. +
  26348. + return rate;
  26349. +}
  26350. +
  26351. +static char* extractMbuf(MV_CESA_MBUF *pMbuf,
  26352. + int offset, int size, char* hexStr)
  26353. +{
  26354. + mvCesaCopyFromMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset, size);
  26355. + mvBinToHex((const MV_U8*)cesaBinBuffer, hexStr, size);
  26356. +
  26357. + return hexStr;
  26358. +}
  26359. +
  26360. +static MV_BOOL cesaCheckMbuf(MV_CESA_MBUF *pMbuf,
  26361. + const char* hexString, int offset,
  26362. + int checkSize)
  26363. +{
  26364. + MV_BOOL isFailed = MV_FALSE;
  26365. + MV_STATUS status;
  26366. + int size = strlen(hexString)/2;
  26367. + int checkedSize = 0;
  26368. +/*
  26369. + mvOsPrintf("cesaCheckMbuf: pMbuf=%p, offset=%d, checkSize=%d, mBufSize=%d\n",
  26370. + pMbuf, offset, checkSize, pMbuf->mbufSize);
  26371. +*/
  26372. + if(pMbuf->mbufSize < (checkSize + offset))
  26373. + {
  26374. + mvOsPrintf("checkSize (%d) is too large: offset=%d, mbufSize=%d\n",
  26375. + checkSize, offset, pMbuf->mbufSize);
  26376. + return MV_TRUE;
  26377. + }
  26378. + status = mvCesaCopyFromMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset, checkSize);
  26379. + if(status != MV_OK)
  26380. + {
  26381. + mvOsPrintf("CesaTest: Can't copy %d bytes from Mbuf=%p to checkBuf=%p\n",
  26382. + checkSize, pMbuf, cesaBinBuffer);
  26383. + return MV_TRUE;
  26384. + }
  26385. +/*
  26386. + mvDebugMemDump(cesaBinBuffer, size, 1);
  26387. +*/
  26388. + mvHexToBin(hexString, (MV_U8*)cesaExpBinBuffer, size);
  26389. +
  26390. + /* Compare buffers */
  26391. + while(checkSize > checkedSize)
  26392. + {
  26393. + size = MV_MIN(size, (checkSize - checkedSize));
  26394. + if(memcmp(cesaExpBinBuffer, &cesaBinBuffer[checkedSize], size) != 0)
  26395. + {
  26396. + mvOsPrintf("CheckMbuf failed: checkSize=%d, size=%d, checkedSize=%d\n",
  26397. + checkSize, size, checkedSize);
  26398. + mvDebugMemDump(&cesaBinBuffer[checkedSize], size, 1);
  26399. + mvDebugMemDump(cesaExpBinBuffer, size, 1);
  26400. +
  26401. + isFailed = MV_TRUE;
  26402. + break;
  26403. + }
  26404. + checkedSize += size;
  26405. + }
  26406. +
  26407. + return isFailed;
  26408. +}
  26409. +
  26410. +static MV_STATUS cesaSetMbuf(MV_CESA_MBUF *pMbuf,
  26411. + const char* hexString,
  26412. + int offset, int reqSize)
  26413. +{
  26414. + MV_STATUS status = MV_OK;
  26415. + int copySize, size = strlen(hexString)/2;
  26416. +
  26417. + mvHexToBin(hexString, (MV_U8*)cesaBinBuffer, size);
  26418. +
  26419. + copySize = 0;
  26420. + while(reqSize > copySize)
  26421. + {
  26422. + size = MV_MIN(size, (reqSize - copySize));
  26423. +
  26424. + status = mvCesaCopyToMbuf((MV_U8*)cesaBinBuffer, pMbuf, offset+copySize, size);
  26425. + if(status != MV_OK)
  26426. + {
  26427. + mvOsPrintf("cesaSetMbuf Error: Copy %d of %d bytes to MBuf\n",
  26428. + copySize, reqSize);
  26429. + break;
  26430. + }
  26431. + copySize += size;
  26432. + }
  26433. + pMbuf->mbufSize = offset+copySize;
  26434. + return status;
  26435. +}
  26436. +
  26437. +static MV_CESA_TEST_SESSION* getTestSessionDb(int idx, int* pTestIdx)
  26438. +{
  26439. + int testIdx, dbIdx = idx/100;
  26440. +
  26441. + if(dbIdx > MAX_TEST_TYPE)
  26442. + {
  26443. + mvOsPrintf("Wrong index %d - No such test type\n", idx);
  26444. + return NULL;
  26445. + }
  26446. + testIdx = idx % 100;
  26447. +
  26448. + if(testIdx >= cesaTestsDB[dbIdx].numSessions)
  26449. + {
  26450. + mvOsPrintf("Wrong index %d - No such test\n", idx);
  26451. + return NULL;
  26452. + }
  26453. + if(pTestIdx != NULL)
  26454. + *pTestIdx = testIdx;
  26455. +
  26456. + return cesaTestsDB[dbIdx].pSessions;
  26457. +}
  26458. +
  26459. +/* Debug */
  26460. +void cesaTestPrintReq(int req, int offset, int size)
  26461. +{
  26462. + MV_CESA_MBUF* pMbuf;
  26463. +
  26464. + mvOsPrintf("cesaTestPrintReq: req=%d, offset=%d, size=%d\n",
  26465. + req, offset, size);
  26466. + mvDebugMemDump(cesaCmdRing, 128, 4);
  26467. +
  26468. + pMbuf = cesaCmdRing[req].pSrc;
  26469. + mvCesaDebugMbuf("src", pMbuf, offset,size);
  26470. + pMbuf = cesaCmdRing[req].pDst;
  26471. + mvCesaDebugMbuf("dst", pMbuf, offset, size);
  26472. +
  26473. + cesaTestPrintStatus();
  26474. +}
  26475. +
  26476. +void cesaLastResult(void)
  26477. +{
  26478. + mvOsPrintf("Last Result: ReqId = %d, SessionId = %d, rc = (%d)\n",
  26479. + (MV_U32)cesaResult.pReqPrv, cesaResult.sessionId,
  26480. + cesaResult.retCode);
  26481. +}
  26482. +
  26483. +void printTestResults(int idx, MV_STATUS status, int checkMode)
  26484. +{
  26485. + int testIdx;
  26486. + MV_CESA_TEST_SESSION* pTestSessions = getTestSessionDb(idx, &testIdx);
  26487. +
  26488. + if(pTestSessions == NULL)
  26489. + return;
  26490. +
  26491. + mvOsPrintf("%-35s %4dx%-4d : ", pTestSessions[testIdx].name,
  26492. + cesaIteration, cesaReqSize);
  26493. + if( (status == MV_OK) &&
  26494. + (cesaCryptoError == 0) &&
  26495. + (cesaError == 0) &&
  26496. + (cesaReqIdError == 0) )
  26497. + {
  26498. + mvOsPrintf("Passed, Rate=%3u.%u Mbps (%5u cpp)\n",
  26499. + cesaRate, cesaRateAfterDot, cesaEndTicks - cesaBeginTicks);
  26500. + }
  26501. + else
  26502. + {
  26503. + mvOsPrintf("Failed, Status = 0x%x\n", status);
  26504. + if(cesaCryptoError > 0)
  26505. + mvOsPrintf("cryptoError : %d\n", cesaCryptoError);
  26506. + if(cesaReqIdError > 0)
  26507. + mvOsPrintf("reqIdError : %d\n", cesaReqIdError);
  26508. + if(cesaError > 0)
  26509. + mvOsPrintf("cesaError : %d\n", cesaError);
  26510. + }
  26511. + if(cesaTestIsrMissCount > 0)
  26512. + mvOsPrintf("cesaIsrMissed : %d\n", cesaTestIsrMissCount);
  26513. +}
  26514. +
  26515. +void cesaCheckReady(MV_CESA_RESULT* r)
  26516. +{
  26517. + int reqId;
  26518. + MV_CESA_MBUF *pMbuf;
  26519. + MV_BOOL isFailed;
  26520. +
  26521. + cesaResult = *r;
  26522. + reqId = (int)cesaResult.pReqPrv;
  26523. + pMbuf = cesaCmdRing[reqId].pDst;
  26524. +
  26525. +/*
  26526. + mvOsPrintf("cesaCheckReady: reqId=%d, checkOffset=%d, checkSize=%d\n",
  26527. + reqId, cesaCheckOffset, cesaCheckSize);
  26528. +*/
  26529. + /* Check expected reqId */
  26530. + if(reqId != cesaExpReqId)
  26531. + {
  26532. + cesaReqIdError++;
  26533. +/*
  26534. + mvOsPrintf("CESA reqId Error: cbIter=%d (%d), reqId=%d, expReqId=%d\n",
  26535. + cesaCbIter, cesaIteration, reqId, cesaExpReqId);
  26536. +*/
  26537. + }
  26538. + else
  26539. + {
  26540. + if( (cesaCheckMode == CESA_FULL_CHECK_MODE) ||
  26541. + (cesaCheckMode == CESA_FAST_CHECK_MODE) )
  26542. + {
  26543. + if(cesaResult.retCode != MV_OK)
  26544. + {
  26545. + cesaError++;
  26546. +
  26547. + mvOsPrintf("CESA Error: cbIter=%d (%d), reqId=%d, rc=%d\n",
  26548. + cesaCbIter, cesaIteration, reqId, cesaResult.retCode);
  26549. + }
  26550. + else
  26551. + {
  26552. + if( (cesaCheckSize > 0) && (cesaOutputHexStr != NULL) )
  26553. + {
  26554. + /* Check expected output */
  26555. +
  26556. + isFailed = cesaCheckMbuf(pMbuf, cesaOutputHexStr, cesaCheckOffset, cesaCheckSize);
  26557. + if(isFailed)
  26558. + {
  26559. + mvOsPrintf("CESA Crypto Error: cbIter=%d (%d), reqId=%d\n",
  26560. + cesaCbIter, cesaIteration, reqId);
  26561. +
  26562. + CESA_TEST_DEBUG_PRINT(("Error: reqId=%d, reqSize=%d, checkOffset=%d, checkSize=%d\n",
  26563. + reqId, cesaReqSize, cesaCheckOffset, cesaCheckSize));
  26564. +
  26565. + CESA_TEST_DEBUG_PRINT(("Output str: %s\n", cesaOutputHexStr));
  26566. +
  26567. + CESA_TEST_DEBUG_CODE( mvCesaDebugMbuf("error", pMbuf, 0, cesaCheckOffset+cesaCheckSize) );
  26568. +
  26569. + cesaCryptoError++;
  26570. + }
  26571. + }
  26572. + }
  26573. + }
  26574. + }
  26575. + if(cesaCheckMode == CESA_SHOW_CHECK_MODE)
  26576. + {
  26577. + extractMbuf(pMbuf, cesaCheckOffset, cesaCheckSize, cesaHexBuffer);
  26578. + mvOsPrintf("%4d, %s\n", cesaCheckOffset, cesaHexBuffer);
  26579. + }
  26580. +
  26581. + cesaCbIter++;
  26582. + if(cesaCbIter >= cesaIteration)
  26583. + {
  26584. + cesaCbIter = 0;
  26585. + cesaExpReqId = 0;
  26586. + cesaIsReady = MV_TRUE;
  26587. +
  26588. + cesaEndTicks = CESA_TEST_TICK_GET();
  26589. + cesaRate = getRate(&cesaRateAfterDot);
  26590. + }
  26591. + else
  26592. + {
  26593. + cesaExpReqId = reqId + 1;
  26594. + if(cesaExpReqId == CESA_DEF_REQ_SIZE)
  26595. + cesaExpReqId = 0;
  26596. + }
  26597. +}
  26598. +
  26599. +
  26600. +#ifdef MV_NETBSD
  26601. +static int cesaTestReadyIsr(void *arg)
  26602. +#else
  26603. +#ifdef __KERNEL__
  26604. +static irqreturn_t cesaTestReadyIsr( int irq , void *dev_id)
  26605. +#endif
  26606. +#ifdef MV_VXWORKS
  26607. +void cesaTestReadyIsr(void)
  26608. +#endif
  26609. +#endif
  26610. +{
  26611. + MV_U32 cause;
  26612. + MV_STATUS status;
  26613. + MV_CESA_RESULT result;
  26614. +
  26615. + cesaTestIsrCount++;
  26616. + /* Clear cause register */
  26617. + cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  26618. + if( (cause & MV_CESA_CAUSE_ACC_DMA_ALL_MASK) == 0)
  26619. + {
  26620. + mvOsPrintf("cesaTestReadyIsr: cause=0x%x\n", cause);
  26621. +#ifdef MV_NETBSD
  26622. + return 0;
  26623. +#else
  26624. +#ifdef __KERNEL__
  26625. + return 1;
  26626. +#else
  26627. + return;
  26628. +#endif
  26629. +#endif
  26630. + }
  26631. +
  26632. + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
  26633. +
  26634. + while(MV_TRUE)
  26635. + {
  26636. + /* Get Ready requests */
  26637. + status = mvCesaReadyGet(&result);
  26638. + if(status == MV_OK)
  26639. + cesaCheckReady(&result);
  26640. +
  26641. + break;
  26642. + }
  26643. + if( (cesaTestFull == 1) && (status != MV_BUSY) )
  26644. + {
  26645. + cesaTestFull = 0;
  26646. + CESA_TEST_WAKE_UP();
  26647. + }
  26648. +
  26649. +#ifdef __KERNEL__
  26650. + return 1;
  26651. +#endif
  26652. +}
  26653. +
  26654. +void
  26655. +cesaTestCheckReady(const MV_CESA_RESULT *r)
  26656. +{
  26657. + MV_CESA_RESULT result = *r;
  26658. +
  26659. + cesaCheckReady(&result);
  26660. +
  26661. + if (cesaTestFull == 1) {
  26662. + cesaTestFull = 0;
  26663. + CESA_TEST_WAKE_UP();
  26664. + }
  26665. +}
  26666. +
  26667. +static INLINE int open_session(MV_CESA_OPEN_SESSION* pOs)
  26668. +{
  26669. + MV_U16 sid;
  26670. + MV_STATUS status;
  26671. +
  26672. + status = mvCesaSessionOpen(pOs, (short*)&sid);
  26673. + if(status != MV_OK)
  26674. + {
  26675. + mvOsPrintf("CesaTest: Can't open new session - status = 0x%x\n",
  26676. + status);
  26677. + return -1;
  26678. + }
  26679. +
  26680. + return (int)sid;
  26681. +}
  26682. +
  26683. +void close_session(int sid)
  26684. +{
  26685. + MV_STATUS status;
  26686. +
  26687. + status = mvCesaSessionClose(sid);
  26688. + if(status != MV_OK)
  26689. + {
  26690. + mvOsPrintf("CesaTest: Can't close session %d - status = 0x%x\n",
  26691. + sid, status);
  26692. + }
  26693. +}
  26694. +
  26695. +MV_STATUS testOpen(int idx)
  26696. +{
  26697. + MV_CESA_OPEN_SESSION os;
  26698. + int sid, i, testIdx;
  26699. + MV_CESA_TEST_SESSION* pTestSession;
  26700. + MV_U16 digestSize = 0;
  26701. +
  26702. + pTestSession = getTestSessionDb(idx, &testIdx);
  26703. + if(pTestSession == NULL)
  26704. + {
  26705. + mvOsPrintf("Test %d is not exist\n", idx);
  26706. + return MV_BAD_PARAM;
  26707. + }
  26708. + pTestSession = &pTestSession[testIdx];
  26709. +
  26710. + if(pTestSession->sid != -1)
  26711. + {
  26712. + mvOsPrintf("Session for test %d already created: sid=%d\n",
  26713. + idx, pTestSession->sid);
  26714. + return MV_OK;
  26715. + }
  26716. +
  26717. + os.cryptoAlgorithm = pTestSession->cryptoAlgorithm;
  26718. + os.macMode = pTestSession->macAlgorithm;
  26719. + switch(os.macMode)
  26720. + {
  26721. + case MV_CESA_MAC_MD5:
  26722. + case MV_CESA_MAC_HMAC_MD5:
  26723. + digestSize = MV_CESA_MD5_DIGEST_SIZE;
  26724. + break;
  26725. +
  26726. + case MV_CESA_MAC_SHA1:
  26727. + case MV_CESA_MAC_HMAC_SHA1:
  26728. + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
  26729. + break;
  26730. +
  26731. + case MV_CESA_MAC_NULL:
  26732. + digestSize = 0;
  26733. + }
  26734. + os.cryptoMode = pTestSession->cryptoMode;
  26735. + os.direction = pTestSession->direction;
  26736. + os.operation = pTestSession->operation;
  26737. +
  26738. + for(i=0; i<pTestSession->cryptoKeySize; i++)
  26739. + os.cryptoKey[i] = pTestSession->pCryptoKey[i];
  26740. +
  26741. + os.cryptoKeyLength = pTestSession->cryptoKeySize;
  26742. +
  26743. + for(i=0; i<pTestSession->macKeySize; i++)
  26744. + os.macKey[i] = pTestSession->pMacKey[i];
  26745. +
  26746. + os.macKeyLength = pTestSession->macKeySize;
  26747. + os.digestSize = digestSize;
  26748. +
  26749. + sid = open_session(&os);
  26750. + if(sid == -1)
  26751. + {
  26752. + mvOsPrintf("Can't open session for test %d: rc=0x%x\n",
  26753. + idx, cesaResult.retCode);
  26754. + return cesaResult.retCode;
  26755. + }
  26756. + CESA_TEST_DEBUG_PRINT(("Opened session: sid = %d\n", sid));
  26757. + pTestSession->sid = sid;
  26758. + return MV_OK;
  26759. +}
  26760. +
  26761. +MV_STATUS testClose(int idx)
  26762. +{
  26763. + int testIdx;
  26764. + MV_CESA_TEST_SESSION* pTestSession;
  26765. +
  26766. + pTestSession = getTestSessionDb(idx, &testIdx);
  26767. + if(pTestSession == NULL)
  26768. + {
  26769. + mvOsPrintf("Test %d is not exist\n", idx);
  26770. + return MV_BAD_PARAM;
  26771. + }
  26772. + pTestSession = &pTestSession[testIdx];
  26773. +
  26774. + if(pTestSession->sid == -1)
  26775. + {
  26776. + mvOsPrintf("Test session %d is not opened\n", idx);
  26777. + return MV_NO_SUCH;
  26778. + }
  26779. +
  26780. + close_session(pTestSession->sid);
  26781. + pTestSession->sid = -1;
  26782. +
  26783. + return MV_OK;
  26784. +}
  26785. +
  26786. +MV_STATUS testCmd(int sid, int iter, MV_CESA_COMMAND* pCmd,
  26787. + MV_CESA_TEST_SESSION* pTestSession, MV_U8* pIV, int ivSize)
  26788. +{
  26789. + int cmdReqId = 0;
  26790. + int i;
  26791. + MV_STATUS rc = MV_OK;
  26792. + char ivZeroHex[] = "0000";
  26793. +
  26794. + if(iter == 0)
  26795. + iter = CESA_DEF_ITER_NUM;
  26796. +
  26797. + if(pCmd == NULL)
  26798. + {
  26799. + mvOsPrintf("testCmd failed: pCmd=NULL\n");
  26800. + return MV_BAD_PARAM;
  26801. + }
  26802. + pCmd->sessionId = sid;
  26803. +
  26804. + cesaCryptoError = 0;
  26805. + cesaReqIdError = 0;
  26806. + cesaError = 0;
  26807. + cesaTestIsrMissCount = 0;
  26808. + cesaIsReady = MV_FALSE;
  26809. + cesaIteration = iter;
  26810. +
  26811. + if(cesaInputHexStr == NULL)
  26812. + cesaInputHexStr = cesaPlainHexEbc;
  26813. +
  26814. + for(i=0; i<CESA_DEF_REQ_SIZE; i++)
  26815. + {
  26816. + pCmd->pSrc = (MV_CESA_MBUF*)(cesaCmdRing[i].pSrc);
  26817. + if(pIV != NULL)
  26818. + {
  26819. + /* If IV from SA - set IV in Source buffer to zeros */
  26820. + cesaSetMbuf(pCmd->pSrc, ivZeroHex, 0, pCmd->cryptoOffset);
  26821. + cesaSetMbuf(pCmd->pSrc, cesaInputHexStr, pCmd->cryptoOffset,
  26822. + (cesaReqSize - pCmd->cryptoOffset));
  26823. + }
  26824. + else
  26825. + {
  26826. + cesaSetMbuf(pCmd->pSrc, cesaInputHexStr, 0, cesaReqSize);
  26827. + }
  26828. + pCmd->pDst = (MV_CESA_MBUF*)(cesaCmdRing[i].pDst);
  26829. + cesaSetMbuf(pCmd->pDst, cesaNullPlainHexText, 0, cesaReqSize);
  26830. +
  26831. + memcpy(&cesaCmdRing[i], pCmd, sizeof(*pCmd));
  26832. + }
  26833. +
  26834. + if(cesaCheckMode == CESA_SW_SHOW_CHECK_MODE)
  26835. + {
  26836. + MV_U8 pDigest[MV_CESA_MAX_DIGEST_SIZE];
  26837. +
  26838. + if(pTestSession->macAlgorithm == MV_CESA_MAC_MD5)
  26839. + {
  26840. + mvMD5(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, pDigest);
  26841. + mvOsPrintf("SW HASH_MD5: reqSize=%d, macLength=%d\n",
  26842. + cesaReqSize, pCmd->macLength);
  26843. + mvDebugMemDump(pDigest, MV_CESA_MD5_DIGEST_SIZE, 1);
  26844. + return MV_OK;
  26845. + }
  26846. + if(pTestSession->macAlgorithm == MV_CESA_MAC_SHA1)
  26847. + {
  26848. + mvSHA1(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, pDigest);
  26849. + mvOsPrintf("SW HASH_SHA1: reqSize=%d, macLength=%d\n",
  26850. + cesaReqSize, pCmd->macLength);
  26851. + mvDebugMemDump(pDigest, MV_CESA_SHA1_DIGEST_SIZE, 1);
  26852. + return MV_OK;
  26853. + }
  26854. + }
  26855. +
  26856. + cesaBeginTicks = CESA_TEST_TICK_GET();
  26857. + CESA_TEST_DEBUG_CODE( memset(cesaTestTrace, 0, sizeof(cesaTestTrace));
  26858. + cesaTestTraceIdx = 0;
  26859. + );
  26860. +
  26861. + if(cesaCheckMode == CESA_SW_NULL_CHECK_MODE)
  26862. + {
  26863. + volatile MV_U8 pDigest[MV_CESA_MAX_DIGEST_SIZE];
  26864. +
  26865. + for(i=0; i<iter; i++)
  26866. + {
  26867. + if(pTestSession->macAlgorithm == MV_CESA_MAC_MD5)
  26868. + {
  26869. + mvMD5(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, (unsigned char*)pDigest);
  26870. + }
  26871. + if(pTestSession->macAlgorithm == MV_CESA_MAC_SHA1)
  26872. + {
  26873. + mvSHA1(pCmd->pSrc->pFrags[0].bufVirtPtr, pCmd->macLength, (MV_U8 *)pDigest);
  26874. + }
  26875. + }
  26876. + cesaEndTicks = CESA_TEST_TICK_GET();
  26877. + cesaRate = getRate(&cesaRateAfterDot);
  26878. + cesaIsReady = MV_TRUE;
  26879. +
  26880. + return MV_OK;
  26881. + }
  26882. +
  26883. + /*cesaTestIsrCount = 0;*/
  26884. + /*mvCesaDebugStatsClear();*/
  26885. +
  26886. +#ifndef MV_NETBSD
  26887. + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
  26888. +#endif
  26889. +
  26890. + for(i=0; i<iter; i++)
  26891. + {
  26892. + unsigned long flags;
  26893. +
  26894. + pCmd = &cesaCmdRing[cmdReqId];
  26895. + pCmd->pReqPrv = (void*)cmdReqId;
  26896. +
  26897. + CESA_TEST_LOCK(flags);
  26898. +
  26899. + rc = mvCesaAction(pCmd);
  26900. + if(rc == MV_NO_RESOURCE)
  26901. + cesaTestFull = 1;
  26902. +
  26903. + CESA_TEST_UNLOCK(flags);
  26904. +
  26905. + if(rc == MV_NO_RESOURCE)
  26906. + {
  26907. + CESA_TEST_LOCK(flags);
  26908. + CESA_TEST_WAIT( (cesaTestFull == 0), 100);
  26909. + CESA_TEST_UNLOCK(flags);
  26910. + if(cesaTestFull == 1)
  26911. + {
  26912. + mvOsPrintf("CESA Test timeout: i=%d, iter=%d, cesaTestFull=%d\n",
  26913. + i, iter, cesaTestFull);
  26914. + cesaTestFull = 0;
  26915. + return MV_TIMEOUT;
  26916. + }
  26917. +
  26918. + CESA_TEST_LOCK(flags);
  26919. +
  26920. + rc = mvCesaAction(pCmd);
  26921. +
  26922. + CESA_TEST_UNLOCK(flags);
  26923. + }
  26924. + if( (rc != MV_OK) && (rc != MV_NO_MORE) )
  26925. + {
  26926. + mvOsPrintf("mvCesaAction failed: rc=%d\n", rc);
  26927. + return rc;
  26928. + }
  26929. +
  26930. + cmdReqId++;
  26931. + if(cmdReqId >= CESA_DEF_REQ_SIZE)
  26932. + cmdReqId = 0;
  26933. +
  26934. +#ifdef MV_LINUX
  26935. + /* Reschedule each 16 requests */
  26936. + if( (i & 0xF) == 0)
  26937. + schedule();
  26938. +#endif
  26939. + }
  26940. + return MV_OK;
  26941. +}
  26942. +
  26943. +void cesaTestStart(int bufNum, int bufSize)
  26944. +{
  26945. + int i, j, idx;
  26946. + MV_CESA_MBUF *pMbufSrc, *pMbufDst;
  26947. + MV_BUF_INFO *pFragsSrc, *pFragsDst;
  26948. + char *pBuf;
  26949. +#ifndef MV_NETBSD
  26950. + int numOfSessions, queueDepth;
  26951. + char *pSram;
  26952. + MV_STATUS status;
  26953. + MV_CPU_DEC_WIN addrDecWin;
  26954. +#endif
  26955. +
  26956. + cesaCmdRing = mvOsMalloc(sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);
  26957. + if(cesaCmdRing == NULL)
  26958. + {
  26959. + mvOsPrintf("testStart: Can't allocate %ld bytes of memory\n",
  26960. + sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);
  26961. + return;
  26962. + }
  26963. + memset(cesaCmdRing, 0, sizeof(MV_CESA_COMMAND) * CESA_DEF_REQ_SIZE);
  26964. +
  26965. + if(bufNum == 0)
  26966. + bufNum = CESA_DEF_BUF_NUM;
  26967. +
  26968. + if(bufSize == 0)
  26969. + bufSize = CESA_DEF_BUF_SIZE;
  26970. +
  26971. + cesaBufNum = bufNum;
  26972. + cesaBufSize = bufSize;
  26973. + mvOsPrintf("CESA test started: bufNum = %d, bufSize = %d\n",
  26974. + bufNum, bufSize);
  26975. +
  26976. + cesaHexBuffer = mvOsMalloc(2*bufNum*bufSize);
  26977. + if(cesaHexBuffer == NULL)
  26978. + {
  26979. + mvOsPrintf("testStart: Can't malloc %d bytes for cesaHexBuffer.\n",
  26980. + 2*bufNum*bufSize);
  26981. + return;
  26982. + }
  26983. + memset(cesaHexBuffer, 0, (2*bufNum*bufSize));
  26984. +
  26985. + cesaBinBuffer = mvOsMalloc(bufNum*bufSize);
  26986. + if(cesaBinBuffer == NULL)
  26987. + {
  26988. + mvOsPrintf("testStart: Can't malloc %d bytes for cesaBinBuffer\n",
  26989. + bufNum*bufSize);
  26990. + return;
  26991. + }
  26992. + memset(cesaBinBuffer, 0, (bufNum*bufSize));
  26993. +
  26994. + cesaExpBinBuffer = mvOsMalloc(bufNum*bufSize);
  26995. + if(cesaExpBinBuffer == NULL)
  26996. + {
  26997. + mvOsPrintf("testStart: Can't malloc %d bytes for cesaExpBinBuffer\n",
  26998. + bufNum*bufSize);
  26999. + return;
  27000. + }
  27001. + memset(cesaExpBinBuffer, 0, (bufNum*bufSize));
  27002. +
  27003. + CESA_TEST_WAIT_INIT();
  27004. +
  27005. + pMbufSrc = mvOsMalloc(sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
  27006. + pFragsSrc = mvOsMalloc(sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
  27007. +
  27008. + pMbufDst = mvOsMalloc(sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
  27009. + pFragsDst = mvOsMalloc(sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
  27010. +
  27011. + if( (pMbufSrc == NULL) || (pFragsSrc == NULL) ||
  27012. + (pMbufDst == NULL) || (pFragsDst == NULL) )
  27013. + {
  27014. + mvOsPrintf("testStart: Can't malloc Src and Dst pMbuf and pFrags structures.\n");
  27015. + /* !!!! Dima cesaTestCleanup();*/
  27016. + return;
  27017. + }
  27018. +
  27019. + memset(pMbufSrc, 0, sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
  27020. + memset(pFragsSrc, 0, sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
  27021. +
  27022. + memset(pMbufDst, 0, sizeof(MV_CESA_MBUF) * CESA_DEF_REQ_SIZE);
  27023. + memset(pFragsDst, 0, sizeof(MV_BUF_INFO) * bufNum * CESA_DEF_REQ_SIZE);
  27024. +
  27025. + mvOsPrintf("Cesa Test Start: pMbufSrc=%p, pFragsSrc=%p, pMbufDst=%p, pFragsDst=%p\n",
  27026. + pMbufSrc, pFragsSrc, pMbufDst, pFragsDst);
  27027. +
  27028. + idx = 0;
  27029. + for(i=0; i<CESA_DEF_REQ_SIZE; i++)
  27030. + {
  27031. + pBuf = mvOsIoCachedMalloc(cesaTestOSHandle,bufSize * bufNum * 2,
  27032. + &cesaReqBufs[i].bufPhysAddr,
  27033. + &cesaReqBufs[i].memHandle);
  27034. + if(pBuf == NULL)
  27035. + {
  27036. + mvOsPrintf("testStart: Can't malloc %d bytes for pBuf\n",
  27037. + bufSize * bufNum * 2);
  27038. + return;
  27039. + }
  27040. +
  27041. + memset(pBuf, 0, bufSize * bufNum * 2);
  27042. + mvOsCacheFlush(cesaTestOSHandle,pBuf, bufSize * bufNum * 2);
  27043. + if(pBuf == NULL)
  27044. + {
  27045. + mvOsPrintf("cesaTestStart: Can't allocate %d bytes for req_%d buffers\n",
  27046. + bufSize * bufNum * 2, i);
  27047. + return;
  27048. + }
  27049. +
  27050. + cesaReqBufs[i].bufVirtPtr = (MV_U8*)pBuf;
  27051. + cesaReqBufs[i].bufSize = bufSize * bufNum * 2;
  27052. +
  27053. + cesaCmdRing[i].pSrc = &pMbufSrc[i];
  27054. + cesaCmdRing[i].pSrc->pFrags = &pFragsSrc[idx];
  27055. + cesaCmdRing[i].pSrc->numFrags = bufNum;
  27056. + cesaCmdRing[i].pSrc->mbufSize = 0;
  27057. +
  27058. + cesaCmdRing[i].pDst = &pMbufDst[i];
  27059. + cesaCmdRing[i].pDst->pFrags = &pFragsDst[idx];
  27060. + cesaCmdRing[i].pDst->numFrags = bufNum;
  27061. + cesaCmdRing[i].pDst->mbufSize = 0;
  27062. +
  27063. + for(j=0; j<bufNum; j++)
  27064. + {
  27065. + cesaCmdRing[i].pSrc->pFrags[j].bufVirtPtr = (MV_U8*)pBuf;
  27066. + cesaCmdRing[i].pSrc->pFrags[j].bufSize = bufSize;
  27067. + pBuf += bufSize;
  27068. + cesaCmdRing[i].pDst->pFrags[j].bufVirtPtr = (MV_U8*)pBuf;
  27069. + cesaCmdRing[i].pDst->pFrags[j].bufSize = bufSize;
  27070. + pBuf += bufSize;
  27071. + }
  27072. + idx += bufNum;
  27073. + }
  27074. +
  27075. +#ifndef MV_NETBSD
  27076. + if (mvCpuIfTargetWinGet(CRYPT_ENG, &addrDecWin) == MV_OK)
  27077. + pSram = (char*)addrDecWin.addrWin.baseLow;
  27078. + else
  27079. + {
  27080. + mvOsPrintf("mvCesaInit: ERR. mvCpuIfTargetWinGet failed\n");
  27081. + return;
  27082. + }
  27083. +
  27084. +#ifdef MV_CESA_NO_SRAM
  27085. + pSram = mvOsMalloc(4*1024+8);
  27086. + if(pSram == NULL)
  27087. + {
  27088. + mvOsPrintf("CesaTest: can't allocate %d bytes for SRAM simulation\n",
  27089. + 4*1024+8);
  27090. + /* !!!! Dima cesaTestCleanup();*/
  27091. + return;
  27092. + }
  27093. + pSram = (MV_U8*)MV_ALIGN_UP((MV_U32)pSram, 8);
  27094. +#endif /* MV_CESA_NO_SRAM */
  27095. +
  27096. + numOfSessions = CESA_DEF_SESSION_NUM;
  27097. + queueDepth = CESA_DEF_REQ_SIZE - MV_CESA_MAX_CHAN;
  27098. +
  27099. + status = mvCesaInit(numOfSessions, queueDepth, pSram, NULL);
  27100. + if(status != MV_OK)
  27101. + {
  27102. + mvOsPrintf("mvCesaInit is Failed: status = 0x%x\n", status);
  27103. + /* !!!! Dima cesaTestCleanup();*/
  27104. + return;
  27105. + }
  27106. +#endif /* !MV_NETBSD */
  27107. +
  27108. + /* Prepare data for tests */
  27109. + for(i=0; i<50; i++)
  27110. + strcat((char*)cesaDataHexStr3, "dd");
  27111. +
  27112. + strcpy((char*)cesaDataAndMd5digest3, cesaDataHexStr3);
  27113. + strcpy((char*)cesaDataAndSha1digest3, cesaDataHexStr3);
  27114. +
  27115. + /* Digest must be 8 byte aligned */
  27116. + for(; i<56; i++)
  27117. + {
  27118. + strcat((char*)cesaDataAndMd5digest3, "00");
  27119. + strcat((char*)cesaDataAndSha1digest3, "00");
  27120. + }
  27121. + strcat((char*)cesaDataAndMd5digest3, cesaHmacMd5digestHex3);
  27122. + strcat((char*)cesaDataAndSha1digest3, cesaHmacSha1digestHex3);
  27123. +
  27124. +#ifndef MV_NETBSD
  27125. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  27126. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, MV_CESA_CAUSE_ACC_DMA_MASK);
  27127. +#endif
  27128. +
  27129. +#ifdef MV_VXWORKS
  27130. + {
  27131. + MV_STATUS status;
  27132. +
  27133. + status = intConnect((VOIDFUNCPTR *)INT_LVL_CESA, cesaTestReadyIsr, (int)NULL);
  27134. + if (status != OK)
  27135. + {
  27136. + mvOsPrintf("CESA: Can't connect CESA (%d) interrupt, status=0x%x \n",
  27137. + INT_LVL_CESA, status);
  27138. + /* !!!! Dima cesaTestCleanup();*/
  27139. + return;
  27140. + }
  27141. + cesaSemId = semMCreate(SEM_Q_PRIORITY | SEM_INVERSION_SAFE | SEM_DELETE_SAFE);
  27142. + if(cesaSemId == NULL)
  27143. + {
  27144. + mvOsPrintf("cesaTestStart: Can't create semaphore\n");
  27145. + return;
  27146. + }
  27147. + intEnable(INT_LVL_CESA);
  27148. + }
  27149. +#endif /* MV_VXWORKS */
  27150. +
  27151. +#if !defined(MV_NETBSD) && defined(__KERNEL__)
  27152. + if( request_irq(CESA_IRQ, cesaTestReadyIsr, (SA_INTERRUPT) , "cesa_test", NULL ) )
  27153. + {
  27154. + mvOsPrintf( "cannot assign irq\n" );
  27155. + /* !!!! Dima cesaTestCleanup();*/
  27156. + return;
  27157. + }
  27158. + spin_lock_init( &cesaLock );
  27159. +#endif
  27160. +}
  27161. +
  27162. +MV_STATUS testRun(int idx, int caseIdx, int iter,
  27163. + int reqSize, int checkMode)
  27164. +{
  27165. + int testIdx, count, sid, digestSize;
  27166. + int blockSize;
  27167. + MV_CESA_TEST_SESSION* pTestSession;
  27168. + MV_CESA_COMMAND cmd;
  27169. + MV_STATUS status;
  27170. +
  27171. + memset(&cmd, 0, sizeof(cmd));
  27172. +
  27173. + pTestSession = getTestSessionDb(idx, &testIdx);
  27174. + if(pTestSession == NULL)
  27175. + {
  27176. + mvOsPrintf("Test %d is not exist\n", idx);
  27177. + return MV_BAD_PARAM;
  27178. + }
  27179. + pTestSession = &pTestSession[testIdx];
  27180. +
  27181. + sid = pTestSession->sid;
  27182. + if(sid == -1)
  27183. + {
  27184. + mvOsPrintf("Test %d is not opened\n", idx);
  27185. + return MV_BAD_STATE;
  27186. + }
  27187. + switch(pTestSession->cryptoAlgorithm)
  27188. + {
  27189. + case MV_CESA_CRYPTO_DES:
  27190. + case MV_CESA_CRYPTO_3DES:
  27191. + blockSize = MV_CESA_DES_BLOCK_SIZE;
  27192. + break;
  27193. +
  27194. + case MV_CESA_CRYPTO_AES:
  27195. + blockSize = MV_CESA_AES_BLOCK_SIZE;
  27196. + break;
  27197. +
  27198. + case MV_CESA_CRYPTO_NULL:
  27199. + blockSize = 0;
  27200. + break;
  27201. +
  27202. + default:
  27203. + mvOsPrintf("cesaTestRun: Bad CryptoAlgorithm=%d\n",
  27204. + pTestSession->cryptoAlgorithm);
  27205. + return MV_BAD_PARAM;
  27206. + }
  27207. + switch(pTestSession->macAlgorithm)
  27208. + {
  27209. + case MV_CESA_MAC_MD5:
  27210. + case MV_CESA_MAC_HMAC_MD5:
  27211. + digestSize = MV_CESA_MD5_DIGEST_SIZE;
  27212. + break;
  27213. +
  27214. + case MV_CESA_MAC_SHA1:
  27215. + case MV_CESA_MAC_HMAC_SHA1:
  27216. + digestSize = MV_CESA_SHA1_DIGEST_SIZE;
  27217. + break;
  27218. + default:
  27219. + digestSize = 0;
  27220. + }
  27221. +
  27222. + if(iter == 0)
  27223. + iter = CESA_DEF_ITER_NUM;
  27224. +
  27225. + if(pTestSession->direction == MV_CESA_DIR_ENCODE)
  27226. + {
  27227. + cesaOutputHexStr = cesaTestCases[caseIdx].cipherHexStr;
  27228. + cesaInputHexStr = cesaTestCases[caseIdx].plainHexStr;
  27229. + }
  27230. + else
  27231. + {
  27232. + cesaOutputHexStr = cesaTestCases[caseIdx].plainHexStr;
  27233. + cesaInputHexStr = cesaTestCases[caseIdx].cipherHexStr;
  27234. + }
  27235. +
  27236. + cmd.sessionId = sid;
  27237. + if(checkMode == CESA_FAST_CHECK_MODE)
  27238. + {
  27239. + cmd.cryptoLength = cesaTestCases[caseIdx].cryptoLength;
  27240. + cmd.macLength = cesaTestCases[caseIdx].macLength;
  27241. + }
  27242. + else
  27243. + {
  27244. + cmd.cryptoLength = reqSize;
  27245. + cmd.macLength = reqSize;
  27246. + }
  27247. + cesaRateSize = cmd.cryptoLength;
  27248. + cesaReqSize = cmd.cryptoLength;
  27249. + cmd.cryptoOffset = 0;
  27250. + if(pTestSession->operation != MV_CESA_MAC_ONLY)
  27251. + {
  27252. + if( (pTestSession->cryptoMode == MV_CESA_CRYPTO_CBC) ||
  27253. + (pTestSession->cryptoMode == MV_CESA_CRYPTO_CTR) )
  27254. + {
  27255. + cmd.ivOffset = 0;
  27256. + cmd.cryptoOffset = blockSize;
  27257. + if(cesaTestCases[caseIdx].pCryptoIV == NULL)
  27258. + {
  27259. + cmd.ivFromUser = 1;
  27260. + }
  27261. + else
  27262. + {
  27263. + cmd.ivFromUser = 0;
  27264. + mvCesaCryptoIvSet(cesaTestCases[caseIdx].pCryptoIV, blockSize);
  27265. + }
  27266. + cesaReqSize = cmd.cryptoOffset + cmd.cryptoLength;
  27267. + }
  27268. + }
  27269. +
  27270. +/*
  27271. + mvOsPrintf("ivFromUser=%d, cryptoLength=%d, cesaReqSize=%d, cryptoOffset=%d\n",
  27272. + cmd.ivFromUser, cmd.cryptoLength, cesaReqSize, cmd.cryptoOffset);
  27273. +*/
  27274. + if(pTestSession->operation != MV_CESA_CRYPTO_ONLY)
  27275. + {
  27276. + cmd.macOffset = cmd.cryptoOffset;
  27277. +
  27278. + if(cesaTestCases[caseIdx].digestOffset == -1)
  27279. + {
  27280. + cmd.digestOffset = cmd.macOffset + cmd.macLength;
  27281. + cmd.digestOffset = MV_ALIGN_UP(cmd.digestOffset, 8);
  27282. + }
  27283. + else
  27284. + {
  27285. + cmd.digestOffset = cesaTestCases[caseIdx].digestOffset;
  27286. + }
  27287. + if( (cmd.digestOffset + digestSize) > cesaReqSize)
  27288. + cesaReqSize = cmd.digestOffset + digestSize;
  27289. + }
  27290. +
  27291. + cesaCheckMode = checkMode;
  27292. +
  27293. + if(checkMode == CESA_NULL_CHECK_MODE)
  27294. + {
  27295. + cesaCheckSize = 0;
  27296. + cesaCheckOffset = 0;
  27297. + }
  27298. + else
  27299. + {
  27300. + if(pTestSession->operation == MV_CESA_CRYPTO_ONLY)
  27301. + {
  27302. + cesaCheckOffset = 0;
  27303. + cesaCheckSize = cmd.cryptoLength;
  27304. + }
  27305. + else
  27306. + {
  27307. + cesaCheckSize = digestSize;
  27308. + cesaCheckOffset = cmd.digestOffset;
  27309. + }
  27310. + }
  27311. +/*
  27312. + mvOsPrintf("reqSize=%d, checkSize=%d, checkOffset=%d, checkMode=%d\n",
  27313. + cesaReqSize, cesaCheckSize, cesaCheckOffset, cesaCheckMode);
  27314. +
  27315. + mvOsPrintf("blockSize=%d, ivOffset=%d, ivFromUser=%d, crOffset=%d, crLength=%d\n",
  27316. + blockSize, cmd.ivOffset, cmd.ivFromUser,
  27317. + cmd.cryptoOffset, cmd.cryptoLength);
  27318. +
  27319. + mvOsPrintf("macOffset=%d, digestOffset=%d, macLength=%d\n",
  27320. + cmd.macOffset, cmd.digestOffset, cmd.macLength);
  27321. +*/
  27322. + status = testCmd(sid, iter, &cmd, pTestSession,
  27323. + cesaTestCases[caseIdx].pCryptoIV, blockSize);
  27324. +
  27325. + if(status != MV_OK)
  27326. + return status;
  27327. +
  27328. + /* Wait when all callbacks is received */
  27329. + count = 0;
  27330. + while(cesaIsReady == MV_FALSE)
  27331. + {
  27332. + mvOsSleep(10);
  27333. + count++;
  27334. + if(count > 100)
  27335. + {
  27336. + mvOsPrintf("testRun: Timeout occured\n");
  27337. + return MV_TIMEOUT;
  27338. + }
  27339. + }
  27340. +
  27341. + return MV_OK;
  27342. +}
  27343. +
  27344. +
  27345. +void cesaTestStop(void)
  27346. +{
  27347. + MV_CESA_MBUF *pMbufSrc, *pMbufDst;
  27348. + MV_BUF_INFO *pFragsSrc, *pFragsDst;
  27349. + int i;
  27350. +
  27351. + /* Release all allocated memories */
  27352. + pMbufSrc = (MV_CESA_MBUF*)(cesaCmdRing[0].pSrc);
  27353. + pFragsSrc = cesaCmdRing[0].pSrc->pFrags;
  27354. +
  27355. + pMbufDst = (MV_CESA_MBUF*)(cesaCmdRing[0].pDst);
  27356. + pFragsDst = cesaCmdRing[0].pDst->pFrags;
  27357. +
  27358. + mvOsFree(pMbufSrc);
  27359. + mvOsFree(pMbufDst);
  27360. + mvOsFree(pFragsSrc);
  27361. + mvOsFree(pFragsDst);
  27362. +
  27363. + for(i=0; i<CESA_DEF_REQ_SIZE; i++)
  27364. + {
  27365. + mvOsIoCachedFree(cesaTestOSHandle,cesaReqBufs[i].bufSize,
  27366. + cesaReqBufs[i].bufPhysAddr,cesaReqBufs[i].bufVirtPtr,
  27367. + cesaReqBufs[i].memHandle);
  27368. + }
  27369. + cesaDataHexStr3[0] = '\0';
  27370. +}
  27371. +
  27372. +void desTest(int iter, int reqSize, int checkMode)
  27373. +{
  27374. + int mode, i;
  27375. + MV_STATUS status;
  27376. +
  27377. + mode = checkMode;
  27378. + if(checkMode == CESA_FULL_CHECK_MODE)
  27379. + mode = CESA_FAST_CHECK_MODE;
  27380. + i = iter;
  27381. + if(mode != CESA_NULL_CHECK_MODE)
  27382. + i = 1;
  27383. +
  27384. + testOpen(0);
  27385. + testOpen(1);
  27386. + testOpen(2);
  27387. + testOpen(3);
  27388. +
  27389. +/* DES / ECB mode / Encrypt only */
  27390. + status = testRun(0, 1, iter, reqSize, checkMode);
  27391. + printTestResults(0, status, checkMode);
  27392. +
  27393. +/* DES / ECB mode / Decrypt only */
  27394. + status = testRun(1, 1, iter, reqSize, checkMode);
  27395. + printTestResults(1, status, checkMode);
  27396. +
  27397. +/* DES / CBC mode / Encrypt only */
  27398. + status = testRun(2, 2, i, reqSize, mode);
  27399. + printTestResults(2, status, mode);
  27400. +
  27401. +/* DES / CBC mode / Decrypt only */
  27402. + status = testRun(3, 2, iter, reqSize, mode);
  27403. + printTestResults(3, status, mode);
  27404. +
  27405. + testClose(0);
  27406. + testClose(1);
  27407. + testClose(2);
  27408. + testClose(3);
  27409. +}
  27410. +
  27411. +void tripleDesTest(int iter, int reqSize, int checkMode)
  27412. +{
  27413. + int mode, i;
  27414. + MV_STATUS status;
  27415. +
  27416. + mode = checkMode;
  27417. + if(checkMode == CESA_FULL_CHECK_MODE)
  27418. + mode = CESA_FAST_CHECK_MODE;
  27419. + i = iter;
  27420. + if(mode != CESA_NULL_CHECK_MODE)
  27421. + i = 1;
  27422. +
  27423. + testOpen(100);
  27424. + testOpen(101);
  27425. + testOpen(102);
  27426. + testOpen(103);
  27427. +
  27428. +/* 3DES / ECB mode / Encrypt only */
  27429. + status = testRun(100, 1, iter, reqSize, checkMode);
  27430. + printTestResults(100, status, checkMode);
  27431. +
  27432. +/* 3DES / ECB mode / Decrypt only */
  27433. + status = testRun(101, 1, iter, reqSize, checkMode);
  27434. + printTestResults(101, status, checkMode);
  27435. +
  27436. +/* 3DES / CBC mode / Encrypt only */
  27437. + status = testRun(102, 2, i, reqSize, mode);
  27438. + printTestResults(102, status, mode);
  27439. +
  27440. +/* 3DES / CBC mode / Decrypt only */
  27441. + status = testRun(103, 2, iter, reqSize, mode);
  27442. + printTestResults(103, status, mode);
  27443. +
  27444. + testClose(100);
  27445. + testClose(101);
  27446. + testClose(102);
  27447. + testClose(103);
  27448. +}
  27449. +
  27450. +void aesTest(int iter, int reqSize, int checkMode)
  27451. +{
  27452. + MV_STATUS status;
  27453. + int mode, i;
  27454. +
  27455. + mode = checkMode;
  27456. + if(checkMode == CESA_FULL_CHECK_MODE)
  27457. + mode = CESA_FAST_CHECK_MODE;
  27458. +
  27459. + i = iter;
  27460. + if(mode != CESA_NULL_CHECK_MODE)
  27461. + i = 1;
  27462. +
  27463. + testOpen(200);
  27464. + testOpen(201);
  27465. + testOpen(202);
  27466. + testOpen(203);
  27467. + testOpen(204);
  27468. + testOpen(205);
  27469. + testOpen(206);
  27470. + testOpen(207);
  27471. + testOpen(208);
  27472. +
  27473. +/* AES-128 Encode ECB mode */
  27474. + status = testRun(200, 3, iter, reqSize, checkMode);
  27475. + printTestResults(200, status, checkMode);
  27476. +
  27477. +/* AES-128 Decode ECB mode */
  27478. + status = testRun(201, 3, iter, reqSize, checkMode);
  27479. + printTestResults(201, status, checkMode);
  27480. +
  27481. +/* AES-128 Encode CBC mode (IV from SA) */
  27482. + status = testRun(202, 10, i, reqSize, mode);
  27483. + printTestResults(202, status, mode);
  27484. +
  27485. +/* AES-128 Encode CBC mode (IV from User) */
  27486. + status = testRun(202, 24, i, reqSize, mode);
  27487. + printTestResults(202, status, mode);
  27488. +
  27489. +/* AES-128 Decode CBC mode */
  27490. + status = testRun(203, 24, iter, reqSize, mode);
  27491. + printTestResults(203, status, checkMode);
  27492. +
  27493. +/* AES-192 Encode ECB mode */
  27494. + status = testRun(204, 4, iter, reqSize, checkMode);
  27495. + printTestResults(204, status, checkMode);
  27496. +
  27497. +/* AES-192 Decode ECB mode */
  27498. + status = testRun(205, 4, iter, reqSize, checkMode);
  27499. + printTestResults(205, status, checkMode);
  27500. +
  27501. +/* AES-256 Encode ECB mode */
  27502. + status = testRun(206, 5, iter, reqSize, checkMode);
  27503. + printTestResults(206, status, checkMode);
  27504. +
  27505. +/* AES-256 Decode ECB mode */
  27506. + status = testRun(207, 5, iter, reqSize, checkMode);
  27507. + printTestResults(207, status, checkMode);
  27508. +
  27509. +#if defined(MV_LINUX)
  27510. +/* AES-128 Encode CTR mode */
  27511. + status = testRun(208, 23, iter, reqSize, mode);
  27512. + printTestResults(208, status, checkMode);
  27513. +#endif
  27514. + testClose(200);
  27515. + testClose(201);
  27516. + testClose(202);
  27517. + testClose(203);
  27518. + testClose(204);
  27519. + testClose(205);
  27520. + testClose(206);
  27521. + testClose(207);
  27522. + testClose(208);
  27523. +}
  27524. +
  27525. +
  27526. +void mdTest(int iter, int reqSize, int checkMode)
  27527. +{
  27528. + int mode;
  27529. + MV_STATUS status;
  27530. +
  27531. + if(iter == 0)
  27532. + iter = CESA_DEF_ITER_NUM;
  27533. +
  27534. + mode = checkMode;
  27535. + if(checkMode == CESA_FULL_CHECK_MODE)
  27536. + mode = CESA_FAST_CHECK_MODE;
  27537. +
  27538. + testOpen(300);
  27539. + testOpen(301);
  27540. + testOpen(302);
  27541. + testOpen(303);
  27542. + testOpen(305);
  27543. +
  27544. +/* HMAC-MD5 Generate signature test */
  27545. + status = testRun(300, 6, iter, reqSize, mode);
  27546. + printTestResults(300, status, checkMode);
  27547. +
  27548. +/* HMAC-MD5 Verify Signature test */
  27549. + status = testRun(301, 7, iter, reqSize, mode);
  27550. + printTestResults(301, status, checkMode);
  27551. +
  27552. +/* HMAC-MD5 Generate signature test */
  27553. + status = testRun(302, 8, iter, reqSize, mode);
  27554. + printTestResults(302, status, checkMode);
  27555. +
  27556. +/* HMAC-MD5 Verify Signature test */
  27557. + status = testRun(303, 9, iter, reqSize, mode);
  27558. + printTestResults(303, status, checkMode);
  27559. +
  27560. +/* HASH-MD5 Generate signature test */
  27561. + status = testRun(305, 15, iter, reqSize, mode);
  27562. + printTestResults(305, status, checkMode);
  27563. +
  27564. + testClose(300);
  27565. + testClose(301);
  27566. + testClose(302);
  27567. + testClose(303);
  27568. + testClose(305);
  27569. +}
  27570. +
  27571. +void shaTest(int iter, int reqSize, int checkMode)
  27572. +{
  27573. + int mode;
  27574. + MV_STATUS status;
  27575. +
  27576. + if(iter == 0)
  27577. + iter = CESA_DEF_ITER_NUM;
  27578. +
  27579. + mode = checkMode;
  27580. + if(checkMode == CESA_FULL_CHECK_MODE)
  27581. + mode = CESA_FAST_CHECK_MODE;
  27582. +
  27583. + testOpen(400);
  27584. + testOpen(401);
  27585. + testOpen(402);
  27586. + testOpen(403);
  27587. + testOpen(405);
  27588. +
  27589. +/* HMAC-SHA1 Generate signature test */
  27590. + status = testRun(400, 11, iter, reqSize, mode);
  27591. + printTestResults(400, status, checkMode);
  27592. +
  27593. +/* HMAC-SHA1 Verify Signature test */
  27594. + status = testRun(401, 12, iter, reqSize, mode);
  27595. + printTestResults(401, status, checkMode);
  27596. +
  27597. +/* HMAC-SHA1 Generate signature test */
  27598. + status = testRun(402, 13, iter, reqSize, mode);
  27599. + printTestResults(402, status, checkMode);
  27600. +
  27601. +/* HMAC-SHA1 Verify Signature test */
  27602. + status = testRun(403, 14, iter, reqSize, mode);
  27603. + printTestResults(403, status, checkMode);
  27604. +
  27605. +/* HMAC-SHA1 Generate signature test */
  27606. + status = testRun(405, 16, iter, reqSize, mode);
  27607. + printTestResults(405, status, checkMode);
  27608. +
  27609. + testClose(400);
  27610. + testClose(401);
  27611. + testClose(402);
  27612. + testClose(403);
  27613. + testClose(405);
  27614. +}
  27615. +
  27616. +void combiTest(int iter, int reqSize, int checkMode)
  27617. +{
  27618. + MV_STATUS status;
  27619. + int mode, i;
  27620. +
  27621. + mode = checkMode;
  27622. + if(checkMode == CESA_FULL_CHECK_MODE)
  27623. + mode = CESA_FAST_CHECK_MODE;
  27624. +
  27625. + if(iter == 0)
  27626. + iter = CESA_DEF_ITER_NUM;
  27627. +
  27628. + i = iter;
  27629. + if(mode != CESA_NULL_CHECK_MODE)
  27630. + i = 1;
  27631. +
  27632. + testOpen(500);
  27633. + testOpen(501);
  27634. + testOpen(502);
  27635. + testOpen(503);
  27636. + testOpen(504);
  27637. + testOpen(505);
  27638. + testOpen(506);
  27639. + testOpen(507);
  27640. +
  27641. +/* DES ECB + MD5 encode test */
  27642. + status = testRun(500, 17, iter, reqSize, mode);
  27643. + printTestResults(500, status, mode);
  27644. +
  27645. +/* DES ECB + SHA1 encode test */
  27646. + status = testRun(501, 18, iter, reqSize, mode);
  27647. + printTestResults(501, status, mode);
  27648. +
  27649. +/* 3DES ECB + MD5 encode test */
  27650. + status = testRun(502, 17, iter, reqSize, mode);
  27651. + printTestResults(502, status, mode);
  27652. +
  27653. +/* 3DES ECB + SHA1 encode test */
  27654. + status = testRun(503, 18, iter, reqSize, mode);
  27655. + printTestResults(503, status, mode);
  27656. +
  27657. +/* 3DES CBC + MD5 encode test */
  27658. + status = testRun(504, 19, i, reqSize, mode);
  27659. + printTestResults(504, status, mode);
  27660. +
  27661. +/* 3DES CBC + SHA1 encode test */
  27662. + status = testRun(505, 20, i, reqSize, mode);
  27663. + printTestResults(505, status, mode);
  27664. +
  27665. +/* AES-128 CBC + MD5 encode test */
  27666. + status = testRun(506, 21, i, reqSize, mode);
  27667. + printTestResults(506, status, mode);
  27668. +
  27669. +/* AES-128 CBC + SHA1 encode test */
  27670. + status = testRun(507, 22, i, reqSize, mode);
  27671. + printTestResults(507, status, mode);
  27672. +
  27673. + testClose(500);
  27674. + testClose(501);
  27675. + testClose(502);
  27676. + testClose(503);
  27677. + testClose(504);
  27678. + testClose(505);
  27679. + testClose(506);
  27680. + testClose(507);
  27681. +}
  27682. +
  27683. +void cesaOneTest(int testIdx, int caseIdx,
  27684. + int iter, int reqSize, int checkMode)
  27685. +{
  27686. + MV_STATUS status;
  27687. +
  27688. + if(iter == 0)
  27689. + iter = CESA_DEF_ITER_NUM;
  27690. +
  27691. + mvOsPrintf("test=%d, case=%d, size=%d, iter=%d\n",
  27692. + testIdx, caseIdx, reqSize, iter);
  27693. +
  27694. + status = testOpen(testIdx);
  27695. +
  27696. + status = testRun(testIdx, caseIdx, iter, reqSize, checkMode);
  27697. + printTestResults(testIdx, status, checkMode);
  27698. + status = testClose(testIdx);
  27699. +
  27700. +}
  27701. +
  27702. +void cesaTest(int iter, int reqSize, int checkMode)
  27703. +{
  27704. + if(iter == 0)
  27705. + iter = CESA_DEF_ITER_NUM;
  27706. +
  27707. + mvOsPrintf("%d iteration\n", iter);
  27708. + mvOsPrintf("%d size\n\n", reqSize);
  27709. +
  27710. +/* DES tests */
  27711. + desTest(iter, reqSize, checkMode);
  27712. +
  27713. +/* 3DES tests */
  27714. + tripleDesTest(iter, reqSize, checkMode);
  27715. +
  27716. +/* AES tests */
  27717. + aesTest(iter, reqSize, checkMode);
  27718. +
  27719. +/* MD5 tests */
  27720. + mdTest(iter, reqSize, checkMode);
  27721. +
  27722. +/* SHA-1 tests */
  27723. + shaTest(iter, reqSize, checkMode);
  27724. +}
  27725. +
  27726. +void multiSizeTest(int idx, int iter, int checkMode, char* inputData)
  27727. +{
  27728. + MV_STATUS status;
  27729. + int i;
  27730. + MV_CESA_SIZE_TEST* pMultiTest;
  27731. +
  27732. + if( testOpen(idx) != MV_OK)
  27733. + return;
  27734. +
  27735. + if(iter == 0)
  27736. + iter = CESA_DEF_ITER_NUM;
  27737. +
  27738. + if(checkMode == CESA_SHOW_CHECK_MODE)
  27739. + {
  27740. + iter = 1;
  27741. + }
  27742. + else
  27743. + checkMode = CESA_FULL_CHECK_MODE;
  27744. +
  27745. + cesaTestCases[0].plainHexStr = inputData;
  27746. + cesaTestCases[0].pCryptoIV = NULL;
  27747. +
  27748. + switch(idx)
  27749. + {
  27750. + case 302:
  27751. + pMultiTest = mdMultiSizeTest302;
  27752. + if(inputData == NULL)
  27753. + cesaTestCases[0].plainHexStr = cesaDataHexStr3;
  27754. + break;
  27755. +
  27756. + case 304:
  27757. + pMultiTest = mdMultiSizeTest304;
  27758. + if(inputData == NULL)
  27759. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27760. + break;
  27761. +
  27762. + case 305:
  27763. + pMultiTest = mdMultiSizeTest305;
  27764. + if(inputData == NULL)
  27765. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27766. + break;
  27767. +
  27768. + case 402:
  27769. + pMultiTest = shaMultiSizeTest402;
  27770. + if(inputData == NULL)
  27771. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27772. + break;
  27773. +
  27774. + case 404:
  27775. + pMultiTest = shaMultiSizeTest404;
  27776. + if(inputData == NULL)
  27777. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27778. + break;
  27779. +
  27780. + case 405:
  27781. + pMultiTest = shaMultiSizeTest405;
  27782. + if(inputData == NULL)
  27783. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27784. + break;
  27785. +
  27786. + case 502:
  27787. + pMultiTest = tripleDesMdMultiSizeTest502;
  27788. + if(inputData == NULL)
  27789. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27790. + break;
  27791. +
  27792. + case 503:
  27793. + pMultiTest = tripleDesShaMultiSizeTest503;
  27794. + if(inputData == NULL)
  27795. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27796. + break;
  27797. +
  27798. + case 504:
  27799. + iter = 1;
  27800. + pMultiTest = cbc3desMdMultiSizeTest504;
  27801. + cesaTestCases[0].pCryptoIV = iv1;
  27802. + if(inputData == NULL)
  27803. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27804. + break;
  27805. +
  27806. + case 505:
  27807. + iter = 1;
  27808. + pMultiTest = cbc3desShaMultiSizeTest505;
  27809. + cesaTestCases[0].pCryptoIV = iv1;
  27810. + if(inputData == NULL)
  27811. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27812. + break;
  27813. +
  27814. + case 506:
  27815. + iter = 1;
  27816. + pMultiTest = cbcAes128md5multiSizeTest506;
  27817. + cesaTestCases[0].pCryptoIV = iv5;
  27818. + if(inputData == NULL)
  27819. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27820. + break;
  27821. +
  27822. + case 507:
  27823. + iter = 1;
  27824. + pMultiTest = cbcAes128sha1multiSizeTest507;
  27825. + cesaTestCases[0].pCryptoIV = iv5;
  27826. + if(inputData == NULL)
  27827. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27828. + break;
  27829. +
  27830. + default:
  27831. + iter = 1;
  27832. + checkMode = CESA_SHOW_CHECK_MODE;
  27833. + pMultiTest = mdMultiSizeTest302;
  27834. + if(inputData == NULL)
  27835. + cesaTestCases[0].plainHexStr = hashHexStr80;
  27836. + }
  27837. + i = 0;
  27838. + while(pMultiTest[i].outputHexStr != NULL)
  27839. + {
  27840. + cesaTestCases[0].cipherHexStr = (char *)pMultiTest[i].outputHexStr;
  27841. + status = testRun(idx, 0, iter, pMultiTest[i].size,
  27842. + checkMode);
  27843. + if(checkMode != CESA_SHOW_CHECK_MODE)
  27844. + {
  27845. + cesaReqSize = pMultiTest[i].size;
  27846. + printTestResults(idx, status, checkMode);
  27847. + }
  27848. + if(status != MV_OK)
  27849. + break;
  27850. + i++;
  27851. + }
  27852. + testClose(idx);
  27853. +/*
  27854. + mvCesaDebugStatus();
  27855. + cesaTestPrintStatus();
  27856. +*/
  27857. +}
  27858. +
  27859. +void open_session_test(int idx, int caseIdx, int iter)
  27860. +{
  27861. + int reqIdError, cryptoError, openErrors, i;
  27862. + int openErrDisp[100];
  27863. + MV_STATUS status;
  27864. +
  27865. + memset(openErrDisp, 0, sizeof(openErrDisp));
  27866. + openErrors = 0;
  27867. + reqIdError = 0;
  27868. + cryptoError = 0;
  27869. + for(i=0; i<iter; i++)
  27870. + {
  27871. + status = testOpen(idx);
  27872. + if(status != MV_OK)
  27873. + {
  27874. + openErrors++;
  27875. + openErrDisp[status]++;
  27876. + }
  27877. + else
  27878. + {
  27879. + testRun(idx, caseIdx, 1, 0, CESA_FAST_CHECK_MODE);
  27880. + if(cesaCryptoError > 0)
  27881. + cryptoError++;
  27882. + if(cesaReqIdError > 0)
  27883. + reqIdError++;
  27884. +
  27885. + testClose(idx);
  27886. + }
  27887. + }
  27888. + if(cryptoError > 0)
  27889. + mvOsPrintf("cryptoError : %d\n", cryptoError);
  27890. + if(reqIdError > 0)
  27891. + mvOsPrintf("reqIdError : %d\n", reqIdError);
  27892. +
  27893. + if(openErrors > 0)
  27894. + {
  27895. + mvOsPrintf("Open Errors = %d\n", openErrors);
  27896. + for(i=0; i<100; i++)
  27897. + {
  27898. + if(openErrDisp[i] != 0)
  27899. + mvOsPrintf("Error %d - occurs %d times\n", i, openErrDisp[i]);
  27900. + }
  27901. + }
  27902. +}
  27903. +
  27904. +
  27905. +void loopback_test(int idx, int iter, int size, char* pPlainData)
  27906. +{
  27907. +}
  27908. +
  27909. +
  27910. +#if defined(MV_VXWORKS)
  27911. +int testMode = 0;
  27912. +unsigned __TASKCONV cesaTask(void* args)
  27913. +{
  27914. + int reqSize = cesaReqSize;
  27915. +
  27916. + if(testMode == 0)
  27917. + {
  27918. + cesaOneTest(cesaTestIdx, cesaCaseIdx, cesaIteration,
  27919. + reqSize, cesaCheckMode);
  27920. + }
  27921. + else
  27922. + {
  27923. + if(testMode == 1)
  27924. + {
  27925. + cesaTest(cesaIteration, reqSize, cesaCheckMode);
  27926. + combiTest(cesaIteration, reqSize, cesaCheckMode);
  27927. + }
  27928. + else
  27929. + {
  27930. + multiSizeTest(cesaIdx, cesaIteration, cesaCheckMode, NULL);
  27931. + }
  27932. + }
  27933. + return 0;
  27934. +}
  27935. +
  27936. +void oneTest(int testIdx, int caseIdx,
  27937. + int iter, int reqSize, int checkMode)
  27938. +{
  27939. + long rc;
  27940. +
  27941. + cesaIteration = iter;
  27942. + cesaReqSize = cesaRateSize = reqSize;
  27943. + cesaCheckMode = checkMode;
  27944. + testMode = 0;
  27945. + cesaTestIdx = testIdx;
  27946. + cesaCaseIdx = caseIdx;
  27947. + rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);
  27948. + if (rc != MV_OK)
  27949. + {
  27950. + mvOsPrintf("hMW: Can't create CESA multiCmd test task, rc = %ld\n", rc);
  27951. + }
  27952. +}
  27953. +
  27954. +void multiTest(int iter, int reqSize, int checkMode)
  27955. +{
  27956. + long rc;
  27957. +
  27958. + cesaIteration = iter;
  27959. + cesaCheckMode = checkMode;
  27960. + cesaReqSize = reqSize;
  27961. + testMode = 1;
  27962. + rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);
  27963. + if (rc != MV_OK)
  27964. + {
  27965. + mvOsPrintf("hMW: Can't create CESA multiCmd test task, rc = %ld\n", rc);
  27966. + }
  27967. +}
  27968. +
  27969. +void sizeTest(int testIdx, int iter, int checkMode)
  27970. +{
  27971. + long rc;
  27972. +
  27973. + cesaIteration = iter;
  27974. + cesaCheckMode = checkMode;
  27975. + testMode = 2;
  27976. + cesaIdx = testIdx;
  27977. + rc = mvOsTaskCreate("CESA_T", 100, 4*1024, cesaTask, NULL, &cesaTaskId);
  27978. + if (rc != MV_OK)
  27979. + {
  27980. + mvOsPrintf("hMW: Can't create CESA test task, rc = %ld\n", rc);
  27981. + }
  27982. +}
  27983. +
  27984. +#endif /* MV_VXWORKS */
  27985. +
  27986. +extern void mvCesaDebugSA(short sid, int mode);
  27987. +void cesaTestPrintSession(int idx)
  27988. +{
  27989. + int testIdx;
  27990. + MV_CESA_TEST_SESSION* pTestSession;
  27991. +
  27992. + pTestSession = getTestSessionDb(idx, &testIdx);
  27993. + if(pTestSession == NULL)
  27994. + {
  27995. + mvOsPrintf("Test %d is not exist\n", idx);
  27996. + return;
  27997. + }
  27998. + pTestSession = &pTestSession[testIdx];
  27999. +
  28000. + if(pTestSession->sid == -1)
  28001. + {
  28002. + mvOsPrintf("Test session %d is not opened\n", idx);
  28003. + return;
  28004. + }
  28005. +
  28006. + mvCesaDebugSA(pTestSession->sid, 1);
  28007. +}
  28008. +
  28009. +void cesaTestPrintStatus(void)
  28010. +{
  28011. + mvOsPrintf("\n\t Cesa Test Status\n\n");
  28012. +
  28013. + mvOsPrintf("isrCount=%d\n",
  28014. + cesaTestIsrCount);
  28015. +
  28016. +#ifdef CESA_TEST_DEBUG
  28017. + {
  28018. + int i, j;
  28019. + j = cesaTestTraceIdx;
  28020. + mvOsPrintf("No Type Cause rCause iCause Res Time pReady pProc pEmpty\n");
  28021. + for(i=0; i<MV_CESA_TEST_TRACE_SIZE; i++)
  28022. + {
  28023. + mvOsPrintf("%02d. %d 0x%04x 0x%04x 0x%04x 0x%02x 0x%02x %02d 0x%06x %p %p %p\n",
  28024. + j, cesaTestTrace[j].type, cesaTestTrace[j].cause, cesaTestTrace[j].realCause,
  28025. + cesaTestTrace[j].dmaCause, cesaTestTrace[j].resources, cesaTestTrace[j].timeStamp,
  28026. + cesaTestTrace[j].pReqReady, cesaTestTrace[j].pReqProcess, cesaTestTrace[j].pReqEmpty);
  28027. + j++;
  28028. + if(j == MV_CESA_TEST_TRACE_SIZE)
  28029. + j = 0;
  28030. + }
  28031. + }
  28032. +#endif /* CESA_TEST_DEBUG */
  28033. +}
  28034. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvLru.c linux-2.6.39/crypto/ocf/kirkwood/cesa/mvLru.c
  28035. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvLru.c 1970-01-01 01:00:00.000000000 +0100
  28036. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvLru.c 2011-08-01 14:38:18.000000000 +0200
  28037. @@ -0,0 +1,158 @@
  28038. +/*******************************************************************************
  28039. +Copyright (C) Marvell International Ltd. and its affiliates
  28040. +
  28041. +This software file (the "File") is owned and distributed by Marvell
  28042. +International Ltd. and/or its affiliates ("Marvell") under the following
  28043. +alternative licensing terms. Once you have made an election to distribute the
  28044. +File under one of the following license alternatives, please (i) delete this
  28045. +introductory statement regarding license alternatives, (ii) delete the two
  28046. +license alternatives that you have not elected to use and (iii) preserve the
  28047. +Marvell copyright notice above.
  28048. +
  28049. +********************************************************************************
  28050. +Marvell Commercial License Option
  28051. +
  28052. +If you received this File from Marvell and you have entered into a commercial
  28053. +license agreement (a "Commercial License") with Marvell, the File is licensed
  28054. +to you under the terms of the applicable Commercial License.
  28055. +
  28056. +********************************************************************************
  28057. +Marvell GPL License Option
  28058. +
  28059. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28060. +modify this File in accordance with the terms and conditions of the General
  28061. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  28062. +available along with the File in the license.txt file or by writing to the Free
  28063. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  28064. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  28065. +
  28066. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  28067. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  28068. +DISCLAIMED. The GPL License provides additional details about this warranty
  28069. +disclaimer.
  28070. +********************************************************************************
  28071. +Marvell BSD License Option
  28072. +
  28073. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28074. +modify this File under the following licensing terms.
  28075. +Redistribution and use in source and binary forms, with or without modification,
  28076. +are permitted provided that the following conditions are met:
  28077. +
  28078. + * Redistributions of source code must retain the above copyright notice,
  28079. + this list of conditions and the following disclaimer.
  28080. +
  28081. + * Redistributions in binary form must reproduce the above copyright
  28082. + notice, this list of conditions and the following disclaimer in the
  28083. + documentation and/or other materials provided with the distribution.
  28084. +
  28085. + * Neither the name of Marvell nor the names of its contributors may be
  28086. + used to endorse or promote products derived from this software without
  28087. + specific prior written permission.
  28088. +
  28089. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  28090. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  28091. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  28092. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  28093. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28094. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28095. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  28096. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28097. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28098. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28099. +
  28100. +*******************************************************************************/
  28101. +
  28102. +#include "mvOs.h"
  28103. +#include "mvLru.h"
  28104. +/* LRU Cache support */
  28105. +
  28106. +
  28107. +/* Init LRU cache database */
  28108. +MV_LRU_CACHE* mvLruCacheInit(int numOfEntries)
  28109. +{
  28110. + int i;
  28111. + MV_LRU_CACHE* pLruCache;
  28112. +
  28113. + pLruCache = mvOsMalloc(sizeof(MV_LRU_CACHE));
  28114. + if(pLruCache == NULL)
  28115. + {
  28116. + return NULL;
  28117. + }
  28118. + memset(pLruCache, 0, sizeof(MV_LRU_CACHE));
  28119. +
  28120. + pLruCache->table = mvOsMalloc(numOfEntries*sizeof(MV_LRU_ENTRY));
  28121. + if(pLruCache->table == NULL)
  28122. + {
  28123. + mvOsFree(pLruCache);
  28124. + return NULL;
  28125. + }
  28126. + memset(pLruCache->table, 0, numOfEntries*sizeof(MV_LRU_ENTRY));
  28127. + pLruCache->tableSize = numOfEntries;
  28128. +
  28129. + for(i=0; i<numOfEntries; i++)
  28130. + {
  28131. + pLruCache->table[i].next = i+1;
  28132. + pLruCache->table[i].prev = i-1;
  28133. + }
  28134. + pLruCache->least = 0;
  28135. + pLruCache->most = numOfEntries-1;
  28136. +
  28137. + return pLruCache;
  28138. +}
  28139. +
  28140. +void mvLruCacheFinish(MV_LRU_CACHE* pLruCache)
  28141. +{
  28142. + mvOsFree(pLruCache->table);
  28143. + mvOsFree(pLruCache);
  28144. +}
  28145. +
  28146. +/* Update LRU cache database after using cache Index */
  28147. +void mvLruCacheIdxUpdate(MV_LRU_CACHE* pLruHndl, int cacheIdx)
  28148. +{
  28149. + int prev, next;
  28150. +
  28151. + if(cacheIdx == pLruHndl->most)
  28152. + return;
  28153. +
  28154. + next = pLruHndl->table[cacheIdx].next;
  28155. + if(cacheIdx == pLruHndl->least)
  28156. + {
  28157. + pLruHndl->least = next;
  28158. + }
  28159. + else
  28160. + {
  28161. + prev = pLruHndl->table[cacheIdx].prev;
  28162. +
  28163. + pLruHndl->table[next].prev = prev;
  28164. + pLruHndl->table[prev].next = next;
  28165. + }
  28166. +
  28167. + pLruHndl->table[pLruHndl->most].next = cacheIdx;
  28168. + pLruHndl->table[cacheIdx].prev = pLruHndl->most;
  28169. + pLruHndl->most = cacheIdx;
  28170. +}
  28171. +
  28172. +/* Delete LRU cache entry */
  28173. +void mvLruCacheIdxDelete(MV_LRU_CACHE* pLruHndl, int cacheIdx)
  28174. +{
  28175. + int prev, next;
  28176. +
  28177. + if(cacheIdx == pLruHndl->least)
  28178. + return;
  28179. +
  28180. + prev = pLruHndl->table[cacheIdx].prev;
  28181. + if(cacheIdx == pLruHndl->most)
  28182. + {
  28183. + pLruHndl->most = prev;
  28184. + }
  28185. + else
  28186. + {
  28187. + next = pLruHndl->table[cacheIdx].next;
  28188. +
  28189. + pLruHndl->table[next].prev = prev;
  28190. + pLruHndl->table[prev].next = next;
  28191. + }
  28192. + pLruHndl->table[pLruHndl->least].prev = cacheIdx;
  28193. + pLruHndl->table[cacheIdx].next = pLruHndl->least;
  28194. + pLruHndl->least = cacheIdx;
  28195. +}
  28196. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvLru.h linux-2.6.39/crypto/ocf/kirkwood/cesa/mvLru.h
  28197. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvLru.h 1970-01-01 01:00:00.000000000 +0100
  28198. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvLru.h 2011-08-01 14:38:18.000000000 +0200
  28199. @@ -0,0 +1,112 @@
  28200. +/*******************************************************************************
  28201. +Copyright (C) Marvell International Ltd. and its affiliates
  28202. +
  28203. +This software file (the "File") is owned and distributed by Marvell
  28204. +International Ltd. and/or its affiliates ("Marvell") under the following
  28205. +alternative licensing terms. Once you have made an election to distribute the
  28206. +File under one of the following license alternatives, please (i) delete this
  28207. +introductory statement regarding license alternatives, (ii) delete the two
  28208. +license alternatives that you have not elected to use and (iii) preserve the
  28209. +Marvell copyright notice above.
  28210. +
  28211. +********************************************************************************
  28212. +Marvell Commercial License Option
  28213. +
  28214. +If you received this File from Marvell and you have entered into a commercial
  28215. +license agreement (a "Commercial License") with Marvell, the File is licensed
  28216. +to you under the terms of the applicable Commercial License.
  28217. +
  28218. +********************************************************************************
  28219. +Marvell GPL License Option
  28220. +
  28221. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28222. +modify this File in accordance with the terms and conditions of the General
  28223. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  28224. +available along with the File in the license.txt file or by writing to the Free
  28225. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  28226. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  28227. +
  28228. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  28229. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  28230. +DISCLAIMED. The GPL License provides additional details about this warranty
  28231. +disclaimer.
  28232. +********************************************************************************
  28233. +Marvell BSD License Option
  28234. +
  28235. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28236. +modify this File under the following licensing terms.
  28237. +Redistribution and use in source and binary forms, with or without modification,
  28238. +are permitted provided that the following conditions are met:
  28239. +
  28240. + * Redistributions of source code must retain the above copyright notice,
  28241. + this list of conditions and the following disclaimer.
  28242. +
  28243. + * Redistributions in binary form must reproduce the above copyright
  28244. + notice, this list of conditions and the following disclaimer in the
  28245. + documentation and/or other materials provided with the distribution.
  28246. +
  28247. + * Neither the name of Marvell nor the names of its contributors may be
  28248. + used to endorse or promote products derived from this software without
  28249. + specific prior written permission.
  28250. +
  28251. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  28252. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  28253. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  28254. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  28255. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28256. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28257. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  28258. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28259. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28260. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28261. +
  28262. +*******************************************************************************/
  28263. +/*******************************************************************************
  28264. +* mvLru.h - Header File for Least Recently Used Cache algorithm
  28265. +*
  28266. +* DESCRIPTION:
  28267. +* This header file contains macros typedefs and function declaration for
  28268. +* the Least Recently Used Cache algorithm.
  28269. +*
  28270. +*******************************************************************************/
  28271. +
  28272. +#ifndef __mvLru_h__
  28273. +#define __mvLru_h__
  28274. +
  28275. +
  28276. +typedef struct
  28277. +{
  28278. + int next;
  28279. + int prev;
  28280. +} MV_LRU_ENTRY;
  28281. +
  28282. +typedef struct
  28283. +{
  28284. + int least;
  28285. + int most;
  28286. + MV_LRU_ENTRY* table;
  28287. + int tableSize;
  28288. +
  28289. +}MV_LRU_CACHE;
  28290. +
  28291. +
  28292. +/* Find Cache index for replacement LRU */
  28293. +static INLINE int mvLruCacheIdxFind(MV_LRU_CACHE* pLruHndl)
  28294. +{
  28295. + return pLruHndl->least;
  28296. +}
  28297. +
  28298. +/* Init LRU cache module */
  28299. +MV_LRU_CACHE* mvLruCacheInit(int numOfEntries);
  28300. +
  28301. +/* Finish LRU cache module */
  28302. +void mvLruCacheFinish(MV_LRU_CACHE* pLruHndl);
  28303. +
  28304. +/* Update LRU cache database after using cache Index */
  28305. +void mvLruCacheIdxUpdate(MV_LRU_CACHE* pLruHndl, int cacheIdx);
  28306. +
  28307. +/* Delete LRU cache entry */
  28308. +void mvLruCacheIdxDelete(MV_LRU_CACHE* pLruHndl, int cacheIdx);
  28309. +
  28310. +
  28311. +#endif /* __mvLru_h__ */
  28312. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvMD5.c linux-2.6.39/crypto/ocf/kirkwood/cesa/mvMD5.c
  28313. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvMD5.c 1970-01-01 01:00:00.000000000 +0100
  28314. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvMD5.c 2011-08-01 14:38:18.000000000 +0200
  28315. @@ -0,0 +1,349 @@
  28316. +/*******************************************************************************
  28317. +Copyright (C) Marvell International Ltd. and its affiliates
  28318. +
  28319. +This software file (the "File") is owned and distributed by Marvell
  28320. +International Ltd. and/or its affiliates ("Marvell") under the following
  28321. +alternative licensing terms. Once you have made an election to distribute the
  28322. +File under one of the following license alternatives, please (i) delete this
  28323. +introductory statement regarding license alternatives, (ii) delete the two
  28324. +license alternatives that you have not elected to use and (iii) preserve the
  28325. +Marvell copyright notice above.
  28326. +
  28327. +********************************************************************************
  28328. +Marvell Commercial License Option
  28329. +
  28330. +If you received this File from Marvell and you have entered into a commercial
  28331. +license agreement (a "Commercial License") with Marvell, the File is licensed
  28332. +to you under the terms of the applicable Commercial License.
  28333. +
  28334. +********************************************************************************
  28335. +Marvell GPL License Option
  28336. +
  28337. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28338. +modify this File in accordance with the terms and conditions of the General
  28339. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  28340. +available along with the File in the license.txt file or by writing to the Free
  28341. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  28342. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  28343. +
  28344. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  28345. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  28346. +DISCLAIMED. The GPL License provides additional details about this warranty
  28347. +disclaimer.
  28348. +********************************************************************************
  28349. +Marvell BSD License Option
  28350. +
  28351. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28352. +modify this File under the following licensing terms.
  28353. +Redistribution and use in source and binary forms, with or without modification,
  28354. +are permitted provided that the following conditions are met:
  28355. +
  28356. + * Redistributions of source code must retain the above copyright notice,
  28357. + this list of conditions and the following disclaimer.
  28358. +
  28359. + * Redistributions in binary form must reproduce the above copyright
  28360. + notice, this list of conditions and the following disclaimer in the
  28361. + documentation and/or other materials provided with the distribution.
  28362. +
  28363. + * Neither the name of Marvell nor the names of its contributors may be
  28364. + used to endorse or promote products derived from this software without
  28365. + specific prior written permission.
  28366. +
  28367. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  28368. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  28369. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  28370. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  28371. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28372. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28373. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  28374. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28375. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28376. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28377. +
  28378. +*******************************************************************************/
  28379. +
  28380. +#include "mvOs.h"
  28381. +#include "mvMD5.h"
  28382. +
  28383. +static void mvMD5Transform(MV_U32 buf[4], MV_U32 const in[MV_MD5_MAC_LEN]);
  28384. +
  28385. +#ifdef MV_CPU_LE
  28386. +#define mvByteReverse(buf, len) /* Nothing */
  28387. +#else
  28388. +static void mvByteReverse(unsigned char *buf, unsigned longs);
  28389. +
  28390. +/*
  28391. + * Note: this code is harmless on little-endian machines.
  28392. + */
  28393. +static void mvByteReverse(unsigned char *buf, unsigned longs)
  28394. +{
  28395. + MV_U32 t;
  28396. +
  28397. + do
  28398. + {
  28399. + t = (MV_U32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
  28400. + ((unsigned) buf[1] << 8 | buf[0]);
  28401. + *(MV_U32 *) buf = t;
  28402. + buf += 4;
  28403. + } while (--longs);
  28404. +}
  28405. +#endif
  28406. +
  28407. +/*
  28408. + * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
  28409. + * initialization constants.
  28410. + */
  28411. +void mvMD5Init(MV_MD5_CONTEXT *ctx)
  28412. +{
  28413. + ctx->buf[0] = 0x67452301;
  28414. + ctx->buf[1] = 0xefcdab89;
  28415. + ctx->buf[2] = 0x98badcfe;
  28416. + ctx->buf[3] = 0x10325476;
  28417. +
  28418. + ctx->bits[0] = 0;
  28419. + ctx->bits[1] = 0;
  28420. +}
  28421. +
  28422. +/*
  28423. + * Update context to reflect the concatenation of another buffer full
  28424. + * of bytes.
  28425. + */
  28426. +void mvMD5Update(MV_MD5_CONTEXT *ctx, unsigned char const *buf, unsigned len)
  28427. +{
  28428. + MV_U32 t;
  28429. +
  28430. + /* Update bitcount */
  28431. +
  28432. + t = ctx->bits[0];
  28433. + if ((ctx->bits[0] = t + ((MV_U32) len << 3)) < t)
  28434. + ctx->bits[1]++; /* Carry from low to high */
  28435. + ctx->bits[1] += len >> 29;
  28436. +
  28437. + t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
  28438. +
  28439. + /* Handle any leading odd-sized chunks */
  28440. +
  28441. + if (t)
  28442. + {
  28443. + unsigned char *p = (unsigned char *) ctx->in + t;
  28444. +
  28445. + t = 64 - t;
  28446. + if (len < t)
  28447. + {
  28448. + memcpy(p, buf, len);
  28449. + return;
  28450. + }
  28451. + memcpy(p, buf, t);
  28452. + mvByteReverse(ctx->in, MV_MD5_MAC_LEN);
  28453. + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
  28454. + buf += t;
  28455. + len -= t;
  28456. + }
  28457. + /* Process data in 64-byte chunks */
  28458. +
  28459. + while (len >= 64)
  28460. + {
  28461. + memcpy(ctx->in, buf, 64);
  28462. + mvByteReverse(ctx->in, MV_MD5_MAC_LEN);
  28463. + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
  28464. + buf += 64;
  28465. + len -= 64;
  28466. + }
  28467. +
  28468. + /* Handle any remaining bytes of data. */
  28469. +
  28470. + memcpy(ctx->in, buf, len);
  28471. +}
  28472. +
  28473. +/*
  28474. + * Final wrapup - pad to 64-byte boundary with the bit pattern
  28475. + * 1 0* (64-bit count of bits processed, MSB-first)
  28476. + */
  28477. +void mvMD5Final(unsigned char digest[MV_MD5_MAC_LEN], MV_MD5_CONTEXT *ctx)
  28478. +{
  28479. + unsigned count;
  28480. + unsigned char *p;
  28481. +
  28482. + /* Compute number of bytes mod 64 */
  28483. + count = (ctx->bits[0] >> 3) & 0x3F;
  28484. +
  28485. + /* Set the first char of padding to 0x80. This is safe since there is
  28486. + always at least one byte free */
  28487. + p = ctx->in + count;
  28488. + *p++ = 0x80;
  28489. +
  28490. + /* Bytes of padding needed to make 64 bytes */
  28491. + count = 64 - 1 - count;
  28492. +
  28493. + /* Pad out to 56 mod 64 */
  28494. + if (count < 8)
  28495. + {
  28496. + /* Two lots of padding: Pad the first block to 64 bytes */
  28497. + memset(p, 0, count);
  28498. + mvByteReverse(ctx->in, MV_MD5_MAC_LEN);
  28499. + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
  28500. +
  28501. + /* Now fill the next block with 56 bytes */
  28502. + memset(ctx->in, 0, 56);
  28503. + }
  28504. + else
  28505. + {
  28506. + /* Pad block to 56 bytes */
  28507. + memset(p, 0, count - 8);
  28508. + }
  28509. + mvByteReverse(ctx->in, 14);
  28510. +
  28511. + /* Append length in bits and transform */
  28512. + ((MV_U32 *) ctx->in)[14] = ctx->bits[0];
  28513. + ((MV_U32 *) ctx->in)[15] = ctx->bits[1];
  28514. +
  28515. + mvMD5Transform(ctx->buf, (MV_U32 *) ctx->in);
  28516. + mvByteReverse((unsigned char *) ctx->buf, 4);
  28517. + memcpy(digest, ctx->buf, MV_MD5_MAC_LEN);
  28518. + memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
  28519. +}
  28520. +
  28521. +/* The four core functions - F1 is optimized somewhat */
  28522. +
  28523. +/* #define F1(x, y, z) (x & y | ~x & z) */
  28524. +#define F1(x, y, z) (z ^ (x & (y ^ z)))
  28525. +#define F2(x, y, z) F1(z, x, y)
  28526. +#define F3(x, y, z) (x ^ y ^ z)
  28527. +#define F4(x, y, z) (y ^ (x | ~z))
  28528. +
  28529. +/* This is the central step in the MD5 algorithm. */
  28530. +#define MD5STEP(f, w, x, y, z, data, s) \
  28531. + ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
  28532. +
  28533. +/*
  28534. + * The core of the MD5 algorithm, this alters an existing MD5 hash to
  28535. + * reflect the addition of 16 longwords of new data. MD5Update blocks
  28536. + * the data and converts bytes into longwords for this routine.
  28537. + */
  28538. +static void mvMD5Transform(MV_U32 buf[4], MV_U32 const in[MV_MD5_MAC_LEN])
  28539. +{
  28540. + register MV_U32 a, b, c, d;
  28541. +
  28542. + a = buf[0];
  28543. + b = buf[1];
  28544. + c = buf[2];
  28545. + d = buf[3];
  28546. +
  28547. + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
  28548. + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
  28549. + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
  28550. + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
  28551. + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
  28552. + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
  28553. + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
  28554. + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
  28555. + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
  28556. + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
  28557. + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
  28558. + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
  28559. + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
  28560. + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
  28561. + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
  28562. + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
  28563. +
  28564. + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
  28565. + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
  28566. + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
  28567. + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
  28568. + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
  28569. + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
  28570. + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
  28571. + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
  28572. + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
  28573. + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
  28574. + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
  28575. + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
  28576. + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
  28577. + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
  28578. + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
  28579. + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
  28580. +
  28581. + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
  28582. + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
  28583. + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
  28584. + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
  28585. + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
  28586. + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
  28587. + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
  28588. + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
  28589. + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
  28590. + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
  28591. + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
  28592. + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
  28593. + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
  28594. + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
  28595. + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
  28596. + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
  28597. +
  28598. + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
  28599. + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
  28600. + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
  28601. + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
  28602. + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
  28603. + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
  28604. + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
  28605. + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
  28606. + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
  28607. + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
  28608. + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
  28609. + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
  28610. + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
  28611. + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
  28612. + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
  28613. + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
  28614. +
  28615. + buf[0] += a;
  28616. + buf[1] += b;
  28617. + buf[2] += c;
  28618. + buf[3] += d;
  28619. +}
  28620. +
  28621. +void mvMD5(unsigned char const *buf, unsigned len, unsigned char* digest)
  28622. +{
  28623. + MV_MD5_CONTEXT ctx;
  28624. +
  28625. + mvMD5Init(&ctx);
  28626. + mvMD5Update(&ctx, buf, len);
  28627. + mvMD5Final(digest, &ctx);
  28628. +}
  28629. +
  28630. +
  28631. +void mvHmacMd5(unsigned char const* text, int text_len,
  28632. + unsigned char const* key, int key_len,
  28633. + unsigned char* digest)
  28634. +{
  28635. + int i;
  28636. + MV_MD5_CONTEXT ctx;
  28637. + unsigned char k_ipad[64+1]; /* inner padding - key XORd with ipad */
  28638. + unsigned char k_opad[64+1]; /* outer padding - key XORd with opad */
  28639. +
  28640. + /* start out by storing key in pads */
  28641. + memset(k_ipad, 0, 64);
  28642. + memcpy(k_ipad, key, key_len);
  28643. + memset(k_opad, 0, 64);
  28644. + memcpy(k_opad, key, key_len);
  28645. +
  28646. + /* XOR key with ipad and opad values */
  28647. + for (i=0; i<64; i++)
  28648. + {
  28649. + k_ipad[i] ^= 0x36;
  28650. + k_opad[i] ^= 0x5c;
  28651. + }
  28652. +
  28653. + /* perform inner MD5 */
  28654. + mvMD5Init(&ctx); /* init ctx for 1st pass */
  28655. + mvMD5Update(&ctx, k_ipad, 64); /* start with inner pad */
  28656. + mvMD5Update(&ctx, text, text_len); /* then text of datagram */
  28657. + mvMD5Final(digest, &ctx); /* finish up 1st pass */
  28658. +
  28659. + /* perform outer MD5 */
  28660. + mvMD5Init(&ctx); /* init ctx for 2nd pass */
  28661. + mvMD5Update(&ctx, k_opad, 64); /* start with outer pad */
  28662. + mvMD5Update(&ctx, digest, 16); /* then results of 1st hash */
  28663. + mvMD5Final(digest, &ctx); /* finish up 2nd pass */
  28664. +}
  28665. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvMD5.h linux-2.6.39/crypto/ocf/kirkwood/cesa/mvMD5.h
  28666. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvMD5.h 1970-01-01 01:00:00.000000000 +0100
  28667. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvMD5.h 2011-08-01 14:38:18.000000000 +0200
  28668. @@ -0,0 +1,93 @@
  28669. +/*******************************************************************************
  28670. +Copyright (C) Marvell International Ltd. and its affiliates
  28671. +
  28672. +This software file (the "File") is owned and distributed by Marvell
  28673. +International Ltd. and/or its affiliates ("Marvell") under the following
  28674. +alternative licensing terms. Once you have made an election to distribute the
  28675. +File under one of the following license alternatives, please (i) delete this
  28676. +introductory statement regarding license alternatives, (ii) delete the two
  28677. +license alternatives that you have not elected to use and (iii) preserve the
  28678. +Marvell copyright notice above.
  28679. +
  28680. +********************************************************************************
  28681. +Marvell Commercial License Option
  28682. +
  28683. +If you received this File from Marvell and you have entered into a commercial
  28684. +license agreement (a "Commercial License") with Marvell, the File is licensed
  28685. +to you under the terms of the applicable Commercial License.
  28686. +
  28687. +********************************************************************************
  28688. +Marvell GPL License Option
  28689. +
  28690. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28691. +modify this File in accordance with the terms and conditions of the General
  28692. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  28693. +available along with the File in the license.txt file or by writing to the Free
  28694. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  28695. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  28696. +
  28697. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  28698. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  28699. +DISCLAIMED. The GPL License provides additional details about this warranty
  28700. +disclaimer.
  28701. +********************************************************************************
  28702. +Marvell BSD License Option
  28703. +
  28704. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28705. +modify this File under the following licensing terms.
  28706. +Redistribution and use in source and binary forms, with or without modification,
  28707. +are permitted provided that the following conditions are met:
  28708. +
  28709. + * Redistributions of source code must retain the above copyright notice,
  28710. + this list of conditions and the following disclaimer.
  28711. +
  28712. + * Redistributions in binary form must reproduce the above copyright
  28713. + notice, this list of conditions and the following disclaimer in the
  28714. + documentation and/or other materials provided with the distribution.
  28715. +
  28716. + * Neither the name of Marvell nor the names of its contributors may be
  28717. + used to endorse or promote products derived from this software without
  28718. + specific prior written permission.
  28719. +
  28720. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  28721. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  28722. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  28723. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  28724. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28725. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28726. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  28727. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28728. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28729. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28730. +
  28731. +*******************************************************************************/
  28732. +
  28733. +#ifndef __mvMD5_h__
  28734. +#define __mvMD5_h__
  28735. +
  28736. +#include "mvMD5.h"
  28737. +
  28738. +#define MV_MD5_MAC_LEN 16
  28739. +
  28740. +
  28741. +typedef struct
  28742. +{
  28743. + MV_U32 buf[4];
  28744. + MV_U32 bits[2];
  28745. + MV_U8 in[64];
  28746. +
  28747. +} MV_MD5_CONTEXT;
  28748. +
  28749. +void mvMD5Init(MV_MD5_CONTEXT *context);
  28750. +void mvMD5Update(MV_MD5_CONTEXT *context, unsigned char const *buf,
  28751. + unsigned len);
  28752. +void mvMD5Final(unsigned char digest[16], MV_MD5_CONTEXT *context);
  28753. +
  28754. +void mvMD5(unsigned char const *buf, unsigned len, unsigned char* digest);
  28755. +
  28756. +void mvHmacMd5(unsigned char const* text, int text_len,
  28757. + unsigned char const* key, int key_len,
  28758. + unsigned char* digest);
  28759. +
  28760. +
  28761. +#endif /* __mvMD5_h__ */
  28762. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvSHA1.c linux-2.6.39/crypto/ocf/kirkwood/cesa/mvSHA1.c
  28763. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvSHA1.c 1970-01-01 01:00:00.000000000 +0100
  28764. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvSHA1.c 2011-08-01 14:38:18.000000000 +0200
  28765. @@ -0,0 +1,239 @@
  28766. +/*******************************************************************************
  28767. +Copyright (C) Marvell International Ltd. and its affiliates
  28768. +
  28769. +This software file (the "File") is owned and distributed by Marvell
  28770. +International Ltd. and/or its affiliates ("Marvell") under the following
  28771. +alternative licensing terms. Once you have made an election to distribute the
  28772. +File under one of the following license alternatives, please (i) delete this
  28773. +introductory statement regarding license alternatives, (ii) delete the two
  28774. +license alternatives that you have not elected to use and (iii) preserve the
  28775. +Marvell copyright notice above.
  28776. +
  28777. +********************************************************************************
  28778. +Marvell Commercial License Option
  28779. +
  28780. +If you received this File from Marvell and you have entered into a commercial
  28781. +license agreement (a "Commercial License") with Marvell, the File is licensed
  28782. +to you under the terms of the applicable Commercial License.
  28783. +
  28784. +********************************************************************************
  28785. +Marvell GPL License Option
  28786. +
  28787. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28788. +modify this File in accordance with the terms and conditions of the General
  28789. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  28790. +available along with the File in the license.txt file or by writing to the Free
  28791. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  28792. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  28793. +
  28794. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  28795. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  28796. +DISCLAIMED. The GPL License provides additional details about this warranty
  28797. +disclaimer.
  28798. +********************************************************************************
  28799. +Marvell BSD License Option
  28800. +
  28801. +If you received this File from Marvell, you may opt to use, redistribute and/or
  28802. +modify this File under the following licensing terms.
  28803. +Redistribution and use in source and binary forms, with or without modification,
  28804. +are permitted provided that the following conditions are met:
  28805. +
  28806. + * Redistributions of source code must retain the above copyright notice,
  28807. + this list of conditions and the following disclaimer.
  28808. +
  28809. + * Redistributions in binary form must reproduce the above copyright
  28810. + notice, this list of conditions and the following disclaimer in the
  28811. + documentation and/or other materials provided with the distribution.
  28812. +
  28813. + * Neither the name of Marvell nor the names of its contributors may be
  28814. + used to endorse or promote products derived from this software without
  28815. + specific prior written permission.
  28816. +
  28817. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  28818. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  28819. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  28820. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  28821. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  28822. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  28823. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  28824. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28825. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  28826. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28827. +
  28828. +*******************************************************************************/
  28829. +
  28830. +#include "mvOs.h"
  28831. +#include "mvSHA1.h"
  28832. +
  28833. +#define SHA1HANDSOFF
  28834. +
  28835. +typedef union
  28836. +{
  28837. + MV_U8 c[64];
  28838. + MV_U32 l[16];
  28839. +
  28840. +} CHAR64LONG16;
  28841. +
  28842. +static void mvSHA1Transform(MV_U32 state[5], const MV_U8 *buffer);
  28843. +
  28844. +#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
  28845. +
  28846. +
  28847. +#ifdef MV_CPU_LE
  28848. +#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
  28849. + (rol(block->l[i], 8) & 0x00FF00FF))
  28850. +#else
  28851. +#define blk0(i) block->l[i]
  28852. +#endif
  28853. +#define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
  28854. + block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
  28855. +
  28856. +/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
  28857. +#define R0(v,w,x,y,z,i) \
  28858. + z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
  28859. + w = rol(w, 30);
  28860. +#define R1(v,w,x,y,z,i) \
  28861. + z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
  28862. + w = rol(w, 30);
  28863. +#define R2(v,w,x,y,z,i) \
  28864. + z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
  28865. +#define R3(v,w,x,y,z,i) \
  28866. + z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
  28867. + w = rol(w, 30);
  28868. +#define R4(v,w,x,y,z,i) \
  28869. + z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
  28870. + w=rol(w, 30);
  28871. +
  28872. +/* Hash a single 512-bit block. This is the core of the algorithm. */
  28873. +static void mvSHA1Transform(MV_U32 state[5], const MV_U8 *buffer)
  28874. +{
  28875. + MV_U32 a, b, c, d, e;
  28876. + CHAR64LONG16* block;
  28877. +
  28878. +#ifdef SHA1HANDSOFF
  28879. + static MV_U32 workspace[16];
  28880. +
  28881. + block = (CHAR64LONG16 *) workspace;
  28882. + memcpy(block, buffer, 64);
  28883. +#else
  28884. + block = (CHAR64LONG16 *) buffer;
  28885. +#endif
  28886. + /* Copy context->state[] to working vars */
  28887. + a = state[0];
  28888. + b = state[1];
  28889. + c = state[2];
  28890. + d = state[3];
  28891. + e = state[4];
  28892. + /* 4 rounds of 20 operations each. Loop unrolled. */
  28893. + 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);
  28894. + 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);
  28895. + 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);
  28896. + 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);
  28897. + 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);
  28898. + 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);
  28899. + 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);
  28900. + 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);
  28901. + 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);
  28902. + 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);
  28903. + 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);
  28904. + 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);
  28905. + 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);
  28906. + 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);
  28907. + 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);
  28908. + 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);
  28909. + 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);
  28910. + 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);
  28911. + 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);
  28912. + 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);
  28913. + /* Add the working vars back into context.state[] */
  28914. + state[0] += a;
  28915. + state[1] += b;
  28916. + state[2] += c;
  28917. + state[3] += d;
  28918. + state[4] += e;
  28919. + /* Wipe variables */
  28920. + a = b = c = d = e = 0;
  28921. +}
  28922. +
  28923. +void mvSHA1Init(MV_SHA1_CTX* context)
  28924. +{
  28925. + /* SHA1 initialization constants */
  28926. + context->state[0] = 0x67452301;
  28927. + context->state[1] = 0xEFCDAB89;
  28928. + context->state[2] = 0x98BADCFE;
  28929. + context->state[3] = 0x10325476;
  28930. + context->state[4] = 0xC3D2E1F0;
  28931. + context->count[0] = context->count[1] = 0;
  28932. +}
  28933. +
  28934. +
  28935. +/* Run your data through this. */
  28936. +void mvSHA1Update(MV_SHA1_CTX *context, MV_U8 const *data,
  28937. + unsigned int len)
  28938. +{
  28939. + MV_U32 i, j;
  28940. +
  28941. + j = (context->count[0] >> 3) & 63;
  28942. + if ((context->count[0] += len << 3) < (len << 3))
  28943. + context->count[1]++;
  28944. + context->count[1] += (len >> 29);
  28945. + if ((j + len) > 63)
  28946. + {
  28947. + memcpy(&context->buffer[j], data, (i = 64-j));
  28948. + mvSHA1Transform(context->state, context->buffer);
  28949. + for ( ; i + 63 < len; i += 64)
  28950. + {
  28951. + mvSHA1Transform(context->state, &data[i]);
  28952. + }
  28953. + j = 0;
  28954. + }
  28955. + else
  28956. + {
  28957. + i = 0;
  28958. + }
  28959. + memcpy(&context->buffer[j], &data[i], len - i);
  28960. +}
  28961. +
  28962. +void mvSHA1Final(MV_U8* digest, MV_SHA1_CTX* context)
  28963. +{
  28964. + MV_U32 i;
  28965. + MV_U8 finalcount[8];
  28966. +
  28967. + for (i = 0; i < 8; i++)
  28968. + {
  28969. + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] >>
  28970. + ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
  28971. + }
  28972. + mvSHA1Update(context, (const unsigned char *) "\200", 1);
  28973. + while ((context->count[0] & 504) != 448)
  28974. + {
  28975. + mvSHA1Update(context, (const unsigned char *) "\0", 1);
  28976. + }
  28977. + mvSHA1Update(context, finalcount, 8); /* Should cause a mvSHA1Transform()
  28978. + */
  28979. + for (i = 0; i < 20; i++)
  28980. + {
  28981. + digest[i] = (unsigned char)
  28982. + ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255);
  28983. + }
  28984. + /* Wipe variables */
  28985. + i = 0;
  28986. + memset(context->buffer, 0, 64);
  28987. + memset(context->state, 0, 20);
  28988. + memset(context->count, 0, 8);
  28989. + memset(finalcount, 0, 8);
  28990. +
  28991. +#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */
  28992. + mvSHA1Transform(context->state, context->buffer);
  28993. +#endif
  28994. +}
  28995. +
  28996. +
  28997. +void mvSHA1(MV_U8 const *buf, unsigned int len, MV_U8* digest)
  28998. +{
  28999. + MV_SHA1_CTX ctx;
  29000. +
  29001. + mvSHA1Init(&ctx);
  29002. + mvSHA1Update(&ctx, buf, len);
  29003. + mvSHA1Final(digest, &ctx);
  29004. +}
  29005. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvSHA1.h linux-2.6.39/crypto/ocf/kirkwood/cesa/mvSHA1.h
  29006. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa/mvSHA1.h 1970-01-01 01:00:00.000000000 +0100
  29007. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa/mvSHA1.h 2011-08-01 14:38:18.000000000 +0200
  29008. @@ -0,0 +1,88 @@
  29009. +/*******************************************************************************
  29010. +Copyright (C) Marvell International Ltd. and its affiliates
  29011. +
  29012. +This software file (the "File") is owned and distributed by Marvell
  29013. +International Ltd. and/or its affiliates ("Marvell") under the following
  29014. +alternative licensing terms. Once you have made an election to distribute the
  29015. +File under one of the following license alternatives, please (i) delete this
  29016. +introductory statement regarding license alternatives, (ii) delete the two
  29017. +license alternatives that you have not elected to use and (iii) preserve the
  29018. +Marvell copyright notice above.
  29019. +
  29020. +********************************************************************************
  29021. +Marvell Commercial License Option
  29022. +
  29023. +If you received this File from Marvell and you have entered into a commercial
  29024. +license agreement (a "Commercial License") with Marvell, the File is licensed
  29025. +to you under the terms of the applicable Commercial License.
  29026. +
  29027. +********************************************************************************
  29028. +Marvell GPL License Option
  29029. +
  29030. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29031. +modify this File in accordance with the terms and conditions of the General
  29032. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  29033. +available along with the File in the license.txt file or by writing to the Free
  29034. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  29035. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  29036. +
  29037. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  29038. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  29039. +DISCLAIMED. The GPL License provides additional details about this warranty
  29040. +disclaimer.
  29041. +********************************************************************************
  29042. +Marvell BSD License Option
  29043. +
  29044. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29045. +modify this File under the following licensing terms.
  29046. +Redistribution and use in source and binary forms, with or without modification,
  29047. +are permitted provided that the following conditions are met:
  29048. +
  29049. + * Redistributions of source code must retain the above copyright notice,
  29050. + this list of conditions and the following disclaimer.
  29051. +
  29052. + * Redistributions in binary form must reproduce the above copyright
  29053. + notice, this list of conditions and the following disclaimer in the
  29054. + documentation and/or other materials provided with the distribution.
  29055. +
  29056. + * Neither the name of Marvell nor the names of its contributors may be
  29057. + used to endorse or promote products derived from this software without
  29058. + specific prior written permission.
  29059. +
  29060. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  29061. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  29062. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  29063. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  29064. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  29065. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  29066. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  29067. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29068. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  29069. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29070. +
  29071. +*******************************************************************************/
  29072. +
  29073. +#ifndef __mvSHA1_h__
  29074. +#define __mvSHA1_h__
  29075. +
  29076. +#include "mvSHA1.h"
  29077. +
  29078. +#define MV_SHA1_MAC_LEN 20
  29079. +
  29080. +
  29081. +typedef struct
  29082. +{
  29083. + MV_U32 state[5];
  29084. + MV_U32 count[2];
  29085. + MV_U8 buffer[64];
  29086. +
  29087. +} MV_SHA1_CTX;
  29088. +
  29089. +void mvSHA1Init(MV_SHA1_CTX *context);
  29090. +void mvSHA1Update(MV_SHA1_CTX *context, MV_U8 const *buf, unsigned int len);
  29091. +void mvSHA1Final(MV_U8* digest, MV_SHA1_CTX *context);
  29092. +
  29093. +void mvSHA1(MV_U8 const *buf, unsigned int len, MV_U8* digest);
  29094. +
  29095. +
  29096. +#endif /* __mvSHA1_h__ */
  29097. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/cesa_ocf_drv.c linux-2.6.39/crypto/ocf/kirkwood/cesa_ocf_drv.c
  29098. --- linux-2.6.39.orig/crypto/ocf/kirkwood/cesa_ocf_drv.c 1970-01-01 01:00:00.000000000 +0100
  29099. +++ linux-2.6.39/crypto/ocf/kirkwood/cesa_ocf_drv.c 2011-08-01 14:38:19.000000000 +0200
  29100. @@ -0,0 +1,1296 @@
  29101. +/*******************************************************************************
  29102. +Copyright (C) Marvell International Ltd. and its affiliates
  29103. +
  29104. +This software file (the "File") is owned and distributed by Marvell
  29105. +International Ltd. and/or its affiliates ("Marvell") under the following
  29106. +alternative licensing terms. Once you have made an election to distribute the
  29107. +File under one of the following license alternatives, please (i) delete this
  29108. +introductory statement regarding license alternatives, (ii) delete the two
  29109. +license alternatives that you have not elected to use and (iii) preserve the
  29110. +Marvell copyright notice above.
  29111. +
  29112. +
  29113. +********************************************************************************
  29114. +Marvell GPL License Option
  29115. +
  29116. +If you received this File from Marvell, you may opt to use, redistribute and/or
  29117. +modify this File in accordance with the terms and conditions of the General
  29118. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  29119. +available along with the File in the license.txt file or by writing to the Free
  29120. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  29121. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  29122. +
  29123. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  29124. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  29125. +DISCLAIMED. The GPL License provides additional details about this warranty
  29126. +disclaimer.
  29127. +*******************************************************************************/
  29128. +
  29129. +#ifndef AUTOCONF_INCLUDED
  29130. +#include <linux/config.h>
  29131. +#endif
  29132. +#include <linux/module.h>
  29133. +#include <linux/init.h>
  29134. +#include <linux/list.h>
  29135. +#include <linux/slab.h>
  29136. +#include <linux/sched.h>
  29137. +#include <linux/wait.h>
  29138. +#include <linux/crypto.h>
  29139. +#include <linux/mm.h>
  29140. +#include <linux/skbuff.h>
  29141. +#include <linux/random.h>
  29142. +#include <linux/platform_device.h>
  29143. +#include <asm/scatterlist.h>
  29144. +#include <linux/spinlock.h>
  29145. +#include "ctrlEnv/sys/mvSysCesa.h"
  29146. +#include "cesa/mvCesa.h" /* moved here before cryptodev.h due to include dependencies */
  29147. +#include <cryptodev.h>
  29148. +#include <uio.h>
  29149. +#include <plat/mv_cesa.h>
  29150. +#include <linux/mbus.h>
  29151. +#include "mvDebug.h"
  29152. +
  29153. +#include "cesa/mvMD5.h"
  29154. +#include "cesa/mvSHA1.h"
  29155. +
  29156. +#include "cesa/mvCesaRegs.h"
  29157. +#include "cesa/AES/mvAes.h"
  29158. +#include "cesa/mvLru.h"
  29159. +
  29160. +#undef RT_DEBUG
  29161. +#ifdef RT_DEBUG
  29162. +static int debug = 1;
  29163. +module_param(debug, int, 1);
  29164. +MODULE_PARM_DESC(debug, "Enable debug");
  29165. +#undef dprintk
  29166. +#define dprintk(a...) if (debug) { printk(a); } else
  29167. +#else
  29168. +static int debug = 0;
  29169. +#undef dprintk
  29170. +#define dprintk(a...)
  29171. +#endif
  29172. +
  29173. +
  29174. +/* TDMA Regs */
  29175. +#define WINDOW_BASE(i) 0xA00 + (i << 3)
  29176. +#define WINDOW_CTRL(i) 0xA04 + (i << 3)
  29177. +
  29178. +/* interrupt handling */
  29179. +#undef CESA_OCF_POLLING
  29180. +#undef CESA_OCF_TASKLET
  29181. +
  29182. +#if defined(CESA_OCF_POLLING) && defined(CESA_OCF_TASKLET)
  29183. +#error "don't use both tasklet and polling mode"
  29184. +#endif
  29185. +
  29186. +extern int cesaReqResources;
  29187. +/* support for spliting action into 2 actions */
  29188. +#define CESA_OCF_SPLIT
  29189. +
  29190. +/* general defines */
  29191. +#define CESA_OCF_MAX_SES 128
  29192. +#define CESA_Q_SIZE 64
  29193. +
  29194. +
  29195. +/* data structures */
  29196. +struct cesa_ocf_data {
  29197. + int cipher_alg;
  29198. + int auth_alg;
  29199. + int encrypt_tn_auth;
  29200. +#define auth_tn_decrypt encrypt_tn_auth
  29201. + int ivlen;
  29202. + int digestlen;
  29203. + short sid_encrypt;
  29204. + short sid_decrypt;
  29205. + /* fragment workaround sessions */
  29206. + short frag_wa_encrypt;
  29207. + short frag_wa_decrypt;
  29208. + short frag_wa_auth;
  29209. +};
  29210. +
  29211. +/* CESA device data */
  29212. +struct cesa_dev {
  29213. + void __iomem *sram;
  29214. + void __iomem *reg;
  29215. + struct mv_cesa_platform_data *plat_data;
  29216. + int irq;
  29217. +};
  29218. +
  29219. +#define DIGEST_BUF_SIZE 32
  29220. +struct cesa_ocf_process {
  29221. + MV_CESA_COMMAND cesa_cmd;
  29222. + MV_CESA_MBUF cesa_mbuf;
  29223. + MV_BUF_INFO cesa_bufs[MV_CESA_MAX_MBUF_FRAGS];
  29224. + char digest[DIGEST_BUF_SIZE];
  29225. + int digest_len;
  29226. + struct cryptop *crp;
  29227. + int need_cb;
  29228. +};
  29229. +
  29230. +/* global variables */
  29231. +static int32_t cesa_ocf_id = -1;
  29232. +static struct cesa_ocf_data *cesa_ocf_sessions[CESA_OCF_MAX_SES];
  29233. +static spinlock_t cesa_lock;
  29234. +static struct cesa_dev cesa_device;
  29235. +
  29236. +/* static APIs */
  29237. +static int cesa_ocf_process (device_t, struct cryptop *, int);
  29238. +static int cesa_ocf_newsession (device_t, u_int32_t *, struct cryptoini *);
  29239. +static int cesa_ocf_freesession (device_t, u_int64_t);
  29240. +static void cesa_callback (unsigned long);
  29241. +static irqreturn_t cesa_interrupt_handler (int, void *);
  29242. +#ifdef CESA_OCF_POLLING
  29243. +static void cesa_interrupt_polling(void);
  29244. +#endif
  29245. +#ifdef CESA_OCF_TASKLET
  29246. +static struct tasklet_struct cesa_ocf_tasklet;
  29247. +#endif
  29248. +
  29249. +static struct timeval tt_start;
  29250. +static struct timeval tt_end;
  29251. +
  29252. +/*
  29253. + * dummy device structure
  29254. + */
  29255. +
  29256. +static struct {
  29257. + softc_device_decl sc_dev;
  29258. +} mv_cesa_dev;
  29259. +
  29260. +static device_method_t mv_cesa_methods = {
  29261. + /* crypto device methods */
  29262. + DEVMETHOD(cryptodev_newsession, cesa_ocf_newsession),
  29263. + DEVMETHOD(cryptodev_freesession,cesa_ocf_freesession),
  29264. + DEVMETHOD(cryptodev_process, cesa_ocf_process),
  29265. + DEVMETHOD(cryptodev_kprocess, NULL),
  29266. +};
  29267. +
  29268. +
  29269. +
  29270. +/* Add debug Trace */
  29271. +#undef CESA_OCF_TRACE_DEBUG
  29272. +#ifdef CESA_OCF_TRACE_DEBUG
  29273. +
  29274. +#define MV_CESA_USE_TIMER_ID 0
  29275. +
  29276. +typedef struct
  29277. +{
  29278. + int type; /* 0 - isrEmpty, 1 - cesaReadyGet, 2 - cesaAction */
  29279. + MV_U32 timeStamp;
  29280. + MV_U32 cause;
  29281. + MV_U32 realCause;
  29282. + MV_U32 dmaCause;
  29283. + int resources;
  29284. + MV_CESA_REQ* pReqReady;
  29285. + MV_CESA_REQ* pReqEmpty;
  29286. + MV_CESA_REQ* pReqProcess;
  29287. +} MV_CESA_TEST_TRACE;
  29288. +
  29289. +#define MV_CESA_TEST_TRACE_SIZE 50
  29290. +
  29291. +static int cesaTestTraceIdx = 0;
  29292. +static MV_CESA_TEST_TRACE cesaTestTrace[MV_CESA_TEST_TRACE_SIZE];
  29293. +
  29294. +static void cesaTestTraceAdd(int type)
  29295. +{
  29296. + cesaTestTrace[cesaTestTraceIdx].type = type;
  29297. + cesaTestTrace[cesaTestTraceIdx].realCause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  29298. + //cesaTestTrace[cesaTestTraceIdx].idmaCause = MV_REG_READ(IDMA_CAUSE_REG);
  29299. + cesaTestTrace[cesaTestTraceIdx].resources = cesaReqResources;
  29300. + cesaTestTrace[cesaTestTraceIdx].pReqReady = pCesaReqReady;
  29301. + cesaTestTrace[cesaTestTraceIdx].pReqEmpty = pCesaReqEmpty;
  29302. + cesaTestTrace[cesaTestTraceIdx].pReqProcess = pCesaReqProcess;
  29303. + cesaTestTrace[cesaTestTraceIdx].timeStamp = mvCntmrRead(MV_CESA_USE_TIMER_ID);
  29304. + cesaTestTraceIdx++;
  29305. + if(cesaTestTraceIdx == MV_CESA_TEST_TRACE_SIZE)
  29306. + cesaTestTraceIdx = 0;
  29307. +}
  29308. +
  29309. +#else /* CESA_OCF_TRACE_DEBUG */
  29310. +
  29311. +#define cesaTestTraceAdd(x)
  29312. +
  29313. +#endif /* CESA_OCF_TRACE_DEBUG */
  29314. +
  29315. +unsigned int
  29316. +get_usec(unsigned int start)
  29317. +{
  29318. + if(start) {
  29319. + do_gettimeofday (&tt_start);
  29320. + return 0;
  29321. + }
  29322. + else {
  29323. + do_gettimeofday (&tt_end);
  29324. + tt_end.tv_sec -= tt_start.tv_sec;
  29325. + tt_end.tv_usec -= tt_start.tv_usec;
  29326. + if (tt_end.tv_usec < 0) {
  29327. + tt_end.tv_usec += 1000 * 1000;
  29328. + tt_end.tv_sec -= 1;
  29329. + }
  29330. + }
  29331. + printk("time taken is %d\n", (unsigned int)(tt_end.tv_usec + tt_end.tv_sec * 1000000));
  29332. + return (tt_end.tv_usec + tt_end.tv_sec * 1000000);
  29333. +}
  29334. +
  29335. +#ifdef RT_DEBUG
  29336. +/*
  29337. + * check that the crp action match the current session
  29338. + */
  29339. +static int
  29340. +ocf_check_action(struct cryptop *crp, struct cesa_ocf_data *cesa_ocf_cur_ses) {
  29341. + int count = 0;
  29342. + int encrypt = 0, decrypt = 0, auth = 0;
  29343. + struct cryptodesc *crd;
  29344. +
  29345. + /* Go through crypto descriptors, processing as we go */
  29346. + for (crd = crp->crp_desc; crd; crd = crd->crd_next, count++) {
  29347. + if(count > 2) {
  29348. + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
  29349. + return 1;
  29350. + }
  29351. +
  29352. + /* Encryption /Decryption */
  29353. + if(crd->crd_alg == cesa_ocf_cur_ses->cipher_alg) {
  29354. + /* check that the action is compatible with session */
  29355. + if(encrypt || decrypt) {
  29356. + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
  29357. + return 1;
  29358. + }
  29359. +
  29360. + if(crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  29361. + if( (count == 2) && (cesa_ocf_cur_ses->encrypt_tn_auth) ) {
  29362. + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
  29363. + return 1;
  29364. + }
  29365. + encrypt++;
  29366. + }
  29367. + else { /* decrypt */
  29368. + if( (count == 2) && !(cesa_ocf_cur_ses->auth_tn_decrypt) ) {
  29369. + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
  29370. + return 1;
  29371. + }
  29372. + decrypt++;
  29373. + }
  29374. +
  29375. + }
  29376. + /* Authentication */
  29377. + else if(crd->crd_alg == cesa_ocf_cur_ses->auth_alg) {
  29378. + /* check that the action is compatible with session */
  29379. + if(auth) {
  29380. + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
  29381. + return 1;
  29382. + }
  29383. + if( (count == 2) && (decrypt) && (cesa_ocf_cur_ses->auth_tn_decrypt)) {
  29384. + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
  29385. + return 1;
  29386. + }
  29387. + if( (count == 2) && (encrypt) && !(cesa_ocf_cur_ses->encrypt_tn_auth)) {
  29388. + printk("%s,%d: sequence isn't supported by this session.\n", __FILE__, __LINE__);
  29389. + return 1;
  29390. + }
  29391. + auth++;
  29392. + }
  29393. + else {
  29394. + printk("%s,%d: Alg isn't supported by this session.\n", __FILE__, __LINE__);
  29395. + return 1;
  29396. + }
  29397. + }
  29398. + return 0;
  29399. +
  29400. +}
  29401. +#endif
  29402. +
  29403. +/*
  29404. + * Process a request.
  29405. + */
  29406. +static int
  29407. +cesa_ocf_process(device_t dev, struct cryptop *crp, int hint)
  29408. +{
  29409. + struct cesa_ocf_process *cesa_ocf_cmd = NULL;
  29410. + struct cesa_ocf_process *cesa_ocf_cmd_wa = NULL;
  29411. + MV_CESA_COMMAND *cesa_cmd;
  29412. + struct cryptodesc *crd;
  29413. + struct cesa_ocf_data *cesa_ocf_cur_ses;
  29414. + int sid = 0, temp_len = 0, i;
  29415. + int encrypt = 0, decrypt = 0, auth = 0;
  29416. + int status;
  29417. + struct sk_buff *skb = NULL;
  29418. + struct uio *uiop = NULL;
  29419. + unsigned char *ivp;
  29420. + MV_BUF_INFO *p_buf_info;
  29421. + MV_CESA_MBUF *p_mbuf_info;
  29422. + unsigned long flags;
  29423. +
  29424. + dprintk("%s()\n", __FUNCTION__);
  29425. +
  29426. + if( cesaReqResources <= 1 ) {
  29427. + dprintk("%s,%d: ERESTART\n", __FILE__, __LINE__);
  29428. + return ERESTART;
  29429. + }
  29430. +
  29431. +#ifdef RT_DEBUG
  29432. + /* Sanity check */
  29433. + if (crp == NULL) {
  29434. + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  29435. + return EINVAL;
  29436. + }
  29437. +
  29438. + if (crp->crp_desc == NULL || crp->crp_buf == NULL ) {
  29439. + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  29440. + crp->crp_etype = EINVAL;
  29441. + return EINVAL;
  29442. + }
  29443. +
  29444. + sid = crp->crp_sid & 0xffffffff;
  29445. + if ((sid >= CESA_OCF_MAX_SES) || (cesa_ocf_sessions[sid] == NULL)) {
  29446. + crp->crp_etype = ENOENT;
  29447. + printk("%s,%d: ENOENT session %d \n", __FILE__, __LINE__, sid);
  29448. + return EINVAL;
  29449. + }
  29450. +#endif
  29451. +
  29452. + sid = crp->crp_sid & 0xffffffff;
  29453. + crp->crp_etype = 0;
  29454. + cesa_ocf_cur_ses = cesa_ocf_sessions[sid];
  29455. +
  29456. +#ifdef RT_DEBUG
  29457. + if(ocf_check_action(crp, cesa_ocf_cur_ses)){
  29458. + goto p_error;
  29459. + }
  29460. +#endif
  29461. +
  29462. + /* malloc a new cesa process */
  29463. + cesa_ocf_cmd = kmalloc(sizeof(struct cesa_ocf_process), GFP_ATOMIC);
  29464. +
  29465. + if (cesa_ocf_cmd == NULL) {
  29466. + printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
  29467. + goto p_error;
  29468. + }
  29469. + memset(cesa_ocf_cmd, 0, sizeof(struct cesa_ocf_process));
  29470. +
  29471. + /* init cesa_process */
  29472. + cesa_ocf_cmd->crp = crp;
  29473. + /* always call callback */
  29474. + cesa_ocf_cmd->need_cb = 1;
  29475. +
  29476. + /* init cesa_cmd for usage of the HALs */
  29477. + cesa_cmd = &cesa_ocf_cmd->cesa_cmd;
  29478. + cesa_cmd->pReqPrv = (void *)cesa_ocf_cmd;
  29479. + cesa_cmd->sessionId = cesa_ocf_cur_ses->sid_encrypt; /* defualt use encrypt */
  29480. +
  29481. + /* prepare src buffer */
  29482. + /* we send the entire buffer to the HAL, even if only part of it should be encrypt/auth. */
  29483. + /* if not using seesions for both encrypt and auth, then it will be wiser to to copy only */
  29484. + /* from skip to crd_len. */
  29485. + p_buf_info = cesa_ocf_cmd->cesa_bufs;
  29486. + p_mbuf_info = &cesa_ocf_cmd->cesa_mbuf;
  29487. +
  29488. + p_buf_info += 2; /* save 2 first buffers for IV and digest -
  29489. + we won't append them to the end since, they
  29490. + might be places in an unaligned addresses. */
  29491. +
  29492. + p_mbuf_info->pFrags = p_buf_info;
  29493. + temp_len = 0;
  29494. +
  29495. + /* handle SKB */
  29496. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  29497. +
  29498. + dprintk("%s,%d: handle SKB.\n", __FILE__, __LINE__);
  29499. + skb = (struct sk_buff *) crp->crp_buf;
  29500. +
  29501. + if (skb_shinfo(skb)->nr_frags >= (MV_CESA_MAX_MBUF_FRAGS - 1)) {
  29502. + printk("%s,%d: %d nr_frags > MV_CESA_MAX_MBUF_FRAGS", __FILE__, __LINE__, skb_shinfo(skb)->nr_frags);
  29503. + goto p_error;
  29504. + }
  29505. +
  29506. + p_mbuf_info->mbufSize = skb->len;
  29507. + temp_len = skb->len;
  29508. + /* first skb fragment */
  29509. + p_buf_info->bufSize = skb_headlen(skb);
  29510. + p_buf_info->bufVirtPtr = skb->data;
  29511. + p_buf_info++;
  29512. +
  29513. + /* now handle all other skb fragments */
  29514. + for ( i = 0; i < skb_shinfo(skb)->nr_frags; i++ ) {
  29515. + skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
  29516. + p_buf_info->bufSize = frag->size;
  29517. + p_buf_info->bufVirtPtr = page_address(frag->page) + frag->page_offset;
  29518. + p_buf_info++;
  29519. + }
  29520. + p_mbuf_info->numFrags = skb_shinfo(skb)->nr_frags + 1;
  29521. + }
  29522. + /* handle UIO */
  29523. + else if(crp->crp_flags & CRYPTO_F_IOV) {
  29524. +
  29525. + dprintk("%s,%d: handle UIO.\n", __FILE__, __LINE__);
  29526. + uiop = (struct uio *) crp->crp_buf;
  29527. +
  29528. + if (uiop->uio_iovcnt > (MV_CESA_MAX_MBUF_FRAGS - 1)) {
  29529. + printk("%s,%d: %d uio_iovcnt > MV_CESA_MAX_MBUF_FRAGS \n", __FILE__, __LINE__, uiop->uio_iovcnt);
  29530. + goto p_error;
  29531. + }
  29532. +
  29533. + p_mbuf_info->mbufSize = crp->crp_ilen;
  29534. + p_mbuf_info->numFrags = uiop->uio_iovcnt;
  29535. + for(i = 0; i < uiop->uio_iovcnt; i++) {
  29536. + p_buf_info->bufVirtPtr = uiop->uio_iov[i].iov_base;
  29537. + p_buf_info->bufSize = uiop->uio_iov[i].iov_len;
  29538. + temp_len += p_buf_info->bufSize;
  29539. + dprintk("%s,%d: buf %x-> addr %x, size %x \n"
  29540. + , __FILE__, __LINE__, i, (unsigned int)p_buf_info->bufVirtPtr, p_buf_info->bufSize);
  29541. + p_buf_info++;
  29542. + }
  29543. +
  29544. + }
  29545. + /* handle CONTIG */
  29546. + else {
  29547. + dprintk("%s,%d: handle CONTIG.\n", __FILE__, __LINE__);
  29548. + p_mbuf_info->numFrags = 1;
  29549. + p_mbuf_info->mbufSize = crp->crp_ilen;
  29550. + p_buf_info->bufVirtPtr = crp->crp_buf;
  29551. + p_buf_info->bufSize = crp->crp_ilen;
  29552. + temp_len = crp->crp_ilen;
  29553. + p_buf_info++;
  29554. + }
  29555. +
  29556. + /* Support up to 64K why? cause! */
  29557. + if(crp->crp_ilen > 64*1024) {
  29558. + printk("%s,%d: buf too big %x \n", __FILE__, __LINE__, crp->crp_ilen);
  29559. + goto p_error;
  29560. + }
  29561. +
  29562. + if( temp_len != crp->crp_ilen ) {
  29563. + printk("%s,%d: warning size don't match.(%x %x) \n", __FILE__, __LINE__, temp_len, crp->crp_ilen);
  29564. + }
  29565. +
  29566. + cesa_cmd->pSrc = p_mbuf_info;
  29567. + cesa_cmd->pDst = p_mbuf_info;
  29568. +
  29569. + /* restore p_buf_info to point to first available buf */
  29570. + p_buf_info = cesa_ocf_cmd->cesa_bufs;
  29571. + p_buf_info += 1;
  29572. +
  29573. +
  29574. + /* Go through crypto descriptors, processing as we go */
  29575. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  29576. +
  29577. + /* Encryption /Decryption */
  29578. + if(crd->crd_alg == cesa_ocf_cur_ses->cipher_alg) {
  29579. +
  29580. + dprintk("%s,%d: cipher", __FILE__, __LINE__);
  29581. +
  29582. + cesa_cmd->cryptoOffset = crd->crd_skip;
  29583. + cesa_cmd->cryptoLength = crd->crd_len;
  29584. +
  29585. + if(crd->crd_flags & CRD_F_ENCRYPT) { /* encrypt */
  29586. + dprintk(" encrypt \n");
  29587. + encrypt++;
  29588. +
  29589. + /* handle IV */
  29590. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) { /* IV from USER */
  29591. + dprintk("%s,%d: IV from USER (offset %x) \n", __FILE__, __LINE__, crd->crd_inject);
  29592. + cesa_cmd->ivFromUser = 1;
  29593. + ivp = crd->crd_iv;
  29594. +
  29595. + /*
  29596. + * do we have to copy the IV back to the buffer ?
  29597. + */
  29598. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  29599. + dprintk("%s,%d: copy the IV back to the buffer\n", __FILE__, __LINE__);
  29600. + cesa_cmd->ivOffset = crd->crd_inject;
  29601. + crypto_copy_bits_back(crp->crp_buf, crd->crd_inject, ivp, cesa_ocf_cur_ses->ivlen);
  29602. + }
  29603. + else {
  29604. + dprintk("%s,%d: don't copy the IV back to the buffer \n", __FILE__, __LINE__);
  29605. + p_mbuf_info->numFrags++;
  29606. + p_mbuf_info->mbufSize += cesa_ocf_cur_ses->ivlen;
  29607. + p_mbuf_info->pFrags = p_buf_info;
  29608. +
  29609. + p_buf_info->bufVirtPtr = ivp;
  29610. + p_buf_info->bufSize = cesa_ocf_cur_ses->ivlen;
  29611. + p_buf_info--;
  29612. +
  29613. + /* offsets */
  29614. + cesa_cmd->ivOffset = 0;
  29615. + cesa_cmd->cryptoOffset += cesa_ocf_cur_ses->ivlen;
  29616. + if(auth) {
  29617. + cesa_cmd->macOffset += cesa_ocf_cur_ses->ivlen;
  29618. + cesa_cmd->digestOffset += cesa_ocf_cur_ses->ivlen;
  29619. + }
  29620. + }
  29621. + }
  29622. + else { /* random IV */
  29623. + dprintk("%s,%d: random IV \n", __FILE__, __LINE__);
  29624. + cesa_cmd->ivFromUser = 0;
  29625. +
  29626. + /*
  29627. + * do we have to copy the IV back to the buffer ?
  29628. + */
  29629. + /* in this mode the HAL will always copy the IV */
  29630. + /* given by the session to the ivOffset */
  29631. + if ((crd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  29632. + cesa_cmd->ivOffset = crd->crd_inject;
  29633. + }
  29634. + else {
  29635. + /* if IV isn't copy, then how will the user know which IV did we use??? */
  29636. + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  29637. + goto p_error;
  29638. + }
  29639. + }
  29640. + }
  29641. + else { /* decrypt */
  29642. + dprintk(" decrypt \n");
  29643. + decrypt++;
  29644. + cesa_cmd->sessionId = cesa_ocf_cur_ses->sid_decrypt;
  29645. +
  29646. + /* handle IV */
  29647. + if (crd->crd_flags & CRD_F_IV_EXPLICIT) {
  29648. + dprintk("%s,%d: IV from USER \n", __FILE__, __LINE__);
  29649. + /* append the IV buf to the mbuf */
  29650. + cesa_cmd->ivFromUser = 1;
  29651. + p_mbuf_info->numFrags++;
  29652. + p_mbuf_info->mbufSize += cesa_ocf_cur_ses->ivlen;
  29653. + p_mbuf_info->pFrags = p_buf_info;
  29654. +
  29655. + p_buf_info->bufVirtPtr = crd->crd_iv;
  29656. + p_buf_info->bufSize = cesa_ocf_cur_ses->ivlen;
  29657. + p_buf_info--;
  29658. +
  29659. + /* offsets */
  29660. + cesa_cmd->ivOffset = 0;
  29661. + cesa_cmd->cryptoOffset += cesa_ocf_cur_ses->ivlen;
  29662. + if(auth) {
  29663. + cesa_cmd->macOffset += cesa_ocf_cur_ses->ivlen;
  29664. + cesa_cmd->digestOffset += cesa_ocf_cur_ses->ivlen;
  29665. + }
  29666. + }
  29667. + else {
  29668. + dprintk("%s,%d: IV inside the buffer \n", __FILE__, __LINE__);
  29669. + cesa_cmd->ivFromUser = 0;
  29670. + cesa_cmd->ivOffset = crd->crd_inject;
  29671. + }
  29672. + }
  29673. +
  29674. + }
  29675. + /* Authentication */
  29676. + else if(crd->crd_alg == cesa_ocf_cur_ses->auth_alg) {
  29677. + dprintk("%s,%d: Authentication \n", __FILE__, __LINE__);
  29678. + auth++;
  29679. + cesa_cmd->macOffset = crd->crd_skip;
  29680. + cesa_cmd->macLength = crd->crd_len;
  29681. +
  29682. + /* digest + mac */
  29683. + cesa_cmd->digestOffset = crd->crd_inject;
  29684. + }
  29685. + else {
  29686. + printk("%s,%d: Alg isn't supported by this session.\n", __FILE__, __LINE__);
  29687. + goto p_error;
  29688. + }
  29689. + }
  29690. +
  29691. + dprintk("\n");
  29692. + dprintk("%s,%d: Sending Action: \n", __FILE__, __LINE__);
  29693. + dprintk("%s,%d: IV from user: %d. IV offset %x \n", __FILE__, __LINE__, cesa_cmd->ivFromUser, cesa_cmd->ivOffset);
  29694. + dprintk("%s,%d: crypt offset %x len %x \n", __FILE__, __LINE__, cesa_cmd->cryptoOffset, cesa_cmd->cryptoLength);
  29695. + dprintk("%s,%d: Auth offset %x len %x \n", __FILE__, __LINE__, cesa_cmd->macOffset, cesa_cmd->macLength);
  29696. + dprintk("%s,%d: set digest in offset %x . \n", __FILE__, __LINE__, cesa_cmd->digestOffset);
  29697. + if(debug) {
  29698. + mvCesaDebugMbuf("SRC BUFFER", cesa_cmd->pSrc, 0, cesa_cmd->pSrc->mbufSize);
  29699. + }
  29700. +
  29701. +
  29702. + /* send action to HAL */
  29703. + spin_lock_irqsave(&cesa_lock, flags);
  29704. + status = mvCesaAction(cesa_cmd);
  29705. + spin_unlock_irqrestore(&cesa_lock, flags);
  29706. +
  29707. + /* action not allowed */
  29708. + if(status == MV_NOT_ALLOWED) {
  29709. +#ifdef CESA_OCF_SPLIT
  29710. + /* if both encrypt and auth try to split */
  29711. + if(auth && (encrypt || decrypt)) {
  29712. + MV_CESA_COMMAND *cesa_cmd_wa;
  29713. +
  29714. + /* malloc a new cesa process and init it */
  29715. + cesa_ocf_cmd_wa = kmalloc(sizeof(struct cesa_ocf_process), GFP_ATOMIC);
  29716. +
  29717. + if (cesa_ocf_cmd_wa == NULL) {
  29718. + printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
  29719. + goto p_error;
  29720. + }
  29721. + memcpy(cesa_ocf_cmd_wa, cesa_ocf_cmd, sizeof(struct cesa_ocf_process));
  29722. + cesa_cmd_wa = &cesa_ocf_cmd_wa->cesa_cmd;
  29723. + cesa_cmd_wa->pReqPrv = (void *)cesa_ocf_cmd_wa;
  29724. + cesa_ocf_cmd_wa->need_cb = 0;
  29725. +
  29726. + /* break requests to two operation, first operation completion won't call callback */
  29727. + if((decrypt) && (cesa_ocf_cur_ses->auth_tn_decrypt)) {
  29728. + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
  29729. + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_decrypt;
  29730. + }
  29731. + else if((decrypt) && !(cesa_ocf_cur_ses->auth_tn_decrypt)) {
  29732. + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_decrypt;
  29733. + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
  29734. + }
  29735. + else if((encrypt) && (cesa_ocf_cur_ses->encrypt_tn_auth)) {
  29736. + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_encrypt;
  29737. + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
  29738. + }
  29739. + else if((encrypt) && !(cesa_ocf_cur_ses->encrypt_tn_auth)){
  29740. + cesa_cmd_wa->sessionId = cesa_ocf_cur_ses->frag_wa_auth;
  29741. + cesa_cmd->sessionId = cesa_ocf_cur_ses->frag_wa_encrypt;
  29742. + }
  29743. + else {
  29744. + printk("%s,%d: Unsupporterd fragment wa mode \n", __FILE__, __LINE__);
  29745. + goto p_error;
  29746. + }
  29747. +
  29748. + /* send the 2 actions to the HAL */
  29749. + spin_lock_irqsave(&cesa_lock, flags);
  29750. + status = mvCesaAction(cesa_cmd_wa);
  29751. + spin_unlock_irqrestore(&cesa_lock, flags);
  29752. +
  29753. + if((status != MV_NO_MORE) && (status != MV_OK)) {
  29754. + printk("%s,%d: cesa action failed, status = 0x%x\n", __FILE__, __LINE__, status);
  29755. + goto p_error;
  29756. + }
  29757. + spin_lock_irqsave(&cesa_lock, flags);
  29758. + status = mvCesaAction(cesa_cmd);
  29759. + spin_unlock_irqrestore(&cesa_lock, flags);
  29760. +
  29761. + }
  29762. + /* action not allowed and can't split */
  29763. + else
  29764. +#endif
  29765. + {
  29766. + goto p_error;
  29767. + }
  29768. + }
  29769. +
  29770. + /* Hal Q is full, send again. This should never happen */
  29771. + if(status == MV_NO_RESOURCE) {
  29772. + printk("%s,%d: cesa no more resources \n", __FILE__, __LINE__);
  29773. + if(cesa_ocf_cmd)
  29774. + kfree(cesa_ocf_cmd);
  29775. + if(cesa_ocf_cmd_wa)
  29776. + kfree(cesa_ocf_cmd_wa);
  29777. + return ERESTART;
  29778. + }
  29779. + else if((status != MV_NO_MORE) && (status != MV_OK)) {
  29780. + printk("%s,%d: cesa action failed, status = 0x%x\n", __FILE__, __LINE__, status);
  29781. + goto p_error;
  29782. + }
  29783. +
  29784. +
  29785. +#ifdef CESA_OCF_POLLING
  29786. + cesa_interrupt_polling();
  29787. +#endif
  29788. + cesaTestTraceAdd(5);
  29789. +
  29790. + return 0;
  29791. +p_error:
  29792. + crp->crp_etype = EINVAL;
  29793. + if(cesa_ocf_cmd)
  29794. + kfree(cesa_ocf_cmd);
  29795. + if(cesa_ocf_cmd_wa)
  29796. + kfree(cesa_ocf_cmd_wa);
  29797. + return EINVAL;
  29798. +}
  29799. +
  29800. +/*
  29801. + * cesa callback.
  29802. + */
  29803. +static void
  29804. +cesa_callback(unsigned long dummy)
  29805. +{
  29806. + struct cesa_ocf_process *cesa_ocf_cmd = NULL;
  29807. + struct cryptop *crp = NULL;
  29808. + MV_CESA_RESULT result[MV_CESA_MAX_CHAN];
  29809. + int res_idx = 0,i;
  29810. + MV_STATUS status;
  29811. +
  29812. + dprintk("%s()\n", __FUNCTION__);
  29813. +
  29814. +#ifdef CESA_OCF_TASKLET
  29815. + disable_irq(cesa_device.irq);
  29816. +#endif
  29817. + while(MV_TRUE) {
  29818. +
  29819. + /* Get Ready requests */
  29820. + spin_lock(&cesa_lock);
  29821. + status = mvCesaReadyGet(&result[res_idx]);
  29822. + spin_unlock(&cesa_lock);
  29823. +
  29824. + cesaTestTraceAdd(2);
  29825. +
  29826. + if(status != MV_OK) {
  29827. +#ifdef CESA_OCF_POLLING
  29828. + if(status == MV_BUSY) { /* Fragment */
  29829. + cesa_interrupt_polling();
  29830. + return;
  29831. + }
  29832. +#endif
  29833. + break;
  29834. + }
  29835. + res_idx++;
  29836. + break;
  29837. + }
  29838. +
  29839. + for(i = 0; i < res_idx; i++) {
  29840. +
  29841. + if(!result[i].pReqPrv) {
  29842. + printk("%s,%d: warning private is NULL\n", __FILE__, __LINE__);
  29843. + break;
  29844. + }
  29845. +
  29846. + cesa_ocf_cmd = result[i].pReqPrv;
  29847. + crp = cesa_ocf_cmd->crp;
  29848. +
  29849. + // ignore HMAC error.
  29850. + //if(result->retCode)
  29851. + // crp->crp_etype = EIO;
  29852. +
  29853. +#if defined(CESA_OCF_POLLING)
  29854. + if(!cesa_ocf_cmd->need_cb){
  29855. + cesa_interrupt_polling();
  29856. + }
  29857. +#endif
  29858. + if(cesa_ocf_cmd->need_cb) {
  29859. + if(debug) {
  29860. + mvCesaDebugMbuf("DST BUFFER", cesa_ocf_cmd->cesa_cmd.pDst, 0, cesa_ocf_cmd->cesa_cmd.pDst->mbufSize);
  29861. + }
  29862. + crypto_done(crp);
  29863. + }
  29864. + kfree(cesa_ocf_cmd);
  29865. + }
  29866. +#ifdef CESA_OCF_TASKLET
  29867. + enable_irq(cesa_device.irq);
  29868. +#endif
  29869. +
  29870. + cesaTestTraceAdd(3);
  29871. +
  29872. + return;
  29873. +}
  29874. +
  29875. +#ifdef CESA_OCF_POLLING
  29876. +static void
  29877. +cesa_interrupt_polling(void)
  29878. +{
  29879. + u32 cause;
  29880. +
  29881. + dprintk("%s()\n", __FUNCTION__);
  29882. +
  29883. + /* Read cause register */
  29884. + do {
  29885. + cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  29886. + cause &= MV_CESA_CAUSE_ACC_DMA_ALL_MASK;
  29887. +
  29888. + } while (cause == 0);
  29889. +
  29890. + /* clear interrupts */
  29891. + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
  29892. +
  29893. + cesa_callback(0);
  29894. +
  29895. + return;
  29896. +}
  29897. +
  29898. +#endif
  29899. +
  29900. +/*
  29901. + * cesa Interrupt polling routine.
  29902. + */
  29903. +static irqreturn_t
  29904. +cesa_interrupt_handler(int irq, void *arg)
  29905. +{
  29906. + u32 cause;
  29907. +
  29908. + dprintk("%s()\n", __FUNCTION__);
  29909. +
  29910. + cesaTestTraceAdd(0);
  29911. +
  29912. + /* Read cause register */
  29913. + cause = MV_REG_READ(MV_CESA_ISR_CAUSE_REG);
  29914. +
  29915. + if( (cause & MV_CESA_CAUSE_ACC_DMA_ALL_MASK) == 0)
  29916. + {
  29917. + /* Empty interrupt */
  29918. + dprintk("%s,%d: cesaTestReadyIsr: cause=0x%x\n", __FILE__, __LINE__, cause);
  29919. + return IRQ_HANDLED;
  29920. + }
  29921. +
  29922. + /* clear interrupts */
  29923. + MV_REG_WRITE(MV_CESA_ISR_CAUSE_REG, 0);
  29924. +
  29925. + cesaTestTraceAdd(1);
  29926. +#ifdef CESA_OCF_TASKLET
  29927. + tasklet_hi_schedule(&cesa_ocf_tasklet);
  29928. +#else
  29929. + cesa_callback(0);
  29930. +#endif
  29931. + return IRQ_HANDLED;
  29932. +}
  29933. +
  29934. +/*
  29935. + * Open a session.
  29936. + */
  29937. +static int
  29938. +/*cesa_ocf_newsession(void *arg, u_int32_t *sid, struct cryptoini *cri)*/
  29939. +cesa_ocf_newsession(device_t dev, u_int32_t *sid, struct cryptoini *cri)
  29940. +{
  29941. + u32 status = 0, i;
  29942. + u32 count = 0, auth = 0, encrypt =0;
  29943. + struct cesa_ocf_data *cesa_ocf_cur_ses;
  29944. + MV_CESA_OPEN_SESSION cesa_session;
  29945. + MV_CESA_OPEN_SESSION *cesa_ses = &cesa_session;
  29946. +
  29947. +
  29948. + dprintk("%s()\n", __FUNCTION__);
  29949. + if (sid == NULL || cri == NULL) {
  29950. + printk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  29951. + return EINVAL;
  29952. + }
  29953. +
  29954. + /* leave first empty like in other implementations */
  29955. + for (i = 1; i < CESA_OCF_MAX_SES; i++) {
  29956. + if (cesa_ocf_sessions[i] == NULL)
  29957. + break;
  29958. + }
  29959. +
  29960. + if(i >= CESA_OCF_MAX_SES) {
  29961. + printk("%s,%d: no more sessions \n", __FILE__, __LINE__);
  29962. + return EINVAL;
  29963. + }
  29964. +
  29965. + cesa_ocf_sessions[i] = (struct cesa_ocf_data *) kmalloc(sizeof(struct cesa_ocf_data), GFP_ATOMIC);
  29966. + if (cesa_ocf_sessions[i] == NULL) {
  29967. + cesa_ocf_freesession(NULL, i);
  29968. + printk("%s,%d: ENOBUFS \n", __FILE__, __LINE__);
  29969. + return ENOBUFS;
  29970. + }
  29971. + dprintk("%s,%d: new session %d \n", __FILE__, __LINE__, i);
  29972. +
  29973. + *sid = i;
  29974. + cesa_ocf_cur_ses = cesa_ocf_sessions[i];
  29975. + memset(cesa_ocf_cur_ses, 0, sizeof(struct cesa_ocf_data));
  29976. + cesa_ocf_cur_ses->sid_encrypt = -1;
  29977. + cesa_ocf_cur_ses->sid_decrypt = -1;
  29978. + cesa_ocf_cur_ses->frag_wa_encrypt = -1;
  29979. + cesa_ocf_cur_ses->frag_wa_decrypt = -1;
  29980. + cesa_ocf_cur_ses->frag_wa_auth = -1;
  29981. +
  29982. + /* init the session */
  29983. + memset(cesa_ses, 0, sizeof(MV_CESA_OPEN_SESSION));
  29984. + count = 1;
  29985. + while (cri) {
  29986. + if(count > 2) {
  29987. + printk("%s,%d: don't support more then 2 operations\n", __FILE__, __LINE__);
  29988. + goto error;
  29989. + }
  29990. + switch (cri->cri_alg) {
  29991. + case CRYPTO_AES_CBC:
  29992. + dprintk("%s,%d: (%d) AES CBC \n", __FILE__, __LINE__, count);
  29993. + cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
  29994. + cesa_ocf_cur_ses->ivlen = MV_CESA_AES_BLOCK_SIZE;
  29995. + cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_AES;
  29996. + cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
  29997. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  29998. + printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
  29999. + goto error;
  30000. + }
  30001. + memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
  30002. + dprintk("%s,%d: key length %d \n", __FILE__, __LINE__, cri->cri_klen/8);
  30003. + cesa_ses->cryptoKeyLength = cri->cri_klen/8;
  30004. + encrypt += count;
  30005. + break;
  30006. + case CRYPTO_3DES_CBC:
  30007. + dprintk("%s,%d: (%d) 3DES CBC \n", __FILE__, __LINE__, count);
  30008. + cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
  30009. + cesa_ocf_cur_ses->ivlen = MV_CESA_3DES_BLOCK_SIZE;
  30010. + cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_3DES;
  30011. + cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
  30012. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  30013. + printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
  30014. + goto error;
  30015. + }
  30016. + memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
  30017. + cesa_ses->cryptoKeyLength = cri->cri_klen/8;
  30018. + encrypt += count;
  30019. + break;
  30020. + case CRYPTO_DES_CBC:
  30021. + dprintk("%s,%d: (%d) DES CBC \n", __FILE__, __LINE__, count);
  30022. + cesa_ocf_cur_ses->cipher_alg = cri->cri_alg;
  30023. + cesa_ocf_cur_ses->ivlen = MV_CESA_DES_BLOCK_SIZE;
  30024. + cesa_ses->cryptoAlgorithm = MV_CESA_CRYPTO_DES;
  30025. + cesa_ses->cryptoMode = MV_CESA_CRYPTO_CBC;
  30026. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  30027. + printk("%s,%d: CRYPTO key too long.\n", __FILE__, __LINE__);
  30028. + goto error;
  30029. + }
  30030. + memcpy(cesa_ses->cryptoKey, cri->cri_key, cri->cri_klen/8);
  30031. + cesa_ses->cryptoKeyLength = cri->cri_klen/8;
  30032. + encrypt += count;
  30033. + break;
  30034. + case CRYPTO_MD5:
  30035. + case CRYPTO_MD5_HMAC:
  30036. + dprintk("%s,%d: (%d) %sMD5 CBC \n", __FILE__, __LINE__, count, (cri->cri_alg != CRYPTO_MD5)? "H-":" ");
  30037. + cesa_ocf_cur_ses->auth_alg = cri->cri_alg;
  30038. + cesa_ocf_cur_ses->digestlen = (cri->cri_alg == CRYPTO_MD5)? MV_CESA_MD5_DIGEST_SIZE : 12;
  30039. + cesa_ses->macMode = (cri->cri_alg == CRYPTO_MD5)? MV_CESA_MAC_MD5 : MV_CESA_MAC_HMAC_MD5;
  30040. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  30041. + printk("%s,%d: MAC key too long. \n", __FILE__, __LINE__);
  30042. + goto error;
  30043. + }
  30044. + cesa_ses->macKeyLength = cri->cri_klen/8;
  30045. + memcpy(cesa_ses->macKey, cri->cri_key, cri->cri_klen/8);
  30046. + cesa_ses->digestSize = cesa_ocf_cur_ses->digestlen;
  30047. + auth += count;
  30048. + break;
  30049. + case CRYPTO_SHA1:
  30050. + case CRYPTO_SHA1_HMAC:
  30051. + dprintk("%s,%d: (%d) %sSHA1 CBC \n", __FILE__, __LINE__, count, (cri->cri_alg != CRYPTO_SHA1)? "H-":" ");
  30052. + cesa_ocf_cur_ses->auth_alg = cri->cri_alg;
  30053. + cesa_ocf_cur_ses->digestlen = (cri->cri_alg == CRYPTO_SHA1)? MV_CESA_SHA1_DIGEST_SIZE : 12;
  30054. + cesa_ses->macMode = (cri->cri_alg == CRYPTO_SHA1)? MV_CESA_MAC_SHA1 : MV_CESA_MAC_HMAC_SHA1;
  30055. + if(cri->cri_klen/8 > MV_CESA_MAX_CRYPTO_KEY_LENGTH) {
  30056. + printk("%s,%d: MAC key too long. \n", __FILE__, __LINE__);
  30057. + goto error;
  30058. + }
  30059. + cesa_ses->macKeyLength = cri->cri_klen/8;
  30060. + memcpy(cesa_ses->macKey, cri->cri_key, cri->cri_klen/8);
  30061. + cesa_ses->digestSize = cesa_ocf_cur_ses->digestlen;
  30062. + auth += count;
  30063. + break;
  30064. + default:
  30065. + printk("%s,%d: unknown algo 0x%x\n", __FILE__, __LINE__, cri->cri_alg);
  30066. + goto error;
  30067. + }
  30068. + cri = cri->cri_next;
  30069. + count++;
  30070. + }
  30071. +
  30072. + if((encrypt > 2) || (auth > 2)) {
  30073. + printk("%s,%d: session mode is not supported.\n", __FILE__, __LINE__);
  30074. + goto error;
  30075. + }
  30076. + /* create new sessions in HAL */
  30077. + if(encrypt) {
  30078. + cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
  30079. + /* encrypt session */
  30080. + if(auth == 1) {
  30081. + cesa_ses->operation = MV_CESA_MAC_THEN_CRYPTO;
  30082. + }
  30083. + else if(auth == 2) {
  30084. + cesa_ses->operation = MV_CESA_CRYPTO_THEN_MAC;
  30085. + cesa_ocf_cur_ses->encrypt_tn_auth = 1;
  30086. + }
  30087. + else {
  30088. + cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
  30089. + }
  30090. + cesa_ses->direction = MV_CESA_DIR_ENCODE;
  30091. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_encrypt);
  30092. + if(status != MV_OK) {
  30093. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  30094. + goto error;
  30095. + }
  30096. + /* decrypt session */
  30097. + if( cesa_ses->operation == MV_CESA_MAC_THEN_CRYPTO ) {
  30098. + cesa_ses->operation = MV_CESA_CRYPTO_THEN_MAC;
  30099. + }
  30100. + else if( cesa_ses->operation == MV_CESA_CRYPTO_THEN_MAC ) {
  30101. + cesa_ses->operation = MV_CESA_MAC_THEN_CRYPTO;
  30102. + }
  30103. + cesa_ses->direction = MV_CESA_DIR_DECODE;
  30104. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_decrypt);
  30105. + if(status != MV_OK) {
  30106. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  30107. + goto error;
  30108. + }
  30109. +
  30110. + /* preapre one action sessions for case we will need to split an action */
  30111. +#ifdef CESA_OCF_SPLIT
  30112. + if(( cesa_ses->operation == MV_CESA_MAC_THEN_CRYPTO ) ||
  30113. + ( cesa_ses->operation == MV_CESA_CRYPTO_THEN_MAC )) {
  30114. + /* open one session for encode and one for decode */
  30115. + cesa_ses->operation = MV_CESA_CRYPTO_ONLY;
  30116. + cesa_ses->direction = MV_CESA_DIR_ENCODE;
  30117. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_encrypt);
  30118. + if(status != MV_OK) {
  30119. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  30120. + goto error;
  30121. + }
  30122. +
  30123. + cesa_ses->direction = MV_CESA_DIR_DECODE;
  30124. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_decrypt);
  30125. + if(status != MV_OK) {
  30126. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  30127. + goto error;
  30128. + }
  30129. + /* open one session for auth */
  30130. + cesa_ses->operation = MV_CESA_MAC_ONLY;
  30131. + cesa_ses->direction = MV_CESA_DIR_ENCODE;
  30132. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->frag_wa_auth);
  30133. + if(status != MV_OK) {
  30134. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  30135. + goto error;
  30136. + }
  30137. + }
  30138. +#endif
  30139. + }
  30140. + else { /* only auth */
  30141. + cesa_ses->operation = MV_CESA_MAC_ONLY;
  30142. + cesa_ses->direction = MV_CESA_DIR_ENCODE;
  30143. + status = mvCesaSessionOpen(cesa_ses, &cesa_ocf_cur_ses->sid_encrypt);
  30144. + if(status != MV_OK) {
  30145. + printk("%s,%d: Can't open new session - status = 0x%x\n", __FILE__, __LINE__, status);
  30146. + goto error;
  30147. + }
  30148. + }
  30149. +
  30150. + return 0;
  30151. +error:
  30152. + cesa_ocf_freesession(NULL, *sid);
  30153. + return EINVAL;
  30154. +
  30155. +}
  30156. +
  30157. +
  30158. +/*
  30159. + * Free a session.
  30160. + */
  30161. +static int
  30162. +cesa_ocf_freesession(device_t dev, u_int64_t tid)
  30163. +{
  30164. + struct cesa_ocf_data *cesa_ocf_cur_ses;
  30165. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  30166. + //unsigned long flags;
  30167. +
  30168. + dprintk("%s() %d \n", __FUNCTION__, sid);
  30169. + if ( (sid >= CESA_OCF_MAX_SES) || (cesa_ocf_sessions[sid] == NULL) ) {
  30170. + printk("%s,%d: EINVAL can't free session %d \n", __FILE__, __LINE__, sid);
  30171. + return(EINVAL);
  30172. + }
  30173. +
  30174. + /* Silently accept and return */
  30175. + if (sid == 0)
  30176. + return(0);
  30177. +
  30178. + /* release session from HAL */
  30179. + cesa_ocf_cur_ses = cesa_ocf_sessions[sid];
  30180. + if (cesa_ocf_cur_ses->sid_encrypt != -1) {
  30181. + mvCesaSessionClose(cesa_ocf_cur_ses->sid_encrypt);
  30182. + }
  30183. + if (cesa_ocf_cur_ses->sid_decrypt != -1) {
  30184. + mvCesaSessionClose(cesa_ocf_cur_ses->sid_decrypt);
  30185. + }
  30186. + if (cesa_ocf_cur_ses->frag_wa_encrypt != -1) {
  30187. + mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_encrypt);
  30188. + }
  30189. + if (cesa_ocf_cur_ses->frag_wa_decrypt != -1) {
  30190. + mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_decrypt);
  30191. + }
  30192. + if (cesa_ocf_cur_ses->frag_wa_auth != -1) {
  30193. + mvCesaSessionClose(cesa_ocf_cur_ses->frag_wa_auth);
  30194. + }
  30195. +
  30196. + kfree(cesa_ocf_cur_ses);
  30197. + cesa_ocf_sessions[sid] = NULL;
  30198. +
  30199. + return 0;
  30200. +}
  30201. +
  30202. +
  30203. +/* TDMA Window setup */
  30204. +
  30205. +static void __init
  30206. +setup_tdma_mbus_windows(struct cesa_dev *dev)
  30207. +{
  30208. + int i;
  30209. +
  30210. + for (i = 0; i < 4; i++) {
  30211. + writel(0, dev->reg + WINDOW_BASE(i));
  30212. + writel(0, dev->reg + WINDOW_CTRL(i));
  30213. + }
  30214. +
  30215. + for (i = 0; i < dev->plat_data->dram->num_cs; i++) {
  30216. + struct mbus_dram_window *cs = dev->plat_data->dram->cs + i;
  30217. + writel(
  30218. + ((cs->size - 1) & 0xffff0000) |
  30219. + (cs->mbus_attr << 8) |
  30220. + (dev->plat_data->dram->mbus_dram_target_id << 4) | 1,
  30221. + dev->reg + WINDOW_CTRL(i)
  30222. + );
  30223. + writel(cs->base, dev->reg + WINDOW_BASE(i));
  30224. + }
  30225. +}
  30226. +
  30227. +/*
  30228. + * our driver startup and shutdown routines
  30229. + */
  30230. +static int
  30231. +mv_cesa_ocf_init(struct platform_device *pdev)
  30232. +{
  30233. +#if defined(CONFIG_MV78200) || defined(CONFIG_MV632X)
  30234. + if (MV_FALSE == mvSocUnitIsMappedToThisCpu(CESA))
  30235. + {
  30236. + dprintk("CESA is not mapped to this CPU\n");
  30237. + return -ENODEV;
  30238. + }
  30239. +#endif
  30240. +
  30241. + dprintk("%s\n", __FUNCTION__);
  30242. + memset(&mv_cesa_dev, 0, sizeof(mv_cesa_dev));
  30243. + softc_device_init(&mv_cesa_dev, "MV CESA", 0, mv_cesa_methods);
  30244. + cesa_ocf_id = crypto_get_driverid(softc_get_device(&mv_cesa_dev),CRYPTOCAP_F_HARDWARE);
  30245. +
  30246. + if (cesa_ocf_id < 0)
  30247. + panic("MV CESA crypto device cannot initialize!");
  30248. +
  30249. + dprintk("%s,%d: cesa ocf device id is %d \n", __FILE__, __LINE__, cesa_ocf_id);
  30250. +
  30251. + /* CESA unit is auto power on off */
  30252. +#if 0
  30253. + if (MV_FALSE == mvCtrlPwrClckGet(CESA_UNIT_ID,0))
  30254. + {
  30255. + printk("\nWarning CESA %d is Powered Off\n",0);
  30256. + return EINVAL;
  30257. + }
  30258. +#endif
  30259. +
  30260. + memset(&cesa_device, 0, sizeof(struct cesa_dev));
  30261. + /* Get the IRQ, and crypto memory regions */
  30262. + {
  30263. + struct resource *res;
  30264. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram");
  30265. +
  30266. + if (!res)
  30267. + return -ENXIO;
  30268. +
  30269. + cesa_device.sram = ioremap(res->start, res->end - res->start + 1);
  30270. + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
  30271. +
  30272. + if (!res) {
  30273. + iounmap(cesa_device.sram);
  30274. + return -ENXIO;
  30275. + }
  30276. + cesa_device.reg = ioremap(res->start, res->end - res->start + 1);
  30277. + cesa_device.irq = platform_get_irq(pdev, 0);
  30278. + cesa_device.plat_data = pdev->dev.platform_data;
  30279. + setup_tdma_mbus_windows(&cesa_device);
  30280. +
  30281. + }
  30282. +
  30283. +
  30284. + if( MV_OK != mvCesaInit(CESA_OCF_MAX_SES*5, CESA_Q_SIZE, cesa_device.reg,
  30285. + NULL) ) {
  30286. + printk("%s,%d: mvCesaInit Failed. \n", __FILE__, __LINE__);
  30287. + return EINVAL;
  30288. + }
  30289. +
  30290. + /* clear and unmask Int */
  30291. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  30292. +#ifndef CESA_OCF_POLLING
  30293. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, MV_CESA_CAUSE_ACC_DMA_MASK);
  30294. +#endif
  30295. +#ifdef CESA_OCF_TASKLET
  30296. + tasklet_init(&cesa_ocf_tasklet, cesa_callback, (unsigned int) 0);
  30297. +#endif
  30298. + /* register interrupt */
  30299. + if( request_irq( cesa_device.irq, cesa_interrupt_handler,
  30300. + (IRQF_DISABLED) , "cesa", &cesa_ocf_id) < 0) {
  30301. + printk("%s,%d: cannot assign irq %x\n", __FILE__, __LINE__, cesa_device.reg);
  30302. + return EINVAL;
  30303. + }
  30304. +
  30305. +
  30306. + memset(cesa_ocf_sessions, 0, sizeof(struct cesa_ocf_data *) * CESA_OCF_MAX_SES);
  30307. +
  30308. +#define REGISTER(alg) \
  30309. + crypto_register(cesa_ocf_id, alg, 0,0)
  30310. + REGISTER(CRYPTO_AES_CBC);
  30311. + REGISTER(CRYPTO_DES_CBC);
  30312. + REGISTER(CRYPTO_3DES_CBC);
  30313. + REGISTER(CRYPTO_MD5);
  30314. + REGISTER(CRYPTO_MD5_HMAC);
  30315. + REGISTER(CRYPTO_SHA1);
  30316. + REGISTER(CRYPTO_SHA1_HMAC);
  30317. +#undef REGISTER
  30318. +
  30319. + return 0;
  30320. +}
  30321. +
  30322. +static void
  30323. +mv_cesa_ocf_exit(struct platform_device *pdev)
  30324. +{
  30325. + dprintk("%s()\n", __FUNCTION__);
  30326. +
  30327. + crypto_unregister_all(cesa_ocf_id);
  30328. + cesa_ocf_id = -1;
  30329. + iounmap(cesa_device.reg);
  30330. + iounmap(cesa_device.sram);
  30331. + free_irq(cesa_device.irq, NULL);
  30332. +
  30333. + /* mask and clear Int */
  30334. + MV_REG_WRITE( MV_CESA_ISR_MASK_REG, 0);
  30335. + MV_REG_WRITE( MV_CESA_ISR_CAUSE_REG, 0);
  30336. +
  30337. +
  30338. + if( MV_OK != mvCesaFinish() ) {
  30339. + printk("%s,%d: mvCesaFinish Failed. \n", __FILE__, __LINE__);
  30340. + return;
  30341. + }
  30342. +}
  30343. +
  30344. +
  30345. +void cesa_ocf_debug(void)
  30346. +{
  30347. +
  30348. +#ifdef CESA_OCF_TRACE_DEBUG
  30349. + {
  30350. + int i, j;
  30351. + j = cesaTestTraceIdx;
  30352. + mvOsPrintf("No Type rCause iCause Proc Isr Res Time pReady pProc pEmpty\n");
  30353. + for(i=0; i<MV_CESA_TEST_TRACE_SIZE; i++)
  30354. + {
  30355. + mvOsPrintf("%02d. %d 0x%04x 0x%04x 0x%02x 0x%02x %02d 0x%06x %p %p %p\n",
  30356. + j, cesaTestTrace[j].type, cesaTestTrace[j].realCause,
  30357. + cesaTestTrace[j].idmaCause,
  30358. + cesaTestTrace[j].resources, cesaTestTrace[j].timeStamp,
  30359. + cesaTestTrace[j].pReqReady, cesaTestTrace[j].pReqProcess, cesaTestTrace[j].pReqEmpty);
  30360. + j++;
  30361. + if(j == MV_CESA_TEST_TRACE_SIZE)
  30362. + j = 0;
  30363. + }
  30364. + }
  30365. +#endif
  30366. +
  30367. +}
  30368. +
  30369. +static struct platform_driver marvell_cesa = {
  30370. + .probe = mv_cesa_ocf_init,
  30371. + .remove = mv_cesa_ocf_exit,
  30372. + .driver = {
  30373. + .owner = THIS_MODULE,
  30374. + .name = "mv_crypto",
  30375. + },
  30376. +};
  30377. +
  30378. +MODULE_ALIAS("platform:mv_crypto");
  30379. +
  30380. +static int __init mv_cesa_init(void)
  30381. +{
  30382. + return platform_driver_register(&marvell_cesa);
  30383. +}
  30384. +
  30385. +module_init(mv_cesa_init);
  30386. +
  30387. +static void __exit mv_cesa_exit(void)
  30388. +{
  30389. + platform_driver_unregister(&marvell_cesa);
  30390. +}
  30391. +
  30392. +module_exit(mv_cesa_exit);
  30393. +
  30394. +MODULE_LICENSE("GPL");
  30395. +MODULE_AUTHOR("Ronen Shitrit");
  30396. +MODULE_DESCRIPTION("OCF module for Orion CESA crypto");
  30397. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mv802_3.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mv802_3.h
  30398. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mv802_3.h 1970-01-01 01:00:00.000000000 +0100
  30399. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mv802_3.h 2011-08-01 14:38:19.000000000 +0200
  30400. @@ -0,0 +1,213 @@
  30401. +/*******************************************************************************
  30402. +Copyright (C) Marvell International Ltd. and its affiliates
  30403. +
  30404. +This software file (the "File") is owned and distributed by Marvell
  30405. +International Ltd. and/or its affiliates ("Marvell") under the following
  30406. +alternative licensing terms. Once you have made an election to distribute the
  30407. +File under one of the following license alternatives, please (i) delete this
  30408. +introductory statement regarding license alternatives, (ii) delete the two
  30409. +license alternatives that you have not elected to use and (iii) preserve the
  30410. +Marvell copyright notice above.
  30411. +
  30412. +********************************************************************************
  30413. +Marvell Commercial License Option
  30414. +
  30415. +If you received this File from Marvell and you have entered into a commercial
  30416. +license agreement (a "Commercial License") with Marvell, the File is licensed
  30417. +to you under the terms of the applicable Commercial License.
  30418. +
  30419. +********************************************************************************
  30420. +Marvell GPL License Option
  30421. +
  30422. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30423. +modify this File in accordance with the terms and conditions of the General
  30424. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  30425. +available along with the File in the license.txt file or by writing to the Free
  30426. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  30427. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  30428. +
  30429. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  30430. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  30431. +DISCLAIMED. The GPL License provides additional details about this warranty
  30432. +disclaimer.
  30433. +********************************************************************************
  30434. +Marvell BSD License Option
  30435. +
  30436. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30437. +modify this File under the following licensing terms.
  30438. +Redistribution and use in source and binary forms, with or without modification,
  30439. +are permitted provided that the following conditions are met:
  30440. +
  30441. + * Redistributions of source code must retain the above copyright notice,
  30442. + this list of conditions and the following disclaimer.
  30443. +
  30444. + * Redistributions in binary form must reproduce the above copyright
  30445. + notice, this list of conditions and the following disclaimer in the
  30446. + documentation and/or other materials provided with the distribution.
  30447. +
  30448. + * Neither the name of Marvell nor the names of its contributors may be
  30449. + used to endorse or promote products derived from this software without
  30450. + specific prior written permission.
  30451. +
  30452. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  30453. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  30454. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  30455. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  30456. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  30457. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30458. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30459. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30460. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30461. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30462. +
  30463. +*******************************************************************************/
  30464. +
  30465. +
  30466. +#ifndef __INCmv802_3h
  30467. +#define __INCmv802_3h
  30468. +
  30469. +
  30470. +/* includes */
  30471. +#include "mvTypes.h"
  30472. +
  30473. +/* Defines */
  30474. +#define MV_MAX_ETH_DATA 1500
  30475. +
  30476. +/* 802.3 types */
  30477. +#define MV_IP_TYPE 0x0800
  30478. +#define MV_IP_ARP_TYPE 0x0806
  30479. +#define MV_APPLE_TALK_ARP_TYPE 0x80F3
  30480. +#define MV_NOVELL_IPX_TYPE 0x8137
  30481. +#define MV_EAPOL_TYPE 0x888e
  30482. +
  30483. +
  30484. +
  30485. +/* Encapsulation header for RFC1042 and Ethernet_tunnel */
  30486. +
  30487. +#define MV_RFC1042_SNAP_HEADER {0xAA, 0xAA, 0x03, 0x00, 0x00, 0x00}
  30488. +
  30489. +#define MV_ETH_SNAP_LSB 0xF8
  30490. +
  30491. +
  30492. +#define MV_MAC_ADDR_SIZE (6)
  30493. +#define MV_MAC_STR_SIZE (20)
  30494. +#define MV_VLAN_HLEN (4)
  30495. +
  30496. +/* This macro checks for a multicast mac address */
  30497. +#define MV_IS_MULTICAST_MAC(mac) (((mac)[0] & 0x1) == 1)
  30498. +
  30499. +
  30500. +/* This macro checks for an broadcast mac address */
  30501. +#define MV_IS_BROADCAST_MAC(mac) \
  30502. + (((mac)[0] == 0xFF) && \
  30503. + ((mac)[1] == 0xFF) && \
  30504. + ((mac)[2] == 0xFF) && \
  30505. + ((mac)[3] == 0xFF) && \
  30506. + ((mac)[4] == 0xFF) && \
  30507. + ((mac)[5] == 0xFF))
  30508. +
  30509. +
  30510. +/* Typedefs */
  30511. +typedef struct
  30512. +{
  30513. + MV_U8 pDA[MV_MAC_ADDR_SIZE];
  30514. + MV_U8 pSA[MV_MAC_ADDR_SIZE];
  30515. + MV_U16 typeOrLen;
  30516. +
  30517. +} MV_802_3_HEADER;
  30518. +
  30519. +enum {
  30520. + MV_IP_PROTO_NULL = 0, /* Dummy protocol for TCP */
  30521. + MV_IP_PROTO_ICMP = 1, /* Internet Control Message Protocol */
  30522. + MV_IP_PROTO_IGMP = 2, /* Internet Group Management Protocol */
  30523. + MV_IP_PROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */
  30524. + MV_IP_PROTO_TCP = 6, /* Transmission Control Protocol */
  30525. + MV_IP_PROTO_EGP = 8, /* Exterior Gateway Protocol */
  30526. + MV_IP_PROTO_PUP = 12, /* PUP protocol */
  30527. + MV_IP_PROTO_UDP = 17, /* User Datagram Protocol */
  30528. + MV_IP_PROTO_IDP = 22, /* XNS IDP protocol */
  30529. + MV_IP_PROTO_DCCP = 33, /* Datagram Congestion Control Protocol */
  30530. + MV_IP_PROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */
  30531. + MV_IP_PROTO_RSVP = 46, /* RSVP protocol */
  30532. + MV_IP_PROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */
  30533. + MV_IP_PROTO_ESP = 50, /* Encapsulation Security Payload protocol */
  30534. + MV_IP_PROTO_AH = 51, /* Authentication Header protocol */
  30535. + MV_IP_PROTO_BEETPH = 94, /* IP option pseudo header for BEET */
  30536. + MV_IP_PROTO_PIM = 103,
  30537. + MV_IP_PROTO_COMP = 108, /* Compression Header protocol */
  30538. + MV_IP_PROTO_ZERO_HOP = 114, /* Any 0 hop protocol (IANA) */
  30539. + MV_IP_PROTO_SCTP = 132, /* Stream Control Transport Protocol */
  30540. + MV_IP_PROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */
  30541. +
  30542. + MV_IP_PROTO_RAW = 255, /* Raw IP packets */
  30543. + MV_IP_PROTO_MAX
  30544. +};
  30545. +
  30546. +typedef struct
  30547. +{
  30548. + MV_U8 version;
  30549. + MV_U8 tos;
  30550. + MV_U16 totalLength;
  30551. + MV_U16 identifier;
  30552. + MV_U16 fragmentCtrl;
  30553. + MV_U8 ttl;
  30554. + MV_U8 protocol;
  30555. + MV_U16 checksum;
  30556. + MV_U32 srcIP;
  30557. + MV_U32 dstIP;
  30558. +
  30559. +} MV_IP_HEADER;
  30560. +
  30561. +typedef struct
  30562. +{
  30563. + MV_U32 spi;
  30564. + MV_U32 seqNum;
  30565. +} MV_ESP_HEADER;
  30566. +
  30567. +#define MV_ICMP_ECHOREPLY 0 /* Echo Reply */
  30568. +#define MV_ICMP_DEST_UNREACH 3 /* Destination Unreachable */
  30569. +#define MV_ICMP_SOURCE_QUENCH 4 /* Source Quench */
  30570. +#define MV_ICMP_REDIRECT 5 /* Redirect (change route) */
  30571. +#define MV_ICMP_ECHO 8 /* Echo Request */
  30572. +#define MV_ICMP_TIME_EXCEEDED 11 /* Time Exceeded */
  30573. +#define MV_ICMP_PARAMETERPROB 12 /* Parameter Problem */
  30574. +#define MV_ICMP_TIMESTAMP 13 /* Timestamp Request */
  30575. +#define MV_ICMP_TIMESTAMPREPLY 14 /* Timestamp Reply */
  30576. +#define MV_ICMP_INFO_REQUEST 15 /* Information Request */
  30577. +#define MV_ICMP_INFO_REPLY 16 /* Information Reply */
  30578. +#define MV_ICMP_ADDRESS 17 /* Address Mask Request */
  30579. +#define MV_ICMP_ADDRESSREPLY 18 /* Address Mask Reply */
  30580. +
  30581. +typedef struct
  30582. +{
  30583. + MV_U8 type;
  30584. + MV_U8 code;
  30585. + MV_U16 checksum;
  30586. + MV_U16 id;
  30587. + MV_U16 sequence;
  30588. +
  30589. +} MV_ICMP_ECHO_HEADER;
  30590. +
  30591. +typedef struct
  30592. +{
  30593. + MV_U16 source;
  30594. + MV_U16 dest;
  30595. + MV_U32 seq;
  30596. + MV_U32 ack_seq;
  30597. + MV_U16 flags;
  30598. + MV_U16 window;
  30599. + MV_U16 chksum;
  30600. + MV_U16 urg_offset;
  30601. +
  30602. +} MV_TCP_HEADER;
  30603. +
  30604. +typedef struct
  30605. +{
  30606. + MV_U16 source;
  30607. + MV_U16 dest;
  30608. + MV_U16 len;
  30609. + MV_U16 check;
  30610. +
  30611. +} MV_UDP_HEADER;
  30612. +
  30613. +#endif /* __INCmv802_3h */
  30614. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvCommon.c
  30615. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.c 1970-01-01 01:00:00.000000000 +0100
  30616. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvCommon.c 2011-08-01 14:38:19.000000000 +0200
  30617. @@ -0,0 +1,277 @@
  30618. +/*******************************************************************************
  30619. +Copyright (C) Marvell International Ltd. and its affiliates
  30620. +
  30621. +This software file (the "File") is owned and distributed by Marvell
  30622. +International Ltd. and/or its affiliates ("Marvell") under the following
  30623. +alternative licensing terms. Once you have made an election to distribute the
  30624. +File under one of the following license alternatives, please (i) delete this
  30625. +introductory statement regarding license alternatives, (ii) delete the two
  30626. +license alternatives that you have not elected to use and (iii) preserve the
  30627. +Marvell copyright notice above.
  30628. +
  30629. +********************************************************************************
  30630. +Marvell Commercial License Option
  30631. +
  30632. +If you received this File from Marvell and you have entered into a commercial
  30633. +license agreement (a "Commercial License") with Marvell, the File is licensed
  30634. +to you under the terms of the applicable Commercial License.
  30635. +
  30636. +********************************************************************************
  30637. +Marvell GPL License Option
  30638. +
  30639. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30640. +modify this File in accordance with the terms and conditions of the General
  30641. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  30642. +available along with the File in the license.txt file or by writing to the Free
  30643. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  30644. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  30645. +
  30646. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  30647. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  30648. +DISCLAIMED. The GPL License provides additional details about this warranty
  30649. +disclaimer.
  30650. +********************************************************************************
  30651. +Marvell BSD License Option
  30652. +
  30653. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30654. +modify this File under the following licensing terms.
  30655. +Redistribution and use in source and binary forms, with or without modification,
  30656. +are permitted provided that the following conditions are met:
  30657. +
  30658. + * Redistributions of source code must retain the above copyright notice,
  30659. + this list of conditions and the following disclaimer.
  30660. +
  30661. + * Redistributions in binary form must reproduce the above copyright
  30662. + notice, this list of conditions and the following disclaimer in the
  30663. + documentation and/or other materials provided with the distribution.
  30664. +
  30665. + * Neither the name of Marvell nor the names of its contributors may be
  30666. + used to endorse or promote products derived from this software without
  30667. + specific prior written permission.
  30668. +
  30669. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  30670. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  30671. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  30672. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  30673. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  30674. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30675. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30676. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30677. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30678. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30679. +
  30680. +*******************************************************************************/
  30681. +
  30682. +#include "mvOs.h"
  30683. +#include "mv802_3.h"
  30684. +#include "mvCommon.h"
  30685. +
  30686. +
  30687. +/*******************************************************************************
  30688. +* mvMacStrToHex - Convert MAC format string to hex.
  30689. +*
  30690. +* DESCRIPTION:
  30691. +* This function convert MAC format string to hex.
  30692. +*
  30693. +* INPUT:
  30694. +* macStr - MAC address string. Fornat of address string is
  30695. +* uu:vv:ww:xx:yy:zz, where ":" can be any delimiter.
  30696. +*
  30697. +* OUTPUT:
  30698. +* macHex - MAC in hex format.
  30699. +*
  30700. +* RETURN:
  30701. +* None.
  30702. +*
  30703. +*******************************************************************************/
  30704. +MV_STATUS mvMacStrToHex(const char* macStr, MV_U8* macHex)
  30705. +{
  30706. + int i;
  30707. + char tmp[3];
  30708. +
  30709. + for(i = 0; i < MV_MAC_ADDR_SIZE; i++)
  30710. + {
  30711. + tmp[0] = macStr[(i * 3) + 0];
  30712. + tmp[1] = macStr[(i * 3) + 1];
  30713. + tmp[2] = '\0';
  30714. + macHex[i] = (MV_U8) (strtol(tmp, NULL, 16));
  30715. + }
  30716. + return MV_OK;
  30717. +}
  30718. +
  30719. +/*******************************************************************************
  30720. +* mvMacHexToStr - Convert MAC in hex format to string format.
  30721. +*
  30722. +* DESCRIPTION:
  30723. +* This function convert MAC in hex format to string format.
  30724. +*
  30725. +* INPUT:
  30726. +* macHex - MAC in hex format.
  30727. +*
  30728. +* OUTPUT:
  30729. +* macStr - MAC address string. String format is uu:vv:ww:xx:yy:zz.
  30730. +*
  30731. +* RETURN:
  30732. +* None.
  30733. +*
  30734. +*******************************************************************************/
  30735. +MV_STATUS mvMacHexToStr(MV_U8* macHex, char* macStr)
  30736. +{
  30737. + int i;
  30738. +
  30739. + for(i = 0; i < MV_MAC_ADDR_SIZE; i++)
  30740. + {
  30741. + mvOsSPrintf(&macStr[i * 3], "%02x:", macHex[i]);
  30742. + }
  30743. + macStr[(i * 3) - 1] = '\0';
  30744. +
  30745. + return MV_OK;
  30746. +}
  30747. +
  30748. +/*******************************************************************************
  30749. +* mvSizePrint - Print the given size with size unit description.
  30750. +*
  30751. +* DESCRIPTION:
  30752. +* This function print the given size with size unit description.
  30753. +* FOr example when size paramter is 0x180000, the function prints:
  30754. +* "size 1MB+500KB"
  30755. +*
  30756. +* INPUT:
  30757. +* size - Size in bytes.
  30758. +*
  30759. +* OUTPUT:
  30760. +* None.
  30761. +*
  30762. +* RETURN:
  30763. +* None.
  30764. +*
  30765. +*******************************************************************************/
  30766. +MV_VOID mvSizePrint(MV_U32 size)
  30767. +{
  30768. + mvOsOutput("size ");
  30769. +
  30770. + if(size >= _1G)
  30771. + {
  30772. + mvOsOutput("%3dGB ", size / _1G);
  30773. + size %= _1G;
  30774. + if(size)
  30775. + mvOsOutput("+");
  30776. + }
  30777. + if(size >= _1M )
  30778. + {
  30779. + mvOsOutput("%3dMB ", size / _1M);
  30780. + size %= _1M;
  30781. + if(size)
  30782. + mvOsOutput("+");
  30783. + }
  30784. + if(size >= _1K)
  30785. + {
  30786. + mvOsOutput("%3dKB ", size / _1K);
  30787. + size %= _1K;
  30788. + if(size)
  30789. + mvOsOutput("+");
  30790. + }
  30791. + if(size > 0)
  30792. + {
  30793. + mvOsOutput("%3dB ", size);
  30794. + }
  30795. +}
  30796. +
  30797. +/*******************************************************************************
  30798. +* mvHexToBin - Convert hex to binary
  30799. +*
  30800. +* DESCRIPTION:
  30801. +* This function Convert hex to binary.
  30802. +*
  30803. +* INPUT:
  30804. +* pHexStr - hex buffer pointer.
  30805. +* size - Size to convert.
  30806. +*
  30807. +* OUTPUT:
  30808. +* pBin - Binary buffer pointer.
  30809. +*
  30810. +* RETURN:
  30811. +* None.
  30812. +*
  30813. +*******************************************************************************/
  30814. +MV_VOID mvHexToBin(const char* pHexStr, MV_U8* pBin, int size)
  30815. +{
  30816. + int j, i;
  30817. + char tmp[3];
  30818. + MV_U8 byte;
  30819. +
  30820. + for(j=0, i=0; j<size; j++, i+=2)
  30821. + {
  30822. + tmp[0] = pHexStr[i];
  30823. + tmp[1] = pHexStr[i+1];
  30824. + tmp[2] = '\0';
  30825. + byte = (MV_U8) (strtol(tmp, NULL, 16) & 0xFF);
  30826. + pBin[j] = byte;
  30827. + }
  30828. +}
  30829. +
  30830. +void mvAsciiToHex(const char* asciiStr, char* hexStr)
  30831. +{
  30832. + int i=0;
  30833. +
  30834. + while(asciiStr[i] != 0)
  30835. + {
  30836. + mvOsSPrintf(&hexStr[i*2], "%02x", asciiStr[i]);
  30837. + i++;
  30838. + }
  30839. + hexStr[i*2] = 0;
  30840. +}
  30841. +
  30842. +
  30843. +void mvBinToHex(const MV_U8* bin, char* hexStr, int size)
  30844. +{
  30845. + int i;
  30846. +
  30847. + for(i=0; i<size; i++)
  30848. + {
  30849. + mvOsSPrintf(&hexStr[i*2], "%02x", bin[i]);
  30850. + }
  30851. + hexStr[i*2] = '\0';
  30852. +}
  30853. +
  30854. +void mvBinToAscii(const MV_U8* bin, char* asciiStr, int size)
  30855. +{
  30856. + int i;
  30857. +
  30858. + for(i=0; i<size; i++)
  30859. + {
  30860. + mvOsSPrintf(&asciiStr[i*2], "%c", bin[i]);
  30861. + }
  30862. + asciiStr[i*2] = '\0';
  30863. +}
  30864. +
  30865. +/*******************************************************************************
  30866. +* mvLog2 -
  30867. +*
  30868. +* DESCRIPTION:
  30869. +* Calculate the Log2 of a given number.
  30870. +*
  30871. +* INPUT:
  30872. +* num - A number to calculate the Log2 for.
  30873. +*
  30874. +* OUTPUT:
  30875. +* None.
  30876. +*
  30877. +* RETURN:
  30878. +* Log 2 of the input number, or 0xFFFFFFFF if input is 0.
  30879. +*
  30880. +*******************************************************************************/
  30881. +MV_U32 mvLog2(MV_U32 num)
  30882. +{
  30883. + MV_U32 result = 0;
  30884. + if(num == 0)
  30885. + return 0xFFFFFFFF;
  30886. + while(num != 1)
  30887. + {
  30888. + num = num >> 1;
  30889. + result++;
  30890. + }
  30891. + return result;
  30892. +}
  30893. +
  30894. +
  30895. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvCommon.h
  30896. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvCommon.h 1970-01-01 01:00:00.000000000 +0100
  30897. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvCommon.h 2011-08-01 14:38:19.000000000 +0200
  30898. @@ -0,0 +1,308 @@
  30899. +/*******************************************************************************
  30900. +Copyright (C) Marvell International Ltd. and its affiliates
  30901. +
  30902. +This software file (the "File") is owned and distributed by Marvell
  30903. +International Ltd. and/or its affiliates ("Marvell") under the following
  30904. +alternative licensing terms. Once you have made an election to distribute the
  30905. +File under one of the following license alternatives, please (i) delete this
  30906. +introductory statement regarding license alternatives, (ii) delete the two
  30907. +license alternatives that you have not elected to use and (iii) preserve the
  30908. +Marvell copyright notice above.
  30909. +
  30910. +********************************************************************************
  30911. +Marvell Commercial License Option
  30912. +
  30913. +If you received this File from Marvell and you have entered into a commercial
  30914. +license agreement (a "Commercial License") with Marvell, the File is licensed
  30915. +to you under the terms of the applicable Commercial License.
  30916. +
  30917. +********************************************************************************
  30918. +Marvell GPL License Option
  30919. +
  30920. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30921. +modify this File in accordance with the terms and conditions of the General
  30922. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  30923. +available along with the File in the license.txt file or by writing to the Free
  30924. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  30925. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  30926. +
  30927. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  30928. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  30929. +DISCLAIMED. The GPL License provides additional details about this warranty
  30930. +disclaimer.
  30931. +********************************************************************************
  30932. +Marvell BSD License Option
  30933. +
  30934. +If you received this File from Marvell, you may opt to use, redistribute and/or
  30935. +modify this File under the following licensing terms.
  30936. +Redistribution and use in source and binary forms, with or without modification,
  30937. +are permitted provided that the following conditions are met:
  30938. +
  30939. + * Redistributions of source code must retain the above copyright notice,
  30940. + this list of conditions and the following disclaimer.
  30941. +
  30942. + * Redistributions in binary form must reproduce the above copyright
  30943. + notice, this list of conditions and the following disclaimer in the
  30944. + documentation and/or other materials provided with the distribution.
  30945. +
  30946. + * Neither the name of Marvell nor the names of its contributors may be
  30947. + used to endorse or promote products derived from this software without
  30948. + specific prior written permission.
  30949. +
  30950. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  30951. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  30952. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  30953. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  30954. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  30955. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  30956. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  30957. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  30958. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30959. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30960. +
  30961. +*******************************************************************************/
  30962. +
  30963. +
  30964. +
  30965. +#ifndef __INCmvCommonh
  30966. +#define __INCmvCommonh
  30967. +
  30968. +#include "mvTypes.h"
  30969. +
  30970. +/* Swap tool */
  30971. +
  30972. +/* 16bit nibble swap. For example 0x1234 -> 0x2143 */
  30973. +#define MV_NIBBLE_SWAP_16BIT(X) (((X&0xf) << 4) | \
  30974. + ((X&0xf0) >> 4) | \
  30975. + ((X&0xf00) << 4) | \
  30976. + ((X&0xf000) >> 4))
  30977. +
  30978. +/* 32bit nibble swap. For example 0x12345678 -> 0x21436587 */
  30979. +#define MV_NIBBLE_SWAP_32BIT(X) (((X&0xf) << 4) | \
  30980. + ((X&0xf0) >> 4) | \
  30981. + ((X&0xf00) << 4) | \
  30982. + ((X&0xf000) >> 4) | \
  30983. + ((X&0xf0000) << 4) | \
  30984. + ((X&0xf00000) >> 4) | \
  30985. + ((X&0xf000000) << 4) | \
  30986. + ((X&0xf0000000) >> 4))
  30987. +
  30988. +/* 16bit byte swap. For example 0x1122 -> 0x2211 */
  30989. +#define MV_BYTE_SWAP_16BIT(X) ((((X)&0xff)<<8) | (((X)&0xff00)>>8))
  30990. +
  30991. +/* 32bit byte swap. For example 0x11223344 -> 0x44332211 */
  30992. +#define MV_BYTE_SWAP_32BIT(X) ((((X)&0xff)<<24) | \
  30993. + (((X)&0xff00)<<8) | \
  30994. + (((X)&0xff0000)>>8) | \
  30995. + (((X)&0xff000000)>>24))
  30996. +
  30997. +/* 64bit byte swap. For example 0x11223344.55667788 -> 0x88776655.44332211 */
  30998. +#define MV_BYTE_SWAP_64BIT(X) ((l64) ((((X)&0xffULL)<<56) | \
  30999. + (((X)&0xff00ULL)<<40) | \
  31000. + (((X)&0xff0000ULL)<<24) | \
  31001. + (((X)&0xff000000ULL)<<8) | \
  31002. + (((X)&0xff00000000ULL)>>8) | \
  31003. + (((X)&0xff0000000000ULL)>>24) | \
  31004. + (((X)&0xff000000000000ULL)>>40) | \
  31005. + (((X)&0xff00000000000000ULL)>>56)))
  31006. +
  31007. +/* Endianess macros. */
  31008. +#if defined(MV_CPU_LE)
  31009. + #define MV_16BIT_LE(X) (X)
  31010. + #define MV_32BIT_LE(X) (X)
  31011. + #define MV_64BIT_LE(X) (X)
  31012. + #define MV_16BIT_BE(X) MV_BYTE_SWAP_16BIT(X)
  31013. + #define MV_32BIT_BE(X) MV_BYTE_SWAP_32BIT(X)
  31014. + #define MV_64BIT_BE(X) MV_BYTE_SWAP_64BIT(X)
  31015. +#elif defined(MV_CPU_BE)
  31016. + #define MV_16BIT_LE(X) MV_BYTE_SWAP_16BIT(X)
  31017. + #define MV_32BIT_LE(X) MV_BYTE_SWAP_32BIT(X)
  31018. + #define MV_64BIT_LE(X) MV_BYTE_SWAP_64BIT(X)
  31019. + #define MV_16BIT_BE(X) (X)
  31020. + #define MV_32BIT_BE(X) (X)
  31021. + #define MV_64BIT_BE(X) (X)
  31022. +#else
  31023. + #error "CPU endianess isn't defined!\n"
  31024. +#endif
  31025. +
  31026. +
  31027. +/* Bit field definitions */
  31028. +#define NO_BIT 0x00000000
  31029. +#define BIT0 0x00000001
  31030. +#define BIT1 0x00000002
  31031. +#define BIT2 0x00000004
  31032. +#define BIT3 0x00000008
  31033. +#define BIT4 0x00000010
  31034. +#define BIT5 0x00000020
  31035. +#define BIT6 0x00000040
  31036. +#define BIT7 0x00000080
  31037. +#define BIT8 0x00000100
  31038. +#define BIT9 0x00000200
  31039. +#define BIT10 0x00000400
  31040. +#define BIT11 0x00000800
  31041. +#define BIT12 0x00001000
  31042. +#define BIT13 0x00002000
  31043. +#define BIT14 0x00004000
  31044. +#define BIT15 0x00008000
  31045. +#define BIT16 0x00010000
  31046. +#define BIT17 0x00020000
  31047. +#define BIT18 0x00040000
  31048. +#define BIT19 0x00080000
  31049. +#define BIT20 0x00100000
  31050. +#define BIT21 0x00200000
  31051. +#define BIT22 0x00400000
  31052. +#define BIT23 0x00800000
  31053. +#define BIT24 0x01000000
  31054. +#define BIT25 0x02000000
  31055. +#define BIT26 0x04000000
  31056. +#define BIT27 0x08000000
  31057. +#define BIT28 0x10000000
  31058. +#define BIT29 0x20000000
  31059. +#define BIT30 0x40000000
  31060. +#define BIT31 0x80000000
  31061. +
  31062. +/* Handy sizes */
  31063. +#define _1K 0x00000400
  31064. +#define _2K 0x00000800
  31065. +#define _4K 0x00001000
  31066. +#define _8K 0x00002000
  31067. +#define _16K 0x00004000
  31068. +#define _32K 0x00008000
  31069. +#define _64K 0x00010000
  31070. +#define _128K 0x00020000
  31071. +#define _256K 0x00040000
  31072. +#define _512K 0x00080000
  31073. +
  31074. +#define _1M 0x00100000
  31075. +#define _2M 0x00200000
  31076. +#define _4M 0x00400000
  31077. +#define _8M 0x00800000
  31078. +#define _16M 0x01000000
  31079. +#define _32M 0x02000000
  31080. +#define _64M 0x04000000
  31081. +#define _128M 0x08000000
  31082. +#define _256M 0x10000000
  31083. +#define _512M 0x20000000
  31084. +
  31085. +#define _1G 0x40000000
  31086. +#define _2G 0x80000000
  31087. +
  31088. +/* Tclock and Sys clock define */
  31089. +#define _100MHz 100000000
  31090. +#define _125MHz 125000000
  31091. +#define _133MHz 133333334
  31092. +#define _150MHz 150000000
  31093. +#define _160MHz 160000000
  31094. +#define _166MHz 166666667
  31095. +#define _175MHz 175000000
  31096. +#define _178MHz 178000000
  31097. +#define _183MHz 183333334
  31098. +#define _187MHz 187000000
  31099. +#define _192MHz 192000000
  31100. +#define _194MHz 194000000
  31101. +#define _200MHz 200000000
  31102. +#define _233MHz 233333334
  31103. +#define _250MHz 250000000
  31104. +#define _266MHz 266666667
  31105. +#define _300MHz 300000000
  31106. +
  31107. +/* For better address window table readability */
  31108. +#define EN MV_TRUE
  31109. +#define DIS MV_FALSE
  31110. +#define N_A -1 /* Not applicable */
  31111. +
  31112. +/* Cache configuration options for memory (DRAM, SRAM, ... ) */
  31113. +
  31114. +/* Memory uncached, HW or SW cache coherency is not needed */
  31115. +#define MV_UNCACHED 0
  31116. +/* Memory cached, HW cache coherency supported in WriteThrough mode */
  31117. +#define MV_CACHE_COHER_HW_WT 1
  31118. +/* Memory cached, HW cache coherency supported in WriteBack mode */
  31119. +#define MV_CACHE_COHER_HW_WB 2
  31120. +/* Memory cached, No HW cache coherency, Cache coherency must be in SW */
  31121. +#define MV_CACHE_COHER_SW 3
  31122. +
  31123. +
  31124. +/* Macro for testing aligment. Positive if number is NOT aligned */
  31125. +#define MV_IS_NOT_ALIGN(number, align) ((number) & ((align) - 1))
  31126. +
  31127. +/* Macro for alignment up. For example, MV_ALIGN_UP(0x0330, 0x20) = 0x0340 */
  31128. +#define MV_ALIGN_UP(number, align) \
  31129. +(((number) & ((align) - 1)) ? (((number) + (align)) & ~((align)-1)) : (number))
  31130. +
  31131. +/* Macro for alignment down. For example, MV_ALIGN_UP(0x0330, 0x20) = 0x0320 */
  31132. +#define MV_ALIGN_DOWN(number, align) ((number) & ~((align)-1))
  31133. +
  31134. +/* This macro returns absolute value */
  31135. +#define MV_ABS(number) (((int)(number) < 0) ? -(int)(number) : (int)(number))
  31136. +
  31137. +
  31138. +/* Bit fields manipulation macros */
  31139. +
  31140. +/* An integer word which its 'x' bit is set */
  31141. +#define MV_BIT_MASK(bitNum) (1 << (bitNum) )
  31142. +
  31143. +/* Checks wheter bit 'x' in integer word is set */
  31144. +#define MV_BIT_CHECK(word, bitNum) ( (word) & MV_BIT_MASK(bitNum) )
  31145. +
  31146. +/* Clear (reset) bit 'x' in integer word (RMW - Read-Modify-Write) */
  31147. +#define MV_BIT_CLEAR(word, bitNum) ( (word) &= ~(MV_BIT_MASK(bitNum)) )
  31148. +
  31149. +/* Set bit 'x' in integer word (RMW) */
  31150. +#define MV_BIT_SET(word, bitNum) ( (word) |= MV_BIT_MASK(bitNum) )
  31151. +
  31152. +/* Invert bit 'x' in integer word (RMW) */
  31153. +#define MV_BIT_INV(word, bitNum) ( (word) ^= MV_BIT_MASK(bitNum) )
  31154. +
  31155. +/* Get the min between 'a' or 'b' */
  31156. +#define MV_MIN(a,b) (((a) < (b)) ? (a) : (b))
  31157. +
  31158. +/* Get the max between 'a' or 'b' */
  31159. +#define MV_MAX(a,b) (((a) < (b)) ? (b) : (a))
  31160. +
  31161. +/* Temporary */
  31162. +#define mvOsDivide(num, div) \
  31163. +({ \
  31164. + int i=0, rem=(num); \
  31165. + \
  31166. + while(rem >= (div)) \
  31167. + { \
  31168. + rem -= (div); \
  31169. + i++; \
  31170. + } \
  31171. + (i); \
  31172. +})
  31173. +
  31174. +/* Temporary */
  31175. +#define mvOsReminder(num, div) \
  31176. +({ \
  31177. + int rem = (num); \
  31178. + \
  31179. + while(rem >= (div)) \
  31180. + rem -= (div); \
  31181. + (rem); \
  31182. +})
  31183. +
  31184. +#define MV_IP_QUAD(ipAddr) ((ipAddr >> 24) & 0xFF), ((ipAddr >> 16) & 0xFF), \
  31185. + ((ipAddr >> 8) & 0xFF), ((ipAddr >> 0) & 0xFF)
  31186. +
  31187. +#define MV_IS_POWER_OF_2(num) ((num != 0) && ((num & (num - 1)) == 0))
  31188. +
  31189. +#ifndef MV_ASMLANGUAGE
  31190. +/* mvCommon API list */
  31191. +
  31192. +MV_VOID mvHexToBin(const char* pHexStr, MV_U8* pBin, int size);
  31193. +void mvAsciiToHex(const char* asciiStr, char* hexStr);
  31194. +void mvBinToHex(const MV_U8* bin, char* hexStr, int size);
  31195. +void mvBinToAscii(const MV_U8* bin, char* asciiStr, int size);
  31196. +
  31197. +MV_STATUS mvMacStrToHex(const char* macStr, MV_U8* macHex);
  31198. +MV_STATUS mvMacHexToStr(MV_U8* macHex, char* macStr);
  31199. +void mvSizePrint(MV_U32);
  31200. +
  31201. +MV_U32 mvLog2(MV_U32 num);
  31202. +
  31203. +#endif /* MV_ASMLANGUAGE */
  31204. +
  31205. +
  31206. +#endif /* __INCmvCommonh */
  31207. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvDebug.c
  31208. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.c 1970-01-01 01:00:00.000000000 +0100
  31209. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvDebug.c 2011-08-01 14:38:19.000000000 +0200
  31210. @@ -0,0 +1,326 @@
  31211. +/*******************************************************************************
  31212. +Copyright (C) Marvell International Ltd. and its affiliates
  31213. +
  31214. +This software file (the "File") is owned and distributed by Marvell
  31215. +International Ltd. and/or its affiliates ("Marvell") under the following
  31216. +alternative licensing terms. Once you have made an election to distribute the
  31217. +File under one of the following license alternatives, please (i) delete this
  31218. +introductory statement regarding license alternatives, (ii) delete the two
  31219. +license alternatives that you have not elected to use and (iii) preserve the
  31220. +Marvell copyright notice above.
  31221. +
  31222. +********************************************************************************
  31223. +Marvell Commercial License Option
  31224. +
  31225. +If you received this File from Marvell and you have entered into a commercial
  31226. +license agreement (a "Commercial License") with Marvell, the File is licensed
  31227. +to you under the terms of the applicable Commercial License.
  31228. +
  31229. +********************************************************************************
  31230. +Marvell GPL License Option
  31231. +
  31232. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31233. +modify this File in accordance with the terms and conditions of the General
  31234. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  31235. +available along with the File in the license.txt file or by writing to the Free
  31236. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  31237. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  31238. +
  31239. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  31240. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  31241. +DISCLAIMED. The GPL License provides additional details about this warranty
  31242. +disclaimer.
  31243. +********************************************************************************
  31244. +Marvell BSD License Option
  31245. +
  31246. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31247. +modify this File under the following licensing terms.
  31248. +Redistribution and use in source and binary forms, with or without modification,
  31249. +are permitted provided that the following conditions are met:
  31250. +
  31251. + * Redistributions of source code must retain the above copyright notice,
  31252. + this list of conditions and the following disclaimer.
  31253. +
  31254. + * Redistributions in binary form must reproduce the above copyright
  31255. + notice, this list of conditions and the following disclaimer in the
  31256. + documentation and/or other materials provided with the distribution.
  31257. +
  31258. + * Neither the name of Marvell nor the names of its contributors may be
  31259. + used to endorse or promote products derived from this software without
  31260. + specific prior written permission.
  31261. +
  31262. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  31263. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  31264. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31265. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  31266. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  31267. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  31268. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  31269. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31270. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31271. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31272. +
  31273. +*******************************************************************************/
  31274. +
  31275. +
  31276. +
  31277. +/* includes */
  31278. +#include "mvOs.h"
  31279. +#include "mv802_3.h"
  31280. +#include "mvCommon.h"
  31281. +#include "mvDebug.h"
  31282. +
  31283. +/* Global variables effect on behave MV_DEBUG_PRINT and MV_DEBUG_CODE macros
  31284. + * mvDebug - map of bits (one for each module) bit=1 means enable
  31285. + * debug code and messages for this module
  31286. + * mvModuleDebug - array of 32 bits varables one for each module
  31287. + */
  31288. +MV_U32 mvDebug = 0;
  31289. +MV_U32 mvDebugModules[MV_MODULE_MAX];
  31290. +
  31291. +/* Init mvModuleDebug array to default values */
  31292. +void mvDebugInit(void)
  31293. +{
  31294. + int bit;
  31295. +
  31296. + mvDebug = 0;
  31297. + for(bit=0; bit<MV_MODULE_MAX; bit++)
  31298. + {
  31299. + mvDebugModules[bit] = MV_DEBUG_FLAG_ERR | MV_DEBUG_FLAG_STATS;
  31300. + mvDebug |= MV_BIT_MASK(bit);
  31301. + }
  31302. +}
  31303. +
  31304. +void mvDebugModuleEnable(MV_MODULE_ID module, MV_BOOL isEnable)
  31305. +{
  31306. + if (isEnable)
  31307. + {
  31308. + MV_BIT_SET(mvDebug, module);
  31309. + }
  31310. + else
  31311. + MV_BIT_CLEAR(mvDebug, module);
  31312. +}
  31313. +
  31314. +void mvDebugModuleSetFlags(MV_MODULE_ID module, MV_U32 flags)
  31315. +{
  31316. + mvDebugModules[module] |= flags;
  31317. +}
  31318. +
  31319. +void mvDebugModuleClearFlags(MV_MODULE_ID module, MV_U32 flags)
  31320. +{
  31321. + mvDebugModules[module] &= ~flags;
  31322. +}
  31323. +
  31324. +/* Dump memory in specific format:
  31325. + * address: X1X1X1X1 X2X2X2X2 ... X8X8X8X8
  31326. + */
  31327. +void mvDebugMemDump(void* addr, int size, int access)
  31328. +{
  31329. + int i, j;
  31330. + MV_U32 memAddr = (MV_U32)addr;
  31331. +
  31332. + if(access == 0)
  31333. + access = 1;
  31334. +
  31335. + if( (access != 4) && (access != 2) && (access != 1) )
  31336. + {
  31337. + mvOsPrintf("%d wrong access size. Access must be 1 or 2 or 4\n",
  31338. + access);
  31339. + return;
  31340. + }
  31341. + memAddr = MV_ALIGN_DOWN( (unsigned int)addr, 4);
  31342. + size = MV_ALIGN_UP(size, 4);
  31343. + addr = (void*)MV_ALIGN_DOWN( (unsigned int)addr, access);
  31344. + while(size > 0)
  31345. + {
  31346. + mvOsPrintf("%08x: ", memAddr);
  31347. + i = 0;
  31348. + /* 32 bytes in the line */
  31349. + while(i < 32)
  31350. + {
  31351. + if(memAddr >= (MV_U32)addr)
  31352. + {
  31353. + switch(access)
  31354. + {
  31355. + case 1:
  31356. + if( memAddr == CPU_PHY_MEM(memAddr) )
  31357. + {
  31358. + mvOsPrintf("%02x ", MV_MEMIO8_READ(memAddr));
  31359. + }
  31360. + else
  31361. + {
  31362. + mvOsPrintf("%02x ", *((MV_U8*)memAddr));
  31363. + }
  31364. + break;
  31365. +
  31366. + case 2:
  31367. + if( memAddr == CPU_PHY_MEM(memAddr) )
  31368. + {
  31369. + mvOsPrintf("%04x ", MV_MEMIO16_READ(memAddr));
  31370. + }
  31371. + else
  31372. + {
  31373. + mvOsPrintf("%04x ", *((MV_U16*)memAddr));
  31374. + }
  31375. + break;
  31376. +
  31377. + case 4:
  31378. + if( memAddr == CPU_PHY_MEM(memAddr) )
  31379. + {
  31380. + mvOsPrintf("%08x ", MV_MEMIO32_READ(memAddr));
  31381. + }
  31382. + else
  31383. + {
  31384. + mvOsPrintf("%08x ", *((MV_U32*)memAddr));
  31385. + }
  31386. + break;
  31387. + }
  31388. + }
  31389. + else
  31390. + {
  31391. + for(j=0; j<(access*2+1); j++)
  31392. + mvOsPrintf(" ");
  31393. + }
  31394. + i += access;
  31395. + memAddr += access;
  31396. + size -= access;
  31397. + if(size <= 0)
  31398. + break;
  31399. + }
  31400. + mvOsPrintf("\n");
  31401. + }
  31402. +}
  31403. +
  31404. +void mvDebugPrintBufInfo(BUF_INFO* pBufInfo, int size, int access)
  31405. +{
  31406. + if(pBufInfo == NULL)
  31407. + {
  31408. + mvOsPrintf("\n!!! pBufInfo = NULL\n");
  31409. + return;
  31410. + }
  31411. + mvOsPrintf("\n*** pBufInfo=0x%x, cmdSts=0x%08x, pBuf=0x%x, bufSize=%d\n",
  31412. + (unsigned int)pBufInfo,
  31413. + (unsigned int)pBufInfo->cmdSts,
  31414. + (unsigned int)pBufInfo->pBuff,
  31415. + (unsigned int)pBufInfo->bufSize);
  31416. + mvOsPrintf("pData=0x%x, byteCnt=%d, pNext=0x%x, uInfo1=0x%x, uInfo2=0x%x\n",
  31417. + (unsigned int)pBufInfo->pData,
  31418. + (unsigned int)pBufInfo->byteCnt,
  31419. + (unsigned int)pBufInfo->pNextBufInfo,
  31420. + (unsigned int)pBufInfo->userInfo1,
  31421. + (unsigned int)pBufInfo->userInfo2);
  31422. + if(pBufInfo->pData != NULL)
  31423. + {
  31424. + if(size > pBufInfo->byteCnt)
  31425. + size = pBufInfo->byteCnt;
  31426. + mvDebugMemDump(pBufInfo->pData, size, access);
  31427. + }
  31428. +}
  31429. +
  31430. +void mvDebugPrintPktInfo(MV_PKT_INFO* pPktInfo, int size, int access)
  31431. +{
  31432. + int frag, len;
  31433. +
  31434. + if(pPktInfo == NULL)
  31435. + {
  31436. + mvOsPrintf("\n!!! pPktInfo = NULL\n");
  31437. + return;
  31438. + }
  31439. + mvOsPrintf("\npPkt=%p, stat=0x%08x, numFr=%d, size=%d, pFr=%p, osInfo=0x%lx\n",
  31440. + pPktInfo, pPktInfo->status, pPktInfo->numFrags, pPktInfo->pktSize,
  31441. + pPktInfo->pFrags, pPktInfo->osInfo);
  31442. +
  31443. + for(frag=0; frag<pPktInfo->numFrags; frag++)
  31444. + {
  31445. + mvOsPrintf("#%2d. bufVirt=%p, bufSize=%d\n",
  31446. + frag, pPktInfo->pFrags[frag].bufVirtPtr,
  31447. + pPktInfo->pFrags[frag].bufSize);
  31448. + if(size > 0)
  31449. + {
  31450. + len = MV_MIN((int)pPktInfo->pFrags[frag].bufSize, size);
  31451. + mvDebugMemDump(pPktInfo->pFrags[frag].bufVirtPtr, len, access);
  31452. + size -= len;
  31453. + }
  31454. + }
  31455. +
  31456. +}
  31457. +
  31458. +void mvDebugPrintIpAddr(MV_U32 ipAddr)
  31459. +{
  31460. + mvOsPrintf("%d.%d.%d.%d", ((ipAddr >> 24) & 0xFF), ((ipAddr >> 16) & 0xFF),
  31461. + ((ipAddr >> 8) & 0xFF), ((ipAddr >> 0) & 0xFF));
  31462. +}
  31463. +
  31464. +void mvDebugPrintMacAddr(const MV_U8* pMacAddr)
  31465. +{
  31466. + int i;
  31467. +
  31468. + mvOsPrintf("%02x", (unsigned int)pMacAddr[0]);
  31469. + for(i=1; i<MV_MAC_ADDR_SIZE; i++)
  31470. + {
  31471. + mvOsPrintf(":%02x", pMacAddr[i]);
  31472. + }
  31473. + /* mvOsPrintf("\n");*/
  31474. +}
  31475. +
  31476. +
  31477. +/******* There are three functions deals with MV_DEBUG_TIMES structure ********/
  31478. +
  31479. +/* Reset MV_DEBUG_TIMES entry */
  31480. +void mvDebugResetTimeEntry(MV_DEBUG_TIMES* pTimeEntry, int count, char* pName)
  31481. +{
  31482. + pTimeEntry->begin = 0;
  31483. + pTimeEntry->count = count;
  31484. + pTimeEntry->end = 0;
  31485. + pTimeEntry->left = pTimeEntry->count;
  31486. + pTimeEntry->total = 0;
  31487. + pTimeEntry->min = 0xFFFFFFFF;
  31488. + pTimeEntry->max = 0x0;
  31489. + strncpy(pTimeEntry->name, pName, sizeof(pTimeEntry->name)-1);
  31490. + pTimeEntry->name[sizeof(pTimeEntry->name)-1] = '\0';
  31491. +}
  31492. +
  31493. +/* Print out MV_DEBUG_TIMES entry */
  31494. +void mvDebugPrintTimeEntry(MV_DEBUG_TIMES* pTimeEntry, MV_BOOL isTitle)
  31495. +{
  31496. + int num;
  31497. +
  31498. + if(isTitle == MV_TRUE)
  31499. + mvOsPrintf("Event NumOfEvents TotalTime Average Min Max\n");
  31500. +
  31501. + num = pTimeEntry->count-pTimeEntry->left;
  31502. + if(num > 0)
  31503. + {
  31504. + mvOsPrintf("%-11s %6u 0x%08lx %6lu %6lu %6lu\n",
  31505. + pTimeEntry->name, num, pTimeEntry->total, pTimeEntry->total/num,
  31506. + pTimeEntry->min, pTimeEntry->max);
  31507. + }
  31508. +}
  31509. +
  31510. +/* Update MV_DEBUG_TIMES entry */
  31511. +void mvDebugUpdateTimeEntry(MV_DEBUG_TIMES* pTimeEntry)
  31512. +{
  31513. + MV_U32 delta;
  31514. +
  31515. + if(pTimeEntry->left > 0)
  31516. + {
  31517. + if(pTimeEntry->end <= pTimeEntry->begin)
  31518. + {
  31519. + delta = pTimeEntry->begin - pTimeEntry->end;
  31520. + }
  31521. + else
  31522. + {
  31523. + delta = ((MV_U32)0x10000 - pTimeEntry->end) + pTimeEntry->begin;
  31524. + }
  31525. + pTimeEntry->total += delta;
  31526. +
  31527. + if(delta < pTimeEntry->min)
  31528. + pTimeEntry->min = delta;
  31529. +
  31530. + if(delta > pTimeEntry->max)
  31531. + pTimeEntry->max = delta;
  31532. +
  31533. + pTimeEntry->left--;
  31534. + }
  31535. +}
  31536. +
  31537. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvDebug.h
  31538. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvDebug.h 1970-01-01 01:00:00.000000000 +0100
  31539. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvDebug.h 2011-08-01 14:38:19.000000000 +0200
  31540. @@ -0,0 +1,178 @@
  31541. +/*******************************************************************************
  31542. +Copyright (C) Marvell International Ltd. and its affiliates
  31543. +
  31544. +This software file (the "File") is owned and distributed by Marvell
  31545. +International Ltd. and/or its affiliates ("Marvell") under the following
  31546. +alternative licensing terms. Once you have made an election to distribute the
  31547. +File under one of the following license alternatives, please (i) delete this
  31548. +introductory statement regarding license alternatives, (ii) delete the two
  31549. +license alternatives that you have not elected to use and (iii) preserve the
  31550. +Marvell copyright notice above.
  31551. +
  31552. +********************************************************************************
  31553. +Marvell Commercial License Option
  31554. +
  31555. +If you received this File from Marvell and you have entered into a commercial
  31556. +license agreement (a "Commercial License") with Marvell, the File is licensed
  31557. +to you under the terms of the applicable Commercial License.
  31558. +
  31559. +********************************************************************************
  31560. +Marvell GPL License Option
  31561. +
  31562. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31563. +modify this File in accordance with the terms and conditions of the General
  31564. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  31565. +available along with the File in the license.txt file or by writing to the Free
  31566. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  31567. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  31568. +
  31569. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  31570. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  31571. +DISCLAIMED. The GPL License provides additional details about this warranty
  31572. +disclaimer.
  31573. +********************************************************************************
  31574. +Marvell BSD License Option
  31575. +
  31576. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31577. +modify this File under the following licensing terms.
  31578. +Redistribution and use in source and binary forms, with or without modification,
  31579. +are permitted provided that the following conditions are met:
  31580. +
  31581. + * Redistributions of source code must retain the above copyright notice,
  31582. + this list of conditions and the following disclaimer.
  31583. +
  31584. + * Redistributions in binary form must reproduce the above copyright
  31585. + notice, this list of conditions and the following disclaimer in the
  31586. + documentation and/or other materials provided with the distribution.
  31587. +
  31588. + * Neither the name of Marvell nor the names of its contributors may be
  31589. + used to endorse or promote products derived from this software without
  31590. + specific prior written permission.
  31591. +
  31592. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  31593. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  31594. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31595. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  31596. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  31597. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  31598. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  31599. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31600. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31601. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31602. +
  31603. +*******************************************************************************/
  31604. +
  31605. +
  31606. +
  31607. +#ifndef __INCmvDebugh
  31608. +#define __INCmvDebugh
  31609. +
  31610. +/* includes */
  31611. +#include "mvTypes.h"
  31612. +
  31613. +typedef enum
  31614. +{
  31615. + MV_MODULE_INVALID = -1,
  31616. + MV_MODULE_ETH = 0,
  31617. + MV_MODULE_IDMA,
  31618. + MV_MODULE_XOR,
  31619. + MV_MODULE_TWASI,
  31620. + MV_MODULE_MGI,
  31621. + MV_MODULE_USB,
  31622. + MV_MODULE_CESA,
  31623. +
  31624. + MV_MODULE_MAX
  31625. +}MV_MODULE_ID;
  31626. +
  31627. +/* Define generic flags useful for most of modules */
  31628. +#define MV_DEBUG_FLAG_ALL (0)
  31629. +#define MV_DEBUG_FLAG_INIT (1 << 0)
  31630. +#define MV_DEBUG_FLAG_RX (1 << 1)
  31631. +#define MV_DEBUG_FLAG_TX (1 << 2)
  31632. +#define MV_DEBUG_FLAG_ERR (1 << 3)
  31633. +#define MV_DEBUG_FLAG_TRACE (1 << 4)
  31634. +#define MV_DEBUG_FLAG_DUMP (1 << 5)
  31635. +#define MV_DEBUG_FLAG_CACHE (1 << 6)
  31636. +#define MV_DEBUG_FLAG_IOCTL (1 << 7)
  31637. +#define MV_DEBUG_FLAG_STATS (1 << 8)
  31638. +
  31639. +extern MV_U32 mvDebug;
  31640. +extern MV_U32 mvDebugModules[MV_MODULE_MAX];
  31641. +
  31642. +#ifdef MV_DEBUG
  31643. +# define MV_DEBUG_PRINT(module, flags, msg) mvOsPrintf msg
  31644. +# define MV_DEBUG_CODE(module, flags, code) code
  31645. +#elif defined(MV_RT_DEBUG)
  31646. +# define MV_DEBUG_PRINT(module, flags, msg) \
  31647. + if( (mvDebug & (1<<(module))) && \
  31648. + ((mvDebugModules[(module)] & (flags)) == (flags)) ) \
  31649. + mvOsPrintf msg
  31650. +# define MV_DEBUG_CODE(module, flags, code) \
  31651. + if( (mvDebug & (1<<(module))) && \
  31652. + ((mvDebugModules[(module)] & (flags)) == (flags)) ) \
  31653. + code
  31654. +#else
  31655. +# define MV_DEBUG_PRINT(module, flags, msg)
  31656. +# define MV_DEBUG_CODE(module, flags, code)
  31657. +#endif
  31658. +
  31659. +
  31660. +
  31661. +/* typedefs */
  31662. +
  31663. +/* time measurement structure used to check how much time pass between
  31664. + * two points
  31665. + */
  31666. +typedef struct {
  31667. + char name[20]; /* name of the entry */
  31668. + unsigned long begin; /* time measured on begin point */
  31669. + unsigned long end; /* time measured on end point */
  31670. + unsigned long total; /* Accumulated time */
  31671. + unsigned long left; /* The rest measurement actions */
  31672. + unsigned long count; /* Maximum measurement actions */
  31673. + unsigned long min; /* Minimum time from begin to end */
  31674. + unsigned long max; /* Maximum time from begin to end */
  31675. +} MV_DEBUG_TIMES;
  31676. +
  31677. +
  31678. +/* mvDebug.h API list */
  31679. +
  31680. +/****** Error Recording ******/
  31681. +
  31682. +/* Dump memory in specific format:
  31683. + * address: X1X1X1X1 X2X2X2X2 ... X8X8X8X8
  31684. + */
  31685. +void mvDebugMemDump(void* addr, int size, int access);
  31686. +
  31687. +void mvDebugPrintBufInfo(BUF_INFO* pBufInfo, int size, int access);
  31688. +
  31689. +void mvDebugPrintPktInfo(MV_PKT_INFO* pPktInfo, int size, int access);
  31690. +
  31691. +void mvDebugPrintIpAddr(MV_U32 ipAddr);
  31692. +
  31693. +void mvDebugPrintMacAddr(const MV_U8* pMacAddr);
  31694. +
  31695. +/**** There are three functions deals with MV_DEBUG_TIMES structure ****/
  31696. +
  31697. +/* Reset MV_DEBUG_TIMES entry */
  31698. +void mvDebugResetTimeEntry(MV_DEBUG_TIMES* pTimeEntry, int count, char* name);
  31699. +
  31700. +/* Update MV_DEBUG_TIMES entry */
  31701. +void mvDebugUpdateTimeEntry(MV_DEBUG_TIMES* pTimeEntry);
  31702. +
  31703. +/* Print out MV_DEBUG_TIMES entry */
  31704. +void mvDebugPrintTimeEntry(MV_DEBUG_TIMES* pTimeEntry, MV_BOOL isTitle);
  31705. +
  31706. +
  31707. +/******** General ***********/
  31708. +
  31709. +/* Change value of mvDebugPrint global variable */
  31710. +
  31711. +void mvDebugInit(void);
  31712. +void mvDebugModuleEnable(MV_MODULE_ID module, MV_BOOL isEnable);
  31713. +void mvDebugModuleSetFlags(MV_MODULE_ID module, MV_U32 flags);
  31714. +void mvDebugModuleClearFlags(MV_MODULE_ID module, MV_U32 flags);
  31715. +
  31716. +
  31717. +#endif /* __INCmvDebug.h */
  31718. +
  31719. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h
  31720. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h 1970-01-01 01:00:00.000000000 +0100
  31721. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvDeviceId.h 2011-08-01 14:38:19.000000000 +0200
  31722. @@ -0,0 +1,225 @@
  31723. +/*******************************************************************************
  31724. +Copyright (C) Marvell International Ltd. and its affiliates
  31725. +
  31726. +This software file (the "File") is owned and distributed by Marvell
  31727. +International Ltd. and/or its affiliates ("Marvell") under the following
  31728. +alternative licensing terms. Once you have made an election to distribute the
  31729. +File under one of the following license alternatives, please (i) delete this
  31730. +introductory statement regarding license alternatives, (ii) delete the two
  31731. +license alternatives that you have not elected to use and (iii) preserve the
  31732. +Marvell copyright notice above.
  31733. +
  31734. +********************************************************************************
  31735. +Marvell Commercial License Option
  31736. +
  31737. +If you received this File from Marvell and you have entered into a commercial
  31738. +license agreement (a "Commercial License") with Marvell, the File is licensed
  31739. +to you under the terms of the applicable Commercial License.
  31740. +
  31741. +********************************************************************************
  31742. +Marvell GPL License Option
  31743. +
  31744. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31745. +modify this File in accordance with the terms and conditions of the General
  31746. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  31747. +available along with the File in the license.txt file or by writing to the Free
  31748. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  31749. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  31750. +
  31751. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  31752. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  31753. +DISCLAIMED. The GPL License provides additional details about this warranty
  31754. +disclaimer.
  31755. +********************************************************************************
  31756. +Marvell BSD License Option
  31757. +
  31758. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31759. +modify this File under the following licensing terms.
  31760. +Redistribution and use in source and binary forms, with or without modification,
  31761. +are permitted provided that the following conditions are met:
  31762. +
  31763. + * Redistributions of source code must retain the above copyright notice,
  31764. + this list of conditions and the following disclaimer.
  31765. +
  31766. + * Redistributions in binary form must reproduce the above copyright
  31767. + notice, this list of conditions and the following disclaimer in the
  31768. + documentation and/or other materials provided with the distribution.
  31769. +
  31770. + * Neither the name of Marvell nor the names of its contributors may be
  31771. + used to endorse or promote products derived from this software without
  31772. + specific prior written permission.
  31773. +
  31774. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  31775. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  31776. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31777. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  31778. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  31779. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  31780. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  31781. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  31782. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  31783. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31784. +
  31785. +*******************************************************************************/
  31786. +
  31787. +#ifndef __INCmvDeviceIdh
  31788. +#define __INCmvDeviceIdh
  31789. +
  31790. +#ifdef __cplusplus
  31791. +extern "C" {
  31792. +#endif /* __cplusplus */
  31793. +
  31794. +/* defines */
  31795. +#define MARVELL_VEN_ID 0x11ab
  31796. +
  31797. +/* Disco-3 */
  31798. +#define MV64460_DEV_ID 0x6480
  31799. +#define MV64460B_DEV_ID 0x6485
  31800. +#define MV64430_DEV_ID 0x6420
  31801. +
  31802. +/* Disco-5 */
  31803. +#define MV64560_DEV_ID 0x6450
  31804. +
  31805. +/* Disco-6 */
  31806. +#define MV64660_DEV_ID 0x6460
  31807. +
  31808. +/* Orion */
  31809. +#define MV_1181_DEV_ID 0x1181
  31810. +#define MV_5181_DEV_ID 0x5181
  31811. +#define MV_5281_DEV_ID 0x5281
  31812. +#define MV_5182_DEV_ID 0x5182
  31813. +#define MV_8660_DEV_ID 0x8660
  31814. +#define MV_5180_DEV_ID 0x5180
  31815. +#define MV_5082_DEV_ID 0x5082
  31816. +#define MV_1281_DEV_ID 0x1281
  31817. +#define MV_6082_DEV_ID 0x6082
  31818. +#define MV_6183_DEV_ID 0x6183
  31819. +#define MV_6183L_DEV_ID 0x6083
  31820. +
  31821. +#define MV_5281_D0_REV 0x4
  31822. +#define MV_5281_D0_ID ((MV_5281_DEV_ID << 16) | MV_5281_D0_REV)
  31823. +#define MV_5281_D0_NAME "88F5281 D0"
  31824. +
  31825. +#define MV_5281_D1_REV 0x5
  31826. +#define MV_5281_D1_ID ((MV_5281_DEV_ID << 16) | MV_5281_D1_REV)
  31827. +#define MV_5281_D1_NAME "88F5281 D1"
  31828. +
  31829. +#define MV_5281_D2_REV 0x6
  31830. +#define MV_5281_D2_ID ((MV_5281_DEV_ID << 16) | MV_5281_D2_REV)
  31831. +#define MV_5281_D2_NAME "88F5281 D2"
  31832. +
  31833. +
  31834. +#define MV_5181L_A0_REV 0x8 /* need for PCIE Er */
  31835. +#define MV_5181_A1_REV 0x1 /* for USB Er ..*/
  31836. +#define MV_5181_B0_REV 0x2
  31837. +#define MV_5181_B1_REV 0x3
  31838. +#define MV_5182_A1_REV 0x1
  31839. +#define MV_5180N_B1_REV 0x3
  31840. +#define MV_5181L_A0_ID ((MV_5181_DEV_ID << 16) | MV_5181L_A0_REV)
  31841. +
  31842. +
  31843. +
  31844. +/* kw */
  31845. +#define MV_6281_DEV_ID 0x6281
  31846. +#define MV_6192_DEV_ID 0x6192
  31847. +#define MV_6190_DEV_ID 0x6190
  31848. +#define MV_6180_DEV_ID 0x6180
  31849. +
  31850. +#define MV_6281_A0_REV 0x2
  31851. +#define MV_6281_A0_ID ((MV_6281_DEV_ID << 16) | MV_6281_A0_REV)
  31852. +#define MV_6281_A0_NAME "88F6281 A0"
  31853. +
  31854. +#define MV_6192_A0_REV 0x2
  31855. +#define MV_6192_A0_ID ((MV_6192_DEV_ID << 16) | MV_6192_A0_REV)
  31856. +#define MV_6192_A0_NAME "88F6192 A0"
  31857. +
  31858. +#define MV_6190_A0_REV 0x2
  31859. +#define MV_6190_A0_ID ((MV_6190_DEV_ID << 16) | MV_6190_A0_REV)
  31860. +#define MV_6190_A0_NAME "88F6190 A0"
  31861. +
  31862. +#define MV_6180_A0_REV 0x2
  31863. +#define MV_6180_A0_ID ((MV_6180_DEV_ID << 16) | MV_6180_A0_REV)
  31864. +#define MV_6180_A0_NAME "88F6180 A0"
  31865. +
  31866. +#define MV_6281_A1_REV 0x3
  31867. +#define MV_6281_A1_ID ((MV_6281_DEV_ID << 16) | MV_6281_A1_REV)
  31868. +#define MV_6281_A1_NAME "88F6281 A1"
  31869. +
  31870. +#define MV_6192_A1_REV 0x3
  31871. +#define MV_6192_A1_ID ((MV_6192_DEV_ID << 16) | MV_6192_A1_REV)
  31872. +#define MV_6192_A1_NAME "88F6192 A1"
  31873. +
  31874. +#define MV_6190_A1_REV 0x3
  31875. +#define MV_6190_A1_ID ((MV_6190_DEV_ID << 16) | MV_6190_A1_REV)
  31876. +#define MV_6190_A1_NAME "88F6190 A1"
  31877. +
  31878. +#define MV_6180_A1_REV 0x3
  31879. +#define MV_6180_A1_ID ((MV_6180_DEV_ID << 16) | MV_6180_A1_REV)
  31880. +#define MV_6180_A1_NAME "88F6180 A1"
  31881. +
  31882. +#define MV_88F6XXX_A0_REV 0x2
  31883. +#define MV_88F6XXX_A1_REV 0x3
  31884. +/* Disco-Duo */
  31885. +#define MV_78XX0_ZY_DEV_ID 0x6381
  31886. +#define MV_78XX0_ZY_NAME "MV78X00"
  31887. +
  31888. +#define MV_78XX0_Z0_REV 0x1
  31889. +#define MV_78XX0_Z0_ID ((MV_78XX0_ZY_DEV_ID << 16) | MV_78XX0_Z0_REV)
  31890. +#define MV_78XX0_Z0_NAME "78X00 Z0"
  31891. +
  31892. +#define MV_78XX0_Y0_REV 0x2
  31893. +#define MV_78XX0_Y0_ID ((MV_78XX0_ZY_DEV_ID << 16) | MV_78XX0_Y0_REV)
  31894. +#define MV_78XX0_Y0_NAME "78X00 Y0"
  31895. +
  31896. +#define MV_78XX0_DEV_ID 0x7800
  31897. +#define MV_78XX0_NAME "MV78X00"
  31898. +
  31899. +#define MV_76100_DEV_ID 0x7610
  31900. +#define MV_78200_DEV_ID 0x7820
  31901. +#define MV_78100_DEV_ID 0x7810
  31902. +#define MV_78XX0_A0_REV 0x1
  31903. +#define MV_78XX0_A1_REV 0x2
  31904. +
  31905. +#define MV_76100_NAME "MV76100"
  31906. +#define MV_78100_NAME "MV78100"
  31907. +#define MV_78200_NAME "MV78200"
  31908. +
  31909. +#define MV_76100_A0_ID ((MV_76100_DEV_ID << 16) | MV_78XX0_A0_REV)
  31910. +#define MV_78100_A0_ID ((MV_78100_DEV_ID << 16) | MV_78XX0_A0_REV)
  31911. +#define MV_78200_A0_ID ((MV_78200_DEV_ID << 16) | MV_78XX0_A0_REV)
  31912. +
  31913. +#define MV_76100_A1_ID ((MV_76100_DEV_ID << 16) | MV_78XX0_A1_REV)
  31914. +#define MV_78100_A1_ID ((MV_78100_DEV_ID << 16) | MV_78XX0_A1_REV)
  31915. +#define MV_78200_A1_ID ((MV_78200_DEV_ID << 16) | MV_78XX0_A1_REV)
  31916. +
  31917. +#define MV_76100_A0_NAME "MV76100 A0"
  31918. +#define MV_78100_A0_NAME "MV78100 A0"
  31919. +#define MV_78200_A0_NAME "MV78200 A0"
  31920. +#define MV_78XX0_A0_NAME "MV78XX0 A0"
  31921. +
  31922. +#define MV_76100_A1_NAME "MV76100 A1"
  31923. +#define MV_78100_A1_NAME "MV78100 A1"
  31924. +#define MV_78200_A1_NAME "MV78200 A1"
  31925. +#define MV_78XX0_A1_NAME "MV78XX0 A1"
  31926. +
  31927. +/*MV88F632X family*/
  31928. +#define MV_6321_DEV_ID 0x6321
  31929. +#define MV_6322_DEV_ID 0x6322
  31930. +#define MV_6323_DEV_ID 0x6323
  31931. +
  31932. +#define MV_6321_NAME "88F6321"
  31933. +#define MV_6322_NAME "88F6322"
  31934. +#define MV_6323_NAME "88F6323"
  31935. +
  31936. +#define MV_632X_A1_REV 0x2
  31937. +
  31938. +#define MV_6321_A1_ID ((MV_6321_DEV_ID << 16) | MV_632X_A1_REV)
  31939. +#define MV_6322_A1_ID ((MV_6322_DEV_ID << 16) | MV_632X_A1_REV)
  31940. +#define MV_6323_A1_ID ((MV_6323_DEV_ID << 16) | MV_632X_A1_REV)
  31941. +
  31942. +#define MV_6321_A1_NAME "88F6321 A1"
  31943. +#define MV_6322_A1_NAME "88F6322 A1"
  31944. +#define MV_6323_A1_NAME "88F6323 A1"
  31945. +
  31946. +
  31947. +#endif /* __INCmvDeviceIdh */
  31948. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h
  31949. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h 1970-01-01 01:00:00.000000000 +0100
  31950. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvHalVer.h 2011-08-01 14:38:19.000000000 +0200
  31951. @@ -0,0 +1,73 @@
  31952. +/*******************************************************************************
  31953. +Copyright (C) Marvell International Ltd. and its affiliates
  31954. +
  31955. +This software file (the "File") is owned and distributed by Marvell
  31956. +International Ltd. and/or its affiliates ("Marvell") under the following
  31957. +alternative licensing terms. Once you have made an election to distribute the
  31958. +File under one of the following license alternatives, please (i) delete this
  31959. +introductory statement regarding license alternatives, (ii) delete the two
  31960. +license alternatives that you have not elected to use and (iii) preserve the
  31961. +Marvell copyright notice above.
  31962. +
  31963. +********************************************************************************
  31964. +Marvell Commercial License Option
  31965. +
  31966. +If you received this File from Marvell and you have entered into a commercial
  31967. +license agreement (a "Commercial License") with Marvell, the File is licensed
  31968. +to you under the terms of the applicable Commercial License.
  31969. +
  31970. +********************************************************************************
  31971. +Marvell GPL License Option
  31972. +
  31973. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31974. +modify this File in accordance with the terms and conditions of the General
  31975. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  31976. +available along with the File in the license.txt file or by writing to the Free
  31977. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  31978. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  31979. +
  31980. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  31981. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  31982. +DISCLAIMED. The GPL License provides additional details about this warranty
  31983. +disclaimer.
  31984. +********************************************************************************
  31985. +Marvell BSD License Option
  31986. +
  31987. +If you received this File from Marvell, you may opt to use, redistribute and/or
  31988. +modify this File under the following licensing terms.
  31989. +Redistribution and use in source and binary forms, with or without modification,
  31990. +are permitted provided that the following conditions are met:
  31991. +
  31992. + * Redistributions of source code must retain the above copyright notice,
  31993. + this list of conditions and the following disclaimer.
  31994. +
  31995. + * Redistributions in binary form must reproduce the above copyright
  31996. + notice, this list of conditions and the following disclaimer in the
  31997. + documentation and/or other materials provided with the distribution.
  31998. +
  31999. + * Neither the name of Marvell nor the names of its contributors may be
  32000. + used to endorse or promote products derived from this software without
  32001. + specific prior written permission.
  32002. +
  32003. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  32004. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  32005. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  32006. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  32007. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  32008. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  32009. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  32010. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  32011. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32012. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32013. +
  32014. +*******************************************************************************/
  32015. +
  32016. +
  32017. +#ifndef __INCmvHalVerh
  32018. +#define __INCmvHalVerh
  32019. +
  32020. +/* Defines */
  32021. +#define MV_HAL_VERSION "FEROCEON_HAL_3_1_7"
  32022. +#define MV_RELEASE_BASELINE "SoCandControllers_FEROCEON_RELEASE_7_9_2009_KW_4_3_4_DD_2_1_4_6183_1_1_4"
  32023. +
  32024. +#endif /* __INCmvHalVerh */
  32025. \ No newline at end of file
  32026. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvStack.c
  32027. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.c 1970-01-01 01:00:00.000000000 +0100
  32028. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvStack.c 2011-08-01 14:38:19.000000000 +0200
  32029. @@ -0,0 +1,100 @@
  32030. +/*******************************************************************************
  32031. +* Copyright 2003, Marvell Semiconductor Israel LTD. *
  32032. +* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL. *
  32033. +* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT *
  32034. +* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE *
  32035. +* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL. *
  32036. +* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED, *
  32037. +* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE. *
  32038. +* *
  32039. +* MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES, *
  32040. +* MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL *
  32041. +* SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K. *
  32042. +* (MJKK), MARVELL SEMICONDUCTOR ISRAEL LTD (MSIL). *
  32043. +********************************************************************************
  32044. +* mvQueue.c
  32045. +*
  32046. +* FILENAME: $Workfile: mvStack.c $
  32047. +* REVISION: $Revision: 1.1 $
  32048. +* LAST UPDATE: $Modtime: $
  32049. +*
  32050. +* DESCRIPTION:
  32051. +* This file implements simple Stack LIFO functionality.
  32052. +*******************************************************************************/
  32053. +
  32054. +/* includes */
  32055. +#include "mvOs.h"
  32056. +#include "mvTypes.h"
  32057. +#include "mvDebug.h"
  32058. +#include "mvStack.h"
  32059. +
  32060. +/* defines */
  32061. +
  32062. +
  32063. +/* Public functions */
  32064. +
  32065. +
  32066. +/* Purpose: Create new stack
  32067. + * Inputs:
  32068. + * - MV_U32 noOfElements - maximum number of elements in the stack.
  32069. + * Each element 4 bytes size
  32070. + * Return: void* - pointer to created stack.
  32071. + */
  32072. +void* mvStackCreate(int numOfElements)
  32073. +{
  32074. + MV_STACK* pStack;
  32075. + MV_U32* pStackElements;
  32076. +
  32077. + pStack = (MV_STACK*)mvOsMalloc(sizeof(MV_STACK));
  32078. + pStackElements = (MV_U32*)mvOsMalloc(numOfElements*sizeof(MV_U32));
  32079. + if( (pStack == NULL) || (pStackElements == NULL) )
  32080. + {
  32081. + mvOsPrintf("mvStack: Can't create new stack\n");
  32082. + return NULL;
  32083. + }
  32084. + memset(pStackElements, 0, numOfElements*sizeof(MV_U32));
  32085. + pStack->numOfElements = numOfElements;
  32086. + pStack->stackIdx = 0;
  32087. + pStack->stackElements = pStackElements;
  32088. +
  32089. + return pStack;
  32090. +}
  32091. +
  32092. +/* Purpose: Delete existing stack
  32093. + * Inputs:
  32094. + * - void* stackHndl - Stack handle as returned by "mvStackCreate()" function
  32095. + *
  32096. + * Return: MV_STATUS MV_NOT_FOUND - Failure. StackHandle is not valid.
  32097. + * MV_OK - Success.
  32098. + */
  32099. +MV_STATUS mvStackDelete(void* stackHndl)
  32100. +{
  32101. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  32102. +
  32103. + if( (pStack == NULL) || (pStack->stackElements == NULL) )
  32104. + return MV_NOT_FOUND;
  32105. +
  32106. + mvOsFree(pStack->stackElements);
  32107. + mvOsFree(pStack);
  32108. +
  32109. + return MV_OK;
  32110. +}
  32111. +
  32112. +
  32113. +/* PrintOut status of the stack */
  32114. +void mvStackStatus(void* stackHndl, MV_BOOL isPrintElements)
  32115. +{
  32116. + int i;
  32117. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  32118. +
  32119. + mvOsPrintf("StackHandle=%p, pElements=%p, numElements=%d, stackIdx=%d\n",
  32120. + stackHndl, pStack->stackElements, pStack->numOfElements,
  32121. + pStack->stackIdx);
  32122. + if(isPrintElements == MV_TRUE)
  32123. + {
  32124. + for(i=0; i<pStack->stackIdx; i++)
  32125. + {
  32126. + mvOsPrintf("%3d. Value=0x%x\n", i, pStack->stackElements[i]);
  32127. + }
  32128. + }
  32129. +}
  32130. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvStack.h
  32131. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvStack.h 1970-01-01 01:00:00.000000000 +0100
  32132. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvStack.h 2011-08-01 14:38:19.000000000 +0200
  32133. @@ -0,0 +1,140 @@
  32134. +/*******************************************************************************
  32135. +* Copyright 2003, Marvell Semiconductor Israel LTD. *
  32136. +* THIS CODE CONTAINS CONFIDENTIAL INFORMATION OF MARVELL. *
  32137. +* NO RIGHTS ARE GRANTED HEREIN UNDER ANY PATENT, MASK WORK RIGHT OR COPYRIGHT *
  32138. +* OF MARVELL OR ANY THIRD PARTY. MARVELL RESERVES THE RIGHT AT ITS SOLE *
  32139. +* DISCRETION TO REQUEST THAT THIS CODE BE IMMEDIATELY RETURNED TO MARVELL. *
  32140. +* THIS CODE IS PROVIDED "AS IS". MARVELL MAKES NO WARRANTIES, EXPRESSED, *
  32141. +* IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, COMPLETENESS OR PERFORMANCE. *
  32142. +* *
  32143. +* MARVELL COMPRISES MARVELL TECHNOLOGY GROUP LTD. (MTGL) AND ITS SUBSIDIARIES, *
  32144. +* MARVELL INTERNATIONAL LTD. (MIL), MARVELL TECHNOLOGY, INC. (MTI), MARVELL *
  32145. +* SEMICONDUCTOR, INC. (MSI), MARVELL ASIA PTE LTD. (MAPL), MARVELL JAPAN K.K. *
  32146. +* (MJKK), MARVELL SEMICONDUCTOR ISRAEL LTD (MSIL). *
  32147. +********************************************************************************
  32148. +* mvStack.h - Header File for :
  32149. +*
  32150. +* FILENAME: $Workfile: mvStack.h $
  32151. +* REVISION: $Revision: 1.1 $
  32152. +* LAST UPDATE: $Modtime: $
  32153. +*
  32154. +* DESCRIPTION:
  32155. +* This file defines simple Stack (LIFO) functionality.
  32156. +*
  32157. +*******************************************************************************/
  32158. +
  32159. +#ifndef __mvStack_h__
  32160. +#define __mvStack_h__
  32161. +
  32162. +
  32163. +/* includes */
  32164. +#include "mvTypes.h"
  32165. +
  32166. +
  32167. +/* defines */
  32168. +
  32169. +
  32170. +/* typedefs */
  32171. +/* Data structure describes general purpose Stack */
  32172. +typedef struct
  32173. +{
  32174. + int stackIdx;
  32175. + int numOfElements;
  32176. + MV_U32* stackElements;
  32177. +} MV_STACK;
  32178. +
  32179. +static INLINE MV_BOOL mvStackIsFull(void* stackHndl)
  32180. +{
  32181. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  32182. +
  32183. + if(pStack->stackIdx == pStack->numOfElements)
  32184. + return MV_TRUE;
  32185. +
  32186. + return MV_FALSE;
  32187. +}
  32188. +
  32189. +static INLINE MV_BOOL mvStackIsEmpty(void* stackHndl)
  32190. +{
  32191. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  32192. +
  32193. + if(pStack->stackIdx == 0)
  32194. + return MV_TRUE;
  32195. +
  32196. + return MV_FALSE;
  32197. +}
  32198. +/* Purpose: Push new element to stack
  32199. + * Inputs:
  32200. + * - void* stackHndl - Stack handle as returned by "mvStackCreate()" function.
  32201. + * - MV_U32 value - New element.
  32202. + *
  32203. + * Return: MV_STATUS MV_FULL - Failure. Stack is full.
  32204. + * MV_OK - Success. Element is put to stack.
  32205. + */
  32206. +static INLINE void mvStackPush(void* stackHndl, MV_U32 value)
  32207. +{
  32208. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  32209. +
  32210. +#ifdef MV_RT_DEBUG
  32211. + if(pStack->stackIdx == pStack->numOfElements)
  32212. + {
  32213. + mvOsPrintf("mvStackPush: Stack is FULL\n");
  32214. + return;
  32215. + }
  32216. +#endif /* MV_RT_DEBUG */
  32217. +
  32218. + pStack->stackElements[pStack->stackIdx] = value;
  32219. + pStack->stackIdx++;
  32220. +}
  32221. +
  32222. +/* Purpose: Pop element from the top of stack and copy it to "pValue"
  32223. + * Inputs:
  32224. + * - void* stackHndl - Stack handle as returned by "mvStackCreate()" function.
  32225. + * - MV_U32 value - Element in the top of stack.
  32226. + *
  32227. + * Return: MV_STATUS MV_EMPTY - Failure. Stack is empty.
  32228. + * MV_OK - Success. Element is removed from the stack and
  32229. + * copied to pValue argument
  32230. + */
  32231. +static INLINE MV_U32 mvStackPop(void* stackHndl)
  32232. +{
  32233. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  32234. +
  32235. +#ifdef MV_RT_DEBUG
  32236. + if(pStack->stackIdx == 0)
  32237. + {
  32238. + mvOsPrintf("mvStackPop: Stack is EMPTY\n");
  32239. + return 0;
  32240. + }
  32241. +#endif /* MV_RT_DEBUG */
  32242. +
  32243. + pStack->stackIdx--;
  32244. + return pStack->stackElements[pStack->stackIdx];
  32245. +}
  32246. +
  32247. +static INLINE int mvStackIndex(void* stackHndl)
  32248. +{
  32249. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  32250. +
  32251. + return pStack->stackIdx;
  32252. +}
  32253. +
  32254. +static INLINE int mvStackFreeElements(void* stackHndl)
  32255. +{
  32256. + MV_STACK* pStack = (MV_STACK*)stackHndl;
  32257. +
  32258. + return (pStack->numOfElements - pStack->stackIdx);
  32259. +}
  32260. +
  32261. +/* mvStack.h API list */
  32262. +
  32263. +/* Create new Stack */
  32264. +void* mvStackCreate(int numOfElements);
  32265. +
  32266. +/* Delete existing stack */
  32267. +MV_STATUS mvStackDelete(void* stackHndl);
  32268. +
  32269. +/* Print status of the stack */
  32270. +void mvStackStatus(void* stackHndl, MV_BOOL isPrintElements);
  32271. +
  32272. +#endif /* __mvStack_h__ */
  32273. +
  32274. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvTypes.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvTypes.h
  32275. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/common/mvTypes.h 1970-01-01 01:00:00.000000000 +0100
  32276. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/common/mvTypes.h 2011-08-01 14:38:19.000000000 +0200
  32277. @@ -0,0 +1,245 @@
  32278. +/*******************************************************************************
  32279. +Copyright (C) Marvell International Ltd. and its affiliates
  32280. +
  32281. +This software file (the "File") is owned and distributed by Marvell
  32282. +International Ltd. and/or its affiliates ("Marvell") under the following
  32283. +alternative licensing terms. Once you have made an election to distribute the
  32284. +File under one of the following license alternatives, please (i) delete this
  32285. +introductory statement regarding license alternatives, (ii) delete the two
  32286. +license alternatives that you have not elected to use and (iii) preserve the
  32287. +Marvell copyright notice above.
  32288. +
  32289. +********************************************************************************
  32290. +Marvell Commercial License Option
  32291. +
  32292. +If you received this File from Marvell and you have entered into a commercial
  32293. +license agreement (a "Commercial License") with Marvell, the File is licensed
  32294. +to you under the terms of the applicable Commercial License.
  32295. +
  32296. +********************************************************************************
  32297. +Marvell GPL License Option
  32298. +
  32299. +If you received this File from Marvell, you may opt to use, redistribute and/or
  32300. +modify this File in accordance with the terms and conditions of the General
  32301. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  32302. +available along with the File in the license.txt file or by writing to the Free
  32303. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  32304. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  32305. +
  32306. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  32307. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  32308. +DISCLAIMED. The GPL License provides additional details about this warranty
  32309. +disclaimer.
  32310. +********************************************************************************
  32311. +Marvell BSD License Option
  32312. +
  32313. +If you received this File from Marvell, you may opt to use, redistribute and/or
  32314. +modify this File under the following licensing terms.
  32315. +Redistribution and use in source and binary forms, with or without modification,
  32316. +are permitted provided that the following conditions are met:
  32317. +
  32318. + * Redistributions of source code must retain the above copyright notice,
  32319. + this list of conditions and the following disclaimer.
  32320. +
  32321. + * Redistributions in binary form must reproduce the above copyright
  32322. + notice, this list of conditions and the following disclaimer in the
  32323. + documentation and/or other materials provided with the distribution.
  32324. +
  32325. + * Neither the name of Marvell nor the names of its contributors may be
  32326. + used to endorse or promote products derived from this software without
  32327. + specific prior written permission.
  32328. +
  32329. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  32330. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  32331. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  32332. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  32333. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  32334. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  32335. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  32336. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  32337. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32338. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32339. +
  32340. +*******************************************************************************/
  32341. +
  32342. +
  32343. +#ifndef __INCmvTypesh
  32344. +#define __INCmvTypesh
  32345. +
  32346. +/* Defines */
  32347. +
  32348. +/* The following is a list of Marvell status */
  32349. +#define MV_ERROR (-1)
  32350. +#define MV_OK (0x00) /* Operation succeeded */
  32351. +#define MV_FAIL (0x01) /* Operation failed */
  32352. +#define MV_BAD_VALUE (0x02) /* Illegal value (general) */
  32353. +#define MV_OUT_OF_RANGE (0x03) /* The value is out of range */
  32354. +#define MV_BAD_PARAM (0x04) /* Illegal parameter in function called */
  32355. +#define MV_BAD_PTR (0x05) /* Illegal pointer value */
  32356. +#define MV_BAD_SIZE (0x06) /* Illegal size */
  32357. +#define MV_BAD_STATE (0x07) /* Illegal state of state machine */
  32358. +#define MV_SET_ERROR (0x08) /* Set operation failed */
  32359. +#define MV_GET_ERROR (0x09) /* Get operation failed */
  32360. +#define MV_CREATE_ERROR (0x0A) /* Fail while creating an item */
  32361. +#define MV_NOT_FOUND (0x0B) /* Item not found */
  32362. +#define MV_NO_MORE (0x0C) /* No more items found */
  32363. +#define MV_NO_SUCH (0x0D) /* No such item */
  32364. +#define MV_TIMEOUT (0x0E) /* Time Out */
  32365. +#define MV_NO_CHANGE (0x0F) /* Parameter(s) is already in this value */
  32366. +#define MV_NOT_SUPPORTED (0x10) /* This request is not support */
  32367. +#define MV_NOT_IMPLEMENTED (0x11) /* Request supported but not implemented */
  32368. +#define MV_NOT_INITIALIZED (0x12) /* The item is not initialized */
  32369. +#define MV_NO_RESOURCE (0x13) /* Resource not available (memory ...) */
  32370. +#define MV_FULL (0x14) /* Item is full (Queue or table etc...) */
  32371. +#define MV_EMPTY (0x15) /* Item is empty (Queue or table etc...) */
  32372. +#define MV_INIT_ERROR (0x16) /* Error occured while INIT process */
  32373. +#define MV_HW_ERROR (0x17) /* Hardware error */
  32374. +#define MV_TX_ERROR (0x18) /* Transmit operation not succeeded */
  32375. +#define MV_RX_ERROR (0x19) /* Recieve operation not succeeded */
  32376. +#define MV_NOT_READY (0x1A) /* The other side is not ready yet */
  32377. +#define MV_ALREADY_EXIST (0x1B) /* Tried to create existing item */
  32378. +#define MV_OUT_OF_CPU_MEM (0x1C) /* Cpu memory allocation failed. */
  32379. +#define MV_NOT_STARTED (0x1D) /* Not started yet */
  32380. +#define MV_BUSY (0x1E) /* Item is busy. */
  32381. +#define MV_TERMINATE (0x1F) /* Item terminates it's work. */
  32382. +#define MV_NOT_ALIGNED (0x20) /* Wrong alignment */
  32383. +#define MV_NOT_ALLOWED (0x21) /* Operation NOT allowed */
  32384. +#define MV_WRITE_PROTECT (0x22) /* Write protected */
  32385. +
  32386. +
  32387. +#define MV_INVALID (int)(-1)
  32388. +
  32389. +#define MV_FALSE 0
  32390. +#define MV_TRUE (!(MV_FALSE))
  32391. +
  32392. +
  32393. +#ifndef NULL
  32394. +#define NULL ((void*)0)
  32395. +#endif
  32396. +
  32397. +
  32398. +#ifndef MV_ASMLANGUAGE
  32399. +/* typedefs */
  32400. +
  32401. +typedef char MV_8;
  32402. +typedef unsigned char MV_U8;
  32403. +
  32404. +typedef int MV_32;
  32405. +typedef unsigned int MV_U32;
  32406. +
  32407. +typedef short MV_16;
  32408. +typedef unsigned short MV_U16;
  32409. +
  32410. +#ifdef MV_PPC64
  32411. +typedef long MV_64;
  32412. +typedef unsigned long MV_U64;
  32413. +#else
  32414. +typedef long long MV_64;
  32415. +typedef unsigned long long MV_U64;
  32416. +#endif
  32417. +
  32418. +typedef long MV_LONG; /* 32/64 */
  32419. +typedef unsigned long MV_ULONG; /* 32/64 */
  32420. +
  32421. +typedef int MV_STATUS;
  32422. +typedef int MV_BOOL;
  32423. +typedef void MV_VOID;
  32424. +typedef float MV_FLOAT;
  32425. +
  32426. +typedef int (*MV_FUNCPTR) (void); /* ptr to function returning int */
  32427. +typedef void (*MV_VOIDFUNCPTR) (void); /* ptr to function returning void */
  32428. +typedef double (*MV_DBLFUNCPTR) (void); /* ptr to function returning double*/
  32429. +typedef float (*MV_FLTFUNCPTR) (void); /* ptr to function returning float */
  32430. +
  32431. +typedef MV_U32 MV_KHZ;
  32432. +typedef MV_U32 MV_MHZ;
  32433. +typedef MV_U32 MV_HZ;
  32434. +
  32435. +
  32436. +/* This enumerator describes the set of commands that can be applied on */
  32437. +/* an engine (e.g. IDMA, XOR). Appling a comman depends on the current */
  32438. +/* status (see MV_STATE enumerator) */
  32439. +/* Start can be applied only when status is IDLE */
  32440. +/* Stop can be applied only when status is IDLE, ACTIVE or PAUSED */
  32441. +/* Pause can be applied only when status is ACTIVE */
  32442. +/* Restart can be applied only when status is PAUSED */
  32443. +typedef enum _mvCommand
  32444. +{
  32445. + MV_START, /* Start */
  32446. + MV_STOP, /* Stop */
  32447. + MV_PAUSE, /* Pause */
  32448. + MV_RESTART /* Restart */
  32449. +} MV_COMMAND;
  32450. +
  32451. +/* This enumerator describes the set of state conditions. */
  32452. +/* Moving from one state to other is stricted. */
  32453. +typedef enum _mvState
  32454. +{
  32455. + MV_IDLE,
  32456. + MV_ACTIVE,
  32457. + MV_PAUSED,
  32458. + MV_UNDEFINED_STATE
  32459. +} MV_STATE;
  32460. +
  32461. +
  32462. +/* This structure describes address space window. Window base can be */
  32463. +/* 64 bit, window size up to 4GB */
  32464. +typedef struct _mvAddrWin
  32465. +{
  32466. + MV_U32 baseLow; /* 32bit base low */
  32467. + MV_U32 baseHigh; /* 32bit base high */
  32468. + MV_U32 size; /* 32bit size */
  32469. +}MV_ADDR_WIN;
  32470. +
  32471. +/* This binary enumerator describes protection attribute status */
  32472. +typedef enum _mvProtRight
  32473. +{
  32474. + ALLOWED, /* Protection attribute allowed */
  32475. + FORBIDDEN /* Protection attribute forbidden */
  32476. +}MV_PROT_RIGHT;
  32477. +
  32478. +/* Unified struct for Rx and Tx packet operations. The user is required to */
  32479. +/* be familier only with Tx/Rx descriptor command status. */
  32480. +typedef struct _bufInfo
  32481. +{
  32482. + MV_U32 cmdSts; /* Tx/Rx command status */
  32483. + MV_U16 byteCnt; /* Size of valid data in the buffer */
  32484. + MV_U16 bufSize; /* Total size of the buffer */
  32485. + MV_U8 *pBuff; /* Pointer to Buffer */
  32486. + MV_U8 *pData; /* Pointer to data in the Buffer */
  32487. + MV_U32 userInfo1; /* Tx/Rx attached user information 1 */
  32488. + MV_U32 userInfo2; /* Tx/Rx attached user information 2 */
  32489. + struct _bufInfo *pNextBufInfo; /* Next buffer in packet */
  32490. +} BUF_INFO;
  32491. +
  32492. +/* This structure contains information describing one of buffers
  32493. + * (fragments) they are built Ethernet packet.
  32494. + */
  32495. +typedef struct
  32496. +{
  32497. + MV_U8* bufVirtPtr;
  32498. + MV_ULONG bufPhysAddr;
  32499. + MV_U32 bufSize;
  32500. + MV_U32 dataSize;
  32501. + MV_U32 memHandle;
  32502. + MV_32 bufAddrShift;
  32503. +} MV_BUF_INFO;
  32504. +
  32505. +/* This structure contains information describing Ethernet packet.
  32506. + * The packet can be divided for few buffers (fragments)
  32507. + */
  32508. +typedef struct
  32509. +{
  32510. + MV_ULONG osInfo;
  32511. + MV_BUF_INFO *pFrags;
  32512. + MV_U32 status;
  32513. + MV_U16 pktSize;
  32514. + MV_U16 numFrags;
  32515. + MV_U32 ownerId;
  32516. + MV_U32 fragIP;
  32517. +} MV_PKT_INFO;
  32518. +
  32519. +#endif /* MV_ASMLANGUAGE */
  32520. +
  32521. +#endif /* __INCmvTypesh */
  32522. +
  32523. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/dbg-trace.c
  32524. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.c 1970-01-01 01:00:00.000000000 +0100
  32525. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/dbg-trace.c 2011-08-01 14:38:19.000000000 +0200
  32526. @@ -0,0 +1,110 @@
  32527. +#include <linux/kernel.h>
  32528. +#include <linux/slab.h>
  32529. +#include <linux/time.h>
  32530. +#include "dbg-trace.h"
  32531. +
  32532. +#define TRACE_ARR_LEN 800
  32533. +#define STR_LEN 128
  32534. +struct trace {
  32535. + struct timeval tv;
  32536. + char str[STR_LEN];
  32537. + unsigned int callback_val1;
  32538. + unsigned int callback_val2;
  32539. + char valid;
  32540. +};
  32541. +static unsigned int (*trc_callback1) (unsigned char) = NULL;
  32542. +static unsigned int (*trc_callback2) (unsigned char) = NULL;
  32543. +static unsigned char trc_param1 = 0;
  32544. +static unsigned char trc_param2 = 0;
  32545. +struct trace *trc_arr;
  32546. +static int trc_index;
  32547. +static int trc_active = 0;
  32548. +
  32549. +void TRC_START()
  32550. +{
  32551. + trc_active = 1;
  32552. +}
  32553. +
  32554. +void TRC_STOP()
  32555. +{
  32556. + trc_active = 0;
  32557. +}
  32558. +
  32559. +void TRC_INIT(void *callback1, void *callback2, unsigned char callback1_param, unsigned char callback2_param)
  32560. +{
  32561. + printk("Marvell debug tracing is on\n");
  32562. + trc_arr = (struct trace *)kmalloc(TRACE_ARR_LEN*sizeof(struct trace),GFP_KERNEL);
  32563. + if(trc_arr == NULL)
  32564. + {
  32565. + printk("Can't allocate Debug Trace buffer\n");
  32566. + return;
  32567. + }
  32568. + memset(trc_arr,0,TRACE_ARR_LEN*sizeof(struct trace));
  32569. + trc_index = 0;
  32570. + trc_callback1 = callback1;
  32571. + trc_callback2 = callback2;
  32572. + trc_param1 = callback1_param;
  32573. + trc_param2 = callback2_param;
  32574. +}
  32575. +void TRC_REC(char *fmt,...)
  32576. +{
  32577. + va_list args;
  32578. + struct trace *trc = &trc_arr[trc_index];
  32579. +
  32580. + if(trc_active == 0)
  32581. + return;
  32582. +
  32583. + do_gettimeofday(&trc->tv);
  32584. + if(trc_callback1)
  32585. + trc->callback_val1 = trc_callback1(trc_param1);
  32586. + if(trc_callback2)
  32587. + trc->callback_val2 = trc_callback2(trc_param2);
  32588. + va_start(args, fmt);
  32589. + vsprintf(trc->str,fmt,args);
  32590. + va_end(args);
  32591. + trc->valid = 1;
  32592. + if((++trc_index) == TRACE_ARR_LEN) {
  32593. + trc_index = 0;
  32594. + }
  32595. +}
  32596. +void TRC_OUTPUT(void)
  32597. +{
  32598. + int i,j;
  32599. + struct trace *p;
  32600. + printk("\n\nTrace %d items\n",TRACE_ARR_LEN);
  32601. + for(i=0,j=trc_index; i<TRACE_ARR_LEN; i++,j++) {
  32602. + if(j == TRACE_ARR_LEN)
  32603. + j = 0;
  32604. + p = &trc_arr[j];
  32605. + if(p->valid) {
  32606. + unsigned long uoffs;
  32607. + struct trace *plast;
  32608. + if(p == &trc_arr[0])
  32609. + plast = &trc_arr[TRACE_ARR_LEN-1];
  32610. + else
  32611. + plast = p-1;
  32612. + if(p->tv.tv_sec == ((plast)->tv.tv_sec))
  32613. + uoffs = (p->tv.tv_usec - ((plast)->tv.tv_usec));
  32614. + else
  32615. + uoffs = (1000000 - ((plast)->tv.tv_usec)) +
  32616. + ((p->tv.tv_sec - ((plast)->tv.tv_sec) - 1) * 1000000) +
  32617. + p->tv.tv_usec;
  32618. + printk("%03d: [+%ld usec]", j, (unsigned long)uoffs);
  32619. + if(trc_callback1)
  32620. + printk("[%u]",p->callback_val1);
  32621. + if(trc_callback2)
  32622. + printk("[%u]",p->callback_val2);
  32623. + printk(": %s",p->str);
  32624. + }
  32625. + p->valid = 0;
  32626. + }
  32627. + memset(trc_arr,0,TRACE_ARR_LEN*sizeof(struct trace));
  32628. + trc_index = 0;
  32629. +}
  32630. +void TRC_RELEASE(void)
  32631. +{
  32632. + kfree(trc_arr);
  32633. + trc_index = 0;
  32634. +}
  32635. +
  32636. +
  32637. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/dbg-trace.h
  32638. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/dbg-trace.h 1970-01-01 01:00:00.000000000 +0100
  32639. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/dbg-trace.h 2011-08-01 14:38:19.000000000 +0200
  32640. @@ -0,0 +1,24 @@
  32641. +
  32642. +#ifndef _MV_DBG_TRCE_H_
  32643. +#define _MV_DBG_TRCE_H_
  32644. +
  32645. +#ifdef CONFIG_MV_DBG_TRACE
  32646. +void TRC_INIT(void *callback1, void *callback2,
  32647. + unsigned char callback1_param, unsigned char callback2_param);
  32648. +void TRC_REC(char *fmt,...);
  32649. +void TRC_OUTPUT(void);
  32650. +void TRC_RELEASE(void);
  32651. +void TRC_START(void);
  32652. +void TRC_STOP(void);
  32653. +
  32654. +#else
  32655. +#define TRC_INIT(x1,x2,x3,x4)
  32656. +#define TRC_REC(X...)
  32657. +#define TRC_OUTPUT()
  32658. +#define TRC_RELEASE()
  32659. +#define TRC_START()
  32660. +#define TRC_STOP()
  32661. +#endif
  32662. +
  32663. +
  32664. +#endif
  32665. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c
  32666. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c 1970-01-01 01:00:00.000000000 +0100
  32667. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.c 2011-08-01 14:38:19.000000000 +0200
  32668. @@ -0,0 +1,2513 @@
  32669. +/*******************************************************************************
  32670. +Copyright (C) Marvell International Ltd. and its affiliates
  32671. +
  32672. +This software file (the "File") is owned and distributed by Marvell
  32673. +International Ltd. and/or its affiliates ("Marvell") under the following
  32674. +alternative licensing terms. Once you have made an election to distribute the
  32675. +File under one of the following license alternatives, please (i) delete this
  32676. +introductory statement regarding license alternatives, (ii) delete the two
  32677. +license alternatives that you have not elected to use and (iii) preserve the
  32678. +Marvell copyright notice above.
  32679. +
  32680. +********************************************************************************
  32681. +Marvell Commercial License Option
  32682. +
  32683. +If you received this File from Marvell and you have entered into a commercial
  32684. +license agreement (a "Commercial License") with Marvell, the File is licensed
  32685. +to you under the terms of the applicable Commercial License.
  32686. +
  32687. +********************************************************************************
  32688. +Marvell GPL License Option
  32689. +
  32690. +If you received this File from Marvell, you may opt to use, redistribute and/or
  32691. +modify this File in accordance with the terms and conditions of the General
  32692. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  32693. +available along with the File in the license.txt file or by writing to the Free
  32694. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  32695. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  32696. +
  32697. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  32698. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  32699. +DISCLAIMED. The GPL License provides additional details about this warranty
  32700. +disclaimer.
  32701. +********************************************************************************
  32702. +Marvell BSD License Option
  32703. +
  32704. +If you received this File from Marvell, you may opt to use, redistribute and/or
  32705. +modify this File under the following licensing terms.
  32706. +Redistribution and use in source and binary forms, with or without modification,
  32707. +are permitted provided that the following conditions are met:
  32708. +
  32709. + * Redistributions of source code must retain the above copyright notice,
  32710. + this list of conditions and the following disclaimer.
  32711. +
  32712. + * Redistributions in binary form must reproduce the above copyright
  32713. + notice, this list of conditions and the following disclaimer in the
  32714. + documentation and/or other materials provided with the distribution.
  32715. +
  32716. + * Neither the name of Marvell nor the names of its contributors may be
  32717. + used to endorse or promote products derived from this software without
  32718. + specific prior written permission.
  32719. +
  32720. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  32721. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  32722. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  32723. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  32724. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  32725. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  32726. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  32727. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  32728. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  32729. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  32730. +
  32731. +*******************************************************************************/
  32732. +
  32733. +#include "boardEnv/mvBoardEnvLib.h"
  32734. +#include "ctrlEnv/mvCtrlEnvLib.h"
  32735. +#include "ctrlEnv/sys/mvCpuIf.h"
  32736. +#include "cpu/mvCpu.h"
  32737. +#include "cntmr/mvCntmr.h"
  32738. +#include "gpp/mvGpp.h"
  32739. +#include "twsi/mvTwsi.h"
  32740. +#include "pex/mvPex.h"
  32741. +#include "device/mvDevice.h"
  32742. +#include "eth/gbe/mvEthRegs.h"
  32743. +
  32744. +/* defines */
  32745. +/* #define MV_DEBUG */
  32746. +#ifdef MV_DEBUG
  32747. + #define DB(x) x
  32748. +#else
  32749. + #define DB(x)
  32750. +#endif
  32751. +
  32752. +extern MV_CPU_ARM_CLK _cpuARMDDRCLK[];
  32753. +
  32754. +#define CODE_IN_ROM MV_FALSE
  32755. +#define CODE_IN_RAM MV_TRUE
  32756. +
  32757. +extern MV_BOARD_INFO* boardInfoTbl[];
  32758. +#define BOARD_INFO(boardId) boardInfoTbl[boardId - BOARD_ID_BASE]
  32759. +
  32760. +/* Locals */
  32761. +static MV_DEV_CS_INFO* boardGetDevEntry(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  32762. +
  32763. +MV_U32 tClkRate = -1;
  32764. +
  32765. +
  32766. +/*******************************************************************************
  32767. +* mvBoardEnvInit - Init board
  32768. +*
  32769. +* DESCRIPTION:
  32770. +* In this function the board environment take care of device bank
  32771. +* initialization.
  32772. +*
  32773. +* INPUT:
  32774. +* None.
  32775. +*
  32776. +* OUTPUT:
  32777. +* None.
  32778. +*
  32779. +* RETURN:
  32780. +* None.
  32781. +*
  32782. +*******************************************************************************/
  32783. +MV_VOID mvBoardEnvInit(MV_VOID)
  32784. +{
  32785. + MV_U32 boardId= mvBoardIdGet();
  32786. +
  32787. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32788. + {
  32789. + mvOsPrintf("mvBoardEnvInit:Board unknown.\n");
  32790. + return;
  32791. +
  32792. + }
  32793. +
  32794. + /* Set GPP Out value */
  32795. + MV_REG_WRITE(GPP_DATA_OUT_REG(0), BOARD_INFO(boardId)->gppOutValLow);
  32796. + MV_REG_WRITE(GPP_DATA_OUT_REG(1), BOARD_INFO(boardId)->gppOutValHigh);
  32797. +
  32798. + /* set GPP polarity */
  32799. + mvGppPolaritySet(0, 0xFFFFFFFF, BOARD_INFO(boardId)->gppPolarityValLow);
  32800. + mvGppPolaritySet(1, 0xFFFFFFFF, BOARD_INFO(boardId)->gppPolarityValHigh);
  32801. +
  32802. + /* Workaround for Erratum FE-MISC-70*/
  32803. + if(mvCtrlRevGet()==MV_88F6XXX_A0_REV)
  32804. + {
  32805. + BOARD_INFO(boardId)->gppOutEnValLow &= 0xfffffffd;
  32806. + BOARD_INFO(boardId)->gppOutEnValLow |= (BOARD_INFO(boardId)->gppOutEnValHigh) & 0x00000002;
  32807. + } /*End of WA*/
  32808. +
  32809. + /* Set GPP Out Enable*/
  32810. + mvGppTypeSet(0, 0xFFFFFFFF, BOARD_INFO(boardId)->gppOutEnValLow);
  32811. + mvGppTypeSet(1, 0xFFFFFFFF, BOARD_INFO(boardId)->gppOutEnValHigh);
  32812. +
  32813. + /* Nand CE */
  32814. + MV_REG_BIT_SET(NAND_CTRL_REG, NAND_ACTCEBOOT_BIT);
  32815. +}
  32816. +
  32817. +/*******************************************************************************
  32818. +* mvBoardModelGet - Get Board model
  32819. +*
  32820. +* DESCRIPTION:
  32821. +* This function returns 16bit describing board model.
  32822. +* Board model is constructed of one byte major and minor numbers in the
  32823. +* following manner:
  32824. +*
  32825. +* INPUT:
  32826. +* None.
  32827. +*
  32828. +* OUTPUT:
  32829. +* None.
  32830. +*
  32831. +* RETURN:
  32832. +* String describing board model.
  32833. +*
  32834. +*******************************************************************************/
  32835. +MV_U16 mvBoardModelGet(MV_VOID)
  32836. +{
  32837. + return (mvBoardIdGet() >> 16);
  32838. +}
  32839. +
  32840. +/*******************************************************************************
  32841. +* mbBoardRevlGet - Get Board revision
  32842. +*
  32843. +* DESCRIPTION:
  32844. +* This function returns a 32bit describing the board revision.
  32845. +* Board revision is constructed of 4bytes. 2bytes describes major number
  32846. +* and the other 2bytes describes minor munber.
  32847. +* For example for board revision 3.4 the function will return
  32848. +* 0x00030004.
  32849. +*
  32850. +* INPUT:
  32851. +* None.
  32852. +*
  32853. +* OUTPUT:
  32854. +* None.
  32855. +*
  32856. +* RETURN:
  32857. +* String describing board model.
  32858. +*
  32859. +*******************************************************************************/
  32860. +MV_U16 mvBoardRevGet(MV_VOID)
  32861. +{
  32862. + return (mvBoardIdGet() & 0xFFFF);
  32863. +}
  32864. +
  32865. +/*******************************************************************************
  32866. +* mvBoardNameGet - Get Board name
  32867. +*
  32868. +* DESCRIPTION:
  32869. +* This function returns a string describing the board model and revision.
  32870. +* String is extracted from board I2C EEPROM.
  32871. +*
  32872. +* INPUT:
  32873. +* None.
  32874. +*
  32875. +* OUTPUT:
  32876. +* pNameBuff - Buffer to contain board name string. Minimum size 32 chars.
  32877. +*
  32878. +* RETURN:
  32879. +*
  32880. +* MV_ERROR if informantion can not be read.
  32881. +*******************************************************************************/
  32882. +MV_STATUS mvBoardNameGet(char *pNameBuff)
  32883. +{
  32884. + MV_U32 boardId= mvBoardIdGet();
  32885. +
  32886. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32887. + {
  32888. + mvOsSPrintf (pNameBuff, "Board unknown.\n");
  32889. + return MV_ERROR;
  32890. +
  32891. + }
  32892. +
  32893. + mvOsSPrintf (pNameBuff, "%s",BOARD_INFO(boardId)->boardName);
  32894. +
  32895. + return MV_OK;
  32896. +}
  32897. +
  32898. +/*******************************************************************************
  32899. +* mvBoardIsPortInSgmii -
  32900. +*
  32901. +* DESCRIPTION:
  32902. +* This routine returns MV_TRUE for port number works in SGMII or MV_FALSE
  32903. +* For all other options.
  32904. +*
  32905. +* INPUT:
  32906. +* ethPortNum - Ethernet port number.
  32907. +*
  32908. +* OUTPUT:
  32909. +* None.
  32910. +*
  32911. +* RETURN:
  32912. +* MV_TRUE - port in SGMII.
  32913. +* MV_FALSE - other.
  32914. +*
  32915. +*******************************************************************************/
  32916. +MV_BOOL mvBoardIsPortInSgmii(MV_U32 ethPortNum)
  32917. +{
  32918. + MV_BOOL ethPortSgmiiSupport[BOARD_ETH_PORT_NUM] = MV_ETH_PORT_SGMII;
  32919. +
  32920. + if(ethPortNum >= BOARD_ETH_PORT_NUM)
  32921. + {
  32922. + mvOsPrintf ("Invalid portNo=%d\n", ethPortNum);
  32923. + return MV_FALSE;
  32924. + }
  32925. + return ethPortSgmiiSupport[ethPortNum];
  32926. +}
  32927. +
  32928. +/*******************************************************************************
  32929. +* mvBoardIsPortInGmii -
  32930. +*
  32931. +* DESCRIPTION:
  32932. +* This routine returns MV_TRUE for port number works in GMII or MV_FALSE
  32933. +* For all other options.
  32934. +*
  32935. +* INPUT:
  32936. +*
  32937. +* OUTPUT:
  32938. +* None.
  32939. +*
  32940. +* RETURN:
  32941. +* MV_TRUE - port in GMII.
  32942. +* MV_FALSE - other.
  32943. +*
  32944. +*******************************************************************************/
  32945. +MV_BOOL mvBoardIsPortInGmii(MV_VOID)
  32946. +{
  32947. + MV_U32 devClassId, devClass = 0;
  32948. + if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_AUTO)
  32949. + {
  32950. + /* Get MPP module ID */
  32951. + devClassId = mvBoarModuleTypeGet(devClass);
  32952. + if (MV_BOARD_MODULE_GMII_ID == devClassId)
  32953. + return MV_TRUE;
  32954. + }
  32955. + else if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_GMII)
  32956. + return MV_TRUE;
  32957. +
  32958. + return MV_FALSE;
  32959. +}
  32960. +/*******************************************************************************
  32961. +* mvBoardPhyAddrGet - Get the phy address
  32962. +*
  32963. +* DESCRIPTION:
  32964. +* This routine returns the Phy address of a given ethernet port.
  32965. +*
  32966. +* INPUT:
  32967. +* ethPortNum - Ethernet port number.
  32968. +*
  32969. +* OUTPUT:
  32970. +* None.
  32971. +*
  32972. +* RETURN:
  32973. +* 32bit describing Phy address, -1 if the port number is wrong.
  32974. +*
  32975. +*******************************************************************************/
  32976. +MV_32 mvBoardPhyAddrGet(MV_U32 ethPortNum)
  32977. +{
  32978. + MV_U32 boardId= mvBoardIdGet();
  32979. +
  32980. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  32981. + {
  32982. + mvOsPrintf("mvBoardPhyAddrGet: Board unknown.\n");
  32983. + return MV_ERROR;
  32984. + }
  32985. +
  32986. + return BOARD_INFO(boardId)->pBoardMacInfo[ethPortNum].boardEthSmiAddr;
  32987. +}
  32988. +
  32989. +/*******************************************************************************
  32990. +* mvBoardMacSpeedGet - Get the Mac speed
  32991. +*
  32992. +* DESCRIPTION:
  32993. +* This routine returns the Mac speed if pre define of a given ethernet port.
  32994. +*
  32995. +* INPUT:
  32996. +* ethPortNum - Ethernet port number.
  32997. +*
  32998. +* OUTPUT:
  32999. +* None.
  33000. +*
  33001. +* RETURN:
  33002. +* MV_BOARD_MAC_SPEED, -1 if the port number is wrong.
  33003. +*
  33004. +*******************************************************************************/
  33005. +MV_BOARD_MAC_SPEED mvBoardMacSpeedGet(MV_U32 ethPortNum)
  33006. +{
  33007. + MV_U32 boardId= mvBoardIdGet();
  33008. +
  33009. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33010. + {
  33011. + mvOsPrintf("mvBoardMacSpeedGet: Board unknown.\n");
  33012. + return MV_ERROR;
  33013. + }
  33014. +
  33015. + return BOARD_INFO(boardId)->pBoardMacInfo[ethPortNum].boardMacSpeed;
  33016. +}
  33017. +
  33018. +/*******************************************************************************
  33019. +* mvBoardLinkStatusIrqGet - Get the IRQ number for the link status indication
  33020. +*
  33021. +* DESCRIPTION:
  33022. +* This routine returns the IRQ number for the link status indication.
  33023. +*
  33024. +* INPUT:
  33025. +* ethPortNum - Ethernet port number.
  33026. +*
  33027. +* OUTPUT:
  33028. +* None.
  33029. +*
  33030. +* RETURN:
  33031. +* the number of the IRQ for the link status indication, -1 if the port
  33032. +* number is wrong or if not relevant.
  33033. +*
  33034. +*******************************************************************************/
  33035. +MV_32 mvBoardLinkStatusIrqGet(MV_U32 ethPortNum)
  33036. +{
  33037. + MV_U32 boardId = mvBoardIdGet();
  33038. +
  33039. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33040. + {
  33041. + mvOsPrintf("mvBoardLinkStatusIrqGet: Board unknown.\n");
  33042. + return MV_ERROR;
  33043. + }
  33044. +
  33045. + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].linkStatusIrq;
  33046. +}
  33047. +
  33048. +/*******************************************************************************
  33049. +* mvBoardSwitchPortGet - Get the mapping between the board connector and the
  33050. +* Ethernet Switch port
  33051. +*
  33052. +* DESCRIPTION:
  33053. +* This routine returns the matching Switch port.
  33054. +*
  33055. +* INPUT:
  33056. +* ethPortNum - Ethernet port number.
  33057. +* boardPortNum - logical number of the connector on the board
  33058. +*
  33059. +* OUTPUT:
  33060. +* None.
  33061. +*
  33062. +* RETURN:
  33063. +* the matching Switch port, -1 if the port number is wrong or if not relevant.
  33064. +*
  33065. +*******************************************************************************/
  33066. +MV_32 mvBoardSwitchPortGet(MV_U32 ethPortNum, MV_U8 boardPortNum)
  33067. +{
  33068. + MV_U32 boardId = mvBoardIdGet();
  33069. +
  33070. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33071. + {
  33072. + mvOsPrintf("mvBoardSwitchPortGet: Board unknown.\n");
  33073. + return MV_ERROR;
  33074. + }
  33075. + if (boardPortNum >= BOARD_ETH_SWITCH_PORT_NUM)
  33076. + {
  33077. + mvOsPrintf("mvBoardSwitchPortGet: Illegal board port number.\n");
  33078. + return MV_ERROR;
  33079. + }
  33080. +
  33081. + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].qdPort[boardPortNum];
  33082. +}
  33083. +
  33084. +/*******************************************************************************
  33085. +* mvBoardSwitchCpuPortGet - Get the the Ethernet Switch CPU port
  33086. +*
  33087. +* DESCRIPTION:
  33088. +* This routine returns the Switch CPU port.
  33089. +*
  33090. +* INPUT:
  33091. +* ethPortNum - Ethernet port number.
  33092. +*
  33093. +* OUTPUT:
  33094. +* None.
  33095. +*
  33096. +* RETURN:
  33097. +* the Switch CPU port, -1 if the port number is wrong or if not relevant.
  33098. +*
  33099. +*******************************************************************************/
  33100. +MV_32 mvBoardSwitchCpuPortGet(MV_U32 ethPortNum)
  33101. +{
  33102. + MV_U32 boardId = mvBoardIdGet();
  33103. +
  33104. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33105. + {
  33106. + mvOsPrintf("mvBoardSwitchCpuPortGet: Board unknown.\n");
  33107. + return MV_ERROR;
  33108. + }
  33109. +
  33110. + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].qdCpuPort;
  33111. +}
  33112. +
  33113. +/*******************************************************************************
  33114. +* mvBoardIsSwitchConnected - Get switch connection status
  33115. +* DESCRIPTION:
  33116. +* This routine returns port's connection status
  33117. +*
  33118. +* INPUT:
  33119. +* ethPortNum - Ethernet port number.
  33120. +*
  33121. +* OUTPUT:
  33122. +* None.
  33123. +*
  33124. +* RETURN:
  33125. +* 1 - if ethPortNum is connected to switch, 0 otherwise
  33126. +*
  33127. +*******************************************************************************/
  33128. +MV_32 mvBoardIsSwitchConnected(MV_U32 ethPortNum)
  33129. +{
  33130. + MV_U32 boardId = mvBoardIdGet();
  33131. +
  33132. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33133. + {
  33134. + mvOsPrintf("mvBoardIsSwitchConnected: Board unknown.\n");
  33135. + return MV_ERROR;
  33136. + }
  33137. +
  33138. + if(ethPortNum >= BOARD_INFO(boardId)->numBoardMacInfo)
  33139. + {
  33140. + mvOsPrintf("mvBoardIsSwitchConnected: Illegal port number(%u)\n", ethPortNum);
  33141. + return MV_ERROR;
  33142. + }
  33143. +
  33144. + if((MV_32)(BOARD_INFO(boardId)->pSwitchInfo))
  33145. + return (MV_32)(BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].switchOnPort == ethPortNum);
  33146. + else
  33147. + return 0;
  33148. +}
  33149. +/*******************************************************************************
  33150. +* mvBoardSmiScanModeGet - Get Switch SMI scan mode
  33151. +*
  33152. +* DESCRIPTION:
  33153. +* This routine returns Switch SMI scan mode.
  33154. +*
  33155. +* INPUT:
  33156. +* ethPortNum - Ethernet port number.
  33157. +*
  33158. +* OUTPUT:
  33159. +* None.
  33160. +*
  33161. +* RETURN:
  33162. +* 1 for SMI_MANUAL_MODE, -1 if the port number is wrong or if not relevant.
  33163. +*
  33164. +*******************************************************************************/
  33165. +MV_32 mvBoardSmiScanModeGet(MV_U32 ethPortNum)
  33166. +{
  33167. + MV_U32 boardId = mvBoardIdGet();
  33168. +
  33169. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33170. + {
  33171. + mvOsPrintf("mvBoardSmiScanModeGet: Board unknown.\n");
  33172. + return MV_ERROR;
  33173. + }
  33174. +
  33175. + return BOARD_INFO(boardId)->pSwitchInfo[ethPortNum].smiScanMode;
  33176. +}
  33177. +/*******************************************************************************
  33178. +* mvBoardSpecInitGet -
  33179. +*
  33180. +* DESCRIPTION:
  33181. +*
  33182. +* INPUT:
  33183. +*
  33184. +* OUTPUT:
  33185. +* None.
  33186. +*
  33187. +* RETURN: Return MV_TRUE and parameters in case board need spesific phy init,
  33188. +* otherwise return MV_FALSE.
  33189. +*
  33190. +*
  33191. +*******************************************************************************/
  33192. +
  33193. +MV_BOOL mvBoardSpecInitGet(MV_U32* regOff, MV_U32* data)
  33194. +{
  33195. + return MV_FALSE;
  33196. +}
  33197. +
  33198. +/*******************************************************************************
  33199. +* mvBoardTclkGet - Get the board Tclk (Controller clock)
  33200. +*
  33201. +* DESCRIPTION:
  33202. +* This routine extract the controller core clock.
  33203. +* This function uses the controller counters to make identification.
  33204. +* Note: In order to avoid interference, make sure task context switch
  33205. +* and interrupts will not occure during this function operation
  33206. +*
  33207. +* INPUT:
  33208. +* countNum - Counter number.
  33209. +*
  33210. +* OUTPUT:
  33211. +* None.
  33212. +*
  33213. +* RETURN:
  33214. +* 32bit clock cycles in Hertz.
  33215. +*
  33216. +*******************************************************************************/
  33217. +MV_U32 mvBoardTclkGet(MV_VOID)
  33218. +{
  33219. + if(mvCtrlModelGet()==MV_6281_DEV_ID)
  33220. + {
  33221. +#if defined(TCLK_AUTO_DETECT)
  33222. + MV_U32 tmpTClkRate = MV_BOARD_TCLK_166MHZ;
  33223. +
  33224. + tmpTClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  33225. + tmpTClkRate &= MSAR_TCLCK_MASK;
  33226. +
  33227. + switch (tmpTClkRate)
  33228. + {
  33229. + case MSAR_TCLCK_166:
  33230. + return MV_BOARD_TCLK_166MHZ;
  33231. + break;
  33232. + case MSAR_TCLCK_200:
  33233. + return MV_BOARD_TCLK_200MHZ;
  33234. + break;
  33235. + }
  33236. +#else
  33237. + return MV_BOARD_TCLK_200MHZ;
  33238. +#endif
  33239. + }
  33240. +
  33241. + return MV_BOARD_TCLK_166MHZ;
  33242. +
  33243. +}
  33244. +/*******************************************************************************
  33245. +* mvBoardSysClkGet - Get the board SysClk (CPU bus clock)
  33246. +*
  33247. +* DESCRIPTION:
  33248. +* This routine extract the CPU bus clock.
  33249. +*
  33250. +* INPUT:
  33251. +* countNum - Counter number.
  33252. +*
  33253. +* OUTPUT:
  33254. +* None.
  33255. +*
  33256. +* RETURN:
  33257. +* 32bit clock cycles in Hertz.
  33258. +*
  33259. +*******************************************************************************/
  33260. +static MV_U32 mvBoard6180SysClkGet(MV_VOID)
  33261. +{
  33262. + MV_U32 sysClkRate=0;
  33263. + MV_CPU_ARM_CLK _cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;
  33264. +
  33265. + sysClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  33266. + sysClkRate = sysClkRate & MSAR_CPUCLCK_MASK_6180;
  33267. + sysClkRate = sysClkRate >> MSAR_CPUCLCK_OFFS_6180;
  33268. +
  33269. + sysClkRate = _cpu6180_ddr_l2_CLK[sysClkRate].ddrClk;
  33270. +
  33271. + return sysClkRate;
  33272. +
  33273. +}
  33274. +
  33275. +MV_U32 mvBoardSysClkGet(MV_VOID)
  33276. +{
  33277. +#ifdef SYSCLK_AUTO_DETECT
  33278. + MV_U32 sysClkRate, tmp, pClkRate, indexDdrRtio;
  33279. + MV_U32 cpuCLK[] = MV_CPU_CLCK_TBL;
  33280. + MV_U32 ddrRtio[][2] = MV_DDR_CLCK_RTIO_TBL;
  33281. +
  33282. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  33283. + return mvBoard6180SysClkGet();
  33284. +
  33285. + tmp = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  33286. + pClkRate = MSAR_CPUCLCK_EXTRACT(tmp);
  33287. + pClkRate = cpuCLK[pClkRate];
  33288. +
  33289. + indexDdrRtio = tmp & MSAR_DDRCLCK_RTIO_MASK;
  33290. + indexDdrRtio = indexDdrRtio >> MSAR_DDRCLCK_RTIO_OFFS;
  33291. + if(ddrRtio[indexDdrRtio][0] != 0)
  33292. + sysClkRate = ((pClkRate * ddrRtio[indexDdrRtio][1]) / ddrRtio[indexDdrRtio][0]);
  33293. + else
  33294. + sysClkRate = 0;
  33295. + return sysClkRate;
  33296. +#else
  33297. + return MV_BOARD_DEFAULT_SYSCLK;
  33298. +#endif
  33299. +}
  33300. +
  33301. +
  33302. +/*******************************************************************************
  33303. +* mvBoardPexBridgeIntPinGet - Get PEX to PCI bridge interrupt pin number
  33304. +*
  33305. +* DESCRIPTION:
  33306. +* Multi-ported PCI Express bridges that is implemented on the board
  33307. +* collapse interrupts across multiple conventional PCI/PCI-X buses.
  33308. +* A dual-headed PCI Express bridge would map (or "swizzle") the
  33309. +* interrupts per the following table (in accordance with the respective
  33310. +* logical PCI/PCI-X bridge's Device Number), collapse the INTA#-INTD#
  33311. +* signals from its two logical PCI/PCI-X bridges, collapse the
  33312. +* INTA#-INTD# signals from any internal sources, and convert the
  33313. +* signals to in-band PCI Express messages. 10
  33314. +* This function returns the upstream interrupt as it was converted by
  33315. +* the bridge, according to board configuration and the following table:
  33316. +* PCI dev num
  33317. +* Interrupt pin 7, 8, 9
  33318. +* A -> A D C
  33319. +* B -> B A D
  33320. +* C -> C B A
  33321. +* D -> D C B
  33322. +*
  33323. +*
  33324. +* INPUT:
  33325. +* devNum - PCI/PCIX device number.
  33326. +* intPin - PCI Int pin
  33327. +*
  33328. +* OUTPUT:
  33329. +* None.
  33330. +*
  33331. +* RETURN:
  33332. +* Int pin connected to the Interrupt controller
  33333. +*
  33334. +*******************************************************************************/
  33335. +MV_U32 mvBoardPexBridgeIntPinGet(MV_U32 devNum, MV_U32 intPin)
  33336. +{
  33337. + MV_U32 realIntPin = ((intPin + (3 - (devNum % 4))) %4 );
  33338. +
  33339. + if (realIntPin == 0) return 4;
  33340. + else return realIntPin;
  33341. +
  33342. +}
  33343. +
  33344. +/*******************************************************************************
  33345. +* mvBoardDebugLedNumGet - Get number of debug Leds
  33346. +*
  33347. +* DESCRIPTION:
  33348. +* INPUT:
  33349. +* boardId
  33350. +*
  33351. +* OUTPUT:
  33352. +* None.
  33353. +*
  33354. +* RETURN:
  33355. +* None.
  33356. +*
  33357. +*******************************************************************************/
  33358. +MV_U32 mvBoardDebugLedNumGet(MV_U32 boardId)
  33359. +{
  33360. + return BOARD_INFO(boardId)->activeLedsNumber;
  33361. +}
  33362. +
  33363. +/*******************************************************************************
  33364. +* mvBoardDebugLeg - Set the board debug Leds
  33365. +*
  33366. +* DESCRIPTION: turn on/off status leds.
  33367. +* Note: assume MPP leds are part of group 0 only.
  33368. +*
  33369. +* INPUT:
  33370. +* hexNum - Number to be displied in hex by Leds.
  33371. +*
  33372. +* OUTPUT:
  33373. +* None.
  33374. +*
  33375. +* RETURN:
  33376. +* None.
  33377. +*
  33378. +*******************************************************************************/
  33379. +MV_VOID mvBoardDebugLed(MV_U32 hexNum)
  33380. +{
  33381. + MV_U32 val = 0,totalMask, currentBitMask = 1,i;
  33382. + MV_U32 boardId= mvBoardIdGet();
  33383. +
  33384. + if (BOARD_INFO(boardId)->pLedGppPin == NULL)
  33385. + return;
  33386. +
  33387. + totalMask = (1 << BOARD_INFO(boardId)->activeLedsNumber) -1;
  33388. + hexNum &= totalMask;
  33389. + totalMask = 0;
  33390. +
  33391. + for (i = 0 ; i < BOARD_INFO(boardId)->activeLedsNumber ; i++)
  33392. + {
  33393. + if (hexNum & currentBitMask)
  33394. + {
  33395. + val |= (1 << BOARD_INFO(boardId)->pLedGppPin[i]);
  33396. + }
  33397. +
  33398. + totalMask |= (1 << BOARD_INFO(boardId)->pLedGppPin[i]);
  33399. +
  33400. + currentBitMask = (currentBitMask << 1);
  33401. + }
  33402. +
  33403. + if (BOARD_INFO(boardId)->ledsPolarity)
  33404. + {
  33405. + mvGppValueSet(0, totalMask, val);
  33406. + }
  33407. + else
  33408. + {
  33409. + mvGppValueSet(0, totalMask, ~val);
  33410. + }
  33411. +}
  33412. +
  33413. +
  33414. +/*******************************************************************************
  33415. +* mvBoarGpioPinGet - mvBoarGpioPinGet
  33416. +*
  33417. +* DESCRIPTION:
  33418. +*
  33419. +* INPUT:
  33420. +* class - MV_BOARD_GPP_CLASS enum.
  33421. +*
  33422. +* OUTPUT:
  33423. +* None.
  33424. +*
  33425. +* RETURN:
  33426. +* GPIO pin number. The function return -1 for bad parameters.
  33427. +*
  33428. +*******************************************************************************/
  33429. +MV_32 mvBoarGpioPinNumGet(MV_BOARD_GPP_CLASS class, MV_U32 index)
  33430. +{
  33431. + MV_U32 boardId, i;
  33432. + MV_U32 indexFound = 0;
  33433. +
  33434. + boardId = mvBoardIdGet();
  33435. +
  33436. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33437. + {
  33438. + mvOsPrintf("mvBoardRTCGpioPinGet:Board unknown.\n");
  33439. + return MV_ERROR;
  33440. +
  33441. + }
  33442. +
  33443. + for (i = 0; i < BOARD_INFO(boardId)->numBoardGppInfo; i++)
  33444. + if (BOARD_INFO(boardId)->pBoardGppInfo[i].devClass == class) {
  33445. + if (indexFound == index)
  33446. + return (MV_U32)BOARD_INFO(boardId)->pBoardGppInfo[i].gppPinNum;
  33447. + else
  33448. + indexFound++;
  33449. +
  33450. + }
  33451. +
  33452. + return MV_ERROR;
  33453. +}
  33454. +
  33455. +
  33456. +/*******************************************************************************
  33457. +* mvBoardRTCGpioPinGet - mvBoardRTCGpioPinGet
  33458. +*
  33459. +* DESCRIPTION:
  33460. +*
  33461. +* INPUT:
  33462. +* None.
  33463. +*
  33464. +* OUTPUT:
  33465. +* None.
  33466. +*
  33467. +* RETURN:
  33468. +* GPIO pin number. The function return -1 for bad parameters.
  33469. +*
  33470. +*******************************************************************************/
  33471. +MV_32 mvBoardRTCGpioPinGet(MV_VOID)
  33472. +{
  33473. + return mvBoarGpioPinNumGet(BOARD_GPP_RTC, 0);
  33474. +}
  33475. +
  33476. +
  33477. +/*******************************************************************************
  33478. +* mvBoardReset - mvBoardReset
  33479. +*
  33480. +* DESCRIPTION:
  33481. +* Reset the board
  33482. +* INPUT:
  33483. +* None.
  33484. +*
  33485. +* OUTPUT:
  33486. +* None.
  33487. +*
  33488. +* RETURN:
  33489. +* None
  33490. +*
  33491. +*******************************************************************************/
  33492. +MV_VOID mvBoardReset(MV_VOID)
  33493. +{
  33494. + MV_32 resetPin;
  33495. +
  33496. + /* Get gpp reset pin if define */
  33497. + resetPin = mvBoardResetGpioPinGet();
  33498. + if (resetPin != MV_ERROR)
  33499. + {
  33500. + MV_REG_BIT_RESET( GPP_DATA_OUT_REG(0) ,(1 << resetPin));
  33501. + MV_REG_BIT_RESET( GPP_DATA_OUT_EN_REG(0) ,(1 << resetPin));
  33502. +
  33503. + }
  33504. + else
  33505. + {
  33506. + /* No gpp reset pin was found, try to reset ussing
  33507. + system reset out */
  33508. + MV_REG_BIT_SET( CPU_RSTOUTN_MASK_REG , BIT2);
  33509. + MV_REG_BIT_SET( CPU_SYS_SOFT_RST_REG , BIT0);
  33510. + }
  33511. +}
  33512. +
  33513. +/*******************************************************************************
  33514. +* mvBoardResetGpioPinGet - mvBoardResetGpioPinGet
  33515. +*
  33516. +* DESCRIPTION:
  33517. +*
  33518. +* INPUT:
  33519. +* None.
  33520. +*
  33521. +* OUTPUT:
  33522. +* None.
  33523. +*
  33524. +* RETURN:
  33525. +* GPIO pin number. The function return -1 for bad parameters.
  33526. +*
  33527. +*******************************************************************************/
  33528. +MV_32 mvBoardResetGpioPinGet(MV_VOID)
  33529. +{
  33530. + return mvBoarGpioPinNumGet(BOARD_GPP_RESET, 0);
  33531. +}
  33532. +/*******************************************************************************
  33533. +* mvBoardSDIOGpioPinGet - mvBoardSDIOGpioPinGet
  33534. +*
  33535. +* DESCRIPTION:
  33536. +* used for hotswap detection
  33537. +* INPUT:
  33538. +* None.
  33539. +*
  33540. +* OUTPUT:
  33541. +* None.
  33542. +*
  33543. +* RETURN:
  33544. +* GPIO pin number. The function return -1 for bad parameters.
  33545. +*
  33546. +*******************************************************************************/
  33547. +MV_32 mvBoardSDIOGpioPinGet(MV_VOID)
  33548. +{
  33549. + return mvBoarGpioPinNumGet(BOARD_GPP_SDIO_DETECT, 0);
  33550. +}
  33551. +
  33552. +/*******************************************************************************
  33553. +* mvBoardUSBVbusGpioPinGet - return Vbus input GPP
  33554. +*
  33555. +* DESCRIPTION:
  33556. +*
  33557. +* INPUT:
  33558. +* int devNo.
  33559. +*
  33560. +* OUTPUT:
  33561. +* None.
  33562. +*
  33563. +* RETURN:
  33564. +* GPIO pin number. The function return -1 for bad parameters.
  33565. +*
  33566. +*******************************************************************************/
  33567. +MV_32 mvBoardUSBVbusGpioPinGet(MV_32 devId)
  33568. +{
  33569. + return mvBoarGpioPinNumGet(BOARD_GPP_USB_VBUS, devId);
  33570. +}
  33571. +
  33572. +/*******************************************************************************
  33573. +* mvBoardUSBVbusEnGpioPinGet - return Vbus Enable output GPP
  33574. +*
  33575. +* DESCRIPTION:
  33576. +*
  33577. +* INPUT:
  33578. +* int devNo.
  33579. +*
  33580. +* OUTPUT:
  33581. +* None.
  33582. +*
  33583. +* RETURN:
  33584. +* GPIO pin number. The function return -1 for bad parameters.
  33585. +*
  33586. +*******************************************************************************/
  33587. +MV_32 mvBoardUSBVbusEnGpioPinGet(MV_32 devId)
  33588. +{
  33589. + return mvBoarGpioPinNumGet(BOARD_GPP_USB_VBUS_EN, devId);
  33590. +}
  33591. +
  33592. +
  33593. +/*******************************************************************************
  33594. +* mvBoardGpioIntMaskGet - Get GPIO mask for interrupt pins
  33595. +*
  33596. +* DESCRIPTION:
  33597. +* This function returns a 32-bit mask of GPP pins that connected to
  33598. +* interrupt generating sources on board.
  33599. +* For example if UART channel A is hardwired to GPP pin 8 and
  33600. +* UART channel B is hardwired to GPP pin 4 the fuinction will return
  33601. +* the value 0x000000110
  33602. +*
  33603. +* INPUT:
  33604. +* None.
  33605. +*
  33606. +* OUTPUT:
  33607. +* None.
  33608. +*
  33609. +* RETURN:
  33610. +* See description. The function return -1 if board is not identified.
  33611. +*
  33612. +*******************************************************************************/
  33613. +MV_32 mvBoardGpioIntMaskLowGet(MV_VOID)
  33614. +{
  33615. + MV_U32 boardId;
  33616. +
  33617. + boardId = mvBoardIdGet();
  33618. +
  33619. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33620. + {
  33621. + mvOsPrintf("mvBoardGpioIntMaskGet:Board unknown.\n");
  33622. + return MV_ERROR;
  33623. +
  33624. + }
  33625. +
  33626. + return BOARD_INFO(boardId)->intsGppMaskLow;
  33627. +}
  33628. +MV_32 mvBoardGpioIntMaskHighGet(MV_VOID)
  33629. +{
  33630. + MV_U32 boardId;
  33631. +
  33632. + boardId = mvBoardIdGet();
  33633. +
  33634. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33635. + {
  33636. + mvOsPrintf("mvBoardGpioIntMaskGet:Board unknown.\n");
  33637. + return MV_ERROR;
  33638. +
  33639. + }
  33640. +
  33641. + return BOARD_INFO(boardId)->intsGppMaskHigh;
  33642. +}
  33643. +
  33644. +
  33645. +/*******************************************************************************
  33646. +* mvBoardMppGet - Get board dependent MPP register value
  33647. +*
  33648. +* DESCRIPTION:
  33649. +* MPP settings are derived from board design.
  33650. +* MPP group consist of 8 MPPs. An MPP group represent MPP
  33651. +* control register.
  33652. +* This function retrieves board dependend MPP register value.
  33653. +*
  33654. +* INPUT:
  33655. +* mppGroupNum - MPP group number.
  33656. +*
  33657. +* OUTPUT:
  33658. +* None.
  33659. +*
  33660. +* RETURN:
  33661. +* 32bit value describing MPP control register value.
  33662. +*
  33663. +*******************************************************************************/
  33664. +MV_32 mvBoardMppGet(MV_U32 mppGroupNum)
  33665. +{
  33666. + MV_U32 boardId;
  33667. +
  33668. + boardId = mvBoardIdGet();
  33669. +
  33670. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33671. + {
  33672. + mvOsPrintf("mvBoardMppGet:Board unknown.\n");
  33673. + return MV_ERROR;
  33674. +
  33675. + }
  33676. +
  33677. + return BOARD_INFO(boardId)->pBoardMppConfigValue[0].mppGroup[mppGroupNum];
  33678. +}
  33679. +
  33680. +
  33681. +/*******************************************************************************
  33682. +* mvBoardMppGroupId - If MPP group type is AUTO then identify it using twsi
  33683. +*
  33684. +* DESCRIPTION:
  33685. +*
  33686. +* INPUT:
  33687. +*
  33688. +* OUTPUT:
  33689. +* None.
  33690. +*
  33691. +* RETURN:
  33692. +*
  33693. +*******************************************************************************/
  33694. +MV_VOID mvBoardMppGroupIdUpdate(MV_VOID)
  33695. +{
  33696. +
  33697. + MV_BOARD_MPP_GROUP_CLASS devClass;
  33698. + MV_BOARD_MODULE_ID_CLASS devClassId;
  33699. + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
  33700. + MV_U32 devId;
  33701. + MV_U32 maxMppGrp = 1;
  33702. +
  33703. + devId = mvCtrlModelGet();
  33704. +
  33705. + switch(devId){
  33706. + case MV_6281_DEV_ID:
  33707. + maxMppGrp = MV_6281_MPP_MAX_MODULE;
  33708. + break;
  33709. + case MV_6192_DEV_ID:
  33710. + maxMppGrp = MV_6192_MPP_MAX_MODULE;
  33711. + break;
  33712. + case MV_6190_DEV_ID:
  33713. + maxMppGrp = MV_6190_MPP_MAX_MODULE;
  33714. + break;
  33715. + case MV_6180_DEV_ID:
  33716. + maxMppGrp = MV_6180_MPP_MAX_MODULE;
  33717. + break;
  33718. + }
  33719. +
  33720. + for (devClass = 0; devClass < maxMppGrp; devClass++)
  33721. + {
  33722. + /* If MPP group can be defined by the module connected to it */
  33723. + if (mvBoardMppGroupTypeGet(devClass) == MV_BOARD_AUTO)
  33724. + {
  33725. + /* Get MPP module ID */
  33726. + devClassId = mvBoarModuleTypeGet(devClass);
  33727. + if (MV_ERROR != devClassId)
  33728. + {
  33729. + switch(devClassId)
  33730. + {
  33731. + case MV_BOARD_MODULE_TDM_ID:
  33732. + case MV_BOARD_MODULE_TDM_5CHAN_ID:
  33733. + mppGroupType = MV_BOARD_TDM;
  33734. + break;
  33735. + case MV_BOARD_MODULE_AUDIO_ID:
  33736. + mppGroupType = MV_BOARD_AUDIO;
  33737. + break;
  33738. + case MV_BOARD_MODULE_RGMII_ID:
  33739. + mppGroupType = MV_BOARD_RGMII;
  33740. + break;
  33741. + case MV_BOARD_MODULE_GMII_ID:
  33742. + mppGroupType = MV_BOARD_GMII;
  33743. + break;
  33744. + case MV_BOARD_MODULE_TS_ID:
  33745. + mppGroupType = MV_BOARD_TS;
  33746. + break;
  33747. + case MV_BOARD_MODULE_MII_ID:
  33748. + mppGroupType = MV_BOARD_MII;
  33749. + break;
  33750. + default:
  33751. + mppGroupType = MV_BOARD_OTHER;
  33752. + break;
  33753. + }
  33754. + }
  33755. + else
  33756. + /* The module bay is empty */
  33757. + mppGroupType = MV_BOARD_OTHER;
  33758. +
  33759. + /* Update MPP group type */
  33760. + mvBoardMppGroupTypeSet(devClass, mppGroupType);
  33761. + }
  33762. +
  33763. + /* Update MPP output voltage for RGMII 1.8V. Set port to GMII for GMII module */
  33764. + if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_RGMII))
  33765. + MV_REG_BIT_SET(MPP_OUTPUT_DRIVE_REG,MPP_1_8_RGMII1_OUTPUT_DRIVE | MPP_1_8_RGMII0_OUTPUT_DRIVE);
  33766. + else
  33767. + {
  33768. + if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_GMII))
  33769. + {
  33770. + MV_REG_BIT_RESET(MPP_OUTPUT_DRIVE_REG, BIT7 | BIT15);
  33771. + MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(0),BIT3);
  33772. + MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(1),BIT3);
  33773. + }
  33774. + else if ((mvBoardMppGroupTypeGet(devClass) == MV_BOARD_MII))
  33775. + {
  33776. + /* Assumption that the MDC & MDIO should be 3.3V */
  33777. + MV_REG_BIT_RESET(MPP_OUTPUT_DRIVE_REG, BIT7 | BIT15);
  33778. + /* Assumption that only ETH1 can be MII when using modules on DB */
  33779. + MV_REG_BIT_RESET(ETH_PORT_SERIAL_CTRL_1_REG(1),BIT3);
  33780. + }
  33781. + }
  33782. + }
  33783. +}
  33784. +
  33785. +/*******************************************************************************
  33786. +* mvBoardMppGroupTypeGet
  33787. +*
  33788. +* DESCRIPTION:
  33789. +*
  33790. +* INPUT:
  33791. +* mppGroupClass - MPP group number 0 for MPP[35:20] or 1 for MPP[49:36].
  33792. +*
  33793. +* OUTPUT:
  33794. +* None.
  33795. +*
  33796. +* RETURN:
  33797. +*
  33798. +*******************************************************************************/
  33799. +MV_BOARD_MPP_TYPE_CLASS mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass)
  33800. +{
  33801. + MV_U32 boardId;
  33802. +
  33803. + boardId = mvBoardIdGet();
  33804. +
  33805. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33806. + {
  33807. + mvOsPrintf("mvBoardMppGet:Board unknown.\n");
  33808. + return MV_ERROR;
  33809. +
  33810. + }
  33811. +
  33812. + if (mppGroupClass == MV_BOARD_MPP_GROUP_1)
  33813. + return BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup1;
  33814. + else
  33815. + return BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup2;
  33816. +}
  33817. +
  33818. +/*******************************************************************************
  33819. +* mvBoardMppGroupTypeSet
  33820. +*
  33821. +* DESCRIPTION:
  33822. +*
  33823. +* INPUT:
  33824. +* mppGroupClass - MPP group number 0 for MPP[35:20] or 1 for MPP[49:36].
  33825. +* mppGroupType - MPP group type for MPP[35:20] or for MPP[49:36].
  33826. +*
  33827. +* OUTPUT:
  33828. +* None.
  33829. +*
  33830. +* RETURN:
  33831. +*
  33832. +*******************************************************************************/
  33833. +MV_VOID mvBoardMppGroupTypeSet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass,
  33834. + MV_BOARD_MPP_TYPE_CLASS mppGroupType)
  33835. +{
  33836. + MV_U32 boardId;
  33837. +
  33838. + boardId = mvBoardIdGet();
  33839. +
  33840. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  33841. + {
  33842. + mvOsPrintf("mvBoardMppGet:Board unknown.\n");
  33843. + }
  33844. +
  33845. + if (mppGroupClass == MV_BOARD_MPP_GROUP_1)
  33846. + BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup1 = mppGroupType;
  33847. + else
  33848. + BOARD_INFO(boardId)->pBoardMppTypeValue[0].boardMppGroup2 = mppGroupType;
  33849. +
  33850. +}
  33851. +
  33852. +/*******************************************************************************
  33853. +* mvBoardMppMuxSet - Update MPP mux
  33854. +*
  33855. +* DESCRIPTION:
  33856. +*
  33857. +* INPUT:
  33858. +*
  33859. +* OUTPUT:
  33860. +* None.
  33861. +*
  33862. +* RETURN:
  33863. +*
  33864. +*******************************************************************************/
  33865. +MV_VOID mvBoardMppMuxSet(MV_VOID)
  33866. +{
  33867. +
  33868. + MV_BOARD_MPP_GROUP_CLASS devClass;
  33869. + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
  33870. + MV_U32 devId;
  33871. + MV_U8 muxVal = 0xf;
  33872. + MV_U32 maxMppGrp = 1;
  33873. + MV_TWSI_SLAVE twsiSlave;
  33874. + MV_TWSI_ADDR slave;
  33875. +
  33876. + devId = mvCtrlModelGet();
  33877. +
  33878. + switch(devId){
  33879. + case MV_6281_DEV_ID:
  33880. + maxMppGrp = MV_6281_MPP_MAX_MODULE;
  33881. + break;
  33882. + case MV_6192_DEV_ID:
  33883. + maxMppGrp = MV_6192_MPP_MAX_MODULE;
  33884. + break;
  33885. + case MV_6190_DEV_ID:
  33886. + maxMppGrp = MV_6190_MPP_MAX_MODULE;
  33887. + break;
  33888. + case MV_6180_DEV_ID:
  33889. + maxMppGrp = MV_6180_MPP_MAX_MODULE;
  33890. + break;
  33891. + }
  33892. +
  33893. + for (devClass = 0; devClass < maxMppGrp; devClass++)
  33894. + {
  33895. + mppGroupType = mvBoardMppGroupTypeGet(devClass);
  33896. +
  33897. + switch(mppGroupType)
  33898. + {
  33899. + case MV_BOARD_TDM:
  33900. + muxVal &= ~(devClass ? (0x2 << (devClass * 2)):0x0);
  33901. + break;
  33902. + case MV_BOARD_AUDIO:
  33903. + muxVal &= ~(devClass ? 0x7 : 0x0); /*old Z0 value 0xd:0x0*/
  33904. + break;
  33905. + case MV_BOARD_TS:
  33906. + muxVal &= ~(devClass ? (0x2 << (devClass * 2)):0x0);
  33907. + break;
  33908. + default:
  33909. + muxVal |= (devClass ? 0xf : 0);
  33910. + break;
  33911. + }
  33912. + }
  33913. +
  33914. + /* TWSI init */
  33915. + slave.type = ADDR7_BIT;
  33916. + slave.address = 0;
  33917. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  33918. +
  33919. + /* Read MPP module ID */
  33920. + DB(mvOsPrintf("Board: twsi exp set\n"));
  33921. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(MV_BOARD_MUX_I2C_ADDR_ENTRY);
  33922. + twsiSlave.slaveAddr.type = mvBoardTwsiExpAddrTypeGet(MV_BOARD_MUX_I2C_ADDR_ENTRY);
  33923. + twsiSlave.validOffset = MV_TRUE;
  33924. + /* Offset is the first command after the address which indicate the register number to be read
  33925. + in next operation */
  33926. + twsiSlave.offset = 2;
  33927. + twsiSlave.moreThen256 = MV_FALSE;
  33928. +
  33929. +
  33930. +
  33931. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  33932. + {
  33933. + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
  33934. + return;
  33935. + }
  33936. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  33937. +
  33938. + /* Change twsi exp to output */
  33939. + twsiSlave.offset = 6;
  33940. + muxVal = 0;
  33941. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  33942. + {
  33943. + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
  33944. + return;
  33945. + }
  33946. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  33947. +
  33948. +}
  33949. +
  33950. +/*******************************************************************************
  33951. +* mvBoardTdmMppSet - set MPPs in TDM module
  33952. +*
  33953. +* DESCRIPTION:
  33954. +*
  33955. +* INPUT: type of second telephony device
  33956. +*
  33957. +* OUTPUT:
  33958. +* None.
  33959. +*
  33960. +* RETURN:
  33961. +*
  33962. +*******************************************************************************/
  33963. +MV_VOID mvBoardTdmMppSet(MV_32 chType)
  33964. +{
  33965. +
  33966. + MV_BOARD_MPP_GROUP_CLASS devClass;
  33967. + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
  33968. + MV_U32 devId;
  33969. + MV_U8 muxVal = 1;
  33970. + MV_U8 muxValMask = 1;
  33971. + MV_U8 twsiVal;
  33972. + MV_U32 maxMppGrp = 1;
  33973. + MV_TWSI_SLAVE twsiSlave;
  33974. + MV_TWSI_ADDR slave;
  33975. +
  33976. + devId = mvCtrlModelGet();
  33977. +
  33978. + switch(devId){
  33979. + case MV_6281_DEV_ID:
  33980. + maxMppGrp = MV_6281_MPP_MAX_MODULE;
  33981. + break;
  33982. + case MV_6192_DEV_ID:
  33983. + maxMppGrp = MV_6192_MPP_MAX_MODULE;
  33984. + break;
  33985. + case MV_6190_DEV_ID:
  33986. + maxMppGrp = MV_6190_MPP_MAX_MODULE;
  33987. + break;
  33988. + case MV_6180_DEV_ID:
  33989. + maxMppGrp = MV_6180_MPP_MAX_MODULE;
  33990. + break;
  33991. + }
  33992. +
  33993. + for (devClass = 0; devClass < maxMppGrp; devClass++)
  33994. + {
  33995. + mppGroupType = mvBoardMppGroupTypeGet(devClass);
  33996. + if(mppGroupType == MV_BOARD_TDM)
  33997. + break;
  33998. + }
  33999. +
  34000. + if(devClass == maxMppGrp)
  34001. + return; /* TDM module not found */
  34002. +
  34003. + /* TWSI init */
  34004. + slave.type = ADDR7_BIT;
  34005. + slave.address = 0;
  34006. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  34007. +
  34008. + /* Read MPP module ID */
  34009. + DB(mvOsPrintf("Board: twsi exp set\n"));
  34010. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(devClass);
  34011. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  34012. + twsiSlave.validOffset = MV_TRUE;
  34013. + /* Offset is the first command after the address which indicate the register number to be read
  34014. + in next operation */
  34015. + twsiSlave.offset = 3;
  34016. + twsiSlave.moreThen256 = MV_FALSE;
  34017. +
  34018. + if(mvBoardIdGet() == RD_88F6281A_ID)
  34019. + {
  34020. + muxVal = 0xc;
  34021. + muxValMask = 0xf3;
  34022. + }
  34023. +
  34024. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  34025. + muxVal = (twsiVal & muxValMask) | muxVal;
  34026. +
  34027. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  34028. + {
  34029. + mvOsPrintf("Board: twsi exp out val fail\n");
  34030. + return;
  34031. + }
  34032. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  34033. +
  34034. + /* Change twsi exp to output */
  34035. + twsiSlave.offset = 7;
  34036. + muxVal = 0xfe;
  34037. + if(mvBoardIdGet() == RD_88F6281A_ID)
  34038. + muxVal = 0xf3;
  34039. +
  34040. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  34041. + muxVal = (twsiVal & muxVal);
  34042. +
  34043. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  34044. + {
  34045. + mvOsPrintf("Board: twsi exp change to out fail\n");
  34046. + return;
  34047. + }
  34048. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  34049. + /* reset the line to 0 */
  34050. + twsiSlave.offset = 3;
  34051. + muxVal = 0;
  34052. + muxValMask = 1;
  34053. +
  34054. + if(mvBoardIdGet() == RD_88F6281A_ID) {
  34055. + muxVal = 0x0;
  34056. + muxValMask = 0xf3;
  34057. + }
  34058. +
  34059. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  34060. + muxVal = (twsiVal & muxValMask) | muxVal;
  34061. +
  34062. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  34063. + {
  34064. + mvOsPrintf("Board: twsi exp out val fail\n");
  34065. + return;
  34066. + }
  34067. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  34068. +
  34069. + mvOsDelay(20);
  34070. +
  34071. + /* set the line to 1 */
  34072. + twsiSlave.offset = 3;
  34073. + muxVal = 1;
  34074. + muxValMask = 1;
  34075. +
  34076. + if(mvBoardIdGet() == RD_88F6281A_ID)
  34077. + {
  34078. + muxVal = 0xc;
  34079. + muxValMask = 0xf3;
  34080. + if(chType) /* FXS - issue reset properly */
  34081. + {
  34082. + MV_REG_BIT_SET(GPP_DATA_OUT_REG(1), MV_GPP12);
  34083. + mvOsDelay(50);
  34084. + MV_REG_BIT_RESET(GPP_DATA_OUT_REG(1), MV_GPP12);
  34085. + }
  34086. + else /* FXO - issue reset via TDM_CODEC_RST*/
  34087. + {
  34088. + /* change MPP44 type to TDM_CODEC_RST(0x2) */
  34089. + MV_REG_WRITE(MPP_CONTROL_REG5, ((MV_REG_READ(MPP_CONTROL_REG5) & 0xFFF0FFFF) | BIT17));
  34090. + }
  34091. + }
  34092. +
  34093. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  34094. + muxVal = (twsiVal & muxValMask) | muxVal;
  34095. +
  34096. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  34097. + {
  34098. + mvOsPrintf("Board: twsi exp out val fail\n");
  34099. + return;
  34100. + }
  34101. +
  34102. + /* TBD - 5 channels */
  34103. +#if defined(MV_TDM_5CHANNELS)
  34104. + /* change MPP38 type to GPIO(0x0) & polarity for TDM_STROBE */
  34105. + MV_REG_WRITE(MPP_CONTROL_REG4, (MV_REG_READ(MPP_CONTROL_REG4) & 0xF0FFFFFF));
  34106. + mvGppPolaritySet(1, MV_GPP6, 0);
  34107. +
  34108. + twsiSlave.offset = 6;
  34109. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(2);
  34110. +
  34111. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  34112. + muxVal = (twsiVal & ~BIT2);
  34113. +
  34114. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  34115. + {
  34116. + mvOsPrintf("Board: twsi exp change to out fail\n");
  34117. + return;
  34118. + }
  34119. +
  34120. +
  34121. + twsiSlave.offset = 2;
  34122. +
  34123. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  34124. + muxVal = (twsiVal & ~BIT2);
  34125. +
  34126. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &muxVal, 1) )
  34127. + {
  34128. + mvOsPrintf("Board: twsi exp change to out fail\n");
  34129. + return;
  34130. + }
  34131. +#endif
  34132. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  34133. +
  34134. +
  34135. +}
  34136. +/*******************************************************************************
  34137. +* mvBoardVoiceConnModeGet - return SLIC/DAA connection & interrupt modes
  34138. +*
  34139. +* DESCRIPTION:
  34140. +*
  34141. +* INPUT:
  34142. +*
  34143. +* OUTPUT:
  34144. +* None.
  34145. +*
  34146. +* RETURN:
  34147. +*
  34148. +*******************************************************************************/
  34149. +
  34150. +MV_VOID mvBoardVoiceConnModeGet(MV_32* connMode, MV_32* irqMode)
  34151. +{
  34152. + switch(mvBoardIdGet())
  34153. + {
  34154. + case RD_88F6281A_ID:
  34155. + *connMode = DAISY_CHAIN_MODE;
  34156. + *irqMode = INTERRUPT_TO_TDM;
  34157. + break;
  34158. + case DB_88F6281A_BP_ID:
  34159. + *connMode = DUAL_CHIP_SELECT_MODE;
  34160. + *irqMode = INTERRUPT_TO_TDM;
  34161. + break;
  34162. + case RD_88F6192A_ID:
  34163. + *connMode = DUAL_CHIP_SELECT_MODE;
  34164. + *irqMode = INTERRUPT_TO_TDM;
  34165. + break;
  34166. + case DB_88F6192A_BP_ID:
  34167. + *connMode = DUAL_CHIP_SELECT_MODE;
  34168. + *irqMode = INTERRUPT_TO_TDM;
  34169. + break;
  34170. + default:
  34171. + *connMode = *irqMode = -1;
  34172. + mvOsPrintf("mvBoardVoiceAssembleModeGet: TDM not supported(boardId=0x%x)\n",mvBoardIdGet());
  34173. + }
  34174. + return;
  34175. +
  34176. +}
  34177. +
  34178. +/*******************************************************************************
  34179. +* mvBoardMppModuleTypePrint - print module detect
  34180. +*
  34181. +* DESCRIPTION:
  34182. +*
  34183. +* INPUT:
  34184. +*
  34185. +* OUTPUT:
  34186. +* None.
  34187. +*
  34188. +* RETURN:
  34189. +*
  34190. +*******************************************************************************/
  34191. +MV_VOID mvBoardMppModuleTypePrint(MV_VOID)
  34192. +{
  34193. +
  34194. + MV_BOARD_MPP_GROUP_CLASS devClass;
  34195. + MV_BOARD_MPP_TYPE_CLASS mppGroupType;
  34196. + MV_U32 devId;
  34197. + MV_U32 maxMppGrp = 1;
  34198. +
  34199. + devId = mvCtrlModelGet();
  34200. +
  34201. + switch(devId){
  34202. + case MV_6281_DEV_ID:
  34203. + maxMppGrp = MV_6281_MPP_MAX_MODULE;
  34204. + break;
  34205. + case MV_6192_DEV_ID:
  34206. + maxMppGrp = MV_6192_MPP_MAX_MODULE;
  34207. + break;
  34208. + case MV_6190_DEV_ID:
  34209. + maxMppGrp = MV_6190_MPP_MAX_MODULE;
  34210. + break;
  34211. + case MV_6180_DEV_ID:
  34212. + maxMppGrp = MV_6180_MPP_MAX_MODULE;
  34213. + break;
  34214. + }
  34215. +
  34216. + for (devClass = 0; devClass < maxMppGrp; devClass++)
  34217. + {
  34218. + mppGroupType = mvBoardMppGroupTypeGet(devClass);
  34219. +
  34220. + switch(mppGroupType)
  34221. + {
  34222. + case MV_BOARD_TDM:
  34223. + if(devId != MV_6190_DEV_ID)
  34224. + mvOsPrintf("Module %d is TDM\n", devClass);
  34225. + break;
  34226. + case MV_BOARD_AUDIO:
  34227. + if(devId != MV_6190_DEV_ID)
  34228. + mvOsPrintf("Module %d is AUDIO\n", devClass);
  34229. + break;
  34230. + case MV_BOARD_RGMII:
  34231. + if(devId != MV_6190_DEV_ID)
  34232. + mvOsPrintf("Module %d is RGMII\n", devClass);
  34233. + break;
  34234. + case MV_BOARD_GMII:
  34235. + if(devId != MV_6190_DEV_ID)
  34236. + mvOsPrintf("Module %d is GMII\n", devClass);
  34237. + break;
  34238. + case MV_BOARD_TS:
  34239. + if(devId != MV_6190_DEV_ID)
  34240. + mvOsPrintf("Module %d is TS\n", devClass);
  34241. + break;
  34242. + default:
  34243. + break;
  34244. + }
  34245. + }
  34246. +}
  34247. +
  34248. +/* Board devices API managments */
  34249. +
  34250. +/*******************************************************************************
  34251. +* mvBoardGetDeviceNumber - Get number of device of some type on the board
  34252. +*
  34253. +* DESCRIPTION:
  34254. +*
  34255. +* INPUT:
  34256. +* devType - The device type ( Flash,RTC , etc .. )
  34257. +*
  34258. +* OUTPUT:
  34259. +* None.
  34260. +*
  34261. +* RETURN:
  34262. +* If the device is found on the board the then the functions returns the
  34263. +* number of those devices else the function returns 0
  34264. +*
  34265. +*
  34266. +*******************************************************************************/
  34267. +MV_32 mvBoardGetDevicesNumber(MV_BOARD_DEV_CLASS devClass)
  34268. +{
  34269. + MV_U32 foundIndex=0,devNum;
  34270. + MV_U32 boardId= mvBoardIdGet();
  34271. +
  34272. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  34273. + {
  34274. + mvOsPrintf("mvBoardGetDeviceNumber:Board unknown.\n");
  34275. + return 0xFFFFFFFF;
  34276. +
  34277. + }
  34278. +
  34279. + for (devNum = START_DEV_CS; devNum < BOARD_INFO(boardId)->numBoardDeviceIf; devNum++)
  34280. + {
  34281. + if (BOARD_INFO(boardId)->pDevCsInfo[devNum].devClass == devClass)
  34282. + {
  34283. + foundIndex++;
  34284. + }
  34285. + }
  34286. +
  34287. + return foundIndex;
  34288. +
  34289. +}
  34290. +
  34291. +/*******************************************************************************
  34292. +* mvBoardGetDeviceBaseAddr - Get base address of a device existing on the board
  34293. +*
  34294. +* DESCRIPTION:
  34295. +*
  34296. +* INPUT:
  34297. +* devIndex - The device sequential number on the board
  34298. +* devType - The device type ( Flash,RTC , etc .. )
  34299. +*
  34300. +* OUTPUT:
  34301. +* None.
  34302. +*
  34303. +* RETURN:
  34304. +* If the device is found on the board the then the functions returns the
  34305. +* Base address else the function returns 0xffffffff
  34306. +*
  34307. +*
  34308. +*******************************************************************************/
  34309. +MV_32 mvBoardGetDeviceBaseAddr(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  34310. +{
  34311. + MV_DEV_CS_INFO* devEntry;
  34312. + devEntry = boardGetDevEntry(devNum,devClass);
  34313. + if (devEntry != NULL)
  34314. + {
  34315. + return mvCpuIfTargetWinBaseLowGet(DEV_TO_TARGET(devEntry->deviceCS));
  34316. +
  34317. + }
  34318. +
  34319. + return 0xFFFFFFFF;
  34320. +}
  34321. +
  34322. +/*******************************************************************************
  34323. +* mvBoardGetDeviceBusWidth - Get Bus width of a device existing on the board
  34324. +*
  34325. +* DESCRIPTION:
  34326. +*
  34327. +* INPUT:
  34328. +* devIndex - The device sequential number on the board
  34329. +* devType - The device type ( Flash,RTC , etc .. )
  34330. +*
  34331. +* OUTPUT:
  34332. +* None.
  34333. +*
  34334. +* RETURN:
  34335. +* If the device is found on the board the then the functions returns the
  34336. +* Bus width else the function returns 0xffffffff
  34337. +*
  34338. +*
  34339. +*******************************************************************************/
  34340. +MV_32 mvBoardGetDeviceBusWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  34341. +{
  34342. + MV_DEV_CS_INFO* devEntry;
  34343. +
  34344. + devEntry = boardGetDevEntry(devNum,devClass);
  34345. + if (devEntry != NULL)
  34346. + {
  34347. + return 8;
  34348. + }
  34349. +
  34350. + return 0xFFFFFFFF;
  34351. +
  34352. +}
  34353. +
  34354. +/*******************************************************************************
  34355. +* mvBoardGetDeviceWidth - Get dev width of a device existing on the board
  34356. +*
  34357. +* DESCRIPTION:
  34358. +*
  34359. +* INPUT:
  34360. +* devIndex - The device sequential number on the board
  34361. +* devType - The device type ( Flash,RTC , etc .. )
  34362. +*
  34363. +* OUTPUT:
  34364. +* None.
  34365. +*
  34366. +* RETURN:
  34367. +* If the device is found on the board the then the functions returns the
  34368. +* dev width else the function returns 0xffffffff
  34369. +*
  34370. +*
  34371. +*******************************************************************************/
  34372. +MV_32 mvBoardGetDeviceWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  34373. +{
  34374. + MV_DEV_CS_INFO* devEntry;
  34375. + MV_U32 boardId= mvBoardIdGet();
  34376. +
  34377. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  34378. + {
  34379. + mvOsPrintf("Board unknown.\n");
  34380. + return 0xFFFFFFFF;
  34381. + }
  34382. +
  34383. + devEntry = boardGetDevEntry(devNum,devClass);
  34384. + if (devEntry != NULL)
  34385. + return devEntry->devWidth;
  34386. +
  34387. + return MV_ERROR;
  34388. +
  34389. +}
  34390. +
  34391. +/*******************************************************************************
  34392. +* mvBoardGetDeviceWinSize - Get the window size of a device existing on the board
  34393. +*
  34394. +* DESCRIPTION:
  34395. +*
  34396. +* INPUT:
  34397. +* devIndex - The device sequential number on the board
  34398. +* devType - The device type ( Flash,RTC , etc .. )
  34399. +*
  34400. +* OUTPUT:
  34401. +* None.
  34402. +*
  34403. +* RETURN:
  34404. +* If the device is found on the board the then the functions returns the
  34405. +* window size else the function returns 0xffffffff
  34406. +*
  34407. +*
  34408. +*******************************************************************************/
  34409. +MV_32 mvBoardGetDeviceWinSize(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  34410. +{
  34411. + MV_DEV_CS_INFO* devEntry;
  34412. + MV_U32 boardId = mvBoardIdGet();
  34413. +
  34414. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  34415. + {
  34416. + mvOsPrintf("Board unknown.\n");
  34417. + return 0xFFFFFFFF;
  34418. + }
  34419. +
  34420. + devEntry = boardGetDevEntry(devNum,devClass);
  34421. + if (devEntry != NULL)
  34422. + {
  34423. + return mvCpuIfTargetWinSizeGet(DEV_TO_TARGET(devEntry->deviceCS));
  34424. + }
  34425. +
  34426. + return 0xFFFFFFFF;
  34427. +}
  34428. +
  34429. +
  34430. +/*******************************************************************************
  34431. +* boardGetDevEntry - returns the entry pointer of a device on the board
  34432. +*
  34433. +* DESCRIPTION:
  34434. +*
  34435. +* INPUT:
  34436. +* devIndex - The device sequential number on the board
  34437. +* devType - The device type ( Flash,RTC , etc .. )
  34438. +*
  34439. +* OUTPUT:
  34440. +* None.
  34441. +*
  34442. +* RETURN:
  34443. +* If the device is found on the board the then the functions returns the
  34444. +* dev number else the function returns 0x0
  34445. +*
  34446. +*
  34447. +*******************************************************************************/
  34448. +static MV_DEV_CS_INFO* boardGetDevEntry(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  34449. +{
  34450. + MV_U32 foundIndex=0,devIndex;
  34451. + MV_U32 boardId= mvBoardIdGet();
  34452. +
  34453. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  34454. + {
  34455. + mvOsPrintf("boardGetDevEntry: Board unknown.\n");
  34456. + return NULL;
  34457. +
  34458. + }
  34459. +
  34460. + for (devIndex = START_DEV_CS; devIndex < BOARD_INFO(boardId)->numBoardDeviceIf; devIndex++)
  34461. + {
  34462. + /* TBR */
  34463. + /*if (BOARD_INFO(boardId)->pDevCsInfo[devIndex].deviceCS == MV_BOOTDEVICE_INDEX)
  34464. + continue;*/
  34465. +
  34466. + if (BOARD_INFO(boardId)->pDevCsInfo[devIndex].devClass == devClass)
  34467. + {
  34468. + if (foundIndex == devNum)
  34469. + {
  34470. + return &(BOARD_INFO(boardId)->pDevCsInfo[devIndex]);
  34471. + }
  34472. + foundIndex++;
  34473. + }
  34474. + }
  34475. +
  34476. + /* device not found */
  34477. + return NULL;
  34478. +}
  34479. +
  34480. +/* Get device CS number */
  34481. +
  34482. +MV_U32 boardGetDevCSNum(MV_32 devNum, MV_BOARD_DEV_CLASS devClass)
  34483. +{
  34484. + MV_DEV_CS_INFO* devEntry;
  34485. + MV_U32 boardId= mvBoardIdGet();
  34486. +
  34487. + if (!((boardId >= BOARD_ID_BASE)&&(boardId < MV_MAX_BOARD_ID)))
  34488. + {
  34489. + mvOsPrintf("Board unknown.\n");
  34490. + return 0xFFFFFFFF;
  34491. +
  34492. + }
  34493. +
  34494. +
  34495. + devEntry = boardGetDevEntry(devNum,devClass);
  34496. + if (devEntry != NULL)
  34497. + return devEntry->deviceCS;
  34498. +
  34499. + return 0xFFFFFFFF;
  34500. +
  34501. +}
  34502. +
  34503. +/*******************************************************************************
  34504. +* mvBoardRtcTwsiAddrTypeGet -
  34505. +*
  34506. +* DESCRIPTION:
  34507. +*
  34508. +* INPUT:
  34509. +*
  34510. +* OUTPUT:
  34511. +* None.
  34512. +*
  34513. +* RETURN:
  34514. +*
  34515. +*
  34516. +*******************************************************************************/
  34517. +MV_U8 mvBoardRtcTwsiAddrTypeGet()
  34518. +{
  34519. + int i;
  34520. + MV_U32 boardId= mvBoardIdGet();
  34521. +
  34522. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  34523. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_RTC)
  34524. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
  34525. + return (MV_ERROR);
  34526. +}
  34527. +
  34528. +/*******************************************************************************
  34529. +* mvBoardRtcTwsiAddrGet -
  34530. +*
  34531. +* DESCRIPTION:
  34532. +*
  34533. +* INPUT:
  34534. +*
  34535. +* OUTPUT:
  34536. +* None.
  34537. +*
  34538. +* RETURN:
  34539. +*
  34540. +*
  34541. +*******************************************************************************/
  34542. +MV_U8 mvBoardRtcTwsiAddrGet()
  34543. +{
  34544. + int i;
  34545. + MV_U32 boardId= mvBoardIdGet();
  34546. +
  34547. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  34548. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_RTC)
  34549. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
  34550. + return (0xFF);
  34551. +}
  34552. +
  34553. +/*******************************************************************************
  34554. +* mvBoardA2DTwsiAddrTypeGet -
  34555. +*
  34556. +* DESCRIPTION:
  34557. +*
  34558. +* INPUT:
  34559. +*
  34560. +* OUTPUT:
  34561. +* None.
  34562. +*
  34563. +* RETURN:
  34564. +*
  34565. +*
  34566. +*******************************************************************************/
  34567. +MV_U8 mvBoardA2DTwsiAddrTypeGet()
  34568. +{
  34569. + int i;
  34570. + MV_U32 boardId= mvBoardIdGet();
  34571. +
  34572. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  34573. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_AUDIO_DEC)
  34574. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
  34575. + return (MV_ERROR);
  34576. +}
  34577. +
  34578. +/*******************************************************************************
  34579. +* mvBoardA2DTwsiAddrGet -
  34580. +*
  34581. +* DESCRIPTION:
  34582. +*
  34583. +* INPUT:
  34584. +*
  34585. +* OUTPUT:
  34586. +* None.
  34587. +*
  34588. +* RETURN:
  34589. +*
  34590. +*
  34591. +*******************************************************************************/
  34592. +MV_U8 mvBoardA2DTwsiAddrGet()
  34593. +{
  34594. + int i;
  34595. + MV_U32 boardId= mvBoardIdGet();
  34596. +
  34597. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  34598. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_TWSI_AUDIO_DEC)
  34599. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
  34600. + return (0xFF);
  34601. +}
  34602. +
  34603. +/*******************************************************************************
  34604. +* mvBoardTwsiExpAddrTypeGet -
  34605. +*
  34606. +* DESCRIPTION:
  34607. +*
  34608. +* INPUT:
  34609. +*
  34610. +* OUTPUT:
  34611. +* None.
  34612. +*
  34613. +* RETURN:
  34614. +*
  34615. +*
  34616. +*******************************************************************************/
  34617. +MV_U8 mvBoardTwsiExpAddrTypeGet(MV_U32 index)
  34618. +{
  34619. + int i;
  34620. + MV_U32 indexFound = 0;
  34621. + MV_U32 boardId= mvBoardIdGet();
  34622. +
  34623. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  34624. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_EXP)
  34625. + {
  34626. + if (indexFound == index)
  34627. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
  34628. + else
  34629. + indexFound++;
  34630. + }
  34631. +
  34632. + return (MV_ERROR);
  34633. +}
  34634. +
  34635. +/*******************************************************************************
  34636. +* mvBoardTwsiExpAddrGet -
  34637. +*
  34638. +* DESCRIPTION:
  34639. +*
  34640. +* INPUT:
  34641. +*
  34642. +* OUTPUT:
  34643. +* None.
  34644. +*
  34645. +* RETURN:
  34646. +*
  34647. +*
  34648. +*******************************************************************************/
  34649. +MV_U8 mvBoardTwsiExpAddrGet(MV_U32 index)
  34650. +{
  34651. + int i;
  34652. + MV_U32 indexFound = 0;
  34653. + MV_U32 boardId= mvBoardIdGet();
  34654. +
  34655. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  34656. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_EXP)
  34657. + {
  34658. + if (indexFound == index)
  34659. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
  34660. + else
  34661. + indexFound++;
  34662. + }
  34663. +
  34664. + return (0xFF);
  34665. +}
  34666. +
  34667. +
  34668. +/*******************************************************************************
  34669. +* mvBoardTwsiSatRAddrTypeGet -
  34670. +*
  34671. +* DESCRIPTION:
  34672. +*
  34673. +* INPUT:
  34674. +*
  34675. +* OUTPUT:
  34676. +* None.
  34677. +*
  34678. +* RETURN:
  34679. +*
  34680. +*
  34681. +*******************************************************************************/
  34682. +MV_U8 mvBoardTwsiSatRAddrTypeGet(MV_U32 index)
  34683. +{
  34684. + int i;
  34685. + MV_U32 indexFound = 0;
  34686. + MV_U32 boardId= mvBoardIdGet();
  34687. +
  34688. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  34689. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_SATR)
  34690. + {
  34691. + if (indexFound == index)
  34692. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddrType;
  34693. + else
  34694. + indexFound++;
  34695. + }
  34696. +
  34697. + return (MV_ERROR);
  34698. +}
  34699. +
  34700. +/*******************************************************************************
  34701. +* mvBoardTwsiSatRAddrGet -
  34702. +*
  34703. +* DESCRIPTION:
  34704. +*
  34705. +* INPUT:
  34706. +*
  34707. +* OUTPUT:
  34708. +* None.
  34709. +*
  34710. +* RETURN:
  34711. +*
  34712. +*
  34713. +*******************************************************************************/
  34714. +MV_U8 mvBoardTwsiSatRAddrGet(MV_U32 index)
  34715. +{
  34716. + int i;
  34717. + MV_U32 indexFound = 0;
  34718. + MV_U32 boardId= mvBoardIdGet();
  34719. +
  34720. + for (i = 0; i < BOARD_INFO(boardId)->numBoardTwsiDev; i++)
  34721. + if (BOARD_INFO(boardId)->pBoardTwsiDev[i].devClass == BOARD_DEV_TWSI_SATR)
  34722. + {
  34723. + if (indexFound == index)
  34724. + return BOARD_INFO(boardId)->pBoardTwsiDev[i].twsiDevAddr;
  34725. + else
  34726. + indexFound++;
  34727. + }
  34728. +
  34729. + return (0xFF);
  34730. +}
  34731. +
  34732. +/*******************************************************************************
  34733. +* mvBoardNandWidthGet -
  34734. +*
  34735. +* DESCRIPTION: Get the width of the first NAND device in byte.
  34736. +*
  34737. +* INPUT:
  34738. +*
  34739. +* OUTPUT:
  34740. +* None.
  34741. +*
  34742. +* RETURN: 1, 2, 4 or MV_ERROR
  34743. +*
  34744. +*
  34745. +*******************************************************************************/
  34746. +/* */
  34747. +MV_32 mvBoardNandWidthGet(void)
  34748. +{
  34749. + MV_U32 devNum;
  34750. + MV_U32 devWidth;
  34751. + MV_U32 boardId= mvBoardIdGet();
  34752. +
  34753. + for (devNum = START_DEV_CS; devNum < BOARD_INFO(boardId)->numBoardDeviceIf; devNum++)
  34754. + {
  34755. + devWidth = mvBoardGetDeviceWidth(devNum, BOARD_DEV_NAND_FLASH);
  34756. + if (devWidth != MV_ERROR)
  34757. + return (devWidth / 8);
  34758. + }
  34759. +
  34760. + /* NAND wasn't found */
  34761. + return MV_ERROR;
  34762. +}
  34763. +
  34764. +MV_U32 gBoardId = -1;
  34765. +
  34766. +/*******************************************************************************
  34767. +* mvBoardIdGet - Get Board model
  34768. +*
  34769. +* DESCRIPTION:
  34770. +* This function returns board ID.
  34771. +* Board ID is 32bit word constructed of board model (16bit) and
  34772. +* board revision (16bit) in the following way: 0xMMMMRRRR.
  34773. +*
  34774. +* INPUT:
  34775. +* None.
  34776. +*
  34777. +* OUTPUT:
  34778. +* None.
  34779. +*
  34780. +* RETURN:
  34781. +* 32bit board ID number, '-1' if board is undefined.
  34782. +*
  34783. +*******************************************************************************/
  34784. +MV_U32 mvBoardIdGet(MV_VOID)
  34785. +{
  34786. + MV_U32 tmpBoardId = -1;
  34787. +
  34788. + if(gBoardId == -1)
  34789. + {
  34790. + #if defined(DB_88F6281A)
  34791. + tmpBoardId = DB_88F6281A_BP_ID;
  34792. + #elif defined(RD_88F6281A)
  34793. + tmpBoardId = RD_88F6281A_ID;
  34794. + #elif defined(DB_88F6192A)
  34795. + tmpBoardId = DB_88F6192A_BP_ID;
  34796. + #elif defined(DB_88F6190A)
  34797. + tmpBoardId = DB_88F6190A_BP_ID;
  34798. + #elif defined(RD_88F6192A)
  34799. + tmpBoardId = RD_88F6192A_ID;
  34800. + #elif defined(RD_88F6190A)
  34801. + tmpBoardId = RD_88F6190A_ID;
  34802. + #elif defined(DB_88F6180A)
  34803. + tmpBoardId = DB_88F6180A_BP_ID;
  34804. + #elif defined(RD_88F6281A_PCAC)
  34805. + tmpBoardId = RD_88F6281A_PCAC_ID;
  34806. + #elif defined(RD_88F6281A_SHEEVA_PLUG)
  34807. + tmpBoardId = SHEEVA_PLUG_ID;
  34808. + #elif defined(DB_CUSTOMER)
  34809. + tmpBoardId = DB_CUSTOMER_ID;
  34810. + #endif
  34811. + gBoardId = tmpBoardId;
  34812. + }
  34813. +
  34814. + return gBoardId;
  34815. +}
  34816. +
  34817. +
  34818. +/*******************************************************************************
  34819. +* mvBoarModuleTypeGet - mvBoarModuleTypeGet
  34820. +*
  34821. +* DESCRIPTION:
  34822. +*
  34823. +* INPUT:
  34824. +* group num - MV_BOARD_MPP_GROUP_CLASS enum
  34825. +*
  34826. +* OUTPUT:
  34827. +* None.
  34828. +*
  34829. +* RETURN:
  34830. +* module num - MV_BOARD_MODULE_CLASS enum
  34831. +*
  34832. +*******************************************************************************/
  34833. +MV_BOARD_MODULE_ID_CLASS mvBoarModuleTypeGet(MV_BOARD_MPP_GROUP_CLASS devClass)
  34834. +{
  34835. + MV_TWSI_SLAVE twsiSlave;
  34836. + MV_TWSI_ADDR slave;
  34837. + MV_U8 data;
  34838. +
  34839. + /* TWSI init */
  34840. + slave.type = ADDR7_BIT;
  34841. + slave.address = 0;
  34842. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  34843. +
  34844. + /* Read MPP module ID */
  34845. + DB(mvOsPrintf("Board: Read MPP module ID\n"));
  34846. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(devClass);
  34847. + twsiSlave.slaveAddr.type = mvBoardTwsiExpAddrTypeGet(devClass);
  34848. + twsiSlave.validOffset = MV_TRUE;
  34849. + /* Offset is the first command after the address which indicate the register number to be read
  34850. + in next operation */
  34851. + twsiSlave.offset = 0;
  34852. + twsiSlave.moreThen256 = MV_FALSE;
  34853. +
  34854. +
  34855. +
  34856. + if( MV_OK != mvTwsiRead (0, &twsiSlave, &data, 1) )
  34857. + {
  34858. + DB(mvOsPrintf("Board: Read MPP module ID fail\n"));
  34859. + return MV_ERROR;
  34860. + }
  34861. + DB(mvOsPrintf("Board: Read MPP module ID succeded\n"));
  34862. +
  34863. + return data;
  34864. +}
  34865. +
  34866. +/*******************************************************************************
  34867. +* mvBoarTwsiSatRGet -
  34868. +*
  34869. +* DESCRIPTION:
  34870. +*
  34871. +* INPUT:
  34872. +* device num - one of three devices
  34873. +* reg num - 0 or 1
  34874. +*
  34875. +* OUTPUT:
  34876. +* None.
  34877. +*
  34878. +* RETURN:
  34879. +* reg value
  34880. +*
  34881. +*******************************************************************************/
  34882. +MV_U8 mvBoarTwsiSatRGet(MV_U8 devNum, MV_U8 regNum)
  34883. +{
  34884. + MV_TWSI_SLAVE twsiSlave;
  34885. + MV_TWSI_ADDR slave;
  34886. + MV_U8 data;
  34887. +
  34888. + /* TWSI init */
  34889. + slave.type = ADDR7_BIT;
  34890. + slave.address = 0;
  34891. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  34892. +
  34893. + /* Read MPP module ID */
  34894. + DB(mvOsPrintf("Board: Read S@R device read\n"));
  34895. + twsiSlave.slaveAddr.address = mvBoardTwsiSatRAddrGet(devNum);
  34896. + twsiSlave.slaveAddr.type = mvBoardTwsiSatRAddrTypeGet(devNum);
  34897. + twsiSlave.validOffset = MV_TRUE;
  34898. + /* Use offset as command */
  34899. + twsiSlave.offset = regNum;
  34900. + twsiSlave.moreThen256 = MV_FALSE;
  34901. +
  34902. + if( MV_OK != mvTwsiRead (0, &twsiSlave, &data, 1) )
  34903. + {
  34904. + DB(mvOsPrintf("Board: Read S@R fail\n"));
  34905. + return MV_ERROR;
  34906. + }
  34907. + DB(mvOsPrintf("Board: Read S@R succeded\n"));
  34908. +
  34909. + return data;
  34910. +}
  34911. +
  34912. +/*******************************************************************************
  34913. +* mvBoarTwsiSatRSet -
  34914. +*
  34915. +* DESCRIPTION:
  34916. +*
  34917. +* INPUT:
  34918. +* devNum - one of three devices
  34919. +* regNum - 0 or 1
  34920. +* regVal - value
  34921. +*
  34922. +*
  34923. +* OUTPUT:
  34924. +* None.
  34925. +*
  34926. +* RETURN:
  34927. +* reg value
  34928. +*
  34929. +*******************************************************************************/
  34930. +MV_STATUS mvBoarTwsiSatRSet(MV_U8 devNum, MV_U8 regNum, MV_U8 regVal)
  34931. +{
  34932. + MV_TWSI_SLAVE twsiSlave;
  34933. + MV_TWSI_ADDR slave;
  34934. +
  34935. + /* TWSI init */
  34936. + slave.type = ADDR7_BIT;
  34937. + slave.address = 0;
  34938. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  34939. +
  34940. + /* Read MPP module ID */
  34941. + twsiSlave.slaveAddr.address = mvBoardTwsiSatRAddrGet(devNum);
  34942. + twsiSlave.slaveAddr.type = mvBoardTwsiSatRAddrTypeGet(devNum);
  34943. + twsiSlave.validOffset = MV_TRUE;
  34944. + DB(mvOsPrintf("Board: Write S@R device addr %x, type %x, data %x\n", twsiSlave.slaveAddr.address,\
  34945. + twsiSlave.slaveAddr.type, regVal));
  34946. + /* Use offset as command */
  34947. + twsiSlave.offset = regNum;
  34948. + twsiSlave.moreThen256 = MV_FALSE;
  34949. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &regVal, 1) )
  34950. + {
  34951. + DB(mvOsPrintf("Board: Write S@R fail\n"));
  34952. + return MV_ERROR;
  34953. + }
  34954. + DB(mvOsPrintf("Board: Write S@R succeded\n"));
  34955. +
  34956. + return MV_OK;
  34957. +}
  34958. +
  34959. +/*******************************************************************************
  34960. +* mvBoardSlicGpioPinGet -
  34961. +*
  34962. +* DESCRIPTION:
  34963. +*
  34964. +* INPUT:
  34965. +*
  34966. +* OUTPUT:
  34967. +* None.
  34968. +*
  34969. +* RETURN:
  34970. +*
  34971. +*
  34972. +*******************************************************************************/
  34973. +MV_32 mvBoardSlicGpioPinGet(MV_U32 slicNum)
  34974. +{
  34975. + MV_U32 boardId;
  34976. + boardId = mvBoardIdGet();
  34977. +
  34978. + switch (boardId)
  34979. + {
  34980. + case DB_88F6281A_BP_ID:
  34981. + case RD_88F6281A_ID:
  34982. + default:
  34983. + return MV_ERROR;
  34984. + break;
  34985. +
  34986. + }
  34987. +}
  34988. +
  34989. +/*******************************************************************************
  34990. +* mvBoardFanPowerControl - Turn on/off the fan power control on the RD-6281A
  34991. +*
  34992. +* DESCRIPTION:
  34993. +*
  34994. +* INPUT:
  34995. +* mode - MV_TRUE = on ; MV_FALSE = off
  34996. +*
  34997. +* OUTPUT:
  34998. +* MV_STATUS - MV_OK , MV_ERROR.
  34999. +*
  35000. +* RETURN:
  35001. +*
  35002. +*******************************************************************************/
  35003. +MV_STATUS mvBoardFanPowerControl(MV_BOOL mode)
  35004. +{
  35005. +
  35006. + MV_U8 val = 1, twsiVal;
  35007. + MV_TWSI_SLAVE twsiSlave;
  35008. + MV_TWSI_ADDR slave;
  35009. +
  35010. + if(mvBoardIdGet() != RD_88F6281A_ID)
  35011. + return MV_ERROR;
  35012. +
  35013. + /* TWSI init */
  35014. + slave.type = ADDR7_BIT;
  35015. + slave.address = 0;
  35016. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  35017. +
  35018. + /* Read MPP module ID */
  35019. + DB(mvOsPrintf("Board: twsi exp set\n"));
  35020. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(1);
  35021. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  35022. + twsiSlave.validOffset = MV_TRUE;
  35023. + /* Offset is the first command after the address which indicate the register number to be read
  35024. + in next operation */
  35025. + twsiSlave.offset = 3;
  35026. + twsiSlave.moreThen256 = MV_FALSE;
  35027. + if(mode == MV_TRUE)
  35028. + val = 0x1;
  35029. + else
  35030. + val = 0;
  35031. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  35032. + val = (twsiVal & 0xfe) | val;
  35033. +
  35034. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  35035. + {
  35036. + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
  35037. + return MV_ERROR;
  35038. + }
  35039. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  35040. +
  35041. + /* Change twsi exp to output */
  35042. + twsiSlave.offset = 7;
  35043. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  35044. + val = (twsiVal & 0xfe);
  35045. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  35046. + {
  35047. + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
  35048. + return MV_ERROR;
  35049. + }
  35050. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  35051. + return MV_OK;
  35052. +}
  35053. +
  35054. +/*******************************************************************************
  35055. +* mvBoardHDDPowerControl - Turn on/off the HDD power control on the RD-6281A
  35056. +*
  35057. +* DESCRIPTION:
  35058. +*
  35059. +* INPUT:
  35060. +* mode - MV_TRUE = on ; MV_FALSE = off
  35061. +*
  35062. +* OUTPUT:
  35063. +* MV_STATUS - MV_OK , MV_ERROR.
  35064. +*
  35065. +* RETURN:
  35066. +*
  35067. +*******************************************************************************/
  35068. +MV_STATUS mvBoardHDDPowerControl(MV_BOOL mode)
  35069. +{
  35070. +
  35071. + MV_U8 val = 1, twsiVal;
  35072. + MV_TWSI_SLAVE twsiSlave;
  35073. + MV_TWSI_ADDR slave;
  35074. +
  35075. + if(mvBoardIdGet() != RD_88F6281A_ID)
  35076. + return MV_ERROR;
  35077. +
  35078. + /* TWSI init */
  35079. + slave.type = ADDR7_BIT;
  35080. + slave.address = 0;
  35081. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  35082. +
  35083. + /* Read MPP module ID */
  35084. + DB(mvOsPrintf("Board: twsi exp set\n"));
  35085. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(1);
  35086. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  35087. + twsiSlave.validOffset = MV_TRUE;
  35088. + /* Offset is the first command after the address which indicate the register number to be read
  35089. + in next operation */
  35090. + twsiSlave.offset = 3;
  35091. + twsiSlave.moreThen256 = MV_FALSE;
  35092. + if(mode == MV_TRUE)
  35093. + val = 0x2;
  35094. + else
  35095. + val = 0;
  35096. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  35097. + val = (twsiVal & 0xfd) | val;
  35098. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  35099. + {
  35100. + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
  35101. + return MV_ERROR;
  35102. + }
  35103. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  35104. +
  35105. + /* Change twsi exp to output */
  35106. + twsiSlave.offset = 7;
  35107. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  35108. + val = (twsiVal & 0xfd);
  35109. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  35110. + {
  35111. + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
  35112. + return MV_ERROR;
  35113. + }
  35114. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  35115. + return MV_OK;
  35116. +}
  35117. +
  35118. +/*******************************************************************************
  35119. +* mvBoardSDioWPControl - Turn on/off the SDIO WP on the RD-6281A
  35120. +*
  35121. +* DESCRIPTION:
  35122. +*
  35123. +* INPUT:
  35124. +* mode - MV_TRUE = on ; MV_FALSE = off
  35125. +*
  35126. +* OUTPUT:
  35127. +* MV_STATUS - MV_OK , MV_ERROR.
  35128. +*
  35129. +* RETURN:
  35130. +*
  35131. +*******************************************************************************/
  35132. +MV_STATUS mvBoardSDioWPControl(MV_BOOL mode)
  35133. +{
  35134. +
  35135. + MV_U8 val = 1, twsiVal;
  35136. + MV_TWSI_SLAVE twsiSlave;
  35137. + MV_TWSI_ADDR slave;
  35138. +
  35139. + if(mvBoardIdGet() != RD_88F6281A_ID)
  35140. + return MV_ERROR;
  35141. +
  35142. + /* TWSI init */
  35143. + slave.type = ADDR7_BIT;
  35144. + slave.address = 0;
  35145. + mvTwsiInit(0, TWSI_SPEED, mvBoardTclkGet(), &slave, 0);
  35146. +
  35147. + /* Read MPP module ID */
  35148. + DB(mvOsPrintf("Board: twsi exp set\n"));
  35149. + twsiSlave.slaveAddr.address = mvBoardTwsiExpAddrGet(0);
  35150. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  35151. + twsiSlave.validOffset = MV_TRUE;
  35152. + /* Offset is the first command after the address which indicate the register number to be read
  35153. + in next operation */
  35154. + twsiSlave.offset = 3;
  35155. + twsiSlave.moreThen256 = MV_FALSE;
  35156. + if(mode == MV_TRUE)
  35157. + val = 0x10;
  35158. + else
  35159. + val = 0;
  35160. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  35161. + val = (twsiVal & 0xef) | val;
  35162. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  35163. + {
  35164. + DB(mvOsPrintf("Board: twsi exp out val fail\n"));
  35165. + return MV_ERROR;
  35166. + }
  35167. + DB(mvOsPrintf("Board: twsi exp out val succeded\n"));
  35168. +
  35169. + /* Change twsi exp to output */
  35170. + twsiSlave.offset = 7;
  35171. + mvTwsiRead(0, &twsiSlave, &twsiVal, 1);
  35172. + val = (twsiVal & 0xef);
  35173. + if( MV_OK != mvTwsiWrite (0, &twsiSlave, &val, 1) )
  35174. + {
  35175. + DB(mvOsPrintf("Board: twsi exp change to out fail\n"));
  35176. + return MV_ERROR;
  35177. + }
  35178. + DB(mvOsPrintf("Board: twsi exp change to out succeded\n"));
  35179. + return MV_OK;
  35180. +}
  35181. +
  35182. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h
  35183. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h 1970-01-01 01:00:00.000000000 +0100
  35184. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvLib.h 2011-08-01 14:38:19.000000000 +0200
  35185. @@ -0,0 +1,376 @@
  35186. +/*******************************************************************************
  35187. +Copyright (C) Marvell International Ltd. and its affiliates
  35188. +
  35189. +This software file (the "File") is owned and distributed by Marvell
  35190. +International Ltd. and/or its affiliates ("Marvell") under the following
  35191. +alternative licensing terms. Once you have made an election to distribute the
  35192. +File under one of the following license alternatives, please (i) delete this
  35193. +introductory statement regarding license alternatives, (ii) delete the two
  35194. +license alternatives that you have not elected to use and (iii) preserve the
  35195. +Marvell copyright notice above.
  35196. +
  35197. +********************************************************************************
  35198. +Marvell Commercial License Option
  35199. +
  35200. +If you received this File from Marvell and you have entered into a commercial
  35201. +license agreement (a "Commercial License") with Marvell, the File is licensed
  35202. +to you under the terms of the applicable Commercial License.
  35203. +
  35204. +********************************************************************************
  35205. +Marvell GPL License Option
  35206. +
  35207. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35208. +modify this File in accordance with the terms and conditions of the General
  35209. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  35210. +available along with the File in the license.txt file or by writing to the Free
  35211. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  35212. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  35213. +
  35214. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  35215. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  35216. +DISCLAIMED. The GPL License provides additional details about this warranty
  35217. +disclaimer.
  35218. +********************************************************************************
  35219. +Marvell BSD License Option
  35220. +
  35221. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35222. +modify this File under the following licensing terms.
  35223. +Redistribution and use in source and binary forms, with or without modification,
  35224. +are permitted provided that the following conditions are met:
  35225. +
  35226. + * Redistributions of source code must retain the above copyright notice,
  35227. + this list of conditions and the following disclaimer.
  35228. +
  35229. + * Redistributions in binary form must reproduce the above copyright
  35230. + notice, this list of conditions and the following disclaimer in the
  35231. + documentation and/or other materials provided with the distribution.
  35232. +
  35233. + * Neither the name of Marvell nor the names of its contributors may be
  35234. + used to endorse or promote products derived from this software without
  35235. + specific prior written permission.
  35236. +
  35237. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  35238. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  35239. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  35240. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  35241. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  35242. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  35243. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  35244. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  35245. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  35246. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35247. +
  35248. +*******************************************************************************/
  35249. +#ifndef __INCmvBoardEnvLibh
  35250. +#define __INCmvBoardEnvLibh
  35251. +
  35252. +/* defines */
  35253. +/* The below constant macros defines the board I2C EEPROM data offsets */
  35254. +
  35255. +
  35256. +
  35257. +#include "ctrlEnv/mvCtrlEnvLib.h"
  35258. +#include "mvSysHwConfig.h"
  35259. +#include "boardEnv/mvBoardEnvSpec.h"
  35260. +
  35261. +
  35262. +/* DUART stuff for Tclk detection only */
  35263. +#define DUART_BAUD_RATE 115200
  35264. +#define MAX_CLOCK_MARGINE 5000000 /* Maximum detected clock margine */
  35265. +
  35266. +/* Voice devices assembly modes */
  35267. +#define DAISY_CHAIN_MODE 1
  35268. +#define DUAL_CHIP_SELECT_MODE 0
  35269. +#define INTERRUPT_TO_MPP 1
  35270. +#define INTERRUPT_TO_TDM 0
  35271. +
  35272. +
  35273. +#define BOARD_ETH_PORT_NUM MV_ETH_MAX_PORTS
  35274. +#define BOARD_ETH_SWITCH_PORT_NUM 5
  35275. +
  35276. +#define MV_BOARD_MAX_USB_IF 1
  35277. +#define MV_BOARD_MAX_MPP 7
  35278. +#define MV_BOARD_NAME_LEN 0x20
  35279. +
  35280. +typedef struct _boardData
  35281. +{
  35282. + MV_U32 magic;
  35283. + MV_U16 boardId;
  35284. + MV_U8 boardVer;
  35285. + MV_U8 boardRev;
  35286. + MV_U32 reserved1;
  35287. + MV_U32 reserved2;
  35288. +
  35289. +}BOARD_DATA;
  35290. +
  35291. +typedef enum _devBoardMppGroupClass
  35292. +{
  35293. + MV_BOARD_MPP_GROUP_1,
  35294. + MV_BOARD_MPP_GROUP_2,
  35295. + MV_BOARD_MAX_MPP_GROUP
  35296. +}MV_BOARD_MPP_GROUP_CLASS;
  35297. +
  35298. +typedef enum _devBoardMppTypeClass
  35299. +{
  35300. + MV_BOARD_AUTO,
  35301. + MV_BOARD_TDM,
  35302. + MV_BOARD_AUDIO,
  35303. + MV_BOARD_RGMII,
  35304. + MV_BOARD_GMII,
  35305. + MV_BOARD_TS,
  35306. + MV_BOARD_MII,
  35307. + MV_BOARD_OTHER
  35308. +}MV_BOARD_MPP_TYPE_CLASS;
  35309. +
  35310. +typedef enum _devBoardModuleIdClass
  35311. +{
  35312. + MV_BOARD_MODULE_TDM_ID = 1,
  35313. + MV_BOARD_MODULE_AUDIO_ID,
  35314. + MV_BOARD_MODULE_RGMII_ID,
  35315. + MV_BOARD_MODULE_GMII_ID,
  35316. + MV_BOARD_MODULE_TS_ID,
  35317. + MV_BOARD_MODULE_MII_ID,
  35318. + MV_BOARD_MODULE_TDM_5CHAN_ID,
  35319. + MV_BOARD_MODULE_OTHER_ID
  35320. +}MV_BOARD_MODULE_ID_CLASS;
  35321. +
  35322. +typedef struct _boardMppTypeInfo
  35323. +{
  35324. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup1;
  35325. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2;
  35326. +
  35327. +}MV_BOARD_MPP_TYPE_INFO;
  35328. +
  35329. +
  35330. +typedef enum _devBoardClass
  35331. +{
  35332. + BOARD_DEV_NOR_FLASH,
  35333. + BOARD_DEV_NAND_FLASH,
  35334. + BOARD_DEV_SEVEN_SEG,
  35335. + BOARD_DEV_FPGA,
  35336. + BOARD_DEV_SRAM,
  35337. + BOARD_DEV_SPI_FLASH,
  35338. + BOARD_DEV_OTHER,
  35339. +}MV_BOARD_DEV_CLASS;
  35340. +
  35341. +typedef enum _devTwsiBoardClass
  35342. +{
  35343. + BOARD_TWSI_RTC,
  35344. + BOARD_DEV_TWSI_EXP,
  35345. + BOARD_DEV_TWSI_SATR,
  35346. + BOARD_TWSI_AUDIO_DEC,
  35347. + BOARD_TWSI_OTHER
  35348. +}MV_BOARD_TWSI_CLASS;
  35349. +
  35350. +typedef enum _devGppBoardClass
  35351. +{
  35352. + BOARD_GPP_RTC,
  35353. + BOARD_GPP_MV_SWITCH,
  35354. + BOARD_GPP_USB_VBUS,
  35355. + BOARD_GPP_USB_VBUS_EN,
  35356. + BOARD_GPP_USB_OC,
  35357. + BOARD_GPP_USB_HOST_DEVICE,
  35358. + BOARD_GPP_REF_CLCK,
  35359. + BOARD_GPP_VOIP_SLIC,
  35360. + BOARD_GPP_LIFELINE,
  35361. + BOARD_GPP_BUTTON,
  35362. + BOARD_GPP_TS_BUTTON_C,
  35363. + BOARD_GPP_TS_BUTTON_U,
  35364. + BOARD_GPP_TS_BUTTON_D,
  35365. + BOARD_GPP_TS_BUTTON_L,
  35366. + BOARD_GPP_TS_BUTTON_R,
  35367. + BOARD_GPP_POWER_BUTTON,
  35368. + BOARD_GPP_RESTOR_BUTTON,
  35369. + BOARD_GPP_WPS_BUTTON,
  35370. + BOARD_GPP_HDD0_POWER,
  35371. + BOARD_GPP_HDD1_POWER,
  35372. + BOARD_GPP_FAN_POWER,
  35373. + BOARD_GPP_RESET,
  35374. + BOARD_GPP_POWER_ON_LED,
  35375. + BOARD_GPP_HDD_POWER,
  35376. + BOARD_GPP_SDIO_POWER,
  35377. + BOARD_GPP_SDIO_DETECT,
  35378. + BOARD_GPP_SDIO_WP,
  35379. + BOARD_GPP_SWITCH_PHY_INT,
  35380. + BOARD_GPP_TSU_DIRCTION,
  35381. + BOARD_GPP_OTHER
  35382. +}MV_BOARD_GPP_CLASS;
  35383. +
  35384. +
  35385. +typedef struct _devCsInfo
  35386. +{
  35387. + MV_U8 deviceCS;
  35388. + MV_U32 params;
  35389. + MV_U32 devClass; /* MV_BOARD_DEV_CLASS */
  35390. + MV_U8 devWidth;
  35391. +
  35392. +}MV_DEV_CS_INFO;
  35393. +
  35394. +
  35395. +#define MV_BOARD_PHY_FORCE_10MB 0x0
  35396. +#define MV_BOARD_PHY_FORCE_100MB 0x1
  35397. +#define MV_BOARD_PHY_FORCE_1000MB 0x2
  35398. +#define MV_BOARD_PHY_SPEED_AUTO 0x3
  35399. +
  35400. +typedef struct _boardSwitchInfo
  35401. +{
  35402. + MV_32 linkStatusIrq;
  35403. + MV_32 qdPort[BOARD_ETH_SWITCH_PORT_NUM];
  35404. + MV_32 qdCpuPort;
  35405. + MV_32 smiScanMode; /* 1 for SMI_MANUAL_MODE, 0 otherwise */
  35406. + MV_32 switchOnPort;
  35407. +
  35408. +}MV_BOARD_SWITCH_INFO;
  35409. +
  35410. +typedef struct _boardLedInfo
  35411. +{
  35412. + MV_U8 activeLedsNumber;
  35413. + MV_U8 ledsPolarity; /* '0' or '1' to turn on led */
  35414. + MV_U8* gppPinNum; /* Pointer to GPP values */
  35415. +
  35416. +}MV_BOARD_LED_INFO;
  35417. +
  35418. +typedef struct _boardGppInfo
  35419. +{
  35420. + MV_BOARD_GPP_CLASS devClass;
  35421. + MV_U8 gppPinNum;
  35422. +
  35423. +}MV_BOARD_GPP_INFO;
  35424. +
  35425. +
  35426. +typedef struct _boardTwsiInfo
  35427. +{
  35428. + MV_BOARD_TWSI_CLASS devClass;
  35429. + MV_U8 twsiDevAddr;
  35430. + MV_U8 twsiDevAddrType;
  35431. +
  35432. +}MV_BOARD_TWSI_INFO;
  35433. +
  35434. +
  35435. +typedef enum _boardMacSpeed
  35436. +{
  35437. + BOARD_MAC_SPEED_10M,
  35438. + BOARD_MAC_SPEED_100M,
  35439. + BOARD_MAC_SPEED_1000M,
  35440. + BOARD_MAC_SPEED_AUTO,
  35441. +
  35442. +}MV_BOARD_MAC_SPEED;
  35443. +
  35444. +typedef struct _boardMacInfo
  35445. +{
  35446. + MV_BOARD_MAC_SPEED boardMacSpeed;
  35447. + MV_U8 boardEthSmiAddr;
  35448. +
  35449. +}MV_BOARD_MAC_INFO;
  35450. +
  35451. +typedef struct _boardMppInfo
  35452. +{
  35453. + MV_U32 mppGroup[MV_BOARD_MAX_MPP];
  35454. +
  35455. +}MV_BOARD_MPP_INFO;
  35456. +
  35457. +typedef struct _boardInfo
  35458. +{
  35459. + char boardName[MV_BOARD_NAME_LEN];
  35460. + MV_U8 numBoardMppTypeValue;
  35461. + MV_BOARD_MPP_TYPE_INFO* pBoardMppTypeValue;
  35462. + MV_U8 numBoardMppConfigValue;
  35463. + MV_BOARD_MPP_INFO* pBoardMppConfigValue;
  35464. + MV_U32 intsGppMaskLow;
  35465. + MV_U32 intsGppMaskHigh;
  35466. + MV_U8 numBoardDeviceIf;
  35467. + MV_DEV_CS_INFO* pDevCsInfo;
  35468. + MV_U8 numBoardTwsiDev;
  35469. + MV_BOARD_TWSI_INFO* pBoardTwsiDev;
  35470. + MV_U8 numBoardMacInfo;
  35471. + MV_BOARD_MAC_INFO* pBoardMacInfo;
  35472. + MV_U8 numBoardGppInfo;
  35473. + MV_BOARD_GPP_INFO* pBoardGppInfo;
  35474. + MV_U8 activeLedsNumber;
  35475. + MV_U8* pLedGppPin;
  35476. + MV_U8 ledsPolarity; /* '0' or '1' to turn on led */
  35477. + /* GPP values */
  35478. + MV_U32 gppOutEnValLow;
  35479. + MV_U32 gppOutEnValHigh;
  35480. + MV_U32 gppOutValLow;
  35481. + MV_U32 gppOutValHigh;
  35482. + MV_U32 gppPolarityValLow;
  35483. + MV_U32 gppPolarityValHigh;
  35484. +
  35485. + /* Switch Configuration */
  35486. + MV_BOARD_SWITCH_INFO* pSwitchInfo;
  35487. +}MV_BOARD_INFO;
  35488. +
  35489. +
  35490. +
  35491. +MV_VOID mvBoardEnvInit(MV_VOID);
  35492. +MV_U32 mvBoardIdGet(MV_VOID);
  35493. +MV_U16 mvBoardModelGet(MV_VOID);
  35494. +MV_U16 mvBoardRevGet(MV_VOID);
  35495. +MV_STATUS mvBoardNameGet(char *pNameBuff);
  35496. +MV_32 mvBoardPhyAddrGet(MV_U32 ethPortNum);
  35497. +MV_BOARD_MAC_SPEED mvBoardMacSpeedGet(MV_U32 ethPortNum);
  35498. +MV_32 mvBoardLinkStatusIrqGet(MV_U32 ethPortNum);
  35499. +MV_32 mvBoardSwitchPortGet(MV_U32 ethPortNum, MV_U8 boardPortNum);
  35500. +MV_32 mvBoardSwitchCpuPortGet(MV_U32 ethPortNum);
  35501. +MV_32 mvBoardIsSwitchConnected(MV_U32 ethPortNum);
  35502. +MV_32 mvBoardSmiScanModeGet(MV_U32 ethPortNum);
  35503. +MV_BOOL mvBoardIsPortInSgmii(MV_U32 ethPortNum);
  35504. +MV_BOOL mvBoardIsPortInGmii(MV_VOID);
  35505. +MV_U32 mvBoardTclkGet(MV_VOID);
  35506. +MV_U32 mvBoardSysClkGet(MV_VOID);
  35507. +MV_U32 mvBoardDebugLedNumGet(MV_U32 boardId);
  35508. +MV_VOID mvBoardDebugLed(MV_U32 hexNum);
  35509. +MV_32 mvBoardMppGet(MV_U32 mppGroupNum);
  35510. +
  35511. +MV_U8 mvBoardRtcTwsiAddrTypeGet(MV_VOID);
  35512. +MV_U8 mvBoardRtcTwsiAddrGet(MV_VOID);
  35513. +
  35514. +MV_U8 mvBoardA2DTwsiAddrTypeGet(MV_VOID);
  35515. +MV_U8 mvBoardA2DTwsiAddrGet(MV_VOID);
  35516. +
  35517. +MV_U8 mvBoardTwsiExpAddrGet(MV_U32 index);
  35518. +MV_U8 mvBoardTwsiSatRAddrTypeGet(MV_U32 index);
  35519. +MV_U8 mvBoardTwsiSatRAddrGet(MV_U32 index);
  35520. +MV_U8 mvBoardTwsiExpAddrTypeGet(MV_U32 index);
  35521. +MV_BOARD_MODULE_ID_CLASS mvBoarModuleTypeGet(MV_BOARD_MPP_GROUP_CLASS devClass);
  35522. +MV_BOARD_MPP_TYPE_CLASS mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass);
  35523. +MV_VOID mvBoardMppGroupTypeSet(MV_BOARD_MPP_GROUP_CLASS mppGroupClass,
  35524. + MV_BOARD_MPP_TYPE_CLASS mppGroupType);
  35525. +MV_VOID mvBoardMppGroupIdUpdate(MV_VOID);
  35526. +MV_VOID mvBoardMppMuxSet(MV_VOID);
  35527. +MV_VOID mvBoardTdmMppSet(MV_32 chType);
  35528. +MV_VOID mvBoardVoiceConnModeGet(MV_32* connMode, MV_32* irqMode);
  35529. +
  35530. +MV_VOID mvBoardMppModuleTypePrint(MV_VOID);
  35531. +MV_VOID mvBoardReset(MV_VOID);
  35532. +MV_U8 mvBoarTwsiSatRGet(MV_U8 devNum, MV_U8 regNum);
  35533. +MV_STATUS mvBoarTwsiSatRSet(MV_U8 devNum, MV_U8 regNum, MV_U8 regVal);
  35534. +MV_BOOL mvBoardSpecInitGet(MV_U32* regOff, MV_U32* data);
  35535. +/* Board devices API managments */
  35536. +MV_32 mvBoardGetDevicesNumber(MV_BOARD_DEV_CLASS devClass);
  35537. +MV_32 mvBoardGetDeviceBaseAddr(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  35538. +MV_32 mvBoardGetDeviceBusWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  35539. +MV_32 mvBoardGetDeviceWidth(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  35540. +MV_32 mvBoardGetDeviceWinSize(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  35541. +MV_U32 boardGetDevCSNum(MV_32 devNum, MV_BOARD_DEV_CLASS devClass);
  35542. +
  35543. +/* Gpio Pin Connections API */
  35544. +MV_32 mvBoardUSBVbusGpioPinGet(int devId);
  35545. +MV_32 mvBoardUSBVbusEnGpioPinGet(int devId);
  35546. +MV_U32 mvBoardPexBridgeIntPinGet(MV_U32 devNum, MV_U32 intPin);
  35547. +
  35548. +MV_32 mvBoardResetGpioPinGet(MV_VOID);
  35549. +MV_32 mvBoardRTCGpioPinGet(MV_VOID);
  35550. +MV_32 mvBoardGpioIntMaskLowGet(MV_VOID);
  35551. +MV_32 mvBoardGpioIntMaskHighGet(MV_VOID);
  35552. +MV_32 mvBoardSlicGpioPinGet(MV_U32 slicNum);
  35553. +
  35554. +MV_32 mvBoardSDIOGpioPinGet(MV_VOID);
  35555. +MV_STATUS mvBoardSDioWPControl(MV_BOOL mode);
  35556. +MV_32 mvBoarGpioPinNumGet(MV_BOARD_GPP_CLASS class, MV_U32 index);
  35557. +
  35558. +MV_32 mvBoardNandWidthGet(void);
  35559. +MV_STATUS mvBoardFanPowerControl(MV_BOOL mode);
  35560. +MV_STATUS mvBoardHDDPowerControl(MV_BOOL mode);
  35561. +#endif /* __INCmvBoardEnvLibh */
  35562. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c
  35563. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c 1970-01-01 01:00:00.000000000 +0100
  35564. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.c 2011-08-01 14:38:19.000000000 +0200
  35565. @@ -0,0 +1,848 @@
  35566. +/*******************************************************************************
  35567. +Copyright (C) Marvell International Ltd. and its affiliates
  35568. +
  35569. +This software file (the "File") is owned and distributed by Marvell
  35570. +International Ltd. and/or its affiliates ("Marvell") under the following
  35571. +alternative licensing terms. Once you have made an election to distribute the
  35572. +File under one of the following license alternatives, please (i) delete this
  35573. +introductory statement regarding license alternatives, (ii) delete the two
  35574. +license alternatives that you have not elected to use and (iii) preserve the
  35575. +Marvell copyright notice above.
  35576. +
  35577. +********************************************************************************
  35578. +Marvell Commercial License Option
  35579. +
  35580. +If you received this File from Marvell and you have entered into a commercial
  35581. +license agreement (a "Commercial License") with Marvell, the File is licensed
  35582. +to you under the terms of the applicable Commercial License.
  35583. +
  35584. +********************************************************************************
  35585. +Marvell GPL License Option
  35586. +
  35587. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35588. +modify this File in accordance with the terms and conditions of the General
  35589. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  35590. +available along with the File in the license.txt file or by writing to the Free
  35591. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  35592. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  35593. +
  35594. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  35595. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  35596. +DISCLAIMED. The GPL License provides additional details about this warranty
  35597. +disclaimer.
  35598. +********************************************************************************
  35599. +Marvell BSD License Option
  35600. +
  35601. +If you received this File from Marvell, you may opt to use, redistribute and/or
  35602. +modify this File under the following licensing terms.
  35603. +Redistribution and use in source and binary forms, with or without modification,
  35604. +are permitted provided that the following conditions are met:
  35605. +
  35606. + * Redistributions of source code must retain the above copyright notice,
  35607. + this list of conditions and the following disclaimer.
  35608. +
  35609. + * Redistributions in binary form must reproduce the above copyright
  35610. + notice, this list of conditions and the following disclaimer in the
  35611. + documentation and/or other materials provided with the distribution.
  35612. +
  35613. + * Neither the name of Marvell nor the names of its contributors may be
  35614. + used to endorse or promote products derived from this software without
  35615. + specific prior written permission.
  35616. +
  35617. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  35618. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  35619. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  35620. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  35621. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  35622. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  35623. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  35624. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  35625. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  35626. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35627. +
  35628. +*******************************************************************************/
  35629. +#include "mvCommon.h"
  35630. +#include "mvBoardEnvLib.h"
  35631. +#include "mvBoardEnvSpec.h"
  35632. +#include "twsi/mvTwsi.h"
  35633. +
  35634. +#define DB_88F6281A_BOARD_PCI_IF_NUM 0x0
  35635. +#define DB_88F6281A_BOARD_TWSI_DEF_NUM 0x7
  35636. +#define DB_88F6281A_BOARD_MAC_INFO_NUM 0x2
  35637. +#define DB_88F6281A_BOARD_GPP_INFO_NUM 0x3
  35638. +#define DB_88F6281A_BOARD_MPP_CONFIG_NUM 0x1
  35639. +#define DB_88F6281A_BOARD_MPP_GROUP_TYPE_NUM 0x1
  35640. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  35641. + #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
  35642. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  35643. + #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x2
  35644. +#else
  35645. + #define DB_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
  35646. +#endif
  35647. +#define DB_88F6281A_BOARD_DEBUG_LED_NUM 0x0
  35648. +
  35649. +
  35650. +MV_BOARD_TWSI_INFO db88f6281AInfoBoardTwsiDev[] =
  35651. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  35652. + {
  35653. + {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},
  35654. + {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},
  35655. + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},
  35656. + {BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},
  35657. + {BOARD_DEV_TWSI_SATR, 0x4D, ADDR7_BIT},
  35658. + {BOARD_DEV_TWSI_SATR, 0x4E, ADDR7_BIT},
  35659. + {BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}
  35660. + };
  35661. +
  35662. +MV_BOARD_MAC_INFO db88f6281AInfoBoardMacInfo[] =
  35663. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  35664. + {
  35665. + {BOARD_MAC_SPEED_AUTO, 0x8},
  35666. + {BOARD_MAC_SPEED_AUTO, 0x9}
  35667. + };
  35668. +
  35669. +MV_BOARD_MPP_TYPE_INFO db88f6281AInfoBoardMppTypeInfo[] =
  35670. + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
  35671. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
  35672. + {{MV_BOARD_AUTO, MV_BOARD_AUTO}
  35673. + };
  35674. +
  35675. +MV_BOARD_GPP_INFO db88f6281AInfoBoardGppInfo[] =
  35676. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  35677. + {
  35678. + {BOARD_GPP_TSU_DIRCTION, 33}
  35679. + /*muxed with TDM/Audio module via IOexpender
  35680. + {BOARD_GPP_SDIO_DETECT, 38},
  35681. + {BOARD_GPP_USB_VBUS, 49}*/
  35682. + };
  35683. +
  35684. +MV_DEV_CS_INFO db88f6281AInfoBoardDeCsInfo[] =
  35685. + /*{deviceCS, params, devType, devWidth}*/
  35686. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  35687. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  35688. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  35689. + {
  35690. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  35691. + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  35692. + };
  35693. +#else
  35694. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  35695. +#endif
  35696. +
  35697. +MV_BOARD_MPP_INFO db88f6281AInfoBoardMppConfigValue[] =
  35698. + {{{
  35699. + DB_88F6281A_MPP0_7,
  35700. + DB_88F6281A_MPP8_15,
  35701. + DB_88F6281A_MPP16_23,
  35702. + DB_88F6281A_MPP24_31,
  35703. + DB_88F6281A_MPP32_39,
  35704. + DB_88F6281A_MPP40_47,
  35705. + DB_88F6281A_MPP48_55
  35706. + }}};
  35707. +
  35708. +
  35709. +MV_BOARD_INFO db88f6281AInfo = {
  35710. + "DB-88F6281A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
  35711. + DB_88F6281A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  35712. + db88f6281AInfoBoardMppTypeInfo,
  35713. + DB_88F6281A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  35714. + db88f6281AInfoBoardMppConfigValue,
  35715. + 0, /* intsGppMaskLow */
  35716. + 0, /* intsGppMaskHigh */
  35717. + DB_88F6281A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  35718. + db88f6281AInfoBoardDeCsInfo,
  35719. + DB_88F6281A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  35720. + db88f6281AInfoBoardTwsiDev,
  35721. + DB_88F6281A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  35722. + db88f6281AInfoBoardMacInfo,
  35723. + DB_88F6281A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  35724. + db88f6281AInfoBoardGppInfo,
  35725. + DB_88F6281A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  35726. + NULL,
  35727. + 0, /* ledsPolarity */
  35728. + DB_88F6281A_OE_LOW, /* gppOutEnLow */
  35729. + DB_88F6281A_OE_HIGH, /* gppOutEnHigh */
  35730. + DB_88F6281A_OE_VAL_LOW, /* gppOutValLow */
  35731. + DB_88F6281A_OE_VAL_HIGH, /* gppOutValHigh */
  35732. + 0, /* gppPolarityValLow */
  35733. + BIT6, /* gppPolarityValHigh */
  35734. + NULL /* pSwitchInfo */
  35735. +};
  35736. +
  35737. +
  35738. +#define RD_88F6281A_BOARD_PCI_IF_NUM 0x0
  35739. +#define RD_88F6281A_BOARD_TWSI_DEF_NUM 0x2
  35740. +#define RD_88F6281A_BOARD_MAC_INFO_NUM 0x2
  35741. +#define RD_88F6281A_BOARD_GPP_INFO_NUM 0x5
  35742. +#define RD_88F6281A_BOARD_MPP_GROUP_TYPE_NUM 0x1
  35743. +#define RD_88F6281A_BOARD_MPP_CONFIG_NUM 0x1
  35744. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  35745. + #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
  35746. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  35747. + #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x2
  35748. +#else
  35749. + #define RD_88F6281A_BOARD_DEVICE_CONFIG_NUM 0x1
  35750. +#endif
  35751. +#define RD_88F6281A_BOARD_DEBUG_LED_NUM 0x0
  35752. +
  35753. +MV_BOARD_MAC_INFO rd88f6281AInfoBoardMacInfo[] =
  35754. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  35755. + {{BOARD_MAC_SPEED_1000M, 0xa},
  35756. + {BOARD_MAC_SPEED_AUTO, 0xb}
  35757. + };
  35758. +
  35759. +MV_BOARD_SWITCH_INFO rd88f6281AInfoBoardSwitchInfo[] =
  35760. + /* MV_32 linkStatusIrq, {MV_32 qdPort0, MV_32 qdPort1, MV_32 qdPort2, MV_32 qdPort3, MV_32 qdPort4},
  35761. + MV_32 qdCpuPort, MV_32 smiScanMode, MV_32 switchOnPort} */
  35762. + {{38, {0, 1, 2, 3, -1}, 5, 2, 0},
  35763. + {-1, {-1}, -1, -1, -1}};
  35764. +
  35765. +MV_BOARD_TWSI_INFO rd88f6281AInfoBoardTwsiDev[] =
  35766. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  35767. + {
  35768. + {BOARD_DEV_TWSI_EXP, 0xFF, ADDR7_BIT}, /* dummy entry to align with modules indexes */
  35769. + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT}
  35770. + };
  35771. +
  35772. +MV_BOARD_MPP_TYPE_INFO rd88f6281AInfoBoardMppTypeInfo[] =
  35773. + {{MV_BOARD_RGMII, MV_BOARD_TDM}
  35774. + };
  35775. +
  35776. +MV_DEV_CS_INFO rd88f6281AInfoBoardDeCsInfo[] =
  35777. + /*{deviceCS, params, devType, devWidth}*/
  35778. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  35779. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  35780. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  35781. + {
  35782. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  35783. + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  35784. + };
  35785. +#else
  35786. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  35787. +#endif
  35788. +
  35789. +MV_BOARD_GPP_INFO rd88f6281AInfoBoardGppInfo[] =
  35790. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  35791. + {{BOARD_GPP_SDIO_DETECT, 28},
  35792. + {BOARD_GPP_USB_OC, 29},
  35793. + {BOARD_GPP_WPS_BUTTON, 35},
  35794. + {BOARD_GPP_MV_SWITCH, 38},
  35795. + {BOARD_GPP_USB_VBUS, 49}
  35796. + };
  35797. +
  35798. +MV_BOARD_MPP_INFO rd88f6281AInfoBoardMppConfigValue[] =
  35799. + {{{
  35800. + RD_88F6281A_MPP0_7,
  35801. + RD_88F6281A_MPP8_15,
  35802. + RD_88F6281A_MPP16_23,
  35803. + RD_88F6281A_MPP24_31,
  35804. + RD_88F6281A_MPP32_39,
  35805. + RD_88F6281A_MPP40_47,
  35806. + RD_88F6281A_MPP48_55
  35807. + }}};
  35808. +
  35809. +MV_BOARD_INFO rd88f6281AInfo = {
  35810. + "RD-88F6281A", /* boardName[MAX_BOARD_NAME_LEN] */
  35811. + RD_88F6281A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  35812. + rd88f6281AInfoBoardMppTypeInfo,
  35813. + RD_88F6281A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  35814. + rd88f6281AInfoBoardMppConfigValue,
  35815. + 0, /* intsGppMaskLow */
  35816. + (1 << 3), /* intsGppMaskHigh */
  35817. + RD_88F6281A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  35818. + rd88f6281AInfoBoardDeCsInfo,
  35819. + RD_88F6281A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  35820. + rd88f6281AInfoBoardTwsiDev,
  35821. + RD_88F6281A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  35822. + rd88f6281AInfoBoardMacInfo,
  35823. + RD_88F6281A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  35824. + rd88f6281AInfoBoardGppInfo,
  35825. + RD_88F6281A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  35826. + NULL,
  35827. + 0, /* ledsPolarity */
  35828. + RD_88F6281A_OE_LOW, /* gppOutEnLow */
  35829. + RD_88F6281A_OE_HIGH, /* gppOutEnHigh */
  35830. + RD_88F6281A_OE_VAL_LOW, /* gppOutValLow */
  35831. + RD_88F6281A_OE_VAL_HIGH, /* gppOutValHigh */
  35832. + 0, /* gppPolarityValLow */
  35833. + BIT6, /* gppPolarityValHigh */
  35834. + rd88f6281AInfoBoardSwitchInfo /* pSwitchInfo */
  35835. +};
  35836. +
  35837. +
  35838. +#define DB_88F6192A_BOARD_PCI_IF_NUM 0x0
  35839. +#define DB_88F6192A_BOARD_TWSI_DEF_NUM 0x7
  35840. +#define DB_88F6192A_BOARD_MAC_INFO_NUM 0x2
  35841. +#define DB_88F6192A_BOARD_GPP_INFO_NUM 0x3
  35842. +#define DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM 0x1
  35843. +#define DB_88F6192A_BOARD_MPP_CONFIG_NUM 0x1
  35844. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  35845. + #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x1
  35846. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  35847. + #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x2
  35848. +#else
  35849. + #define DB_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x1
  35850. +#endif
  35851. +#define DB_88F6192A_BOARD_DEBUG_LED_NUM 0x0
  35852. +
  35853. +MV_BOARD_TWSI_INFO db88f6192AInfoBoardTwsiDev[] =
  35854. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  35855. + {
  35856. + {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},
  35857. + {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},
  35858. + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},
  35859. + {BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},
  35860. + {BOARD_DEV_TWSI_SATR, 0x4D, ADDR7_BIT},
  35861. + {BOARD_DEV_TWSI_SATR, 0x4E, ADDR7_BIT},
  35862. + {BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}
  35863. + };
  35864. +
  35865. +MV_BOARD_MAC_INFO db88f6192AInfoBoardMacInfo[] =
  35866. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  35867. + {
  35868. + {BOARD_MAC_SPEED_AUTO, 0x8},
  35869. + {BOARD_MAC_SPEED_AUTO, 0x9}
  35870. + };
  35871. +
  35872. +MV_BOARD_MPP_TYPE_INFO db88f6192AInfoBoardMppTypeInfo[] =
  35873. + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
  35874. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
  35875. + {{MV_BOARD_AUTO, MV_BOARD_OTHER}
  35876. + };
  35877. +
  35878. +MV_DEV_CS_INFO db88f6192AInfoBoardDeCsInfo[] =
  35879. + /*{deviceCS, params, devType, devWidth}*/
  35880. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  35881. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  35882. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  35883. + {
  35884. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  35885. + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  35886. + };
  35887. +#else
  35888. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  35889. +#endif
  35890. +
  35891. +MV_BOARD_GPP_INFO db88f6192AInfoBoardGppInfo[] =
  35892. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  35893. + {
  35894. + {BOARD_GPP_SDIO_WP, 20},
  35895. + {BOARD_GPP_USB_VBUS, 22},
  35896. + {BOARD_GPP_SDIO_DETECT, 23},
  35897. + };
  35898. +
  35899. +MV_BOARD_MPP_INFO db88f6192AInfoBoardMppConfigValue[] =
  35900. + {{{
  35901. + DB_88F6192A_MPP0_7,
  35902. + DB_88F6192A_MPP8_15,
  35903. + DB_88F6192A_MPP16_23,
  35904. + DB_88F6192A_MPP24_31,
  35905. + DB_88F6192A_MPP32_35
  35906. + }}};
  35907. +
  35908. +MV_BOARD_INFO db88f6192AInfo = {
  35909. + "DB-88F6192A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
  35910. + DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  35911. + db88f6192AInfoBoardMppTypeInfo,
  35912. + DB_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  35913. + db88f6192AInfoBoardMppConfigValue,
  35914. + 0, /* intsGppMaskLow */
  35915. + (1 << 3), /* intsGppMaskHigh */
  35916. + DB_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  35917. + db88f6192AInfoBoardDeCsInfo,
  35918. + DB_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  35919. + db88f6192AInfoBoardTwsiDev,
  35920. + DB_88F6192A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  35921. + db88f6192AInfoBoardMacInfo,
  35922. + DB_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  35923. + db88f6192AInfoBoardGppInfo,
  35924. + DB_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  35925. + NULL,
  35926. + 0, /* ledsPolarity */
  35927. + DB_88F6192A_OE_LOW, /* gppOutEnLow */
  35928. + DB_88F6192A_OE_HIGH, /* gppOutEnHigh */
  35929. + DB_88F6192A_OE_VAL_LOW, /* gppOutValLow */
  35930. + DB_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
  35931. + 0, /* gppPolarityValLow */
  35932. + 0, /* gppPolarityValHigh */
  35933. + NULL /* pSwitchInfo */
  35934. +};
  35935. +
  35936. +#define DB_88F6190A_BOARD_MAC_INFO_NUM 0x1
  35937. +
  35938. +MV_BOARD_INFO db88f6190AInfo = {
  35939. + "DB-88F6190A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
  35940. + DB_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  35941. + db88f6192AInfoBoardMppTypeInfo,
  35942. + DB_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  35943. + db88f6192AInfoBoardMppConfigValue,
  35944. + 0, /* intsGppMaskLow */
  35945. + (1 << 3), /* intsGppMaskHigh */
  35946. + DB_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  35947. + db88f6192AInfoBoardDeCsInfo,
  35948. + DB_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  35949. + db88f6192AInfoBoardTwsiDev,
  35950. + DB_88F6190A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  35951. + db88f6192AInfoBoardMacInfo,
  35952. + DB_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  35953. + db88f6192AInfoBoardGppInfo,
  35954. + DB_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  35955. + NULL,
  35956. + 0, /* ledsPolarity */
  35957. + DB_88F6192A_OE_LOW, /* gppOutEnLow */
  35958. + DB_88F6192A_OE_HIGH, /* gppOutEnHigh */
  35959. + DB_88F6192A_OE_VAL_LOW, /* gppOutValLow */
  35960. + DB_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
  35961. + 0, /* gppPolarityValLow */
  35962. + 0, /* gppPolarityValHigh */
  35963. + NULL /* pSwitchInfo */
  35964. +};
  35965. +
  35966. +#define RD_88F6192A_BOARD_PCI_IF_NUM 0x0
  35967. +#define RD_88F6192A_BOARD_TWSI_DEF_NUM 0x0
  35968. +#define RD_88F6192A_BOARD_MAC_INFO_NUM 0x1
  35969. +#define RD_88F6192A_BOARD_GPP_INFO_NUM 0xE
  35970. +#define RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM 0x1
  35971. +#define RD_88F6192A_BOARD_MPP_CONFIG_NUM 0x1
  35972. +#define RD_88F6192A_BOARD_DEVICE_CONFIG_NUM 0x1
  35973. +#define RD_88F6192A_BOARD_DEBUG_LED_NUM 0x3
  35974. +
  35975. +MV_U8 rd88f6192AInfoBoardDebugLedIf[] =
  35976. + {17, 28, 29};
  35977. +
  35978. +MV_BOARD_MAC_INFO rd88f6192AInfoBoardMacInfo[] =
  35979. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  35980. + {{BOARD_MAC_SPEED_AUTO, 0x8}
  35981. + };
  35982. +
  35983. +MV_BOARD_MPP_TYPE_INFO rd88f6192AInfoBoardMppTypeInfo[] =
  35984. + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
  35985. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
  35986. + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
  35987. + };
  35988. +
  35989. +MV_DEV_CS_INFO rd88f6192AInfoBoardDeCsInfo[] =
  35990. + /*{deviceCS, params, devType, devWidth}*/
  35991. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  35992. +
  35993. +MV_BOARD_GPP_INFO rd88f6192AInfoBoardGppInfo[] =
  35994. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  35995. + {
  35996. + {BOARD_GPP_USB_VBUS_EN, 10},
  35997. + {BOARD_GPP_USB_HOST_DEVICE, 11},
  35998. + {BOARD_GPP_RESET, 14},
  35999. + {BOARD_GPP_POWER_ON_LED, 15},
  36000. + {BOARD_GPP_HDD_POWER, 16},
  36001. + {BOARD_GPP_WPS_BUTTON, 24},
  36002. + {BOARD_GPP_TS_BUTTON_C, 25},
  36003. + {BOARD_GPP_USB_VBUS, 26},
  36004. + {BOARD_GPP_USB_OC, 27},
  36005. + {BOARD_GPP_TS_BUTTON_U, 30},
  36006. + {BOARD_GPP_TS_BUTTON_R, 31},
  36007. + {BOARD_GPP_TS_BUTTON_L, 32},
  36008. + {BOARD_GPP_TS_BUTTON_D, 34},
  36009. + {BOARD_GPP_FAN_POWER, 35}
  36010. + };
  36011. +
  36012. +MV_BOARD_MPP_INFO rd88f6192AInfoBoardMppConfigValue[] =
  36013. + {{{
  36014. + RD_88F6192A_MPP0_7,
  36015. + RD_88F6192A_MPP8_15,
  36016. + RD_88F6192A_MPP16_23,
  36017. + RD_88F6192A_MPP24_31,
  36018. + RD_88F6192A_MPP32_35
  36019. + }}};
  36020. +
  36021. +MV_BOARD_INFO rd88f6192AInfo = {
  36022. + "RD-88F6192A-NAS", /* boardName[MAX_BOARD_NAME_LEN] */
  36023. + RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  36024. + rd88f6192AInfoBoardMppTypeInfo,
  36025. + RD_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  36026. + rd88f6192AInfoBoardMppConfigValue,
  36027. + 0, /* intsGppMaskLow */
  36028. + (1 << 3), /* intsGppMaskHigh */
  36029. + RD_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  36030. + rd88f6192AInfoBoardDeCsInfo,
  36031. + RD_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  36032. + NULL,
  36033. + RD_88F6192A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  36034. + rd88f6192AInfoBoardMacInfo,
  36035. + RD_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  36036. + rd88f6192AInfoBoardGppInfo,
  36037. + RD_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  36038. + rd88f6192AInfoBoardDebugLedIf,
  36039. + 0, /* ledsPolarity */
  36040. + RD_88F6192A_OE_LOW, /* gppOutEnLow */
  36041. + RD_88F6192A_OE_HIGH, /* gppOutEnHigh */
  36042. + RD_88F6192A_OE_VAL_LOW, /* gppOutValLow */
  36043. + RD_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
  36044. + 0, /* gppPolarityValLow */
  36045. + 0, /* gppPolarityValHigh */
  36046. + NULL /* pSwitchInfo */
  36047. +};
  36048. +
  36049. +MV_BOARD_INFO rd88f6190AInfo = {
  36050. + "RD-88F6190A-NAS", /* boardName[MAX_BOARD_NAME_LEN] */
  36051. + RD_88F6192A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  36052. + rd88f6192AInfoBoardMppTypeInfo,
  36053. + RD_88F6192A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  36054. + rd88f6192AInfoBoardMppConfigValue,
  36055. + 0, /* intsGppMaskLow */
  36056. + (1 << 3), /* intsGppMaskHigh */
  36057. + RD_88F6192A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  36058. + rd88f6192AInfoBoardDeCsInfo,
  36059. + RD_88F6192A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  36060. + NULL,
  36061. + RD_88F6192A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  36062. + rd88f6192AInfoBoardMacInfo,
  36063. + RD_88F6192A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  36064. + rd88f6192AInfoBoardGppInfo,
  36065. + RD_88F6192A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  36066. + rd88f6192AInfoBoardDebugLedIf,
  36067. + 0, /* ledsPolarity */
  36068. + RD_88F6192A_OE_LOW, /* gppOutEnLow */
  36069. + RD_88F6192A_OE_HIGH, /* gppOutEnHigh */
  36070. + RD_88F6192A_OE_VAL_LOW, /* gppOutValLow */
  36071. + RD_88F6192A_OE_VAL_HIGH, /* gppOutValHigh */
  36072. + 0, /* gppPolarityValLow */
  36073. + 0, /* gppPolarityValHigh */
  36074. + NULL /* pSwitchInfo */
  36075. +};
  36076. +
  36077. +#define DB_88F6180A_BOARD_PCI_IF_NUM 0x0
  36078. +#define DB_88F6180A_BOARD_TWSI_DEF_NUM 0x5
  36079. +#define DB_88F6180A_BOARD_MAC_INFO_NUM 0x1
  36080. +#define DB_88F6180A_BOARD_GPP_INFO_NUM 0x0
  36081. +#define DB_88F6180A_BOARD_MPP_GROUP_TYPE_NUM 0x2
  36082. +#define DB_88F6180A_BOARD_MPP_CONFIG_NUM 0x1
  36083. +#define DB_88F6180A_BOARD_DEVICE_CONFIG_NUM 0x1
  36084. +#define DB_88F6180A_BOARD_DEBUG_LED_NUM 0x0
  36085. +
  36086. +MV_BOARD_TWSI_INFO db88f6180AInfoBoardTwsiDev[] =
  36087. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  36088. + {
  36089. + {BOARD_DEV_TWSI_EXP, 0x20, ADDR7_BIT},
  36090. + {BOARD_DEV_TWSI_EXP, 0x21, ADDR7_BIT},
  36091. + {BOARD_DEV_TWSI_EXP, 0x27, ADDR7_BIT},
  36092. + {BOARD_DEV_TWSI_SATR, 0x4C, ADDR7_BIT},
  36093. + {BOARD_TWSI_AUDIO_DEC, 0x4A, ADDR7_BIT}
  36094. + };
  36095. +
  36096. +MV_BOARD_MAC_INFO db88f6180AInfoBoardMacInfo[] =
  36097. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  36098. + {{BOARD_MAC_SPEED_AUTO, 0x8}
  36099. + };
  36100. +
  36101. +MV_BOARD_GPP_INFO db88f6180AInfoBoardGppInfo[] =
  36102. + /* {{MV_BOARD_GPP_CLASS devClass, MV_U8 gppPinNum}} */
  36103. + {
  36104. + /* Muxed with TDM/Audio module via IOexpender
  36105. + {BOARD_GPP_USB_VBUS, 6} */
  36106. + };
  36107. +
  36108. +MV_BOARD_MPP_TYPE_INFO db88f6180AInfoBoardMppTypeInfo[] =
  36109. + /* {{MV_BOARD_MPP_TYPE_CLASS boardMppGroup1,
  36110. + MV_BOARD_MPP_TYPE_CLASS boardMppGroup2}} */
  36111. + {{MV_BOARD_OTHER, MV_BOARD_AUTO}
  36112. + };
  36113. +
  36114. +MV_DEV_CS_INFO db88f6180AInfoBoardDeCsInfo[] =
  36115. + /*{deviceCS, params, devType, devWidth}*/
  36116. +#if defined(MV_NAND_BOOT)
  36117. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  36118. +#else
  36119. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  36120. +#endif
  36121. +
  36122. +MV_BOARD_MPP_INFO db88f6180AInfoBoardMppConfigValue[] =
  36123. + {{{
  36124. + DB_88F6180A_MPP0_7,
  36125. + DB_88F6180A_MPP8_15,
  36126. + DB_88F6180A_MPP16_23,
  36127. + DB_88F6180A_MPP24_31,
  36128. + DB_88F6180A_MPP32_39,
  36129. + DB_88F6180A_MPP40_44
  36130. + }}};
  36131. +
  36132. +MV_BOARD_INFO db88f6180AInfo = {
  36133. + "DB-88F6180A-BP", /* boardName[MAX_BOARD_NAME_LEN] */
  36134. + DB_88F6180A_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  36135. + db88f6180AInfoBoardMppTypeInfo,
  36136. + DB_88F6180A_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  36137. + db88f6180AInfoBoardMppConfigValue,
  36138. + 0, /* intsGppMaskLow */
  36139. + 0, /* intsGppMaskHigh */
  36140. + DB_88F6180A_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  36141. + db88f6180AInfoBoardDeCsInfo,
  36142. + DB_88F6180A_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  36143. + db88f6180AInfoBoardTwsiDev,
  36144. + DB_88F6180A_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  36145. + db88f6180AInfoBoardMacInfo,
  36146. + DB_88F6180A_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  36147. + NULL,
  36148. + DB_88F6180A_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  36149. + NULL,
  36150. + 0, /* ledsPolarity */
  36151. + DB_88F6180A_OE_LOW, /* gppOutEnLow */
  36152. + DB_88F6180A_OE_HIGH, /* gppOutEnHigh */
  36153. + DB_88F6180A_OE_VAL_LOW, /* gppOutValLow */
  36154. + DB_88F6180A_OE_VAL_HIGH, /* gppOutValHigh */
  36155. + 0, /* gppPolarityValLow */
  36156. + 0, /* gppPolarityValHigh */
  36157. + NULL /* pSwitchInfo */
  36158. +};
  36159. +
  36160. +
  36161. +#define RD_88F6281A_PCAC_BOARD_PCI_IF_NUM 0x0
  36162. +#define RD_88F6281A_PCAC_BOARD_TWSI_DEF_NUM 0x1
  36163. +#define RD_88F6281A_PCAC_BOARD_MAC_INFO_NUM 0x1
  36164. +#define RD_88F6281A_PCAC_BOARD_GPP_INFO_NUM 0x0
  36165. +#define RD_88F6281A_PCAC_BOARD_MPP_GROUP_TYPE_NUM 0x1
  36166. +#define RD_88F6281A_PCAC_BOARD_MPP_CONFIG_NUM 0x1
  36167. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  36168. + #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM 0x1
  36169. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  36170. + #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM 0x2
  36171. +#else
  36172. + #define RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM 0x1
  36173. +#endif
  36174. +#define RD_88F6281A_PCAC_BOARD_DEBUG_LED_NUM 0x4
  36175. +
  36176. +MV_U8 rd88f6281APcacInfoBoardDebugLedIf[] =
  36177. + {38, 39, 40, 41};
  36178. +
  36179. +MV_BOARD_MAC_INFO rd88f6281APcacInfoBoardMacInfo[] =
  36180. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  36181. + {{BOARD_MAC_SPEED_AUTO, 0x8}
  36182. + };
  36183. +
  36184. +MV_BOARD_TWSI_INFO rd88f6281APcacInfoBoardTwsiDev[] =
  36185. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  36186. + {
  36187. + {BOARD_TWSI_OTHER, 0xa7, ADDR7_BIT}
  36188. + };
  36189. +
  36190. +MV_BOARD_MPP_TYPE_INFO rd88f6281APcacInfoBoardMppTypeInfo[] =
  36191. + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
  36192. + };
  36193. +
  36194. +MV_DEV_CS_INFO rd88f6281APcacInfoBoardDeCsInfo[] =
  36195. + /*{deviceCS, params, devType, devWidth}*/
  36196. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  36197. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  36198. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  36199. + {
  36200. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  36201. + {1, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  36202. + };
  36203. +#else
  36204. + {{1, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  36205. +#endif
  36206. +
  36207. +MV_BOARD_MPP_INFO rd88f6281APcacInfoBoardMppConfigValue[] =
  36208. + {{{
  36209. + RD_88F6281A_PCAC_MPP0_7,
  36210. + RD_88F6281A_PCAC_MPP8_15,
  36211. + RD_88F6281A_PCAC_MPP16_23,
  36212. + RD_88F6281A_PCAC_MPP24_31,
  36213. + RD_88F6281A_PCAC_MPP32_39,
  36214. + RD_88F6281A_PCAC_MPP40_47,
  36215. + RD_88F6281A_PCAC_MPP48_55
  36216. + }}};
  36217. +
  36218. +MV_BOARD_INFO rd88f6281APcacInfo = {
  36219. + "RD-88F6281A-PCAC", /* boardName[MAX_BOARD_NAME_LEN] */
  36220. + RD_88F6281A_PCAC_BOARD_MPP_GROUP_TYPE_NUM, /* numBoardMppGroupType */
  36221. + rd88f6281APcacInfoBoardMppTypeInfo,
  36222. + RD_88F6281A_PCAC_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  36223. + rd88f6281APcacInfoBoardMppConfigValue,
  36224. + 0, /* intsGppMaskLow */
  36225. + (1 << 3), /* intsGppMaskHigh */
  36226. + RD_88F6281A_PCAC_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  36227. + rd88f6281APcacInfoBoardDeCsInfo,
  36228. + RD_88F6281A_PCAC_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  36229. + rd88f6281APcacInfoBoardTwsiDev,
  36230. + RD_88F6281A_PCAC_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  36231. + rd88f6281APcacInfoBoardMacInfo,
  36232. + RD_88F6281A_PCAC_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  36233. + 0,
  36234. + RD_88F6281A_PCAC_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  36235. + NULL,
  36236. + 0, /* ledsPolarity */
  36237. + RD_88F6281A_PCAC_OE_LOW, /* gppOutEnLow */
  36238. + RD_88F6281A_PCAC_OE_HIGH, /* gppOutEnHigh */
  36239. + RD_88F6281A_PCAC_OE_VAL_LOW, /* gppOutValLow */
  36240. + RD_88F6281A_PCAC_OE_VAL_HIGH, /* gppOutValHigh */
  36241. + 0, /* gppPolarityValLow */
  36242. + 0, /* gppPolarityValHigh */
  36243. + NULL /* pSwitchInfo */
  36244. +};
  36245. +
  36246. +
  36247. +/* 6281 Sheeva Plug*/
  36248. +
  36249. +#define SHEEVA_PLUG_BOARD_PCI_IF_NUM 0x0
  36250. +#define SHEEVA_PLUG_BOARD_TWSI_DEF_NUM 0x0
  36251. +#define SHEEVA_PLUG_BOARD_MAC_INFO_NUM 0x1
  36252. +#define SHEEVA_PLUG_BOARD_GPP_INFO_NUM 0x0
  36253. +#define SHEEVA_PLUG_BOARD_MPP_GROUP_TYPE_NUN 0x1
  36254. +#define SHEEVA_PLUG_BOARD_MPP_CONFIG_NUM 0x1
  36255. +#define SHEEVA_PLUG_BOARD_DEVICE_CONFIG_NUM 0x1
  36256. +#define SHEEVA_PLUG_BOARD_DEBUG_LED_NUM 0x1
  36257. +
  36258. +MV_U8 sheevaPlugInfoBoardDebugLedIf[] =
  36259. + {49};
  36260. +
  36261. +MV_BOARD_MAC_INFO sheevaPlugInfoBoardMacInfo[] =
  36262. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  36263. + {{BOARD_MAC_SPEED_AUTO, 0x0}};
  36264. +
  36265. +MV_BOARD_TWSI_INFO sheevaPlugInfoBoardTwsiDev[] =
  36266. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  36267. + {{BOARD_TWSI_OTHER, 0x0, ADDR7_BIT}};
  36268. +
  36269. +MV_BOARD_MPP_TYPE_INFO sheevaPlugInfoBoardMppTypeInfo[] =
  36270. + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
  36271. + };
  36272. +
  36273. +MV_DEV_CS_INFO sheevaPlugInfoBoardDeCsInfo[] =
  36274. + /*{deviceCS, params, devType, devWidth}*/
  36275. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  36276. +
  36277. +MV_BOARD_MPP_INFO sheevaPlugInfoBoardMppConfigValue[] =
  36278. + {{{
  36279. + RD_SHEEVA_PLUG_MPP0_7,
  36280. + RD_SHEEVA_PLUG_MPP8_15,
  36281. + RD_SHEEVA_PLUG_MPP16_23,
  36282. + RD_SHEEVA_PLUG_MPP24_31,
  36283. + RD_SHEEVA_PLUG_MPP32_39,
  36284. + RD_SHEEVA_PLUG_MPP40_47,
  36285. + RD_SHEEVA_PLUG_MPP48_55
  36286. + }}};
  36287. +
  36288. +MV_BOARD_INFO sheevaPlugInfo = {
  36289. + "SHEEVA PLUG", /* boardName[MAX_BOARD_NAME_LEN] */
  36290. + SHEEVA_PLUG_BOARD_MPP_GROUP_TYPE_NUN, /* numBoardMppGroupType */
  36291. + sheevaPlugInfoBoardMppTypeInfo,
  36292. + SHEEVA_PLUG_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  36293. + sheevaPlugInfoBoardMppConfigValue,
  36294. + 0, /* intsGppMaskLow */
  36295. + 0, /* intsGppMaskHigh */
  36296. + SHEEVA_PLUG_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  36297. + sheevaPlugInfoBoardDeCsInfo,
  36298. + SHEEVA_PLUG_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  36299. + sheevaPlugInfoBoardTwsiDev,
  36300. + SHEEVA_PLUG_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  36301. + sheevaPlugInfoBoardMacInfo,
  36302. + SHEEVA_PLUG_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  36303. + 0,
  36304. + SHEEVA_PLUG_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  36305. + sheevaPlugInfoBoardDebugLedIf,
  36306. + 0, /* ledsPolarity */
  36307. + RD_SHEEVA_PLUG_OE_LOW, /* gppOutEnLow */
  36308. + RD_SHEEVA_PLUG_OE_HIGH, /* gppOutEnHigh */
  36309. + RD_SHEEVA_PLUG_OE_VAL_LOW, /* gppOutValLow */
  36310. + RD_SHEEVA_PLUG_OE_VAL_HIGH, /* gppOutValHigh */
  36311. + 0, /* gppPolarityValLow */
  36312. + 0, /* gppPolarityValHigh */
  36313. + NULL /* pSwitchInfo */
  36314. +};
  36315. +
  36316. +/* Customer specific board place holder*/
  36317. +
  36318. +#define DB_CUSTOMER_BOARD_PCI_IF_NUM 0x0
  36319. +#define DB_CUSTOMER_BOARD_TWSI_DEF_NUM 0x0
  36320. +#define DB_CUSTOMER_BOARD_MAC_INFO_NUM 0x0
  36321. +#define DB_CUSTOMER_BOARD_GPP_INFO_NUM 0x0
  36322. +#define DB_CUSTOMER_BOARD_MPP_GROUP_TYPE_NUN 0x0
  36323. +#define DB_CUSTOMER_BOARD_MPP_CONFIG_NUM 0x0
  36324. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  36325. + #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM 0x0
  36326. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  36327. + #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM 0x0
  36328. +#else
  36329. + #define DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM 0x0
  36330. +#endif
  36331. +#define DB_CUSTOMER_BOARD_DEBUG_LED_NUM 0x0
  36332. +
  36333. +MV_U8 dbCustomerInfoBoardDebugLedIf[] =
  36334. + {0};
  36335. +
  36336. +MV_BOARD_MAC_INFO dbCustomerInfoBoardMacInfo[] =
  36337. + /* {{MV_BOARD_MAC_SPEED boardMacSpeed, MV_U8 boardEthSmiAddr}} */
  36338. + {{BOARD_MAC_SPEED_AUTO, 0x0}};
  36339. +
  36340. +MV_BOARD_TWSI_INFO dbCustomerInfoBoardTwsiDev[] =
  36341. + /* {{MV_BOARD_DEV_CLASS devClass, MV_U8 twsiDevAddr, MV_U8 twsiDevAddrType}} */
  36342. + {{BOARD_TWSI_OTHER, 0x0, ADDR7_BIT}};
  36343. +
  36344. +MV_BOARD_MPP_TYPE_INFO dbCustomerInfoBoardMppTypeInfo[] =
  36345. + {{MV_BOARD_OTHER, MV_BOARD_OTHER}
  36346. + };
  36347. +
  36348. +MV_DEV_CS_INFO dbCustomerInfoBoardDeCsInfo[] =
  36349. + /*{deviceCS, params, devType, devWidth}*/
  36350. +#if defined(MV_NAND) && defined(MV_NAND_BOOT)
  36351. + {{0, N_A, BOARD_DEV_NAND_FLASH, 8}}; /* NAND DEV */
  36352. +#elif defined(MV_NAND) && defined(MV_SPI_BOOT)
  36353. + {
  36354. + {0, N_A, BOARD_DEV_NAND_FLASH, 8}, /* NAND DEV */
  36355. + {2, N_A, BOARD_DEV_SPI_FLASH, 8}, /* SPI DEV */
  36356. + };
  36357. +#else
  36358. + {{2, N_A, BOARD_DEV_SPI_FLASH, 8}}; /* SPI DEV */
  36359. +#endif
  36360. +
  36361. +MV_BOARD_MPP_INFO dbCustomerInfoBoardMppConfigValue[] =
  36362. + {{{
  36363. + DB_CUSTOMER_MPP0_7,
  36364. + DB_CUSTOMER_MPP8_15,
  36365. + DB_CUSTOMER_MPP16_23,
  36366. + DB_CUSTOMER_MPP24_31,
  36367. + DB_CUSTOMER_MPP32_39,
  36368. + DB_CUSTOMER_MPP40_47,
  36369. + DB_CUSTOMER_MPP48_55
  36370. + }}};
  36371. +
  36372. +MV_BOARD_INFO dbCustomerInfo = {
  36373. + "DB-CUSTOMER", /* boardName[MAX_BOARD_NAME_LEN] */
  36374. + DB_CUSTOMER_BOARD_MPP_GROUP_TYPE_NUN, /* numBoardMppGroupType */
  36375. + dbCustomerInfoBoardMppTypeInfo,
  36376. + DB_CUSTOMER_BOARD_MPP_CONFIG_NUM, /* numBoardMppConfig */
  36377. + dbCustomerInfoBoardMppConfigValue,
  36378. + 0, /* intsGppMaskLow */
  36379. + 0, /* intsGppMaskHigh */
  36380. + DB_CUSTOMER_BOARD_DEVICE_CONFIG_NUM, /* numBoardDevIf */
  36381. + dbCustomerInfoBoardDeCsInfo,
  36382. + DB_CUSTOMER_BOARD_TWSI_DEF_NUM, /* numBoardTwsiDev */
  36383. + dbCustomerInfoBoardTwsiDev,
  36384. + DB_CUSTOMER_BOARD_MAC_INFO_NUM, /* numBoardMacInfo */
  36385. + dbCustomerInfoBoardMacInfo,
  36386. + DB_CUSTOMER_BOARD_GPP_INFO_NUM, /* numBoardGppInfo */
  36387. + 0,
  36388. + DB_CUSTOMER_BOARD_DEBUG_LED_NUM, /* activeLedsNumber */
  36389. + NULL,
  36390. + 0, /* ledsPolarity */
  36391. + DB_CUSTOMER_OE_LOW, /* gppOutEnLow */
  36392. + DB_CUSTOMER_OE_HIGH, /* gppOutEnHigh */
  36393. + DB_CUSTOMER_OE_VAL_LOW, /* gppOutValLow */
  36394. + DB_CUSTOMER_OE_VAL_HIGH, /* gppOutValHigh */
  36395. + 0, /* gppPolarityValLow */
  36396. + 0, /* gppPolarityValHigh */
  36397. + NULL /* pSwitchInfo */
  36398. +};
  36399. +
  36400. +MV_BOARD_INFO* boardInfoTbl[] = {
  36401. + &db88f6281AInfo,
  36402. + &rd88f6281AInfo,
  36403. + &db88f6192AInfo,
  36404. + &rd88f6192AInfo,
  36405. + &db88f6180AInfo,
  36406. + &db88f6190AInfo,
  36407. + &rd88f6190AInfo,
  36408. + &rd88f6281APcacInfo,
  36409. + &dbCustomerInfo,
  36410. + &sheevaPlugInfo
  36411. + };
  36412. +
  36413. +
  36414. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h
  36415. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h 1970-01-01 01:00:00.000000000 +0100
  36416. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/boardEnv/mvBoardEnvSpec.h 2011-08-01 14:38:19.000000000 +0200
  36417. @@ -0,0 +1,262 @@
  36418. +/*******************************************************************************
  36419. +Copyright (C) Marvell International Ltd. and its affiliates
  36420. +
  36421. +This software file (the "File") is owned and distributed by Marvell
  36422. +International Ltd. and/or its affiliates ("Marvell") under the following
  36423. +alternative licensing terms. Once you have made an election to distribute the
  36424. +File under one of the following license alternatives, please (i) delete this
  36425. +introductory statement regarding license alternatives, (ii) delete the two
  36426. +license alternatives that you have not elected to use and (iii) preserve the
  36427. +Marvell copyright notice above.
  36428. +
  36429. +********************************************************************************
  36430. +Marvell Commercial License Option
  36431. +
  36432. +If you received this File from Marvell and you have entered into a commercial
  36433. +license agreement (a "Commercial License") with Marvell, the File is licensed
  36434. +to you under the terms of the applicable Commercial License.
  36435. +
  36436. +********************************************************************************
  36437. +Marvell GPL License Option
  36438. +
  36439. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36440. +modify this File in accordance with the terms and conditions of the General
  36441. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  36442. +available along with the File in the license.txt file or by writing to the Free
  36443. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  36444. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  36445. +
  36446. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  36447. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  36448. +DISCLAIMED. The GPL License provides additional details about this warranty
  36449. +disclaimer.
  36450. +********************************************************************************
  36451. +Marvell BSD License Option
  36452. +
  36453. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36454. +modify this File under the following licensing terms.
  36455. +Redistribution and use in source and binary forms, with or without modification,
  36456. +are permitted provided that the following conditions are met:
  36457. +
  36458. + * Redistributions of source code must retain the above copyright notice,
  36459. + this list of conditions and the following disclaimer.
  36460. +
  36461. + * Redistributions in binary form must reproduce the above copyright
  36462. + notice, this list of conditions and the following disclaimer in the
  36463. + documentation and/or other materials provided with the distribution.
  36464. +
  36465. + * Neither the name of Marvell nor the names of its contributors may be
  36466. + used to endorse or promote products derived from this software without
  36467. + specific prior written permission.
  36468. +
  36469. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  36470. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  36471. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  36472. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  36473. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  36474. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  36475. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  36476. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  36477. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  36478. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36479. +
  36480. +*******************************************************************************/
  36481. +
  36482. +
  36483. +#ifndef __INCmvBoardEnvSpech
  36484. +#define __INCmvBoardEnvSpech
  36485. +
  36486. +#include "mvSysHwConfig.h"
  36487. +
  36488. +
  36489. +/* For future use */
  36490. +#define BD_ID_DATA_START_OFFS 0x0
  36491. +#define BD_DETECT_SEQ_OFFS 0x0
  36492. +#define BD_SYS_NUM_OFFS 0x4
  36493. +#define BD_NAME_OFFS 0x8
  36494. +
  36495. +/* I2C bus addresses */
  36496. +#define MV_BOARD_CTRL_I2C_ADDR 0x0 /* Controller slave addr */
  36497. +#define MV_BOARD_CTRL_I2C_ADDR_TYPE ADDR7_BIT
  36498. +#define MV_BOARD_DIMM0_I2C_ADDR 0x56
  36499. +#define MV_BOARD_DIMM0_I2C_ADDR_TYPE ADDR7_BIT
  36500. +#define MV_BOARD_DIMM1_I2C_ADDR 0x54
  36501. +#define MV_BOARD_DIMM1_I2C_ADDR_TYPE ADDR7_BIT
  36502. +#define MV_BOARD_EEPROM_I2C_ADDR 0x51
  36503. +#define MV_BOARD_EEPROM_I2C_ADDR_TYPE ADDR7_BIT
  36504. +#define MV_BOARD_MAIN_EEPROM_I2C_ADDR 0x50
  36505. +#define MV_BOARD_MAIN_EEPROM_I2C_ADDR_TYPE ADDR7_BIT
  36506. +#define MV_BOARD_MUX_I2C_ADDR_ENTRY 0x2
  36507. +#define MV_BOARD_DIMM_I2C_CHANNEL 0x0
  36508. +
  36509. +#define BOOT_FLASH_INDEX 0
  36510. +#define MAIN_FLASH_INDEX 1
  36511. +
  36512. +#define BOARD_ETH_START_PORT_NUM 0
  36513. +
  36514. +/* Supported clocks */
  36515. +#define MV_BOARD_TCLK_100MHZ 100000000
  36516. +#define MV_BOARD_TCLK_125MHZ 125000000
  36517. +#define MV_BOARD_TCLK_133MHZ 133333333
  36518. +#define MV_BOARD_TCLK_150MHZ 150000000
  36519. +#define MV_BOARD_TCLK_166MHZ 166666667
  36520. +#define MV_BOARD_TCLK_200MHZ 200000000
  36521. +
  36522. +#define MV_BOARD_SYSCLK_100MHZ 100000000
  36523. +#define MV_BOARD_SYSCLK_125MHZ 125000000
  36524. +#define MV_BOARD_SYSCLK_133MHZ 133333333
  36525. +#define MV_BOARD_SYSCLK_150MHZ 150000000
  36526. +#define MV_BOARD_SYSCLK_166MHZ 166666667
  36527. +#define MV_BOARD_SYSCLK_200MHZ 200000000
  36528. +#define MV_BOARD_SYSCLK_233MHZ 233333333
  36529. +#define MV_BOARD_SYSCLK_250MHZ 250000000
  36530. +#define MV_BOARD_SYSCLK_267MHZ 266666667
  36531. +#define MV_BOARD_SYSCLK_300MHZ 300000000
  36532. +#define MV_BOARD_SYSCLK_333MHZ 333333334
  36533. +#define MV_BOARD_SYSCLK_400MHZ 400000000
  36534. +
  36535. +#define MV_BOARD_REFCLK_25MHZ 25000000
  36536. +
  36537. +/* Board specific */
  36538. +/* =============================== */
  36539. +
  36540. +/* boards ID numbers */
  36541. +
  36542. +#define BOARD_ID_BASE 0x0
  36543. +
  36544. +/* New board ID numbers */
  36545. +#define DB_88F6281A_BP_ID (BOARD_ID_BASE)
  36546. +#define DB_88F6281_BP_MLL_ID 1680
  36547. +#define RD_88F6281A_ID (BOARD_ID_BASE+0x1)
  36548. +#define RD_88F6281_MLL_ID 1682
  36549. +#define DB_88F6192A_BP_ID (BOARD_ID_BASE+0x2)
  36550. +#define RD_88F6192A_ID (BOARD_ID_BASE+0x3)
  36551. +#define RD_88F6192_MLL_ID 1681
  36552. +#define DB_88F6180A_BP_ID (BOARD_ID_BASE+0x4)
  36553. +#define DB_88F6190A_BP_ID (BOARD_ID_BASE+0x5)
  36554. +#define RD_88F6190A_ID (BOARD_ID_BASE+0x6)
  36555. +#define RD_88F6281A_PCAC_ID (BOARD_ID_BASE+0x7)
  36556. +#define DB_CUSTOMER_ID (BOARD_ID_BASE+0x8)
  36557. +#define SHEEVA_PLUG_ID (BOARD_ID_BASE+0x9)
  36558. +#define MV_MAX_BOARD_ID (SHEEVA_PLUG_ID + 1)
  36559. +
  36560. +/* DB-88F6281A-BP */
  36561. +#if defined(MV_NAND)
  36562. + #define DB_88F6281A_MPP0_7 0x21111111
  36563. +#else
  36564. + #define DB_88F6281A_MPP0_7 0x21112220
  36565. +#endif
  36566. +#define DB_88F6281A_MPP8_15 0x11113311
  36567. +#define DB_88F6281A_MPP16_23 0x00551111
  36568. +#define DB_88F6281A_MPP24_31 0x00000000
  36569. +#define DB_88F6281A_MPP32_39 0x00000000
  36570. +#define DB_88F6281A_MPP40_47 0x00000000
  36571. +#define DB_88F6281A_MPP48_55 0x00000000
  36572. +#define DB_88F6281A_OE_LOW 0x0
  36573. +#if defined(MV_TDM_5CHANNELS)
  36574. + #define DB_88F6281A_OE_HIGH (BIT6)
  36575. +#else
  36576. +#define DB_88F6281A_OE_HIGH 0x0
  36577. +#endif
  36578. +#define DB_88F6281A_OE_VAL_LOW 0x0
  36579. +#define DB_88F6281A_OE_VAL_HIGH 0x0
  36580. +
  36581. +/* RD-88F6281A */
  36582. +#if defined(MV_NAND)
  36583. + #define RD_88F6281A_MPP0_7 0x21111111
  36584. +#else
  36585. + #define RD_88F6281A_MPP0_7 0x21112220
  36586. +#endif
  36587. +#define RD_88F6281A_MPP8_15 0x11113311
  36588. +#define RD_88F6281A_MPP16_23 0x33331111
  36589. +#define RD_88F6281A_MPP24_31 0x33003333
  36590. +#define RD_88F6281A_MPP32_39 0x20440533
  36591. +#define RD_88F6281A_MPP40_47 0x22202222
  36592. +#define RD_88F6281A_MPP48_55 0x00000002
  36593. +#define RD_88F6281A_OE_LOW (BIT28 | BIT29)
  36594. +#define RD_88F6281A_OE_HIGH (BIT3 | BIT6 | BIT17)
  36595. +#define RD_88F6281A_OE_VAL_LOW 0x0
  36596. +#define RD_88F6281A_OE_VAL_HIGH 0x0
  36597. +
  36598. +/* DB-88F6192A-BP */
  36599. +#if defined(MV_NAND)
  36600. + #define DB_88F6192A_MPP0_7 0x21111111
  36601. +#else
  36602. + #define DB_88F6192A_MPP0_7 0x21112220
  36603. +#endif
  36604. +#define DB_88F6192A_MPP8_15 0x11113311
  36605. +#define DB_88F6192A_MPP16_23 0x00501111
  36606. +#define DB_88F6192A_MPP24_31 0x00000000
  36607. +#define DB_88F6192A_MPP32_35 0x00000000
  36608. +#define DB_88F6192A_OE_LOW (BIT22 | BIT23)
  36609. +#define DB_88F6192A_OE_HIGH 0x0
  36610. +#define DB_88F6192A_OE_VAL_LOW 0x0
  36611. +#define DB_88F6192A_OE_VAL_HIGH 0x0
  36612. +
  36613. +/* RD-88F6192A */
  36614. +#define RD_88F6192A_MPP0_7 0x01222222
  36615. +#define RD_88F6192A_MPP8_15 0x00000011
  36616. +#define RD_88F6192A_MPP16_23 0x05550000
  36617. +#define RD_88F6192A_MPP24_31 0x0
  36618. +#define RD_88F6192A_MPP32_35 0x0
  36619. +#define RD_88F6192A_OE_LOW (BIT11 | BIT14 | BIT24 | BIT25 | BIT26 | BIT27 | BIT30 | BIT31)
  36620. +#define RD_88F6192A_OE_HIGH (BIT0 | BIT2)
  36621. +#define RD_88F6192A_OE_VAL_LOW 0x18400
  36622. +#define RD_88F6192A_OE_VAL_HIGH 0x8
  36623. +
  36624. +/* DB-88F6180A-BP */
  36625. +#if defined(MV_NAND)
  36626. + #define DB_88F6180A_MPP0_7 0x21111111
  36627. +#else
  36628. + #define DB_88F6180A_MPP0_7 0x01112222
  36629. +#endif
  36630. +#define DB_88F6180A_MPP8_15 0x11113311
  36631. +#define DB_88F6180A_MPP16_23 0x00001111
  36632. +#define DB_88F6180A_MPP24_31 0x0
  36633. +#define DB_88F6180A_MPP32_39 0x4444c000
  36634. +#define DB_88F6180A_MPP40_44 0x00044444
  36635. +#define DB_88F6180A_OE_LOW 0x0
  36636. +#define DB_88F6180A_OE_HIGH 0x0
  36637. +#define DB_88F6180A_OE_VAL_LOW 0x0
  36638. +#define DB_88F6180A_OE_VAL_HIGH 0x0
  36639. +
  36640. +/* RD-88F6281A_PCAC */
  36641. +#define RD_88F6281A_PCAC_MPP0_7 0x21111111
  36642. +#define RD_88F6281A_PCAC_MPP8_15 0x00003311
  36643. +#define RD_88F6281A_PCAC_MPP16_23 0x00001100
  36644. +#define RD_88F6281A_PCAC_MPP24_31 0x00000000
  36645. +#define RD_88F6281A_PCAC_MPP32_39 0x00000000
  36646. +#define RD_88F6281A_PCAC_MPP40_47 0x00000000
  36647. +#define RD_88F6281A_PCAC_MPP48_55 0x00000000
  36648. +#define RD_88F6281A_PCAC_OE_LOW 0x0
  36649. +#define RD_88F6281A_PCAC_OE_HIGH 0x0
  36650. +#define RD_88F6281A_PCAC_OE_VAL_LOW 0x0
  36651. +#define RD_88F6281A_PCAC_OE_VAL_HIGH 0x0
  36652. +
  36653. +/* SHEEVA PLUG */
  36654. +#define RD_SHEEVA_PLUG_MPP0_7 0x01111111
  36655. +#define RD_SHEEVA_PLUG_MPP8_15 0x11113322
  36656. +#define RD_SHEEVA_PLUG_MPP16_23 0x00001111
  36657. +#define RD_SHEEVA_PLUG_MPP24_31 0x00100000
  36658. +#define RD_SHEEVA_PLUG_MPP32_39 0x00000000
  36659. +#define RD_SHEEVA_PLUG_MPP40_47 0x00000000
  36660. +#define RD_SHEEVA_PLUG_MPP48_55 0x00000000
  36661. +#define RD_SHEEVA_PLUG_OE_LOW 0x0
  36662. +#define RD_SHEEVA_PLUG_OE_HIGH 0x0
  36663. +#define RD_SHEEVA_PLUG_OE_VAL_LOW (BIT29)
  36664. +#define RD_SHEEVA_PLUG_OE_VAL_HIGH ((~(BIT17 | BIT16 | BIT15)) | BIT14)
  36665. +
  36666. +/* DB-CUSTOMER */
  36667. +#define DB_CUSTOMER_MPP0_7 0x21111111
  36668. +#define DB_CUSTOMER_MPP8_15 0x00003311
  36669. +#define DB_CUSTOMER_MPP16_23 0x00001100
  36670. +#define DB_CUSTOMER_MPP24_31 0x00000000
  36671. +#define DB_CUSTOMER_MPP32_39 0x00000000
  36672. +#define DB_CUSTOMER_MPP40_47 0x00000000
  36673. +#define DB_CUSTOMER_MPP48_55 0x00000000
  36674. +#define DB_CUSTOMER_OE_LOW 0x0
  36675. +#define DB_CUSTOMER_OE_HIGH (~((BIT6) | (BIT7) | (BIT8) | (BIT9)))
  36676. +#define DB_CUSTOMER_OE_VAL_LOW 0x0
  36677. +#define DB_CUSTOMER_OE_VAL_HIGH 0x0
  36678. +
  36679. +#endif /* __INCmvBoardEnvSpech */
  36680. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c
  36681. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c 1970-01-01 01:00:00.000000000 +0100
  36682. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.c 2011-08-01 14:38:19.000000000 +0200
  36683. @@ -0,0 +1,320 @@
  36684. +/*******************************************************************************
  36685. +Copyright (C) Marvell International Ltd. and its affiliates
  36686. +
  36687. +This software file (the "File") is owned and distributed by Marvell
  36688. +International Ltd. and/or its affiliates ("Marvell") under the following
  36689. +alternative licensing terms. Once you have made an election to distribute the
  36690. +File under one of the following license alternatives, please (i) delete this
  36691. +introductory statement regarding license alternatives, (ii) delete the two
  36692. +license alternatives that you have not elected to use and (iii) preserve the
  36693. +Marvell copyright notice above.
  36694. +
  36695. +********************************************************************************
  36696. +Marvell Commercial License Option
  36697. +
  36698. +If you received this File from Marvell and you have entered into a commercial
  36699. +license agreement (a "Commercial License") with Marvell, the File is licensed
  36700. +to you under the terms of the applicable Commercial License.
  36701. +
  36702. +********************************************************************************
  36703. +Marvell GPL License Option
  36704. +
  36705. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36706. +modify this File in accordance with the terms and conditions of the General
  36707. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  36708. +available along with the File in the license.txt file or by writing to the Free
  36709. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  36710. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  36711. +
  36712. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  36713. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  36714. +DISCLAIMED. The GPL License provides additional details about this warranty
  36715. +disclaimer.
  36716. +********************************************************************************
  36717. +Marvell BSD License Option
  36718. +
  36719. +If you received this File from Marvell, you may opt to use, redistribute and/or
  36720. +modify this File under the following licensing terms.
  36721. +Redistribution and use in source and binary forms, with or without modification,
  36722. +are permitted provided that the following conditions are met:
  36723. +
  36724. + * Redistributions of source code must retain the above copyright notice,
  36725. + this list of conditions and the following disclaimer.
  36726. +
  36727. + * Redistributions in binary form must reproduce the above copyright
  36728. + notice, this list of conditions and the following disclaimer in the
  36729. + documentation and/or other materials provided with the distribution.
  36730. +
  36731. + * Neither the name of Marvell nor the names of its contributors may be
  36732. + used to endorse or promote products derived from this software without
  36733. + specific prior written permission.
  36734. +
  36735. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  36736. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  36737. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  36738. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  36739. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  36740. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  36741. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  36742. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  36743. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  36744. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36745. +
  36746. +*******************************************************************************/
  36747. +
  36748. +
  36749. +#include "cpu/mvCpu.h"
  36750. +#include "ctrlEnv/mvCtrlEnvLib.h"
  36751. +#include "ctrlEnv/mvCtrlEnvRegs.h"
  36752. +#include "ctrlEnv/sys/mvCpuIfRegs.h"
  36753. +
  36754. +/* defines */
  36755. +#ifdef MV_DEBUG
  36756. + #define DB(x) x
  36757. +#else
  36758. + #define DB(x)
  36759. +#endif
  36760. +
  36761. +/* locals */
  36762. +
  36763. +/*******************************************************************************
  36764. +* mvCpuPclkGet - Get the CPU pClk (pipe clock)
  36765. +*
  36766. +* DESCRIPTION:
  36767. +* This routine extract the CPU core clock.
  36768. +*
  36769. +* INPUT:
  36770. +* None.
  36771. +*
  36772. +* OUTPUT:
  36773. +* None.
  36774. +*
  36775. +* RETURN:
  36776. +* 32bit clock cycles in MHertz.
  36777. +*
  36778. +*******************************************************************************/
  36779. +/* 6180 have different clk reset sampling */
  36780. +
  36781. +static MV_U32 mvCpu6180PclkGet(MV_VOID)
  36782. +{
  36783. + MV_U32 tmpPClkRate=0;
  36784. + MV_CPU_ARM_CLK cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;
  36785. +
  36786. + tmpPClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  36787. + tmpPClkRate = tmpPClkRate & MSAR_CPUCLCK_MASK_6180;
  36788. + tmpPClkRate = tmpPClkRate >> MSAR_CPUCLCK_OFFS_6180;
  36789. +
  36790. + tmpPClkRate = cpu6180_ddr_l2_CLK[tmpPClkRate].cpuClk;
  36791. +
  36792. + return tmpPClkRate;
  36793. +}
  36794. +
  36795. +
  36796. +MV_U32 mvCpuPclkGet(MV_VOID)
  36797. +{
  36798. +#if defined(PCLCK_AUTO_DETECT)
  36799. + MV_U32 tmpPClkRate=0;
  36800. + MV_U32 cpuCLK[] = MV_CPU_CLCK_TBL;
  36801. +
  36802. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  36803. + return mvCpu6180PclkGet();
  36804. +
  36805. + tmpPClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  36806. + tmpPClkRate = MSAR_CPUCLCK_EXTRACT(tmpPClkRate);
  36807. + tmpPClkRate = cpuCLK[tmpPClkRate];
  36808. +
  36809. + return tmpPClkRate;
  36810. +#else
  36811. + return MV_DEFAULT_PCLK
  36812. +#endif
  36813. +}
  36814. +
  36815. +/*******************************************************************************
  36816. +* mvCpuL2ClkGet - Get the CPU L2 (CPU bus clock)
  36817. +*
  36818. +* DESCRIPTION:
  36819. +* This routine extract the CPU L2 clock.
  36820. +*
  36821. +* RETURN:
  36822. +* 32bit clock cycles in Hertz.
  36823. +*
  36824. +*******************************************************************************/
  36825. +static MV_U32 mvCpu6180L2ClkGet(MV_VOID)
  36826. +{
  36827. + MV_U32 L2ClkRate=0;
  36828. + MV_CPU_ARM_CLK _cpu6180_ddr_l2_CLK[] = MV_CPU6180_DDR_L2_CLCK_TBL;
  36829. +
  36830. + L2ClkRate = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  36831. + L2ClkRate = L2ClkRate & MSAR_CPUCLCK_MASK_6180;
  36832. + L2ClkRate = L2ClkRate >> MSAR_CPUCLCK_OFFS_6180;
  36833. +
  36834. + L2ClkRate = _cpu6180_ddr_l2_CLK[L2ClkRate].l2Clk;
  36835. +
  36836. + return L2ClkRate;
  36837. +
  36838. +}
  36839. +
  36840. +MV_U32 mvCpuL2ClkGet(MV_VOID)
  36841. +{
  36842. +#ifdef L2CLK_AUTO_DETECT
  36843. + MV_U32 L2ClkRate, tmp, pClkRate, indexL2Rtio;
  36844. + MV_U32 L2Rtio[][2] = MV_L2_CLCK_RTIO_TBL;
  36845. +
  36846. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  36847. + return mvCpu6180L2ClkGet();
  36848. +
  36849. + pClkRate = mvCpuPclkGet();
  36850. +
  36851. + tmp = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  36852. + indexL2Rtio = MSAR_L2CLCK_EXTRACT(tmp);
  36853. +
  36854. + L2ClkRate = ((pClkRate * L2Rtio[indexL2Rtio][1]) / L2Rtio[indexL2Rtio][0]);
  36855. +
  36856. + return L2ClkRate;
  36857. +#else
  36858. + return MV_BOARD_DEFAULT_L2CLK;
  36859. +#endif
  36860. +}
  36861. +
  36862. +
  36863. +/*******************************************************************************
  36864. +* mvCpuNameGet - Get CPU name
  36865. +*
  36866. +* DESCRIPTION:
  36867. +* This function returns a string describing the CPU model and revision.
  36868. +*
  36869. +* INPUT:
  36870. +* None.
  36871. +*
  36872. +* OUTPUT:
  36873. +* pNameBuff - Buffer to contain board name string. Minimum size 32 chars.
  36874. +*
  36875. +* RETURN:
  36876. +* None.
  36877. +*******************************************************************************/
  36878. +MV_VOID mvCpuNameGet(char *pNameBuff)
  36879. +{
  36880. + MV_U32 cpuModel;
  36881. +
  36882. + cpuModel = mvOsCpuPartGet();
  36883. +
  36884. + /* The CPU module is indicated in the Processor Version Register (PVR) */
  36885. + switch(cpuModel)
  36886. + {
  36887. + case CPU_PART_MRVL131:
  36888. + mvOsSPrintf(pNameBuff, "%s (Rev %d)", "Marvell Feroceon",mvOsCpuRevGet());
  36889. + break;
  36890. + case CPU_PART_ARM926:
  36891. + mvOsSPrintf(pNameBuff, "%s (Rev %d)", "ARM926",mvOsCpuRevGet());
  36892. + break;
  36893. + case CPU_PART_ARM946:
  36894. + mvOsSPrintf(pNameBuff, "%s (Rev %d)", "ARM946",mvOsCpuRevGet());
  36895. + break;
  36896. + default:
  36897. + mvOsSPrintf(pNameBuff,"??? (0x%04x) (Rev %d)",cpuModel,mvOsCpuRevGet());
  36898. + break;
  36899. + } /* switch */
  36900. +
  36901. + return;
  36902. +}
  36903. +
  36904. +
  36905. +#define MV_PROC_STR_SIZE 50
  36906. +
  36907. +static void mvCpuIfGetL2EccMode(MV_8 *buf)
  36908. +{
  36909. + MV_U32 regVal = MV_REG_READ(CPU_L2_CONFIG_REG);
  36910. + if (regVal & BIT2)
  36911. + mvOsSPrintf(buf, "L2 ECC Enabled");
  36912. + else
  36913. + mvOsSPrintf(buf, "L2 ECC Disabled");
  36914. +}
  36915. +
  36916. +static void mvCpuIfGetL2Mode(MV_8 *buf)
  36917. +{
  36918. + MV_U32 regVal = 0;
  36919. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  36920. + if (regVal & BIT22)
  36921. + mvOsSPrintf(buf, "L2 Enabled");
  36922. + else
  36923. + mvOsSPrintf(buf, "L2 Disabled");
  36924. +}
  36925. +
  36926. +static void mvCpuIfGetL2PrefetchMode(MV_8 *buf)
  36927. +{
  36928. + MV_U32 regVal = 0;
  36929. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  36930. + if (regVal & BIT24)
  36931. + mvOsSPrintf(buf, "L2 Prefetch Disabled");
  36932. + else
  36933. + mvOsSPrintf(buf, "L2 Prefetch Enabled");
  36934. +}
  36935. +
  36936. +static void mvCpuIfGetWriteAllocMode(MV_8 *buf)
  36937. +{
  36938. + MV_U32 regVal = 0;
  36939. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  36940. + if (regVal & BIT28)
  36941. + mvOsSPrintf(buf, "Write Allocate Enabled");
  36942. + else
  36943. + mvOsSPrintf(buf, "Write Allocate Disabled");
  36944. +}
  36945. +
  36946. +static void mvCpuIfGetCpuStreamMode(MV_8 *buf)
  36947. +{
  36948. + MV_U32 regVal = 0;
  36949. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  36950. + if (regVal & BIT29)
  36951. + mvOsSPrintf(buf, "CPU Streaming Enabled");
  36952. + else
  36953. + mvOsSPrintf(buf, "CPU Streaming Disabled");
  36954. +}
  36955. +
  36956. +static void mvCpuIfPrintCpuRegs(void)
  36957. +{
  36958. + MV_U32 regVal = 0;
  36959. +
  36960. + __asm volatile ("mrc p15, 1, %0, c15, c1, 0" : "=r" (regVal)); /* Read Marvell extra features register */
  36961. + mvOsPrintf("Extra Feature Reg = 0x%x\n",regVal);
  36962. +
  36963. + __asm volatile ("mrc p15, 0, %0, c1, c0, 0" : "=r" (regVal)); /* Read Control register */
  36964. + mvOsPrintf("Control Reg = 0x%x\n",regVal);
  36965. +
  36966. + __asm volatile ("mrc p15, 0, %0, c0, c0, 0" : "=r" (regVal)); /* Read ID Code register */
  36967. + mvOsPrintf("ID Code Reg = 0x%x\n",regVal);
  36968. +
  36969. + __asm volatile ("mrc p15, 0, %0, c0, c0, 1" : "=r" (regVal)); /* Read Cache Type register */
  36970. + mvOsPrintf("Cache Type Reg = 0x%x\n",regVal);
  36971. +
  36972. +}
  36973. +
  36974. +MV_U32 mvCpuIfPrintSystemConfig(MV_8 *buffer, MV_U32 index)
  36975. +{
  36976. + MV_U32 count = 0;
  36977. +
  36978. + MV_8 L2_ECC_str[MV_PROC_STR_SIZE];
  36979. + MV_8 L2_En_str[MV_PROC_STR_SIZE];
  36980. + MV_8 L2_Prefetch_str[MV_PROC_STR_SIZE];
  36981. + MV_8 Write_Alloc_str[MV_PROC_STR_SIZE];
  36982. + MV_8 Cpu_Stream_str[MV_PROC_STR_SIZE];
  36983. +
  36984. + mvCpuIfGetL2Mode(L2_En_str);
  36985. + mvCpuIfGetL2EccMode(L2_ECC_str);
  36986. + mvCpuIfGetL2PrefetchMode(L2_Prefetch_str);
  36987. + mvCpuIfGetWriteAllocMode(Write_Alloc_str);
  36988. + mvCpuIfGetCpuStreamMode(Cpu_Stream_str);
  36989. + mvCpuIfPrintCpuRegs();
  36990. +
  36991. + count += mvOsSPrintf(buffer + count + index, "%s\n", L2_En_str);
  36992. + count += mvOsSPrintf(buffer + count + index, "%s\n", L2_ECC_str);
  36993. + count += mvOsSPrintf(buffer + count + index, "%s\n", L2_Prefetch_str);
  36994. + count += mvOsSPrintf(buffer + count + index, "%s\n", Write_Alloc_str);
  36995. + count += mvOsSPrintf(buffer + count + index, "%s\n", Cpu_Stream_str);
  36996. + return count;
  36997. +}
  36998. +
  36999. +MV_U32 whoAmI(MV_VOID)
  37000. +{
  37001. + return 0;
  37002. +}
  37003. +
  37004. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h
  37005. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h 1970-01-01 01:00:00.000000000 +0100
  37006. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/cpu/mvCpu.h 2011-08-01 14:38:19.000000000 +0200
  37007. @@ -0,0 +1,99 @@
  37008. +/*******************************************************************************
  37009. +Copyright (C) Marvell International Ltd. and its affiliates
  37010. +
  37011. +This software file (the "File") is owned and distributed by Marvell
  37012. +International Ltd. and/or its affiliates ("Marvell") under the following
  37013. +alternative licensing terms. Once you have made an election to distribute the
  37014. +File under one of the following license alternatives, please (i) delete this
  37015. +introductory statement regarding license alternatives, (ii) delete the two
  37016. +license alternatives that you have not elected to use and (iii) preserve the
  37017. +Marvell copyright notice above.
  37018. +
  37019. +********************************************************************************
  37020. +Marvell Commercial License Option
  37021. +
  37022. +If you received this File from Marvell and you have entered into a commercial
  37023. +license agreement (a "Commercial License") with Marvell, the File is licensed
  37024. +to you under the terms of the applicable Commercial License.
  37025. +
  37026. +********************************************************************************
  37027. +Marvell GPL License Option
  37028. +
  37029. +If you received this File from Marvell, you may opt to use, redistribute and/or
  37030. +modify this File in accordance with the terms and conditions of the General
  37031. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  37032. +available along with the File in the license.txt file or by writing to the Free
  37033. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  37034. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  37035. +
  37036. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  37037. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  37038. +DISCLAIMED. The GPL License provides additional details about this warranty
  37039. +disclaimer.
  37040. +********************************************************************************
  37041. +Marvell BSD License Option
  37042. +
  37043. +If you received this File from Marvell, you may opt to use, redistribute and/or
  37044. +modify this File under the following licensing terms.
  37045. +Redistribution and use in source and binary forms, with or without modification,
  37046. +are permitted provided that the following conditions are met:
  37047. +
  37048. + * Redistributions of source code must retain the above copyright notice,
  37049. + this list of conditions and the following disclaimer.
  37050. +
  37051. + * Redistributions in binary form must reproduce the above copyright
  37052. + notice, this list of conditions and the following disclaimer in the
  37053. + documentation and/or other materials provided with the distribution.
  37054. +
  37055. + * Neither the name of Marvell nor the names of its contributors may be
  37056. + used to endorse or promote products derived from this software without
  37057. + specific prior written permission.
  37058. +
  37059. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  37060. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  37061. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  37062. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  37063. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  37064. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37065. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  37066. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  37067. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  37068. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37069. +
  37070. +*******************************************************************************/
  37071. +
  37072. +
  37073. +#ifndef __INCmvCpuh
  37074. +#define __INCmvCpuh
  37075. +
  37076. +#include "mvCommon.h"
  37077. +#include "mvOs.h"
  37078. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  37079. +
  37080. +/* defines */
  37081. +#define CPU_PART_MRVL131 0x131
  37082. +#define CPU_PART_ARM926 0x926
  37083. +#define CPU_PART_ARM946 0x946
  37084. +#define MV_CPU_ARM_CLK_ELM_SIZE 12
  37085. +#define MV_CPU_ARM_CLK_RATIO_OFF 8
  37086. +#define MV_CPU_ARM_CLK_DDR_OFF 4
  37087. +
  37088. +#ifndef MV_ASMLANGUAGE
  37089. +typedef struct _mvCpuArmClk
  37090. +{
  37091. + MV_U32 cpuClk; /* CPU clock in MHz */
  37092. + MV_U32 ddrClk; /* DDR clock in MHz */
  37093. + MV_U32 l2Clk; /* CPU DDR clock ratio */
  37094. +
  37095. +}MV_CPU_ARM_CLK;
  37096. +
  37097. +MV_U32 mvCpuPclkGet(MV_VOID);
  37098. +MV_VOID mvCpuNameGet(char *pNameBuff);
  37099. +MV_U32 mvCpuL2ClkGet(MV_VOID);
  37100. +MV_U32 mvCpuIfPrintSystemConfig(MV_8 *buffer, MV_U32 index);
  37101. +MV_U32 whoAmI(MV_VOID);
  37102. +
  37103. +#endif /* MV_ASMLANGUAGE */
  37104. +
  37105. +
  37106. +#endif /* __INCmvCpuh */
  37107. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c
  37108. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c 1970-01-01 01:00:00.000000000 +0100
  37109. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.c 2011-08-01 14:38:19.000000000 +0200
  37110. @@ -0,0 +1,296 @@
  37111. +/*******************************************************************************
  37112. +Copyright (C) Marvell International Ltd. and its affiliates
  37113. +
  37114. +This software file (the "File") is owned and distributed by Marvell
  37115. +International Ltd. and/or its affiliates ("Marvell") under the following
  37116. +alternative licensing terms. Once you have made an election to distribute the
  37117. +File under one of the following license alternatives, please (i) delete this
  37118. +introductory statement regarding license alternatives, (ii) delete the two
  37119. +license alternatives that you have not elected to use and (iii) preserve the
  37120. +Marvell copyright notice above.
  37121. +
  37122. +********************************************************************************
  37123. +Marvell Commercial License Option
  37124. +
  37125. +If you received this File from Marvell and you have entered into a commercial
  37126. +license agreement (a "Commercial License") with Marvell, the File is licensed
  37127. +to you under the terms of the applicable Commercial License.
  37128. +
  37129. +********************************************************************************
  37130. +Marvell GPL License Option
  37131. +
  37132. +If you received this File from Marvell, you may opt to use, redistribute and/or
  37133. +modify this File in accordance with the terms and conditions of the General
  37134. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  37135. +available along with the File in the license.txt file or by writing to the Free
  37136. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  37137. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  37138. +
  37139. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  37140. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  37141. +DISCLAIMED. The GPL License provides additional details about this warranty
  37142. +disclaimer.
  37143. +********************************************************************************
  37144. +Marvell BSD License Option
  37145. +
  37146. +If you received this File from Marvell, you may opt to use, redistribute and/or
  37147. +modify this File under the following licensing terms.
  37148. +Redistribution and use in source and binary forms, with or without modification,
  37149. +are permitted provided that the following conditions are met:
  37150. +
  37151. + * Redistributions of source code must retain the above copyright notice,
  37152. + this list of conditions and the following disclaimer.
  37153. +
  37154. + * Redistributions in binary form must reproduce the above copyright
  37155. + notice, this list of conditions and the following disclaimer in the
  37156. + documentation and/or other materials provided with the distribution.
  37157. +
  37158. + * Neither the name of Marvell nor the names of its contributors may be
  37159. + used to endorse or promote products derived from this software without
  37160. + specific prior written permission.
  37161. +
  37162. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  37163. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  37164. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  37165. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  37166. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  37167. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37168. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  37169. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  37170. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  37171. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37172. +
  37173. +*******************************************************************************/
  37174. +
  37175. +/*******************************************************************************
  37176. +* mvCtrlEnvAddrDec.h - Marvell controller address decode library
  37177. +*
  37178. +* DESCRIPTION:
  37179. +*
  37180. +* DEPENDENCIES:
  37181. +* None.
  37182. +*
  37183. +*******************************************************************************/
  37184. +
  37185. +/* includes */
  37186. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  37187. +#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
  37188. +#include "ddr2/mvDramIfRegs.h"
  37189. +#include "pex/mvPexRegs.h"
  37190. +
  37191. +#define MV_DEBUG
  37192. +
  37193. +/* defines */
  37194. +#ifdef MV_DEBUG
  37195. + #define DB(x) x
  37196. +#else
  37197. + #define DB(x)
  37198. +#endif
  37199. +
  37200. +/* Default Attributes array */
  37201. +MV_TARGET_ATTRIB mvTargetDefaultsArray[] = TARGETS_DEF_ARRAY;
  37202. +extern MV_TARGET *sampleAtResetTargetArray;
  37203. +/* Dram\AHBToMbus\PEX share regsiter */
  37204. +
  37205. +#define CTRL_DEC_BASE_OFFS 16
  37206. +#define CTRL_DEC_BASE_MASK (0xffff << CTRL_DEC_BASE_OFFS)
  37207. +#define CTRL_DEC_BASE_ALIGNMENT 0x10000
  37208. +
  37209. +#define CTRL_DEC_SIZE_OFFS 16
  37210. +#define CTRL_DEC_SIZE_MASK (0xffff << CTRL_DEC_SIZE_OFFS)
  37211. +#define CTRL_DEC_SIZE_ALIGNMENT 0x10000
  37212. +
  37213. +#define CTRL_DEC_WIN_EN BIT0
  37214. +
  37215. +
  37216. +
  37217. +/*******************************************************************************
  37218. +* mvCtrlAddrDecToReg - Get address decode register format values
  37219. +*
  37220. +* DESCRIPTION:
  37221. +*
  37222. +* INPUT:
  37223. +*
  37224. +* OUTPUT:
  37225. +*
  37226. +* RETURN:
  37227. +*
  37228. +*******************************************************************************/
  37229. +MV_STATUS mvCtrlAddrDecToReg(MV_ADDR_WIN *pAddrDecWin, MV_DEC_REGS *pAddrDecRegs)
  37230. +{
  37231. +
  37232. + MV_U32 baseToReg=0 , sizeToReg=0;
  37233. +
  37234. + /* BaseLow[31:16] => base register [31:16] */
  37235. + baseToReg = pAddrDecWin->baseLow & CTRL_DEC_BASE_MASK;
  37236. +
  37237. + /* Write to address decode Base Address Register */
  37238. + pAddrDecRegs->baseReg &= ~CTRL_DEC_BASE_MASK;
  37239. + pAddrDecRegs->baseReg |= baseToReg;
  37240. +
  37241. + /* Get size register value according to window size */
  37242. + sizeToReg = ctrlSizeToReg(pAddrDecWin->size, CTRL_DEC_SIZE_ALIGNMENT);
  37243. +
  37244. + /* Size parameter validity check. */
  37245. + if (-1 == sizeToReg)
  37246. + {
  37247. + return MV_BAD_PARAM;
  37248. + }
  37249. +
  37250. + /* set size */
  37251. + pAddrDecRegs->sizeReg &= ~CTRL_DEC_SIZE_MASK;
  37252. + pAddrDecRegs->sizeReg |= (sizeToReg << CTRL_DEC_SIZE_OFFS);
  37253. +
  37254. +
  37255. + return MV_OK;
  37256. +
  37257. +}
  37258. +
  37259. +/*******************************************************************************
  37260. +* mvCtrlRegToAddrDec - Extract address decode struct from registers.
  37261. +*
  37262. +* DESCRIPTION:
  37263. +* This function extract address decode struct from address decode
  37264. +* registers given as parameters.
  37265. +*
  37266. +* INPUT:
  37267. +* pAddrDecRegs - Address decode register struct.
  37268. +*
  37269. +* OUTPUT:
  37270. +* pAddrDecWin - Target window data structure.
  37271. +*
  37272. +* RETURN:
  37273. +* MV_BAD_PARAM if address decode registers data is invalid.
  37274. +*
  37275. +*******************************************************************************/
  37276. +MV_STATUS mvCtrlRegToAddrDec(MV_DEC_REGS *pAddrDecRegs, MV_ADDR_WIN *pAddrDecWin)
  37277. +{
  37278. + MV_U32 sizeRegVal;
  37279. +
  37280. + sizeRegVal = (pAddrDecRegs->sizeReg & CTRL_DEC_SIZE_MASK) >>
  37281. + CTRL_DEC_SIZE_OFFS;
  37282. +
  37283. + pAddrDecWin->size = ctrlRegToSize(sizeRegVal, CTRL_DEC_SIZE_ALIGNMENT);
  37284. +
  37285. +
  37286. + /* Extract base address */
  37287. + /* Base register [31:16] ==> baseLow[31:16] */
  37288. + pAddrDecWin->baseLow = pAddrDecRegs->baseReg & CTRL_DEC_BASE_MASK;
  37289. +
  37290. + pAddrDecWin->baseHigh = 0;
  37291. +
  37292. + return MV_OK;
  37293. +
  37294. +}
  37295. +
  37296. +/*******************************************************************************
  37297. +* mvCtrlAttribGet -
  37298. +*
  37299. +* DESCRIPTION:
  37300. +*
  37301. +* INPUT:
  37302. +*
  37303. +* OUTPUT:
  37304. +*
  37305. +* RETURN:
  37306. +*
  37307. +*******************************************************************************/
  37308. +
  37309. +MV_STATUS mvCtrlAttribGet(MV_TARGET target,
  37310. + MV_TARGET_ATTRIB *targetAttrib)
  37311. +{
  37312. +
  37313. + targetAttrib->attrib = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].attrib;
  37314. + targetAttrib->targetId = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].targetId;
  37315. +
  37316. + return MV_OK;
  37317. +
  37318. +}
  37319. +
  37320. +/*******************************************************************************
  37321. +* mvCtrlGetAttrib -
  37322. +*
  37323. +* DESCRIPTION:
  37324. +*
  37325. +* INPUT:
  37326. +*
  37327. +* OUTPUT:
  37328. +*
  37329. +* RETURN:
  37330. +*
  37331. +*******************************************************************************/
  37332. +MV_TARGET mvCtrlTargetGet(MV_TARGET_ATTRIB *targetAttrib)
  37333. +{
  37334. + MV_TARGET target;
  37335. + MV_TARGET x;
  37336. + for (target = SDRAM_CS0; target < MAX_TARGETS ; target ++)
  37337. + {
  37338. + x = MV_CHANGE_BOOT_CS(target);
  37339. + if ((mvTargetDefaultsArray[x].attrib == targetAttrib->attrib) &&
  37340. + (mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(target)].targetId == targetAttrib->targetId))
  37341. + {
  37342. + /* found it */
  37343. + break;
  37344. + }
  37345. + }
  37346. +
  37347. + return target;
  37348. +}
  37349. +
  37350. +MV_STATUS mvCtrlAddrDecToParams(MV_DEC_WIN *pAddrDecWin,
  37351. + MV_DEC_WIN_PARAMS *pWinParam)
  37352. +{
  37353. + MV_U32 baseToReg=0, sizeToReg=0;
  37354. +
  37355. + /* BaseLow[31:16] => base register [31:16] */
  37356. + baseToReg = pAddrDecWin->addrWin.baseLow & CTRL_DEC_BASE_MASK;
  37357. +
  37358. + /* Write to address decode Base Address Register */
  37359. + pWinParam->baseAddr &= ~CTRL_DEC_BASE_MASK;
  37360. + pWinParam->baseAddr |= baseToReg;
  37361. +
  37362. + /* Get size register value according to window size */
  37363. + sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, CTRL_DEC_SIZE_ALIGNMENT);
  37364. +
  37365. + /* Size parameter validity check. */
  37366. + if (-1 == sizeToReg)
  37367. + {
  37368. + mvOsPrintf("mvCtrlAddrDecToParams: ERR. ctrlSizeToReg failed.\n");
  37369. + return MV_BAD_PARAM;
  37370. + }
  37371. + pWinParam->size = sizeToReg;
  37372. +
  37373. + pWinParam->attrib = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(pAddrDecWin->target)].attrib;
  37374. + pWinParam->targetId = mvTargetDefaultsArray[MV_CHANGE_BOOT_CS(pAddrDecWin->target)].targetId;
  37375. +
  37376. + return MV_OK;
  37377. +}
  37378. +
  37379. +MV_STATUS mvCtrlParamsToAddrDec(MV_DEC_WIN_PARAMS *pWinParam,
  37380. + MV_DEC_WIN *pAddrDecWin)
  37381. +{
  37382. + MV_TARGET_ATTRIB targetAttrib;
  37383. +
  37384. + pAddrDecWin->addrWin.baseLow = pWinParam->baseAddr;
  37385. +
  37386. + /* Upper 32bit address base is supported under PCI High Address remap */
  37387. + pAddrDecWin->addrWin.baseHigh = 0;
  37388. +
  37389. + /* Prepare sizeReg to ctrlRegToSize function */
  37390. + pAddrDecWin->addrWin.size = ctrlRegToSize(pWinParam->size, CTRL_DEC_SIZE_ALIGNMENT);
  37391. +
  37392. + if (-1 == pAddrDecWin->addrWin.size)
  37393. + {
  37394. + DB(mvOsPrintf("mvCtrlParamsToAddrDec: ERR. ctrlRegToSize failed.\n"));
  37395. + return MV_BAD_PARAM;
  37396. + }
  37397. + targetAttrib.targetId = pWinParam->targetId;
  37398. + targetAttrib.attrib = pWinParam->attrib;
  37399. +
  37400. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  37401. +
  37402. + return MV_OK;
  37403. +}
  37404. +
  37405. +
  37406. +
  37407. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h
  37408. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h 1970-01-01 01:00:00.000000000 +0100
  37409. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAddrDec.h 2011-08-01 14:38:19.000000000 +0200
  37410. @@ -0,0 +1,203 @@
  37411. +/*******************************************************************************
  37412. +Copyright (C) Marvell International Ltd. and its affiliates
  37413. +
  37414. +This software file (the "File") is owned and distributed by Marvell
  37415. +International Ltd. and/or its affiliates ("Marvell") under the following
  37416. +alternative licensing terms. Once you have made an election to distribute the
  37417. +File under one of the following license alternatives, please (i) delete this
  37418. +introductory statement regarding license alternatives, (ii) delete the two
  37419. +license alternatives that you have not elected to use and (iii) preserve the
  37420. +Marvell copyright notice above.
  37421. +
  37422. +********************************************************************************
  37423. +Marvell Commercial License Option
  37424. +
  37425. +If you received this File from Marvell and you have entered into a commercial
  37426. +license agreement (a "Commercial License") with Marvell, the File is licensed
  37427. +to you under the terms of the applicable Commercial License.
  37428. +
  37429. +********************************************************************************
  37430. +Marvell GPL License Option
  37431. +
  37432. +If you received this File from Marvell, you may opt to use, redistribute and/or
  37433. +modify this File in accordance with the terms and conditions of the General
  37434. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  37435. +available along with the File in the license.txt file or by writing to the Free
  37436. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  37437. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  37438. +
  37439. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  37440. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  37441. +DISCLAIMED. The GPL License provides additional details about this warranty
  37442. +disclaimer.
  37443. +********************************************************************************
  37444. +Marvell BSD License Option
  37445. +
  37446. +If you received this File from Marvell, you may opt to use, redistribute and/or
  37447. +modify this File under the following licensing terms.
  37448. +Redistribution and use in source and binary forms, with or without modification,
  37449. +are permitted provided that the following conditions are met:
  37450. +
  37451. + * Redistributions of source code must retain the above copyright notice,
  37452. + this list of conditions and the following disclaimer.
  37453. +
  37454. + * Redistributions in binary form must reproduce the above copyright
  37455. + notice, this list of conditions and the following disclaimer in the
  37456. + documentation and/or other materials provided with the distribution.
  37457. +
  37458. + * Neither the name of Marvell nor the names of its contributors may be
  37459. + used to endorse or promote products derived from this software without
  37460. + specific prior written permission.
  37461. +
  37462. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  37463. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  37464. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  37465. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  37466. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  37467. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37468. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  37469. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  37470. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  37471. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37472. +
  37473. +*******************************************************************************/
  37474. +
  37475. +
  37476. +#ifndef __INCmvCtrlEnvAddrDech
  37477. +#define __INCmvCtrlEnvAddrDech
  37478. +
  37479. +/* includes */
  37480. +#include "ctrlEnv/mvCtrlEnvLib.h"
  37481. +#include "ctrlEnv/mvCtrlEnvRegs.h"
  37482. +
  37483. +
  37484. +/* defines */
  37485. +/* DUnit attributes */
  37486. +#define ATMWCR_WIN_DUNIT_CS0_OFFS 0
  37487. +#define ATMWCR_WIN_DUNIT_CS0_MASK BIT0
  37488. +#define ATMWCR_WIN_DUNIT_CS0_REQ (0 << ATMWCR_WIN_DUNIT_CS0_OFFS)
  37489. +
  37490. +#define ATMWCR_WIN_DUNIT_CS1_OFFS 1
  37491. +#define ATMWCR_WIN_DUNIT_CS1_MASK BIT1
  37492. +#define ATMWCR_WIN_DUNIT_CS1_REQ (0 << ATMWCR_WIN_DUNIT_CS1_OFFS)
  37493. +
  37494. +#define ATMWCR_WIN_DUNIT_CS2_OFFS 2
  37495. +#define ATMWCR_WIN_DUNIT_CS2_MASK BIT2
  37496. +#define ATMWCR_WIN_DUNIT_CS2_REQ (0 << ATMWCR_WIN_DUNIT_CS2_OFFS)
  37497. +
  37498. +#define ATMWCR_WIN_DUNIT_CS3_OFFS 3
  37499. +#define ATMWCR_WIN_DUNIT_CS3_MASK BIT3
  37500. +#define ATMWCR_WIN_DUNIT_CS3_REQ (0 << ATMWCR_WIN_DUNIT_CS3_OFFS)
  37501. +
  37502. +/* RUnit (Device) attributes */
  37503. +#define ATMWCR_WIN_RUNIT_DEVCS0_OFFS 0
  37504. +#define ATMWCR_WIN_RUNIT_DEVCS0_MASK BIT0
  37505. +#define ATMWCR_WIN_RUNIT_DEVCS0_REQ (0 << ATMWCR_WIN_RUNIT_DEVCS0_OFFS)
  37506. +
  37507. +#define ATMWCR_WIN_RUNIT_DEVCS1_OFFS 1
  37508. +#define ATMWCR_WIN_RUNIT_DEVCS1_MASK BIT1
  37509. +#define ATMWCR_WIN_RUNIT_DEVCS1_REQ (0 << ATMWCR_WIN_RUNIT_DEVCS1_OFFS)
  37510. +
  37511. +#define ATMWCR_WIN_RUNIT_DEVCS2_OFFS 2
  37512. +#define ATMWCR_WIN_RUNIT_DEVCS2_MASK BIT2
  37513. +#define ATMWCR_WIN_RUNIT_DEVCS2_REQ (0 << ATMWCR_WIN_RUNIT_DEVCS2_OFFS)
  37514. +
  37515. +#define ATMWCR_WIN_RUNIT_BOOTCS_OFFS 4
  37516. +#define ATMWCR_WIN_RUNIT_BOOTCS_MASK BIT4
  37517. +#define ATMWCR_WIN_RUNIT_BOOTCS_REQ (0 << ATMWCR_WIN_RUNIT_BOOTCS_OFFS)
  37518. +
  37519. +/* LMaster (PCI) attributes */
  37520. +#define ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS 0
  37521. +#define ATMWCR_WIN_LUNIT_BYTE_SWP_MASK BIT0
  37522. +#define ATMWCR_WIN_LUNIT_BYTE_SWP (0 << ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS)
  37523. +#define ATMWCR_WIN_LUNIT_BYTE_NO_SWP (1 << ATMWCR_WIN_LUNIT_BYTE_SWP_OFFS)
  37524. +
  37525. +
  37526. +#define ATMWCR_WIN_LUNIT_WORD_SWP_OFFS 1
  37527. +#define ATMWCR_WIN_LUNIT_WORD_SWP_MASK BIT1
  37528. +#define ATMWCR_WIN_LUNIT_WORD_SWP (0 << ATMWCR_WIN_LUNIT_WORD_SWP_OFFS)
  37529. +#define ATMWCR_WIN_LUNIT_WORD_NO_SWP (1 << ATMWCR_WIN_LUNIT_WORD_SWP_OFFS)
  37530. +
  37531. +#define ATMWCR_WIN_LUNIT_NO_SNOOP BIT2
  37532. +
  37533. +#define ATMWCR_WIN_LUNIT_TYPE_OFFS 3
  37534. +#define ATMWCR_WIN_LUNIT_TYPE_MASK BIT3
  37535. +#define ATMWCR_WIN_LUNIT_TYPE_IO (0 << ATMWCR_WIN_LUNIT_TYPE_OFFS)
  37536. +#define ATMWCR_WIN_LUNIT_TYPE_MEM (1 << ATMWCR_WIN_LUNIT_TYPE_OFFS)
  37537. +
  37538. +#define ATMWCR_WIN_LUNIT_FORCE64_OFFS 4
  37539. +#define ATMWCR_WIN_LUNIT_FORCE64_MASK BIT4
  37540. +#define ATMWCR_WIN_LUNIT_FORCE64 (0 << ATMWCR_WIN_LUNIT_FORCE64_OFFS)
  37541. +
  37542. +#define ATMWCR_WIN_LUNIT_ORDERING_OFFS 6
  37543. +#define ATMWCR_WIN_LUNIT_ORDERING_MASK BIT6
  37544. +#define ATMWCR_WIN_LUNIT_ORDERING (1 << ATMWCR_WIN_LUNIT_FORCE64_OFFS)
  37545. +
  37546. +/* PEX Attributes */
  37547. +#define ATMWCR_WIN_PEX_TYPE_OFFS 3
  37548. +#define ATMWCR_WIN_PEX_TYPE_MASK BIT3
  37549. +#define ATMWCR_WIN_PEX_TYPE_IO (0 << ATMWCR_WIN_PEX_TYPE_OFFS)
  37550. +#define ATMWCR_WIN_PEX_TYPE_MEM (1 << ATMWCR_WIN_PEX_TYPE_OFFS)
  37551. +
  37552. +/* typedefs */
  37553. +
  37554. +/* Unsupported attributes for address decode: */
  37555. +/* 2) PCI0/1_REQ64n control */
  37556. +
  37557. +typedef struct _mvDecRegs
  37558. +{
  37559. + MV_U32 baseReg;
  37560. + MV_U32 baseRegHigh;
  37561. + MV_U32 sizeReg;
  37562. +
  37563. +}MV_DEC_REGS;
  37564. +
  37565. +typedef struct _mvTargetAttrib
  37566. +{
  37567. + MV_U8 attrib; /* chip select attributes */
  37568. + MV_TARGET_ID targetId; /* Target Id of this MV_TARGET */
  37569. +
  37570. +}MV_TARGET_ATTRIB;
  37571. +
  37572. +
  37573. +/* This structure describes address decode window */
  37574. +typedef struct _mvDecWin
  37575. +{
  37576. + MV_TARGET target; /* Target for addr decode window */
  37577. + MV_ADDR_WIN addrWin; /* Address window of target */
  37578. + MV_BOOL enable; /* Window enable/disable */
  37579. +}MV_DEC_WIN;
  37580. +
  37581. +typedef struct _mvDecWinParams
  37582. +{
  37583. + MV_TARGET_ID targetId; /* Target ID field */
  37584. + MV_U8 attrib; /* Attribute field */
  37585. + MV_U32 baseAddr; /* Base address in register format */
  37586. + MV_U32 size; /* Size in register format */
  37587. +}MV_DEC_WIN_PARAMS;
  37588. +
  37589. +
  37590. +/* mvCtrlEnvAddrDec API list */
  37591. +
  37592. +MV_STATUS mvCtrlAddrDecToReg(MV_ADDR_WIN *pAddrDecWin,
  37593. + MV_DEC_REGS *pAddrDecRegs);
  37594. +
  37595. +MV_STATUS mvCtrlRegToAddrDec(MV_DEC_REGS *pAddrDecRegs,
  37596. + MV_ADDR_WIN *pAddrDecWin);
  37597. +
  37598. +MV_STATUS mvCtrlAttribGet(MV_TARGET target,
  37599. + MV_TARGET_ATTRIB *targetAttrib);
  37600. +
  37601. +MV_TARGET mvCtrlTargetGet(MV_TARGET_ATTRIB *targetAttrib);
  37602. +
  37603. +
  37604. +MV_STATUS mvCtrlAddrDecToParams(MV_DEC_WIN *pAddrDecWin,
  37605. + MV_DEC_WIN_PARAMS *pWinParam);
  37606. +
  37607. +MV_STATUS mvCtrlParamsToAddrDec(MV_DEC_WIN_PARAMS *pWinParam,
  37608. + MV_DEC_WIN *pAddrDecWin);
  37609. +
  37610. +
  37611. +
  37612. +
  37613. +#endif /* __INCmvCtrlEnvAddrDech */
  37614. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h
  37615. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h 1970-01-01 01:00:00.000000000 +0100
  37616. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvAsm.h 2011-08-01 14:38:19.000000000 +0200
  37617. @@ -0,0 +1,98 @@
  37618. +/*******************************************************************************
  37619. +Copyright (C) Marvell International Ltd. and its affiliates
  37620. +
  37621. +This software file (the "File") is owned and distributed by Marvell
  37622. +International Ltd. and/or its affiliates ("Marvell") under the following
  37623. +alternative licensing terms. Once you have made an election to distribute the
  37624. +File under one of the following license alternatives, please (i) delete this
  37625. +introductory statement regarding license alternatives, (ii) delete the two
  37626. +license alternatives that you have not elected to use and (iii) preserve the
  37627. +Marvell copyright notice above.
  37628. +
  37629. +********************************************************************************
  37630. +Marvell Commercial License Option
  37631. +
  37632. +If you received this File from Marvell and you have entered into a commercial
  37633. +license agreement (a "Commercial License") with Marvell, the File is licensed
  37634. +to you under the terms of the applicable Commercial License.
  37635. +
  37636. +********************************************************************************
  37637. +Marvell GPL License Option
  37638. +
  37639. +If you received this File from Marvell, you may opt to use, redistribute and/or
  37640. +modify this File in accordance with the terms and conditions of the General
  37641. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  37642. +available along with the File in the license.txt file or by writing to the Free
  37643. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  37644. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  37645. +
  37646. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  37647. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  37648. +DISCLAIMED. The GPL License provides additional details about this warranty
  37649. +disclaimer.
  37650. +********************************************************************************
  37651. +Marvell BSD License Option
  37652. +
  37653. +If you received this File from Marvell, you may opt to use, redistribute and/or
  37654. +modify this File under the following licensing terms.
  37655. +Redistribution and use in source and binary forms, with or without modification,
  37656. +are permitted provided that the following conditions are met:
  37657. +
  37658. + * Redistributions of source code must retain the above copyright notice,
  37659. + this list of conditions and the following disclaimer.
  37660. +
  37661. + * Redistributions in binary form must reproduce the above copyright
  37662. + notice, this list of conditions and the following disclaimer in the
  37663. + documentation and/or other materials provided with the distribution.
  37664. +
  37665. + * Neither the name of Marvell nor the names of its contributors may be
  37666. + used to endorse or promote products derived from this software without
  37667. + specific prior written permission.
  37668. +
  37669. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  37670. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  37671. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  37672. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  37673. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  37674. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37675. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  37676. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  37677. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  37678. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37679. +
  37680. +*******************************************************************************/
  37681. +
  37682. +
  37683. +#ifndef __INCmvCtrlEnvAsmh
  37684. +#define __INCmvCtrlEnvAsmh
  37685. +#include "pex/mvPexRegs.h"
  37686. +
  37687. +#define CHIP_BOND_REG 0x10034
  37688. +#define PCKG_OPT_MASK_AS #3
  37689. +#define PXCCARI_REVID_MASK_AS #PXCCARI_REVID_MASK
  37690. +
  37691. +/* Read device ID into toReg bits 15:0 from 0xd0000000 */
  37692. +/* defines */
  37693. +#define MV_DV_CTRL_MODEL_GET_ASM(toReg, tmpReg) \
  37694. + MV_DV_REG_READ_ASM(toReg, tmpReg, CHIP_BOND_REG);\
  37695. + and toReg, toReg, PCKG_OPT_MASK_AS /* Mask for package ID */
  37696. +
  37697. +/* Read device ID into toReg bits 15:0 from 0xf1000000*/
  37698. +#define MV_CTRL_MODEL_GET_ASM(toReg, tmpReg) \
  37699. + MV_REG_READ_ASM(toReg, tmpReg, CHIP_BOND_REG);\
  37700. + and toReg, toReg, PCKG_OPT_MASK_AS /* Mask for package ID */
  37701. +
  37702. +/* Read Revision into toReg bits 7:0 0xd0000000*/
  37703. +#define MV_DV_CTRL_REV_GET_ASM(toReg, tmpReg) \
  37704. + /* Read device revision */ \
  37705. + MV_DV_REG_READ_ASM(toReg, tmpReg, PEX_CFG_DIRECT_ACCESS(0,PEX_CLASS_CODE_AND_REVISION_ID));\
  37706. + and toReg, toReg, PXCCARI_REVID_MASK_AS /* Mask for calss ID */
  37707. +
  37708. +/* Read Revision into toReg bits 7:0 0xf1000000*/
  37709. +#define MV_CTRL_REV_GET_ASM(toReg, tmpReg) \
  37710. + /* Read device revision */ \
  37711. + MV_REG_READ_ASM(toReg, tmpReg, PEX_CFG_DIRECT_ACCESS(0,PEX_CLASS_CODE_AND_REVISION_ID));\
  37712. + and toReg, toReg, PXCCARI_REVID_MASK_AS /* Mask for calss ID */
  37713. +
  37714. +
  37715. +#endif /* __INCmvCtrlEnvAsmh */
  37716. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c
  37717. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c 1970-01-01 01:00:00.000000000 +0100
  37718. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.c 2011-08-01 14:38:19.000000000 +0200
  37719. @@ -0,0 +1,1825 @@
  37720. +/*******************************************************************************
  37721. +Copyright (C) Marvell International Ltd. and its affiliates
  37722. +
  37723. +This software file (the "File") is owned and distributed by Marvell
  37724. +International Ltd. and/or its affiliates ("Marvell") under the following
  37725. +alternative licensing terms. Once you have made an election to distribute the
  37726. +File under one of the following license alternatives, please (i) delete this
  37727. +introductory statement regarding license alternatives, (ii) delete the two
  37728. +license alternatives that you have not elected to use and (iii) preserve the
  37729. +Marvell copyright notice above.
  37730. +
  37731. +********************************************************************************
  37732. +Marvell Commercial License Option
  37733. +
  37734. +If you received this File from Marvell and you have entered into a commercial
  37735. +license agreement (a "Commercial License") with Marvell, the File is licensed
  37736. +to you under the terms of the applicable Commercial License.
  37737. +
  37738. +********************************************************************************
  37739. +Marvell GPL License Option
  37740. +
  37741. +If you received this File from Marvell, you may opt to use, redistribute and/or
  37742. +modify this File in accordance with the terms and conditions of the General
  37743. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  37744. +available along with the File in the license.txt file or by writing to the Free
  37745. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  37746. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  37747. +
  37748. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  37749. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  37750. +DISCLAIMED. The GPL License provides additional details about this warranty
  37751. +disclaimer.
  37752. +********************************************************************************
  37753. +Marvell BSD License Option
  37754. +
  37755. +If you received this File from Marvell, you may opt to use, redistribute and/or
  37756. +modify this File under the following licensing terms.
  37757. +Redistribution and use in source and binary forms, with or without modification,
  37758. +are permitted provided that the following conditions are met:
  37759. +
  37760. + * Redistributions of source code must retain the above copyright notice,
  37761. + this list of conditions and the following disclaimer.
  37762. +
  37763. + * Redistributions in binary form must reproduce the above copyright
  37764. + notice, this list of conditions and the following disclaimer in the
  37765. + documentation and/or other materials provided with the distribution.
  37766. +
  37767. + * Neither the name of Marvell nor the names of its contributors may be
  37768. + used to endorse or promote products derived from this software without
  37769. + specific prior written permission.
  37770. +
  37771. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  37772. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  37773. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  37774. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  37775. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  37776. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  37777. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  37778. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  37779. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  37780. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37781. +
  37782. +*******************************************************************************/
  37783. +
  37784. +
  37785. +/* includes */
  37786. +#include "mvCommon.h"
  37787. +#include "mvCtrlEnvLib.h"
  37788. +#include "ctrlEnv/sys/mvCpuIf.h"
  37789. +
  37790. +#if defined(MV_INCLUDE_PEX)
  37791. +#include "pex/mvPex.h"
  37792. +#include "ctrlEnv/sys/mvSysPex.h"
  37793. +#endif
  37794. +
  37795. +#if defined(MV_INCLUDE_GIG_ETH)
  37796. +#include "ctrlEnv/sys/mvSysGbe.h"
  37797. +#endif
  37798. +
  37799. +#if defined(MV_INCLUDE_XOR)
  37800. +#include "ctrlEnv/sys/mvSysXor.h"
  37801. +#endif
  37802. +
  37803. +#if defined(MV_INCLUDE_SATA)
  37804. +#include "ctrlEnv/sys/mvSysSata.h"
  37805. +#endif
  37806. +
  37807. +#if defined(MV_INCLUDE_USB)
  37808. +#include "ctrlEnv/sys/mvSysUsb.h"
  37809. +#endif
  37810. +
  37811. +#if defined(MV_INCLUDE_AUDIO)
  37812. +#include "ctrlEnv/sys/mvSysAudio.h"
  37813. +#endif
  37814. +
  37815. +#if defined(MV_INCLUDE_CESA)
  37816. +#include "ctrlEnv/sys/mvSysCesa.h"
  37817. +#endif
  37818. +
  37819. +#if defined(MV_INCLUDE_TS)
  37820. +#include "ctrlEnv/sys/mvSysTs.h"
  37821. +#endif
  37822. +
  37823. +/* defines */
  37824. +#ifdef MV_DEBUG
  37825. + #define DB(x) x
  37826. +#else
  37827. + #define DB(x)
  37828. +#endif
  37829. +
  37830. +/*******************************************************************************
  37831. +* mvCtrlEnvInit - Initialize Marvell controller environment.
  37832. +*
  37833. +* DESCRIPTION:
  37834. +* This function get environment information and initialize controller
  37835. +* internal/external environment. For example
  37836. +* 1) MPP settings according to board MPP macros.
  37837. +* NOTE: It is the user responsibility to shut down all DMA channels
  37838. +* in device and disable controller sub units interrupts during
  37839. +* boot process.
  37840. +*
  37841. +* INPUT:
  37842. +* None.
  37843. +*
  37844. +* OUTPUT:
  37845. +* None.
  37846. +*
  37847. +* RETURN:
  37848. +* None.
  37849. +*
  37850. +*******************************************************************************/
  37851. +MV_STATUS mvCtrlEnvInit(MV_VOID)
  37852. +{
  37853. + MV_U32 mppGroup;
  37854. + MV_U32 devId;
  37855. + MV_U32 boardId;
  37856. + MV_U32 i;
  37857. + MV_U32 maxMppGrp = 1;
  37858. + MV_U32 mppVal = 0;
  37859. + MV_U32 bootVal = 0;
  37860. + MV_U32 mppGroupType = 0;
  37861. + MV_U32 mppGroup1[][3] = MPP_GROUP_1_TYPE;
  37862. + MV_U32 mppGroup2[][3] = MPP_GROUP_2_TYPE;
  37863. +
  37864. + devId = mvCtrlModelGet();
  37865. + boardId= mvBoardIdGet();
  37866. +
  37867. + switch(devId){
  37868. + case MV_6281_DEV_ID:
  37869. + maxMppGrp = MV_6281_MPP_MAX_GROUP;
  37870. + break;
  37871. + case MV_6192_DEV_ID:
  37872. + maxMppGrp = MV_6192_MPP_MAX_GROUP;
  37873. + break;
  37874. + case MV_6190_DEV_ID:
  37875. + maxMppGrp = MV_6190_MPP_MAX_GROUP;
  37876. + break;
  37877. + case MV_6180_DEV_ID:
  37878. + maxMppGrp = MV_6180_MPP_MAX_GROUP;
  37879. + break;
  37880. + }
  37881. +
  37882. + /* MPP Init */
  37883. + /* We split mpp init to 3 phases:
  37884. + * 1. We init mpp[19:0] from the board info. mpp[23:20] will be over write
  37885. + * in phase 2.
  37886. + * 2. We detect the mpp group type and according the mpp values [35:20].
  37887. + * 3. We detect the mpp group type and according the mpp values [49:36].
  37888. + */
  37889. + /* Mpp phase 1 mpp[19:0] */
  37890. + /* Read MPP group from board level and assign to MPP register */
  37891. + for (mppGroup = 0; mppGroup < 3; mppGroup++)
  37892. + {
  37893. + mppVal = mvBoardMppGet(mppGroup);
  37894. + if (mppGroup == 0)
  37895. + {
  37896. + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
  37897. + if (mvCtrlIsBootFromSPI())
  37898. + {
  37899. + mppVal &= ~0xffff;
  37900. + bootVal &= 0xffff;
  37901. + mppVal |= bootVal;
  37902. + }
  37903. + else if (mvCtrlIsBootFromSPIUseNAND())
  37904. + {
  37905. + mppVal &= ~0xf0000000;
  37906. + bootVal &= 0xf0000000;
  37907. + mppVal |= bootVal;
  37908. + }
  37909. + else if (mvCtrlIsBootFromNAND())
  37910. + {
  37911. + mppVal &= ~0xffffff;
  37912. + bootVal &= 0xffffff;
  37913. + mppVal |= bootVal;
  37914. + }
  37915. + }
  37916. +
  37917. + if (mppGroup == 2)
  37918. + {
  37919. + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
  37920. + if (mvCtrlIsBootFromNAND())
  37921. + {
  37922. + mppVal &= ~0xff00;
  37923. + bootVal &= 0xff00;
  37924. + mppVal |= bootVal;
  37925. + }
  37926. + }
  37927. +
  37928. + MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
  37929. + }
  37930. +
  37931. + /* Identify MPPs group */
  37932. + mvBoardMppGroupIdUpdate();
  37933. +
  37934. + /* Update MPPs mux relevent only on Marvell DB */
  37935. + if ((boardId == DB_88F6281A_BP_ID) ||
  37936. + (boardId == DB_88F6180A_BP_ID))
  37937. + mvBoardMppMuxSet();
  37938. +
  37939. + mppGroupType = mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_1);
  37940. +
  37941. + /* Mpp phase 2 */
  37942. + /* Read MPP group from board level and assign to MPP register */
  37943. + if (devId != MV_6180_DEV_ID)
  37944. + {
  37945. + i = 0;
  37946. + for (mppGroup = 2; mppGroup < 5; mppGroup++)
  37947. + {
  37948. + if ((mppGroupType == MV_BOARD_OTHER) ||
  37949. + (boardId == RD_88F6281A_ID) ||
  37950. + (boardId == RD_88F6192A_ID) ||
  37951. + (boardId == RD_88F6190A_ID) ||
  37952. + (boardId == RD_88F6281A_PCAC_ID) ||
  37953. + (boardId == SHEEVA_PLUG_ID))
  37954. + mppVal = mvBoardMppGet(mppGroup);
  37955. + else
  37956. + {
  37957. + mppVal = mppGroup1[mppGroupType][i];
  37958. + i++;
  37959. + }
  37960. +
  37961. + /* Group 2 is shared mpp[23:16] */
  37962. + if (mppGroup == 2)
  37963. + {
  37964. + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
  37965. + mppVal &= ~0xffff;
  37966. + bootVal &= 0xffff;
  37967. + mppVal |= bootVal;
  37968. + }
  37969. +
  37970. + MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
  37971. + }
  37972. + }
  37973. +
  37974. + if ((devId == MV_6192_DEV_ID) || (devId == MV_6190_DEV_ID))
  37975. + return MV_OK;
  37976. +
  37977. + /* Mpp phase 3 */
  37978. + mppGroupType = mvBoardMppGroupTypeGet(MV_BOARD_MPP_GROUP_2);
  37979. + /* Read MPP group from board level and assign to MPP register */
  37980. + i = 0;
  37981. + for (mppGroup = 4; mppGroup < 7; mppGroup++)
  37982. + {
  37983. + if ((mppGroupType == MV_BOARD_OTHER) ||
  37984. + (boardId == RD_88F6281A_ID) ||
  37985. + (boardId == RD_88F6281A_PCAC_ID) ||
  37986. + (boardId == SHEEVA_PLUG_ID))
  37987. + mppVal = mvBoardMppGet(mppGroup);
  37988. + else
  37989. + {
  37990. + mppVal = mppGroup2[mppGroupType][i];
  37991. + i++;
  37992. + }
  37993. +
  37994. + /* Group 4 is shared mpp[35:32] */
  37995. + if (mppGroup == 4)
  37996. + {
  37997. + bootVal = MV_REG_READ(mvCtrlMppRegGet(mppGroup));
  37998. + mppVal &= ~0xffff;
  37999. + bootVal &= 0xffff;
  38000. + mppVal |= bootVal;
  38001. + }
  38002. +
  38003. + MV_REG_WRITE(mvCtrlMppRegGet(mppGroup), mppVal);
  38004. + }
  38005. + /* Update SSCG configuration register*/
  38006. + if(mvBoardIdGet() == DB_88F6281A_BP_ID || mvBoardIdGet() == DB_88F6192A_BP_ID ||
  38007. + mvBoardIdGet() == DB_88F6190A_BP_ID || mvBoardIdGet() == DB_88F6180A_BP_ID)
  38008. + MV_REG_WRITE(0x100d8, 0x53);
  38009. +
  38010. + return MV_OK;
  38011. +}
  38012. +
  38013. +/*******************************************************************************
  38014. +* mvCtrlMppRegGet - return reg address of mpp group
  38015. +*
  38016. +* DESCRIPTION:
  38017. +*
  38018. +* INPUT:
  38019. +* mppGroup - MPP group.
  38020. +*
  38021. +* OUTPUT:
  38022. +* None.
  38023. +*
  38024. +* RETURN:
  38025. +* MV_U32 - Register address.
  38026. +*
  38027. +*******************************************************************************/
  38028. +MV_U32 mvCtrlMppRegGet(MV_U32 mppGroup)
  38029. +{
  38030. + MV_U32 ret;
  38031. +
  38032. + switch(mppGroup){
  38033. + case (0): ret = MPP_CONTROL_REG0;
  38034. + break;
  38035. + case (1): ret = MPP_CONTROL_REG1;
  38036. + break;
  38037. + case (2): ret = MPP_CONTROL_REG2;
  38038. + break;
  38039. + case (3): ret = MPP_CONTROL_REG3;
  38040. + break;
  38041. + case (4): ret = MPP_CONTROL_REG4;
  38042. + break;
  38043. + case (5): ret = MPP_CONTROL_REG5;
  38044. + break;
  38045. + case (6): ret = MPP_CONTROL_REG6;
  38046. + break;
  38047. + default: ret = MPP_CONTROL_REG0;
  38048. + break;
  38049. + }
  38050. + return ret;
  38051. +}
  38052. +#if defined(MV_INCLUDE_PEX)
  38053. +/*******************************************************************************
  38054. +* mvCtrlPexMaxIfGet - Get Marvell controller number of PEX interfaces.
  38055. +*
  38056. +* DESCRIPTION:
  38057. +* This function returns Marvell controller number of PEX interfaces.
  38058. +*
  38059. +* INPUT:
  38060. +* None.
  38061. +*
  38062. +* OUTPUT:
  38063. +* None.
  38064. +*
  38065. +* RETURN:
  38066. +* Marvell controller number of PEX interfaces. If controller
  38067. +* ID is undefined the function returns '0'.
  38068. +*
  38069. +*******************************************************************************/
  38070. +MV_U32 mvCtrlPexMaxIfGet(MV_VOID)
  38071. +{
  38072. +
  38073. + return MV_PEX_MAX_IF;
  38074. +}
  38075. +#endif
  38076. +
  38077. +#if defined(MV_INCLUDE_GIG_ETH)
  38078. +/*******************************************************************************
  38079. +* mvCtrlEthMaxPortGet - Get Marvell controller number of etherent ports.
  38080. +*
  38081. +* DESCRIPTION:
  38082. +* This function returns Marvell controller number of etherent port.
  38083. +*
  38084. +* INPUT:
  38085. +* None.
  38086. +*
  38087. +* OUTPUT:
  38088. +* None.
  38089. +*
  38090. +* RETURN:
  38091. +* Marvell controller number of etherent port.
  38092. +*
  38093. +*******************************************************************************/
  38094. +MV_U32 mvCtrlEthMaxPortGet(MV_VOID)
  38095. +{
  38096. + MV_U32 devId;
  38097. +
  38098. + devId = mvCtrlModelGet();
  38099. +
  38100. + switch(devId){
  38101. + case MV_6281_DEV_ID:
  38102. + return MV_6281_ETH_MAX_PORTS;
  38103. + break;
  38104. + case MV_6192_DEV_ID:
  38105. + return MV_6192_ETH_MAX_PORTS;
  38106. + break;
  38107. + case MV_6190_DEV_ID:
  38108. + return MV_6190_ETH_MAX_PORTS;
  38109. + break;
  38110. + case MV_6180_DEV_ID:
  38111. + return MV_6180_ETH_MAX_PORTS;
  38112. + break;
  38113. + }
  38114. + return 0;
  38115. +
  38116. +}
  38117. +#endif
  38118. +
  38119. +#if defined(MV_INCLUDE_XOR)
  38120. +/*******************************************************************************
  38121. +* mvCtrlXorMaxChanGet - Get Marvell controller number of XOR channels.
  38122. +*
  38123. +* DESCRIPTION:
  38124. +* This function returns Marvell controller number of XOR channels.
  38125. +*
  38126. +* INPUT:
  38127. +* None.
  38128. +*
  38129. +* OUTPUT:
  38130. +* None.
  38131. +*
  38132. +* RETURN:
  38133. +* Marvell controller number of XOR channels.
  38134. +*
  38135. +*******************************************************************************/
  38136. +MV_U32 mvCtrlXorMaxChanGet(MV_VOID)
  38137. +{
  38138. + return MV_XOR_MAX_CHAN;
  38139. +}
  38140. +#endif
  38141. +
  38142. +#if defined(MV_INCLUDE_USB)
  38143. +/*******************************************************************************
  38144. +* mvCtrlUsbHostMaxGet - Get number of Marvell Usb controllers
  38145. +*
  38146. +* DESCRIPTION:
  38147. +*
  38148. +* INPUT:
  38149. +* None.
  38150. +*
  38151. +* OUTPUT:
  38152. +* None.
  38153. +*
  38154. +* RETURN:
  38155. +* returns number of Marvell USB controllers.
  38156. +*
  38157. +*******************************************************************************/
  38158. +MV_U32 mvCtrlUsbMaxGet(void)
  38159. +{
  38160. + return MV_USB_MAX_PORTS;
  38161. +}
  38162. +#endif
  38163. +
  38164. +
  38165. +#if defined(MV_INCLUDE_NAND)
  38166. +/*******************************************************************************
  38167. +* mvCtrlNandSupport - Return if this controller has integrated NAND flash support
  38168. +*
  38169. +* DESCRIPTION:
  38170. +*
  38171. +* INPUT:
  38172. +* None.
  38173. +*
  38174. +* OUTPUT:
  38175. +* None.
  38176. +*
  38177. +* RETURN:
  38178. +* MV_TRUE if NAND is supported and MV_FALSE otherwise
  38179. +*
  38180. +*******************************************************************************/
  38181. +MV_U32 mvCtrlNandSupport(MV_VOID)
  38182. +{
  38183. + MV_U32 devId;
  38184. +
  38185. + devId = mvCtrlModelGet();
  38186. +
  38187. + switch(devId){
  38188. + case MV_6281_DEV_ID:
  38189. + return MV_6281_NAND;
  38190. + break;
  38191. + case MV_6192_DEV_ID:
  38192. + return MV_6192_NAND;
  38193. + break;
  38194. + case MV_6190_DEV_ID:
  38195. + return MV_6190_NAND;
  38196. + break;
  38197. + case MV_6180_DEV_ID:
  38198. + return MV_6180_NAND;
  38199. + break;
  38200. + }
  38201. + return 0;
  38202. +
  38203. +}
  38204. +#endif
  38205. +
  38206. +#if defined(MV_INCLUDE_SDIO)
  38207. +/*******************************************************************************
  38208. +* mvCtrlSdioSupport - Return if this controller has integrated SDIO flash support
  38209. +*
  38210. +* DESCRIPTION:
  38211. +*
  38212. +* INPUT:
  38213. +* None.
  38214. +*
  38215. +* OUTPUT:
  38216. +* None.
  38217. +*
  38218. +* RETURN:
  38219. +* MV_TRUE if SDIO is supported and MV_FALSE otherwise
  38220. +*
  38221. +*******************************************************************************/
  38222. +MV_U32 mvCtrlSdioSupport(MV_VOID)
  38223. +{
  38224. + MV_U32 devId;
  38225. +
  38226. + devId = mvCtrlModelGet();
  38227. +
  38228. + switch(devId){
  38229. + case MV_6281_DEV_ID:
  38230. + return MV_6281_SDIO;
  38231. + break;
  38232. + case MV_6192_DEV_ID:
  38233. + return MV_6192_SDIO;
  38234. + break;
  38235. + case MV_6190_DEV_ID:
  38236. + return MV_6190_SDIO;
  38237. + break;
  38238. + case MV_6180_DEV_ID:
  38239. + return MV_6180_SDIO;
  38240. + break;
  38241. + }
  38242. + return 0;
  38243. +
  38244. +}
  38245. +#endif
  38246. +
  38247. +#if defined(MV_INCLUDE_TS)
  38248. +/*******************************************************************************
  38249. +* mvCtrlTsSupport - Return if this controller has integrated TS flash support
  38250. +*
  38251. +* DESCRIPTION:
  38252. +*
  38253. +* INPUT:
  38254. +* None.
  38255. +*
  38256. +* OUTPUT:
  38257. +* None.
  38258. +*
  38259. +* RETURN:
  38260. +* MV_TRUE if TS is supported and MV_FALSE otherwise
  38261. +*
  38262. +*******************************************************************************/
  38263. +MV_U32 mvCtrlTsSupport(MV_VOID)
  38264. +{
  38265. + MV_U32 devId;
  38266. +
  38267. + devId = mvCtrlModelGet();
  38268. +
  38269. + switch(devId){
  38270. + case MV_6281_DEV_ID:
  38271. + return MV_6281_TS;
  38272. + break;
  38273. + case MV_6192_DEV_ID:
  38274. + return MV_6192_TS;
  38275. + break;
  38276. + case MV_6190_DEV_ID:
  38277. + return MV_6190_TS;
  38278. + break;
  38279. + case MV_6180_DEV_ID:
  38280. + return MV_6180_TS;
  38281. + break;
  38282. + }
  38283. + return 0;
  38284. +}
  38285. +#endif
  38286. +
  38287. +#if defined(MV_INCLUDE_AUDIO)
  38288. +/*******************************************************************************
  38289. +* mvCtrlAudioSupport - Return if this controller has integrated AUDIO flash support
  38290. +*
  38291. +* DESCRIPTION:
  38292. +*
  38293. +* INPUT:
  38294. +* None.
  38295. +*
  38296. +* OUTPUT:
  38297. +* None.
  38298. +*
  38299. +* RETURN:
  38300. +* MV_TRUE if AUDIO is supported and MV_FALSE otherwise
  38301. +*
  38302. +*******************************************************************************/
  38303. +MV_U32 mvCtrlAudioSupport(MV_VOID)
  38304. +{
  38305. + MV_U32 devId;
  38306. +
  38307. + devId = mvCtrlModelGet();
  38308. +
  38309. + switch(devId){
  38310. + case MV_6281_DEV_ID:
  38311. + return MV_6281_AUDIO;
  38312. + break;
  38313. + case MV_6192_DEV_ID:
  38314. + return MV_6192_AUDIO;
  38315. + break;
  38316. + case MV_6190_DEV_ID:
  38317. + return MV_6190_AUDIO;
  38318. + break;
  38319. + case MV_6180_DEV_ID:
  38320. + return MV_6180_AUDIO;
  38321. + break;
  38322. + }
  38323. + return 0;
  38324. +
  38325. +}
  38326. +#endif
  38327. +
  38328. +#if defined(MV_INCLUDE_TDM)
  38329. +/*******************************************************************************
  38330. +* mvCtrlTdmSupport - Return if this controller has integrated TDM flash support
  38331. +*
  38332. +* DESCRIPTION:
  38333. +*
  38334. +* INPUT:
  38335. +* None.
  38336. +*
  38337. +* OUTPUT:
  38338. +* None.
  38339. +*
  38340. +* RETURN:
  38341. +* MV_TRUE if TDM is supported and MV_FALSE otherwise
  38342. +*
  38343. +*******************************************************************************/
  38344. +MV_U32 mvCtrlTdmSupport(MV_VOID)
  38345. +{
  38346. + MV_U32 devId;
  38347. +
  38348. + devId = mvCtrlModelGet();
  38349. +
  38350. + switch(devId){
  38351. + case MV_6281_DEV_ID:
  38352. + return MV_6281_TDM;
  38353. + break;
  38354. + case MV_6192_DEV_ID:
  38355. + return MV_6192_TDM;
  38356. + break;
  38357. + case MV_6190_DEV_ID:
  38358. + return MV_6190_TDM;
  38359. + break;
  38360. + case MV_6180_DEV_ID:
  38361. + return MV_6180_TDM;
  38362. + break;
  38363. + }
  38364. + return 0;
  38365. +
  38366. +}
  38367. +#endif
  38368. +
  38369. +/*******************************************************************************
  38370. +* mvCtrlModelGet - Get Marvell controller device model (Id)
  38371. +*
  38372. +* DESCRIPTION:
  38373. +* This function returns 16bit describing the device model (ID) as defined
  38374. +* in PCI Device and Vendor ID configuration register offset 0x0.
  38375. +*
  38376. +* INPUT:
  38377. +* None.
  38378. +*
  38379. +* OUTPUT:
  38380. +* None.
  38381. +*
  38382. +* RETURN:
  38383. +* 16bit desscribing Marvell controller ID
  38384. +*
  38385. +*******************************************************************************/
  38386. +MV_U16 mvCtrlModelGet(MV_VOID)
  38387. +{
  38388. + MV_U32 devId;
  38389. +
  38390. + devId = MV_REG_READ(CHIP_BOND_REG);
  38391. + devId &= PCKG_OPT_MASK;
  38392. +
  38393. + switch(devId){
  38394. + case 2:
  38395. + return MV_6281_DEV_ID;
  38396. + break;
  38397. + case 1:
  38398. + if (((MV_REG_READ(PEX_CFG_DIRECT_ACCESS(0,PEX_DEVICE_AND_VENDOR_ID))& 0xffff0000) >> 16)
  38399. + == MV_6190_DEV_ID)
  38400. + return MV_6190_DEV_ID;
  38401. + else
  38402. + return MV_6192_DEV_ID;
  38403. + break;
  38404. + case 0:
  38405. + return MV_6180_DEV_ID;
  38406. + break;
  38407. + }
  38408. +
  38409. + return 0;
  38410. +}
  38411. +/*******************************************************************************
  38412. +* mvCtrlRevGet - Get Marvell controller device revision number
  38413. +*
  38414. +* DESCRIPTION:
  38415. +* This function returns 8bit describing the device revision as defined
  38416. +* in PCI Express Class Code and Revision ID Register.
  38417. +*
  38418. +* INPUT:
  38419. +* None.
  38420. +*
  38421. +* OUTPUT:
  38422. +* None.
  38423. +*
  38424. +* RETURN:
  38425. +* 8bit desscribing Marvell controller revision number
  38426. +*
  38427. +*******************************************************************************/
  38428. +MV_U8 mvCtrlRevGet(MV_VOID)
  38429. +{
  38430. + MV_U8 revNum;
  38431. +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
  38432. + /* Check pex power state */
  38433. + MV_U32 pexPower;
  38434. + pexPower = mvCtrlPwrClckGet(PEX_UNIT_ID,0);
  38435. + if (pexPower == MV_FALSE)
  38436. + mvCtrlPwrClckSet(PEX_UNIT_ID, 0, MV_TRUE);
  38437. +#endif
  38438. + revNum = (MV_U8)MV_REG_READ(PEX_CFG_DIRECT_ACCESS(0,PCI_CLASS_CODE_AND_REVISION_ID));
  38439. +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
  38440. + /* Return to power off state */
  38441. + if (pexPower == MV_FALSE)
  38442. + mvCtrlPwrClckSet(PEX_UNIT_ID, 0, MV_FALSE);
  38443. +#endif
  38444. + return ((revNum & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS);
  38445. +}
  38446. +
  38447. +/*******************************************************************************
  38448. +* mvCtrlNameGet - Get Marvell controller name
  38449. +*
  38450. +* DESCRIPTION:
  38451. +* This function returns a string describing the device model and revision.
  38452. +*
  38453. +* INPUT:
  38454. +* None.
  38455. +*
  38456. +* OUTPUT:
  38457. +* pNameBuff - Buffer to contain device name string. Minimum size 30 chars.
  38458. +*
  38459. +* RETURN:
  38460. +*
  38461. +* MV_ERROR if informantion can not be read.
  38462. +*******************************************************************************/
  38463. +MV_STATUS mvCtrlNameGet(char *pNameBuff)
  38464. +{
  38465. + mvOsSPrintf (pNameBuff, "%s%x Rev %d", SOC_NAME_PREFIX,
  38466. + mvCtrlModelGet(), mvCtrlRevGet());
  38467. +
  38468. + return MV_OK;
  38469. +}
  38470. +
  38471. +/*******************************************************************************
  38472. +* mvCtrlModelRevGet - Get Controller Model (Device ID) and Revision
  38473. +*
  38474. +* DESCRIPTION:
  38475. +* This function returns 32bit value describing both Device ID and Revision
  38476. +* as defined in PCI Express Device and Vendor ID Register and device revision
  38477. +* as defined in PCI Express Class Code and Revision ID Register.
  38478. +
  38479. +*
  38480. +* INPUT:
  38481. +* None.
  38482. +*
  38483. +* OUTPUT:
  38484. +* None.
  38485. +*
  38486. +* RETURN:
  38487. +* 32bit describing both controller device ID and revision number
  38488. +*
  38489. +*******************************************************************************/
  38490. +MV_U32 mvCtrlModelRevGet(MV_VOID)
  38491. +{
  38492. + return ((mvCtrlModelGet() << 16) | mvCtrlRevGet());
  38493. +}
  38494. +
  38495. +/*******************************************************************************
  38496. +* mvCtrlModelRevNameGet - Get Marvell controller name
  38497. +*
  38498. +* DESCRIPTION:
  38499. +* This function returns a string describing the device model and revision.
  38500. +*
  38501. +* INPUT:
  38502. +* None.
  38503. +*
  38504. +* OUTPUT:
  38505. +* pNameBuff - Buffer to contain device name string. Minimum size 30 chars.
  38506. +*
  38507. +* RETURN:
  38508. +*
  38509. +* MV_ERROR if informantion can not be read.
  38510. +*******************************************************************************/
  38511. +
  38512. +MV_STATUS mvCtrlModelRevNameGet(char *pNameBuff)
  38513. +{
  38514. +
  38515. + switch (mvCtrlModelRevGet())
  38516. + {
  38517. + case MV_6281_A0_ID:
  38518. + mvOsSPrintf (pNameBuff, "%s",MV_6281_A0_NAME);
  38519. + break;
  38520. + case MV_6192_A0_ID:
  38521. + mvOsSPrintf (pNameBuff, "%s",MV_6192_A0_NAME);
  38522. + break;
  38523. + case MV_6180_A0_ID:
  38524. + mvOsSPrintf (pNameBuff, "%s",MV_6180_A0_NAME);
  38525. + break;
  38526. + case MV_6190_A0_ID:
  38527. + mvOsSPrintf (pNameBuff, "%s",MV_6190_A0_NAME);
  38528. + break;
  38529. + case MV_6281_A1_ID:
  38530. + mvOsSPrintf (pNameBuff, "%s",MV_6281_A1_NAME);
  38531. + break;
  38532. + case MV_6192_A1_ID:
  38533. + mvOsSPrintf (pNameBuff, "%s",MV_6192_A1_NAME);
  38534. + break;
  38535. + case MV_6180_A1_ID:
  38536. + mvOsSPrintf (pNameBuff, "%s",MV_6180_A1_NAME);
  38537. + break;
  38538. + case MV_6190_A1_ID:
  38539. + mvOsSPrintf (pNameBuff, "%s",MV_6190_A1_NAME);
  38540. + break;
  38541. + default:
  38542. + mvCtrlNameGet(pNameBuff);
  38543. + break;
  38544. + }
  38545. +
  38546. + return MV_OK;
  38547. +}
  38548. +
  38549. +
  38550. +/*******************************************************************************
  38551. +* ctrlWinOverlapTest - Test address windows for overlaping.
  38552. +*
  38553. +* DESCRIPTION:
  38554. +* This function checks the given two address windows for overlaping.
  38555. +*
  38556. +* INPUT:
  38557. +* pAddrWin1 - Address window 1.
  38558. +* pAddrWin2 - Address window 2.
  38559. +*
  38560. +* OUTPUT:
  38561. +* None.
  38562. +*
  38563. +* RETURN:
  38564. +*
  38565. +* MV_TRUE if address window overlaps, MV_FALSE otherwise.
  38566. +*******************************************************************************/
  38567. +MV_STATUS ctrlWinOverlapTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2)
  38568. +{
  38569. + MV_U32 winBase1, winBase2;
  38570. + MV_U32 winTop1, winTop2;
  38571. +
  38572. + /* check if we have overflow than 4G*/
  38573. + if (((0xffffffff - pAddrWin1->baseLow) < pAddrWin1->size-1)||
  38574. + ((0xffffffff - pAddrWin2->baseLow) < pAddrWin2->size-1))
  38575. + {
  38576. + return MV_TRUE;
  38577. + }
  38578. +
  38579. + winBase1 = pAddrWin1->baseLow;
  38580. + winBase2 = pAddrWin2->baseLow;
  38581. + winTop1 = winBase1 + pAddrWin1->size-1;
  38582. + winTop2 = winBase2 + pAddrWin2->size-1;
  38583. +
  38584. +
  38585. + if (((winBase1 <= winTop2 ) && ( winTop2 <= winTop1)) ||
  38586. + ((winBase1 <= winBase2) && (winBase2 <= winTop1)))
  38587. + {
  38588. + return MV_TRUE;
  38589. + }
  38590. + else
  38591. + {
  38592. + return MV_FALSE;
  38593. + }
  38594. +}
  38595. +
  38596. +/*******************************************************************************
  38597. +* ctrlWinWithinWinTest - Test address windows for overlaping.
  38598. +*
  38599. +* DESCRIPTION:
  38600. +* This function checks the given win1 boundries is within
  38601. +* win2 boundries.
  38602. +*
  38603. +* INPUT:
  38604. +* pAddrWin1 - Address window 1.
  38605. +* pAddrWin2 - Address window 2.
  38606. +*
  38607. +* OUTPUT:
  38608. +* None.
  38609. +*
  38610. +* RETURN:
  38611. +*
  38612. +* MV_TRUE if found win1 inside win2, MV_FALSE otherwise.
  38613. +*******************************************************************************/
  38614. +MV_STATUS ctrlWinWithinWinTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2)
  38615. +{
  38616. + MV_U32 winBase1, winBase2;
  38617. + MV_U32 winTop1, winTop2;
  38618. +
  38619. + winBase1 = pAddrWin1->baseLow;
  38620. + winBase2 = pAddrWin2->baseLow;
  38621. + winTop1 = winBase1 + pAddrWin1->size -1;
  38622. + winTop2 = winBase2 + pAddrWin2->size -1;
  38623. +
  38624. + if (((winBase1 >= winBase2 ) && ( winBase1 <= winTop2)) ||
  38625. + ((winTop1 >= winBase2) && (winTop1 <= winTop2)))
  38626. + {
  38627. + return MV_TRUE;
  38628. + }
  38629. + else
  38630. + {
  38631. + return MV_FALSE;
  38632. + }
  38633. +}
  38634. +
  38635. +static const char* cntrlName[] = TARGETS_NAME_ARRAY;
  38636. +
  38637. +/*******************************************************************************
  38638. +* mvCtrlTargetNameGet - Get Marvell controller target name
  38639. +*
  38640. +* DESCRIPTION:
  38641. +* This function convert the trget enumeration to string.
  38642. +*
  38643. +* INPUT:
  38644. +* None.
  38645. +*
  38646. +* OUTPUT:
  38647. +* None.
  38648. +*
  38649. +* RETURN:
  38650. +* Target name (const MV_8 *)
  38651. +*******************************************************************************/
  38652. +const MV_8* mvCtrlTargetNameGet( MV_TARGET target )
  38653. +{
  38654. +
  38655. + if (target >= MAX_TARGETS)
  38656. + {
  38657. + return "target unknown";
  38658. + }
  38659. +
  38660. + return cntrlName[target];
  38661. +}
  38662. +
  38663. +/*******************************************************************************
  38664. +* mvCtrlAddrDecShow - Print the Controller units address decode map.
  38665. +*
  38666. +* DESCRIPTION:
  38667. +* This function the Controller units address decode map.
  38668. +*
  38669. +* INPUT:
  38670. +* None.
  38671. +*
  38672. +* OUTPUT:
  38673. +* None.
  38674. +*
  38675. +* RETURN:
  38676. +* None.
  38677. +*
  38678. +*******************************************************************************/
  38679. +MV_VOID mvCtrlAddrDecShow(MV_VOID)
  38680. +{
  38681. + mvCpuIfAddDecShow();
  38682. + mvAhbToMbusAddDecShow();
  38683. +#if defined(MV_INCLUDE_PEX)
  38684. + mvPexAddrDecShow();
  38685. +#endif
  38686. +#if defined(MV_INCLUDE_USB)
  38687. + mvUsbAddrDecShow();
  38688. +#endif
  38689. +#if defined(MV_INCLUDE_GIG_ETH)
  38690. + mvEthAddrDecShow();
  38691. +#endif
  38692. +#if defined(MV_INCLUDE_XOR)
  38693. + mvXorAddrDecShow();
  38694. +#endif
  38695. +#if defined(MV_INCLUDE_SATA)
  38696. + mvSataAddrDecShow();
  38697. +#endif
  38698. +#if defined(MV_INCLUDE_AUDIO)
  38699. + mvAudioAddrDecShow();
  38700. +#endif
  38701. +#if defined(MV_INCLUDE_TS)
  38702. + mvTsuAddrDecShow();
  38703. +#endif
  38704. +}
  38705. +
  38706. +/*******************************************************************************
  38707. +* ctrlSizeToReg - Extract size value for register assignment.
  38708. +*
  38709. +* DESCRIPTION:
  38710. +* Address decode size parameter must be programed from LSB to MSB as
  38711. +* sequence of 1's followed by sequence of 0's. The number of 1's
  38712. +* specifies the size of the window in 64 KB granularity (e.g. a
  38713. +* value of 0x00ff specifies 256x64k = 16 MB).
  38714. +* This function extract the size value from the size parameter according
  38715. +* to given aligment paramter. For example for size 0x1000000 (16MB) and
  38716. +* aligment 0x10000 (64KB) the function will return 0x00FF.
  38717. +*
  38718. +* INPUT:
  38719. +* size - Size.
  38720. +* alignment - Size alignment. Note that alignment must be power of 2!
  38721. +*
  38722. +* OUTPUT:
  38723. +* None.
  38724. +*
  38725. +* RETURN:
  38726. +* 32bit describing size register value correspond to size parameter.
  38727. +* If value is '-1' size parameter or aligment are invalid.
  38728. +*******************************************************************************/
  38729. +MV_U32 ctrlSizeToReg(MV_U32 size, MV_U32 alignment)
  38730. +{
  38731. + MV_U32 retVal;
  38732. +
  38733. + /* Check size parameter alignment */
  38734. + if ((0 == size) || (MV_IS_NOT_ALIGN(size, alignment)))
  38735. + {
  38736. + DB(mvOsPrintf("ctrlSizeToReg: ERR. Size is zero or not aligned.\n"));
  38737. + return -1;
  38738. + }
  38739. +
  38740. + /* Take out the "alignment" portion out of the size parameter */
  38741. + alignment--; /* Now the alignmet is a sequance of '1' (e.g. 0xffff) */
  38742. + /* and size is 0x1000000 (16MB) for example */
  38743. + while(alignment & 1) /* Check that alignmet LSB is set */
  38744. + {
  38745. + size = (size >> 1); /* If LSB is set, move 'size' one bit to right */
  38746. + alignment = (alignment >> 1);
  38747. + }
  38748. +
  38749. + /* If after the alignment first '0' was met we still have '1' in */
  38750. + /* it then aligment is invalid (not power of 2) */
  38751. + if (alignment)
  38752. + {
  38753. + DB(mvOsPrintf("ctrlSizeToReg: ERR. Alignment parameter 0x%x invalid.\n",
  38754. + (MV_U32)alignment));
  38755. + return -1;
  38756. + }
  38757. +
  38758. + /* Now the size is shifted right according to aligment: 0x0100 */
  38759. + size--; /* Now the size is a sequance of '1': 0x00ff */
  38760. +
  38761. + retVal = size ;
  38762. +
  38763. + /* Check that LSB to MSB is sequence of 1's followed by sequence of 0's */
  38764. + while(size & 1) /* Check that LSB is set */
  38765. + {
  38766. + size = (size >> 1); /* If LSB is set, move one bit to the right */
  38767. + }
  38768. +
  38769. + if (size) /* Sequance of 1's is over. Check that we have no other 1's */
  38770. + {
  38771. + DB(mvOsPrintf("ctrlSizeToReg: ERR. Size parameter 0x%x invalid.\n",
  38772. + size));
  38773. + return -1;
  38774. + }
  38775. +
  38776. + return retVal;
  38777. +
  38778. +}
  38779. +
  38780. +/*******************************************************************************
  38781. +* ctrlRegToSize - Extract size value from register value.
  38782. +*
  38783. +* DESCRIPTION:
  38784. +* This function extract a size value from the register size parameter
  38785. +* according to given aligment paramter. For example for register size
  38786. +* value 0xff and aligment 0x10000 the function will return 0x01000000.
  38787. +*
  38788. +* INPUT:
  38789. +* regSize - Size as in register format. See ctrlSizeToReg.
  38790. +* alignment - Size alignment. Note that alignment must be power of 2!
  38791. +*
  38792. +* OUTPUT:
  38793. +* None.
  38794. +*
  38795. +* RETURN:
  38796. +* 32bit describing size.
  38797. +* If value is '-1' size parameter or aligment are invalid.
  38798. +*******************************************************************************/
  38799. +MV_U32 ctrlRegToSize(MV_U32 regSize, MV_U32 alignment)
  38800. +{
  38801. + MV_U32 temp;
  38802. +
  38803. + /* Check that LSB to MSB is sequence of 1's followed by sequence of 0's */
  38804. + temp = regSize; /* Now the size is a sequance of '1': 0x00ff */
  38805. +
  38806. + while(temp & 1) /* Check that LSB is set */
  38807. + {
  38808. + temp = (temp >> 1); /* If LSB is set, move one bit to the right */
  38809. + }
  38810. +
  38811. + if (temp) /* Sequance of 1's is over. Check that we have no other 1's */
  38812. + {
  38813. + DB(mvOsPrintf("ctrlRegToSize: ERR. Size parameter 0x%x invalid.\n",
  38814. + regSize));
  38815. + return -1;
  38816. + }
  38817. +
  38818. +
  38819. + /* Check that aligment is a power of two */
  38820. + temp = alignment - 1;/* Now the alignmet is a sequance of '1' (0xffff) */
  38821. +
  38822. + while(temp & 1) /* Check that alignmet LSB is set */
  38823. + {
  38824. + temp = (temp >> 1); /* If LSB is set, move 'size' one bit to right */
  38825. + }
  38826. +
  38827. + /* If after the 'temp' first '0' was met we still have '1' in 'temp' */
  38828. + /* then 'temp' is invalid (not power of 2) */
  38829. + if (temp)
  38830. + {
  38831. + DB(mvOsPrintf("ctrlSizeToReg: ERR. Alignment parameter 0x%x invalid.\n",
  38832. + alignment));
  38833. + return -1;
  38834. + }
  38835. +
  38836. + regSize++; /* Now the size is 0x0100 */
  38837. +
  38838. + /* Add in the "alignment" portion to the register size parameter */
  38839. + alignment--; /* Now the alignmet is a sequance of '1' (e.g. 0xffff) */
  38840. +
  38841. + while(alignment & 1) /* Check that alignmet LSB is set */
  38842. + {
  38843. + regSize = (regSize << 1); /* LSB is set, move 'size' one bit left */
  38844. + alignment = (alignment >> 1);
  38845. + }
  38846. +
  38847. + return regSize;
  38848. +}
  38849. +
  38850. +
  38851. +/*******************************************************************************
  38852. +* ctrlSizeRegRoundUp - Round up given size
  38853. +*
  38854. +* DESCRIPTION:
  38855. +* This function round up a given size to a size that fits the
  38856. +* restrictions of size format given an aligment parameter.
  38857. +* to given aligment paramter. For example for size parameter 0xa1000 and
  38858. +* aligment 0x1000 the function will return 0xFF000.
  38859. +*
  38860. +* INPUT:
  38861. +* size - Size.
  38862. +* alignment - Size alignment. Note that alignment must be power of 2!
  38863. +*
  38864. +* OUTPUT:
  38865. +* None.
  38866. +*
  38867. +* RETURN:
  38868. +* 32bit describing size value correspond to size in register.
  38869. +*******************************************************************************/
  38870. +MV_U32 ctrlSizeRegRoundUp(MV_U32 size, MV_U32 alignment)
  38871. +{
  38872. + MV_U32 msbBit = 0;
  38873. + MV_U32 retSize;
  38874. +
  38875. + /* Check if size parameter is already comply with restriction */
  38876. + if (!(-1 == ctrlSizeToReg(size, alignment)))
  38877. + {
  38878. + return size;
  38879. + }
  38880. +
  38881. + while(size)
  38882. + {
  38883. + size = (size >> 1);
  38884. + msbBit++;
  38885. + }
  38886. +
  38887. + retSize = (1 << msbBit);
  38888. +
  38889. + if (retSize < alignment)
  38890. + {
  38891. + return alignment;
  38892. + }
  38893. + else
  38894. + {
  38895. + return retSize;
  38896. + }
  38897. +}
  38898. +/*******************************************************************************
  38899. +* mvCtrlSysRstLengthCounterGet - Return number of milliseconds the reset button
  38900. +* was pressed and clear counter
  38901. +*
  38902. +* DESCRIPTION:
  38903. +*
  38904. +* INPUT:
  38905. +*
  38906. +* OUTPUT:
  38907. +*
  38908. +* RETURN: number of milliseconds the reset button was pressed
  38909. +*******************************************************************************/
  38910. +MV_U32 mvCtrlSysRstLengthCounterGet(MV_VOID)
  38911. +{
  38912. + static volatile MV_U32 Count = 0;
  38913. +
  38914. + if(!Count) {
  38915. + Count = (MV_REG_READ(SYSRST_LENGTH_COUNTER_REG) & SLCR_COUNT_MASK);
  38916. + Count = (Count / (MV_BOARD_REFCLK_25MHZ / 1000));
  38917. + /* clear counter for next boot */
  38918. + MV_REG_BIT_SET(SYSRST_LENGTH_COUNTER_REG, SLCR_CLR_MASK);
  38919. + }
  38920. +
  38921. + DB(mvOsPrintf("mvCtrlSysRstLengthCounterGet: Reset button was pressed for %u milliseconds\n", Count));
  38922. +
  38923. + return Count;
  38924. +}
  38925. +
  38926. +MV_BOOL mvCtrlIsBootFromSPI(MV_VOID)
  38927. +{
  38928. + MV_U32 satr = 0;
  38929. + satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  38930. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  38931. + {
  38932. + if (MSAR_BOOT_MODE_6180(satr) == MSAR_BOOT_SPI_WITH_BOOTROM_6180)
  38933. + return MV_TRUE;
  38934. + else
  38935. + return MV_FALSE;
  38936. + }
  38937. + satr = satr & MSAR_BOOT_MODE_MASK;
  38938. + if (satr == MSAR_BOOT_SPI_WITH_BOOTROM)
  38939. + return MV_TRUE;
  38940. + else
  38941. + return MV_FALSE;
  38942. +}
  38943. +
  38944. +MV_BOOL mvCtrlIsBootFromSPIUseNAND(MV_VOID)
  38945. +{
  38946. + MV_U32 satr = 0;
  38947. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  38948. + return MV_FALSE;
  38949. + satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  38950. + satr = satr & MSAR_BOOT_MODE_MASK;
  38951. +
  38952. + if (satr == MSAR_BOOT_SPI_USE_NAND_WITH_BOOTROM)
  38953. + return MV_TRUE;
  38954. + else
  38955. + return MV_FALSE;
  38956. +}
  38957. +
  38958. +MV_BOOL mvCtrlIsBootFromNAND(MV_VOID)
  38959. +{
  38960. + MV_U32 satr = 0;
  38961. + satr = MV_REG_READ(MPP_SAMPLE_AT_RESET);
  38962. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  38963. + {
  38964. + if (MSAR_BOOT_MODE_6180(satr) == MSAR_BOOT_NAND_WITH_BOOTROM_6180)
  38965. + return MV_TRUE;
  38966. + else
  38967. + return MV_FALSE;
  38968. + }
  38969. + satr = satr & MSAR_BOOT_MODE_MASK;
  38970. + if ((satr == MSAR_BOOT_NAND_WITH_BOOTROM))
  38971. + return MV_TRUE;
  38972. + else
  38973. + return MV_FALSE;
  38974. +}
  38975. +
  38976. +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
  38977. +/*******************************************************************************
  38978. +* mvCtrlPwrSaveOn - Set Power save mode
  38979. +*
  38980. +* DESCRIPTION:
  38981. +*
  38982. +* INPUT:
  38983. +*
  38984. +* OUTPUT:
  38985. +*
  38986. +* RETURN:
  38987. +*******************************************************************************/
  38988. +MV_VOID mvCtrlPwrSaveOn(MV_VOID)
  38989. +{
  38990. + unsigned long old,temp;
  38991. + /* Disable int */
  38992. + __asm__ __volatile__("mrs %0, cpsr\n"
  38993. + "orr %1, %0, #0xc0\n"
  38994. + "msr cpsr_c, %1"
  38995. + : "=r" (old), "=r" (temp)
  38996. + :
  38997. + : "memory");
  38998. +
  38999. + /* Set SoC in power save */
  39000. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, BIT11);
  39001. + /* Wait for int */
  39002. + __asm__ __volatile__("mcr p15, 0, r0, c7, c0, 4");
  39003. +
  39004. + /* Enabled int */
  39005. + __asm__ __volatile__("msr cpsr_c, %0"
  39006. + :
  39007. + : "r" (old)
  39008. + : "memory");
  39009. +}
  39010. +
  39011. +
  39012. +
  39013. +/*******************************************************************************
  39014. +* mvCtrlPwrSaveOff - Go out of power save mode
  39015. +*
  39016. +* DESCRIPTION:
  39017. +*
  39018. +* INPUT:
  39019. +*
  39020. +* OUTPUT:
  39021. +*
  39022. +* RETURN:
  39023. +*******************************************************************************/
  39024. +MV_VOID mvCtrlPwrSaveOff(MV_VOID)
  39025. +{
  39026. + unsigned long old,temp;
  39027. + /* Disable int */
  39028. + __asm__ __volatile__("mrs %0, cpsr\n"
  39029. + "orr %1, %0, #0xc0\n"
  39030. + "msr cpsr_c, %1"
  39031. + : "=r" (old), "=r" (temp)
  39032. + :
  39033. + : "memory");
  39034. +
  39035. + /* Set SoC in power save */
  39036. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, BIT11);
  39037. + /* Wait for int */
  39038. + __asm__ __volatile__("mcr p15, 0, r0, c7, c0, 4");
  39039. +
  39040. + /* Enabled int */
  39041. + __asm__ __volatile__("msr cpsr_c, %0"
  39042. + :
  39043. + : "r" (old)
  39044. + : "memory");
  39045. +}
  39046. +
  39047. +/*******************************************************************************
  39048. +* mvCtrlPwrClckSet - Set Power State for specific Unit
  39049. +*
  39050. +* DESCRIPTION:
  39051. +*
  39052. +* INPUT:
  39053. +*
  39054. +* OUTPUT:
  39055. +*
  39056. +* RETURN:
  39057. +*******************************************************************************/
  39058. +MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable)
  39059. +{
  39060. + switch (unitId)
  39061. + {
  39062. +#if defined(MV_INCLUDE_PEX)
  39063. + case PEX_UNIT_ID:
  39064. + if (enable == MV_FALSE)
  39065. + {
  39066. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_PEXSTOPCLOCK_MASK);
  39067. + }
  39068. + else
  39069. + {
  39070. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_PEXSTOPCLOCK_MASK);
  39071. + }
  39072. + break;
  39073. +#endif
  39074. +#if defined(MV_INCLUDE_GIG_ETH)
  39075. + case ETH_GIG_UNIT_ID:
  39076. + if (enable == MV_FALSE)
  39077. + {
  39078. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_GESTOPCLOCK_MASK(index));
  39079. + }
  39080. + else
  39081. + {
  39082. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_GESTOPCLOCK_MASK(index));
  39083. + }
  39084. + break;
  39085. +#endif
  39086. +#if defined(MV_INCLUDE_INTEG_SATA)
  39087. + case SATA_UNIT_ID:
  39088. + if (enable == MV_FALSE)
  39089. + {
  39090. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SATASTOPCLOCK_MASK(index));
  39091. + }
  39092. + else
  39093. + {
  39094. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SATASTOPCLOCK_MASK(index));
  39095. + }
  39096. + break;
  39097. +#endif
  39098. +#if defined(MV_INCLUDE_CESA)
  39099. + case CESA_UNIT_ID:
  39100. + if (enable == MV_FALSE)
  39101. + {
  39102. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SESTOPCLOCK_MASK);
  39103. + }
  39104. + else
  39105. + {
  39106. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SESTOPCLOCK_MASK);
  39107. + }
  39108. + break;
  39109. +#endif
  39110. +#if defined(MV_INCLUDE_USB)
  39111. + case USB_UNIT_ID:
  39112. + if (enable == MV_FALSE)
  39113. + {
  39114. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_USBSTOPCLOCK_MASK);
  39115. + }
  39116. + else
  39117. + {
  39118. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_USBSTOPCLOCK_MASK);
  39119. + }
  39120. + break;
  39121. +#endif
  39122. +#if defined(MV_INCLUDE_AUDIO)
  39123. + case AUDIO_UNIT_ID:
  39124. + if (enable == MV_FALSE)
  39125. + {
  39126. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_AUDIOSTOPCLOCK_MASK);
  39127. + }
  39128. + else
  39129. + {
  39130. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_AUDIOSTOPCLOCK_MASK);
  39131. + }
  39132. + break;
  39133. +#endif
  39134. +#if defined(MV_INCLUDE_TS)
  39135. + case TS_UNIT_ID:
  39136. + if (enable == MV_FALSE)
  39137. + {
  39138. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_TSSTOPCLOCK_MASK);
  39139. + }
  39140. + else
  39141. + {
  39142. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_TSSTOPCLOCK_MASK);
  39143. + }
  39144. + break;
  39145. +#endif
  39146. +#if defined(MV_INCLUDE_SDIO)
  39147. + case SDIO_UNIT_ID:
  39148. + if (enable == MV_FALSE)
  39149. + {
  39150. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_SDIOSTOPCLOCK_MASK);
  39151. + }
  39152. + else
  39153. + {
  39154. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_SDIOSTOPCLOCK_MASK);
  39155. + }
  39156. + break;
  39157. +#endif
  39158. +#if defined(MV_INCLUDE_TDM)
  39159. + case TDM_UNIT_ID:
  39160. + if (enable == MV_FALSE)
  39161. + {
  39162. + MV_REG_BIT_RESET(POWER_MNG_CTRL_REG, PMC_TDMSTOPCLOCK_MASK);
  39163. + }
  39164. + else
  39165. + {
  39166. + MV_REG_BIT_SET(POWER_MNG_CTRL_REG, PMC_TDMSTOPCLOCK_MASK);
  39167. + }
  39168. + break;
  39169. +#endif
  39170. +
  39171. + default:
  39172. +
  39173. + break;
  39174. +
  39175. + }
  39176. +}
  39177. +
  39178. +/*******************************************************************************
  39179. +* mvCtrlPwrClckGet - Get Power State of specific Unit
  39180. +*
  39181. +* DESCRIPTION:
  39182. +*
  39183. +* INPUT:
  39184. +*
  39185. +* OUTPUT:
  39186. +*
  39187. +* RETURN:
  39188. +******************************************************************************/
  39189. +MV_BOOL mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index)
  39190. +{
  39191. + MV_U32 reg = MV_REG_READ(POWER_MNG_CTRL_REG);
  39192. + MV_BOOL state = MV_TRUE;
  39193. +
  39194. + switch (unitId)
  39195. + {
  39196. +#if defined(MV_INCLUDE_PEX)
  39197. + case PEX_UNIT_ID:
  39198. + if ((reg & PMC_PEXSTOPCLOCK_MASK) == PMC_PEXSTOPCLOCK_STOP)
  39199. + {
  39200. + state = MV_FALSE;
  39201. + }
  39202. + else state = MV_TRUE;
  39203. +
  39204. + break;
  39205. +#endif
  39206. +#if defined(MV_INCLUDE_GIG_ETH)
  39207. + case ETH_GIG_UNIT_ID:
  39208. + if ((reg & PMC_GESTOPCLOCK_MASK(index)) == PMC_GESTOPCLOCK_STOP(index))
  39209. + {
  39210. + state = MV_FALSE;
  39211. + }
  39212. + else state = MV_TRUE;
  39213. + break;
  39214. +#endif
  39215. +#if defined(MV_INCLUDE_SATA)
  39216. + case SATA_UNIT_ID:
  39217. + if ((reg & PMC_SATASTOPCLOCK_MASK(index)) == PMC_SATASTOPCLOCK_STOP(index))
  39218. + {
  39219. + state = MV_FALSE;
  39220. + }
  39221. + else state = MV_TRUE;
  39222. + break;
  39223. +#endif
  39224. +#if defined(MV_INCLUDE_CESA)
  39225. + case CESA_UNIT_ID:
  39226. + if ((reg & PMC_SESTOPCLOCK_MASK) == PMC_SESTOPCLOCK_STOP)
  39227. + {
  39228. + state = MV_FALSE;
  39229. + }
  39230. + else state = MV_TRUE;
  39231. + break;
  39232. +#endif
  39233. +#if defined(MV_INCLUDE_USB)
  39234. + case USB_UNIT_ID:
  39235. + if ((reg & PMC_USBSTOPCLOCK_MASK) == PMC_USBSTOPCLOCK_STOP)
  39236. + {
  39237. + state = MV_FALSE;
  39238. + }
  39239. + else state = MV_TRUE;
  39240. + break;
  39241. +#endif
  39242. +#if defined(MV_INCLUDE_AUDIO)
  39243. + case AUDIO_UNIT_ID:
  39244. + if ((reg & PMC_AUDIOSTOPCLOCK_MASK) == PMC_AUDIOSTOPCLOCK_STOP)
  39245. + {
  39246. + state = MV_FALSE;
  39247. + }
  39248. + else state = MV_TRUE;
  39249. + break;
  39250. +#endif
  39251. +#if defined(MV_INCLUDE_TS)
  39252. + case TS_UNIT_ID:
  39253. + if ((reg & PMC_TSSTOPCLOCK_MASK) == PMC_TSSTOPCLOCK_STOP)
  39254. + {
  39255. + state = MV_FALSE;
  39256. + }
  39257. + else state = MV_TRUE;
  39258. + break;
  39259. +#endif
  39260. +#if defined(MV_INCLUDE_SDIO)
  39261. + case SDIO_UNIT_ID:
  39262. + if ((reg & PMC_SDIOSTOPCLOCK_MASK)== PMC_SDIOSTOPCLOCK_STOP)
  39263. + {
  39264. + state = MV_FALSE;
  39265. + }
  39266. + else state = MV_TRUE;
  39267. + break;
  39268. +#endif
  39269. +#if defined(MV_INCLUDE_TDM)
  39270. + case TDM_UNIT_ID:
  39271. + if ((reg & PMC_TDMSTOPCLOCK_MASK) == PMC_TDMSTOPCLOCK_STOP)
  39272. + {
  39273. + state = MV_FALSE;
  39274. + }
  39275. + else state = MV_TRUE;
  39276. + break;
  39277. +#endif
  39278. +
  39279. + default:
  39280. + state = MV_TRUE;
  39281. + break;
  39282. + }
  39283. +
  39284. +
  39285. + return state;
  39286. +}
  39287. +/*******************************************************************************
  39288. +* mvCtrlPwrMemSet - Set Power State for memory on specific Unit
  39289. +*
  39290. +* DESCRIPTION:
  39291. +*
  39292. +* INPUT:
  39293. +*
  39294. +* OUTPUT:
  39295. +*
  39296. +* RETURN:
  39297. +*******************************************************************************/
  39298. +MV_VOID mvCtrlPwrMemSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable)
  39299. +{
  39300. + switch (unitId)
  39301. + {
  39302. +#if defined(MV_INCLUDE_PEX)
  39303. + case PEX_UNIT_ID:
  39304. + if (enable == MV_FALSE)
  39305. + {
  39306. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_PEXSTOPMEM_MASK);
  39307. + }
  39308. + else
  39309. + {
  39310. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_PEXSTOPMEM_MASK);
  39311. + }
  39312. + break;
  39313. +#endif
  39314. +#if defined(MV_INCLUDE_GIG_ETH)
  39315. + case ETH_GIG_UNIT_ID:
  39316. + if (enable == MV_FALSE)
  39317. + {
  39318. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_GESTOPMEM_MASK(index));
  39319. + }
  39320. + else
  39321. + {
  39322. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_GESTOPMEM_MASK(index));
  39323. + }
  39324. + break;
  39325. +#endif
  39326. +#if defined(MV_INCLUDE_INTEG_SATA)
  39327. + case SATA_UNIT_ID:
  39328. + if (enable == MV_FALSE)
  39329. + {
  39330. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_SATASTOPMEM_MASK(index));
  39331. + }
  39332. + else
  39333. + {
  39334. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_SATASTOPMEM_MASK(index));
  39335. + }
  39336. + break;
  39337. +#endif
  39338. +#if defined(MV_INCLUDE_CESA)
  39339. + case CESA_UNIT_ID:
  39340. + if (enable == MV_FALSE)
  39341. + {
  39342. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_SESTOPMEM_MASK);
  39343. + }
  39344. + else
  39345. + {
  39346. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_SESTOPMEM_MASK);
  39347. + }
  39348. + break;
  39349. +#endif
  39350. +#if defined(MV_INCLUDE_USB)
  39351. + case USB_UNIT_ID:
  39352. + if (enable == MV_FALSE)
  39353. + {
  39354. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_USBSTOPMEM_MASK);
  39355. + }
  39356. + else
  39357. + {
  39358. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_USBSTOPMEM_MASK);
  39359. + }
  39360. + break;
  39361. +#endif
  39362. +#if defined(MV_INCLUDE_AUDIO)
  39363. + case AUDIO_UNIT_ID:
  39364. + if (enable == MV_FALSE)
  39365. + {
  39366. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_AUDIOSTOPMEM_MASK);
  39367. + }
  39368. + else
  39369. + {
  39370. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_AUDIOSTOPMEM_MASK);
  39371. + }
  39372. + break;
  39373. +#endif
  39374. +#if defined(MV_INCLUDE_XOR)
  39375. + case XOR_UNIT_ID:
  39376. + if (enable == MV_FALSE)
  39377. + {
  39378. + MV_REG_BIT_SET(POWER_MNG_MEM_CTRL_REG, PMC_XORSTOPMEM_MASK(index));
  39379. + }
  39380. + else
  39381. + {
  39382. + MV_REG_BIT_RESET(POWER_MNG_MEM_CTRL_REG, PMC_XORSTOPMEM_MASK(index));
  39383. + }
  39384. + break;
  39385. +#endif
  39386. + default:
  39387. +
  39388. + break;
  39389. +
  39390. + }
  39391. +}
  39392. +
  39393. +/*******************************************************************************
  39394. +* mvCtrlPwrMemGet - Get Power State of memory on specific Unit
  39395. +*
  39396. +* DESCRIPTION:
  39397. +*
  39398. +* INPUT:
  39399. +*
  39400. +* OUTPUT:
  39401. +*
  39402. +* RETURN:
  39403. +******************************************************************************/
  39404. +MV_BOOL mvCtrlPwrMemGet(MV_UNIT_ID unitId, MV_U32 index)
  39405. +{
  39406. + MV_U32 reg = MV_REG_READ(POWER_MNG_MEM_CTRL_REG);
  39407. + MV_BOOL state = MV_TRUE;
  39408. +
  39409. + switch (unitId)
  39410. + {
  39411. +#if defined(MV_INCLUDE_PEX)
  39412. + case PEX_UNIT_ID:
  39413. + if ((reg & PMC_PEXSTOPMEM_MASK) == PMC_PEXSTOPMEM_STOP)
  39414. + {
  39415. + state = MV_FALSE;
  39416. + }
  39417. + else state = MV_TRUE;
  39418. +
  39419. + break;
  39420. +#endif
  39421. +#if defined(MV_INCLUDE_GIG_ETH)
  39422. + case ETH_GIG_UNIT_ID:
  39423. + if ((reg & PMC_GESTOPMEM_MASK(index)) == PMC_GESTOPMEM_STOP(index))
  39424. + {
  39425. + state = MV_FALSE;
  39426. + }
  39427. + else state = MV_TRUE;
  39428. + break;
  39429. +#endif
  39430. +#if defined(MV_INCLUDE_SATA)
  39431. + case SATA_UNIT_ID:
  39432. + if ((reg & PMC_SATASTOPMEM_MASK(index)) == PMC_SATASTOPMEM_STOP(index))
  39433. + {
  39434. + state = MV_FALSE;
  39435. + }
  39436. + else state = MV_TRUE;
  39437. + break;
  39438. +#endif
  39439. +#if defined(MV_INCLUDE_CESA)
  39440. + case CESA_UNIT_ID:
  39441. + if ((reg & PMC_SESTOPMEM_MASK) == PMC_SESTOPMEM_STOP)
  39442. + {
  39443. + state = MV_FALSE;
  39444. + }
  39445. + else state = MV_TRUE;
  39446. + break;
  39447. +#endif
  39448. +#if defined(MV_INCLUDE_USB)
  39449. + case USB_UNIT_ID:
  39450. + if ((reg & PMC_USBSTOPMEM_MASK) == PMC_USBSTOPMEM_STOP)
  39451. + {
  39452. + state = MV_FALSE;
  39453. + }
  39454. + else state = MV_TRUE;
  39455. + break;
  39456. +#endif
  39457. +#if defined(MV_INCLUDE_AUDIO)
  39458. + case AUDIO_UNIT_ID:
  39459. + if ((reg & PMC_AUDIOSTOPMEM_MASK) == PMC_AUDIOSTOPMEM_STOP)
  39460. + {
  39461. + state = MV_FALSE;
  39462. + }
  39463. + else state = MV_TRUE;
  39464. + break;
  39465. +#endif
  39466. +#if defined(MV_INCLUDE_XOR)
  39467. + case XOR_UNIT_ID:
  39468. + if ((reg & PMC_XORSTOPMEM_MASK(index)) == PMC_XORSTOPMEM_STOP(index))
  39469. + {
  39470. + state = MV_FALSE;
  39471. + }
  39472. + else state = MV_TRUE;
  39473. + break;
  39474. +#endif
  39475. +
  39476. + default:
  39477. + state = MV_TRUE;
  39478. + break;
  39479. + }
  39480. +
  39481. +
  39482. + return state;
  39483. +}
  39484. +#else
  39485. +MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable) {return;}
  39486. +MV_BOOL mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index) {return MV_TRUE;}
  39487. +#endif /* #if defined(MV_INCLUDE_CLK_PWR_CNTRL) */
  39488. +
  39489. +
  39490. +/*******************************************************************************
  39491. +* mvMPPConfigToSPI - Change MPP[3:0] configuration to SPI mode
  39492. +*
  39493. +* DESCRIPTION:
  39494. +*
  39495. +* INPUT:
  39496. +*
  39497. +* OUTPUT:
  39498. +*
  39499. +* RETURN:
  39500. +******************************************************************************/
  39501. +MV_VOID mvMPPConfigToSPI(MV_VOID)
  39502. +{
  39503. + MV_U32 mppVal = 0;
  39504. + MV_U32 bootVal = 0;
  39505. +
  39506. + if(!mvCtrlIsBootFromSPIUseNAND())
  39507. + return;
  39508. + mppVal = 0x00002220; /* Set MPP [3:1] to SPI mode */
  39509. + bootVal = MV_REG_READ(mvCtrlMppRegGet(0));
  39510. + bootVal &= 0xffff000f;
  39511. + mppVal |= bootVal;
  39512. +
  39513. + MV_REG_WRITE(mvCtrlMppRegGet(0), mppVal);
  39514. +}
  39515. +
  39516. +
  39517. +/*******************************************************************************
  39518. +* mvMPPConfigToDefault - Change MPP[7:0] configuration to default configuration
  39519. +*
  39520. +* DESCRIPTION:
  39521. +*
  39522. +* INPUT:
  39523. +*
  39524. +* OUTPUT:
  39525. +*
  39526. +* RETURN:
  39527. +******************************************************************************/
  39528. +MV_VOID mvMPPConfigToDefault(MV_VOID)
  39529. +{
  39530. + MV_U32 mppVal = 0;
  39531. + MV_U32 bootVal = 0;
  39532. +
  39533. + if(!mvCtrlIsBootFromSPIUseNAND())
  39534. + return;
  39535. + mppVal = mvBoardMppGet(0);
  39536. + bootVal = MV_REG_READ(mvCtrlMppRegGet(0));
  39537. + mppVal &= ~0xffff000f;
  39538. + bootVal &= 0xffff000f;
  39539. + mppVal |= bootVal;
  39540. +
  39541. + MV_REG_WRITE(mvCtrlMppRegGet(0), mppVal);
  39542. +}
  39543. +
  39544. +
  39545. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h
  39546. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h 1970-01-01 01:00:00.000000000 +0100
  39547. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvLib.h 2011-08-01 14:38:19.000000000 +0200
  39548. @@ -0,0 +1,185 @@
  39549. +/*******************************************************************************
  39550. +Copyright (C) Marvell International Ltd. and its affiliates
  39551. +
  39552. +This software file (the "File") is owned and distributed by Marvell
  39553. +International Ltd. and/or its affiliates ("Marvell") under the following
  39554. +alternative licensing terms. Once you have made an election to distribute the
  39555. +File under one of the following license alternatives, please (i) delete this
  39556. +introductory statement regarding license alternatives, (ii) delete the two
  39557. +license alternatives that you have not elected to use and (iii) preserve the
  39558. +Marvell copyright notice above.
  39559. +
  39560. +********************************************************************************
  39561. +Marvell Commercial License Option
  39562. +
  39563. +If you received this File from Marvell and you have entered into a commercial
  39564. +license agreement (a "Commercial License") with Marvell, the File is licensed
  39565. +to you under the terms of the applicable Commercial License.
  39566. +
  39567. +********************************************************************************
  39568. +Marvell GPL License Option
  39569. +
  39570. +If you received this File from Marvell, you may opt to use, redistribute and/or
  39571. +modify this File in accordance with the terms and conditions of the General
  39572. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  39573. +available along with the File in the license.txt file or by writing to the Free
  39574. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  39575. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  39576. +
  39577. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  39578. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  39579. +DISCLAIMED. The GPL License provides additional details about this warranty
  39580. +disclaimer.
  39581. +********************************************************************************
  39582. +Marvell BSD License Option
  39583. +
  39584. +If you received this File from Marvell, you may opt to use, redistribute and/or
  39585. +modify this File under the following licensing terms.
  39586. +Redistribution and use in source and binary forms, with or without modification,
  39587. +are permitted provided that the following conditions are met:
  39588. +
  39589. + * Redistributions of source code must retain the above copyright notice,
  39590. + this list of conditions and the following disclaimer.
  39591. +
  39592. + * Redistributions in binary form must reproduce the above copyright
  39593. + notice, this list of conditions and the following disclaimer in the
  39594. + documentation and/or other materials provided with the distribution.
  39595. +
  39596. + * Neither the name of Marvell nor the names of its contributors may be
  39597. + used to endorse or promote products derived from this software without
  39598. + specific prior written permission.
  39599. +
  39600. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  39601. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  39602. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39603. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  39604. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  39605. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  39606. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  39607. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  39608. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  39609. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  39610. +
  39611. +*******************************************************************************/
  39612. +
  39613. +
  39614. +#ifndef __INCmvCtrlEnvLibh
  39615. +#define __INCmvCtrlEnvLibh
  39616. +
  39617. +/* includes */
  39618. +#include "mvSysHwConfig.h"
  39619. +#include "mvCommon.h"
  39620. +#include "mvTypes.h"
  39621. +#include "mvOs.h"
  39622. +#include "boardEnv/mvBoardEnvLib.h"
  39623. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  39624. +#include "ctrlEnv/mvCtrlEnvRegs.h"
  39625. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  39626. +
  39627. +
  39628. +/* typedefs */
  39629. +
  39630. +/* This enumerator describes the possible HW cache coherency policies the */
  39631. +/* controllers supports. */
  39632. +typedef enum _mvCachePolicy
  39633. +{
  39634. + NO_COHERENCY, /* No HW cache coherency support */
  39635. + WT_COHERENCY, /* HW cache coherency supported in Write Through policy */
  39636. + WB_COHERENCY /* HW cache coherency supported in Write Back policy */
  39637. +}MV_CACHE_POLICY;
  39638. +
  39639. +
  39640. +/* The swapping is referred to a 64-bit words (as this is the controller */
  39641. +/* internal data path width). This enumerator describes the possible */
  39642. +/* data swap types. Below is an example of the data 0x0011223344556677 */
  39643. +typedef enum _mvSwapType
  39644. +{
  39645. + MV_BYTE_SWAP, /* Byte Swap 77 66 55 44 33 22 11 00 */
  39646. + MV_NO_SWAP, /* No swapping 00 11 22 33 44 55 66 77 */
  39647. + MV_BYTE_WORD_SWAP, /* Both byte and word swap 33 22 11 00 77 66 55 44 */
  39648. + MV_WORD_SWAP, /* Word swap 44 55 66 77 00 11 22 33 */
  39649. + SWAP_TYPE_MAX /* Delimiter for this enumerator */
  39650. +}MV_SWAP_TYPE;
  39651. +
  39652. +/* This structure describes access rights for Access protection windows */
  39653. +/* that can be found in IDMA, XOR, Ethernet and MPSC units. */
  39654. +/* Note that the permission enumerator coresponds to its register format. */
  39655. +/* For example, Read only premission is presented as "1" in register field. */
  39656. +typedef enum _mvAccessRights
  39657. +{
  39658. + NO_ACCESS_ALLOWED = 0, /* No access allowed */
  39659. + READ_ONLY = 1, /* Read only permission */
  39660. + ACC_RESERVED = 2, /* Reserved access right */
  39661. + FULL_ACCESS = 3, /* Read and Write permission */
  39662. + MAX_ACC_RIGHTS
  39663. +}MV_ACCESS_RIGHTS;
  39664. +
  39665. +
  39666. +/* mcspLib.h API list */
  39667. +
  39668. +MV_STATUS mvCtrlEnvInit(MV_VOID);
  39669. +MV_U32 mvCtrlMppRegGet(MV_U32 mppGroup);
  39670. +
  39671. +#if defined(MV_INCLUDE_PEX)
  39672. +MV_U32 mvCtrlPexMaxIfGet(MV_VOID);
  39673. +#else
  39674. +#define mvCtrlPexMaxIfGet() (0)
  39675. +#endif
  39676. +
  39677. +#define mvCtrlPciIfMaxIfGet() (0)
  39678. +
  39679. +#if defined(MV_INCLUDE_GIG_ETH)
  39680. +MV_U32 mvCtrlEthMaxPortGet(MV_VOID);
  39681. +#endif
  39682. +#if defined(MV_INCLUDE_XOR)
  39683. +MV_U32 mvCtrlXorMaxChanGet(MV_VOID);
  39684. +#endif
  39685. +#if defined(MV_INCLUDE_USB)
  39686. +MV_U32 mvCtrlUsbMaxGet(MV_VOID);
  39687. +#endif
  39688. +#if defined(MV_INCLUDE_NAND)
  39689. +MV_U32 mvCtrlNandSupport(MV_VOID);
  39690. +#endif
  39691. +#if defined(MV_INCLUDE_SDIO)
  39692. +MV_U32 mvCtrlSdioSupport(MV_VOID);
  39693. +#endif
  39694. +#if defined(MV_INCLUDE_TS)
  39695. +MV_U32 mvCtrlTsSupport(MV_VOID);
  39696. +#endif
  39697. +#if defined(MV_INCLUDE_AUDIO)
  39698. +MV_U32 mvCtrlAudioSupport(MV_VOID);
  39699. +#endif
  39700. +#if defined(MV_INCLUDE_TDM)
  39701. +MV_U32 mvCtrlTdmSupport(MV_VOID);
  39702. +#endif
  39703. +
  39704. +MV_U16 mvCtrlModelGet(MV_VOID);
  39705. +MV_U8 mvCtrlRevGet(MV_VOID);
  39706. +MV_STATUS mvCtrlNameGet(char *pNameBuff);
  39707. +MV_U32 mvCtrlModelRevGet(MV_VOID);
  39708. +MV_STATUS mvCtrlModelRevNameGet(char *pNameBuff);
  39709. +MV_VOID mvCtrlAddrDecShow(MV_VOID);
  39710. +const MV_8* mvCtrlTargetNameGet(MV_TARGET target);
  39711. +MV_U32 ctrlSizeToReg(MV_U32 size, MV_U32 alignment);
  39712. +MV_U32 ctrlRegToSize(MV_U32 regSize, MV_U32 alignment);
  39713. +MV_U32 ctrlSizeRegRoundUp(MV_U32 size, MV_U32 alignment);
  39714. +MV_U32 mvCtrlSysRstLengthCounterGet(MV_VOID);
  39715. +MV_STATUS ctrlWinOverlapTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2);
  39716. +MV_STATUS ctrlWinWithinWinTest(MV_ADDR_WIN *pAddrWin1, MV_ADDR_WIN *pAddrWin2);
  39717. +
  39718. +MV_VOID mvCtrlPwrClckSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable);
  39719. +MV_BOOL mvCtrlPwrClckGet(MV_UNIT_ID unitId, MV_U32 index);
  39720. +MV_VOID mvCtrlPwrMemSet(MV_UNIT_ID unitId, MV_U32 index, MV_BOOL enable);
  39721. +MV_BOOL mvCtrlIsBootFromSPI(MV_VOID);
  39722. +MV_BOOL mvCtrlIsBootFromSPIUseNAND(MV_VOID);
  39723. +MV_BOOL mvCtrlIsBootFromNAND(MV_VOID);
  39724. +#if defined(MV_INCLUDE_CLK_PWR_CNTRL)
  39725. +MV_VOID mvCtrlPwrSaveOn(MV_VOID);
  39726. +MV_VOID mvCtrlPwrSaveOff(MV_VOID);
  39727. +#endif
  39728. +MV_BOOL mvCtrlPwrMemGet(MV_UNIT_ID unitId, MV_U32 index);
  39729. +MV_VOID mvMPPConfigToSPI(MV_VOID);
  39730. +MV_VOID mvMPPConfigToDefault(MV_VOID);
  39731. +
  39732. +
  39733. +#endif /* __INCmvCtrlEnvLibh */
  39734. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h
  39735. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h 1970-01-01 01:00:00.000000000 +0100
  39736. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvRegs.h 2011-08-01 14:38:19.000000000 +0200
  39737. @@ -0,0 +1,419 @@
  39738. +/*******************************************************************************
  39739. +Copyright (C) Marvell International Ltd. and its affiliates
  39740. +
  39741. +This software file (the "File") is owned and distributed by Marvell
  39742. +International Ltd. and/or its affiliates ("Marvell") under the following
  39743. +alternative licensing terms. Once you have made an election to distribute the
  39744. +File under one of the following license alternatives, please (i) delete this
  39745. +introductory statement regarding license alternatives, (ii) delete the two
  39746. +license alternatives that you have not elected to use and (iii) preserve the
  39747. +Marvell copyright notice above.
  39748. +
  39749. +********************************************************************************
  39750. +Marvell Commercial License Option
  39751. +
  39752. +If you received this File from Marvell and you have entered into a commercial
  39753. +license agreement (a "Commercial License") with Marvell, the File is licensed
  39754. +to you under the terms of the applicable Commercial License.
  39755. +
  39756. +********************************************************************************
  39757. +Marvell GPL License Option
  39758. +
  39759. +If you received this File from Marvell, you may opt to use, redistribute and/or
  39760. +modify this File in accordance with the terms and conditions of the General
  39761. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  39762. +available along with the File in the license.txt file or by writing to the Free
  39763. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  39764. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  39765. +
  39766. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  39767. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  39768. +DISCLAIMED. The GPL License provides additional details about this warranty
  39769. +disclaimer.
  39770. +********************************************************************************
  39771. +Marvell BSD License Option
  39772. +
  39773. +If you received this File from Marvell, you may opt to use, redistribute and/or
  39774. +modify this File under the following licensing terms.
  39775. +Redistribution and use in source and binary forms, with or without modification,
  39776. +are permitted provided that the following conditions are met:
  39777. +
  39778. + * Redistributions of source code must retain the above copyright notice,
  39779. + this list of conditions and the following disclaimer.
  39780. +
  39781. + * Redistributions in binary form must reproduce the above copyright
  39782. + notice, this list of conditions and the following disclaimer in the
  39783. + documentation and/or other materials provided with the distribution.
  39784. +
  39785. + * Neither the name of Marvell nor the names of its contributors may be
  39786. + used to endorse or promote products derived from this software without
  39787. + specific prior written permission.
  39788. +
  39789. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  39790. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  39791. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39792. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  39793. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  39794. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  39795. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  39796. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  39797. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  39798. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  39799. +
  39800. +*******************************************************************************/
  39801. +
  39802. +#ifndef __INCmvCtrlEnvRegsh
  39803. +#define __INCmvCtrlEnvRegsh
  39804. +
  39805. +#ifdef __cplusplus
  39806. +extern "C" {
  39807. +#endif /* __cplusplus */
  39808. +
  39809. +/* CV Support */
  39810. +#define PEX0_MEM0 PEX0_MEM
  39811. +#define PCI0_MEM0 PEX0_MEM
  39812. +
  39813. +/* Controller revision info */
  39814. +#define PCI_CLASS_CODE_AND_REVISION_ID 0x008
  39815. +#define PCCRIR_REVID_OFFS 0 /* Revision ID */
  39816. +#define PCCRIR_REVID_MASK (0xff << PCCRIR_REVID_OFFS)
  39817. +
  39818. +/* Controler environment registers offsets */
  39819. +
  39820. +/* Power Managment Control */
  39821. +#define POWER_MNG_MEM_CTRL_REG 0x20118
  39822. +
  39823. +#define PMC_GESTOPMEM_OFFS(port) ((port)? 13 : 0)
  39824. +#define PMC_GESTOPMEM_MASK(port) (1 << PMC_GESTOPMEM_OFFS(port))
  39825. +#define PMC_GESTOPMEM_EN(port) (0 << PMC_GESTOPMEM_OFFS(port))
  39826. +#define PMC_GESTOPMEM_STOP(port) (1 << PMC_GESTOPMEM_OFFS(port))
  39827. +
  39828. +#define PMC_PEXSTOPMEM_OFFS 1
  39829. +#define PMC_PEXSTOPMEM_MASK (1 << PMC_PEXSTOPMEM_OFFS)
  39830. +#define PMC_PEXSTOPMEM_EN (0 << PMC_PEXSTOPMEM_OFFS)
  39831. +#define PMC_PEXSTOPMEM_STOP (1 << PMC_PEXSTOPMEM_OFFS)
  39832. +
  39833. +#define PMC_USBSTOPMEM_OFFS 2
  39834. +#define PMC_USBSTOPMEM_MASK (1 << PMC_USBSTOPMEM_OFFS)
  39835. +#define PMC_USBSTOPMEM_EN (0 << PMC_USBSTOPMEM_OFFS)
  39836. +#define PMC_USBSTOPMEM_STOP (1 << PMC_USBSTOPMEM_OFFS)
  39837. +
  39838. +#define PMC_DUNITSTOPMEM_OFFS 3
  39839. +#define PMC_DUNITSTOPMEM_MASK (1 << PMC_DUNITSTOPMEM_OFFS)
  39840. +#define PMC_DUNITSTOPMEM_EN (0 << PMC_DUNITSTOPMEM_OFFS)
  39841. +#define PMC_DUNITSTOPMEM_STOP (1 << PMC_DUNITSTOPMEM_OFFS)
  39842. +
  39843. +#define PMC_RUNITSTOPMEM_OFFS 4
  39844. +#define PMC_RUNITSTOPMEM_MASK (1 << PMC_RUNITSTOPMEM_OFFS)
  39845. +#define PMC_RUNITSTOPMEM_EN (0 << PMC_RUNITSTOPMEM_OFFS)
  39846. +#define PMC_RUNITSTOPMEM_STOP (1 << PMC_RUNITSTOPMEM_OFFS)
  39847. +
  39848. +#define PMC_XORSTOPMEM_OFFS(port) (5+(port*2))
  39849. +#define PMC_XORSTOPMEM_MASK(port) (1 << PMC_XORSTOPMEM_OFFS(port))
  39850. +#define PMC_XORSTOPMEM_EN(port) (0 << PMC_XORSTOPMEM_OFFS(port))
  39851. +#define PMC_XORSTOPMEM_STOP(port) (1 << PMC_XORSTOPMEM_OFFS(port))
  39852. +
  39853. +#define PMC_SATASTOPMEM_OFFS(port) (6+(port*5))
  39854. +#define PMC_SATASTOPMEM_MASK(port) (1 << PMC_SATASTOPMEM_OFFS(port))
  39855. +#define PMC_SATASTOPMEM_EN(port) (0 << PMC_SATASTOPMEM_OFFS(port))
  39856. +#define PMC_SATASTOPMEM_STOP(port) (1 << PMC_SATASTOPMEM_OFFS(port))
  39857. +
  39858. +#define PMC_SESTOPMEM_OFFS 8
  39859. +#define PMC_SESTOPMEM_MASK (1 << PMC_SESTOPMEM_OFFS)
  39860. +#define PMC_SESTOPMEM_EN (0 << PMC_SESTOPMEM_OFFS)
  39861. +#define PMC_SESTOPMEM_STOP (1 << PMC_SESTOPMEM_OFFS)
  39862. +
  39863. +#define PMC_AUDIOSTOPMEM_OFFS 9
  39864. +#define PMC_AUDIOSTOPMEM_MASK (1 << PMC_AUDIOSTOPMEM_OFFS)
  39865. +#define PMC_AUDIOSTOPMEM_EN (0 << PMC_AUDIOSTOPMEM_OFFS)
  39866. +#define PMC_AUDIOSTOPMEM_STOP (1 << PMC_AUDIOSTOPMEM_OFFS)
  39867. +
  39868. +#define POWER_MNG_CTRL_REG 0x2011C
  39869. +
  39870. +#define PMC_GESTOPCLOCK_OFFS(port) ((port)? 19 : 0)
  39871. +#define PMC_GESTOPCLOCK_MASK(port) (1 << PMC_GESTOPCLOCK_OFFS(port))
  39872. +#define PMC_GESTOPCLOCK_EN(port) (1 << PMC_GESTOPCLOCK_OFFS(port))
  39873. +#define PMC_GESTOPCLOCK_STOP(port) (0 << PMC_GESTOPCLOCK_OFFS(port))
  39874. +
  39875. +#define PMC_PEXPHYSTOPCLOCK_OFFS 1
  39876. +#define PMC_PEXPHYSTOPCLOCK_MASK (1 << PMC_PEXPHYSTOPCLOCK_OFFS)
  39877. +#define PMC_PEXPHYSTOPCLOCK_EN (1 << PMC_PEXPHYSTOPCLOCK_OFFS)
  39878. +#define PMC_PEXPHYSTOPCLOCK_STOP (0 << PMC_PEXPHYSTOPCLOCK_OFFS)
  39879. +
  39880. +#define PMC_PEXSTOPCLOCK_OFFS 2
  39881. +#define PMC_PEXSTOPCLOCK_MASK (1 << PMC_PEXSTOPCLOCK_OFFS)
  39882. +#define PMC_PEXSTOPCLOCK_EN (1 << PMC_PEXSTOPCLOCK_OFFS)
  39883. +#define PMC_PEXSTOPCLOCK_STOP (0 << PMC_PEXSTOPCLOCK_OFFS)
  39884. +
  39885. +#define PMC_USBSTOPCLOCK_OFFS 3
  39886. +#define PMC_USBSTOPCLOCK_MASK (1 << PMC_USBSTOPCLOCK_OFFS)
  39887. +#define PMC_USBSTOPCLOCK_EN (1 << PMC_USBSTOPCLOCK_OFFS)
  39888. +#define PMC_USBSTOPCLOCK_STOP (0 << PMC_USBSTOPCLOCK_OFFS)
  39889. +
  39890. +#define PMC_SDIOSTOPCLOCK_OFFS 4
  39891. +#define PMC_SDIOSTOPCLOCK_MASK (1 << PMC_SDIOSTOPCLOCK_OFFS)
  39892. +#define PMC_SDIOSTOPCLOCK_EN (1 << PMC_SDIOSTOPCLOCK_OFFS)
  39893. +#define PMC_SDIOSTOPCLOCK_STOP (0 << PMC_SDIOSTOPCLOCK_OFFS)
  39894. +
  39895. +#define PMC_TSSTOPCLOCK_OFFS 5
  39896. +#define PMC_TSSTOPCLOCK_MASK (1 << PMC_TSSTOPCLOCK_OFFS)
  39897. +#define PMC_TSSTOPCLOCK_EN (1 << PMC_TSSTOPCLOCK_OFFS)
  39898. +#define PMC_TSSTOPCLOCK_STOP (0 << PMC_TSSTOPCLOCK_OFFS)
  39899. +
  39900. +#define PMC_AUDIOSTOPCLOCK_OFFS 9
  39901. +#define PMC_AUDIOSTOPCLOCK_MASK (1 << PMC_AUDIOSTOPCLOCK_OFFS)
  39902. +#define PMC_AUDIOSTOPCLOCK_EN (1 << PMC_AUDIOSTOPCLOCK_OFFS)
  39903. +#define PMC_AUDIOSTOPCLOCK_STOP (0 << PMC_AUDIOSTOPCLOCK_OFFS)
  39904. +
  39905. +#define PMC_POWERSAVE_OFFS 11
  39906. +#define PMC_POWERSAVE_MASK (1 << PMC_POWERSAVE_OFFS)
  39907. +#define PMC_POWERSAVE_EN (1 << PMC_POWERSAVE_OFFS)
  39908. +#define PMC_POWERSAVE_STOP (0 << PMC_POWERSAVE_OFFS)
  39909. +
  39910. +
  39911. +
  39912. +
  39913. +#define PMC_SATASTOPCLOCK_OFFS(port) (14+(port))
  39914. +#define PMC_SATASTOPCLOCK_MASK(port) (1 << PMC_SATASTOPCLOCK_OFFS(port))
  39915. +#define PMC_SATASTOPCLOCK_EN(port) (1 << PMC_SATASTOPCLOCK_OFFS(port))
  39916. +#define PMC_SATASTOPCLOCK_STOP(port) (0 << PMC_SATASTOPCLOCK_OFFS(port))
  39917. +
  39918. +#define PMC_SESTOPCLOCK_OFFS 17
  39919. +#define PMC_SESTOPCLOCK_MASK (1 << PMC_SESTOPCLOCK_OFFS)
  39920. +#define PMC_SESTOPCLOCK_EN (1 << PMC_SESTOPCLOCK_OFFS)
  39921. +#define PMC_SESTOPCLOCK_STOP (0 << PMC_SESTOPCLOCK_OFFS)
  39922. +
  39923. +#define PMC_TDMSTOPCLOCK_OFFS 20
  39924. +#define PMC_TDMSTOPCLOCK_MASK (1 << PMC_TDMSTOPCLOCK_OFFS)
  39925. +#define PMC_TDMSTOPCLOCK_EN (1 << PMC_TDMSTOPCLOCK_OFFS)
  39926. +#define PMC_TDMSTOPCLOCK_STOP (0 << PMC_TDMSTOPCLOCK_OFFS)
  39927. +
  39928. +
  39929. +/* Controler environment registers offsets */
  39930. +#define MPP_CONTROL_REG0 0x10000
  39931. +#define MPP_CONTROL_REG1 0x10004
  39932. +#define MPP_CONTROL_REG2 0x10008
  39933. +#define MPP_CONTROL_REG3 0x1000C
  39934. +#define MPP_CONTROL_REG4 0x10010
  39935. +#define MPP_CONTROL_REG5 0x10014
  39936. +#define MPP_CONTROL_REG6 0x10018
  39937. +#define MPP_SAMPLE_AT_RESET 0x10030
  39938. +#define CHIP_BOND_REG 0x10034
  39939. +#define SYSRST_LENGTH_COUNTER_REG 0x10050
  39940. +#define SLCR_COUNT_OFFS 0
  39941. +#define SLCR_COUNT_MASK (0x1FFFFFFF << SLCR_COUNT_OFFS)
  39942. +#define SLCR_CLR_OFFS 31
  39943. +#define SLCR_CLR_MASK (1 << SLCR_CLR_OFFS)
  39944. +#define PCKG_OPT_MASK 0x3
  39945. +#define MPP_OUTPUT_DRIVE_REG 0x100E0
  39946. +#define MPP_RGMII0_OUTPUT_DRIVE_OFFS 7
  39947. +#define MPP_3_3_RGMII0_OUTPUT_DRIVE (0x0 << MPP_RGMII0_OUTPUT_DRIVE_OFFS)
  39948. +#define MPP_1_8_RGMII0_OUTPUT_DRIVE (0x1 << MPP_RGMII0_OUTPUT_DRIVE_OFFS)
  39949. +#define MPP_RGMII1_OUTPUT_DRIVE_OFFS 15
  39950. +#define MPP_3_3_RGMII1_OUTPUT_DRIVE (0x0 << MPP_RGMII1_OUTPUT_DRIVE_OFFS)
  39951. +#define MPP_1_8_RGMII1_OUTPUT_DRIVE (0x1 << MPP_RGMII1_OUTPUT_DRIVE_OFFS)
  39952. +
  39953. +#define MSAR_BOOT_MODE_OFFS 12
  39954. +#define MSAR_BOOT_MODE_MASK (0x7 << MSAR_BOOT_MODE_OFFS)
  39955. +#define MSAR_BOOT_NAND_WITH_BOOTROM (0x5 << MSAR_BOOT_MODE_OFFS)
  39956. +#define MSAR_BOOT_SPI_WITH_BOOTROM (0x4 << MSAR_BOOT_MODE_OFFS)
  39957. +#define MSAR_BOOT_SPI_USE_NAND_WITH_BOOTROM (0x2 << MSAR_BOOT_MODE_OFFS)
  39958. +
  39959. +#define MSAR_BOOT_MODE_6180(X) (((X & 0x3000) >> 12) | \
  39960. + ((X & 0x2) << 1))
  39961. +#define MSAR_BOOT_SPI_WITH_BOOTROM_6180 0x1
  39962. +#define MSAR_BOOT_NAND_WITH_BOOTROM_6180 0x5
  39963. +
  39964. +#define MSAR_TCLCK_OFFS 21
  39965. +#define MSAR_TCLCK_MASK (0x1 << MSAR_TCLCK_OFFS)
  39966. +#define MSAR_TCLCK_166 (0x1 << MSAR_TCLCK_OFFS)
  39967. +#define MSAR_TCLCK_200 (0x0 << MSAR_TCLCK_OFFS)
  39968. +
  39969. +
  39970. +#define MSAR_CPUCLCK_EXTRACT(X) (((X & 0x2) >> 1) | ((X & 0x400000) >> 21) | \
  39971. + ((X & 0x18) >> 1))
  39972. +
  39973. +#define MSAR_CPUCLCK_OFFS_6180 2
  39974. +#define MSAR_CPUCLCK_MASK_6180 (0x7 << MSAR_CPUCLCK_OFFS_6180)
  39975. +
  39976. +#define MSAR_DDRCLCK_RTIO_OFFS 5
  39977. +#define MSAR_DDRCLCK_RTIO_MASK (0xF << MSAR_DDRCLCK_RTIO_OFFS)
  39978. +
  39979. +#define MSAR_L2CLCK_EXTRACT(X) (((X & 0x600) >> 9) | ((X & 0x80000) >> 17))
  39980. +
  39981. +#ifndef MV_ASMLANGUAGE
  39982. +/* CPU clock for 6281,6192 0->Resereved */
  39983. +#define MV_CPU_CLCK_TBL { 0, 0, 0, 0, \
  39984. + 600000000, 0, 800000000, 1000000000, \
  39985. + 0, 1200000000, 0, 0, \
  39986. + 1500000000, 0, 0, 0}
  39987. +
  39988. +/* DDR clock RATIO for 6281,6192 {0,0}->Reserved */
  39989. +#define MV_DDR_CLCK_RTIO_TBL {\
  39990. + {0, 0}, {0, 0}, {2, 1}, {0, 0}, \
  39991. + {3, 1}, {0, 0}, {4, 1}, {9, 2}, \
  39992. + {5, 1}, {6, 1}, {0, 0}, {0, 0}, \
  39993. + {0, 0}, {0, 0}, {0, 0}, {0, 0} \
  39994. +}
  39995. +
  39996. +/* L2 clock RATIO for 6281,6192 {1,1}->Reserved */
  39997. +#define MV_L2_CLCK_RTIO_TBL {\
  39998. + {0, 0}, {2, 1}, {0, 0}, {3, 1}, \
  39999. + {0, 0}, {0, 0}, {0, 0}, {0, 0} \
  40000. +}
  40001. +
  40002. +/* 6180 have different clk reset sampling */
  40003. +/* ARM CPU, DDR, L2 clock for 6180 {0,0,0}->Reserved */
  40004. +#define MV_CPU6180_DDR_L2_CLCK_TBL { \
  40005. + {0, 0, 0 },\
  40006. + {0, 0, 0 },\
  40007. + {0, 0, 0 },\
  40008. + {0, 0, 0 },\
  40009. + {0, 0, 0 },\
  40010. + {600000000, 200000000, 300000000 },\
  40011. + {800000000, 200000000, 400000000 },\
  40012. + {0, 0, 0 }\
  40013. +}
  40014. +
  40015. +
  40016. +
  40017. +/* These macros help units to identify a target Mbus Arbiter group */
  40018. +#define MV_TARGET_IS_DRAM(target) \
  40019. + ((target >= SDRAM_CS0) && (target <= SDRAM_CS3))
  40020. +
  40021. +#define MV_TARGET_IS_PEX0(target) \
  40022. + ((target >= PEX0_MEM) && (target <= PEX0_IO))
  40023. +
  40024. +#define MV_TARGET_IS_PEX1(target) 0
  40025. +
  40026. +#define MV_TARGET_IS_PEX(target) (MV_TARGET_IS_PEX0(target) || MV_TARGET_IS_PEX1(target))
  40027. +
  40028. +#define MV_TARGET_IS_DEVICE(target) \
  40029. + ((target >= DEVICE_CS0) && (target <= DEVICE_CS3))
  40030. +
  40031. +#define MV_PCI_DRAM_BAR_TO_DRAM_TARGET(bar) 0
  40032. +
  40033. +#define MV_TARGET_IS_AS_BOOT(target) ((target) == (sampleAtResetTargetArray[ \
  40034. + (mvCtrlModelGet() == MV_6180_DEV_ID)? MSAR_BOOT_MODE_6180 \
  40035. + (MV_REG_READ(MPP_SAMPLE_AT_RESET)):((MV_REG_READ(MPP_SAMPLE_AT_RESET)\
  40036. + & MSAR_BOOT_MODE_MASK) >> MSAR_BOOT_MODE_OFFS)]))
  40037. +
  40038. +
  40039. +#define MV_CHANGE_BOOT_CS(target) (((target) == DEV_BOOCS)?\
  40040. + sampleAtResetTargetArray[(mvCtrlModelGet() == MV_6180_DEV_ID)? \
  40041. + MSAR_BOOT_MODE_6180(MV_REG_READ(MPP_SAMPLE_AT_RESET)): \
  40042. + ((MV_REG_READ(MPP_SAMPLE_AT_RESET) & MSAR_BOOT_MODE_MASK)\
  40043. + >> MSAR_BOOT_MODE_OFFS)]:(target))
  40044. +
  40045. +#define TCLK_TO_COUNTER_RATIO 1 /* counters running in Tclk */
  40046. +
  40047. +#define BOOT_TARGETS_NAME_ARRAY { \
  40048. + TBL_TERM, \
  40049. + TBL_TERM, \
  40050. + BOOT_ROM_CS, \
  40051. + TBL_TERM, \
  40052. + BOOT_ROM_CS, \
  40053. + BOOT_ROM_CS, \
  40054. + TBL_TERM, \
  40055. + TBL_TERM \
  40056. +}
  40057. +
  40058. +#define BOOT_TARGETS_NAME_ARRAY_6180 { \
  40059. + TBL_TERM, \
  40060. + BOOT_ROM_CS, \
  40061. + TBL_TERM, \
  40062. + TBL_TERM, \
  40063. + TBL_TERM, \
  40064. + BOOT_ROM_CS, \
  40065. + TBL_TERM, \
  40066. + TBL_TERM \
  40067. +}
  40068. +
  40069. +
  40070. +/* For old competability */
  40071. +#define DEVICE_CS0 NFLASH_CS
  40072. +#define DEVICE_CS1 SPI_CS
  40073. +#define DEVICE_CS2 BOOT_ROM_CS
  40074. +#define DEVICE_CS3 DEV_BOOCS
  40075. +#define MV_BOOTDEVICE_INDEX 0
  40076. +
  40077. +#define START_DEV_CS DEV_CS0
  40078. +#define DEV_TO_TARGET(dev) ((dev) + DEVICE_CS0)
  40079. +
  40080. +#define PCI_IF0_MEM0 PEX0_MEM
  40081. +#define PCI_IF0_IO PEX0_IO
  40082. +
  40083. +
  40084. +/* This enumerator defines the Marvell controller target ID */
  40085. +typedef enum _mvTargetId
  40086. +{
  40087. + DRAM_TARGET_ID = 0 , /* Port 0 -> DRAM interface */
  40088. + DEV_TARGET_ID = 1, /* Port 1 -> Nand/SPI */
  40089. + PEX0_TARGET_ID = 4 , /* Port 4 -> PCI Express0 */
  40090. + CRYPT_TARGET_ID = 3 , /* Port 3 --> Crypto Engine */
  40091. + SAGE_TARGET_ID = 12 , /* Port 12 -> SAGE Unit */
  40092. + MAX_TARGETS_ID
  40093. +}MV_TARGET_ID;
  40094. +
  40095. +
  40096. +/* This enumerator described the possible Controller paripheral targets. */
  40097. +/* Controller peripherals are designated memory/IO address spaces that the */
  40098. +/* controller can access. They are also refered as "targets" */
  40099. +typedef enum _mvTarget
  40100. +{
  40101. + TBL_TERM = -1, /* none valid target, used as targets list terminator*/
  40102. + SDRAM_CS0, /* SDRAM chip select 0 */
  40103. + SDRAM_CS1, /* SDRAM chip select 1 */
  40104. + SDRAM_CS2, /* SDRAM chip select 2 */
  40105. + SDRAM_CS3, /* SDRAM chip select 3 */
  40106. + PEX0_MEM, /* PCI Express 0 Memory */
  40107. + PEX0_IO, /* PCI Express 0 IO */
  40108. + INTER_REGS, /* Internal registers */
  40109. + NFLASH_CS, /* NFLASH_CS */
  40110. + SPI_CS, /* SPI_CS */
  40111. + BOOT_ROM_CS, /* BOOT_ROM_CS */
  40112. + DEV_BOOCS, /* DEV_BOOCS */
  40113. + CRYPT_ENG, /* Crypto Engine */
  40114. +#ifdef MV_INCLUDE_SAGE
  40115. + SAGE_UNIT, /* SAGE Unit */
  40116. +#endif
  40117. + MAX_TARGETS
  40118. +
  40119. +}MV_TARGET;
  40120. +
  40121. +#define TARGETS_DEF_ARRAY { \
  40122. + {0x0E, DRAM_TARGET_ID }, /* SDRAM_CS0 */ \
  40123. + {0x0D, DRAM_TARGET_ID }, /* SDRAM_CS1 */ \
  40124. + {0x0B, DRAM_TARGET_ID }, /* SDRAM_CS0 */ \
  40125. + {0x07, DRAM_TARGET_ID }, /* SDRAM_CS1 */ \
  40126. + {0xE8, PEX0_TARGET_ID }, /* PEX0_MEM */ \
  40127. + {0xE0, PEX0_TARGET_ID }, /* PEX0_IO */ \
  40128. + {0xFF, 0xFF }, /* INTER_REGS */ \
  40129. + {0x2F, DEV_TARGET_ID }, /* NFLASH_CS */ \
  40130. + {0x1E, DEV_TARGET_ID }, /* SPI_CS */ \
  40131. + {0x1D, DEV_TARGET_ID }, /* BOOT_ROM_CS */ \
  40132. + {0x1E, DEV_TARGET_ID }, /* DEV_BOOCS */ \
  40133. + {0x01, CRYPT_TARGET_ID}, /* CRYPT_ENG */ \
  40134. + {0x00, SAGE_TARGET_ID } \
  40135. +}
  40136. +
  40137. +
  40138. +#define TARGETS_NAME_ARRAY { \
  40139. + "SDRAM_CS0", /* SDRAM_CS0 */ \
  40140. + "SDRAM_CS1", /* SDRAM_CS1 */ \
  40141. + "SDRAM_CS2", /* SDRAM_CS2 */ \
  40142. + "SDRAM_CS3", /* SDRAM_CS3 */ \
  40143. + "PEX0_MEM", /* PEX0_MEM */ \
  40144. + "PEX0_IO", /* PEX0_IO */ \
  40145. + "INTER_REGS", /* INTER_REGS */ \
  40146. + "NFLASH_CS", /* NFLASH_CS */ \
  40147. + "SPI_CS", /* SPI_CS */ \
  40148. + "BOOT_ROM_CS", /* BOOT_ROM_CS */ \
  40149. + "DEV_BOOTCS", /* DEV_BOOCS */ \
  40150. + "CRYPT_ENG", /* CRYPT_ENG */ \
  40151. + "SAGE_UNIT" /* SAGE_UNIT */ \
  40152. +}
  40153. +#endif /* MV_ASMLANGUAGE */
  40154. +
  40155. +
  40156. +#endif
  40157. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h
  40158. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h 1970-01-01 01:00:00.000000000 +0100
  40159. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/mvCtrlEnvSpec.h 2011-08-01 14:38:19.000000000 +0200
  40160. @@ -0,0 +1,257 @@
  40161. +/*******************************************************************************
  40162. +Copyright (C) Marvell International Ltd. and its affiliates
  40163. +
  40164. +This software file (the "File") is owned and distributed by Marvell
  40165. +International Ltd. and/or its affiliates ("Marvell") under the following
  40166. +alternative licensing terms. Once you have made an election to distribute the
  40167. +File under one of the following license alternatives, please (i) delete this
  40168. +introductory statement regarding license alternatives, (ii) delete the two
  40169. +license alternatives that you have not elected to use and (iii) preserve the
  40170. +Marvell copyright notice above.
  40171. +
  40172. +********************************************************************************
  40173. +Marvell Commercial License Option
  40174. +
  40175. +If you received this File from Marvell and you have entered into a commercial
  40176. +license agreement (a "Commercial License") with Marvell, the File is licensed
  40177. +to you under the terms of the applicable Commercial License.
  40178. +
  40179. +********************************************************************************
  40180. +Marvell GPL License Option
  40181. +
  40182. +If you received this File from Marvell, you may opt to use, redistribute and/or
  40183. +modify this File in accordance with the terms and conditions of the General
  40184. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  40185. +available along with the File in the license.txt file or by writing to the Free
  40186. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  40187. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  40188. +
  40189. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  40190. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  40191. +DISCLAIMED. The GPL License provides additional details about this warranty
  40192. +disclaimer.
  40193. +********************************************************************************
  40194. +Marvell BSD License Option
  40195. +
  40196. +If you received this File from Marvell, you may opt to use, redistribute and/or
  40197. +modify this File under the following licensing terms.
  40198. +Redistribution and use in source and binary forms, with or without modification,
  40199. +are permitted provided that the following conditions are met:
  40200. +
  40201. + * Redistributions of source code must retain the above copyright notice,
  40202. + this list of conditions and the following disclaimer.
  40203. +
  40204. + * Redistributions in binary form must reproduce the above copyright
  40205. + notice, this list of conditions and the following disclaimer in the
  40206. + documentation and/or other materials provided with the distribution.
  40207. +
  40208. + * Neither the name of Marvell nor the names of its contributors may be
  40209. + used to endorse or promote products derived from this software without
  40210. + specific prior written permission.
  40211. +
  40212. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  40213. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  40214. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  40215. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  40216. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  40217. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  40218. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  40219. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  40220. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  40221. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40222. +
  40223. +*******************************************************************************/
  40224. +
  40225. +#ifndef __INCmvCtrlEnvSpech
  40226. +#define __INCmvCtrlEnvSpech
  40227. +
  40228. +#include "mvDeviceId.h"
  40229. +#include "mvSysHwConfig.h"
  40230. +
  40231. +#ifdef __cplusplus
  40232. +extern "C" {
  40233. +#endif /* __cplusplus */
  40234. +
  40235. +#define MV_ARM_SOC
  40236. +#define SOC_NAME_PREFIX "MV88F"
  40237. +
  40238. +
  40239. +/* units base and port numbers */
  40240. +#ifdef MV_ASMLANGUAGE
  40241. +#define XOR_UNIT_BASE(unit) 0x60800
  40242. +#else
  40243. +#define MV_XOR_REG_BASE 0x60000
  40244. +#define XOR_UNIT_BASE(unit) ((unit)? 0x60900:0x60800)
  40245. +#endif
  40246. +
  40247. +#define TDM_REG_BASE 0xD0000
  40248. +#define USB_REG_BASE(dev) 0x50000
  40249. +#define AUDIO_REG_BASE 0xA0000
  40250. +#define SATA_REG_BASE 0x80000
  40251. +#define MV_CESA_REG_BASE 0x3D000
  40252. +#define MV_CESA_TDMA_REG_BASE 0x30000
  40253. +#define MV_SDIO_REG_BASE 0x90000
  40254. +#define MV_ETH_REG_BASE(port) (((port) == 0) ? 0x72000 : 0x76000)
  40255. +#define MV_UART_CHAN_BASE(chanNum) (0x12000 + (chanNum * 0x100))
  40256. +#define DRAM_BASE 0x0
  40257. +#define CNTMR_BASE 0x20300
  40258. +#define TWSI_SLAVE_BASE(chanNum) 0x11000
  40259. +#define PEX_IF_BASE(pexIf) 0x40000
  40260. +#define MPP_REG_BASE 0x10000
  40261. +#define TSU_GLOBAL_REG_BASE 0xB4000
  40262. +#define MAX_AHB_TO_MBUS_REG_BASE 0x20000
  40263. +
  40264. +#define INTER_REGS_SIZE _1M
  40265. +/* This define describes the TWSI interrupt bit and location */
  40266. +#define TWSI_CPU_MAIN_INT_CAUSE_REG 0x20200
  40267. +#define TWSI0_CPU_MAIN_INT_BIT (1<<29)
  40268. +#define TWSI_SPEED 100000
  40269. +
  40270. +#define MV_GPP_MAX_GROUP 2
  40271. +#define MV_CNTMR_MAX_COUNTER 2
  40272. +#define MV_UART_MAX_CHAN 2
  40273. +#define MV_XOR_MAX_UNIT 2
  40274. +#define MV_XOR_MAX_CHAN 4 /* total channels for all units together*/
  40275. +#define MV_XOR_MAX_CHAN_PER_UNIT 2 /* channels for units */
  40276. +#define MV_SATA_MAX_CHAN 2
  40277. +
  40278. +#define MV_6281_MPP_MAX_MODULE 2
  40279. +#define MV_6192_MPP_MAX_MODULE 1
  40280. +#define MV_6190_MPP_MAX_MODULE 1
  40281. +#define MV_6180_MPP_MAX_MODULE 2
  40282. +#define MV_6281_MPP_MAX_GROUP 7
  40283. +#define MV_6192_MPP_MAX_GROUP 4
  40284. +#define MV_6190_MPP_MAX_GROUP 4
  40285. +#define MV_6180_MPP_MAX_GROUP 3
  40286. +
  40287. +#define MV_DRAM_MAX_CS 4
  40288. +
  40289. +/* This define describes the maximum number of supported PCI\PCIX Interfaces*/
  40290. +#define MV_PCI_MAX_IF 0
  40291. +#define MV_PCI_START_IF 0
  40292. +
  40293. +/* This define describes the maximum number of supported PEX Interfaces */
  40294. +#define MV_INCLUDE_PEX0
  40295. +#define MV_DISABLE_PEX_DEVICE_BAR
  40296. +#define MV_PEX_MAX_IF 1
  40297. +#define MV_PEX_START_IF MV_PCI_MAX_IF
  40298. +
  40299. +/* This define describes the maximum number of supported PCI Interfaces */
  40300. +#define MV_PCI_IF_MAX_IF (MV_PEX_MAX_IF+MV_PCI_MAX_IF)
  40301. +
  40302. +#define MV_ETH_MAX_PORTS 2
  40303. +#define MV_6281_ETH_MAX_PORTS 2
  40304. +#define MV_6192_ETH_MAX_PORTS 2
  40305. +#define MV_6190_ETH_MAX_PORTS 1
  40306. +#define MV_6180_ETH_MAX_PORTS 1
  40307. +
  40308. +#define MV_IDMA_MAX_CHAN 0
  40309. +
  40310. +#define MV_USB_MAX_PORTS 1
  40311. +
  40312. +#define MV_USB_VERSION 1
  40313. +
  40314. +
  40315. +#define MV_6281_NAND 1
  40316. +#define MV_6192_NAND 1
  40317. +#define MV_6190_NAND 1
  40318. +#define MV_6180_NAND 0
  40319. +
  40320. +#define MV_6281_SDIO 1
  40321. +#define MV_6192_SDIO 1
  40322. +#define MV_6190_SDIO 1
  40323. +#define MV_6180_SDIO 1
  40324. +
  40325. +#define MV_6281_TS 1
  40326. +#define MV_6192_TS 1
  40327. +#define MV_6190_TS 0
  40328. +#define MV_6180_TS 0
  40329. +
  40330. +#define MV_6281_AUDIO 1
  40331. +#define MV_6192_AUDIO 1
  40332. +#define MV_6190_AUDIO 0
  40333. +#define MV_6180_AUDIO 1
  40334. +
  40335. +#define MV_6281_TDM 1
  40336. +#define MV_6192_TDM 1
  40337. +#define MV_6190_TDM 0
  40338. +#define MV_6180_TDM 0
  40339. +
  40340. +#define MV_DEVICE_MAX_CS 4
  40341. +
  40342. +/* Others */
  40343. +#define PEX_HOST_BUS_NUM(pciIf) (pciIf)
  40344. +#define PEX_HOST_DEV_NUM(pciIf) 0
  40345. +
  40346. +#define PCI_IO(pciIf) (PEX0_IO)
  40347. +#define PCI_MEM(pciIf, memNum) (PEX0_MEM0)
  40348. +/* CESA version #2: One channel, 2KB SRAM, TDMA */
  40349. +#if defined(MV_CESA_CHAIN_MODE_SUPPORT)
  40350. + #define MV_CESA_VERSION 3
  40351. +#else
  40352. +#define MV_CESA_VERSION 2
  40353. +#endif
  40354. +#define MV_CESA_SRAM_SIZE 2*1024
  40355. +/* This define describes the maximum number of supported Ethernet ports */
  40356. +#define MV_ETH_VERSION 4
  40357. +#define MV_ETH_MAX_RXQ 8
  40358. +#define MV_ETH_MAX_TXQ 8
  40359. +#define MV_ETH_PORT_SGMII { MV_FALSE, MV_FALSE }
  40360. +/* This define describes the the support of USB */
  40361. +#define MV_USB_VERSION 1
  40362. +
  40363. +#define MV_INCLUDE_SDRAM_CS0
  40364. +#define MV_INCLUDE_SDRAM_CS1
  40365. +#define MV_INCLUDE_SDRAM_CS2
  40366. +#define MV_INCLUDE_SDRAM_CS3
  40367. +
  40368. +#define MV_INCLUDE_DEVICE_CS0
  40369. +#define MV_INCLUDE_DEVICE_CS1
  40370. +#define MV_INCLUDE_DEVICE_CS2
  40371. +#define MV_INCLUDE_DEVICE_CS3
  40372. +
  40373. +#define MPP_GROUP_1_TYPE {\
  40374. + {0, 0, 0}, /* Reserved for AUTO */ \
  40375. + {0x22220000, 0x22222222, 0x2222}, /* TDM */ \
  40376. + {0x44440000, 0x00044444, 0x0000}, /* AUDIO */ \
  40377. + {0x33330000, 0x33003333, 0x0033}, /* RGMII */ \
  40378. + {0x33330000, 0x03333333, 0x0033}, /* GMII */ \
  40379. + {0x11110000, 0x11111111, 0x0001}, /* TS */ \
  40380. + {0x33330000, 0x33333333, 0x3333} /* MII */ \
  40381. +}
  40382. +
  40383. +#define MPP_GROUP_2_TYPE {\
  40384. + {0, 0, 0}, /* Reserved for AUTO */ \
  40385. + {0x22220000, 0x22222222, 0x22}, /* TDM */ \
  40386. + {0x44440000, 0x00044444, 0x0}, /* AUDIO */ \
  40387. + {0, 0, 0}, /* N_A */ \
  40388. + {0, 0, 0}, /* N_A */ \
  40389. + {0x11110000, 0x11111111, 0x01} /* TS */ \
  40390. +}
  40391. +
  40392. +#ifndef MV_ASMLANGUAGE
  40393. +
  40394. +/* This enumerator defines the Marvell Units ID */
  40395. +typedef enum _mvUnitId
  40396. +{
  40397. + DRAM_UNIT_ID,
  40398. + PEX_UNIT_ID,
  40399. + ETH_GIG_UNIT_ID,
  40400. + USB_UNIT_ID,
  40401. + IDMA_UNIT_ID,
  40402. + XOR_UNIT_ID,
  40403. + SATA_UNIT_ID,
  40404. + TDM_UNIT_ID,
  40405. + UART_UNIT_ID,
  40406. + CESA_UNIT_ID,
  40407. + SPI_UNIT_ID,
  40408. + AUDIO_UNIT_ID,
  40409. + SDIO_UNIT_ID,
  40410. + TS_UNIT_ID,
  40411. + MAX_UNITS_ID
  40412. +
  40413. +}MV_UNIT_ID;
  40414. +
  40415. +#endif
  40416. +
  40417. +#endif /* __INCmvCtrlEnvSpech */
  40418. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c
  40419. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c 1970-01-01 01:00:00.000000000 +0100
  40420. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.c 2011-08-01 14:38:19.000000000 +0200
  40421. @@ -0,0 +1,1048 @@
  40422. +/*******************************************************************************
  40423. +Copyright (C) Marvell International Ltd. and its affiliates
  40424. +
  40425. +This software file (the "File") is owned and distributed by Marvell
  40426. +International Ltd. and/or its affiliates ("Marvell") under the following
  40427. +alternative licensing terms. Once you have made an election to distribute the
  40428. +File under one of the following license alternatives, please (i) delete this
  40429. +introductory statement regarding license alternatives, (ii) delete the two
  40430. +license alternatives that you have not elected to use and (iii) preserve the
  40431. +Marvell copyright notice above.
  40432. +
  40433. +********************************************************************************
  40434. +Marvell Commercial License Option
  40435. +
  40436. +If you received this File from Marvell and you have entered into a commercial
  40437. +license agreement (a "Commercial License") with Marvell, the File is licensed
  40438. +to you under the terms of the applicable Commercial License.
  40439. +
  40440. +********************************************************************************
  40441. +Marvell GPL License Option
  40442. +
  40443. +If you received this File from Marvell, you may opt to use, redistribute and/or
  40444. +modify this File in accordance with the terms and conditions of the General
  40445. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  40446. +available along with the File in the license.txt file or by writing to the Free
  40447. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  40448. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  40449. +
  40450. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  40451. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  40452. +DISCLAIMED. The GPL License provides additional details about this warranty
  40453. +disclaimer.
  40454. +********************************************************************************
  40455. +Marvell BSD License Option
  40456. +
  40457. +If you received this File from Marvell, you may opt to use, redistribute and/or
  40458. +modify this File under the following licensing terms.
  40459. +Redistribution and use in source and binary forms, with or without modification,
  40460. +are permitted provided that the following conditions are met:
  40461. +
  40462. + * Redistributions of source code must retain the above copyright notice,
  40463. + this list of conditions and the following disclaimer.
  40464. +
  40465. + * Redistributions in binary form must reproduce the above copyright
  40466. + notice, this list of conditions and the following disclaimer in the
  40467. + documentation and/or other materials provided with the distribution.
  40468. +
  40469. + * Neither the name of Marvell nor the names of its contributors may be
  40470. + used to endorse or promote products derived from this software without
  40471. + specific prior written permission.
  40472. +
  40473. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  40474. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  40475. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  40476. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  40477. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  40478. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  40479. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  40480. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  40481. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  40482. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40483. +
  40484. +*******************************************************************************/
  40485. +
  40486. +
  40487. +/* includes */
  40488. +#include "ctrlEnv/sys/mvAhbToMbus.h"
  40489. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  40490. +
  40491. +#undef MV_DEBUG
  40492. +/* defines */
  40493. +#ifdef MV_DEBUG
  40494. + #define DB(x) x
  40495. +#else
  40496. + #define DB(x)
  40497. +#endif
  40498. +
  40499. +/* typedefs */
  40500. +
  40501. +
  40502. +/* CPU address remap registers offsets are inconsecutive. This struct */
  40503. +/* describes address remap register offsets */
  40504. +typedef struct _ahbToMbusRemapRegOffs
  40505. +{
  40506. + MV_U32 lowRegOffs; /* Low 32-bit remap register offset */
  40507. + MV_U32 highRegOffs; /* High 32 bit remap register offset */
  40508. +}AHB_TO_MBUS_REMAP_REG_OFFS;
  40509. +
  40510. +/* locals */
  40511. +static MV_STATUS ahbToMbusRemapRegOffsGet (MV_U32 winNum,
  40512. + AHB_TO_MBUS_REMAP_REG_OFFS *pRemapRegs);
  40513. +
  40514. +/*******************************************************************************
  40515. +* mvAhbToMbusInit - Initialize Ahb To Mbus Address Map !
  40516. +*
  40517. +* DESCRIPTION:
  40518. +*
  40519. +* INPUT:
  40520. +* None.
  40521. +*
  40522. +* OUTPUT:
  40523. +* None.
  40524. +*
  40525. +* RETURN:
  40526. +* MV_OK laways.
  40527. +*
  40528. +*******************************************************************************/
  40529. +MV_STATUS mvAhbToMbusInit(void)
  40530. +{
  40531. + return MV_OK;
  40532. +
  40533. +}
  40534. +
  40535. +/*******************************************************************************
  40536. +* mvAhbToMbusWinSet - Set CPU-to-peripheral winNum address window
  40537. +*
  40538. +* DESCRIPTION:
  40539. +* This function sets
  40540. +* address window, also known as address decode window.
  40541. +* A new address decode window is set for specified winNum address window.
  40542. +* If address decode window parameter structure enables the window,
  40543. +* the routine will also enable the winNum window, allowing CPU to access
  40544. +* the winNum window.
  40545. +*
  40546. +* INPUT:
  40547. +* winNum - Windows number.
  40548. +* pAddrDecWin - CPU winNum window data structure.
  40549. +*
  40550. +* OUTPUT:
  40551. +* N/A
  40552. +*
  40553. +* RETURN:
  40554. +* MV_OK if CPU winNum window was set correctly, MV_ERROR in case of
  40555. +* address window overlapps with other active CPU winNum window or
  40556. +* trying to assign 36bit base address while CPU does not support that.
  40557. +* The function returns MV_NOT_SUPPORTED, if the winNum is unsupported.
  40558. +*
  40559. +*******************************************************************************/
  40560. +MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin)
  40561. +{
  40562. + MV_TARGET_ATTRIB targetAttribs;
  40563. + MV_DEC_REGS decRegs;
  40564. +
  40565. + /* Parameter checking */
  40566. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  40567. + {
  40568. + mvOsPrintf("mvAhbToMbusWinSet: ERR. Invalid winNum %d\n", winNum);
  40569. + return MV_NOT_SUPPORTED;
  40570. + }
  40571. +
  40572. +
  40573. + /* read base register*/
  40574. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  40575. + {
  40576. + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
  40577. + }
  40578. + else
  40579. + {
  40580. + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG);
  40581. + }
  40582. +
  40583. + /* check if address is aligned to the size */
  40584. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  40585. + {
  40586. + mvOsPrintf("mvAhbToMbusWinSet:Error setting AHB to MBUS window %d to "\
  40587. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  40588. + winNum,
  40589. + mvCtrlTargetNameGet(pAddrDecWin->target),
  40590. + pAddrDecWin->addrWin.baseLow,
  40591. + pAddrDecWin->addrWin.size);
  40592. + return MV_ERROR;
  40593. + }
  40594. +
  40595. + /* read control register*/
  40596. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  40597. + {
  40598. + decRegs.sizeReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
  40599. + }
  40600. +
  40601. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  40602. + {
  40603. + mvOsPrintf("mvAhbToMbusWinSet:mvCtrlAddrDecToReg Failed\n");
  40604. + return MV_ERROR;
  40605. + }
  40606. +
  40607. + /* enable\Disable */
  40608. + if (MV_TRUE == pAddrDecWin->enable)
  40609. + {
  40610. + decRegs.sizeReg |= ATMWCR_WIN_ENABLE;
  40611. + }
  40612. + else
  40613. + {
  40614. + decRegs.sizeReg &= ~ATMWCR_WIN_ENABLE;
  40615. + }
  40616. +
  40617. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  40618. +
  40619. + /* set attributes */
  40620. + decRegs.sizeReg &= ~ATMWCR_WIN_ATTR_MASK;
  40621. + decRegs.sizeReg |= targetAttribs.attrib << ATMWCR_WIN_ATTR_OFFS;
  40622. + /* set target ID */
  40623. + decRegs.sizeReg &= ~ATMWCR_WIN_TARGET_MASK;
  40624. + decRegs.sizeReg |= targetAttribs.targetId << ATMWCR_WIN_TARGET_OFFS;
  40625. +
  40626. +#if !defined(MV_RUN_FROM_FLASH)
  40627. + /* To be on the safe side we disable the window before writing the */
  40628. + /* new values. */
  40629. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  40630. + {
  40631. + mvAhbToMbusWinEnable(winNum,MV_FALSE);
  40632. + }
  40633. +#endif
  40634. +
  40635. + /* 3) Write to address decode Base Address Register */
  40636. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  40637. + {
  40638. + MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum), decRegs.baseReg);
  40639. + }
  40640. + else
  40641. + {
  40642. + MV_REG_WRITE(AHB_TO_MBUS_WIN_INTEREG_REG, decRegs.baseReg);
  40643. + }
  40644. +
  40645. +
  40646. + /* Internal register space have no size */
  40647. + /* register. Do not perform size register assigment for those targets */
  40648. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  40649. + {
  40650. + /* Write to address decode Size Register */
  40651. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum), decRegs.sizeReg);
  40652. + }
  40653. +
  40654. + return MV_OK;
  40655. +}
  40656. +
  40657. +/*******************************************************************************
  40658. +* mvAhbToMbusWinGet - Get CPU-to-peripheral winNum address window
  40659. +*
  40660. +* DESCRIPTION:
  40661. +* Get the CPU peripheral winNum address window.
  40662. +*
  40663. +* INPUT:
  40664. +* winNum - Peripheral winNum enumerator
  40665. +*
  40666. +* OUTPUT:
  40667. +* pAddrDecWin - CPU winNum window information data structure.
  40668. +*
  40669. +* RETURN:
  40670. +* MV_OK if winNum exist, MV_ERROR otherwise.
  40671. +*
  40672. +*******************************************************************************/
  40673. +MV_STATUS mvAhbToMbusWinGet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin)
  40674. +{
  40675. + MV_DEC_REGS decRegs;
  40676. + MV_TARGET_ATTRIB targetAttrib;
  40677. +
  40678. +
  40679. + /* Parameter checking */
  40680. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  40681. + {
  40682. + mvOsPrintf("mvAhbToMbusWinGet: ERR. Invalid winNum %d\n", winNum);
  40683. + return MV_NOT_SUPPORTED;
  40684. + }
  40685. +
  40686. +
  40687. + /* Internal register space size have no size register*/
  40688. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  40689. + {
  40690. + decRegs.sizeReg = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
  40691. + }
  40692. + else
  40693. + {
  40694. + decRegs.sizeReg = 0;
  40695. + }
  40696. +
  40697. +
  40698. + /* Read base and size */
  40699. + if (winNum != MV_AHB_TO_MBUS_INTREG_WIN)
  40700. + {
  40701. + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
  40702. + }
  40703. + else
  40704. + {
  40705. + decRegs.baseReg = MV_REG_READ(AHB_TO_MBUS_WIN_INTEREG_REG);
  40706. + }
  40707. +
  40708. +
  40709. +
  40710. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  40711. + {
  40712. + mvOsPrintf("mvAhbToMbusWinGet: mvCtrlRegToAddrDec Failed \n");
  40713. + return MV_ERROR;
  40714. + }
  40715. +
  40716. + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
  40717. + {
  40718. + pAddrDecWin->addrWin.size = INTER_REGS_SIZE;
  40719. + pAddrDecWin->target = INTER_REGS;
  40720. + pAddrDecWin->enable = MV_TRUE;
  40721. +
  40722. + return MV_OK;
  40723. + }
  40724. +
  40725. +
  40726. + if (decRegs.sizeReg & ATMWCR_WIN_ENABLE)
  40727. + {
  40728. + pAddrDecWin->enable = MV_TRUE;
  40729. + }
  40730. + else
  40731. + {
  40732. + pAddrDecWin->enable = MV_FALSE;
  40733. +
  40734. + }
  40735. +
  40736. +
  40737. +
  40738. + if (-1 == pAddrDecWin->addrWin.size)
  40739. + {
  40740. + return MV_ERROR;
  40741. + }
  40742. +
  40743. + /* attrib and targetId */
  40744. + targetAttrib.attrib = (decRegs.sizeReg & ATMWCR_WIN_ATTR_MASK) >>
  40745. + ATMWCR_WIN_ATTR_OFFS;
  40746. + targetAttrib.targetId = (decRegs.sizeReg & ATMWCR_WIN_TARGET_MASK) >>
  40747. + ATMWCR_WIN_TARGET_OFFS;
  40748. +
  40749. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  40750. +
  40751. + return MV_OK;
  40752. +}
  40753. +
  40754. +/*******************************************************************************
  40755. +* mvAhbToMbusWinTargetGet - Get Window number associated with target
  40756. +*
  40757. +* DESCRIPTION:
  40758. +*
  40759. +* INPUT:
  40760. +*
  40761. +* OUTPUT:
  40762. +*
  40763. +* RETURN:
  40764. +*
  40765. +*******************************************************************************/
  40766. +MV_U32 mvAhbToMbusWinTargetGet(MV_TARGET target)
  40767. +{
  40768. + MV_AHB_TO_MBUS_DEC_WIN decWin;
  40769. + MV_U32 winNum;
  40770. +
  40771. + /* Check parameters */
  40772. + if (target >= MAX_TARGETS)
  40773. + {
  40774. + mvOsPrintf("mvAhbToMbusWinTargetGet: target %d is Illigal\n", target);
  40775. + return 0xffffffff;
  40776. + }
  40777. +
  40778. + if (INTER_REGS == target)
  40779. + {
  40780. + return MV_AHB_TO_MBUS_INTREG_WIN;
  40781. + }
  40782. +
  40783. + for (winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS ; winNum++)
  40784. + {
  40785. + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
  40786. + continue;
  40787. +
  40788. + if (mvAhbToMbusWinGet(winNum,&decWin) != MV_OK)
  40789. + {
  40790. + mvOsPrintf("mvAhbToMbusWinTargetGet: mvAhbToMbusWinGet fail\n");
  40791. + return 0xffffffff;
  40792. +
  40793. + }
  40794. +
  40795. + if (decWin.enable == MV_TRUE)
  40796. + {
  40797. + if (decWin.target == target)
  40798. + {
  40799. + return winNum;
  40800. + }
  40801. +
  40802. + }
  40803. +
  40804. + }
  40805. +
  40806. + return 0xFFFFFFFF;
  40807. +
  40808. +
  40809. +}
  40810. +
  40811. +/*******************************************************************************
  40812. +* mvAhbToMbusWinAvailGet - Get First Available window number.
  40813. +*
  40814. +* DESCRIPTION:
  40815. +*
  40816. +* INPUT:
  40817. +*
  40818. +* OUTPUT:
  40819. +*
  40820. +* RETURN:
  40821. +*
  40822. +*******************************************************************************/
  40823. +MV_U32 mvAhbToMbusWinAvailGet(MV_VOID)
  40824. +{
  40825. + MV_AHB_TO_MBUS_DEC_WIN decWin;
  40826. + MV_U32 winNum;
  40827. +
  40828. + for (winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS ; winNum++)
  40829. + {
  40830. + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
  40831. + continue;
  40832. +
  40833. + if (mvAhbToMbusWinGet(winNum,&decWin) != MV_OK)
  40834. + {
  40835. + mvOsPrintf("mvAhbToMbusWinTargetGet: mvAhbToMbusWinGet fail\n");
  40836. + return 0xffffffff;
  40837. +
  40838. + }
  40839. +
  40840. + if (decWin.enable == MV_FALSE)
  40841. + {
  40842. + return winNum;
  40843. + }
  40844. +
  40845. + }
  40846. +
  40847. + return 0xFFFFFFFF;
  40848. +}
  40849. +
  40850. +
  40851. +/*******************************************************************************
  40852. +* mvAhbToMbusWinEnable - Enable/disable a CPU address decode window
  40853. +*
  40854. +* DESCRIPTION:
  40855. +* This function enable/disable a CPU address decode window.
  40856. +* if parameter 'enable' == MV_TRUE the routine will enable the
  40857. +* window, thus enabling CPU accesses (before enabling the window it is
  40858. +* tested for overlapping). Otherwise, the window will be disabled.
  40859. +*
  40860. +* INPUT:
  40861. +* winNum - Peripheral winNum enumerator.
  40862. +* enable - Enable/disable parameter.
  40863. +*
  40864. +* OUTPUT:
  40865. +* N/A
  40866. +*
  40867. +* RETURN:
  40868. +* MV_ERROR if protection window number was wrong, or the window
  40869. +* overlapps other winNum window.
  40870. +*
  40871. +*******************************************************************************/
  40872. +MV_STATUS mvAhbToMbusWinEnable(MV_U32 winNum, MV_BOOL enable)
  40873. +{
  40874. +
  40875. + /* Parameter checking */
  40876. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  40877. + {
  40878. + mvOsPrintf("mvAhbToMbusWinEnable: ERR. Invalid winNum %d\n", winNum);
  40879. + return MV_NOT_SUPPORTED;
  40880. + }
  40881. +
  40882. + /* Internal registers bar can't be disable or enabled */
  40883. + if (winNum == MV_AHB_TO_MBUS_INTREG_WIN)
  40884. + {
  40885. + return (enable ? MV_OK : MV_ERROR);
  40886. + }
  40887. +
  40888. + if (enable == MV_TRUE)
  40889. + {
  40890. + /* enable the window */
  40891. + MV_REG_BIT_SET(AHB_TO_MBUS_WIN_CTRL_REG(winNum), ATMWCR_WIN_ENABLE);
  40892. + }
  40893. + else
  40894. + { /* Disable address decode winNum window */
  40895. + MV_REG_BIT_RESET(AHB_TO_MBUS_WIN_CTRL_REG(winNum), ATMWCR_WIN_ENABLE);
  40896. + }
  40897. +
  40898. + return MV_OK;
  40899. +}
  40900. +
  40901. +
  40902. +/*******************************************************************************
  40903. +* mvAhbToMbusWinRemap - Set CPU remap register for address windows.
  40904. +*
  40905. +* DESCRIPTION:
  40906. +* After a CPU address hits one of PCI address decode windows there is an
  40907. +* option to remap the address to a different one. For example, CPU
  40908. +* executes a read from PCI winNum window address 0x1200.0000. This
  40909. +* can be modified so the address on the PCI bus would be 0x1400.0000
  40910. +* Using the PCI address remap mechanism.
  40911. +*
  40912. +* INPUT:
  40913. +* winNum - Peripheral winNum enumerator. Must be a PCI winNum.
  40914. +* pAddrDecWin - CPU winNum window information data structure.
  40915. +* Note that caller has to fill in the base field only. The
  40916. +* size field is ignored.
  40917. +*
  40918. +* OUTPUT:
  40919. +* None.
  40920. +*
  40921. +* RETURN:
  40922. +* MV_ERROR if winNum is not a PCI one, MV_OK otherwise.
  40923. +*
  40924. +*******************************************************************************/
  40925. +MV_U32 mvAhbToMbusWinRemap(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  40926. +{
  40927. + MV_U32 baseAddr;
  40928. + AHB_TO_MBUS_REMAP_REG_OFFS remapRegOffs;
  40929. +
  40930. + MV_U32 effectiveBaseAddress=0,
  40931. + baseAddrValue=0,windowSizeValue=0;
  40932. +
  40933. +
  40934. + /* Get registers offsets of given winNum */
  40935. + if (MV_NO_SUCH == ahbToMbusRemapRegOffsGet(winNum, &remapRegOffs))
  40936. + {
  40937. + return 0xffffffff;
  40938. + }
  40939. +
  40940. + /* 1) Set address remap low */
  40941. + baseAddr = pAddrWin->baseLow;
  40942. +
  40943. + /* Check base address aligment */
  40944. + /*
  40945. + if (MV_IS_NOT_ALIGN(baseAddr, ATMWRLR_REMAP_LOW_ALIGNMENT))
  40946. + {
  40947. + mvOsPrintf("mvAhbToMbusPciRemap: Warning. Target base 0x%x unaligned\n",
  40948. + baseAddr);
  40949. + return MV_ERROR;
  40950. + }
  40951. + */
  40952. +
  40953. + /* BaseLow[31:16] => base register [31:16] */
  40954. + baseAddr = baseAddr & ATMWRLR_REMAP_LOW_MASK;
  40955. +
  40956. + MV_REG_WRITE(remapRegOffs.lowRegOffs, baseAddr);
  40957. +
  40958. + MV_REG_WRITE(remapRegOffs.highRegOffs, pAddrWin->baseHigh);
  40959. +
  40960. +
  40961. + baseAddrValue = MV_REG_READ(AHB_TO_MBUS_WIN_BASE_REG(winNum));
  40962. + windowSizeValue = MV_REG_READ(AHB_TO_MBUS_WIN_CTRL_REG(winNum));
  40963. +
  40964. + baseAddrValue &= ATMWBR_BASE_MASK;
  40965. + windowSizeValue &=ATMWCR_WIN_SIZE_MASK;
  40966. +
  40967. + /* Start calculating the effective Base Address */
  40968. + effectiveBaseAddress = baseAddrValue ;
  40969. +
  40970. + /* The effective base address will be combined from the chopped (if any)
  40971. + remap value (according to the size value and remap mechanism) and the
  40972. + window's base address */
  40973. + effectiveBaseAddress |= (((windowSizeValue) | 0xffff) & pAddrWin->baseLow);
  40974. + /* If the effectiveBaseAddress exceed the window boundaries return an
  40975. + invalid value. */
  40976. +
  40977. + if (effectiveBaseAddress > (baseAddrValue + (windowSizeValue | 0xffff)))
  40978. + {
  40979. + mvOsPrintf("mvAhbToMbusPciRemap: Error\n");
  40980. + return 0xffffffff;
  40981. + }
  40982. +
  40983. + return effectiveBaseAddress;
  40984. +
  40985. +
  40986. +}
  40987. +/*******************************************************************************
  40988. +* mvAhbToMbusWinTargetSwap - Swap AhbToMbus windows between targets
  40989. +*
  40990. +* DESCRIPTION:
  40991. +*
  40992. +* INPUT:
  40993. +* target1 - CPU Interface target 1
  40994. +* target2 - CPU Interface target 2
  40995. +*
  40996. +* OUTPUT:
  40997. +* None.
  40998. +*
  40999. +* RETURN:
  41000. +* MV_ERROR if targets are illigal, or if one of the targets is not
  41001. +* associated to a valid window .
  41002. +* MV_OK otherwise.
  41003. +*
  41004. +*******************************************************************************/
  41005. +
  41006. +
  41007. +MV_STATUS mvAhbToMbusWinTargetSwap(MV_TARGET target1,MV_TARGET target2)
  41008. +{
  41009. + MV_U32 winNum1,winNum2;
  41010. + MV_AHB_TO_MBUS_DEC_WIN winDec1,winDec2,winDecTemp;
  41011. + AHB_TO_MBUS_REMAP_REG_OFFS remapRegs1,remapRegs2;
  41012. + MV_U32 remapBaseLow1=0,remapBaseLow2=0;
  41013. + MV_U32 remapBaseHigh1=0,remapBaseHigh2=0;
  41014. +
  41015. +
  41016. + /* Check parameters */
  41017. + if (target1 >= MAX_TARGETS)
  41018. + {
  41019. + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d is Illigal\n", target1);
  41020. + return MV_ERROR;
  41021. + }
  41022. +
  41023. + if (target2 >= MAX_TARGETS)
  41024. + {
  41025. + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d is Illigal\n", target1);
  41026. + return MV_ERROR;
  41027. + }
  41028. +
  41029. +
  41030. + /* get window associated with this target */
  41031. + winNum1 = mvAhbToMbusWinTargetGet(target1);
  41032. +
  41033. + if (winNum1 == 0xffffffff)
  41034. + {
  41035. + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d has illigal win %d\n",
  41036. + target1,winNum1);
  41037. + return MV_ERROR;
  41038. +
  41039. + }
  41040. +
  41041. + /* get window associated with this target */
  41042. + winNum2 = mvAhbToMbusWinTargetGet(target2);
  41043. +
  41044. + if (winNum2 == 0xffffffff)
  41045. + {
  41046. + mvOsPrintf("mvAhbToMbusWinTargetSwap: target %d has illigal win %d\n",
  41047. + target2,winNum2);
  41048. + return MV_ERROR;
  41049. +
  41050. + }
  41051. +
  41052. + /* now Get original values of both Windows */
  41053. + if (MV_OK != mvAhbToMbusWinGet(winNum1,&winDec1))
  41054. + {
  41055. + mvOsPrintf("mvAhbToMbusWinTargetSwap: mvAhbToMbusWinGet failed win %d\n",
  41056. + winNum1);
  41057. + return MV_ERROR;
  41058. +
  41059. + }
  41060. + if (MV_OK != mvAhbToMbusWinGet(winNum2,&winDec2))
  41061. + {
  41062. + mvOsPrintf("mvAhbToMbusWinTargetSwap: mvAhbToMbusWinGet failed win %d\n",
  41063. + winNum2);
  41064. + return MV_ERROR;
  41065. +
  41066. + }
  41067. +
  41068. +
  41069. + /* disable both windows */
  41070. + if (MV_OK != mvAhbToMbusWinEnable(winNum1,MV_FALSE))
  41071. + {
  41072. + mvOsPrintf("mvAhbToMbusWinTargetSwap: failed to enable window %d\n",
  41073. + winNum1);
  41074. + return MV_ERROR;
  41075. +
  41076. + }
  41077. + if (MV_OK != mvAhbToMbusWinEnable(winNum2,MV_FALSE))
  41078. + {
  41079. + mvOsPrintf("mvAhbToMbusWinTargetSwap: failed to enable windo %d\n",
  41080. + winNum2);
  41081. + return MV_ERROR;
  41082. +
  41083. + }
  41084. +
  41085. +
  41086. + /* now swap targets */
  41087. +
  41088. + /* first save winDec2 values */
  41089. + winDecTemp.addrWin.baseHigh = winDec2.addrWin.baseHigh;
  41090. + winDecTemp.addrWin.baseLow = winDec2.addrWin.baseLow;
  41091. + winDecTemp.addrWin.size = winDec2.addrWin.size;
  41092. + winDecTemp.enable = winDec2.enable;
  41093. + winDecTemp.target = winDec2.target;
  41094. +
  41095. + /* winDec2 = winDec1 */
  41096. + winDec2.addrWin.baseHigh = winDec1.addrWin.baseHigh;
  41097. + winDec2.addrWin.baseLow = winDec1.addrWin.baseLow;
  41098. + winDec2.addrWin.size = winDec1.addrWin.size;
  41099. + winDec2.enable = winDec1.enable;
  41100. + winDec2.target = winDec1.target;
  41101. +
  41102. +
  41103. + /* winDec1 = winDecTemp */
  41104. + winDec1.addrWin.baseHigh = winDecTemp.addrWin.baseHigh;
  41105. + winDec1.addrWin.baseLow = winDecTemp.addrWin.baseLow;
  41106. + winDec1.addrWin.size = winDecTemp.addrWin.size;
  41107. + winDec1.enable = winDecTemp.enable;
  41108. + winDec1.target = winDecTemp.target;
  41109. +
  41110. +
  41111. + /* now set the new values */
  41112. +
  41113. +
  41114. + mvAhbToMbusWinSet(winNum1,&winDec1);
  41115. + mvAhbToMbusWinSet(winNum2,&winDec2);
  41116. +
  41117. +
  41118. +
  41119. +
  41120. +
  41121. + /* now we will treat the remap windows if exist */
  41122. +
  41123. +
  41124. + /* now check if one or both windows has a remap window
  41125. + as well after the swap ! */
  41126. +
  41127. + /* if a window had a remap value differnt than the base value
  41128. + before the swap , then after the swap the remap value will be
  41129. + equal to the base value unless both windows has a remap windows*/
  41130. +
  41131. + /* first get old values */
  41132. + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum1,&remapRegs1))
  41133. + {
  41134. + remapBaseLow1 = MV_REG_READ(remapRegs1.lowRegOffs);
  41135. + remapBaseHigh1 = MV_REG_READ(remapRegs1.highRegOffs);
  41136. +
  41137. + }
  41138. + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))
  41139. + {
  41140. + remapBaseLow2 = MV_REG_READ(remapRegs2.lowRegOffs);
  41141. + remapBaseHigh2 = MV_REG_READ(remapRegs2.highRegOffs);
  41142. +
  41143. +
  41144. + }
  41145. +
  41146. + /* now do the swap */
  41147. + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum1,&remapRegs1))
  41148. + {
  41149. + if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))
  41150. + {
  41151. + /* Two windows has a remap !!! so swap */
  41152. +
  41153. + MV_REG_WRITE(remapRegs2.highRegOffs,remapBaseHigh1);
  41154. + MV_REG_WRITE(remapRegs2.lowRegOffs,remapBaseLow1);
  41155. +
  41156. + MV_REG_WRITE(remapRegs1.highRegOffs,remapBaseHigh2);
  41157. + MV_REG_WRITE(remapRegs1.lowRegOffs,remapBaseLow2);
  41158. +
  41159. +
  41160. +
  41161. + }
  41162. + else
  41163. + {
  41164. + /* remap == base */
  41165. + MV_REG_WRITE(remapRegs1.highRegOffs,winDec1.addrWin.baseHigh);
  41166. + MV_REG_WRITE(remapRegs1.lowRegOffs,winDec1.addrWin.baseLow);
  41167. +
  41168. + }
  41169. +
  41170. + }
  41171. + else if (MV_NO_SUCH != ahbToMbusRemapRegOffsGet(winNum2,&remapRegs2))
  41172. + {
  41173. + /* remap == base */
  41174. + MV_REG_WRITE(remapRegs2.highRegOffs,winDec2.addrWin.baseHigh);
  41175. + MV_REG_WRITE(remapRegs2.lowRegOffs,winDec2.addrWin.baseLow);
  41176. +
  41177. + }
  41178. +
  41179. +
  41180. +
  41181. + return MV_OK;
  41182. +
  41183. +
  41184. +}
  41185. +
  41186. +
  41187. +
  41188. +#if defined(MV_88F1181)
  41189. +
  41190. +/*******************************************************************************
  41191. +* mvAhbToMbusXbarCtrlSet - Set The CPU master Xbar arbitration.
  41192. +*
  41193. +* DESCRIPTION:
  41194. +* This function sets CPU Mbus Arbiter
  41195. +*
  41196. +* INPUT:
  41197. +* pPizzaArbArray - A priority Structure describing 16 "pizza slices". At
  41198. +* each clock cycle, the crossbar arbiter samples all
  41199. +* requests and gives the bus to the next agent according
  41200. +* to the "pizza".
  41201. +*
  41202. +* OUTPUT:
  41203. +* N/A
  41204. +*
  41205. +* RETURN:
  41206. +* MV_ERROR if paramers to function invalid.
  41207. +*
  41208. +*******************************************************************************/
  41209. +MV_STATUS mvMbusArbSet(MV_MBUS_ARB_TARGET *pPizzaArbArray)
  41210. +{
  41211. + MV_U32 sliceNum;
  41212. + MV_U32 xbarCtrl = 0;
  41213. + MV_MBUS_ARB_TARGET xbarTarget;
  41214. +
  41215. + /* 1) Set crossbar control low register */
  41216. + for (sliceNum = 0; sliceNum < MRLR_SLICE_NUM; sliceNum++)
  41217. + {
  41218. + xbarTarget = pPizzaArbArray[sliceNum];
  41219. +
  41220. + /* sliceNum parameter check */
  41221. + if (xbarTarget > MAX_MBUS_ARB_TARGETS)
  41222. + {
  41223. + mvOsPrintf("mvAhbToMbusXbarCtrlSet: ERR. Can't set Target %d\n",
  41224. + xbarTarget);
  41225. + return MV_ERROR;
  41226. + }
  41227. + xbarCtrl |= (xbarTarget << MRLR_LOW_ARB_OFFS(sliceNum));
  41228. + }
  41229. + /* Write to crossbar control low register */
  41230. + MV_REG_WRITE(MBUS_ARBITER_LOW_REG, xbarCtrl);
  41231. +
  41232. + xbarCtrl = 0;
  41233. +
  41234. + /* 2) Set crossbar control high register */
  41235. + for (sliceNum = MRLR_SLICE_NUM;
  41236. + sliceNum < MRLR_SLICE_NUM+MRHR_SLICE_NUM;
  41237. + sliceNum++)
  41238. + {
  41239. +
  41240. + xbarTarget = pPizzaArbArray[sliceNum];
  41241. +
  41242. + /* sliceNum parameter check */
  41243. + if (xbarTarget > MAX_MBUS_ARB_TARGETS)
  41244. + {
  41245. + mvOsPrintf("mvAhbToMbusXbarCtrlSet: ERR. Can't set Target %d\n",
  41246. + xbarTarget);
  41247. + return MV_ERROR;
  41248. + }
  41249. + xbarCtrl |= (xbarTarget << MRHR_HIGH_ARB_OFFS(sliceNum));
  41250. + }
  41251. + /* Write to crossbar control high register */
  41252. + MV_REG_WRITE(MBUS_ARBITER_HIGH_REG, xbarCtrl);
  41253. +
  41254. + return MV_OK;
  41255. +}
  41256. +
  41257. +/*******************************************************************************
  41258. +* mvMbusArbCtrlSet - Set MBus Arbiter control register
  41259. +*
  41260. +* DESCRIPTION:
  41261. +*
  41262. +* INPUT:
  41263. +* ctrl - pointer to MV_MBUS_ARB_CTRL register
  41264. +*
  41265. +* OUTPUT:
  41266. +* N/A
  41267. +*
  41268. +* RETURN:
  41269. +* MV_ERROR if paramers to function invalid.
  41270. +*
  41271. +*******************************************************************************/
  41272. +MV_STATUS mvMbusArbCtrlSet(MV_MBUS_ARB_CTRL *ctrl)
  41273. +{
  41274. +
  41275. + if (ctrl->highPrio == MV_FALSE)
  41276. + {
  41277. + MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_ARM_TOP);
  41278. + }
  41279. + else
  41280. + {
  41281. + MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_ARM_TOP);
  41282. + }
  41283. +
  41284. + if (ctrl->fixedRoundRobin == MV_FALSE)
  41285. + {
  41286. + MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_TARGET_FIXED);
  41287. + }
  41288. + else
  41289. + {
  41290. + MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_TARGET_FIXED);
  41291. + }
  41292. +
  41293. + if (ctrl->starvEn == MV_FALSE)
  41294. + {
  41295. + MV_REG_BIT_RESET(MBUS_ARBITER_CTRL_REG, MACR_ARB_REQ_CTRL_EN);
  41296. + }
  41297. + else
  41298. + {
  41299. + MV_REG_BIT_SET(MBUS_ARBITER_CTRL_REG, MACR_ARB_REQ_CTRL_EN);
  41300. + }
  41301. +
  41302. + return MV_OK;
  41303. +}
  41304. +
  41305. +/*******************************************************************************
  41306. +* mvMbusArbCtrlGet - Get MBus Arbiter control register
  41307. +*
  41308. +* DESCRIPTION:
  41309. +*
  41310. +* INPUT:
  41311. +* ctrl - pointer to MV_MBUS_ARB_CTRL register
  41312. +*
  41313. +* OUTPUT:
  41314. +* ctrl - pointer to MV_MBUS_ARB_CTRL register
  41315. +*
  41316. +* RETURN:
  41317. +* MV_ERROR if paramers to function invalid.
  41318. +*
  41319. +*******************************************************************************/
  41320. +MV_STATUS mvMbusArbCtrlGet(MV_MBUS_ARB_CTRL *ctrl)
  41321. +{
  41322. +
  41323. + MV_U32 ctrlReg = MV_REG_READ(MBUS_ARBITER_CTRL_REG);
  41324. +
  41325. + if (ctrlReg & MACR_ARB_ARM_TOP)
  41326. + {
  41327. + ctrl->highPrio = MV_TRUE;
  41328. + }
  41329. + else
  41330. + {
  41331. + ctrl->highPrio = MV_FALSE;
  41332. + }
  41333. +
  41334. + if (ctrlReg & MACR_ARB_TARGET_FIXED)
  41335. + {
  41336. + ctrl->fixedRoundRobin = MV_TRUE;
  41337. + }
  41338. + else
  41339. + {
  41340. + ctrl->fixedRoundRobin = MV_FALSE;
  41341. + }
  41342. +
  41343. + if (ctrlReg & MACR_ARB_REQ_CTRL_EN)
  41344. + {
  41345. + ctrl->starvEn = MV_TRUE;
  41346. + }
  41347. + else
  41348. + {
  41349. + ctrl->starvEn = MV_FALSE;
  41350. + }
  41351. +
  41352. +
  41353. + return MV_OK;
  41354. +}
  41355. +
  41356. +#endif /* #if defined(MV_88F1181) */
  41357. +
  41358. +
  41359. +
  41360. +/*******************************************************************************
  41361. +* ahbToMbusRemapRegOffsGet - Get CPU address remap register offsets
  41362. +*
  41363. +* DESCRIPTION:
  41364. +* CPU to PCI address remap registers offsets are inconsecutive.
  41365. +* This function returns PCI address remap registers offsets.
  41366. +*
  41367. +* INPUT:
  41368. +* winNum - Address decode window number. See MV_U32 enumerator.
  41369. +*
  41370. +* OUTPUT:
  41371. +* None.
  41372. +*
  41373. +* RETURN:
  41374. +* MV_ERROR if winNum is not a PCI one.
  41375. +*
  41376. +*******************************************************************************/
  41377. +static MV_STATUS ahbToMbusRemapRegOffsGet(MV_U32 winNum,
  41378. + AHB_TO_MBUS_REMAP_REG_OFFS *pRemapRegs)
  41379. +{
  41380. + switch (winNum)
  41381. + {
  41382. + case 0:
  41383. + case 1:
  41384. + pRemapRegs->lowRegOffs = AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum);
  41385. + pRemapRegs->highRegOffs = AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum);
  41386. + break;
  41387. + case 2:
  41388. + case 3:
  41389. + if((mvCtrlModelGet() == MV_5281_DEV_ID) ||
  41390. + (mvCtrlModelGet() == MV_1281_DEV_ID) ||
  41391. + (mvCtrlModelGet() == MV_6183_DEV_ID) ||
  41392. + (mvCtrlModelGet() == MV_6183L_DEV_ID))
  41393. + {
  41394. + pRemapRegs->lowRegOffs = AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum);
  41395. + pRemapRegs->highRegOffs = AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum);
  41396. + break;
  41397. + }
  41398. + else
  41399. + {
  41400. + pRemapRegs->lowRegOffs = 0;
  41401. + pRemapRegs->highRegOffs = 0;
  41402. +
  41403. + DB(mvOsPrintf("ahbToMbusRemapRegOffsGet: ERR. Invalid winNum %d\n",
  41404. + winNum));
  41405. + return MV_NO_SUCH;
  41406. + }
  41407. + default:
  41408. + {
  41409. + pRemapRegs->lowRegOffs = 0;
  41410. + pRemapRegs->highRegOffs = 0;
  41411. +
  41412. + DB(mvOsPrintf("ahbToMbusRemapRegOffsGet: ERR. Invalid winNum %d\n",
  41413. + winNum));
  41414. + return MV_NO_SUCH;
  41415. + }
  41416. + }
  41417. +
  41418. + return MV_OK;
  41419. +}
  41420. +
  41421. +/*******************************************************************************
  41422. +* mvAhbToMbusAddDecShow - Print the AHB to MBus bridge address decode map.
  41423. +*
  41424. +* DESCRIPTION:
  41425. +* This function print the CPU address decode map.
  41426. +*
  41427. +* INPUT:
  41428. +* None.
  41429. +*
  41430. +* OUTPUT:
  41431. +* None.
  41432. +*
  41433. +* RETURN:
  41434. +* None.
  41435. +*
  41436. +*******************************************************************************/
  41437. +MV_VOID mvAhbToMbusAddDecShow(MV_VOID)
  41438. +{
  41439. + MV_AHB_TO_MBUS_DEC_WIN win;
  41440. + MV_U32 winNum;
  41441. + mvOsOutput( "\n" );
  41442. + mvOsOutput( "AHB To MBUS Bridge:\n" );
  41443. + mvOsOutput( "-------------------\n" );
  41444. +
  41445. + for( winNum = 0; winNum < MAX_AHB_TO_MBUS_WINS; winNum++ )
  41446. + {
  41447. + memset( &win, 0, sizeof(MV_AHB_TO_MBUS_DEC_WIN) );
  41448. +
  41449. + mvOsOutput( "win%d - ", winNum );
  41450. +
  41451. + if( mvAhbToMbusWinGet( winNum, &win ) == MV_OK )
  41452. + {
  41453. + if( win.enable )
  41454. + {
  41455. + mvOsOutput( "%s base %08x, ",
  41456. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  41457. + mvOsOutput( "...." );
  41458. + mvSizePrint( win.addrWin.size );
  41459. +
  41460. + mvOsOutput( "\n" );
  41461. +
  41462. + }
  41463. + else
  41464. + mvOsOutput( "disable\n" );
  41465. + }
  41466. + }
  41467. +
  41468. +}
  41469. +
  41470. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h
  41471. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h 1970-01-01 01:00:00.000000000 +0100
  41472. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbus.h 2011-08-01 14:38:19.000000000 +0200
  41473. @@ -0,0 +1,130 @@
  41474. +/*******************************************************************************
  41475. +Copyright (C) Marvell International Ltd. and its affiliates
  41476. +
  41477. +This software file (the "File") is owned and distributed by Marvell
  41478. +International Ltd. and/or its affiliates ("Marvell") under the following
  41479. +alternative licensing terms. Once you have made an election to distribute the
  41480. +File under one of the following license alternatives, please (i) delete this
  41481. +introductory statement regarding license alternatives, (ii) delete the two
  41482. +license alternatives that you have not elected to use and (iii) preserve the
  41483. +Marvell copyright notice above.
  41484. +
  41485. +********************************************************************************
  41486. +Marvell Commercial License Option
  41487. +
  41488. +If you received this File from Marvell and you have entered into a commercial
  41489. +license agreement (a "Commercial License") with Marvell, the File is licensed
  41490. +to you under the terms of the applicable Commercial License.
  41491. +
  41492. +********************************************************************************
  41493. +Marvell GPL License Option
  41494. +
  41495. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41496. +modify this File in accordance with the terms and conditions of the General
  41497. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  41498. +available along with the File in the license.txt file or by writing to the Free
  41499. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  41500. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  41501. +
  41502. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  41503. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  41504. +DISCLAIMED. The GPL License provides additional details about this warranty
  41505. +disclaimer.
  41506. +********************************************************************************
  41507. +Marvell BSD License Option
  41508. +
  41509. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41510. +modify this File under the following licensing terms.
  41511. +Redistribution and use in source and binary forms, with or without modification,
  41512. +are permitted provided that the following conditions are met:
  41513. +
  41514. + * Redistributions of source code must retain the above copyright notice,
  41515. + this list of conditions and the following disclaimer.
  41516. +
  41517. + * Redistributions in binary form must reproduce the above copyright
  41518. + notice, this list of conditions and the following disclaimer in the
  41519. + documentation and/or other materials provided with the distribution.
  41520. +
  41521. + * Neither the name of Marvell nor the names of its contributors may be
  41522. + used to endorse or promote products derived from this software without
  41523. + specific prior written permission.
  41524. +
  41525. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  41526. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  41527. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  41528. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  41529. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  41530. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  41531. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  41532. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  41533. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  41534. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  41535. +
  41536. +*******************************************************************************/
  41537. +
  41538. +
  41539. +#ifndef __INCmvAhbToMbush
  41540. +#define __INCmvAhbToMbush
  41541. +
  41542. +/* includes */
  41543. +#include "ctrlEnv/mvCtrlEnvLib.h"
  41544. +#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
  41545. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  41546. +
  41547. +/* defines */
  41548. +
  41549. +#if defined(MV_88F1181)
  41550. +/* This enumerator defines the Marvell controller possible MBUS arbiter */
  41551. +/* target ports. It is used to define crossbar priority scheame (pizza) */
  41552. +typedef enum _mvMBusArbTargetId
  41553. +{
  41554. + DRAM_MBUS_ARB_TARGET = 0, /* Port 0 -> DRAM interface */
  41555. + TWSI_MBUS_ARB_TARGET = 1, /* Port 1 -> TWSI */
  41556. + ARM_MBUS_ARB_TARGET = 2, /* Port 2 -> ARM */
  41557. + PEX1_MBUS_ARB_TARGET = 3, /* Port 3 -> PCI Express 1 */
  41558. + PEX0_MBUS_ARB_TARGET = 4, /* Port 4 -> PCI Express0 */
  41559. + MAX_MBUS_ARB_TARGETS
  41560. +}MV_MBUS_ARB_TARGET;
  41561. +
  41562. +typedef struct _mvMBusArbCtrl
  41563. +{
  41564. + MV_BOOL starvEn;
  41565. + MV_BOOL highPrio;
  41566. + MV_BOOL fixedRoundRobin;
  41567. +
  41568. +}MV_MBUS_ARB_CTRL;
  41569. +
  41570. +#endif /* #if defined(MV_88F1181) */
  41571. +
  41572. +typedef struct _mvAhbtoMbusDecWin
  41573. +{
  41574. + MV_TARGET target;
  41575. + MV_ADDR_WIN addrWin; /* An address window*/
  41576. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  41577. +
  41578. +}MV_AHB_TO_MBUS_DEC_WIN;
  41579. +
  41580. +/* mvAhbToMbus.h API list */
  41581. +
  41582. +MV_STATUS mvAhbToMbusInit(MV_VOID);
  41583. +MV_STATUS mvAhbToMbusWinSet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin);
  41584. +MV_STATUS mvAhbToMbusWinGet(MV_U32 winNum, MV_AHB_TO_MBUS_DEC_WIN *pAddrDecWin);
  41585. +MV_STATUS mvAhbToMbusWinEnable(MV_U32 winNum,MV_BOOL enable);
  41586. +MV_U32 mvAhbToMbusWinRemap(MV_U32 winNum, MV_ADDR_WIN *pAddrDecWin);
  41587. +MV_U32 mvAhbToMbusWinTargetGet(MV_TARGET target);
  41588. +MV_U32 mvAhbToMbusWinAvailGet(MV_VOID);
  41589. +MV_STATUS mvAhbToMbusWinTargetSwap(MV_TARGET target1,MV_TARGET target2);
  41590. +
  41591. +#if defined(MV_88F1181)
  41592. +
  41593. +MV_STATUS mvMbusArbSet(MV_MBUS_ARB_TARGET *pPizzaArbArray);
  41594. +MV_STATUS mvMbusArbCtrlSet(MV_MBUS_ARB_CTRL *ctrl);
  41595. +MV_STATUS mvMbusArbCtrlGet(MV_MBUS_ARB_CTRL *ctrl);
  41596. +
  41597. +#endif /* #if defined(MV_88F1181) */
  41598. +
  41599. +
  41600. +MV_VOID mvAhbToMbusAddDecShow(MV_VOID);
  41601. +
  41602. +
  41603. +#endif /* __INCmvAhbToMbush */
  41604. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h
  41605. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h 1970-01-01 01:00:00.000000000 +0100
  41606. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvAhbToMbusRegs.h 2011-08-01 14:38:19.000000000 +0200
  41607. @@ -0,0 +1,143 @@
  41608. +/*******************************************************************************
  41609. +Copyright (C) Marvell International Ltd. and its affiliates
  41610. +
  41611. +This software file (the "File") is owned and distributed by Marvell
  41612. +International Ltd. and/or its affiliates ("Marvell") under the following
  41613. +alternative licensing terms. Once you have made an election to distribute the
  41614. +File under one of the following license alternatives, please (i) delete this
  41615. +introductory statement regarding license alternatives, (ii) delete the two
  41616. +license alternatives that you have not elected to use and (iii) preserve the
  41617. +Marvell copyright notice above.
  41618. +
  41619. +********************************************************************************
  41620. +Marvell Commercial License Option
  41621. +
  41622. +If you received this File from Marvell and you have entered into a commercial
  41623. +license agreement (a "Commercial License") with Marvell, the File is licensed
  41624. +to you under the terms of the applicable Commercial License.
  41625. +
  41626. +********************************************************************************
  41627. +Marvell GPL License Option
  41628. +
  41629. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41630. +modify this File in accordance with the terms and conditions of the General
  41631. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  41632. +available along with the File in the license.txt file or by writing to the Free
  41633. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  41634. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  41635. +
  41636. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  41637. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  41638. +DISCLAIMED. The GPL License provides additional details about this warranty
  41639. +disclaimer.
  41640. +********************************************************************************
  41641. +Marvell BSD License Option
  41642. +
  41643. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41644. +modify this File under the following licensing terms.
  41645. +Redistribution and use in source and binary forms, with or without modification,
  41646. +are permitted provided that the following conditions are met:
  41647. +
  41648. + * Redistributions of source code must retain the above copyright notice,
  41649. + this list of conditions and the following disclaimer.
  41650. +
  41651. + * Redistributions in binary form must reproduce the above copyright
  41652. + notice, this list of conditions and the following disclaimer in the
  41653. + documentation and/or other materials provided with the distribution.
  41654. +
  41655. + * Neither the name of Marvell nor the names of its contributors may be
  41656. + used to endorse or promote products derived from this software without
  41657. + specific prior written permission.
  41658. +
  41659. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  41660. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  41661. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  41662. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  41663. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  41664. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  41665. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  41666. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  41667. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  41668. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  41669. +
  41670. +*******************************************************************************/
  41671. +
  41672. +
  41673. +#ifndef __INCmvAhbToMbusRegsh
  41674. +#define __INCmvAhbToMbusRegsh
  41675. +
  41676. +/******************************/
  41677. +/* ARM Address Map Registers */
  41678. +/******************************/
  41679. +
  41680. +#define MAX_AHB_TO_MBUS_WINS 9
  41681. +#define MV_AHB_TO_MBUS_INTREG_WIN 8
  41682. +
  41683. +
  41684. +#define AHB_TO_MBUS_WIN_CTRL_REG(winNum) (0x20000 + (winNum)*0x10)
  41685. +#define AHB_TO_MBUS_WIN_BASE_REG(winNum) (0x20004 + (winNum)*0x10)
  41686. +#define AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum) (0x20008 + (winNum)*0x10)
  41687. +#define AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum) (0x2000C + (winNum)*0x10)
  41688. +#define AHB_TO_MBUS_WIN_INTEREG_REG 0x20080
  41689. +
  41690. +/* Window Control Register */
  41691. +/* AHB_TO_MBUS_WIN_CTRL_REG (ATMWCR)*/
  41692. +#define ATMWCR_WIN_ENABLE BIT0 /* Window Enable */
  41693. +
  41694. +#define ATMWCR_WIN_TARGET_OFFS 4 /* The target interface associated
  41695. + with this window*/
  41696. +#define ATMWCR_WIN_TARGET_MASK (0xf << ATMWCR_WIN_TARGET_OFFS)
  41697. +
  41698. +#define ATMWCR_WIN_ATTR_OFFS 8 /* The target interface attributes
  41699. + Associated with this window */
  41700. +#define ATMWCR_WIN_ATTR_MASK (0xff << ATMWCR_WIN_ATTR_OFFS)
  41701. +
  41702. +
  41703. +/*
  41704. +Used with the Base register to set the address window size and location
  41705. +Must be programed from LSB to MSB as sequence of 1’s followed
  41706. +by sequence of 0’s. The number of 1’s specifies the size of the window
  41707. +in 64 KB granularity (e.g. a value of 0x00FF specifies 256 = 16 MB).
  41708. +
  41709. +NOTE: A value of 0x0 specifies 64KB size.
  41710. +*/
  41711. +#define ATMWCR_WIN_SIZE_OFFS 16 /* Window Size */
  41712. +#define ATMWCR_WIN_SIZE_MASK (0xffff << ATMWCR_WIN_SIZE_OFFS)
  41713. +#define ATMWCR_WIN_SIZE_ALIGNMENT 0x10000
  41714. +
  41715. +/* Window Base Register */
  41716. +/* AHB_TO_MBUS_WIN_BASE_REG (ATMWBR) */
  41717. +
  41718. +/*
  41719. +Used with the size field to set the address window size and location.
  41720. +Corresponds to transaction address[31:16]
  41721. +*/
  41722. +#define ATMWBR_BASE_OFFS 16 /* Base Address */
  41723. +#define ATMWBR_BASE_MASK (0xffff << ATMWBR_BASE_OFFS)
  41724. +#define ATMWBR_BASE_ALIGNMENT 0x10000
  41725. +
  41726. +/* Window Remap Low Register */
  41727. +/* AHB_TO_MBUS_WIN_REMAP_LOW_REG (ATMWRLR) */
  41728. +
  41729. +/*
  41730. +Used with the size field to specifies address bits[31:0] to be driven to
  41731. +the target interface.:
  41732. +target_addr[31:16] = (addr[31:16] & size[15:0]) | (remap[31:16] & ~size[15:0])
  41733. +*/
  41734. +#define ATMWRLR_REMAP_LOW_OFFS 16 /* Remap Address */
  41735. +#define ATMWRLR_REMAP_LOW_MASK (0xffff << ATMWRLR_REMAP_LOW_OFFS)
  41736. +#define ATMWRLR_REMAP_LOW_ALIGNMENT 0x10000
  41737. +
  41738. +/* Window Remap High Register */
  41739. +/* AHB_TO_MBUS_WIN_REMAP_HIGH_REG (ATMWRHR) */
  41740. +
  41741. +/*
  41742. +Specifies address bits[63:32] to be driven to the target interface.
  41743. +target_addr[63:32] = (RemapHigh[31:0]
  41744. +*/
  41745. +#define ATMWRHR_REMAP_HIGH_OFFS 0 /* Remap Address */
  41746. +#define ATMWRHR_REMAP_HIGH_MASK (0xffffffff << ATMWRHR_REMAP_HIGH_OFFS)
  41747. +
  41748. +
  41749. +#endif /* __INCmvAhbToMbusRegsh */
  41750. +
  41751. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c
  41752. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c 1970-01-01 01:00:00.000000000 +0100
  41753. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.c 2011-08-01 14:38:19.000000000 +0200
  41754. @@ -0,0 +1,1036 @@
  41755. +/*******************************************************************************
  41756. +Copyright (C) Marvell International Ltd. and its affiliates
  41757. +
  41758. +This software file (the "File") is owned and distributed by Marvell
  41759. +International Ltd. and/or its affiliates ("Marvell") under the following
  41760. +alternative licensing terms. Once you have made an election to distribute the
  41761. +File under one of the following license alternatives, please (i) delete this
  41762. +introductory statement regarding license alternatives, (ii) delete the two
  41763. +license alternatives that you have not elected to use and (iii) preserve the
  41764. +Marvell copyright notice above.
  41765. +
  41766. +********************************************************************************
  41767. +Marvell Commercial License Option
  41768. +
  41769. +If you received this File from Marvell and you have entered into a commercial
  41770. +license agreement (a "Commercial License") with Marvell, the File is licensed
  41771. +to you under the terms of the applicable Commercial License.
  41772. +
  41773. +********************************************************************************
  41774. +Marvell GPL License Option
  41775. +
  41776. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41777. +modify this File in accordance with the terms and conditions of the General
  41778. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  41779. +available along with the File in the license.txt file or by writing to the Free
  41780. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  41781. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  41782. +
  41783. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  41784. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  41785. +DISCLAIMED. The GPL License provides additional details about this warranty
  41786. +disclaimer.
  41787. +********************************************************************************
  41788. +Marvell BSD License Option
  41789. +
  41790. +If you received this File from Marvell, you may opt to use, redistribute and/or
  41791. +modify this File under the following licensing terms.
  41792. +Redistribution and use in source and binary forms, with or without modification,
  41793. +are permitted provided that the following conditions are met:
  41794. +
  41795. + * Redistributions of source code must retain the above copyright notice,
  41796. + this list of conditions and the following disclaimer.
  41797. +
  41798. + * Redistributions in binary form must reproduce the above copyright
  41799. + notice, this list of conditions and the following disclaimer in the
  41800. + documentation and/or other materials provided with the distribution.
  41801. +
  41802. + * Neither the name of Marvell nor the names of its contributors may be
  41803. + used to endorse or promote products derived from this software without
  41804. + specific prior written permission.
  41805. +
  41806. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  41807. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  41808. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  41809. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  41810. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  41811. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  41812. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  41813. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  41814. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  41815. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  41816. +
  41817. +*******************************************************************************/
  41818. +
  41819. +
  41820. +/* includes */
  41821. +#include "ctrlEnv/sys/mvCpuIf.h"
  41822. +#include "ctrlEnv/sys/mvAhbToMbusRegs.h"
  41823. +#include "cpu/mvCpu.h"
  41824. +#include "ctrlEnv/mvCtrlEnvLib.h"
  41825. +#include "mvSysHwConfig.h"
  41826. +#include "mvSysDram.h"
  41827. +
  41828. +/*#define MV_DEBUG*/
  41829. +/* defines */
  41830. +
  41831. +#ifdef MV_DEBUG
  41832. + #define DB(x) x
  41833. +#else
  41834. + #define DB(x)
  41835. +#endif
  41836. +
  41837. +/* locals */
  41838. +/* static functions */
  41839. +static MV_BOOL cpuTargetWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
  41840. +
  41841. +MV_TARGET * sampleAtResetTargetArray;
  41842. +MV_TARGET sampleAtResetTargetArrayP[] = BOOT_TARGETS_NAME_ARRAY;
  41843. +MV_TARGET sampleAtResetTargetArray6180P[] = BOOT_TARGETS_NAME_ARRAY_6180;
  41844. +/*******************************************************************************
  41845. +* mvCpuIfInit - Initialize Controller CPU interface
  41846. +*
  41847. +* DESCRIPTION:
  41848. +* This function initialize Controller CPU interface:
  41849. +* 1. Set CPU interface configuration registers.
  41850. +* 2. Set CPU master Pizza arbiter control according to static
  41851. +* configuration described in configuration file.
  41852. +* 3. Opens CPU address decode windows. DRAM windows are assumed to be
  41853. +* already set (auto detection).
  41854. +*
  41855. +* INPUT:
  41856. +* None.
  41857. +*
  41858. +* OUTPUT:
  41859. +* None.
  41860. +*
  41861. +* RETURN:
  41862. +* None.
  41863. +*
  41864. +*******************************************************************************/
  41865. +MV_STATUS mvCpuIfInit(MV_CPU_DEC_WIN *cpuAddrWinMap)
  41866. +{
  41867. + MV_U32 regVal;
  41868. + MV_TARGET target;
  41869. + MV_ADDR_WIN addrWin;
  41870. +
  41871. + if (cpuAddrWinMap == NULL)
  41872. + {
  41873. + DB(mvOsPrintf("mvCpuIfInit:ERR. cpuAddrWinMap == NULL\n"));
  41874. + return MV_ERROR;
  41875. + }
  41876. +
  41877. + /*Initialize the boot target array according to device type*/
  41878. + if(mvCtrlModelGet() == MV_6180_DEV_ID)
  41879. + sampleAtResetTargetArray = sampleAtResetTargetArray6180P;
  41880. + else
  41881. + sampleAtResetTargetArray = sampleAtResetTargetArrayP;
  41882. +
  41883. + /* Set ARM Configuration register */
  41884. + regVal = MV_REG_READ(CPU_CONFIG_REG);
  41885. + regVal &= ~CPU_CONFIG_DEFAULT_MASK;
  41886. + regVal |= CPU_CONFIG_DEFAULT;
  41887. + MV_REG_WRITE(CPU_CONFIG_REG,regVal);
  41888. +
  41889. + /* First disable all CPU target windows */
  41890. + for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++)
  41891. + {
  41892. + if ((MV_TARGET_IS_DRAM(target))||(target == INTER_REGS))
  41893. + {
  41894. + continue;
  41895. + }
  41896. +
  41897. +#if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA)
  41898. + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
  41899. + if (MV_TARGET_IS_PCI(target))
  41900. + {
  41901. + continue;
  41902. + }
  41903. +#endif
  41904. +
  41905. +#if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA)
  41906. + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
  41907. + if (MV_TARGET_IS_PEX(target))
  41908. + {
  41909. + continue;
  41910. + }
  41911. +#endif
  41912. +#if defined(MV_RUN_FROM_FLASH)
  41913. + /* Don't disable the boot device. */
  41914. + if (target == DEV_BOOCS)
  41915. + {
  41916. + continue;
  41917. + }
  41918. +#endif /* MV_RUN_FROM_FLASH */
  41919. + mvCpuIfTargetWinEnable(MV_CHANGE_BOOT_CS(target),MV_FALSE);
  41920. + }
  41921. +
  41922. +#if defined(MV_RUN_FROM_FLASH)
  41923. + /* Resize the bootcs windows before other windows, because this */
  41924. + /* window is enabled and will cause an overlap if not resized. */
  41925. + target = DEV_BOOCS;
  41926. +
  41927. + if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target]))
  41928. + {
  41929. + DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n"));
  41930. + return MV_ERROR;
  41931. + }
  41932. +
  41933. + addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow;
  41934. + addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh;
  41935. + if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin))
  41936. + {
  41937. + DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n",
  41938. + cpuAddrWinMap[target].winNum));
  41939. + }
  41940. +
  41941. +#endif /* MV_RUN_FROM_FLASH */
  41942. +
  41943. + /* Go through all targets in user table until table terminator */
  41944. + for (target = 0; cpuAddrWinMap[target].enable != TBL_TERM; target++)
  41945. + {
  41946. +
  41947. +#if defined(MV_RUN_FROM_FLASH)
  41948. + if (target == DEV_BOOCS)
  41949. + {
  41950. + continue;
  41951. + }
  41952. +#endif /* MV_RUN_FROM_FLASH */
  41953. +
  41954. + /* if DRAM auto sizing is used do not initialized DRAM target windows, */
  41955. + /* assuming this already has been done earlier. */
  41956. +#ifdef MV_DRAM_AUTO_SIZE
  41957. + if (MV_TARGET_IS_DRAM(target))
  41958. + {
  41959. + continue;
  41960. + }
  41961. +#endif
  41962. +
  41963. +#if defined(MV_MEM_OVER_PCI_WA) || defined(MV_UART_OVER_PCI_WA)
  41964. + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
  41965. + if (MV_TARGET_IS_PCI(target))
  41966. + {
  41967. + continue;
  41968. + }
  41969. +#endif
  41970. +
  41971. +#if defined(MV_MEM_OVER_PEX_WA) || defined(MV_UART_OVER_PEX_WA)
  41972. + /* If the target PEX or PCI and memory is over PEX or PCI we don't touch this CPU windows */
  41973. + if (MV_TARGET_IS_PEX(target))
  41974. + {
  41975. + continue;
  41976. + }
  41977. +#endif
  41978. + /* If the target attribute is the same as the boot device attribute */
  41979. + /* then it's stays disable */
  41980. + if (MV_TARGET_IS_AS_BOOT(target))
  41981. + {
  41982. + continue;
  41983. + }
  41984. +
  41985. + if((0 == cpuAddrWinMap[target].addrWin.size) ||
  41986. + (DIS == cpuAddrWinMap[target].enable))
  41987. +
  41988. + {
  41989. + if (MV_OK != mvCpuIfTargetWinEnable(target, MV_FALSE))
  41990. + {
  41991. + DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinEnable fail\n"));
  41992. + return MV_ERROR;
  41993. + }
  41994. +
  41995. + }
  41996. + else
  41997. + {
  41998. + if (MV_OK != mvCpuIfTargetWinSet(target, &cpuAddrWinMap[target]))
  41999. + {
  42000. + DB(mvOsPrintf("mvCpuIfInit:ERR. mvCpuIfTargetWinSet fail\n"));
  42001. + return MV_ERROR;
  42002. + }
  42003. +
  42004. + addrWin.baseLow = cpuAddrWinMap[target].addrWin.baseLow;
  42005. + addrWin.baseHigh = cpuAddrWinMap[target].addrWin.baseHigh;
  42006. + if (0xffffffff == mvAhbToMbusWinRemap(cpuAddrWinMap[target].winNum ,&addrWin))
  42007. + {
  42008. + DB(mvOsPrintf("mvCpuIfInit:WARN. mvAhbToMbusWinRemap can't remap winNum=%d\n",
  42009. + cpuAddrWinMap[target].winNum));
  42010. + }
  42011. +
  42012. +
  42013. + }
  42014. + }
  42015. +
  42016. + return MV_OK;
  42017. +
  42018. +
  42019. +}
  42020. +
  42021. +
  42022. +/*******************************************************************************
  42023. +* mvCpuIfTargetWinSet - Set CPU-to-peripheral target address window
  42024. +*
  42025. +* DESCRIPTION:
  42026. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI0_MEM0)
  42027. +* address window, also known as address decode window.
  42028. +* A new address decode window is set for specified target address window.
  42029. +* If address decode window parameter structure enables the window,
  42030. +* the routine will also enable the target window, allowing CPU to access
  42031. +* the target window.
  42032. +*
  42033. +* INPUT:
  42034. +* target - Peripheral target enumerator.
  42035. +* pAddrDecWin - CPU target window data structure.
  42036. +*
  42037. +* OUTPUT:
  42038. +* N/A
  42039. +*
  42040. +* RETURN:
  42041. +* MV_OK if CPU target window was set correctly, MV_ERROR in case of
  42042. +* address window overlapps with other active CPU target window or
  42043. +* trying to assign 36bit base address while CPU does not support that.
  42044. +* The function returns MV_NOT_SUPPORTED, if the target is unsupported.
  42045. +*
  42046. +*******************************************************************************/
  42047. +MV_STATUS mvCpuIfTargetWinSet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin)
  42048. +{
  42049. + MV_AHB_TO_MBUS_DEC_WIN decWin;
  42050. + MV_U32 existingWinNum;
  42051. + MV_DRAM_DEC_WIN addrDecWin;
  42052. +
  42053. + target = MV_CHANGE_BOOT_CS(target);
  42054. +
  42055. + /* Check parameters */
  42056. + if (target >= MAX_TARGETS)
  42057. + {
  42058. + mvOsPrintf("mvCpuIfTargetWinSet: target %d is Illigal\n", target);
  42059. + return MV_ERROR;
  42060. + }
  42061. +
  42062. + /* 2) Check if the requested window overlaps with current windows */
  42063. + if (MV_TRUE == cpuTargetWinOverlap(target, &pAddrDecWin->addrWin))
  42064. + {
  42065. + mvOsPrintf("mvCpuIfTargetWinSet: ERR. Target %d overlap\n", target);
  42066. + return MV_BAD_PARAM;
  42067. + }
  42068. +
  42069. + if (MV_TARGET_IS_DRAM(target))
  42070. + {
  42071. + /* copy relevant data to MV_DRAM_DEC_WIN structure */
  42072. + addrDecWin.addrWin.baseHigh = pAddrDecWin->addrWin.baseHigh;
  42073. + addrDecWin.addrWin.baseLow = pAddrDecWin->addrWin.baseLow;
  42074. + addrDecWin.addrWin.size = pAddrDecWin->addrWin.size;
  42075. + addrDecWin.enable = pAddrDecWin->enable;
  42076. +
  42077. +
  42078. + if (mvDramIfWinSet(target,&addrDecWin) != MV_OK);
  42079. + {
  42080. + mvOsPrintf("mvCpuIfTargetWinSet: mvDramIfWinSet Failed\n");
  42081. + return MV_ERROR;
  42082. + }
  42083. +
  42084. + }
  42085. + else
  42086. + {
  42087. + /* copy relevant data to MV_AHB_TO_MBUS_DEC_WIN structure */
  42088. + decWin.addrWin.baseLow = pAddrDecWin->addrWin.baseLow;
  42089. + decWin.addrWin.baseHigh = pAddrDecWin->addrWin.baseHigh;
  42090. + decWin.addrWin.size = pAddrDecWin->addrWin.size;
  42091. + decWin.enable = pAddrDecWin->enable;
  42092. + decWin.target = target;
  42093. +
  42094. + existingWinNum = mvAhbToMbusWinTargetGet(target);
  42095. +
  42096. + /* check if there is already another Window configured
  42097. + for this target */
  42098. + if ((existingWinNum < MAX_AHB_TO_MBUS_WINS )&&
  42099. + (existingWinNum != pAddrDecWin->winNum))
  42100. + {
  42101. + /* if we want to enable the new winow number
  42102. + passed by the user , then the old one should
  42103. + be disabled */
  42104. + if (MV_TRUE == pAddrDecWin->enable)
  42105. + {
  42106. + /* be sure it is disabled */
  42107. + mvAhbToMbusWinEnable(existingWinNum , MV_FALSE);
  42108. + }
  42109. + }
  42110. +
  42111. + if (mvAhbToMbusWinSet(pAddrDecWin->winNum,&decWin) != MV_OK)
  42112. + {
  42113. + mvOsPrintf("mvCpuIfTargetWinSet: mvAhbToMbusWinSet Failed\n");
  42114. + return MV_ERROR;
  42115. + }
  42116. +
  42117. + }
  42118. +
  42119. + return MV_OK;
  42120. +}
  42121. +
  42122. +/*******************************************************************************
  42123. +* mvCpuIfTargetWinGet - Get CPU-to-peripheral target address window
  42124. +*
  42125. +* DESCRIPTION:
  42126. +* Get the CPU peripheral target address window.
  42127. +*
  42128. +* INPUT:
  42129. +* target - Peripheral target enumerator
  42130. +*
  42131. +* OUTPUT:
  42132. +* pAddrDecWin - CPU target window information data structure.
  42133. +*
  42134. +* RETURN:
  42135. +* MV_OK if target exist, MV_ERROR otherwise.
  42136. +*
  42137. +*******************************************************************************/
  42138. +MV_STATUS mvCpuIfTargetWinGet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin)
  42139. +{
  42140. +
  42141. + MV_U32 winNum=0xffffffff;
  42142. + MV_AHB_TO_MBUS_DEC_WIN decWin;
  42143. + MV_DRAM_DEC_WIN addrDecWin;
  42144. +
  42145. + target = MV_CHANGE_BOOT_CS(target);
  42146. +
  42147. + /* Check parameters */
  42148. + if (target >= MAX_TARGETS)
  42149. + {
  42150. + mvOsPrintf("mvCpuIfTargetWinGet: target %d is Illigal\n", target);
  42151. + return MV_ERROR;
  42152. + }
  42153. +
  42154. + if (MV_TARGET_IS_DRAM(target))
  42155. + {
  42156. + if (mvDramIfWinGet(target,&addrDecWin) != MV_OK)
  42157. + {
  42158. + mvOsPrintf("mvCpuIfTargetWinGet: Failed to get window target %d\n",
  42159. + target);
  42160. + return MV_ERROR;
  42161. + }
  42162. +
  42163. + /* copy relevant data to MV_CPU_DEC_WIN structure */
  42164. + pAddrDecWin->addrWin.baseLow = addrDecWin.addrWin.baseLow;
  42165. + pAddrDecWin->addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  42166. + pAddrDecWin->addrWin.size = addrDecWin.addrWin.size;
  42167. + pAddrDecWin->enable = addrDecWin.enable;
  42168. + pAddrDecWin->winNum = 0xffffffff;
  42169. +
  42170. + }
  42171. + else
  42172. + {
  42173. + /* get the Window number associated with this target */
  42174. +
  42175. + winNum = mvAhbToMbusWinTargetGet(target);
  42176. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  42177. + {
  42178. + return MV_NO_SUCH;
  42179. +
  42180. + }
  42181. +
  42182. + if (mvAhbToMbusWinGet(winNum , &decWin) != MV_OK)
  42183. + {
  42184. + mvOsPrintf("%s: mvAhbToMbusWinGet Failed at winNum = %d\n",
  42185. + __FUNCTION__, winNum);
  42186. + return MV_ERROR;
  42187. +
  42188. + }
  42189. +
  42190. + /* copy relevant data to MV_CPU_DEC_WIN structure */
  42191. + pAddrDecWin->addrWin.baseLow = decWin.addrWin.baseLow;
  42192. + pAddrDecWin->addrWin.baseHigh = decWin.addrWin.baseHigh;
  42193. + pAddrDecWin->addrWin.size = decWin.addrWin.size;
  42194. + pAddrDecWin->enable = decWin.enable;
  42195. + pAddrDecWin->winNum = winNum;
  42196. +
  42197. + }
  42198. +
  42199. +
  42200. +
  42201. +
  42202. + return MV_OK;
  42203. +}
  42204. +
  42205. +
  42206. +/*******************************************************************************
  42207. +* mvCpuIfTargetWinEnable - Enable/disable a CPU address decode window
  42208. +*
  42209. +* DESCRIPTION:
  42210. +* This function enable/disable a CPU address decode window.
  42211. +* if parameter 'enable' == MV_TRUE the routine will enable the
  42212. +* window, thus enabling CPU accesses (before enabling the window it is
  42213. +* tested for overlapping). Otherwise, the window will be disabled.
  42214. +*
  42215. +* INPUT:
  42216. +* target - Peripheral target enumerator.
  42217. +* enable - Enable/disable parameter.
  42218. +*
  42219. +* OUTPUT:
  42220. +* N/A
  42221. +*
  42222. +* RETURN:
  42223. +* MV_ERROR if protection window number was wrong, or the window
  42224. +* overlapps other target window.
  42225. +*
  42226. +*******************************************************************************/
  42227. +MV_STATUS mvCpuIfTargetWinEnable(MV_TARGET target,MV_BOOL enable)
  42228. +{
  42229. + MV_U32 winNum, temp;
  42230. + MV_CPU_DEC_WIN addrDecWin;
  42231. +
  42232. + target = MV_CHANGE_BOOT_CS(target);
  42233. +
  42234. + /* Check parameters */
  42235. + if (target >= MAX_TARGETS)
  42236. + {
  42237. + mvOsPrintf("mvCpuIfTargetWinEnable: target %d is Illigal\n", target);
  42238. + return MV_ERROR;
  42239. + }
  42240. +
  42241. + /* get the window and check if it exist */
  42242. + temp = mvCpuIfTargetWinGet(target, &addrDecWin);
  42243. + if (MV_NO_SUCH == temp)
  42244. + {
  42245. + return (enable? MV_ERROR: MV_OK);
  42246. + }
  42247. + else if( MV_OK != temp)
  42248. + {
  42249. + mvOsPrintf("%s: ERR. Getting target %d failed.\n",__FUNCTION__, target);
  42250. + return MV_ERROR;
  42251. + }
  42252. +
  42253. +
  42254. + /* check overlap */
  42255. +
  42256. + if (MV_TRUE == enable)
  42257. + {
  42258. + if (MV_TRUE == cpuTargetWinOverlap(target, &addrDecWin.addrWin))
  42259. + {
  42260. + DB(mvOsPrintf("%s: ERR. Target %d overlap\n",__FUNCTION__, target));
  42261. + return MV_ERROR;
  42262. + }
  42263. +
  42264. + }
  42265. +
  42266. +
  42267. + if (MV_TARGET_IS_DRAM(target))
  42268. + {
  42269. + if (mvDramIfWinEnable(target , enable) != MV_OK)
  42270. + {
  42271. + mvOsPrintf("mvCpuIfTargetWinGet: mvDramIfWinEnable Failed at \n");
  42272. + return MV_ERROR;
  42273. +
  42274. + }
  42275. +
  42276. + }
  42277. + else
  42278. + {
  42279. + /* get the Window number associated with this target */
  42280. +
  42281. + winNum = mvAhbToMbusWinTargetGet(target);
  42282. +
  42283. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  42284. + {
  42285. + return (enable? MV_ERROR: MV_OK);
  42286. + }
  42287. +
  42288. + if (mvAhbToMbusWinEnable(winNum , enable) != MV_OK)
  42289. + {
  42290. + mvOsPrintf("mvCpuIfTargetWinGet: Failed to enable window = %d\n",
  42291. + winNum);
  42292. + return MV_ERROR;
  42293. +
  42294. + }
  42295. +
  42296. + }
  42297. +
  42298. + return MV_OK;
  42299. +}
  42300. +
  42301. +
  42302. +/*******************************************************************************
  42303. +* mvCpuIfTargetWinSizeGet - Get CPU target address window size
  42304. +*
  42305. +* DESCRIPTION:
  42306. +* Get the size of CPU-to-peripheral target window.
  42307. +*
  42308. +* INPUT:
  42309. +* target - Peripheral target enumerator
  42310. +*
  42311. +* OUTPUT:
  42312. +* None.
  42313. +*
  42314. +* RETURN:
  42315. +* 32bit size. Function also returns '0' if window is closed.
  42316. +* Function returns 0xFFFFFFFF in case of an error.
  42317. +*
  42318. +*******************************************************************************/
  42319. +MV_U32 mvCpuIfTargetWinSizeGet(MV_TARGET target)
  42320. +{
  42321. + MV_CPU_DEC_WIN addrDecWin;
  42322. +
  42323. + target = MV_CHANGE_BOOT_CS(target);
  42324. +
  42325. + /* Check parameters */
  42326. + if (target >= MAX_TARGETS)
  42327. + {
  42328. + mvOsPrintf("mvCpuIfTargetWinSizeGet: target %d is Illigal\n", target);
  42329. + return 0;
  42330. + }
  42331. +
  42332. + /* Get the winNum window */
  42333. + if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))
  42334. + {
  42335. + mvOsPrintf("mvCpuIfTargetWinSizeGet:ERR. Getting target %d failed.\n",
  42336. + target);
  42337. + return 0;
  42338. + }
  42339. +
  42340. + /* Check if window is enabled */
  42341. + if (addrDecWin.enable == MV_TRUE)
  42342. + {
  42343. + return (addrDecWin.addrWin.size);
  42344. + }
  42345. + else
  42346. + {
  42347. + return 0; /* Window disabled. return 0 */
  42348. + }
  42349. +}
  42350. +
  42351. +/*******************************************************************************
  42352. +* mvCpuIfTargetWinBaseLowGet - Get CPU target address window base low
  42353. +*
  42354. +* DESCRIPTION:
  42355. +* CPU-to-peripheral target address window base is constructed of
  42356. +* two parts: Low and high.
  42357. +* This function gets the CPU peripheral target low base address.
  42358. +*
  42359. +* INPUT:
  42360. +* target - Peripheral target enumerator
  42361. +*
  42362. +* OUTPUT:
  42363. +* None.
  42364. +*
  42365. +* RETURN:
  42366. +* 32bit low base address.
  42367. +*
  42368. +*******************************************************************************/
  42369. +MV_U32 mvCpuIfTargetWinBaseLowGet(MV_TARGET target)
  42370. +{
  42371. + MV_CPU_DEC_WIN addrDecWin;
  42372. +
  42373. + target = MV_CHANGE_BOOT_CS(target);
  42374. +
  42375. + /* Check parameters */
  42376. + if (target >= MAX_TARGETS)
  42377. + {
  42378. + mvOsPrintf("mvCpuIfTargetWinBaseLowGet: target %d is Illigal\n", target);
  42379. + return 0xffffffff;
  42380. + }
  42381. +
  42382. + /* Get the target window */
  42383. + if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))
  42384. + {
  42385. + mvOsPrintf("mvCpuIfTargetWinBaseLowGet:ERR. Getting target %d failed.\n",
  42386. + target);
  42387. + return 0xffffffff;
  42388. + }
  42389. +
  42390. + if (MV_FALSE == addrDecWin.enable)
  42391. + {
  42392. + return 0xffffffff;
  42393. + }
  42394. + return (addrDecWin.addrWin.baseLow);
  42395. +}
  42396. +
  42397. +/*******************************************************************************
  42398. +* mvCpuIfTargetWinBaseHighGet - Get CPU target address window base high
  42399. +*
  42400. +* DESCRIPTION:
  42401. +* CPU-to-peripheral target address window base is constructed of
  42402. +* two parts: Low and high.
  42403. +* This function gets the CPU peripheral target high base address.
  42404. +*
  42405. +* INPUT:
  42406. +* target - Peripheral target enumerator
  42407. +*
  42408. +* OUTPUT:
  42409. +* None.
  42410. +*
  42411. +* RETURN:
  42412. +* 32bit high base address.
  42413. +*
  42414. +*******************************************************************************/
  42415. +MV_U32 mvCpuIfTargetWinBaseHighGet(MV_TARGET target)
  42416. +{
  42417. + MV_CPU_DEC_WIN addrDecWin;
  42418. +
  42419. + target = MV_CHANGE_BOOT_CS(target);
  42420. +
  42421. + /* Check parameters */
  42422. + if (target >= MAX_TARGETS)
  42423. + {
  42424. + mvOsPrintf("mvCpuIfTargetWinBaseLowGet: target %d is Illigal\n", target);
  42425. + return 0xffffffff;
  42426. + }
  42427. +
  42428. + /* Get the target window */
  42429. + if (MV_OK != mvCpuIfTargetWinGet(target, &addrDecWin))
  42430. + {
  42431. + mvOsPrintf("mvCpuIfTargetWinBaseHighGet:ERR. Getting target %d failed.\n",
  42432. + target);
  42433. + return 0xffffffff;
  42434. + }
  42435. +
  42436. + if (MV_FALSE == addrDecWin.enable)
  42437. + {
  42438. + return 0;
  42439. + }
  42440. +
  42441. + return (addrDecWin.addrWin.baseHigh);
  42442. +}
  42443. +
  42444. +#if defined(MV_INCLUDE_PEX)
  42445. +/*******************************************************************************
  42446. +* mvCpuIfPexRemap - Set CPU remap register for address windows.
  42447. +*
  42448. +* DESCRIPTION:
  42449. +*
  42450. +* INPUT:
  42451. +* pexTarget - Peripheral target enumerator. Must be a PEX target.
  42452. +* pAddrDecWin - CPU target window information data structure.
  42453. +* Note that caller has to fill in the base field only. The
  42454. +* size field is ignored.
  42455. +*
  42456. +* OUTPUT:
  42457. +* None.
  42458. +*
  42459. +* RETURN:
  42460. +* MV_ERROR if target is not a PEX one, MV_OK otherwise.
  42461. +*
  42462. +*******************************************************************************/
  42463. +MV_U32 mvCpuIfPexRemap(MV_TARGET pexTarget, MV_ADDR_WIN *pAddrDecWin)
  42464. +{
  42465. + MV_U32 winNum;
  42466. +
  42467. + /* Check parameters */
  42468. +
  42469. + if (mvCtrlPexMaxIfGet() > 1)
  42470. + {
  42471. + if ((!MV_TARGET_IS_PEX1(pexTarget))&&(!MV_TARGET_IS_PEX0(pexTarget)))
  42472. + {
  42473. + mvOsPrintf("mvCpuIfPexRemap: target %d is Illigal\n",pexTarget);
  42474. + return 0xffffffff;
  42475. + }
  42476. +
  42477. + }
  42478. + else
  42479. + {
  42480. + if (!MV_TARGET_IS_PEX0(pexTarget))
  42481. + {
  42482. + mvOsPrintf("mvCpuIfPexRemap: target %d is Illigal\n",pexTarget);
  42483. + return 0xffffffff;
  42484. + }
  42485. +
  42486. + }
  42487. +
  42488. + /* get the Window number associated with this target */
  42489. + winNum = mvAhbToMbusWinTargetGet(pexTarget);
  42490. +
  42491. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  42492. + {
  42493. + mvOsPrintf("mvCpuIfPexRemap: mvAhbToMbusWinTargetGet Failed\n");
  42494. + return 0xffffffff;
  42495. +
  42496. + }
  42497. +
  42498. + return mvAhbToMbusWinRemap(winNum , pAddrDecWin);
  42499. +}
  42500. +
  42501. +#endif
  42502. +
  42503. +#if defined(MV_INCLUDE_PCI)
  42504. +/*******************************************************************************
  42505. +* mvCpuIfPciRemap - Set CPU remap register for address windows.
  42506. +*
  42507. +* DESCRIPTION:
  42508. +*
  42509. +* INPUT:
  42510. +* pciTarget - Peripheral target enumerator. Must be a PCI target.
  42511. +* pAddrDecWin - CPU target window information data structure.
  42512. +* Note that caller has to fill in the base field only. The
  42513. +* size field is ignored.
  42514. +*
  42515. +* OUTPUT:
  42516. +* None.
  42517. +*
  42518. +* RETURN:
  42519. +* MV_ERROR if target is not a PCI one, MV_OK otherwise.
  42520. +*
  42521. +*******************************************************************************/
  42522. +MV_U32 mvCpuIfPciRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin)
  42523. +{
  42524. + MV_U32 winNum;
  42525. +
  42526. + /* Check parameters */
  42527. + if (!MV_TARGET_IS_PCI(pciTarget))
  42528. + {
  42529. + mvOsPrintf("mvCpuIfPciRemap: target %d is Illigal\n",pciTarget);
  42530. + return 0xffffffff;
  42531. + }
  42532. +
  42533. + /* get the Window number associated with this target */
  42534. + winNum = mvAhbToMbusWinTargetGet(pciTarget);
  42535. +
  42536. + if (winNum >= MAX_AHB_TO_MBUS_WINS)
  42537. + {
  42538. + mvOsPrintf("mvCpuIfPciRemap: mvAhbToMbusWinTargetGet Failed\n");
  42539. + return 0xffffffff;
  42540. +
  42541. + }
  42542. +
  42543. + return mvAhbToMbusWinRemap(winNum , pAddrDecWin);
  42544. +}
  42545. +#endif /* MV_INCLUDE_PCI */
  42546. +
  42547. +
  42548. +/*******************************************************************************
  42549. +* mvCpuIfPciIfRemap - Set CPU remap register for address windows.
  42550. +*
  42551. +* DESCRIPTION:
  42552. +*
  42553. +* INPUT:
  42554. +* pciTarget - Peripheral target enumerator. Must be a PCI target.
  42555. +* pAddrDecWin - CPU target window information data structure.
  42556. +* Note that caller has to fill in the base field only. The
  42557. +* size field is ignored.
  42558. +*
  42559. +* OUTPUT:
  42560. +* None.
  42561. +*
  42562. +* RETURN:
  42563. +* MV_ERROR if target is not a PCI one, MV_OK otherwise.
  42564. +*
  42565. +*******************************************************************************/
  42566. +MV_U32 mvCpuIfPciIfRemap(MV_TARGET pciIfTarget, MV_ADDR_WIN *pAddrDecWin)
  42567. +{
  42568. +#if defined(MV_INCLUDE_PEX)
  42569. + if (MV_TARGET_IS_PEX(pciIfTarget))
  42570. + {
  42571. + return mvCpuIfPexRemap(pciIfTarget,pAddrDecWin);
  42572. + }
  42573. +#endif
  42574. +#if defined(MV_INCLUDE_PCI)
  42575. +
  42576. + if (MV_TARGET_IS_PCI(pciIfTarget))
  42577. + {
  42578. + return mvCpuIfPciRemap(pciIfTarget,pAddrDecWin);
  42579. + }
  42580. +#endif
  42581. + return 0;
  42582. +}
  42583. +
  42584. +
  42585. +
  42586. +/*******************************************************************************
  42587. +* mvCpuIfTargetOfBaseAddressGet - Get the target according to base address
  42588. +*
  42589. +* DESCRIPTION:
  42590. +*
  42591. +* INPUT:
  42592. +* baseAddress - base address to be checked
  42593. +*
  42594. +* OUTPUT:
  42595. +* None.
  42596. +*
  42597. +* RETURN:
  42598. +* the target number that baseAddress belongs to or MAX_TARGETS is not
  42599. +* found
  42600. +*
  42601. +*******************************************************************************/
  42602. +
  42603. +MV_TARGET mvCpuIfTargetOfBaseAddressGet(MV_U32 baseAddress)
  42604. +{
  42605. + MV_CPU_DEC_WIN win;
  42606. + MV_U32 target;
  42607. +
  42608. + for( target = 0; target < MAX_TARGETS; target++ )
  42609. + {
  42610. + if( mvCpuIfTargetWinGet( target, &win ) == MV_OK )
  42611. + {
  42612. + if( win.enable )
  42613. + {
  42614. + if ((baseAddress >= win.addrWin.baseLow) &&
  42615. + (baseAddress < win.addrWin.baseLow + win.addrWin.size)) break;
  42616. + }
  42617. + }
  42618. + else return MAX_TARGETS;
  42619. +
  42620. + }
  42621. +
  42622. + return target;
  42623. +}
  42624. +/*******************************************************************************
  42625. +* cpuTargetWinOverlap - Detect CPU address decode windows overlapping
  42626. +*
  42627. +* DESCRIPTION:
  42628. +* An unpredicted behaviur is expected in case CPU address decode
  42629. +* windows overlapps.
  42630. +* This function detects CPU address decode windows overlapping of a
  42631. +* specified target. The function does not check the target itself for
  42632. +* overlapping. The function also skipps disabled address decode windows.
  42633. +*
  42634. +* INPUT:
  42635. +* target - Peripheral target enumerator.
  42636. +* pAddrDecWin - An address decode window struct.
  42637. +*
  42638. +* OUTPUT:
  42639. +* None.
  42640. +*
  42641. +* RETURN:
  42642. +* MV_TRUE if the given address window overlaps current address
  42643. +* decode map, MV_FALSE otherwise.
  42644. +*
  42645. +*******************************************************************************/
  42646. +static MV_BOOL cpuTargetWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
  42647. +{
  42648. + MV_U32 targetNum;
  42649. + MV_CPU_DEC_WIN addrDecWin;
  42650. + MV_STATUS status;
  42651. +
  42652. +
  42653. + for(targetNum = 0; targetNum < MAX_TARGETS; targetNum++)
  42654. + {
  42655. +#if defined(MV_RUN_FROM_FLASH)
  42656. + if(MV_TARGET_IS_AS_BOOT(target))
  42657. + {
  42658. + if (MV_CHANGE_BOOT_CS(targetNum) == target)
  42659. + continue;
  42660. + }
  42661. +#endif /* MV_RUN_FROM_FLASH */
  42662. +
  42663. + /* don't check our target or illegal targets */
  42664. + if (targetNum == target)
  42665. + {
  42666. + continue;
  42667. + }
  42668. +
  42669. + /* Get window parameters */
  42670. + status = mvCpuIfTargetWinGet(targetNum, &addrDecWin);
  42671. + if(MV_NO_SUCH == status)
  42672. + {
  42673. + continue;
  42674. + }
  42675. + if(MV_OK != status)
  42676. + {
  42677. + DB(mvOsPrintf("cpuTargetWinOverlap: ERR. TargetWinGet failed\n"));
  42678. + return MV_TRUE;
  42679. + }
  42680. +
  42681. + /* Do not check disabled windows */
  42682. + if (MV_FALSE == addrDecWin.enable)
  42683. + {
  42684. + continue;
  42685. + }
  42686. +
  42687. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
  42688. + {
  42689. + DB(mvOsPrintf(
  42690. + "cpuTargetWinOverlap: Required target %d overlap current %d\n",
  42691. + target, targetNum));
  42692. + return MV_TRUE;
  42693. + }
  42694. + }
  42695. +
  42696. + return MV_FALSE;
  42697. +
  42698. +}
  42699. +
  42700. +/*******************************************************************************
  42701. +* mvCpuIfAddDecShow - Print the CPU address decode map.
  42702. +*
  42703. +* DESCRIPTION:
  42704. +* This function print the CPU address decode map.
  42705. +*
  42706. +* INPUT:
  42707. +* None.
  42708. +*
  42709. +* OUTPUT:
  42710. +* None.
  42711. +*
  42712. +* RETURN:
  42713. +* None.
  42714. +*
  42715. +*******************************************************************************/
  42716. +MV_VOID mvCpuIfAddDecShow(MV_VOID)
  42717. +{
  42718. + MV_CPU_DEC_WIN win;
  42719. + MV_U32 target;
  42720. + mvOsOutput( "\n" );
  42721. + mvOsOutput( "CPU Interface\n" );
  42722. + mvOsOutput( "-------------\n" );
  42723. +
  42724. + for( target = 0; target < MAX_TARGETS; target++ )
  42725. + {
  42726. +
  42727. + memset( &win, 0, sizeof(MV_CPU_DEC_WIN) );
  42728. +
  42729. + mvOsOutput( "%s ",mvCtrlTargetNameGet(target));
  42730. + mvOsOutput( "...." );
  42731. +
  42732. + if( mvCpuIfTargetWinGet( target, &win ) == MV_OK )
  42733. + {
  42734. + if( win.enable )
  42735. + {
  42736. + mvOsOutput( "base %08x, ", win.addrWin.baseLow );
  42737. + mvSizePrint( win.addrWin.size );
  42738. + mvOsOutput( "\n" );
  42739. +
  42740. + }
  42741. + else
  42742. + mvOsOutput( "disable\n" );
  42743. + }
  42744. + else if( mvCpuIfTargetWinGet( target, &win ) == MV_NO_SUCH )
  42745. + {
  42746. + mvOsOutput( "no such\n" );
  42747. + }
  42748. + }
  42749. +}
  42750. +
  42751. +/*******************************************************************************
  42752. +* mvCpuIfEnablePex - Enable PCI Express.
  42753. +*
  42754. +* DESCRIPTION:
  42755. +* This function Enable PCI Express.
  42756. +*
  42757. +* INPUT:
  42758. +* pexIf - PEX interface number.
  42759. +* pexType - MV_PEX_ROOT_COMPLEX - root complex device
  42760. +* MV_PEX_END_POINT - end point device
  42761. +* OUTPUT:
  42762. +* None.
  42763. +*
  42764. +* RETURN:
  42765. +* None.
  42766. +*
  42767. +*******************************************************************************/
  42768. +#if defined(MV_INCLUDE_PEX)
  42769. +MV_VOID mvCpuIfEnablePex(MV_U32 pexIf, MV_PEX_TYPE pexType)
  42770. +{
  42771. + /* Set pex mode incase S@R not exist */
  42772. + if( pexType == MV_PEX_END_POINT)
  42773. + {
  42774. + MV_REG_BIT_RESET(PEX_CTRL_REG(pexIf),PXCR_DEV_TYPE_CTRL_MASK);
  42775. + /* Change pex mode in capability reg */
  42776. + MV_REG_BIT_RESET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_CAPABILITY_REG), BIT22);
  42777. + MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_CAPABILITY_REG), BIT20);
  42778. +
  42779. + }
  42780. + else
  42781. + {
  42782. + MV_REG_BIT_SET(PEX_CTRL_REG(pexIf),PXCR_DEV_TYPE_CTRL_MASK);
  42783. + }
  42784. +
  42785. + /* CPU config register Pex enable */
  42786. + MV_REG_BIT_SET(CPU_CTRL_STAT_REG,CCSR_PCI_ACCESS_MASK);
  42787. +}
  42788. +#endif
  42789. +
  42790. +
  42791. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h
  42792. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h 1970-01-01 01:00:00.000000000 +0100
  42793. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIf.h 2011-08-01 14:38:19.000000000 +0200
  42794. @@ -0,0 +1,120 @@
  42795. +/*******************************************************************************
  42796. +Copyright (C) Marvell International Ltd. and its affiliates
  42797. +
  42798. +This software file (the "File") is owned and distributed by Marvell
  42799. +International Ltd. and/or its affiliates ("Marvell") under the following
  42800. +alternative licensing terms. Once you have made an election to distribute the
  42801. +File under one of the following license alternatives, please (i) delete this
  42802. +introductory statement regarding license alternatives, (ii) delete the two
  42803. +license alternatives that you have not elected to use and (iii) preserve the
  42804. +Marvell copyright notice above.
  42805. +
  42806. +********************************************************************************
  42807. +Marvell Commercial License Option
  42808. +
  42809. +If you received this File from Marvell and you have entered into a commercial
  42810. +license agreement (a "Commercial License") with Marvell, the File is licensed
  42811. +to you under the terms of the applicable Commercial License.
  42812. +
  42813. +********************************************************************************
  42814. +Marvell GPL License Option
  42815. +
  42816. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42817. +modify this File in accordance with the terms and conditions of the General
  42818. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  42819. +available along with the File in the license.txt file or by writing to the Free
  42820. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  42821. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  42822. +
  42823. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  42824. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  42825. +DISCLAIMED. The GPL License provides additional details about this warranty
  42826. +disclaimer.
  42827. +********************************************************************************
  42828. +Marvell BSD License Option
  42829. +
  42830. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42831. +modify this File under the following licensing terms.
  42832. +Redistribution and use in source and binary forms, with or without modification,
  42833. +are permitted provided that the following conditions are met:
  42834. +
  42835. + * Redistributions of source code must retain the above copyright notice,
  42836. + this list of conditions and the following disclaimer.
  42837. +
  42838. + * Redistributions in binary form must reproduce the above copyright
  42839. + notice, this list of conditions and the following disclaimer in the
  42840. + documentation and/or other materials provided with the distribution.
  42841. +
  42842. + * Neither the name of Marvell nor the names of its contributors may be
  42843. + used to endorse or promote products derived from this software without
  42844. + specific prior written permission.
  42845. +
  42846. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  42847. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  42848. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  42849. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  42850. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  42851. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42852. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  42853. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42854. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  42855. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42856. +
  42857. +*******************************************************************************/
  42858. +
  42859. +
  42860. +#ifndef __INCmvCpuIfh
  42861. +#define __INCmvCpuIfh
  42862. +
  42863. +/* includes */
  42864. +#include "ctrlEnv/mvCtrlEnvLib.h"
  42865. +#include "ctrlEnv/sys/mvCpuIfRegs.h"
  42866. +#include "ctrlEnv/sys/mvAhbToMbus.h"
  42867. +#include "ddr2/mvDramIf.h"
  42868. +#include "ctrlEnv/sys/mvSysDram.h"
  42869. +#if defined(MV_INCLUDE_PEX)
  42870. +#include "pex/mvPex.h"
  42871. +#endif
  42872. +
  42873. +/* defines */
  42874. +
  42875. +/* typedefs */
  42876. +/* This structure describes CPU interface address decode window */
  42877. +typedef struct _mvCpuIfDecWin
  42878. +{
  42879. + MV_ADDR_WIN addrWin; /* An address window*/
  42880. + MV_U32 winNum; /* Window Number in the AHB To Mbus bridge */
  42881. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  42882. +
  42883. +}MV_CPU_DEC_WIN;
  42884. +
  42885. +
  42886. +
  42887. +/* mvCpuIfLib.h API list */
  42888. +
  42889. +/* mvCpuIfLib.h API list */
  42890. +
  42891. +MV_STATUS mvCpuIfInit(MV_CPU_DEC_WIN *cpuAddrWinMap);
  42892. +MV_STATUS mvCpuIfTargetWinSet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin);
  42893. +MV_STATUS mvCpuIfTargetWinGet(MV_TARGET target, MV_CPU_DEC_WIN *pAddrDecWin);
  42894. +MV_STATUS mvCpuIfTargetWinEnable(MV_TARGET target,MV_BOOL enable);
  42895. +MV_U32 mvCpuIfTargetWinSizeGet(MV_TARGET target);
  42896. +MV_U32 mvCpuIfTargetWinBaseLowGet(MV_TARGET target);
  42897. +MV_U32 mvCpuIfTargetWinBaseHighGet(MV_TARGET target);
  42898. +MV_TARGET mvCpuIfTargetOfBaseAddressGet(MV_U32 baseAddress);
  42899. +#if defined(MV_INCLUDE_PEX)
  42900. +MV_U32 mvCpuIfPexRemap(MV_TARGET pexTarget, MV_ADDR_WIN *pAddrDecWin);
  42901. +MV_VOID mvCpuIfEnablePex(MV_U32 pexIf, MV_PEX_TYPE pexType);
  42902. +#endif
  42903. +#if defined(MV_INCLUDE_PCI)
  42904. +MV_U32 mvCpuIfPciRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin);
  42905. +#endif
  42906. +MV_U32 mvCpuIfPciIfRemap(MV_TARGET pciTarget, MV_ADDR_WIN *pAddrDecWin);
  42907. +
  42908. +MV_VOID mvCpuIfAddDecShow(MV_VOID);
  42909. +
  42910. +#if defined(MV88F6281)
  42911. +MV_STATUS mvCpuIfBridgeReorderWAInit(void);
  42912. +#endif
  42913. +
  42914. +#endif /* __INCmvCpuIfh */
  42915. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h
  42916. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h 1970-01-01 01:00:00.000000000 +0100
  42917. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvCpuIfRegs.h 2011-08-01 14:38:19.000000000 +0200
  42918. @@ -0,0 +1,304 @@
  42919. +/*******************************************************************************
  42920. +Copyright (C) Marvell International Ltd. and its affiliates
  42921. +
  42922. +This software file (the "File") is owned and distributed by Marvell
  42923. +International Ltd. and/or its affiliates ("Marvell") under the following
  42924. +alternative licensing terms. Once you have made an election to distribute the
  42925. +File under one of the following license alternatives, please (i) delete this
  42926. +introductory statement regarding license alternatives, (ii) delete the two
  42927. +license alternatives that you have not elected to use and (iii) preserve the
  42928. +Marvell copyright notice above.
  42929. +
  42930. +********************************************************************************
  42931. +Marvell Commercial License Option
  42932. +
  42933. +If you received this File from Marvell and you have entered into a commercial
  42934. +license agreement (a "Commercial License") with Marvell, the File is licensed
  42935. +to you under the terms of the applicable Commercial License.
  42936. +
  42937. +********************************************************************************
  42938. +Marvell GPL License Option
  42939. +
  42940. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42941. +modify this File in accordance with the terms and conditions of the General
  42942. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  42943. +available along with the File in the license.txt file or by writing to the Free
  42944. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  42945. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  42946. +
  42947. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  42948. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  42949. +DISCLAIMED. The GPL License provides additional details about this warranty
  42950. +disclaimer.
  42951. +********************************************************************************
  42952. +Marvell BSD License Option
  42953. +
  42954. +If you received this File from Marvell, you may opt to use, redistribute and/or
  42955. +modify this File under the following licensing terms.
  42956. +Redistribution and use in source and binary forms, with or without modification,
  42957. +are permitted provided that the following conditions are met:
  42958. +
  42959. + * Redistributions of source code must retain the above copyright notice,
  42960. + this list of conditions and the following disclaimer.
  42961. +
  42962. + * Redistributions in binary form must reproduce the above copyright
  42963. + notice, this list of conditions and the following disclaimer in the
  42964. + documentation and/or other materials provided with the distribution.
  42965. +
  42966. + * Neither the name of Marvell nor the names of its contributors may be
  42967. + used to endorse or promote products derived from this software without
  42968. + specific prior written permission.
  42969. +
  42970. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  42971. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  42972. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  42973. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  42974. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  42975. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  42976. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  42977. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  42978. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  42979. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  42980. +
  42981. +*******************************************************************************/
  42982. +
  42983. +
  42984. +#ifndef __INCmvCpuIfRegsh
  42985. +#define __INCmvCpuIfRegsh
  42986. +
  42987. +/****************************************/
  42988. +/* ARM Control and Status Registers Map */
  42989. +/****************************************/
  42990. +
  42991. +#define CPU_CONFIG_REG 0x20100
  42992. +#define CPU_CTRL_STAT_REG 0x20104
  42993. +#define CPU_RSTOUTN_MASK_REG 0x20108
  42994. +#define CPU_SYS_SOFT_RST_REG 0x2010C
  42995. +#define CPU_AHB_MBUS_CAUSE_INT_REG 0x20110
  42996. +#define CPU_AHB_MBUS_MASK_INT_REG 0x20114
  42997. +#define CPU_FTDLL_CONFIG_REG 0x20120
  42998. +#define CPU_L2_CONFIG_REG 0x20128
  42999. +
  43000. +
  43001. +
  43002. +/* ARM Configuration register */
  43003. +/* CPU_CONFIG_REG (CCR) */
  43004. +
  43005. +
  43006. +/* Reset vector location */
  43007. +#define CCR_VEC_INIT_LOC_OFFS 1
  43008. +#define CCR_VEC_INIT_LOC_MASK BIT1
  43009. +/* reset at 0x00000000 */
  43010. +#define CCR_VEC_INIT_LOC_0000 (0 << CCR_VEC_INIT_LOC_OFFS)
  43011. +/* reset at 0xFFFF0000 */
  43012. +#define CCR_VEC_INIT_LOC_FF00 (1 << CCR_VEC_INIT_LOC_OFFS)
  43013. +
  43014. +
  43015. +#define CCR_AHB_ERROR_PROP_OFFS 2
  43016. +#define CCR_AHB_ERROR_PROP_MASK BIT2
  43017. +/* Erros are not propogated to AHB */
  43018. +#define CCR_AHB_ERROR_PROP_NO_INDICATE (0 << CCR_AHB_ERROR_PROP_OFFS)
  43019. +/* Erros are propogated to AHB */
  43020. +#define CCR_AHB_ERROR_PROP_INDICATE (1 << CCR_AHB_ERROR_PROP_OFFS)
  43021. +
  43022. +
  43023. +#define CCR_ENDIAN_INIT_OFFS 3
  43024. +#define CCR_ENDIAN_INIT_MASK BIT3
  43025. +#define CCR_ENDIAN_INIT_LITTLE (0 << CCR_ENDIAN_INIT_OFFS)
  43026. +#define CCR_ENDIAN_INIT_BIG (1 << CCR_ENDIAN_INIT_OFFS)
  43027. +
  43028. +
  43029. +#define CCR_INCR_EN_OFFS 4
  43030. +#define CCR_INCR_EN_MASK BIT4
  43031. +#define CCR_INCR_EN BIT4
  43032. +
  43033. +
  43034. +#define CCR_NCB_BLOCKING_OFFS 5
  43035. +#define CCR_NCB_BLOCKING_MASK (1 << CCR_NCB_BLOCKING_OFFS)
  43036. +#define CCR_NCB_BLOCKING_NON (0 << CCR_NCB_BLOCKING_OFFS)
  43037. +#define CCR_NCB_BLOCKING_EN (1 << CCR_NCB_BLOCKING_OFFS)
  43038. +
  43039. +#define CCR_CPU_2_MBUSL_TICK_DRV_OFFS 8
  43040. +#define CCR_CPU_2_MBUSL_TICK_DRV_MASK (0xF << CCR_CPU_2_MBUSL_TICK_DRV_OFFS)
  43041. +#define CCR_CPU_2_MBUSL_TICK_SMPL_OFFS 12
  43042. +#define CCR_CPU_2_MBUSL_TICK_SMPL_MASK (0xF << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS)
  43043. +#define CCR_ICACH_PREF_BUF_ENABLE BIT16
  43044. +#define CCR_DCACH_PREF_BUF_ENABLE BIT17
  43045. +
  43046. +/* Ratio options for CPU to DDR for 6281/6192/6190 */
  43047. +#define CPU_2_DDR_CLK_1x3 4
  43048. +#define CPU_2_DDR_CLK_1x4 6
  43049. +
  43050. +/* Ratio options for CPU to DDR for 6281 only */
  43051. +#define CPU_2_DDR_CLK_2x9 7
  43052. +#define CPU_2_DDR_CLK_1x5 8
  43053. +#define CPU_2_DDR_CLK_1x6 9
  43054. +
  43055. +/* Ratio options for CPU to DDR for 6180 only */
  43056. +#define CPU_2_DDR_CLK_1x3_1 0x5
  43057. +#define CPU_2_DDR_CLK_1x4_1 0x6
  43058. +
  43059. +/* Default values for CPU to Mbus-L DDR Interface Tick Driver and */
  43060. +/* CPU to Mbus-L Tick Sample fields in CPU config register */
  43061. +
  43062. +#define TICK_DRV_1x1 0
  43063. +#define TICK_DRV_1x2 0
  43064. +#define TICK_DRV_1x3 1
  43065. +#define TICK_DRV_1x4 2
  43066. +#define TICK_SMPL_1x1 0
  43067. +#define TICK_SMPL_1x2 1
  43068. +#define TICK_SMPL_1x3 0
  43069. +#define TICK_SMPL_1x4 0
  43070. +
  43071. +#define CPU_2_MBUSL_DDR_CLK_1x2 \
  43072. + ((TICK_DRV_1x2 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
  43073. + (TICK_SMPL_1x2 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
  43074. +#define CPU_2_MBUSL_DDR_CLK_1x3 \
  43075. + ((TICK_DRV_1x3 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
  43076. + (TICK_SMPL_1x3 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
  43077. +#define CPU_2_MBUSL_DDR_CLK_1x4 \
  43078. + ((TICK_DRV_1x4 << CCR_CPU_2_MBUSL_TICK_DRV_OFFS) | \
  43079. + (TICK_SMPL_1x4 << CCR_CPU_2_MBUSL_TICK_SMPL_OFFS))
  43080. +
  43081. +/* ARM Control and Status register */
  43082. +/* CPU_CTRL_STAT_REG (CCSR) */
  43083. +
  43084. +
  43085. +/*
  43086. +This is used to block PCI express\PCI from access Socrates/Feroceon GP
  43087. +while ARM boot is still in progress
  43088. +*/
  43089. +
  43090. +#define CCSR_PCI_ACCESS_OFFS 0
  43091. +#define CCSR_PCI_ACCESS_MASK BIT0
  43092. +#define CCSR_PCI_ACCESS_ENABLE (0 << CCSR_PCI_ACCESS_OFFS)
  43093. +#define CCSR_PCI_ACCESS_DISBALE (1 << CCSR_PCI_ACCESS_OFFS)
  43094. +
  43095. +#define CCSR_ARM_RESET BIT1
  43096. +#define CCSR_SELF_INT BIT2
  43097. +#define CCSR_BIG_ENDIAN BIT15
  43098. +
  43099. +
  43100. +/* RSTOUTn Mask Register */
  43101. +/* CPU_RSTOUTN_MASK_REG (CRMR) */
  43102. +
  43103. +#define CRMR_PEX_RST_OUT_OFFS 0
  43104. +#define CRMR_PEX_RST_OUT_MASK BIT0
  43105. +#define CRMR_PEX_RST_OUT_ENABLE (1 << CRMR_PEX_RST_OUT_OFFS)
  43106. +#define CRMR_PEX_RST_OUT_DISABLE (0 << CRMR_PEX_RST_OUT_OFFS)
  43107. +
  43108. +#define CRMR_WD_RST_OUT_OFFS 1
  43109. +#define CRMR_WD_RST_OUT_MASK BIT1
  43110. +#define CRMR_WD_RST_OUT_ENABLE (1 << CRMR_WD_RST_OUT_OFFS)
  43111. +#define CRMR_WD_RST_OUT_DISBALE (0 << CRMR_WD_RST_OUT_OFFS)
  43112. +
  43113. +#define CRMR_SOFT_RST_OUT_OFFS 2
  43114. +#define CRMR_SOFT_RST_OUT_MASK BIT2
  43115. +#define CRMR_SOFT_RST_OUT_ENABLE (1 << CRMR_SOFT_RST_OUT_OFFS)
  43116. +#define CRMR_SOFT_RST_OUT_DISBALE (0 << CRMR_SOFT_RST_OUT_OFFS)
  43117. +
  43118. +/* System Software Reset Register */
  43119. +/* CPU_SYS_SOFT_RST_REG (CSSRR) */
  43120. +
  43121. +#define CSSRR_SYSTEM_SOFT_RST BIT0
  43122. +
  43123. +/* AHB to Mbus Bridge Interrupt Cause Register*/
  43124. +/* CPU_AHB_MBUS_CAUSE_INT_REG (CAMCIR) */
  43125. +
  43126. +#define CAMCIR_ARM_SELF_INT BIT0
  43127. +#define CAMCIR_ARM_TIMER0_INT_REQ BIT1
  43128. +#define CAMCIR_ARM_TIMER1_INT_REQ BIT2
  43129. +#define CAMCIR_ARM_WD_TIMER_INT_REQ BIT3
  43130. +
  43131. +
  43132. +/* AHB to Mbus Bridge Interrupt Mask Register*/
  43133. +/* CPU_AHB_MBUS_MASK_INT_REG (CAMMIR) */
  43134. +
  43135. +#define CAMCIR_ARM_SELF_INT_OFFS 0
  43136. +#define CAMCIR_ARM_SELF_INT_MASK BIT0
  43137. +#define CAMCIR_ARM_SELF_INT_EN (1 << CAMCIR_ARM_SELF_INT_OFFS)
  43138. +#define CAMCIR_ARM_SELF_INT_DIS (0 << CAMCIR_ARM_SELF_INT_OFFS)
  43139. +
  43140. +
  43141. +#define CAMCIR_ARM_TIMER0_INT_REQ_OFFS 1
  43142. +#define CAMCIR_ARM_TIMER0_INT_REQ_MASK BIT1
  43143. +#define CAMCIR_ARM_TIMER0_INT_REQ_EN (1 << CAMCIR_ARM_TIMER0_INT_REQ_OFFS)
  43144. +#define CAMCIR_ARM_TIMER0_INT_REQ_DIS (0 << CAMCIR_ARM_TIMER0_INT_REQ_OFFS)
  43145. +
  43146. +#define CAMCIR_ARM_TIMER1_INT_REQ_OFFS 2
  43147. +#define CAMCIR_ARM_TIMER1_INT_REQ_MASK BIT2
  43148. +#define CAMCIR_ARM_TIMER1_INT_REQ_EN (1 << CAMCIR_ARM_TIMER1_INT_REQ_OFFS)
  43149. +#define CAMCIR_ARM_TIMER1_INT_REQ_DIS (0 << CAMCIR_ARM_TIMER1_INT_REQ_OFFS)
  43150. +
  43151. +#define CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS 3
  43152. +#define CAMCIR_ARM_WD_TIMER_INT_REQ_MASK BIT3
  43153. +#define CAMCIR_ARM_WD_TIMER_INT_REQ_EN (1 << CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS)
  43154. +#define CAMCIR_ARM_WD_TIMER_INT_REQ_DIS (0 << CAMCIR_ARM_WD_TIMER_INT_REQ_OFFS)
  43155. +
  43156. +/* CPU FTDLL Config register (CFCR) fields */
  43157. +#define CFCR_FTDLL_ICACHE_TAG_OFFS 0
  43158. +#define CFCR_FTDLL_ICACHE_TAG_MASK (0x7F << CFCR_FTDLL_ICACHE_TAG_OFFS)
  43159. +#define CFCR_FTDLL_DCACHE_TAG_OFFS 8
  43160. +#define CFCR_FTDLL_DCACHE_TAG_MASK (0x7F << CFCR_FTDLL_DCACHE_TAG_OFFS)
  43161. +#define CFCR_FTDLL_OVERWRITE_ENABLE (1 << 15)
  43162. +/* For Orion 2 D2 only */
  43163. +#define CFCR_MRVL_CPU_ID_OFFS 16
  43164. +#define CFCR_MRVL_CPU_ID_MASK (0x1 << CFCR_MRVL_CPU_ID_OFFS)
  43165. +#define CFCR_ARM_CPU_ID (0x0 << CFCR_MRVL_CPU_ID_OFFS)
  43166. +#define CFCR_MRVL_CPU_ID (0x1 << CFCR_MRVL_CPU_ID_OFFS)
  43167. +#define CFCR_VFP_SUB_ARC_NUM_OFFS 7
  43168. +#define CFCR_VFP_SUB_ARC_NUM_MASK (0x1 << CFCR_VFP_SUB_ARC_NUM_OFFS)
  43169. +#define CFCR_VFP_SUB_ARC_NUM_1 (0x0 << CFCR_VFP_SUB_ARC_NUM_OFFS)
  43170. +#define CFCR_VFP_SUB_ARC_NUM_2 (0x1 << CFCR_VFP_SUB_ARC_NUM_OFFS)
  43171. +
  43172. +/* CPU_L2_CONFIG_REG fields */
  43173. +#ifdef MV_CPU_LE
  43174. +#define CL2CR_L2_ECC_EN_OFFS 2
  43175. +#define CL2CR_L2_WT_MODE_OFFS 4
  43176. +#else
  43177. +#define CL2CR_L2_ECC_EN_OFFS 26
  43178. +#define CL2CR_L2_WT_MODE_OFFS 28
  43179. +#endif
  43180. +
  43181. +#define CL2CR_L2_ECC_EN_MASK (1 << CL2CR_L2_ECC_EN_OFFS)
  43182. +#define CL2CR_L2_WT_MODE_MASK (1 << CL2CR_L2_WT_MODE_OFFS)
  43183. +
  43184. +/*******************************************/
  43185. +/* Main Interrupt Controller Registers Map */
  43186. +/*******************************************/
  43187. +
  43188. +#define CPU_MAIN_INT_CAUSE_REG 0x20200
  43189. +#define CPU_MAIN_IRQ_MASK_REG 0x20204
  43190. +#define CPU_MAIN_FIQ_MASK_REG 0x20208
  43191. +#define CPU_ENPOINT_MASK_REG 0x2020C
  43192. +#define CPU_MAIN_INT_CAUSE_HIGH_REG 0x20210
  43193. +#define CPU_MAIN_IRQ_MASK_HIGH_REG 0x20214
  43194. +#define CPU_MAIN_FIQ_MASK_HIGH_REG 0x20218
  43195. +#define CPU_ENPOINT_MASK_HIGH_REG 0x2021C
  43196. +
  43197. +
  43198. +/*******************************************/
  43199. +/* ARM Doorbell Registers Map */
  43200. +/*******************************************/
  43201. +
  43202. +#define CPU_HOST_TO_ARM_DRBL_REG 0x20400
  43203. +#define CPU_HOST_TO_ARM_MASK_REG 0x20404
  43204. +#define CPU_ARM_TO_HOST_DRBL_REG 0x20408
  43205. +#define CPU_ARM_TO_HOST_MASK_REG 0x2040C
  43206. +
  43207. +
  43208. +
  43209. +/* CPU control register map */
  43210. +/* Set bits means value is about to change according to new value */
  43211. +#define CPU_CONFIG_DEFAULT_MASK (CCR_VEC_INIT_LOC_MASK | CCR_AHB_ERROR_PROP_MASK)
  43212. +
  43213. +#define CPU_CONFIG_DEFAULT (CCR_VEC_INIT_LOC_FF00)
  43214. +
  43215. +/* CPU Control and status defaults */
  43216. +#define CPU_CTRL_STAT_DEFAULT_MASK (CCSR_PCI_ACCESS_MASK)
  43217. +
  43218. +
  43219. +#define CPU_CTRL_STAT_DEFAULT (CCSR_PCI_ACCESS_ENABLE)
  43220. +
  43221. +#endif /* __INCmvCpuIfRegsh */
  43222. +
  43223. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c
  43224. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c 1970-01-01 01:00:00.000000000 +0100
  43225. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.c 2011-08-01 14:38:19.000000000 +0200
  43226. @@ -0,0 +1,324 @@
  43227. +/*******************************************************************************
  43228. +Copyright (C) Marvell International Ltd. and its affiliates
  43229. +
  43230. +This software file (the "File") is owned and distributed by Marvell
  43231. +International Ltd. and/or its affiliates ("Marvell") under the following
  43232. +alternative licensing terms. Once you have made an election to distribute the
  43233. +File under one of the following license alternatives, please (i) delete this
  43234. +introductory statement regarding license alternatives, (ii) delete the two
  43235. +license alternatives that you have not elected to use and (iii) preserve the
  43236. +Marvell copyright notice above.
  43237. +
  43238. +********************************************************************************
  43239. +Marvell Commercial License Option
  43240. +
  43241. +If you received this File from Marvell and you have entered into a commercial
  43242. +license agreement (a "Commercial License") with Marvell, the File is licensed
  43243. +to you under the terms of the applicable Commercial License.
  43244. +
  43245. +********************************************************************************
  43246. +Marvell GPL License Option
  43247. +
  43248. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43249. +modify this File in accordance with the terms and conditions of the General
  43250. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  43251. +available along with the File in the license.txt file or by writing to the Free
  43252. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  43253. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  43254. +
  43255. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  43256. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  43257. +DISCLAIMED. The GPL License provides additional details about this warranty
  43258. +disclaimer.
  43259. +********************************************************************************
  43260. +Marvell BSD License Option
  43261. +
  43262. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43263. +modify this File under the following licensing terms.
  43264. +Redistribution and use in source and binary forms, with or without modification,
  43265. +are permitted provided that the following conditions are met:
  43266. +
  43267. + * Redistributions of source code must retain the above copyright notice,
  43268. + this list of conditions and the following disclaimer.
  43269. +
  43270. + * Redistributions in binary form must reproduce the above copyright
  43271. + notice, this list of conditions and the following disclaimer in the
  43272. + documentation and/or other materials provided with the distribution.
  43273. +
  43274. + * Neither the name of Marvell nor the names of its contributors may be
  43275. + used to endorse or promote products derived from this software without
  43276. + specific prior written permission.
  43277. +
  43278. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  43279. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  43280. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  43281. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  43282. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  43283. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  43284. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  43285. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  43286. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  43287. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  43288. +
  43289. +*******************************************************************************/
  43290. +#include "mvSysAudio.h"
  43291. +
  43292. +/*******************************************************************************
  43293. +* mvAudioWinSet - Set AUDIO target address window
  43294. +*
  43295. +* DESCRIPTION:
  43296. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  43297. +* address window, also known as address decode window.
  43298. +* After setting this target window, the AUDIO will be able to access the
  43299. +* target within the address window.
  43300. +*
  43301. +* INPUT:
  43302. +* winNum - AUDIO target address decode window number.
  43303. +* pAddrDecWin - AUDIO target window data structure.
  43304. +*
  43305. +* OUTPUT:
  43306. +* None.
  43307. +*
  43308. +* RETURN:
  43309. +* MV_ERROR if address window overlapps with other address decode windows.
  43310. +* MV_BAD_PARAM if base address is invalid parameter or target is
  43311. +* unknown.
  43312. +*
  43313. +*******************************************************************************/
  43314. +MV_STATUS mvAudioWinSet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin)
  43315. +{
  43316. + MV_TARGET_ATTRIB targetAttribs;
  43317. + MV_DEC_REGS decRegs;
  43318. +
  43319. + /* Parameter checking */
  43320. + if (winNum >= MV_AUDIO_MAX_ADDR_DECODE_WIN)
  43321. + {
  43322. + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
  43323. + return MV_BAD_PARAM;
  43324. + }
  43325. +
  43326. + /* check if address is aligned to the size */
  43327. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  43328. + {
  43329. + mvOsPrintf("mvAudioWinSet:Error setting AUDIO window %d to "\
  43330. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  43331. + winNum,
  43332. + mvCtrlTargetNameGet(pAddrDecWin->target),
  43333. + pAddrDecWin->addrWin.baseLow,
  43334. + pAddrDecWin->addrWin.size);
  43335. + return MV_ERROR;
  43336. + }
  43337. +
  43338. + decRegs.baseReg = 0;
  43339. + decRegs.sizeReg = 0;
  43340. +
  43341. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  43342. + {
  43343. + mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
  43344. + return MV_ERROR;
  43345. + }
  43346. +
  43347. + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
  43348. +
  43349. + /* set attributes */
  43350. + decRegs.sizeReg &= ~MV_AUDIO_WIN_ATTR_MASK;
  43351. + decRegs.sizeReg |= (targetAttribs.attrib << MV_AUDIO_WIN_ATTR_OFFSET);
  43352. +
  43353. + /* set target ID */
  43354. + decRegs.sizeReg &= ~MV_AUDIO_WIN_TARGET_MASK;
  43355. + decRegs.sizeReg |= (targetAttribs.targetId << MV_AUDIO_WIN_TARGET_OFFSET);
  43356. +
  43357. + if (pAddrDecWin->enable == MV_TRUE)
  43358. + {
  43359. + decRegs.sizeReg |= MV_AUDIO_WIN_ENABLE_MASK;
  43360. + }
  43361. + else
  43362. + {
  43363. + decRegs.sizeReg &= ~MV_AUDIO_WIN_ENABLE_MASK;
  43364. + }
  43365. +
  43366. + MV_REG_WRITE( MV_AUDIO_WIN_CTRL_REG(winNum), decRegs.sizeReg);
  43367. + MV_REG_WRITE( MV_AUDIO_WIN_BASE_REG(winNum), decRegs.baseReg);
  43368. +
  43369. + return MV_OK;
  43370. +}
  43371. +
  43372. +/*******************************************************************************
  43373. +* mvAudioWinGet - Get AUDIO peripheral target address window.
  43374. +*
  43375. +* DESCRIPTION:
  43376. +* Get AUDIO peripheral target address window.
  43377. +*
  43378. +* INPUT:
  43379. +* winNum - AUDIO target address decode window number.
  43380. +*
  43381. +* OUTPUT:
  43382. +* pAddrDecWin - AUDIO target window data structure.
  43383. +*
  43384. +* RETURN:
  43385. +* MV_ERROR if register parameters are invalid.
  43386. +*
  43387. +*******************************************************************************/
  43388. +MV_STATUS mvAudioWinGet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin)
  43389. +{
  43390. + MV_DEC_REGS decRegs;
  43391. + MV_TARGET_ATTRIB targetAttrib;
  43392. +
  43393. + /* Parameter checking */
  43394. + if (winNum >= MV_AUDIO_MAX_ADDR_DECODE_WIN)
  43395. + {
  43396. + mvOsPrintf("%s : ERR. Invalid winNum %d\n",
  43397. + __FUNCTION__, winNum);
  43398. + return MV_NOT_SUPPORTED;
  43399. + }
  43400. +
  43401. + decRegs.baseReg = MV_REG_READ( MV_AUDIO_WIN_BASE_REG(winNum) );
  43402. + decRegs.sizeReg = MV_REG_READ( MV_AUDIO_WIN_CTRL_REG(winNum) );
  43403. +
  43404. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
  43405. + {
  43406. + mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
  43407. + return MV_ERROR;
  43408. + }
  43409. +
  43410. + /* attrib and targetId */
  43411. + targetAttrib.attrib = (decRegs.sizeReg & MV_AUDIO_WIN_ATTR_MASK) >>
  43412. + MV_AUDIO_WIN_ATTR_OFFSET;
  43413. + targetAttrib.targetId = (decRegs.sizeReg & MV_AUDIO_WIN_TARGET_MASK) >>
  43414. + MV_AUDIO_WIN_TARGET_OFFSET;
  43415. +
  43416. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  43417. +
  43418. + /* Check if window is enabled */
  43419. + if(decRegs.sizeReg & MV_AUDIO_WIN_ENABLE_MASK)
  43420. + {
  43421. + pAddrDecWin->enable = MV_TRUE;
  43422. + }
  43423. + else
  43424. + {
  43425. + pAddrDecWin->enable = MV_FALSE;
  43426. + }
  43427. + return MV_OK;
  43428. +}
  43429. +/*******************************************************************************
  43430. +* mvAudioAddrDecShow - Print the AUDIO address decode map.
  43431. +*
  43432. +* DESCRIPTION:
  43433. +* This function print the AUDIO address decode map.
  43434. +*
  43435. +* INPUT:
  43436. +* None.
  43437. +*
  43438. +* OUTPUT:
  43439. +* None.
  43440. +*
  43441. +* RETURN:
  43442. +* None.
  43443. +*
  43444. +*******************************************************************************/
  43445. +MV_VOID mvAudioAddrDecShow(MV_VOID)
  43446. +{
  43447. +
  43448. + MV_AUDIO_DEC_WIN win;
  43449. + int i;
  43450. +
  43451. + if (MV_FALSE == mvCtrlPwrClckGet(AUDIO_UNIT_ID, 0))
  43452. + return;
  43453. +
  43454. +
  43455. + mvOsOutput( "\n" );
  43456. + mvOsOutput( "AUDIO:\n" );
  43457. + mvOsOutput( "----\n" );
  43458. +
  43459. + for( i = 0; i < MV_AUDIO_MAX_ADDR_DECODE_WIN; i++ )
  43460. + {
  43461. + memset( &win, 0, sizeof(MV_AUDIO_DEC_WIN) );
  43462. +
  43463. + mvOsOutput( "win%d - ", i );
  43464. +
  43465. + if( mvAudioWinGet( i, &win ) == MV_OK )
  43466. + {
  43467. + if( win.enable )
  43468. + {
  43469. + mvOsOutput( "%s base %08x, ",
  43470. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  43471. + mvOsOutput( "...." );
  43472. +
  43473. + mvSizePrint( win.addrWin.size );
  43474. +
  43475. + mvOsOutput( "\n" );
  43476. + }
  43477. + else
  43478. + mvOsOutput( "disable\n" );
  43479. + }
  43480. + }
  43481. +}
  43482. +
  43483. +
  43484. +/*******************************************************************************
  43485. +* mvAudioWinInit - Initialize the integrated AUDIO target address window.
  43486. +*
  43487. +* DESCRIPTION:
  43488. +* Initialize the AUDIO peripheral target address window.
  43489. +*
  43490. +* INPUT:
  43491. +*
  43492. +*
  43493. +* OUTPUT:
  43494. +*
  43495. +*
  43496. +* RETURN:
  43497. +* MV_ERROR if register parameters are invalid.
  43498. +*
  43499. +*******************************************************************************/
  43500. +MV_STATUS mvAudioInit(MV_VOID)
  43501. +{
  43502. + int winNum;
  43503. + MV_AUDIO_DEC_WIN audioWin;
  43504. + MV_CPU_DEC_WIN cpuAddrDecWin;
  43505. + MV_U32 status;
  43506. +
  43507. + mvAudioHalInit();
  43508. +
  43509. + /* Initiate Audio address decode */
  43510. +
  43511. + /* First disable all address decode windows */
  43512. + for(winNum = 0; winNum < MV_AUDIO_MAX_ADDR_DECODE_WIN; winNum++)
  43513. + {
  43514. + MV_U32 regVal = MV_REG_READ(MV_AUDIO_WIN_CTRL_REG(winNum));
  43515. + regVal &= ~MV_AUDIO_WIN_ENABLE_MASK;
  43516. + MV_REG_WRITE(MV_AUDIO_WIN_CTRL_REG(winNum), regVal);
  43517. + }
  43518. +
  43519. + for(winNum = 0; winNum < MV_AUDIO_MAX_ADDR_DECODE_WIN; winNum++)
  43520. + {
  43521. +
  43522. + /* We will set the Window to DRAM_CS0 in default */
  43523. + /* first get attributes from CPU If */
  43524. + status = mvCpuIfTargetWinGet(SDRAM_CS0,
  43525. + &cpuAddrDecWin);
  43526. +
  43527. + if (MV_OK != status)
  43528. + {
  43529. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  43530. + return MV_ERROR;
  43531. + }
  43532. +
  43533. + if (cpuAddrDecWin.enable == MV_TRUE)
  43534. + {
  43535. + audioWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  43536. + audioWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  43537. + audioWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  43538. + audioWin.enable = MV_TRUE;
  43539. + audioWin.target = SDRAM_CS0;
  43540. +
  43541. + if(MV_OK != mvAudioWinSet(winNum, &audioWin))
  43542. + {
  43543. + return MV_ERROR;
  43544. + }
  43545. + }
  43546. + }
  43547. +
  43548. + return MV_OK;
  43549. +}
  43550. +
  43551. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h
  43552. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h 1970-01-01 01:00:00.000000000 +0100
  43553. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysAudio.h 2011-08-01 14:38:19.000000000 +0200
  43554. @@ -0,0 +1,123 @@
  43555. +/*******************************************************************************
  43556. +Copyright (C) Marvell International Ltd. and its affiliates
  43557. +
  43558. +This software file (the "File") is owned and distributed by Marvell
  43559. +International Ltd. and/or its affiliates ("Marvell") under the following
  43560. +alternative licensing terms. Once you have made an election to distribute the
  43561. +File under one of the following license alternatives, please (i) delete this
  43562. +introductory statement regarding license alternatives, (ii) delete the two
  43563. +license alternatives that you have not elected to use and (iii) preserve the
  43564. +Marvell copyright notice above.
  43565. +
  43566. +********************************************************************************
  43567. +Marvell Commercial License Option
  43568. +
  43569. +If you received this File from Marvell and you have entered into a commercial
  43570. +license agreement (a "Commercial License") with Marvell, the File is licensed
  43571. +to you under the terms of the applicable Commercial License.
  43572. +
  43573. +********************************************************************************
  43574. +Marvell GPL License Option
  43575. +
  43576. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43577. +modify this File in accordance with the terms and conditions of the General
  43578. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  43579. +available along with the File in the license.txt file or by writing to the Free
  43580. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  43581. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  43582. +
  43583. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  43584. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  43585. +DISCLAIMED. The GPL License provides additional details about this warranty
  43586. +disclaimer.
  43587. +********************************************************************************
  43588. +Marvell BSD License Option
  43589. +
  43590. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43591. +modify this File under the following licensing terms.
  43592. +Redistribution and use in source and binary forms, with or without modification,
  43593. +are permitted provided that the following conditions are met:
  43594. +
  43595. + * Redistributions of source code must retain the above copyright notice,
  43596. + this list of conditions and the following disclaimer.
  43597. +
  43598. + * Redistributions in binary form must reproduce the above copyright
  43599. + notice, this list of conditions and the following disclaimer in the
  43600. + documentation and/or other materials provided with the distribution.
  43601. +
  43602. + * Neither the name of Marvell nor the names of its contributors may be
  43603. + used to endorse or promote products derived from this software without
  43604. + specific prior written permission.
  43605. +
  43606. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  43607. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  43608. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  43609. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  43610. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  43611. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  43612. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  43613. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  43614. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  43615. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  43616. +
  43617. +*******************************************************************************/
  43618. +#ifndef __INCMVSysAudioH
  43619. +#define __INCMVSysAudioH
  43620. +
  43621. +#include "mvCommon.h"
  43622. +#include "audio/mvAudio.h"
  43623. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  43624. +#include "ctrlEnv/sys/mvCpuIf.h"
  43625. +
  43626. +/***********************************/
  43627. +/* Audio Address Decoding registers*/
  43628. +/***********************************/
  43629. +
  43630. +#define MV_AUDIO_MAX_ADDR_DECODE_WIN 2
  43631. +#define MV_AUDIO_RECORD_WIN_NUM 0
  43632. +#define MV_AUDIO_PLAYBACK_WIN_NUM 1
  43633. +
  43634. +#define MV_AUDIO_WIN_CTRL_REG(win) (AUDIO_REG_BASE + 0xA04 + ((win)<<3))
  43635. +#define MV_AUDIO_WIN_BASE_REG(win) (AUDIO_REG_BASE + 0xA00 + ((win)<<3))
  43636. +
  43637. +#define MV_AUDIO_RECORD_WIN_CTRL_REG MV_AUDIO_WIN_CTRL_REG(MV_AUDIO_RECORD_WIN_NUM)
  43638. +#define MV_AUDIO_RECORD_WIN_BASE_REG MV_AUDIO_WIN_BASE_REG(MV_AUDIO_RECORD_WIN_NUM)
  43639. +#define MV_AUDIO_PLAYBACK_WIN_CTRL_REG MV_AUDIO_WIN_CTRL_REG(MV_AUDIO_PLAYBACK_WIN_NUM)
  43640. +#define MV_AUDIO_PLAYBACK_WIN_BASE_REG MV_AUDIO_WIN_BASE_REG(MV_AUDIO_PLAYBACK_WIN_NUM)
  43641. +
  43642. +
  43643. +/* BITs in Windows 0-3 Control and Base Registers */
  43644. +#define MV_AUDIO_WIN_ENABLE_BIT 0
  43645. +#define MV_AUDIO_WIN_ENABLE_MASK (1<<MV_AUDIO_WIN_ENABLE_BIT)
  43646. +
  43647. +#define MV_AUDIO_WIN_TARGET_OFFSET 4
  43648. +#define MV_AUDIO_WIN_TARGET_MASK (0xF<<MV_AUDIO_WIN_TARGET_OFFSET)
  43649. +
  43650. +#define MV_AUDIO_WIN_ATTR_OFFSET 8
  43651. +#define MV_AUDIO_WIN_ATTR_MASK (0xFF<<MV_AUDIO_WIN_ATTR_OFFSET)
  43652. +
  43653. +#define MV_AUDIO_WIN_SIZE_OFFSET 16
  43654. +#define MV_AUDIO_WIN_SIZE_MASK (0xFFFF<<MV_AUDIO_WIN_SIZE_OFFSET)
  43655. +
  43656. +#define MV_AUDIO_WIN_BASE_OFFSET 16
  43657. +#define MV_AUDIO_WIN_BASE_MASK (0xFFFF<<MV_AUDIO_WIN_BASE_OFFSET)
  43658. +
  43659. +
  43660. +typedef struct _mvAudioDecWin
  43661. +{
  43662. + MV_TARGET target;
  43663. + MV_ADDR_WIN addrWin; /* An address window*/
  43664. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  43665. +
  43666. +} MV_AUDIO_DEC_WIN;
  43667. +
  43668. +
  43669. +MV_STATUS mvAudioInit(MV_VOID);
  43670. +MV_STATUS mvAudioWinGet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin);
  43671. +MV_STATUS mvAudioWinSet(MV_U32 winNum, MV_AUDIO_DEC_WIN *pAddrDecWin);
  43672. +MV_STATUS mvAudioWinInit(MV_VOID);
  43673. +MV_VOID mvAudioAddrDecShow(MV_VOID);
  43674. +
  43675. +
  43676. +#endif
  43677. +
  43678. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c
  43679. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c 1970-01-01 01:00:00.000000000 +0100
  43680. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.c 2011-08-01 14:38:19.000000000 +0200
  43681. @@ -0,0 +1,382 @@
  43682. +/*******************************************************************************
  43683. +Copyright (C) Marvell International Ltd. and its affiliates
  43684. +
  43685. +This software file (the "File") is owned and distributed by Marvell
  43686. +International Ltd. and/or its affiliates ("Marvell") under the following
  43687. +alternative licensing terms. Once you have made an election to distribute the
  43688. +File under one of the following license alternatives, please (i) delete this
  43689. +introductory statement regarding license alternatives, (ii) delete the two
  43690. +license alternatives that you have not elected to use and (iii) preserve the
  43691. +Marvell copyright notice above.
  43692. +
  43693. +********************************************************************************
  43694. +Marvell Commercial License Option
  43695. +
  43696. +If you received this File from Marvell and you have entered into a commercial
  43697. +license agreement (a "Commercial License") with Marvell, the File is licensed
  43698. +to you under the terms of the applicable Commercial License.
  43699. +
  43700. +********************************************************************************
  43701. +Marvell GPL License Option
  43702. +
  43703. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43704. +modify this File in accordance with the terms and conditions of the General
  43705. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  43706. +available along with the File in the license.txt file or by writing to the Free
  43707. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  43708. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  43709. +
  43710. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  43711. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  43712. +DISCLAIMED. The GPL License provides additional details about this warranty
  43713. +disclaimer.
  43714. +********************************************************************************
  43715. +Marvell BSD License Option
  43716. +
  43717. +If you received this File from Marvell, you may opt to use, redistribute and/or
  43718. +modify this File under the following licensing terms.
  43719. +Redistribution and use in source and binary forms, with or without modification,
  43720. +are permitted provided that the following conditions are met:
  43721. +
  43722. + * Redistributions of source code must retain the above copyright notice,
  43723. + this list of conditions and the following disclaimer.
  43724. +
  43725. + * Redistributions in binary form must reproduce the above copyright
  43726. + notice, this list of conditions and the following disclaimer in the
  43727. + documentation and/or other materials provided with the distribution.
  43728. +
  43729. + * Neither the name of Marvell nor the names of its contributors may be
  43730. + used to endorse or promote products derived from this software without
  43731. + specific prior written permission.
  43732. +
  43733. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  43734. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  43735. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  43736. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  43737. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  43738. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  43739. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  43740. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  43741. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  43742. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  43743. +
  43744. +*******************************************************************************/
  43745. +
  43746. +#include "mvSysCesa.h"
  43747. +
  43748. +#if (MV_CESA_VERSION >= 2)
  43749. +MV_TARGET tdmaAddrDecPrioTable[] =
  43750. +{
  43751. +#if defined(MV_INCLUDE_SDRAM_CS0)
  43752. + SDRAM_CS0,
  43753. +#endif
  43754. +#if defined(MV_INCLUDE_SDRAM_CS1)
  43755. + SDRAM_CS1,
  43756. +#endif
  43757. +#if defined(MV_INCLUDE_SDRAM_CS2)
  43758. + SDRAM_CS2,
  43759. +#endif
  43760. +#if defined(MV_INCLUDE_SDRAM_CS3)
  43761. + SDRAM_CS3,
  43762. +#endif
  43763. +#if defined(MV_INCLUDE_PEX)
  43764. + PEX0_MEM,
  43765. +#endif
  43766. +
  43767. + TBL_TERM
  43768. +};
  43769. +
  43770. +/*******************************************************************************
  43771. +* mvCesaWinGet - Get TDMA target address window.
  43772. +*
  43773. +* DESCRIPTION:
  43774. +* Get TDMA target address window.
  43775. +*
  43776. +* INPUT:
  43777. +* winNum - TDMA target address decode window number.
  43778. +*
  43779. +* OUTPUT:
  43780. +* pDecWin - TDMA target window data structure.
  43781. +*
  43782. +* RETURN:
  43783. +* MV_ERROR if register parameters are invalid.
  43784. +*
  43785. +*******************************************************************************/
  43786. +static MV_STATUS mvCesaWinGet(MV_U32 winNum, MV_DEC_WIN *pDecWin)
  43787. +{
  43788. + MV_DEC_WIN_PARAMS winParam;
  43789. + MV_U32 sizeReg, baseReg;
  43790. +
  43791. + /* Parameter checking */
  43792. + if (winNum >= MV_CESA_TDMA_ADDR_DEC_WIN)
  43793. + {
  43794. + mvOsPrintf("%s : ERR. Invalid winNum %d\n",
  43795. + __FUNCTION__, winNum);
  43796. + return MV_NOT_SUPPORTED;
  43797. + }
  43798. +
  43799. + baseReg = MV_REG_READ( MV_CESA_TDMA_BASE_ADDR_REG(winNum) );
  43800. + sizeReg = MV_REG_READ( MV_CESA_TDMA_WIN_CTRL_REG(winNum) );
  43801. +
  43802. + /* Check if window is enabled */
  43803. + if(sizeReg & MV_CESA_TDMA_WIN_ENABLE_MASK)
  43804. + {
  43805. + pDecWin->enable = MV_TRUE;
  43806. +
  43807. + /* Extract window parameters from registers */
  43808. + winParam.targetId = (sizeReg & MV_CESA_TDMA_WIN_TARGET_MASK) >> MV_CESA_TDMA_WIN_TARGET_OFFSET;
  43809. + winParam.attrib = (sizeReg & MV_CESA_TDMA_WIN_ATTR_MASK) >> MV_CESA_TDMA_WIN_ATTR_OFFSET;
  43810. + winParam.size = (sizeReg & MV_CESA_TDMA_WIN_SIZE_MASK) >> MV_CESA_TDMA_WIN_SIZE_OFFSET;
  43811. + winParam.baseAddr = (baseReg & MV_CESA_TDMA_WIN_BASE_MASK);
  43812. +
  43813. + /* Translate the decode window parameters to address decode struct */
  43814. + if (MV_OK != mvCtrlParamsToAddrDec(&winParam, pDecWin))
  43815. + {
  43816. + mvOsPrintf("Failed to translate register parameters to CESA address" \
  43817. + " decode window structure\n");
  43818. + return MV_ERROR;
  43819. + }
  43820. + }
  43821. + else
  43822. + {
  43823. + pDecWin->enable = MV_FALSE;
  43824. + }
  43825. + return MV_OK;
  43826. +}
  43827. +
  43828. +/*******************************************************************************
  43829. +* cesaWinOverlapDetect - Detect CESA TDMA address windows overlapping
  43830. +*
  43831. +* DESCRIPTION:
  43832. +* An unpredicted behaviur is expected in case TDMA address decode
  43833. +* windows overlapps.
  43834. +* This function detects TDMA address decode windows overlapping of a
  43835. +* specified window. The function does not check the window itself for
  43836. +* overlapping. The function also skipps disabled address decode windows.
  43837. +*
  43838. +* INPUT:
  43839. +* winNum - address decode window number.
  43840. +* pAddrDecWin - An address decode window struct.
  43841. +*
  43842. +* OUTPUT:
  43843. +* None.
  43844. +*
  43845. +* RETURN:
  43846. +* MV_TRUE - if the given address window overlap current address
  43847. +* decode map,
  43848. +* MV_FALSE - otherwise, MV_ERROR if reading invalid data
  43849. +* from registers.
  43850. +*
  43851. +*******************************************************************************/
  43852. +static MV_STATUS cesaWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  43853. +{
  43854. + MV_U32 winNumIndex;
  43855. + MV_DEC_WIN addrDecWin;
  43856. +
  43857. + for(winNumIndex=0; winNumIndex<MV_CESA_TDMA_ADDR_DEC_WIN; winNumIndex++)
  43858. + {
  43859. + /* Do not check window itself */
  43860. + if (winNumIndex == winNum)
  43861. + {
  43862. + continue;
  43863. + }
  43864. +
  43865. + /* Get window parameters */
  43866. + if (MV_OK != mvCesaWinGet(winNumIndex, &addrDecWin))
  43867. + {
  43868. + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
  43869. + return MV_ERROR;
  43870. + }
  43871. +
  43872. + /* Do not check disabled windows */
  43873. + if(addrDecWin.enable == MV_FALSE)
  43874. + {
  43875. + continue;
  43876. + }
  43877. +
  43878. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  43879. + {
  43880. + return MV_TRUE;
  43881. + }
  43882. + }
  43883. + return MV_FALSE;
  43884. +}
  43885. +
  43886. +/*******************************************************************************
  43887. +* mvCesaTdmaWinSet - Set CESA TDMA target address window
  43888. +*
  43889. +* DESCRIPTION:
  43890. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  43891. +* address window, also known as address decode window.
  43892. +* After setting this target window, the CESA TDMA will be able to access the
  43893. +* target within the address window.
  43894. +*
  43895. +* INPUT:
  43896. +* winNum - CESA TDMA target address decode window number.
  43897. +* pAddrDecWin - CESA TDMA target window data structure.
  43898. +*
  43899. +* OUTPUT:
  43900. +* None.
  43901. +*
  43902. +* RETURN:
  43903. +* MV_ERROR - if address window overlapps with other address decode windows.
  43904. +* MV_BAD_PARAM - if base address is invalid parameter or target is
  43905. +* unknown.
  43906. +*
  43907. +*******************************************************************************/
  43908. +static MV_STATUS mvCesaTdmaWinSet(MV_U32 winNum, MV_DEC_WIN *pDecWin)
  43909. +{
  43910. + MV_DEC_WIN_PARAMS winParams;
  43911. + MV_U32 sizeReg, baseReg;
  43912. +
  43913. + /* Parameter checking */
  43914. + if (winNum >= MV_CESA_TDMA_ADDR_DEC_WIN)
  43915. + {
  43916. + mvOsPrintf("mvCesaTdmaWinSet: ERR. Invalid win num %d\n",winNum);
  43917. + return MV_BAD_PARAM;
  43918. + }
  43919. +
  43920. + /* Check if the requested window overlapps with current windows */
  43921. + if (MV_TRUE == cesaWinOverlapDetect(winNum, &pDecWin->addrWin))
  43922. + {
  43923. + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
  43924. + return MV_ERROR;
  43925. + }
  43926. +
  43927. + /* check if address is aligned to the size */
  43928. + if(MV_IS_NOT_ALIGN(pDecWin->addrWin.baseLow, pDecWin->addrWin.size))
  43929. + {
  43930. + mvOsPrintf("mvCesaTdmaWinSet: Error setting CESA TDMA window %d to "\
  43931. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  43932. + winNum,
  43933. + mvCtrlTargetNameGet(pDecWin->target),
  43934. + pDecWin->addrWin.baseLow,
  43935. + pDecWin->addrWin.size);
  43936. + return MV_ERROR;
  43937. + }
  43938. +
  43939. + if(MV_OK != mvCtrlAddrDecToParams(pDecWin, &winParams))
  43940. + {
  43941. + mvOsPrintf("%s: mvCtrlAddrDecToParams Failed\n", __FUNCTION__);
  43942. + return MV_ERROR;
  43943. + }
  43944. +
  43945. + /* set Size, Attributes and TargetID */
  43946. + sizeReg = (((winParams.targetId << MV_CESA_TDMA_WIN_TARGET_OFFSET) & MV_CESA_TDMA_WIN_TARGET_MASK) |
  43947. + ((winParams.attrib << MV_CESA_TDMA_WIN_ATTR_OFFSET) & MV_CESA_TDMA_WIN_ATTR_MASK) |
  43948. + ((winParams.size << MV_CESA_TDMA_WIN_SIZE_OFFSET) & MV_CESA_TDMA_WIN_SIZE_MASK));
  43949. +
  43950. + if (pDecWin->enable == MV_TRUE)
  43951. + {
  43952. + sizeReg |= MV_CESA_TDMA_WIN_ENABLE_MASK;
  43953. + }
  43954. + else
  43955. + {
  43956. + sizeReg &= ~MV_CESA_TDMA_WIN_ENABLE_MASK;
  43957. + }
  43958. +
  43959. + /* Update Base value */
  43960. + baseReg = (winParams.baseAddr & MV_CESA_TDMA_WIN_BASE_MASK);
  43961. +
  43962. + MV_REG_WRITE( MV_CESA_TDMA_WIN_CTRL_REG(winNum), sizeReg);
  43963. + MV_REG_WRITE( MV_CESA_TDMA_BASE_ADDR_REG(winNum), baseReg);
  43964. +
  43965. + return MV_OK;
  43966. +}
  43967. +
  43968. +
  43969. +static MV_STATUS mvCesaTdmaAddrDecInit (void)
  43970. +{
  43971. + MV_U32 winNum;
  43972. + MV_STATUS status;
  43973. + MV_CPU_DEC_WIN cpuAddrDecWin;
  43974. + MV_DEC_WIN cesaWin;
  43975. + MV_U32 winPrioIndex = 0;
  43976. +
  43977. + /* First disable all address decode windows */
  43978. + for(winNum=0; winNum<MV_CESA_TDMA_ADDR_DEC_WIN; winNum++)
  43979. + {
  43980. + MV_REG_BIT_RESET(MV_CESA_TDMA_WIN_CTRL_REG(winNum), MV_CESA_TDMA_WIN_ENABLE_MASK);
  43981. + }
  43982. +
  43983. + /* Go through all windows in user table until table terminator */
  43984. + winNum = 0;
  43985. + while( (tdmaAddrDecPrioTable[winPrioIndex] != TBL_TERM) &&
  43986. + (winNum < MV_CESA_TDMA_ADDR_DEC_WIN) ) {
  43987. +
  43988. + /* first get attributes from CPU If */
  43989. + status = mvCpuIfTargetWinGet(tdmaAddrDecPrioTable[winPrioIndex],
  43990. + &cpuAddrDecWin);
  43991. + if(MV_NO_SUCH == status){
  43992. + winPrioIndex++;
  43993. + continue;
  43994. + }
  43995. +
  43996. + if (MV_OK != status)
  43997. + {
  43998. + mvOsPrintf("cesaInit: TargetWinGet failed. winNum=%d, winIdx=%d, target=%d, status=0x%x\n",
  43999. + winNum, winPrioIndex, tdmaAddrDecPrioTable[winPrioIndex], status);
  44000. + return MV_ERROR;
  44001. + }
  44002. + if (cpuAddrDecWin.enable == MV_TRUE)
  44003. + {
  44004. + cesaWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  44005. + cesaWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  44006. + cesaWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  44007. + cesaWin.enable = MV_TRUE;
  44008. + cesaWin.target = tdmaAddrDecPrioTable[winPrioIndex];
  44009. +
  44010. +#if defined(MV646xx)
  44011. + /* Get the default attributes for that target window */
  44012. + mvCtrlDefAttribGet(cesaWin.target, &cesaWin.addrWinAttr);
  44013. +#endif /* MV646xx */
  44014. +
  44015. + if(MV_OK != mvCesaTdmaWinSet(winNum, &cesaWin))
  44016. + {
  44017. + mvOsPrintf("mvCesaTdmaWinSet FAILED: winNum=%d\n",
  44018. + winNum);
  44019. + return MV_ERROR;
  44020. + }
  44021. + winNum++;
  44022. + }
  44023. + winPrioIndex++;
  44024. + }
  44025. + return MV_OK;
  44026. +}
  44027. +#endif /* MV_CESA_VERSION >= 2 */
  44028. +
  44029. +
  44030. +
  44031. +
  44032. +MV_STATUS mvCesaInit (int numOfSession, int queueDepth, char* pSramBase, void *osHandle)
  44033. +{
  44034. + MV_U32 cesaCryptEngBase;
  44035. + MV_CPU_DEC_WIN addrDecWin;
  44036. +
  44037. + if(sizeof(MV_CESA_SRAM_MAP) > MV_CESA_SRAM_SIZE)
  44038. + {
  44039. + mvOsPrintf("mvCesaInit: Wrong SRAM map - %ld > %d\n",
  44040. + sizeof(MV_CESA_SRAM_MAP), MV_CESA_SRAM_SIZE);
  44041. + return MV_FAIL;
  44042. + }
  44043. +#if 0
  44044. + if (mvCpuIfTargetWinGet(CRYPT_ENG, &addrDecWin) == MV_OK)
  44045. + cesaCryptEngBase = addrDecWin.addrWin.baseLow;
  44046. + else
  44047. + {
  44048. + mvOsPrintf("mvCesaInit: ERR. mvCpuIfTargetWinGet failed\n");
  44049. + return MV_ERROR;
  44050. + }
  44051. +#else
  44052. + cesaCryptEngBase = (MV_U32)pSramBase;
  44053. +#endif
  44054. +
  44055. +#if 0 /* Already done in the platform init */
  44056. +#if (MV_CESA_VERSION >= 2)
  44057. + mvCesaTdmaAddrDecInit();
  44058. +#endif /* MV_CESA_VERSION >= 2 */
  44059. +#endif
  44060. + return mvCesaHalInit(numOfSession, queueDepth, pSramBase, cesaCryptEngBase,
  44061. + osHandle);
  44062. +
  44063. +}
  44064. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h
  44065. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h 1970-01-01 01:00:00.000000000 +0100
  44066. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysCesa.h 2011-08-01 14:38:19.000000000 +0200
  44067. @@ -0,0 +1,100 @@
  44068. +/*******************************************************************************
  44069. +Copyright (C) Marvell International Ltd. and its affiliates
  44070. +
  44071. +This software file (the "File") is owned and distributed by Marvell
  44072. +International Ltd. and/or its affiliates ("Marvell") under the following
  44073. +alternative licensing terms. Once you have made an election to distribute the
  44074. +File under one of the following license alternatives, please (i) delete this
  44075. +introductory statement regarding license alternatives, (ii) delete the two
  44076. +license alternatives that you have not elected to use and (iii) preserve the
  44077. +Marvell copyright notice above.
  44078. +
  44079. +********************************************************************************
  44080. +Marvell Commercial License Option
  44081. +
  44082. +If you received this File from Marvell and you have entered into a commercial
  44083. +license agreement (a "Commercial License") with Marvell, the File is licensed
  44084. +to you under the terms of the applicable Commercial License.
  44085. +
  44086. +********************************************************************************
  44087. +Marvell GPL License Option
  44088. +
  44089. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44090. +modify this File in accordance with the terms and conditions of the General
  44091. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  44092. +available along with the File in the license.txt file or by writing to the Free
  44093. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  44094. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  44095. +
  44096. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  44097. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  44098. +DISCLAIMED. The GPL License provides additional details about this warranty
  44099. +disclaimer.
  44100. +********************************************************************************
  44101. +Marvell BSD License Option
  44102. +
  44103. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44104. +modify this File under the following licensing terms.
  44105. +Redistribution and use in source and binary forms, with or without modification,
  44106. +are permitted provided that the following conditions are met:
  44107. +
  44108. + * Redistributions of source code must retain the above copyright notice,
  44109. + this list of conditions and the following disclaimer.
  44110. +
  44111. + * Redistributions in binary form must reproduce the above copyright
  44112. + notice, this list of conditions and the following disclaimer in the
  44113. + documentation and/or other materials provided with the distribution.
  44114. +
  44115. + * Neither the name of Marvell nor the names of its contributors may be
  44116. + used to endorse or promote products derived from this software without
  44117. + specific prior written permission.
  44118. +
  44119. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  44120. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  44121. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  44122. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  44123. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  44124. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  44125. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  44126. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  44127. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  44128. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44129. +
  44130. +*******************************************************************************/
  44131. +
  44132. +#ifndef __mvSysCesa_h__
  44133. +#define __mvSysCesa_h__
  44134. +
  44135. +
  44136. +#include "mvCommon.h"
  44137. +#include "cesa/mvCesa.h"
  44138. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  44139. +#include "ctrlEnv/sys/mvCpuIf.h"
  44140. +
  44141. +/***************************** TDMA Registers *************************************/
  44142. +
  44143. +#define MV_CESA_TDMA_ADDR_DEC_WIN 4
  44144. +
  44145. +#define MV_CESA_TDMA_BASE_ADDR_REG(win) (MV_CESA_TDMA_REG_BASE + 0xa00 + (win<<3))
  44146. +
  44147. +#define MV_CESA_TDMA_WIN_CTRL_REG(win) (MV_CESA_TDMA_REG_BASE + 0xa04 + (win<<3))
  44148. +
  44149. +#define MV_CESA_TDMA_WIN_ENABLE_BIT 0
  44150. +#define MV_CESA_TDMA_WIN_ENABLE_MASK (1 << MV_CESA_TDMA_WIN_ENABLE_BIT)
  44151. +
  44152. +#define MV_CESA_TDMA_WIN_TARGET_OFFSET 4
  44153. +#define MV_CESA_TDMA_WIN_TARGET_MASK (0xf << MV_CESA_TDMA_WIN_TARGET_OFFSET)
  44154. +
  44155. +#define MV_CESA_TDMA_WIN_ATTR_OFFSET 8
  44156. +#define MV_CESA_TDMA_WIN_ATTR_MASK (0xff << MV_CESA_TDMA_WIN_ATTR_OFFSET)
  44157. +
  44158. +#define MV_CESA_TDMA_WIN_SIZE_OFFSET 16
  44159. +#define MV_CESA_TDMA_WIN_SIZE_MASK (0xFFFF << MV_CESA_TDMA_WIN_SIZE_OFFSET)
  44160. +
  44161. +#define MV_CESA_TDMA_WIN_BASE_OFFSET 16
  44162. +#define MV_CESA_TDMA_WIN_BASE_MASK (0xFFFF << MV_CESA_TDMA_WIN_BASE_OFFSET)
  44163. +
  44164. +
  44165. +MV_STATUS mvCesaInit (int numOfSession, int queueDepth, char* pSramBase, void *osHandle);
  44166. +
  44167. +#endif
  44168. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c
  44169. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c 1970-01-01 01:00:00.000000000 +0100
  44170. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.c 2011-08-01 14:38:19.000000000 +0200
  44171. @@ -0,0 +1,348 @@
  44172. +/*******************************************************************************
  44173. +Copyright (C) Marvell International Ltd. and its affiliates
  44174. +
  44175. +This software file (the "File") is owned and distributed by Marvell
  44176. +International Ltd. and/or its affiliates ("Marvell") under the following
  44177. +alternative licensing terms. Once you have made an election to distribute the
  44178. +File under one of the following license alternatives, please (i) delete this
  44179. +introductory statement regarding license alternatives, (ii) delete the two
  44180. +license alternatives that you have not elected to use and (iii) preserve the
  44181. +Marvell copyright notice above.
  44182. +
  44183. +********************************************************************************
  44184. +Marvell Commercial License Option
  44185. +
  44186. +If you received this File from Marvell and you have entered into a commercial
  44187. +license agreement (a "Commercial License") with Marvell, the File is licensed
  44188. +to you under the terms of the applicable Commercial License.
  44189. +
  44190. +********************************************************************************
  44191. +Marvell GPL License Option
  44192. +
  44193. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44194. +modify this File in accordance with the terms and conditions of the General
  44195. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  44196. +available along with the File in the license.txt file or by writing to the Free
  44197. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  44198. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  44199. +
  44200. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  44201. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  44202. +DISCLAIMED. The GPL License provides additional details about this warranty
  44203. +disclaimer.
  44204. +********************************************************************************
  44205. +Marvell BSD License Option
  44206. +
  44207. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44208. +modify this File under the following licensing terms.
  44209. +Redistribution and use in source and binary forms, with or without modification,
  44210. +are permitted provided that the following conditions are met:
  44211. +
  44212. + * Redistributions of source code must retain the above copyright notice,
  44213. + this list of conditions and the following disclaimer.
  44214. +
  44215. + * Redistributions in binary form must reproduce the above copyright
  44216. + notice, this list of conditions and the following disclaimer in the
  44217. + documentation and/or other materials provided with the distribution.
  44218. +
  44219. + * Neither the name of Marvell nor the names of its contributors may be
  44220. + used to endorse or promote products derived from this software without
  44221. + specific prior written permission.
  44222. +
  44223. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  44224. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  44225. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  44226. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  44227. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  44228. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  44229. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  44230. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  44231. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  44232. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44233. +
  44234. +*******************************************************************************/
  44235. +
  44236. +
  44237. +/* includes */
  44238. +
  44239. +#include "ddr2/mvDramIf.h"
  44240. +#include "ctrlEnv/sys/mvCpuIf.h"
  44241. +#include "ctrlEnv/sys/mvSysDram.h"
  44242. +
  44243. +/* #define MV_DEBUG */
  44244. +#ifdef MV_DEBUG
  44245. +#define DB(x) x
  44246. +#else
  44247. +#define DB(x)
  44248. +#endif
  44249. +
  44250. +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
  44251. +
  44252. +/*******************************************************************************
  44253. +* mvDramIfWinSet - Set DRAM interface address decode window
  44254. +*
  44255. +* DESCRIPTION:
  44256. +* This function sets DRAM interface address decode window.
  44257. +*
  44258. +* INPUT:
  44259. +* target - System target. Use only SDRAM targets.
  44260. +* pAddrDecWin - SDRAM address window structure.
  44261. +*
  44262. +* OUTPUT:
  44263. +* None
  44264. +*
  44265. +* RETURN:
  44266. +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
  44267. +* otherwise.
  44268. +*******************************************************************************/
  44269. +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
  44270. +{
  44271. + MV_U32 baseReg=0,sizeReg=0;
  44272. + MV_U32 baseToReg=0 , sizeToReg=0;
  44273. +
  44274. + /* Check parameters */
  44275. + if (!MV_TARGET_IS_DRAM(target))
  44276. + {
  44277. + mvOsPrintf("mvDramIfWinSet: target %d is not SDRAM\n", target);
  44278. + return MV_BAD_PARAM;
  44279. + }
  44280. +
  44281. + /* Check if the requested window overlaps with current enabled windows */
  44282. + if (MV_TRUE == sdramIfWinOverlap(target, &pAddrDecWin->addrWin))
  44283. + {
  44284. + mvOsPrintf("mvDramIfWinSet: ERR. Target %d overlaps\n", target);
  44285. + return MV_BAD_PARAM;
  44286. + }
  44287. +
  44288. + /* check if address is aligned to the size */
  44289. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  44290. + {
  44291. + mvOsPrintf("mvDramIfWinSet:Error setting DRAM interface window %d."\
  44292. + "\nAddress 0x%08x is unaligned to size 0x%x.\n",
  44293. + target,
  44294. + pAddrDecWin->addrWin.baseLow,
  44295. + pAddrDecWin->addrWin.size);
  44296. + return MV_ERROR;
  44297. + }
  44298. +
  44299. + /* read base register*/
  44300. + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(0,target));
  44301. +
  44302. + /* read size register */
  44303. + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(0,target));
  44304. +
  44305. + /* BaseLow[31:16] => base register [31:16] */
  44306. + baseToReg = pAddrDecWin->addrWin.baseLow & SCBAR_BASE_MASK;
  44307. +
  44308. + /* Write to address decode Base Address Register */
  44309. + baseReg &= ~SCBAR_BASE_MASK;
  44310. + baseReg |= baseToReg;
  44311. +
  44312. + /* Translate the given window size to register format */
  44313. + sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, SCSR_SIZE_ALIGNMENT);
  44314. +
  44315. + /* Size parameter validity check. */
  44316. + if (-1 == sizeToReg)
  44317. + {
  44318. + mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n",target);
  44319. + return MV_BAD_PARAM;
  44320. + }
  44321. +
  44322. + /* set size */
  44323. + sizeReg &= ~SCSR_SIZE_MASK;
  44324. + /* Size is located at upper 16 bits */
  44325. + sizeReg |= (sizeToReg << SCSR_SIZE_OFFS);
  44326. +
  44327. + /* enable/Disable */
  44328. + if (MV_TRUE == pAddrDecWin->enable)
  44329. + {
  44330. + sizeReg |= SCSR_WIN_EN;
  44331. + }
  44332. + else
  44333. + {
  44334. + sizeReg &= ~SCSR_WIN_EN;
  44335. + }
  44336. +
  44337. + /* 3) Write to address decode Base Address Register */
  44338. + MV_REG_WRITE(SDRAM_BASE_ADDR_REG(0,target), baseReg);
  44339. +
  44340. + /* Write to address decode Size Register */
  44341. + MV_REG_WRITE(SDRAM_SIZE_REG(0,target), sizeReg);
  44342. +
  44343. + return MV_OK;
  44344. +}
  44345. +/*******************************************************************************
  44346. +* mvDramIfWinGet - Get DRAM interface address decode window
  44347. +*
  44348. +* DESCRIPTION:
  44349. +* This function gets DRAM interface address decode window.
  44350. +*
  44351. +* INPUT:
  44352. +* target - System target. Use only SDRAM targets.
  44353. +*
  44354. +* OUTPUT:
  44355. +* pAddrDecWin - SDRAM address window structure.
  44356. +*
  44357. +* RETURN:
  44358. +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
  44359. +* otherwise.
  44360. +*******************************************************************************/
  44361. +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
  44362. +{
  44363. + MV_U32 baseReg,sizeReg;
  44364. + MV_U32 sizeRegVal;
  44365. + /* Check parameters */
  44366. + if (!MV_TARGET_IS_DRAM(target))
  44367. + {
  44368. + mvOsPrintf("mvDramIfWinGet: target %d is Illigal\n", target);
  44369. + return MV_ERROR;
  44370. + }
  44371. +
  44372. + /* Read base and size registers */
  44373. + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(0,target));
  44374. + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(0,target));
  44375. +
  44376. + sizeRegVal = (sizeReg & SCSR_SIZE_MASK) >> SCSR_SIZE_OFFS;
  44377. +
  44378. + pAddrDecWin->addrWin.size = ctrlRegToSize(sizeRegVal,
  44379. + SCSR_SIZE_ALIGNMENT);
  44380. +
  44381. + /* Check if ctrlRegToSize returned OK */
  44382. + if (-1 == pAddrDecWin->addrWin.size)
  44383. + {
  44384. + mvOsPrintf("mvDramIfWinGet: size of target %d is Illigal\n", target);
  44385. + return MV_ERROR;
  44386. + }
  44387. +
  44388. + /* Extract base address */
  44389. + /* Base register [31:16] ==> baseLow[31:16] */
  44390. + pAddrDecWin->addrWin.baseLow = baseReg & SCBAR_BASE_MASK;
  44391. +
  44392. + pAddrDecWin->addrWin.baseHigh = 0;
  44393. +
  44394. +
  44395. + if (sizeReg & SCSR_WIN_EN)
  44396. + {
  44397. + pAddrDecWin->enable = MV_TRUE;
  44398. + }
  44399. + else
  44400. + {
  44401. + pAddrDecWin->enable = MV_FALSE;
  44402. + }
  44403. +
  44404. + return MV_OK;
  44405. +}
  44406. +/*******************************************************************************
  44407. +* mvDramIfWinEnable - Enable/Disable SDRAM address decode window
  44408. +*
  44409. +* DESCRIPTION:
  44410. +* This function enable/Disable SDRAM address decode window.
  44411. +*
  44412. +* INPUT:
  44413. +* target - System target. Use only SDRAM targets.
  44414. +*
  44415. +* OUTPUT:
  44416. +* None.
  44417. +*
  44418. +* RETURN:
  44419. +* MV_ERROR in case function parameter are invalid, MV_OK otherewise.
  44420. +*
  44421. +*******************************************************************************/
  44422. +MV_STATUS mvDramIfWinEnable(MV_TARGET target, MV_BOOL enable)
  44423. +{
  44424. + MV_DRAM_DEC_WIN addrDecWin;
  44425. +
  44426. + /* Check parameters */
  44427. + if (!MV_TARGET_IS_DRAM(target))
  44428. + {
  44429. + mvOsPrintf("mvDramIfWinEnable: target %d is Illigal\n", target);
  44430. + return MV_ERROR;
  44431. + }
  44432. +
  44433. + if (enable == MV_TRUE)
  44434. + { /* First check for overlap with other enabled windows */
  44435. + if (MV_OK != mvDramIfWinGet(target, &addrDecWin))
  44436. + {
  44437. + mvOsPrintf("mvDramIfWinEnable:ERR. Getting target %d failed.\n",
  44438. + target);
  44439. + return MV_ERROR;
  44440. + }
  44441. + /* Check for overlapping */
  44442. + if (MV_FALSE == sdramIfWinOverlap(target, &(addrDecWin.addrWin)))
  44443. + {
  44444. + /* No Overlap. Enable address decode winNum window */
  44445. + MV_REG_BIT_SET(SDRAM_SIZE_REG(0,target), SCSR_WIN_EN);
  44446. + }
  44447. + else
  44448. + { /* Overlap detected */
  44449. + mvOsPrintf("mvDramIfWinEnable: ERR. Target %d overlap detect\n",
  44450. + target);
  44451. + return MV_ERROR;
  44452. + }
  44453. + }
  44454. + else
  44455. + { /* Disable address decode winNum window */
  44456. + MV_REG_BIT_RESET(SDRAM_SIZE_REG(0, target), SCSR_WIN_EN);
  44457. + }
  44458. +
  44459. + return MV_OK;
  44460. +}
  44461. +
  44462. +/*******************************************************************************
  44463. +* sdramIfWinOverlap - Check if an address window overlap an SDRAM address window
  44464. +*
  44465. +* DESCRIPTION:
  44466. +* This function scan each SDRAM address decode window to test if it
  44467. +* overlapps the given address windoow
  44468. +*
  44469. +* INPUT:
  44470. +* target - SDRAM target where the function skips checking.
  44471. +* pAddrDecWin - The tested address window for overlapping with
  44472. +* SDRAM windows.
  44473. +*
  44474. +* OUTPUT:
  44475. +* None.
  44476. +*
  44477. +* RETURN:
  44478. +* MV_TRUE if the given address window overlaps any enabled address
  44479. +* decode map, MV_FALSE otherwise.
  44480. +*
  44481. +*******************************************************************************/
  44482. +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
  44483. +{
  44484. + MV_TARGET targetNum;
  44485. + MV_DRAM_DEC_WIN addrDecWin;
  44486. +
  44487. + for(targetNum = SDRAM_CS0; targetNum < MV_DRAM_MAX_CS ; targetNum++)
  44488. + {
  44489. + /* don't check our winNum or illegal targets */
  44490. + if (targetNum == target)
  44491. + {
  44492. + continue;
  44493. + }
  44494. +
  44495. + /* Get window parameters */
  44496. + if (MV_OK != mvDramIfWinGet(targetNum, &addrDecWin))
  44497. + {
  44498. + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
  44499. + return MV_ERROR;
  44500. + }
  44501. +
  44502. + /* Do not check disabled windows */
  44503. + if (MV_FALSE == addrDecWin.enable)
  44504. + {
  44505. + continue;
  44506. + }
  44507. +
  44508. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
  44509. + {
  44510. + mvOsPrintf(
  44511. + "sdramIfWinOverlap: Required target %d overlap winNum %d\n",
  44512. + target, targetNum);
  44513. + return MV_TRUE;
  44514. + }
  44515. + }
  44516. +
  44517. + return MV_FALSE;
  44518. +}
  44519. +
  44520. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h
  44521. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h 1970-01-01 01:00:00.000000000 +0100
  44522. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysDram.h 2011-08-01 14:38:19.000000000 +0200
  44523. @@ -0,0 +1,80 @@
  44524. +/*******************************************************************************
  44525. +Copyright (C) Marvell International Ltd. and its affiliates
  44526. +
  44527. +This software file (the "File") is owned and distributed by Marvell
  44528. +International Ltd. and/or its affiliates ("Marvell") under the following
  44529. +alternative licensing terms. Once you have made an election to distribute the
  44530. +File under one of the following license alternatives, please (i) delete this
  44531. +introductory statement regarding license alternatives, (ii) delete the two
  44532. +license alternatives that you have not elected to use and (iii) preserve the
  44533. +Marvell copyright notice above.
  44534. +
  44535. +********************************************************************************
  44536. +Marvell Commercial License Option
  44537. +
  44538. +If you received this File from Marvell and you have entered into a commercial
  44539. +license agreement (a "Commercial License") with Marvell, the File is licensed
  44540. +to you under the terms of the applicable Commercial License.
  44541. +
  44542. +********************************************************************************
  44543. +Marvell GPL License Option
  44544. +
  44545. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44546. +modify this File in accordance with the terms and conditions of the General
  44547. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  44548. +available along with the File in the license.txt file or by writing to the Free
  44549. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  44550. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  44551. +
  44552. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  44553. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  44554. +DISCLAIMED. The GPL License provides additional details about this warranty
  44555. +disclaimer.
  44556. +********************************************************************************
  44557. +Marvell BSD License Option
  44558. +
  44559. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44560. +modify this File under the following licensing terms.
  44561. +Redistribution and use in source and binary forms, with or without modification,
  44562. +are permitted provided that the following conditions are met:
  44563. +
  44564. + * Redistributions of source code must retain the above copyright notice,
  44565. + this list of conditions and the following disclaimer.
  44566. +
  44567. + * Redistributions in binary form must reproduce the above copyright
  44568. + notice, this list of conditions and the following disclaimer in the
  44569. + documentation and/or other materials provided with the distribution.
  44570. +
  44571. + * Neither the name of Marvell nor the names of its contributors may be
  44572. + used to endorse or promote products derived from this software without
  44573. + specific prior written permission.
  44574. +
  44575. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  44576. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  44577. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  44578. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  44579. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  44580. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  44581. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  44582. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  44583. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  44584. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44585. +
  44586. +*******************************************************************************/
  44587. +
  44588. +
  44589. +#ifndef __sysDram
  44590. +#define __sysDram
  44591. +
  44592. +/* This structure describes CPU interface address decode window */
  44593. +typedef struct _mvDramIfDecWin
  44594. +{
  44595. + MV_ADDR_WIN addrWin; /* An address window*/
  44596. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  44597. +}MV_DRAM_DEC_WIN;
  44598. +
  44599. +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
  44600. +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
  44601. +MV_STATUS mvDramIfWinEnable(MV_TARGET target, MV_BOOL enable);
  44602. +
  44603. +#endif
  44604. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c
  44605. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c 1970-01-01 01:00:00.000000000 +0100
  44606. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.c 2011-08-01 14:38:19.000000000 +0200
  44607. @@ -0,0 +1,658 @@
  44608. +/*******************************************************************************
  44609. +Copyright (C) Marvell International Ltd. and its affiliates
  44610. +
  44611. +This software file (the "File") is owned and distributed by Marvell
  44612. +International Ltd. and/or its affiliates ("Marvell") under the following
  44613. +alternative licensing terms. Once you have made an election to distribute the
  44614. +File under one of the following license alternatives, please (i) delete this
  44615. +introductory statement regarding license alternatives, (ii) delete the two
  44616. +license alternatives that you have not elected to use and (iii) preserve the
  44617. +Marvell copyright notice above.
  44618. +
  44619. +********************************************************************************
  44620. +Marvell Commercial License Option
  44621. +
  44622. +If you received this File from Marvell and you have entered into a commercial
  44623. +license agreement (a "Commercial License") with Marvell, the File is licensed
  44624. +to you under the terms of the applicable Commercial License.
  44625. +
  44626. +********************************************************************************
  44627. +Marvell GPL License Option
  44628. +
  44629. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44630. +modify this File in accordance with the terms and conditions of the General
  44631. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  44632. +available along with the File in the license.txt file or by writing to the Free
  44633. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  44634. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  44635. +
  44636. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  44637. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  44638. +DISCLAIMED. The GPL License provides additional details about this warranty
  44639. +disclaimer.
  44640. +********************************************************************************
  44641. +Marvell BSD License Option
  44642. +
  44643. +If you received this File from Marvell, you may opt to use, redistribute and/or
  44644. +modify this File under the following licensing terms.
  44645. +Redistribution and use in source and binary forms, with or without modification,
  44646. +are permitted provided that the following conditions are met:
  44647. +
  44648. + * Redistributions of source code must retain the above copyright notice,
  44649. + this list of conditions and the following disclaimer.
  44650. +
  44651. + * Redistributions in binary form must reproduce the above copyright
  44652. + notice, this list of conditions and the following disclaimer in the
  44653. + documentation and/or other materials provided with the distribution.
  44654. +
  44655. + * Neither the name of Marvell nor the names of its contributors may be
  44656. + used to endorse or promote products derived from this software without
  44657. + specific prior written permission.
  44658. +
  44659. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  44660. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  44661. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  44662. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  44663. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  44664. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  44665. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  44666. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  44667. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  44668. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  44669. +
  44670. +*******************************************************************************/
  44671. +
  44672. +
  44673. +#include "ctrlEnv/sys/mvSysGbe.h"
  44674. +
  44675. +
  44676. +
  44677. +typedef struct _mvEthDecWin
  44678. +{
  44679. + MV_TARGET target;
  44680. + MV_ADDR_WIN addrWin; /* An address window*/
  44681. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  44682. +
  44683. +}MV_ETH_DEC_WIN;
  44684. +
  44685. +MV_TARGET ethAddrDecPrioTap[] =
  44686. +{
  44687. +#if defined(MV_INCLUDE_SDRAM_CS0)
  44688. + SDRAM_CS0,
  44689. +#endif
  44690. +#if defined(MV_INCLUDE_SDRAM_CS1)
  44691. + SDRAM_CS1,
  44692. +#endif
  44693. +#if defined(MV_INCLUDE_SDRAM_CS2)
  44694. + SDRAM_CS2,
  44695. +#endif
  44696. +#if defined(MV_INCLUDE_SDRAM_CS3)
  44697. + SDRAM_CS3,
  44698. +#endif
  44699. +#if defined(MV_INCLUDE_DEVICE_CS0)
  44700. + DEVICE_CS0,
  44701. +#endif
  44702. +#if defined(MV_INCLUDE_DEVICE_CS1)
  44703. + DEVICE_CS1,
  44704. +#endif
  44705. +#if defined(MV_INCLUDE_DEVICE_CS2)
  44706. + DEVICE_CS2,
  44707. +#endif
  44708. +#if defined(MV_INCLUDE_DEVICE_CS3)
  44709. + DEVICE_CS3,
  44710. +#endif
  44711. +#if defined(MV_INCLUDE_PEX)
  44712. + PEX0_IO,
  44713. +#endif
  44714. + TBL_TERM
  44715. +};
  44716. +
  44717. +static MV_STATUS ethWinOverlapDetect(int port, MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
  44718. +static MV_STATUS mvEthWinSet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin);
  44719. +static MV_STATUS mvEthWinGet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin);
  44720. +
  44721. +
  44722. +/*******************************************************************************
  44723. +* mvEthWinInit - Initialize ETH address decode windows
  44724. +*
  44725. +* DESCRIPTION:
  44726. +* This function initialize ETH window decode unit. It set the
  44727. +* default address decode windows of the unit.
  44728. +*
  44729. +* INPUT:
  44730. +* None.
  44731. +*
  44732. +* OUTPUT:
  44733. +* None.
  44734. +*
  44735. +* RETURN:
  44736. +* MV_ERROR if setting fail.
  44737. +*******************************************************************************/
  44738. +/* Configure EthDrv memory map registes. */
  44739. +MV_STATUS mvEthWinInit (int port)
  44740. +{
  44741. + MV_U32 winNum, status, winPrioIndex=0, i, regVal=0;
  44742. + MV_ETH_DEC_WIN ethWin;
  44743. + MV_CPU_DEC_WIN cpuAddrDecWin;
  44744. + static MV_U32 accessProtReg = 0;
  44745. +
  44746. +#if (MV_ETH_VERSION <= 1)
  44747. + static MV_BOOL isFirst = MV_TRUE;
  44748. +
  44749. + if(isFirst == MV_FALSE)
  44750. + {
  44751. + MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(port), accessProtReg);
  44752. + return MV_OK;
  44753. + }
  44754. + isFirst = MV_FALSE;
  44755. +#endif /* MV_GIGA_ETH_VERSION */
  44756. +
  44757. + /* Initiate Ethernet address decode */
  44758. +
  44759. + /* First disable all address decode windows */
  44760. + for(winNum=0; winNum<ETH_MAX_DECODE_WIN; winNum++)
  44761. + {
  44762. + regVal |= MV_BIT_MASK(winNum);
  44763. + }
  44764. + MV_REG_WRITE(ETH_BASE_ADDR_ENABLE_REG(port), regVal);
  44765. +
  44766. + /* Go through all windows in user table until table terminator */
  44767. + for (winNum=0; ((ethAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
  44768. + (winNum < ETH_MAX_DECODE_WIN)); )
  44769. + {
  44770. + /* first get attributes from CPU If */
  44771. + status = mvCpuIfTargetWinGet(ethAddrDecPrioTap[winPrioIndex],
  44772. + &cpuAddrDecWin);
  44773. +
  44774. + if(MV_NO_SUCH == status)
  44775. + {
  44776. + winPrioIndex++;
  44777. + continue;
  44778. + }
  44779. + if (MV_OK != status)
  44780. + {
  44781. + mvOsPrintf("mvEthWinInit: ERR. mvCpuIfTargetWinGet failed\n");
  44782. + return MV_ERROR;
  44783. + }
  44784. +
  44785. + if (cpuAddrDecWin.enable == MV_TRUE)
  44786. + {
  44787. + ethWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  44788. + ethWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  44789. + ethWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  44790. + ethWin.enable = MV_TRUE;
  44791. + ethWin.target = ethAddrDecPrioTap[winPrioIndex];
  44792. +
  44793. + if(MV_OK != mvEthWinSet(port, winNum, &ethWin))
  44794. + {
  44795. + mvOsPrintf("mvEthWinInit: ERR. mvEthWinSet failed winNum=%d\n",
  44796. + winNum);
  44797. + return MV_ERROR;
  44798. + }
  44799. + winNum++;
  44800. + }
  44801. + winPrioIndex ++;
  44802. + }
  44803. +
  44804. + /* set full access to all windows. */
  44805. + for(i=0; i<winNum; i++)
  44806. + {
  44807. + accessProtReg |= (FULL_ACCESS << (i*2));
  44808. + }
  44809. + MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(port), accessProtReg);
  44810. +
  44811. + return MV_OK;
  44812. +}
  44813. +
  44814. +/*******************************************************************************
  44815. +* mvEthWinSet - Set ETH target address window
  44816. +*
  44817. +* DESCRIPTION:
  44818. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  44819. +* address window, also known as address decode window.
  44820. +* After setting this target window, the ETH will be able to access the
  44821. +* target within the address window.
  44822. +*
  44823. +* INPUT:
  44824. +* winNum - ETH to target address decode window number.
  44825. +* pAddrDecWin - ETH target window data structure.
  44826. +*
  44827. +* OUTPUT:
  44828. +* None.
  44829. +*
  44830. +* RETURN:
  44831. +* MV_ERROR if address window overlapps with other address decode windows.
  44832. +* MV_BAD_PARAM if base address is invalid parameter or target is
  44833. +* unknown.
  44834. +*
  44835. +*******************************************************************************/
  44836. +MV_STATUS mvEthWinSet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin)
  44837. +{
  44838. + MV_TARGET_ATTRIB targetAttribs;
  44839. + MV_DEC_REGS decRegs;
  44840. +
  44841. + /* Parameter checking */
  44842. + if (winNum >= ETH_MAX_DECODE_WIN)
  44843. + {
  44844. + mvOsPrintf("mvEthWinSet: ERR. Invalid win num %d\n",winNum);
  44845. + return MV_BAD_PARAM;
  44846. + }
  44847. +
  44848. + /* Check if the requested window overlapps with current windows */
  44849. + if (MV_TRUE == ethWinOverlapDetect(port, winNum, &pAddrDecWin->addrWin))
  44850. + {
  44851. + mvOsPrintf("mvEthWinSet: ERR. Window %d overlap\n", winNum);
  44852. + return MV_ERROR;
  44853. + }
  44854. +
  44855. + /* check if address is aligned to the size */
  44856. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  44857. + {
  44858. + mvOsPrintf("mvEthWinSet: Error setting Ethernet window %d to "\
  44859. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  44860. + winNum,
  44861. + mvCtrlTargetNameGet(pAddrDecWin->target),
  44862. + pAddrDecWin->addrWin.baseLow,
  44863. + pAddrDecWin->addrWin.size);
  44864. + return MV_ERROR;
  44865. + }
  44866. +
  44867. +
  44868. + decRegs.baseReg = MV_REG_READ(ETH_WIN_BASE_REG(port, winNum));
  44869. + decRegs.sizeReg = MV_REG_READ(ETH_WIN_SIZE_REG(port, winNum));
  44870. +
  44871. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  44872. + {
  44873. + mvOsPrintf("mvEthWinSet:mvCtrlAddrDecToReg Failed\n");
  44874. + return MV_ERROR;
  44875. + }
  44876. +
  44877. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  44878. +
  44879. + /* set attributes */
  44880. + decRegs.baseReg &= ~ETH_WIN_ATTR_MASK;
  44881. + decRegs.baseReg |= targetAttribs.attrib << ETH_WIN_ATTR_OFFS;
  44882. + /* set target ID */
  44883. + decRegs.baseReg &= ~ETH_WIN_TARGET_MASK;
  44884. + decRegs.baseReg |= targetAttribs.targetId << ETH_WIN_TARGET_OFFS;
  44885. +
  44886. + /* for the safe side we disable the window before writing the new
  44887. + values */
  44888. + mvEthWinEnable(port, winNum, MV_FALSE);
  44889. + MV_REG_WRITE(ETH_WIN_BASE_REG(port, winNum), decRegs.baseReg);
  44890. +
  44891. + /* Write to address decode Size Register */
  44892. + MV_REG_WRITE(ETH_WIN_SIZE_REG(port, winNum), decRegs.sizeReg);
  44893. +
  44894. + /* Enable address decode target window */
  44895. + if (pAddrDecWin->enable == MV_TRUE)
  44896. + {
  44897. + mvEthWinEnable(port, winNum, MV_TRUE);
  44898. + }
  44899. +
  44900. + return MV_OK;
  44901. +}
  44902. +
  44903. +/*******************************************************************************
  44904. +* mvETHWinGet - Get dma peripheral target address window.
  44905. +*
  44906. +* DESCRIPTION:
  44907. +* Get ETH peripheral target address window.
  44908. +*
  44909. +* INPUT:
  44910. +* winNum - ETH to target address decode window number.
  44911. +*
  44912. +* OUTPUT:
  44913. +* pAddrDecWin - ETH target window data structure.
  44914. +*
  44915. +* RETURN:
  44916. +* MV_ERROR if register parameters are invalid.
  44917. +*
  44918. +*******************************************************************************/
  44919. +MV_STATUS mvEthWinGet(int port, MV_U32 winNum, MV_ETH_DEC_WIN *pAddrDecWin)
  44920. +{
  44921. + MV_DEC_REGS decRegs;
  44922. + MV_TARGET_ATTRIB targetAttrib;
  44923. +
  44924. + /* Parameter checking */
  44925. + if (winNum >= ETH_MAX_DECODE_WIN)
  44926. + {
  44927. + mvOsPrintf("mvEthWinGet: ERR. Invalid winNum %d\n", winNum);
  44928. + return MV_NOT_SUPPORTED;
  44929. + }
  44930. +
  44931. + decRegs.baseReg = MV_REG_READ(ETH_WIN_BASE_REG(port, winNum));
  44932. + decRegs.sizeReg = MV_REG_READ(ETH_WIN_SIZE_REG(port, winNum));
  44933. +
  44934. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  44935. + {
  44936. + mvOsPrintf("mvAhbToMbusWinGet: mvCtrlRegToAddrDec Failed \n");
  44937. + return MV_ERROR;
  44938. + }
  44939. +
  44940. + /* attrib and targetId */
  44941. + targetAttrib.attrib =
  44942. + (decRegs.baseReg & ETH_WIN_ATTR_MASK) >> ETH_WIN_ATTR_OFFS;
  44943. + targetAttrib.targetId =
  44944. + (decRegs.baseReg & ETH_WIN_TARGET_MASK) >> ETH_WIN_TARGET_OFFS;
  44945. +
  44946. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  44947. +
  44948. + /* Check if window is enabled */
  44949. + if (~(MV_REG_READ(ETH_BASE_ADDR_ENABLE_REG(port))) & (1 << winNum) )
  44950. + {
  44951. + pAddrDecWin->enable = MV_TRUE;
  44952. + }
  44953. + else
  44954. + {
  44955. + pAddrDecWin->enable = MV_FALSE;
  44956. + }
  44957. +
  44958. + return MV_OK;
  44959. +}
  44960. +
  44961. +/*******************************************************************************
  44962. +* mvEthWinEnable - Enable/disable a ETH to target address window
  44963. +*
  44964. +* DESCRIPTION:
  44965. +* This function enable/disable a ETH to target address window.
  44966. +* According to parameter 'enable' the routine will enable the
  44967. +* window, thus enabling ETH accesses (before enabling the window it is
  44968. +* tested for overlapping). Otherwise, the window will be disabled.
  44969. +*
  44970. +* INPUT:
  44971. +* winNum - ETH to target address decode window number.
  44972. +* enable - Enable/disable parameter.
  44973. +*
  44974. +* OUTPUT:
  44975. +* N/A
  44976. +*
  44977. +* RETURN:
  44978. +* MV_ERROR if decode window number was wrong or enabled window overlapps.
  44979. +*
  44980. +*******************************************************************************/
  44981. +MV_STATUS mvEthWinEnable(int port, MV_U32 winNum,MV_BOOL enable)
  44982. +{
  44983. + MV_ETH_DEC_WIN addrDecWin;
  44984. +
  44985. + /* Parameter checking */
  44986. + if (winNum >= ETH_MAX_DECODE_WIN)
  44987. + {
  44988. + mvOsPrintf("mvEthTargetWinEnable:ERR. Invalid winNum%d\n",winNum);
  44989. + return MV_ERROR;
  44990. + }
  44991. +
  44992. + if (enable == MV_TRUE)
  44993. + { /* First check for overlap with other enabled windows */
  44994. + /* Get current window */
  44995. + if (MV_OK != mvEthWinGet(port, winNum, &addrDecWin))
  44996. + {
  44997. + mvOsPrintf("mvEthTargetWinEnable:ERR. targetWinGet fail\n");
  44998. + return MV_ERROR;
  44999. + }
  45000. + /* Check for overlapping */
  45001. + if (MV_FALSE == ethWinOverlapDetect(port, winNum, &(addrDecWin.addrWin)))
  45002. + {
  45003. + /* No Overlap. Enable address decode target window */
  45004. + MV_REG_BIT_RESET(ETH_BASE_ADDR_ENABLE_REG(port), (1 << winNum));
  45005. + }
  45006. + else
  45007. + { /* Overlap detected */
  45008. + mvOsPrintf("mvEthTargetWinEnable:ERR. Overlap detected\n");
  45009. + return MV_ERROR;
  45010. + }
  45011. + }
  45012. + else
  45013. + { /* Disable address decode target window */
  45014. + MV_REG_BIT_SET(ETH_BASE_ADDR_ENABLE_REG(port), (1 << winNum));
  45015. + }
  45016. + return MV_OK;
  45017. +}
  45018. +
  45019. +/*******************************************************************************
  45020. +* mvEthWinTargetGet - Get Window number associated with target
  45021. +*
  45022. +* DESCRIPTION:
  45023. +*
  45024. +* INPUT:
  45025. +*
  45026. +* OUTPUT:
  45027. +*
  45028. +* RETURN:
  45029. +* window number
  45030. +*
  45031. +*******************************************************************************/
  45032. +MV_U32 mvEthWinTargetGet(int port, MV_TARGET target)
  45033. +{
  45034. + MV_ETH_DEC_WIN decWin;
  45035. + MV_U32 winNum;
  45036. +
  45037. + /* Check parameters */
  45038. + if (target >= MAX_TARGETS)
  45039. + {
  45040. + mvOsPrintf("mvAhbToMbusWinTargetGet: target %d is Illigal\n", target);
  45041. + return 0xffffffff;
  45042. + }
  45043. +
  45044. + for (winNum=0; winNum<ETH_MAX_DECODE_WIN; winNum++)
  45045. + {
  45046. + if (mvEthWinGet(port, winNum,&decWin) != MV_OK)
  45047. + {
  45048. + mvOsPrintf("mvAhbToMbusWinTargetGet: window returned error\n");
  45049. + return 0xffffffff;
  45050. + }
  45051. +
  45052. + if (decWin.enable == MV_TRUE)
  45053. + {
  45054. + if (decWin.target == target)
  45055. + {
  45056. + return winNum;
  45057. + }
  45058. + }
  45059. + }
  45060. + return 0xFFFFFFFF;
  45061. +}
  45062. +
  45063. +/*******************************************************************************
  45064. +* mvEthProtWinSet - Set access protection of Ethernet to target window.
  45065. +*
  45066. +* DESCRIPTION:
  45067. +* Each Ethernet port can be configured with access attributes for each
  45068. +* of the Ethenret to target windows (address decode windows). This
  45069. +* function sets access attributes to a given window for the given channel.
  45070. +*
  45071. +* INPUTS:
  45072. +* ethPort - ETH channel number. See MV_ETH_CHANNEL enumerator.
  45073. +* winNum - IETH to target address decode window number.
  45074. +* access - IETH access rights. See MV_ACCESS_RIGHTS enumerator.
  45075. +*
  45076. +* OUTPUT:
  45077. +* None.
  45078. +*
  45079. +* RETURN:
  45080. +* MV_ERROR in case window number is invalid or access right reserved.
  45081. +*
  45082. +*******************************************************************************/
  45083. +MV_STATUS mvEthProtWinSet(MV_U32 portNo, MV_U32 winNum, MV_ACCESS_RIGHTS access)
  45084. +{
  45085. + MV_U32 protReg;
  45086. +
  45087. + /* Parameter checking */
  45088. + if(portNo >= mvCtrlEthMaxPortGet())
  45089. + {
  45090. + mvOsPrintf("mvEthProtWinSet:ERR. Invalid port number %d\n", portNo);
  45091. + return MV_ERROR;
  45092. + }
  45093. +
  45094. + if (winNum >= ETH_MAX_DECODE_WIN)
  45095. + {
  45096. + mvOsPrintf("mvEthProtWinSet:ERR. Invalid winNum%d\n",winNum);
  45097. + return MV_ERROR;
  45098. + }
  45099. +
  45100. + if((access == ACC_RESERVED) || (access >= MAX_ACC_RIGHTS))
  45101. + {
  45102. + mvOsPrintf("mvEthProtWinSet:ERR. Inv access param %d\n", access);
  45103. + return MV_ERROR;
  45104. + }
  45105. + /* Read current protection register */
  45106. + protReg = MV_REG_READ(ETH_ACCESS_PROTECT_REG(portNo));
  45107. +
  45108. + /* Clear protection window field */
  45109. + protReg &= ~(ETH_PROT_WIN_MASK(winNum));
  45110. +
  45111. + /* Set new protection field value */
  45112. + protReg |= (access << (ETH_PROT_WIN_OFFS(winNum)));
  45113. +
  45114. + /* Write protection register back */
  45115. + MV_REG_WRITE(ETH_ACCESS_PROTECT_REG(portNo), protReg);
  45116. +
  45117. + return MV_OK;
  45118. +}
  45119. +
  45120. +/*******************************************************************************
  45121. +* ethWinOverlapDetect - Detect ETH address windows overlapping
  45122. +*
  45123. +* DESCRIPTION:
  45124. +* An unpredicted behaviur is expected in case ETH address decode
  45125. +* windows overlapps.
  45126. +* This function detects ETH address decode windows overlapping of a
  45127. +* specified window. The function does not check the window itself for
  45128. +* overlapping. The function also skipps disabled address decode windows.
  45129. +*
  45130. +* INPUT:
  45131. +* winNum - address decode window number.
  45132. +* pAddrDecWin - An address decode window struct.
  45133. +*
  45134. +* OUTPUT:
  45135. +* None.
  45136. +*
  45137. +* RETURN:
  45138. +* MV_TRUE if the given address window overlap current address
  45139. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  45140. +* from registers.
  45141. +*
  45142. +*******************************************************************************/
  45143. +static MV_STATUS ethWinOverlapDetect(int port, MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  45144. +{
  45145. + MV_U32 baseAddrEnableReg;
  45146. + MV_U32 winNumIndex;
  45147. + MV_ETH_DEC_WIN addrDecWin;
  45148. +
  45149. + /* Read base address enable register. Do not check disabled windows */
  45150. + baseAddrEnableReg = MV_REG_READ(ETH_BASE_ADDR_ENABLE_REG(port));
  45151. +
  45152. + for (winNumIndex=0; winNumIndex<ETH_MAX_DECODE_WIN; winNumIndex++)
  45153. + {
  45154. + /* Do not check window itself */
  45155. + if (winNumIndex == winNum)
  45156. + {
  45157. + continue;
  45158. + }
  45159. +
  45160. + /* Do not check disabled windows */
  45161. + if (baseAddrEnableReg & (1 << winNumIndex))
  45162. + {
  45163. + continue;
  45164. + }
  45165. +
  45166. + /* Get window parameters */
  45167. + if (MV_OK != mvEthWinGet(port, winNumIndex, &addrDecWin))
  45168. + {
  45169. + mvOsPrintf("ethWinOverlapDetect: ERR. TargetWinGet failed\n");
  45170. + return MV_ERROR;
  45171. + }
  45172. +/*
  45173. + mvOsPrintf("ethWinOverlapDetect:\n
  45174. + winNumIndex =%d baseHigh =0x%x baseLow=0x%x size=0x%x enable=0x%x\n",
  45175. + winNumIndex,
  45176. + addrDecWin.addrWin.baseHigh,
  45177. + addrDecWin.addrWin.baseLow,
  45178. + addrDecWin.addrWin.size,
  45179. + addrDecWin.enable);
  45180. +*/
  45181. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  45182. + {
  45183. + return MV_TRUE;
  45184. + }
  45185. + }
  45186. + return MV_FALSE;
  45187. +}
  45188. +
  45189. +/*******************************************************************************
  45190. +* mvEthAddrDecShow - Print the Etherent address decode map.
  45191. +*
  45192. +* DESCRIPTION:
  45193. +* This function print the Etherent address decode map.
  45194. +*
  45195. +* INPUT:
  45196. +* None.
  45197. +*
  45198. +* OUTPUT:
  45199. +* None.
  45200. +*
  45201. +* RETURN:
  45202. +* None.
  45203. +*
  45204. +*******************************************************************************/
  45205. +void mvEthPortAddrDecShow(int port)
  45206. +{
  45207. + MV_ETH_DEC_WIN win;
  45208. + int i;
  45209. +
  45210. + mvOsOutput( "\n" );
  45211. + mvOsOutput( "ETH %d:\n", port );
  45212. + mvOsOutput( "----\n" );
  45213. +
  45214. + for( i = 0; i < ETH_MAX_DECODE_WIN; i++ )
  45215. + {
  45216. + memset( &win, 0, sizeof(ETH_MAX_DECODE_WIN) );
  45217. +
  45218. + mvOsOutput( "win%d - ", i );
  45219. +
  45220. + if( mvEthWinGet(port, i, &win ) == MV_OK )
  45221. + {
  45222. + if( win.enable )
  45223. + {
  45224. + mvOsOutput( "%s base %08x, ",
  45225. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  45226. + mvOsOutput( "...." );
  45227. + mvSizePrint( win.addrWin.size );
  45228. +
  45229. + mvOsOutput( "\n" );
  45230. + }
  45231. + else
  45232. + mvOsOutput( "disable\n" );
  45233. + }
  45234. + }
  45235. + return;
  45236. +}
  45237. +
  45238. +void mvEthAddrDecShow(void)
  45239. +{
  45240. + int port;
  45241. +
  45242. + for(port=0; port<mvCtrlEthMaxPortGet(); port++)
  45243. + {
  45244. + if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port)) continue;
  45245. +
  45246. + mvEthPortAddrDecShow(port);
  45247. + }
  45248. +}
  45249. +
  45250. +
  45251. +void mvEthInit(void)
  45252. +{
  45253. + MV_U32 port;
  45254. +
  45255. + /* Power down all existing ports */
  45256. + for(port=0; port<mvCtrlEthMaxPortGet(); port++)
  45257. + {
  45258. + if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port))
  45259. + continue;
  45260. +
  45261. + mvEthPortPowerUp(port);
  45262. + mvEthWinInit(port);
  45263. + }
  45264. + mvEthHalInit();
  45265. +}
  45266. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h
  45267. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h 1970-01-01 01:00:00.000000000 +0100
  45268. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysGbe.h 2011-08-01 14:38:19.000000000 +0200
  45269. @@ -0,0 +1,113 @@
  45270. +/*******************************************************************************
  45271. +Copyright (C) Marvell International Ltd. and its affiliates
  45272. +
  45273. +This software file (the "File") is owned and distributed by Marvell
  45274. +International Ltd. and/or its affiliates ("Marvell") under the following
  45275. +alternative licensing terms. Once you have made an election to distribute the
  45276. +File under one of the following license alternatives, please (i) delete this
  45277. +introductory statement regarding license alternatives, (ii) delete the two
  45278. +license alternatives that you have not elected to use and (iii) preserve the
  45279. +Marvell copyright notice above.
  45280. +
  45281. +********************************************************************************
  45282. +Marvell Commercial License Option
  45283. +
  45284. +If you received this File from Marvell and you have entered into a commercial
  45285. +license agreement (a "Commercial License") with Marvell, the File is licensed
  45286. +to you under the terms of the applicable Commercial License.
  45287. +
  45288. +********************************************************************************
  45289. +Marvell GPL License Option
  45290. +
  45291. +If you received this File from Marvell, you may opt to use, redistribute and/or
  45292. +modify this File in accordance with the terms and conditions of the General
  45293. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  45294. +available along with the File in the license.txt file or by writing to the Free
  45295. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  45296. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  45297. +
  45298. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  45299. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  45300. +DISCLAIMED. The GPL License provides additional details about this warranty
  45301. +disclaimer.
  45302. +********************************************************************************
  45303. +Marvell BSD License Option
  45304. +
  45305. +If you received this File from Marvell, you may opt to use, redistribute and/or
  45306. +modify this File under the following licensing terms.
  45307. +Redistribution and use in source and binary forms, with or without modification,
  45308. +are permitted provided that the following conditions are met:
  45309. +
  45310. + * Redistributions of source code must retain the above copyright notice,
  45311. + this list of conditions and the following disclaimer.
  45312. +
  45313. + * Redistributions in binary form must reproduce the above copyright
  45314. + notice, this list of conditions and the following disclaimer in the
  45315. + documentation and/or other materials provided with the distribution.
  45316. +
  45317. + * Neither the name of Marvell nor the names of its contributors may be
  45318. + used to endorse or promote products derived from this software without
  45319. + specific prior written permission.
  45320. +
  45321. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  45322. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  45323. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  45324. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  45325. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  45326. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  45327. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  45328. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  45329. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  45330. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  45331. +
  45332. +*******************************************************************************/
  45333. +
  45334. +#ifndef __INCmvSysGbeh
  45335. +#define __INCmvSysGbeh
  45336. +
  45337. +#include "mvCommon.h"
  45338. +#include "eth/mvEth.h"
  45339. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  45340. +#include "ctrlEnv/sys/mvCpuIf.h"
  45341. +
  45342. +#define ETH_WIN_BASE_REG(port, win) (MV_ETH_REG_BASE(port) + 0x200 + ((win)<<3))
  45343. +#define ETH_WIN_SIZE_REG(port, win) (MV_ETH_REG_BASE(port) + 0x204 + ((win)<<3))
  45344. +#define ETH_WIN_REMAP_REG(port, win) (MV_ETH_REG_BASE(port) + 0x280 + ((win)<<2))
  45345. +#define ETH_BASE_ADDR_ENABLE_REG(port) (MV_ETH_REG_BASE(port) + 0x290)
  45346. +#define ETH_ACCESS_PROTECT_REG(port) (MV_ETH_REG_BASE(port) + 0x294)
  45347. +
  45348. +/**** Address decode parameters ****/
  45349. +
  45350. +/* Ethernet Base Address Register bits */
  45351. +#define ETH_MAX_DECODE_WIN 6
  45352. +#define ETH_MAX_HIGH_ADDR_REMAP_WIN 4
  45353. +
  45354. +/* Ethernet Port Access Protect (EPAP) register */
  45355. +
  45356. +/* The target associated with this window*/
  45357. +#define ETH_WIN_TARGET_OFFS 0
  45358. +#define ETH_WIN_TARGET_MASK (0xf << ETH_WIN_TARGET_OFFS)
  45359. +/* The target attributes Associated with window */
  45360. +#define ETH_WIN_ATTR_OFFS 8
  45361. +#define ETH_WIN_ATTR_MASK (0xff << ETH_WIN_ATTR_OFFS)
  45362. +
  45363. +/* Ethernet Port Access Protect Register (EPAPR) */
  45364. +#define ETH_PROT_NO_ACCESS NO_ACCESS_ALLOWED
  45365. +#define ETH_PROT_READ_ONLY READ_ONLY
  45366. +#define ETH_PROT_FULL_ACCESS FULL_ACCESS
  45367. +#define ETH_PROT_WIN_OFFS(winNum) (2 * (winNum))
  45368. +#define ETH_PROT_WIN_MASK(winNum) (0x3 << ETH_PROT_WIN_OFFS(winNum))
  45369. +
  45370. +MV_STATUS mvEthWinInit (int port);
  45371. +MV_STATUS mvEthWinEnable(int port, MV_U32 winNum, MV_BOOL enable);
  45372. +MV_U32 mvEthWinTargetGet(int port, MV_TARGET target);
  45373. +MV_STATUS mvEthProtWinSet(MV_U32 portNo, MV_U32 winNum, MV_ACCESS_RIGHTS
  45374. + access);
  45375. +
  45376. +void mvEthPortAddrDecShow(int port);
  45377. +
  45378. +MV_VOID mvEthAddrDecShow(MV_VOID);
  45379. +
  45380. +void mvEthInit(void);
  45381. +
  45382. +#endif
  45383. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c
  45384. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c 1970-01-01 01:00:00.000000000 +0100
  45385. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.c 2011-08-01 14:38:19.000000000 +0200
  45386. @@ -0,0 +1,1697 @@
  45387. +/*******************************************************************************
  45388. +Copyright (C) Marvell International Ltd. and its affiliates
  45389. +
  45390. +This software file (the "File") is owned and distributed by Marvell
  45391. +International Ltd. and/or its affiliates ("Marvell") under the following
  45392. +alternative licensing terms. Once you have made an election to distribute the
  45393. +File under one of the following license alternatives, please (i) delete this
  45394. +introductory statement regarding license alternatives, (ii) delete the two
  45395. +license alternatives that you have not elected to use and (iii) preserve the
  45396. +Marvell copyright notice above.
  45397. +
  45398. +********************************************************************************
  45399. +Marvell Commercial License Option
  45400. +
  45401. +If you received this File from Marvell and you have entered into a commercial
  45402. +license agreement (a "Commercial License") with Marvell, the File is licensed
  45403. +to you under the terms of the applicable Commercial License.
  45404. +
  45405. +********************************************************************************
  45406. +Marvell GPL License Option
  45407. +
  45408. +If you received this File from Marvell, you may opt to use, redistribute and/or
  45409. +modify this File in accordance with the terms and conditions of the General
  45410. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  45411. +available along with the File in the license.txt file or by writing to the Free
  45412. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  45413. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  45414. +
  45415. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  45416. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  45417. +DISCLAIMED. The GPL License provides additional details about this warranty
  45418. +disclaimer.
  45419. +********************************************************************************
  45420. +Marvell BSD License Option
  45421. +
  45422. +If you received this File from Marvell, you may opt to use, redistribute and/or
  45423. +modify this File under the following licensing terms.
  45424. +Redistribution and use in source and binary forms, with or without modification,
  45425. +are permitted provided that the following conditions are met:
  45426. +
  45427. + * Redistributions of source code must retain the above copyright notice,
  45428. + this list of conditions and the following disclaimer.
  45429. +
  45430. + * Redistributions in binary form must reproduce the above copyright
  45431. + notice, this list of conditions and the following disclaimer in the
  45432. + documentation and/or other materials provided with the distribution.
  45433. +
  45434. + * Neither the name of Marvell nor the names of its contributors may be
  45435. + used to endorse or promote products derived from this software without
  45436. + specific prior written permission.
  45437. +
  45438. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  45439. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  45440. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  45441. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  45442. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  45443. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  45444. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  45445. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  45446. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  45447. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  45448. +
  45449. +*******************************************************************************/
  45450. +
  45451. +#include "ctrlEnv/sys/mvSysPex.h"
  45452. +
  45453. +/* this structure describes the mapping between a Pex Window and a CPU target*/
  45454. +typedef struct _pexWinToTarget
  45455. +{
  45456. + MV_TARGET target;
  45457. + MV_BOOL enable;
  45458. +
  45459. +}PEX_WIN_TO_TARGET;
  45460. +
  45461. +/* this array is a priority array that define How Pex windows should be
  45462. +configured , We have only 6 Pex Windows that can be configured , but we
  45463. +have maximum of 9 CPU target windows ! the following array is a priority
  45464. +array where the lowest index has the highest priotiy and the highest
  45465. +index has the lowest priority of being cnfigured */
  45466. +
  45467. +MV_U32 pexDevBarPrioTable[] =
  45468. +{
  45469. +#if defined(MV_INCLUDE_DEVICE_CS0)
  45470. + DEVICE_CS0,
  45471. +#endif
  45472. +#if defined(MV_INCLUDE_DEVICE_CS1)
  45473. + DEVICE_CS1,
  45474. +#endif
  45475. +#if defined(MV_INCLUDE_DEVICE_CS2)
  45476. + DEVICE_CS2,
  45477. +#endif
  45478. +#if defined(MV_INCLUDE_DEVICE_CS3)
  45479. + DEVICE_CS3,
  45480. +#endif
  45481. +/*
  45482. +#if defined(MV_INCLUDE_DEVICE_CS4)
  45483. + DEVICE_CS4,
  45484. +#endif
  45485. +*/
  45486. + TBL_TERM
  45487. +};
  45488. +
  45489. +
  45490. +/* PEX Wins registers offsets are inconsecutive. This struct describes WIN */
  45491. +/* register offsets and its function where its is located. */
  45492. +/* Also, PEX address remap registers offsets are inconsecutive. This struct */
  45493. +/* describes address remap register offsets */
  45494. +typedef struct _pexWinRegInfo
  45495. +{
  45496. + MV_U32 baseLowRegOffs;
  45497. + MV_U32 baseHighRegOffs;
  45498. + MV_U32 sizeRegOffs;
  45499. + MV_U32 remapLowRegOffs;
  45500. + MV_U32 remapHighRegOffs;
  45501. +
  45502. +}PEX_WIN_REG_INFO;
  45503. +
  45504. +static MV_STATUS pexWinOverlapDetect(MV_U32 pexIf, MV_U32 winNum,
  45505. + MV_ADDR_WIN *pAddrWin);
  45506. +static MV_STATUS pexWinRegInfoGet(MV_U32 pexIf, MV_U32 winNum,
  45507. + PEX_WIN_REG_INFO *pWinRegInfo);
  45508. +
  45509. +static MV_STATUS pexBarIsValid(MV_U32 baseLow, MV_U32 size);
  45510. +
  45511. +static MV_BOOL pexIsWinWithinBar(MV_U32 pexIf,MV_ADDR_WIN *pAddrWin);
  45512. +static MV_BOOL pexBarOverlapDetect(MV_U32 pexIf,MV_U32 barNum,
  45513. + MV_ADDR_WIN *pAddrWin);
  45514. +const MV_8* pexBarNameGet( MV_U32 bar );
  45515. +
  45516. +
  45517. +/*******************************************************************************
  45518. +* mvPexInit - Initialize PEX interfaces
  45519. +*
  45520. +* DESCRIPTION:
  45521. +*
  45522. +* This function is responsible of intialization of the Pex Interface , It
  45523. +* configure the Pex Bars and Windows in the following manner:
  45524. +*
  45525. +* Assumptions :
  45526. +* Bar0 is always internal registers bar
  45527. +* Bar1 is always the DRAM bar
  45528. +* Bar2 is always the Device bar
  45529. +*
  45530. +* 1) Sets the Internal registers bar base by obtaining the base from
  45531. +* the CPU Interface
  45532. +* 2) Sets the DRAM bar base and size by getting the base and size from
  45533. +* the CPU Interface when the size is the sum of all enabled DRAM
  45534. +* chip selects and the base is the base of CS0 .
  45535. +* 3) Sets the Device bar base and size by getting these values from the
  45536. +* CPU Interface when the base is the base of the lowest base of the
  45537. +* Device chip selects, and the
  45538. +*
  45539. +*
  45540. +* INPUT:
  45541. +*
  45542. +* pexIf - PEX interface number.
  45543. +*
  45544. +*
  45545. +* OUTPUT:
  45546. +* None.
  45547. +*
  45548. +* RETURN:
  45549. +* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
  45550. +*
  45551. +*******************************************************************************/
  45552. +MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType)
  45553. +{
  45554. + MV_U32 bar;
  45555. + MV_U32 winNum;
  45556. + MV_PEX_BAR pexBar;
  45557. + MV_PEX_DEC_WIN pexWin;
  45558. + MV_CPU_DEC_WIN addrDecWin;
  45559. + MV_TARGET target;
  45560. + MV_U32 pexCurrWin=0;
  45561. + MV_U32 status;
  45562. + /* default and exapntion rom
  45563. + are always configured */
  45564. +
  45565. +#ifndef MV_DISABLE_PEX_DEVICE_BAR
  45566. + MV_U32 winIndex;
  45567. + MV_U32 maxBase=0, sizeOfMaxBase=0;
  45568. + MV_U32 pexStartWindow;
  45569. +#endif
  45570. +
  45571. + /* Parameter checking */
  45572. + if(pexIf >= mvCtrlPexMaxIfGet())
  45573. + {
  45574. + mvOsPrintf("mvPexInit: ERR. Invalid PEX interface %d\n", pexIf);
  45575. + return MV_BAD_PARAM;
  45576. + }
  45577. +
  45578. + /* Enabled CPU access to PCI-Express */
  45579. + mvCpuIfEnablePex(pexIf, pexType);
  45580. +
  45581. + /* Start with bars */
  45582. + /* First disable all PEX bars*/
  45583. + for (bar = 0; bar < PEX_MAX_BARS; bar++)
  45584. + {
  45585. + if (PEX_INTER_REGS_BAR != bar)
  45586. + {
  45587. + if (MV_OK != mvPexBarEnable(pexIf, bar, MV_FALSE))
  45588. + {
  45589. + mvOsPrintf("mvPexInit:mvPexBarEnable bar =%d failed \n",bar);
  45590. + return MV_ERROR;
  45591. + }
  45592. +
  45593. + }
  45594. +
  45595. + }
  45596. +
  45597. + /* and disable all PEX target windows */
  45598. + for (winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++)
  45599. + {
  45600. + if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_FALSE))
  45601. + {
  45602. + mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n",
  45603. + winNum);
  45604. + return MV_ERROR;
  45605. +
  45606. + }
  45607. + }
  45608. +
  45609. + /* Now, go through all bars*/
  45610. +
  45611. +
  45612. +
  45613. +/******************************************************************************/
  45614. +/* Internal registers bar */
  45615. +/******************************************************************************/
  45616. + bar = PEX_INTER_REGS_BAR;
  45617. +
  45618. + /* we only open the bar , no need to open windows for this bar */
  45619. +
  45620. + /* first get the CS attribute from the CPU Interface */
  45621. + if (MV_OK !=mvCpuIfTargetWinGet(INTER_REGS,&addrDecWin))
  45622. + {
  45623. + mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",INTER_REGS);
  45624. + return MV_ERROR;
  45625. + }
  45626. +
  45627. + pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  45628. + pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  45629. + pexBar.addrWin.size = addrDecWin.addrWin.size;
  45630. + pexBar.enable = MV_TRUE;
  45631. +
  45632. + if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
  45633. + {
  45634. + mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
  45635. + return MV_ERROR;
  45636. + }
  45637. +
  45638. +/******************************************************************************/
  45639. +/* DRAM bar */
  45640. +/******************************************************************************/
  45641. +
  45642. + bar = PEX_DRAM_BAR;
  45643. +
  45644. + pexBar.addrWin.size = 0;
  45645. +
  45646. + for (target = SDRAM_CS0;target < MV_DRAM_MAX_CS; target++ )
  45647. + {
  45648. +
  45649. + status = mvCpuIfTargetWinGet(target,&addrDecWin);
  45650. +
  45651. + if((MV_NO_SUCH == status)&&(target != SDRAM_CS0))
  45652. + {
  45653. + continue;
  45654. + }
  45655. +
  45656. + /* first get attributes from CPU If */
  45657. + if (MV_OK != status)
  45658. + {
  45659. + mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target);
  45660. + return MV_ERROR;
  45661. + }
  45662. + if (addrDecWin.enable == MV_TRUE)
  45663. + {
  45664. + /* the base is the base of DRAM CS0 always */
  45665. + if (SDRAM_CS0 == target )
  45666. + {
  45667. + pexBar.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  45668. + pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  45669. +
  45670. + }
  45671. +
  45672. + /* increment the bar size to be the sum of the size of all
  45673. + DRAM chips selecs */
  45674. + pexBar.addrWin.size += addrDecWin.addrWin.size;
  45675. +
  45676. + /* set a Pex window for this target !
  45677. + DRAM CS always will have a Pex Window , and is not a
  45678. + part of the priority table */
  45679. + pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  45680. + pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  45681. + pexWin.addrWin.size = addrDecWin.addrWin.size;
  45682. +
  45683. + /* we disable the windows at first because we are not
  45684. + sure that it is witihin bar boundries */
  45685. + pexWin.enable =MV_FALSE;
  45686. + pexWin.target = target;
  45687. + pexWin.targetBar = bar;
  45688. +
  45689. + if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,&pexWin))
  45690. + {
  45691. + mvOsPrintf("mvPexInit: ERR. mvPexTargetWinSet failed\n");
  45692. + return MV_ERROR;
  45693. + }
  45694. + }
  45695. + }
  45696. +
  45697. + /* check if the size of the bar is illeggal */
  45698. + if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT))
  45699. + {
  45700. + /* try to get a good size */
  45701. + pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size,
  45702. + PXBCR_BAR_SIZE_ALIGNMENT);
  45703. + }
  45704. +
  45705. + /* check if the size and base are valid */
  45706. + if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin))
  45707. + {
  45708. + mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar);
  45709. + mvOsPrintf("it will be disabled\n");
  45710. + mvOsPrintf("please check Pex and CPU windows configuration\n");
  45711. + }
  45712. + else
  45713. + {
  45714. + pexBar.enable = MV_TRUE;
  45715. +
  45716. + /* configure the bar */
  45717. + if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
  45718. + {
  45719. + mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
  45720. + return MV_ERROR;
  45721. + }
  45722. +
  45723. + /* after the bar was configured then we enable the Pex windows*/
  45724. + for (winNum = 0;winNum < pexCurrWin ;winNum++)
  45725. + {
  45726. + if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE))
  45727. + {
  45728. + mvOsPrintf("mvPexInit: Can't enable window =%d\n",winNum);
  45729. + return MV_ERROR;
  45730. + }
  45731. +
  45732. + }
  45733. + }
  45734. +
  45735. +/******************************************************************************/
  45736. +/* DEVICE bar */
  45737. +/******************************************************************************/
  45738. +
  45739. +/* Open the Device BAR for non linux only */
  45740. +#ifndef MV_DISABLE_PEX_DEVICE_BAR
  45741. +
  45742. + /* then device bar*/
  45743. + bar = PEX_DEVICE_BAR;
  45744. +
  45745. + /* save the starting window */
  45746. + pexStartWindow = pexCurrWin;
  45747. + pexBar.addrWin.size = 0;
  45748. + pexBar.addrWin.baseLow = 0xffffffff;
  45749. + pexBar.addrWin.baseHigh = 0;
  45750. + maxBase = 0;
  45751. +
  45752. + for (target = DEV_TO_TARGET(START_DEV_CS);target < DEV_TO_TARGET(MV_DEV_MAX_CS); target++ )
  45753. + {
  45754. + status = mvCpuIfTargetWinGet(target,&addrDecWin);
  45755. +
  45756. + if (MV_NO_SUCH == status)
  45757. + {
  45758. + continue;
  45759. + }
  45760. +
  45761. + if (MV_OK != status)
  45762. + {
  45763. + mvOsPrintf("mvPexInit: ERR. mvCpuIfTargetWinGet failed target =%d\n",target);
  45764. + return MV_ERROR;
  45765. + }
  45766. +
  45767. + if (addrDecWin.enable == MV_TRUE)
  45768. + {
  45769. + /* get the minimum base */
  45770. + if (addrDecWin.addrWin.baseLow < pexBar.addrWin.baseLow)
  45771. + {
  45772. + pexBar.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  45773. + }
  45774. +
  45775. + /* get the maximum base */
  45776. + if (addrDecWin.addrWin.baseLow > maxBase)
  45777. + {
  45778. + maxBase = addrDecWin.addrWin.baseLow;
  45779. + sizeOfMaxBase = addrDecWin.addrWin.size;
  45780. + }
  45781. +
  45782. + /* search in the priority table for this target */
  45783. + for (winIndex = 0; pexDevBarPrioTable[winIndex] != TBL_TERM;
  45784. + winIndex++)
  45785. + {
  45786. + if (pexDevBarPrioTable[winIndex] != target)
  45787. + {
  45788. + continue;
  45789. + }
  45790. + else if (pexDevBarPrioTable[winIndex] == target)
  45791. + {
  45792. + /*found it */
  45793. +
  45794. + /* if the index of this target in the prio table is valid
  45795. + then we set the Pex window for this target, a valid index is
  45796. + an index that is lower than the number of the windows that
  45797. + was not configured yet */
  45798. +
  45799. + /* we subtract 2 always because the default and expantion
  45800. + rom windows are always configured */
  45801. + if ( pexCurrWin < PEX_MAX_TARGET_WIN - 2)
  45802. + {
  45803. + /* set a Pex window for this target ! */
  45804. + pexWin.addrWin.baseHigh = addrDecWin.addrWin.baseHigh;
  45805. + pexWin.addrWin.baseLow = addrDecWin.addrWin.baseLow;
  45806. + pexWin.addrWin.size = addrDecWin.addrWin.size;
  45807. +
  45808. + /* we disable the windows at first because we are not
  45809. + sure that it is witihin bar boundries */
  45810. + pexWin.enable = MV_FALSE;
  45811. + pexWin.target = target;
  45812. + pexWin.targetBar = bar;
  45813. +
  45814. + if (MV_OK != mvPexTargetWinSet(pexIf,pexCurrWin++,
  45815. + &pexWin))
  45816. + {
  45817. + mvOsPrintf("mvPexInit: ERR. Window Set failed\n");
  45818. + return MV_ERROR;
  45819. + }
  45820. + }
  45821. + }
  45822. + }
  45823. + }
  45824. + }
  45825. +
  45826. + pexBar.addrWin.size = maxBase - pexBar.addrWin.baseLow + sizeOfMaxBase;
  45827. + pexBar.enable = MV_TRUE;
  45828. +
  45829. + /* check if the size of the bar is illegal */
  45830. + if (-1 == ctrlSizeToReg(pexBar.addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT))
  45831. + {
  45832. + /* try to get a good size */
  45833. + pexBar.addrWin.size = ctrlSizeRegRoundUp(pexBar.addrWin.size,
  45834. + PXBCR_BAR_SIZE_ALIGNMENT);
  45835. + }
  45836. +
  45837. + /* check if the size and base are valid */
  45838. + if (MV_TRUE == pexBarOverlapDetect(pexIf,bar,&pexBar.addrWin))
  45839. + {
  45840. + mvOsPrintf("mvPexInit:Warning :Bar %d size is illigal\n",bar);
  45841. + mvOsPrintf("it will be disabled\n");
  45842. + mvOsPrintf("please check Pex and CPU windows configuration\n");
  45843. + }
  45844. + else
  45845. + {
  45846. + if (MV_OK != mvPexBarSet(pexIf, bar, &pexBar))
  45847. + {
  45848. + mvOsPrintf("mvPexInit: ERR. mvPexBarSet %d failed\n", bar);
  45849. + return MV_ERROR;
  45850. + }
  45851. +
  45852. + /* now enable the windows */
  45853. + for (winNum = pexStartWindow; winNum < pexCurrWin ; winNum++)
  45854. + {
  45855. + if (MV_OK != mvPexTargetWinEnable(pexIf, winNum, MV_TRUE))
  45856. + {
  45857. + mvOsPrintf("mvPexInit:mvPexTargetWinEnable winNum =%d failed \n",
  45858. + winNum);
  45859. + return MV_ERROR;
  45860. + }
  45861. + }
  45862. + }
  45863. +
  45864. +#endif
  45865. +
  45866. + return mvPexHalInit(pexIf, pexType);
  45867. +
  45868. +}
  45869. +
  45870. +/*******************************************************************************
  45871. +* mvPexTargetWinSet - Set PEX to peripheral target address window BAR
  45872. +*
  45873. +* DESCRIPTION:
  45874. +*
  45875. +* INPUT:
  45876. +*
  45877. +* OUTPUT:
  45878. +* N/A
  45879. +*
  45880. +* RETURN:
  45881. +* MV_OK if PEX BAR target window was set correctly,
  45882. +* MV_BAD_PARAM on bad params
  45883. +* MV_ERROR otherwise
  45884. +* (e.g. address window overlapps with other active PEX target window).
  45885. +*
  45886. +*******************************************************************************/
  45887. +MV_STATUS mvPexTargetWinSet(MV_U32 pexIf, MV_U32 winNum,
  45888. + MV_PEX_DEC_WIN *pAddrDecWin)
  45889. +{
  45890. +
  45891. + MV_DEC_REGS decRegs;
  45892. + PEX_WIN_REG_INFO winRegInfo;
  45893. + MV_TARGET_ATTRIB targetAttribs;
  45894. +
  45895. + /* Parameter checking */
  45896. + if(pexIf >= mvCtrlPexMaxIfGet())
  45897. + {
  45898. + mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX interface %d\n", pexIf);
  45899. + return MV_BAD_PARAM;
  45900. + }
  45901. +
  45902. + if (winNum >= PEX_MAX_TARGET_WIN)
  45903. + {
  45904. + mvOsPrintf("mvPexTargetWinSet: ERR. Invalid PEX winNum %d\n", winNum);
  45905. + return MV_BAD_PARAM;
  45906. +
  45907. + }
  45908. +
  45909. + /* get the pex Window registers offsets */
  45910. + pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
  45911. +
  45912. +
  45913. + if (MV_TRUE == pAddrDecWin->enable)
  45914. + {
  45915. +
  45916. + /* 2) Check if the requested window overlaps with current windows */
  45917. + if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &pAddrDecWin->addrWin))
  45918. + {
  45919. + mvOsPrintf("mvPexTargetWinSet: ERR. Target %d overlap\n", winNum);
  45920. + return MV_BAD_PARAM;
  45921. + }
  45922. +
  45923. + /* 2) Check if the requested window overlaps with current windows */
  45924. + if (MV_FALSE == pexIsWinWithinBar(pexIf,&pAddrDecWin->addrWin))
  45925. + {
  45926. + mvOsPrintf("mvPexTargetWinSet: Win %d should be in bar boundries\n",
  45927. + winNum);
  45928. + return MV_BAD_PARAM;
  45929. + }
  45930. +
  45931. + }
  45932. +
  45933. +
  45934. +
  45935. + /* read base register*/
  45936. +
  45937. + if (winRegInfo.baseLowRegOffs)
  45938. + {
  45939. + decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs);
  45940. + }
  45941. + else
  45942. + {
  45943. + decRegs.baseReg = 0;
  45944. + }
  45945. +
  45946. + if (winRegInfo.sizeRegOffs)
  45947. + {
  45948. + decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs);
  45949. + }
  45950. + else
  45951. + {
  45952. + decRegs.sizeReg =0;
  45953. + }
  45954. +
  45955. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  45956. + {
  45957. + mvOsPrintf("mvPexTargetWinSet:mvCtrlAddrDecToReg Failed\n");
  45958. + return MV_ERROR;
  45959. + }
  45960. +
  45961. + /* enable\Disable */
  45962. + if (MV_TRUE == pAddrDecWin->enable)
  45963. + {
  45964. + decRegs.sizeReg |= PXWCR_WIN_EN;
  45965. + }
  45966. + else
  45967. + {
  45968. + decRegs.sizeReg &= ~PXWCR_WIN_EN;
  45969. + }
  45970. +
  45971. +
  45972. + /* clear bit location */
  45973. + decRegs.sizeReg &= ~PXWCR_WIN_BAR_MAP_MASK;
  45974. +
  45975. + /* set bar Mapping */
  45976. + if (pAddrDecWin->targetBar == 1)
  45977. + {
  45978. + decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR1;
  45979. + }
  45980. + else if (pAddrDecWin->targetBar == 2)
  45981. + {
  45982. + decRegs.sizeReg |= PXWCR_WIN_BAR_MAP_BAR2;
  45983. + }
  45984. +
  45985. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  45986. +
  45987. + /* set attributes */
  45988. + decRegs.sizeReg &= ~PXWCR_ATTRIB_MASK;
  45989. + decRegs.sizeReg |= targetAttribs.attrib << PXWCR_ATTRIB_OFFS;
  45990. + /* set target ID */
  45991. + decRegs.sizeReg &= ~PXWCR_TARGET_MASK;
  45992. + decRegs.sizeReg |= targetAttribs.targetId << PXWCR_TARGET_OFFS;
  45993. +
  45994. +
  45995. + /* 3) Write to address decode Base Address Register */
  45996. +
  45997. + if (winRegInfo.baseLowRegOffs)
  45998. + {
  45999. + MV_REG_WRITE(winRegInfo.baseLowRegOffs, decRegs.baseReg);
  46000. + }
  46001. +
  46002. + /* write size reg */
  46003. + if (winRegInfo.sizeRegOffs)
  46004. + {
  46005. + if ((MV_PEX_WIN_DEFAULT == winNum)||
  46006. + (MV_PEX_WIN_EXP_ROM == winNum))
  46007. + {
  46008. + /* clear size because there is no size field*/
  46009. + decRegs.sizeReg &= ~PXWCR_SIZE_MASK;
  46010. +
  46011. + /* clear enable because there is no enable field*/
  46012. + decRegs.sizeReg &= ~PXWCR_WIN_EN;
  46013. +
  46014. + }
  46015. +
  46016. + MV_REG_WRITE(winRegInfo.sizeRegOffs, decRegs.sizeReg);
  46017. + }
  46018. +
  46019. +
  46020. + return MV_OK;
  46021. +
  46022. +}
  46023. +
  46024. +/*******************************************************************************
  46025. +* mvPexTargetWinGet - Get PEX to peripheral target address window
  46026. +*
  46027. +* DESCRIPTION:
  46028. +* Get the PEX to peripheral target address window BAR.
  46029. +*
  46030. +* INPUT:
  46031. +* pexIf - PEX interface number.
  46032. +* bar - BAR to be accessed by slave.
  46033. +*
  46034. +* OUTPUT:
  46035. +* pAddrBarWin - PEX target window information data structure.
  46036. +*
  46037. +* RETURN:
  46038. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  46039. +*
  46040. +*******************************************************************************/
  46041. +MV_STATUS mvPexTargetWinGet(MV_U32 pexIf, MV_U32 winNum,
  46042. + MV_PEX_DEC_WIN *pAddrDecWin)
  46043. +{
  46044. + MV_TARGET_ATTRIB targetAttrib;
  46045. + MV_DEC_REGS decRegs;
  46046. +
  46047. + PEX_WIN_REG_INFO winRegInfo;
  46048. +
  46049. + /* Parameter checking */
  46050. + if(pexIf >= mvCtrlPexMaxIfGet())
  46051. + {
  46052. + mvOsPrintf("mvPexTargetWinGet: ERR. Invalid PEX interface %d\n", pexIf);
  46053. + return MV_BAD_PARAM;
  46054. + }
  46055. +
  46056. + if (winNum >= PEX_MAX_TARGET_WIN)
  46057. + {
  46058. + mvOsPrintf("mvPexTargetWinGet: ERR. Invalid PEX winNum %d\n", winNum);
  46059. + return MV_BAD_PARAM;
  46060. +
  46061. + }
  46062. +
  46063. + /* get the pex Window registers offsets */
  46064. + pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
  46065. +
  46066. + /* read base register*/
  46067. + if (winRegInfo.baseLowRegOffs)
  46068. + {
  46069. + decRegs.baseReg = MV_REG_READ(winRegInfo.baseLowRegOffs);
  46070. + }
  46071. + else
  46072. + {
  46073. + decRegs.baseReg = 0;
  46074. + }
  46075. +
  46076. + /* read size reg */
  46077. + if (winRegInfo.sizeRegOffs)
  46078. + {
  46079. + decRegs.sizeReg = MV_REG_READ(winRegInfo.sizeRegOffs);
  46080. + }
  46081. + else
  46082. + {
  46083. + decRegs.sizeReg =0;
  46084. + }
  46085. +
  46086. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  46087. + {
  46088. + mvOsPrintf("mvPexTargetWinGet: mvCtrlRegToAddrDec Failed \n");
  46089. + return MV_ERROR;
  46090. +
  46091. + }
  46092. +
  46093. + if (decRegs.sizeReg & PXWCR_WIN_EN)
  46094. + {
  46095. + pAddrDecWin->enable = MV_TRUE;
  46096. + }
  46097. + else
  46098. + {
  46099. + pAddrDecWin->enable = MV_FALSE;
  46100. +
  46101. + }
  46102. +
  46103. +
  46104. + #if 0
  46105. + if (-1 == pAddrDecWin->addrWin.size)
  46106. + {
  46107. + return MV_ERROR;
  46108. + }
  46109. + #endif
  46110. +
  46111. +
  46112. + /* get target bar */
  46113. + if ((decRegs.sizeReg & PXWCR_WIN_BAR_MAP_MASK) == PXWCR_WIN_BAR_MAP_BAR1 )
  46114. + {
  46115. + pAddrDecWin->targetBar = 1;
  46116. + }
  46117. + else if ((decRegs.sizeReg & PXWCR_WIN_BAR_MAP_MASK) ==
  46118. + PXWCR_WIN_BAR_MAP_BAR2 )
  46119. + {
  46120. + pAddrDecWin->targetBar = 2;
  46121. + }
  46122. +
  46123. + /* attrib and targetId */
  46124. + pAddrDecWin->attrib = (decRegs.sizeReg & PXWCR_ATTRIB_MASK) >>
  46125. + PXWCR_ATTRIB_OFFS;
  46126. + pAddrDecWin->targetId = (decRegs.sizeReg & PXWCR_TARGET_MASK) >>
  46127. + PXWCR_TARGET_OFFS;
  46128. +
  46129. + targetAttrib.attrib = pAddrDecWin->attrib;
  46130. + targetAttrib.targetId = pAddrDecWin->targetId;
  46131. +
  46132. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  46133. +
  46134. + return MV_OK;
  46135. +
  46136. +}
  46137. +
  46138. +
  46139. +/*******************************************************************************
  46140. +* mvPexTargetWinEnable - Enable/disable a PEX BAR window
  46141. +*
  46142. +* DESCRIPTION:
  46143. +* This function enable/disable a PEX BAR window.
  46144. +* if parameter 'enable' == MV_TRUE the routine will enable the
  46145. +* window, thus enabling PEX accesses for that BAR (before enabling the
  46146. +* window it is tested for overlapping). Otherwise, the window will
  46147. +* be disabled.
  46148. +*
  46149. +* INPUT:
  46150. +* pexIf - PEX interface number.
  46151. +* bar - BAR to be accessed by slave.
  46152. +* enable - Enable/disable parameter.
  46153. +*
  46154. +* OUTPUT:
  46155. +* None.
  46156. +*
  46157. +* RETURN:
  46158. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  46159. +*
  46160. +*******************************************************************************/
  46161. +MV_STATUS mvPexTargetWinEnable(MV_U32 pexIf,MV_U32 winNum, MV_BOOL enable)
  46162. +{
  46163. + PEX_WIN_REG_INFO winRegInfo;
  46164. + MV_PEX_DEC_WIN addrDecWin;
  46165. +
  46166. + /* Parameter checking */
  46167. + if(pexIf >= mvCtrlPexMaxIfGet())
  46168. + {
  46169. + mvOsPrintf("mvPexTargetWinEnable: ERR. Invalid PEX If %d\n", pexIf);
  46170. + return MV_BAD_PARAM;
  46171. + }
  46172. +
  46173. + if (winNum >= PEX_MAX_TARGET_WIN)
  46174. + {
  46175. + mvOsPrintf("mvPexTargetWinEnable ERR. Invalid PEX winNum %d\n", winNum);
  46176. + return MV_BAD_PARAM;
  46177. +
  46178. + }
  46179. +
  46180. +
  46181. + /* get the pex Window registers offsets */
  46182. + pexWinRegInfoGet(pexIf,winNum,&winRegInfo);
  46183. +
  46184. +
  46185. + /* if the address windows is disabled , we only disable the appropriare
  46186. + pex window and ignore other settings */
  46187. +
  46188. + if (MV_FALSE == enable)
  46189. + {
  46190. +
  46191. + /* this is not relevant to default and expantion rom
  46192. + windows */
  46193. + if (winRegInfo.sizeRegOffs)
  46194. + {
  46195. + if ((MV_PEX_WIN_DEFAULT != winNum)&&
  46196. + (MV_PEX_WIN_EXP_ROM != winNum))
  46197. + {
  46198. + MV_REG_BIT_RESET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN);
  46199. + }
  46200. + }
  46201. +
  46202. + }
  46203. + else
  46204. + {
  46205. + if (MV_OK != mvPexTargetWinGet(pexIf,winNum, &addrDecWin))
  46206. + {
  46207. + mvOsPrintf("mvPexTargetWinEnable: mvPexTargetWinGet Failed\n");
  46208. + return MV_ERROR;
  46209. + }
  46210. +
  46211. + /* Check if the requested window overlaps with current windows */
  46212. + if (MV_TRUE == pexWinOverlapDetect(pexIf,winNum, &addrDecWin.addrWin))
  46213. + {
  46214. + mvOsPrintf("mvPexTargetWinEnable: ERR. Target %d overlap\n", winNum);
  46215. + return MV_BAD_PARAM;
  46216. + }
  46217. +
  46218. + if (MV_FALSE == pexIsWinWithinBar(pexIf,&addrDecWin.addrWin))
  46219. + {
  46220. + mvOsPrintf("mvPexTargetWinEnable: Win %d should be in bar boundries\n",
  46221. + winNum);
  46222. + return MV_BAD_PARAM;
  46223. + }
  46224. +
  46225. +
  46226. + /* this is not relevant to default and expantion rom
  46227. + windows */
  46228. + if (winRegInfo.sizeRegOffs)
  46229. + {
  46230. + if ((MV_PEX_WIN_DEFAULT != winNum)&&
  46231. + (MV_PEX_WIN_EXP_ROM != winNum))
  46232. + {
  46233. + MV_REG_BIT_SET(winRegInfo.sizeRegOffs, PXWCR_WIN_EN);
  46234. + }
  46235. + }
  46236. +
  46237. +
  46238. + }
  46239. +
  46240. + return MV_OK;
  46241. +
  46242. +}
  46243. +
  46244. +
  46245. +
  46246. +/*******************************************************************************
  46247. +* mvPexTargetWinRemap - Set PEX to target address window remap.
  46248. +*
  46249. +* DESCRIPTION:
  46250. +* The PEX interface supports remap of the BAR original address window.
  46251. +* For each BAR it is possible to define a remap address. For example
  46252. +* an address 0x12345678 that hits BAR 0x10 (SDRAM CS[0]) will be modified
  46253. +* according to remap register but will also be targeted to the
  46254. +* SDRAM CS[0].
  46255. +*
  46256. +* INPUT:
  46257. +* pexIf - PEX interface number.
  46258. +* bar - Peripheral target enumerator accessed by slave.
  46259. +* pAddrWin - Address window to be checked.
  46260. +*
  46261. +* OUTPUT:
  46262. +* None.
  46263. +*
  46264. +* RETURN:
  46265. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  46266. +*
  46267. +*******************************************************************************/
  46268. +MV_STATUS mvPexTargetWinRemap(MV_U32 pexIf, MV_U32 winNum,
  46269. + MV_PEX_REMAP_WIN *pAddrWin)
  46270. +{
  46271. +
  46272. + PEX_WIN_REG_INFO winRegInfo;
  46273. +
  46274. + /* Parameter checking */
  46275. + if (pexIf >= mvCtrlPexMaxIfGet())
  46276. + {
  46277. + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n",
  46278. + pexIf);
  46279. + return MV_BAD_PARAM;
  46280. + }
  46281. + if (MV_PEX_WIN_DEFAULT == winNum)
  46282. + {
  46283. + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n",
  46284. + winNum);
  46285. + return MV_BAD_PARAM;
  46286. +
  46287. + }
  46288. +
  46289. + if (MV_IS_NOT_ALIGN(pAddrWin->addrWin.baseLow, PXWRR_REMAP_ALIGNMENT))
  46290. + {
  46291. + mvOsPrintf("mvPexTargetWinRemap: Error remap PEX interface %d win %d."\
  46292. + "\nAddress 0x%08x is unaligned to size 0x%x.\n",
  46293. + pexIf,
  46294. + winNum,
  46295. + pAddrWin->addrWin.baseLow,
  46296. + pAddrWin->addrWin.size);
  46297. +
  46298. + return MV_ERROR;
  46299. + }
  46300. +
  46301. + pexWinRegInfoGet(pexIf, winNum, &winRegInfo);
  46302. +
  46303. + /* Set remap low register value */
  46304. + MV_REG_WRITE(winRegInfo.remapLowRegOffs, pAddrWin->addrWin.baseLow);
  46305. +
  46306. + /* Skip base high settings if the BAR has only base low (32-bit) */
  46307. + if (0 != winRegInfo.remapHighRegOffs)
  46308. + {
  46309. + MV_REG_WRITE(winRegInfo.remapHighRegOffs, pAddrWin->addrWin.baseHigh);
  46310. + }
  46311. +
  46312. +
  46313. + if (pAddrWin->enable == MV_TRUE)
  46314. + {
  46315. + MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
  46316. + }
  46317. + else
  46318. + {
  46319. + MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
  46320. + }
  46321. +
  46322. + return MV_OK;
  46323. +}
  46324. +
  46325. +/*******************************************************************************
  46326. +* mvPexTargetWinRemapEnable -
  46327. +*
  46328. +* DESCRIPTION:
  46329. +*
  46330. +* INPUT:
  46331. +*
  46332. +* OUTPUT:
  46333. +*
  46334. +* RETURN:
  46335. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  46336. +*
  46337. +*******************************************************************************/
  46338. +
  46339. +MV_STATUS mvPexTargetWinRemapEnable(MV_U32 pexIf, MV_U32 winNum,
  46340. + MV_BOOL enable)
  46341. +{
  46342. + PEX_WIN_REG_INFO winRegInfo;
  46343. +
  46344. + /* Parameter checking */
  46345. + if (pexIf >= mvCtrlPexMaxIfGet())
  46346. + {
  46347. + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX interface num %d\n",
  46348. + pexIf);
  46349. + return MV_BAD_PARAM;
  46350. + }
  46351. + if (MV_PEX_WIN_DEFAULT == winNum)
  46352. + {
  46353. + mvOsPrintf("mvPexTargetWinRemap: ERR. Invalid PEX win num %d\n",
  46354. + winNum);
  46355. + return MV_BAD_PARAM;
  46356. +
  46357. + }
  46358. +
  46359. +
  46360. + pexWinRegInfoGet(pexIf, winNum, &winRegInfo);
  46361. +
  46362. + if (enable == MV_TRUE)
  46363. + {
  46364. + MV_REG_BIT_SET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
  46365. + }
  46366. + else
  46367. + {
  46368. + MV_REG_BIT_RESET(winRegInfo.remapLowRegOffs,PXWRR_REMAP_EN);
  46369. + }
  46370. +
  46371. + return MV_OK;
  46372. +
  46373. +}
  46374. +
  46375. +/*******************************************************************************
  46376. +* mvPexBarSet - Set PEX bar address and size
  46377. +*
  46378. +* DESCRIPTION:
  46379. +*
  46380. +* INPUT:
  46381. +*
  46382. +* OUTPUT:
  46383. +* None.
  46384. +*
  46385. +* RETURN:
  46386. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  46387. +*
  46388. +*******************************************************************************/
  46389. +MV_STATUS mvPexBarSet(MV_U32 pexIf,
  46390. + MV_U32 barNum,
  46391. + MV_PEX_BAR *pAddrWin)
  46392. +{
  46393. + MV_U32 regBaseLow;
  46394. + MV_U32 regSize,sizeToReg;
  46395. +
  46396. +
  46397. + /* check parameters */
  46398. + if(pexIf >= mvCtrlPexMaxIfGet())
  46399. + {
  46400. + mvOsPrintf("mvPexBarSet: ERR. Invalid PEX interface %d\n", pexIf);
  46401. + return MV_BAD_PARAM;
  46402. + }
  46403. +
  46404. + if(barNum >= PEX_MAX_BARS)
  46405. + {
  46406. + mvOsPrintf("mvPexBarSet: ERR. Invalid bar number %d\n", barNum);
  46407. + return MV_BAD_PARAM;
  46408. + }
  46409. +
  46410. +
  46411. + if (pAddrWin->addrWin.size == 0)
  46412. + {
  46413. + mvOsPrintf("mvPexBarSet: Size zero is Illigal\n" );
  46414. + return MV_BAD_PARAM;
  46415. + }
  46416. +
  46417. +
  46418. + /* Check if the window complies with PEX spec */
  46419. + if (MV_TRUE != pexBarIsValid(pAddrWin->addrWin.baseLow,
  46420. + pAddrWin->addrWin.size))
  46421. + {
  46422. + mvOsPrintf("mvPexBarSet: ERR. Target %d window invalid\n", barNum);
  46423. + return MV_BAD_PARAM;
  46424. + }
  46425. +
  46426. + /* 2) Check if the requested bar overlaps with current bars */
  46427. + if (MV_TRUE == pexBarOverlapDetect(pexIf,barNum, &pAddrWin->addrWin))
  46428. + {
  46429. + mvOsPrintf("mvPexBarSet: ERR. Target %d overlap\n", barNum);
  46430. + return MV_BAD_PARAM;
  46431. + }
  46432. +
  46433. + /* Get size register value according to window size */
  46434. + sizeToReg = ctrlSizeToReg(pAddrWin->addrWin.size, PXBCR_BAR_SIZE_ALIGNMENT);
  46435. +
  46436. + /* Read bar size */
  46437. + if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */
  46438. + {
  46439. + regSize = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum));
  46440. +
  46441. + /* Size parameter validity check. */
  46442. + if (-1 == sizeToReg)
  46443. + {
  46444. + mvOsPrintf("mvPexBarSet: ERR. Target BAR %d size invalid.\n",barNum);
  46445. + return MV_BAD_PARAM;
  46446. + }
  46447. +
  46448. + regSize &= ~PXBCR_BAR_SIZE_MASK;
  46449. + regSize |= (sizeToReg << PXBCR_BAR_SIZE_OFFS) ;
  46450. +
  46451. + MV_REG_WRITE(PEX_BAR_CTRL_REG(pexIf,barNum),regSize);
  46452. +
  46453. + }
  46454. +
  46455. + /* set size */
  46456. +
  46457. +
  46458. +
  46459. + /* Read base address low */
  46460. + regBaseLow = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,
  46461. + PEX_MV_BAR_BASE(barNum)));
  46462. +
  46463. + /* clear current base */
  46464. + if (PEX_INTER_REGS_BAR == barNum)
  46465. + {
  46466. + regBaseLow &= ~PXBIR_BASE_MASK;
  46467. + regBaseLow |= (pAddrWin->addrWin.baseLow & PXBIR_BASE_MASK);
  46468. + }
  46469. + else
  46470. + {
  46471. + regBaseLow &= ~PXBR_BASE_MASK;
  46472. + regBaseLow |= (pAddrWin->addrWin.baseLow & PXBR_BASE_MASK);
  46473. + }
  46474. +
  46475. + /* if we had a previous value that contain the bar type (MeM\IO), we want to
  46476. + restore it */
  46477. + regBaseLow |= PEX_BAR_DEFAULT_ATTRIB;
  46478. +
  46479. +
  46480. +
  46481. + /* write base low */
  46482. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)),
  46483. + regBaseLow);
  46484. +
  46485. + if (pAddrWin->addrWin.baseHigh != 0)
  46486. + {
  46487. + /* Read base address high */
  46488. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)),
  46489. + pAddrWin->addrWin.baseHigh);
  46490. +
  46491. + }
  46492. +
  46493. + /* lastly enable the Bar */
  46494. + if (pAddrWin->enable == MV_TRUE)
  46495. + {
  46496. + if (PEX_INTER_REGS_BAR != barNum) /* internal registers
  46497. + are enabled always */
  46498. + {
  46499. + MV_REG_BIT_SET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
  46500. + }
  46501. + }
  46502. + else if (MV_FALSE == pAddrWin->enable)
  46503. + {
  46504. + if (PEX_INTER_REGS_BAR != barNum) /* internal registers
  46505. + are enabled always */
  46506. + {
  46507. + MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
  46508. + }
  46509. +
  46510. + }
  46511. +
  46512. +
  46513. +
  46514. + return MV_OK;
  46515. +}
  46516. +
  46517. +
  46518. +/*******************************************************************************
  46519. +* mvPexBarGet - Get PEX bar address and size
  46520. +*
  46521. +* DESCRIPTION:
  46522. +*
  46523. +* INPUT:
  46524. +*
  46525. +* OUTPUT:
  46526. +* None.
  46527. +*
  46528. +* RETURN:
  46529. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  46530. +*
  46531. +*******************************************************************************/
  46532. +
  46533. +MV_STATUS mvPexBarGet(MV_U32 pexIf,
  46534. + MV_U32 barNum,
  46535. + MV_PEX_BAR *pAddrWin)
  46536. +{
  46537. + /* check parameters */
  46538. + if(pexIf >= mvCtrlPexMaxIfGet())
  46539. + {
  46540. + mvOsPrintf("mvPexBarGet: ERR. Invalid PEX interface %d\n", pexIf);
  46541. + return MV_BAD_PARAM;
  46542. + }
  46543. +
  46544. + if(barNum >= PEX_MAX_BARS)
  46545. + {
  46546. + mvOsPrintf("mvPexBarGet: ERR. Invalid bar number %d\n", barNum);
  46547. + return MV_BAD_PARAM;
  46548. + }
  46549. +
  46550. + /* read base low */
  46551. + pAddrWin->addrWin.baseLow =
  46552. + MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE(barNum)));
  46553. +
  46554. +
  46555. + if (PEX_INTER_REGS_BAR == barNum)
  46556. + {
  46557. + pAddrWin->addrWin.baseLow &= PXBIR_BASE_MASK;
  46558. + }
  46559. + else
  46560. + {
  46561. + pAddrWin->addrWin.baseLow &= PXBR_BASE_MASK;
  46562. + }
  46563. +
  46564. +
  46565. + /* read base high */
  46566. + pAddrWin->addrWin.baseHigh =
  46567. + MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_MV_BAR_BASE_HIGH(barNum)));
  46568. +
  46569. +
  46570. + /* Read bar size */
  46571. + if (PEX_INTER_REGS_BAR != barNum) /* internal registers have no size */
  46572. + {
  46573. + pAddrWin->addrWin.size = MV_REG_READ(PEX_BAR_CTRL_REG(pexIf,barNum));
  46574. +
  46575. + /* check if enable or not */
  46576. + if (pAddrWin->addrWin.size & PXBCR_BAR_EN)
  46577. + {
  46578. + pAddrWin->enable = MV_TRUE;
  46579. + }
  46580. + else
  46581. + {
  46582. + pAddrWin->enable = MV_FALSE;
  46583. + }
  46584. +
  46585. + /* now get the size */
  46586. + pAddrWin->addrWin.size &= PXBCR_BAR_SIZE_MASK;
  46587. + pAddrWin->addrWin.size >>= PXBCR_BAR_SIZE_OFFS;
  46588. +
  46589. + pAddrWin->addrWin.size = ctrlRegToSize(pAddrWin->addrWin.size,
  46590. + PXBCR_BAR_SIZE_ALIGNMENT);
  46591. +
  46592. + }
  46593. + else /* PEX_INTER_REGS_BAR */
  46594. + {
  46595. + pAddrWin->addrWin.size = INTER_REGS_SIZE;
  46596. + pAddrWin->enable = MV_TRUE;
  46597. + }
  46598. +
  46599. +
  46600. + return MV_OK;
  46601. +}
  46602. +
  46603. +/*******************************************************************************
  46604. +* mvPexBarEnable -
  46605. +*
  46606. +* DESCRIPTION:
  46607. +*
  46608. +* INPUT:
  46609. +*
  46610. +* OUTPUT:
  46611. +* None.
  46612. +*
  46613. +* RETURN:
  46614. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  46615. +*
  46616. +*******************************************************************************/
  46617. +
  46618. +
  46619. +MV_STATUS mvPexBarEnable(MV_U32 pexIf, MV_U32 barNum, MV_BOOL enable)
  46620. +{
  46621. +
  46622. + MV_PEX_BAR pexBar;
  46623. +
  46624. + /* check parameters */
  46625. + if(pexIf >= mvCtrlPexMaxIfGet())
  46626. + {
  46627. + mvOsPrintf("mvPexBarEnable: ERR. Invalid PEX interface %d\n", pexIf);
  46628. + return MV_BAD_PARAM;
  46629. + }
  46630. +
  46631. +
  46632. + if(barNum >= PEX_MAX_BARS)
  46633. + {
  46634. + mvOsPrintf("mvPexBarEnable: ERR. Invalid bar number %d\n", barNum);
  46635. + return MV_BAD_PARAM;
  46636. + }
  46637. +
  46638. + if (PEX_INTER_REGS_BAR == barNum)
  46639. + {
  46640. + if (MV_TRUE == enable)
  46641. + {
  46642. + return MV_OK;
  46643. + }
  46644. + else
  46645. + {
  46646. + return MV_ERROR;
  46647. + }
  46648. + }
  46649. +
  46650. +
  46651. + if (MV_FALSE == enable)
  46652. + {
  46653. + /* disable bar and quit */
  46654. + MV_REG_BIT_RESET(PEX_BAR_CTRL_REG(pexIf,barNum),PXBCR_BAR_EN);
  46655. + return MV_OK;
  46656. + }
  46657. +
  46658. + /* else */
  46659. +
  46660. + if (mvPexBarGet(pexIf,barNum,&pexBar) != MV_OK)
  46661. + {
  46662. + mvOsPrintf("mvPexBarEnable: mvPexBarGet Failed\n");
  46663. + return MV_ERROR;
  46664. +
  46665. + }
  46666. +
  46667. + if (MV_TRUE == pexBar.enable)
  46668. + {
  46669. + /* it is already enabled !!! */
  46670. + return MV_OK;
  46671. + }
  46672. +
  46673. + /* else enable the bar*/
  46674. +
  46675. + pexBar.enable = MV_TRUE;
  46676. +
  46677. + if (mvPexBarSet(pexIf,barNum,&pexBar) != MV_OK)
  46678. + {
  46679. + mvOsPrintf("mvPexBarEnable: mvPexBarSet Failed\n");
  46680. + return MV_ERROR;
  46681. +
  46682. + }
  46683. +
  46684. + return MV_OK;
  46685. +}
  46686. +
  46687. +
  46688. +/*******************************************************************************
  46689. +* pexWinOverlapDetect - Detect address windows overlapping
  46690. +*
  46691. +* DESCRIPTION:
  46692. +* This function detects address window overlapping of a given address
  46693. +* window in PEX BARs.
  46694. +*
  46695. +* INPUT:
  46696. +* pAddrWin - Address window to be checked.
  46697. +* bar - BAR to be accessed by slave.
  46698. +*
  46699. +* OUTPUT:
  46700. +* None.
  46701. +*
  46702. +* RETURN:
  46703. +* MV_TRUE if the given address window overlap current address
  46704. +* decode map, MV_FALSE otherwise.
  46705. +*
  46706. +*******************************************************************************/
  46707. +static MV_BOOL pexWinOverlapDetect(MV_U32 pexIf,
  46708. + MV_U32 winNum,
  46709. + MV_ADDR_WIN *pAddrWin)
  46710. +{
  46711. + MV_U32 win;
  46712. + MV_PEX_DEC_WIN addrDecWin;
  46713. +
  46714. +
  46715. + for(win = 0; win < PEX_MAX_TARGET_WIN -2 ; win++)
  46716. + {
  46717. + /* don't check our target or illegal targets */
  46718. + if (winNum == win)
  46719. + {
  46720. + continue;
  46721. + }
  46722. +
  46723. + /* Get window parameters */
  46724. + if (MV_OK != mvPexTargetWinGet(pexIf, win, &addrDecWin))
  46725. + {
  46726. + mvOsPrintf("pexWinOverlapDetect: ERR. TargetWinGet failed win=%x\n",
  46727. + win);
  46728. + return MV_ERROR;
  46729. + }
  46730. +
  46731. + /* Do not check disabled windows */
  46732. + if (MV_FALSE == addrDecWin.enable)
  46733. + {
  46734. + continue;
  46735. + }
  46736. +
  46737. +
  46738. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
  46739. + {
  46740. + mvOsPrintf("pexWinOverlapDetect: winNum %d overlap current %d\n",
  46741. + winNum, win);
  46742. + return MV_TRUE;
  46743. + }
  46744. + }
  46745. +
  46746. + return MV_FALSE;
  46747. +}
  46748. +
  46749. +/*******************************************************************************
  46750. +* pexIsWinWithinBar - Detect if address is within PEX bar boundries
  46751. +*
  46752. +* DESCRIPTION:
  46753. +*
  46754. +* INPUT:
  46755. +*
  46756. +* OUTPUT:
  46757. +* None.
  46758. +*
  46759. +* RETURN:
  46760. +* MV_TRUE if the given address window overlap current address
  46761. +* decode map, MV_FALSE otherwise.
  46762. +*
  46763. +*******************************************************************************/
  46764. +static MV_BOOL pexIsWinWithinBar(MV_U32 pexIf,
  46765. + MV_ADDR_WIN *pAddrWin)
  46766. +{
  46767. + MV_U32 bar;
  46768. + MV_PEX_BAR addrDecWin;
  46769. +
  46770. + for(bar = 0; bar < PEX_MAX_BARS; bar++)
  46771. + {
  46772. +
  46773. + /* Get window parameters */
  46774. + if (MV_OK != mvPexBarGet(pexIf, bar, &addrDecWin))
  46775. + {
  46776. + mvOsPrintf("pexIsWinWithinBar: ERR. mvPexBarGet failed\n");
  46777. + return MV_ERROR;
  46778. + }
  46779. +
  46780. + /* Do not check disabled bars */
  46781. + if (MV_FALSE == addrDecWin.enable)
  46782. + {
  46783. + continue;
  46784. + }
  46785. +
  46786. +
  46787. + if(MV_TRUE == ctrlWinWithinWinTest(pAddrWin, &addrDecWin.addrWin))
  46788. + {
  46789. + return MV_TRUE;
  46790. + }
  46791. + }
  46792. +
  46793. + return MV_FALSE;
  46794. +
  46795. +}
  46796. +
  46797. +/*******************************************************************************
  46798. +* pexBarOverlapDetect - Detect address windows overlapping
  46799. +*
  46800. +* DESCRIPTION:
  46801. +* This function detects address window overlapping of a given address
  46802. +* window in PEX BARs.
  46803. +*
  46804. +* INPUT:
  46805. +* pAddrWin - Address window to be checked.
  46806. +* bar - BAR to be accessed by slave.
  46807. +*
  46808. +* OUTPUT:
  46809. +* None.
  46810. +*
  46811. +* RETURN:
  46812. +* MV_TRUE if the given address window overlap current address
  46813. +* decode map, MV_FALSE otherwise.
  46814. +*
  46815. +*******************************************************************************/
  46816. +static MV_BOOL pexBarOverlapDetect(MV_U32 pexIf,
  46817. + MV_U32 barNum,
  46818. + MV_ADDR_WIN *pAddrWin)
  46819. +{
  46820. + MV_U32 bar;
  46821. + MV_PEX_BAR barDecWin;
  46822. +
  46823. +
  46824. + for(bar = 0; bar < PEX_MAX_BARS; bar++)
  46825. + {
  46826. + /* don't check our target or illegal targets */
  46827. + if (barNum == bar)
  46828. + {
  46829. + continue;
  46830. + }
  46831. +
  46832. + /* Get window parameters */
  46833. + if (MV_OK != mvPexBarGet(pexIf, bar, &barDecWin))
  46834. + {
  46835. + mvOsPrintf("pexBarOverlapDetect: ERR. TargetWinGet failed\n");
  46836. + return MV_ERROR;
  46837. + }
  46838. +
  46839. + /* don'nt check disabled bars */
  46840. + if (barDecWin.enable == MV_FALSE)
  46841. + {
  46842. + continue;
  46843. + }
  46844. +
  46845. +
  46846. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &barDecWin.addrWin))
  46847. + {
  46848. + mvOsPrintf("pexBarOverlapDetect: winNum %d overlap current %d\n",
  46849. + barNum, bar);
  46850. + return MV_TRUE;
  46851. + }
  46852. + }
  46853. +
  46854. + return MV_FALSE;
  46855. +}
  46856. +
  46857. +/*******************************************************************************
  46858. +* pexBarIsValid - Check if the given address window is valid
  46859. +*
  46860. +* DESCRIPTION:
  46861. +* PEX spec restrict BAR base to be aligned to BAR size.
  46862. +* This function checks if the given address window is valid.
  46863. +*
  46864. +* INPUT:
  46865. +* baseLow - 32bit low base address.
  46866. +* size - Window size.
  46867. +*
  46868. +* OUTPUT:
  46869. +* None.
  46870. +*
  46871. +* RETURN:
  46872. +* MV_TRUE if the address window is valid, MV_FALSE otherwise.
  46873. +*
  46874. +*******************************************************************************/
  46875. +static MV_STATUS pexBarIsValid(MV_U32 baseLow, MV_U32 size)
  46876. +{
  46877. +
  46878. + /* PCI spec restrict BAR base to be aligned to BAR size */
  46879. + if(MV_IS_NOT_ALIGN(baseLow, size))
  46880. + {
  46881. + return MV_ERROR;
  46882. + }
  46883. + else
  46884. + {
  46885. + return MV_TRUE;
  46886. + }
  46887. +
  46888. + return MV_TRUE;
  46889. +}
  46890. +
  46891. +/*******************************************************************************
  46892. +* pexBarRegInfoGet - Get BAR register information
  46893. +*
  46894. +* DESCRIPTION:
  46895. +* PEX BARs registers offsets are inconsecutive.
  46896. +* This function gets a PEX BAR register information like register offsets
  46897. +* and function location of the BAR.
  46898. +*
  46899. +* INPUT:
  46900. +* pexIf - PEX interface number.
  46901. +* bar - The PEX BAR in question.
  46902. +*
  46903. +* OUTPUT:
  46904. +* pBarRegInfo - BAR register info struct.
  46905. +*
  46906. +* RETURN:
  46907. +* MV_BAD_PARAM when bad parameters ,MV_ERROR on error ,othewise MV_OK
  46908. +*
  46909. +*******************************************************************************/
  46910. +static MV_STATUS pexWinRegInfoGet(MV_U32 pexIf,
  46911. + MV_U32 winNum,
  46912. + PEX_WIN_REG_INFO *pWinRegInfo)
  46913. +{
  46914. +
  46915. + if ((winNum >= 0)&&(winNum <=3))
  46916. + {
  46917. + pWinRegInfo->baseLowRegOffs = PEX_WIN0_3_BASE_REG(pexIf,winNum);
  46918. + pWinRegInfo->baseHighRegOffs = 0;
  46919. + pWinRegInfo->sizeRegOffs = PEX_WIN0_3_CTRL_REG(pexIf,winNum);
  46920. + pWinRegInfo->remapLowRegOffs = PEX_WIN0_3_REMAP_REG(pexIf,winNum);
  46921. + pWinRegInfo->remapHighRegOffs = 0;
  46922. + }
  46923. + else if ((winNum >= 4)&&(winNum <=5))
  46924. + {
  46925. + pWinRegInfo->baseLowRegOffs = PEX_WIN4_5_BASE_REG(pexIf,winNum);
  46926. + pWinRegInfo->baseHighRegOffs = 0;
  46927. + pWinRegInfo->sizeRegOffs = PEX_WIN4_5_CTRL_REG(pexIf,winNum);
  46928. + pWinRegInfo->remapLowRegOffs = PEX_WIN4_5_REMAP_REG(pexIf,winNum);
  46929. + pWinRegInfo->remapHighRegOffs = PEX_WIN4_5_REMAP_HIGH_REG(pexIf,winNum);
  46930. +
  46931. + }
  46932. + else if (MV_PEX_WIN_DEFAULT == winNum)
  46933. + {
  46934. + pWinRegInfo->baseLowRegOffs = 0;
  46935. + pWinRegInfo->baseHighRegOffs = 0;
  46936. + pWinRegInfo->sizeRegOffs = PEX_WIN_DEFAULT_CTRL_REG(pexIf);
  46937. + pWinRegInfo->remapLowRegOffs = 0;
  46938. + pWinRegInfo->remapHighRegOffs = 0;
  46939. + }
  46940. + else if (MV_PEX_WIN_EXP_ROM == winNum)
  46941. + {
  46942. + pWinRegInfo->baseLowRegOffs = 0;
  46943. + pWinRegInfo->baseHighRegOffs = 0;
  46944. + pWinRegInfo->sizeRegOffs = PEX_WIN_EXP_ROM_CTRL_REG(pexIf);
  46945. + pWinRegInfo->remapLowRegOffs = PEX_WIN_EXP_ROM_REMAP_REG(pexIf);
  46946. + pWinRegInfo->remapHighRegOffs = 0;
  46947. +
  46948. + }
  46949. +
  46950. + return MV_OK;
  46951. +}
  46952. +
  46953. +/*******************************************************************************
  46954. +* pexBarNameGet - Get the string name of PEX BAR.
  46955. +*
  46956. +* DESCRIPTION:
  46957. +* This function get the string name of PEX BAR.
  46958. +*
  46959. +* INPUT:
  46960. +* bar - PEX bar number.
  46961. +*
  46962. +* OUTPUT:
  46963. +* None.
  46964. +*
  46965. +* RETURN:
  46966. +* pointer to the string name of PEX BAR.
  46967. +*
  46968. +*******************************************************************************/
  46969. +const MV_8* pexBarNameGet( MV_U32 bar )
  46970. +{
  46971. + switch( bar )
  46972. + {
  46973. + case PEX_INTER_REGS_BAR:
  46974. + return "Internal Regs Bar0....";
  46975. + case PEX_DRAM_BAR:
  46976. + return "DRAM Bar1.............";
  46977. + case PEX_DEVICE_BAR:
  46978. + return "Devices Bar2..........";
  46979. + default:
  46980. + return "Bar unknown";
  46981. + }
  46982. +}
  46983. +/*******************************************************************************
  46984. +* mvPexAddrDecShow - Print the PEX address decode map (BARs and windows).
  46985. +*
  46986. +* DESCRIPTION:
  46987. +* This function print the PEX address decode map (BARs and windows).
  46988. +*
  46989. +* INPUT:
  46990. +* None.
  46991. +*
  46992. +* OUTPUT:
  46993. +* None.
  46994. +*
  46995. +* RETURN:
  46996. +* None.
  46997. +*
  46998. +*******************************************************************************/
  46999. +MV_VOID mvPexAddrDecShow(MV_VOID)
  47000. +{
  47001. + MV_PEX_BAR pexBar;
  47002. + MV_PEX_DEC_WIN win;
  47003. + MV_U32 pexIf;
  47004. + MV_U32 bar,winNum;
  47005. +
  47006. + for( pexIf = 0; pexIf < mvCtrlPexMaxIfGet(); pexIf++ )
  47007. + {
  47008. + if (MV_FALSE == mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf)) continue;
  47009. + mvOsOutput( "\n" );
  47010. + mvOsOutput( "PEX%d:\n", pexIf );
  47011. + mvOsOutput( "-----\n" );
  47012. +
  47013. + mvOsOutput( "\nPex Bars \n\n");
  47014. +
  47015. + for( bar = 0; bar < PEX_MAX_BARS; bar++ )
  47016. + {
  47017. + memset( &pexBar, 0, sizeof(MV_PEX_BAR) );
  47018. +
  47019. + mvOsOutput( "%s ", pexBarNameGet(bar) );
  47020. +
  47021. + if( mvPexBarGet( pexIf, bar, &pexBar ) == MV_OK )
  47022. + {
  47023. + if( pexBar.enable )
  47024. + {
  47025. + mvOsOutput( "base %08x, ", pexBar.addrWin.baseLow );
  47026. + mvSizePrint( pexBar.addrWin.size );
  47027. + mvOsOutput( "\n" );
  47028. + }
  47029. + else
  47030. + mvOsOutput( "disable\n" );
  47031. + }
  47032. + }
  47033. + mvOsOutput( "\nPex Decode Windows\n\n");
  47034. +
  47035. + for( winNum = 0; winNum < PEX_MAX_TARGET_WIN - 2; winNum++)
  47036. + {
  47037. + memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
  47038. +
  47039. + mvOsOutput( "win%d - ", winNum );
  47040. +
  47041. + if ( mvPexTargetWinGet(pexIf,winNum,&win) == MV_OK)
  47042. + {
  47043. + if (win.enable)
  47044. + {
  47045. + mvOsOutput( "%s base %08x, ",
  47046. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  47047. + mvOsOutput( "...." );
  47048. + mvSizePrint( win.addrWin.size );
  47049. +
  47050. + mvOsOutput( "\n" );
  47051. + }
  47052. + else
  47053. + mvOsOutput( "disable\n" );
  47054. +
  47055. +
  47056. + }
  47057. + }
  47058. +
  47059. + memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
  47060. +
  47061. + mvOsOutput( "default win - " );
  47062. +
  47063. + if ( mvPexTargetWinGet(pexIf, MV_PEX_WIN_DEFAULT, &win) == MV_OK)
  47064. + {
  47065. + mvOsOutput( "%s ",
  47066. + mvCtrlTargetNameGet(win.target) );
  47067. + mvOsOutput( "\n" );
  47068. + }
  47069. + memset( &win, 0,sizeof(MV_PEX_DEC_WIN) );
  47070. +
  47071. + mvOsOutput( "Expansion ROM - " );
  47072. +
  47073. + if ( mvPexTargetWinGet(pexIf, MV_PEX_WIN_EXP_ROM, &win) == MV_OK)
  47074. + {
  47075. + mvOsOutput( "%s ",
  47076. + mvCtrlTargetNameGet(win.target) );
  47077. + mvOsOutput( "\n" );
  47078. + }
  47079. +
  47080. + }
  47081. +}
  47082. +
  47083. +
  47084. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h
  47085. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h 1970-01-01 01:00:00.000000000 +0100
  47086. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysPex.h 2011-08-01 14:38:19.000000000 +0200
  47087. @@ -0,0 +1,348 @@
  47088. +/*******************************************************************************
  47089. +Copyright (C) Marvell International Ltd. and its affiliates
  47090. +
  47091. +This software file (the "File") is owned and distributed by Marvell
  47092. +International Ltd. and/or its affiliates ("Marvell") under the following
  47093. +alternative licensing terms. Once you have made an election to distribute the
  47094. +File under one of the following license alternatives, please (i) delete this
  47095. +introductory statement regarding license alternatives, (ii) delete the two
  47096. +license alternatives that you have not elected to use and (iii) preserve the
  47097. +Marvell copyright notice above.
  47098. +
  47099. +********************************************************************************
  47100. +Marvell Commercial License Option
  47101. +
  47102. +If you received this File from Marvell and you have entered into a commercial
  47103. +license agreement (a "Commercial License") with Marvell, the File is licensed
  47104. +to you under the terms of the applicable Commercial License.
  47105. +
  47106. +********************************************************************************
  47107. +Marvell GPL License Option
  47108. +
  47109. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47110. +modify this File in accordance with the terms and conditions of the General
  47111. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  47112. +available along with the File in the license.txt file or by writing to the Free
  47113. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  47114. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  47115. +
  47116. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  47117. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  47118. +DISCLAIMED. The GPL License provides additional details about this warranty
  47119. +disclaimer.
  47120. +********************************************************************************
  47121. +Marvell BSD License Option
  47122. +
  47123. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47124. +modify this File under the following licensing terms.
  47125. +Redistribution and use in source and binary forms, with or without modification,
  47126. +are permitted provided that the following conditions are met:
  47127. +
  47128. + * Redistributions of source code must retain the above copyright notice,
  47129. + this list of conditions and the following disclaimer.
  47130. +
  47131. + * Redistributions in binary form must reproduce the above copyright
  47132. + notice, this list of conditions and the following disclaimer in the
  47133. + documentation and/or other materials provided with the distribution.
  47134. +
  47135. + * Neither the name of Marvell nor the names of its contributors may be
  47136. + used to endorse or promote products derived from this software without
  47137. + specific prior written permission.
  47138. +
  47139. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  47140. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  47141. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  47142. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  47143. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  47144. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  47145. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  47146. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  47147. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  47148. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  47149. +
  47150. +*******************************************************************************/
  47151. +
  47152. +#ifndef __INCSysPEXH
  47153. +#define __INCSysPEXH
  47154. +
  47155. +#include "mvCommon.h"
  47156. +#include "ctrlEnv/sys/mvCpuIf.h"
  47157. +#include "ctrlEnv/mvCtrlEnvLib.h"
  47158. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  47159. +
  47160. +/* 4KB granularity */
  47161. +#define MINIMUM_WINDOW_SIZE 0x1000
  47162. +#define MINIMUM_BAR_SIZE 0x1000
  47163. +#define MINIMUM_BAR_SIZE_MASK 0xFFFFF000
  47164. +#define BAR_SIZE_OFFS 12
  47165. +#define BAR_SIZE_MASK (0xFFFFF << BAR_SIZE_OFFS)
  47166. +
  47167. +
  47168. +
  47169. +#define MV_PEX_WIN_DEFAULT 6
  47170. +#define MV_PEX_WIN_EXP_ROM 7
  47171. +#define PEX_MAX_TARGET_WIN 8
  47172. +
  47173. +
  47174. +#define PEX_MAX_BARS 3
  47175. +#define PEX_INTER_REGS_BAR 0
  47176. +#define PEX_DRAM_BAR 1
  47177. +#define PEX_DEVICE_BAR 2
  47178. +
  47179. +/*************************************/
  47180. +/* PCI Express BAR Control Registers */
  47181. +/*************************************/
  47182. +#define PEX_BAR_CTRL_REG(pexIf,bar) (0x41804 + (bar-1)*4- (pexIf)*0x10000)
  47183. +#define PEX_EXP_ROM_BAR_CTRL_REG(pexIf) (0x4180C - (pexIf)*0x10000)
  47184. +
  47185. +
  47186. +/* PCI Express BAR Control Register */
  47187. +/* PEX_BAR_CTRL_REG (PXBCR) */
  47188. +
  47189. +#define PXBCR_BAR_EN BIT0
  47190. +#define PXBCR_BAR_SIZE_OFFS 16
  47191. +#define PXBCR_BAR_SIZE_MASK (0xffff << PXBCR_BAR_SIZE_OFFS)
  47192. +#define PXBCR_BAR_SIZE_ALIGNMENT 0x10000
  47193. +
  47194. +
  47195. +
  47196. +/* PCI Express Expansion ROM BAR Control Register */
  47197. +/* PEX_EXP_ROM_BAR_CTRL_REG (PXERBCR) */
  47198. +
  47199. +#define PXERBCR_EXPROM_EN BIT0
  47200. +#define PXERBCR_EXPROMSZ_OFFS 19
  47201. +#define PXERBCR_EXPROMSZ_MASK (0xf << PXERBCR_EXPROMSZ_OFFS)
  47202. +#define PXERBCR_EXPROMSZ_512KB (0x0 << PXERBCR_EXPROMSZ_OFFS)
  47203. +#define PXERBCR_EXPROMSZ_1024KB (0x1 << PXERBCR_EXPROMSZ_OFFS)
  47204. +#define PXERBCR_EXPROMSZ_2048KB (0x3 << PXERBCR_EXPROMSZ_OFFS)
  47205. +#define PXERBCR_EXPROMSZ_4096KB (0x7 << PXERBCR_EXPROMSZ_OFFS)
  47206. +
  47207. +/************************************************/
  47208. +/* PCI Express Address Window Control Registers */
  47209. +/************************************************/
  47210. +#define PEX_WIN0_3_CTRL_REG(pexIf,winNum) \
  47211. + (0x41820 + (winNum) * 0x10 - (pexIf) * 0x10000)
  47212. +#define PEX_WIN0_3_BASE_REG(pexIf,winNum) \
  47213. + (0x41824 + (winNum) * 0x10 - (pexIf) * 0x10000)
  47214. +#define PEX_WIN0_3_REMAP_REG(pexIf,winNum) \
  47215. + (0x4182C + (winNum) * 0x10 - (pexIf) * 0x10000)
  47216. +#define PEX_WIN4_5_CTRL_REG(pexIf,winNum) \
  47217. + (0x41860 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
  47218. +#define PEX_WIN4_5_BASE_REG(pexIf,winNum) \
  47219. + (0x41864 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
  47220. +#define PEX_WIN4_5_REMAP_REG(pexIf,winNum) \
  47221. + (0x4186C + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
  47222. +#define PEX_WIN4_5_REMAP_HIGH_REG(pexIf,winNum) \
  47223. + (0x41870 + (winNum - 4) * 0x20 - (pexIf) * 0x10000)
  47224. +
  47225. +#define PEX_WIN_DEFAULT_CTRL_REG(pexIf) (0x418B0 - (pexIf) * 0x10000)
  47226. +#define PEX_WIN_EXP_ROM_CTRL_REG(pexIf) (0x418C0 - (pexIf) * 0x10000)
  47227. +#define PEX_WIN_EXP_ROM_REMAP_REG(pexIf) (0x418C4 - (pexIf) * 0x10000)
  47228. +
  47229. +/* PCI Express Window Control Register */
  47230. +/* PEX_WIN_CTRL_REG (PXWCR) */
  47231. +
  47232. +#define PXWCR_WIN_EN BIT0 /* Window Enable.*/
  47233. +
  47234. +#define PXWCR_WIN_BAR_MAP_OFFS 1 /* Mapping to BAR.*/
  47235. +#define PXWCR_WIN_BAR_MAP_MASK BIT1
  47236. +#define PXWCR_WIN_BAR_MAP_BAR1 (0 << PXWCR_WIN_BAR_MAP_OFFS)
  47237. +#define PXWCR_WIN_BAR_MAP_BAR2 (1 << PXWCR_WIN_BAR_MAP_OFFS)
  47238. +
  47239. +#define PXWCR_TARGET_OFFS 4 /*Unit ID */
  47240. +#define PXWCR_TARGET_MASK (0xf << PXWCR_TARGET_OFFS)
  47241. +
  47242. +#define PXWCR_ATTRIB_OFFS 8 /* target attributes */
  47243. +#define PXWCR_ATTRIB_MASK (0xff << PXWCR_ATTRIB_OFFS)
  47244. +
  47245. +#define PXWCR_SIZE_OFFS 16 /* size */
  47246. +#define PXWCR_SIZE_MASK (0xffff << PXWCR_SIZE_OFFS)
  47247. +#define PXWCR_SIZE_ALIGNMENT 0x10000
  47248. +
  47249. +/* PCI Express Window Base Register */
  47250. +/* PEX_WIN_BASE_REG (PXWBR)*/
  47251. +
  47252. +#define PXWBR_BASE_OFFS 16 /* address[31:16] */
  47253. +#define PXWBR_BASE_MASK (0xffff << PXWBR_BASE_OFFS)
  47254. +#define PXWBR_BASE_ALIGNMENT 0x10000
  47255. +
  47256. +/* PCI Express Window Remap Register */
  47257. +/* PEX_WIN_REMAP_REG (PXWRR)*/
  47258. +
  47259. +#define PXWRR_REMAP_EN BIT0
  47260. +#define PXWRR_REMAP_OFFS 16
  47261. +#define PXWRR_REMAP_MASK (0xffff << PXWRR_REMAP_OFFS)
  47262. +#define PXWRR_REMAP_ALIGNMENT 0x10000
  47263. +
  47264. +/* PCI Express Window Remap (High) Register */
  47265. +/* PEX_WIN_REMAP_HIGH_REG (PXWRHR)*/
  47266. +
  47267. +#define PXWRHR_REMAP_HIGH_OFFS 0
  47268. +#define PXWRHR_REMAP_HIGH_MASK (0xffffffff << PXWRHR_REMAP_HIGH_OFFS)
  47269. +
  47270. +/* PCI Express Default Window Control Register */
  47271. +/* PEX_WIN_DEFAULT_CTRL_REG (PXWDCR) */
  47272. +
  47273. +#define PXWDCR_TARGET_OFFS 4 /*Unit ID */
  47274. +#define PXWDCR_TARGET_MASK (0xf << PXWDCR_TARGET_OFFS)
  47275. +#define PXWDCR_ATTRIB_OFFS 8 /* target attributes */
  47276. +#define PXWDCR_ATTRIB_MASK (0xff << PXWDCR_ATTRIB_OFFS)
  47277. +
  47278. +/* PCI Express Expansion ROM Window Control Register */
  47279. +/* PEX_WIN_EXP_ROM_CTRL_REG (PXWERCR)*/
  47280. +
  47281. +#define PXWERCR_TARGET_OFFS 4 /*Unit ID */
  47282. +#define PXWERCR_TARGET_MASK (0xf << PXWERCR_TARGET_OFFS)
  47283. +#define PXWERCR_ATTRIB_OFFS 8 /* target attributes */
  47284. +#define PXWERCR_ATTRIB_MASK (0xff << PXWERCR_ATTRIB_OFFS)
  47285. +
  47286. +/* PCI Express Expansion ROM Window Remap Register */
  47287. +/* PEX_WIN_EXP_ROM_REMAP_REG (PXWERRR)*/
  47288. +
  47289. +#define PXWERRR_REMAP_EN BIT0
  47290. +#define PXWERRR_REMAP_OFFS 16
  47291. +#define PXWERRR_REMAP_MASK (0xffff << PXWERRR_REMAP_OFFS)
  47292. +#define PXWERRR_REMAP_ALIGNMENT 0x10000
  47293. +
  47294. +
  47295. +
  47296. +/*PEX_MEMORY_BAR_BASE_ADDR(barNum) (PXMBBA)*/
  47297. +/* PCI Express BAR0 Internal Register*/
  47298. +/*PEX BAR0_INTER_REG (PXBIR)*/
  47299. +
  47300. +#define PXBIR_IOSPACE BIT0 /* Memory Space Indicator */
  47301. +
  47302. +#define PXBIR_TYPE_OFFS 1 /* BAR Type/Init Val. */
  47303. +#define PXBIR_TYPE_MASK (0x3 << PXBIR_TYPE_OFFS)
  47304. +#define PXBIR_TYPE_32BIT_ADDR (0x0 << PXBIR_TYPE_OFFS)
  47305. +#define PXBIR_TYPE_64BIT_ADDR (0x2 << PXBIR_TYPE_OFFS)
  47306. +
  47307. +#define PXBIR_PREFETCH_EN BIT3 /* Prefetch Enable */
  47308. +
  47309. +#define PXBIR_BASE_OFFS 20 /* Base address. Address bits [31:20] */
  47310. +#define PXBIR_BASE_MASK (0xfff << PXBIR_BASE_OFFS)
  47311. +#define PXBIR_BASE_ALIGNMET (1 << PXBIR_BASE_OFFS)
  47312. +
  47313. +
  47314. +/* PCI Express BAR0 Internal (High) Register*/
  47315. +/*PEX BAR0_INTER_REG_HIGH (PXBIRH)*/
  47316. +
  47317. +#define PXBIRH_BASE_OFFS 0 /* Base address. Bits [63:32] */
  47318. +#define PXBIRH_BASE_MASK (0xffffffff << PBBHR_BASE_OFFS)
  47319. +
  47320. +
  47321. +#define PEX_BAR_DEFAULT_ATTRIB 0xc /* Memory - Prefetch - 64 bit address */
  47322. +#define PEX_BAR0_DEFAULT_ATTRIB PEX_BAR_DEFAULT_ATTRIB
  47323. +#define PEX_BAR1_DEFAULT_ATTRIB PEX_BAR_DEFAULT_ATTRIB
  47324. +#define PEX_BAR2_DEFAULT_ATTRIB PEX_BAR_DEFAULT_ATTRIB
  47325. +
  47326. +
  47327. +/* PCI Express BAR1 Register */
  47328. +/* PCI Express BAR2 Register*/
  47329. +/*PEX BAR1_REG (PXBR)*/
  47330. +/*PEX BAR2_REG (PXBR)*/
  47331. +
  47332. +#define PXBR_IOSPACE BIT0 /* Memory Space Indicator */
  47333. +
  47334. +#define PXBR_TYPE_OFFS 1 /* BAR Type/Init Val. */
  47335. +#define PXBR_TYPE_MASK (0x3 << PXBR_TYPE_OFFS)
  47336. +#define PXBR_TYPE_32BIT_ADDR (0x0 << PXBR_TYPE_OFFS)
  47337. +#define PXBR_TYPE_64BIT_ADDR (0x2 << PXBR_TYPE_OFFS)
  47338. +
  47339. +#define PXBR_PREFETCH_EN BIT3 /* Prefetch Enable */
  47340. +
  47341. +#define PXBR_BASE_OFFS 16 /* Base address. Address bits [31:16] */
  47342. +#define PXBR_BASE_MASK (0xffff << PXBR_BASE_OFFS)
  47343. +#define PXBR_BASE_ALIGNMET (1 << PXBR_BASE_OFFS)
  47344. +
  47345. +
  47346. +/* PCI Express BAR1 (High) Register*/
  47347. +/* PCI Express BAR2 (High) Register*/
  47348. +/*PEX BAR1_REG_HIGH (PXBRH)*/
  47349. +/*PEX BAR2_REG_HIGH (PXBRH)*/
  47350. +
  47351. +#define PXBRH_BASE_OFFS 0 /* Base address. Address bits [63:32] */
  47352. +#define PXBRH_BASE_MASK (0xffffffff << PXBRH_BASE_OFFS)
  47353. +
  47354. +/* PCI Express Expansion ROM BAR Register*/
  47355. +/*PEX_EXPANSION_ROM_BASE_ADDR_REG (PXERBAR)*/
  47356. +
  47357. +#define PXERBAR_EXPROMEN BIT0 /* Expansion ROM Enable */
  47358. +
  47359. +#define PXERBAR_BASE_512K_OFFS 19 /* Expansion ROM Base Address */
  47360. +#define PXERBAR_BASE_512K_MASK (0x1fff << PXERBAR_BASE_512K_OFFS)
  47361. +
  47362. +#define PXERBAR_BASE_1MB_OFFS 20 /* Expansion ROM Base Address */
  47363. +#define PXERBAR_BASE_1MB_MASK (0xfff << PXERBAR_BASE_1MB_OFFS)
  47364. +
  47365. +#define PXERBAR_BASE_2MB_OFFS 21 /* Expansion ROM Base Address */
  47366. +#define PXERBAR_BASE_2MB_MASK (0x7ff << PXERBAR_BASE_2MB_OFFS)
  47367. +
  47368. +#define PXERBAR_BASE_4MB_OFFS 22 /* Expansion ROM Base Address */
  47369. +#define PXERBAR_BASE_4MB_MASK (0x3ff << PXERBAR_BASE_4MB_OFFS)
  47370. +
  47371. +/* PEX Bar attributes */
  47372. +typedef struct _mvPexBar
  47373. +{
  47374. + MV_ADDR_WIN addrWin; /* An address window*/
  47375. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  47376. +
  47377. +}MV_PEX_BAR;
  47378. +
  47379. +/* PEX Remap Window attributes */
  47380. +typedef struct _mvPexRemapWin
  47381. +{
  47382. + MV_ADDR_WIN addrWin; /* An address window*/
  47383. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  47384. +
  47385. +}MV_PEX_REMAP_WIN;
  47386. +
  47387. +/* PEX Remap Window attributes */
  47388. +typedef struct _mvPexDecWin
  47389. +{
  47390. + MV_TARGET target;
  47391. + MV_ADDR_WIN addrWin; /* An address window*/
  47392. + MV_U32 targetBar;
  47393. + MV_U8 attrib; /* chip select attributes */
  47394. + MV_TARGET_ID targetId; /* Target Id of this MV_TARGET */
  47395. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  47396. +
  47397. +}MV_PEX_DEC_WIN;
  47398. +
  47399. +/* Global Functions prototypes */
  47400. +/* mvPexHalInit - Initialize PEX interfaces*/
  47401. +MV_STATUS mvPexInit(MV_U32 pexIf, MV_PEX_TYPE pexType);
  47402. +
  47403. +
  47404. +/* mvPexTargetWinSet - Set PEX to peripheral target address window BAR*/
  47405. +MV_STATUS mvPexTargetWinSet(MV_U32 pexIf, MV_U32 winNum,
  47406. + MV_PEX_DEC_WIN *pAddrDecWin);
  47407. +
  47408. +/* mvPexTargetWinGet - Get PEX to peripheral target address window*/
  47409. +MV_STATUS mvPexTargetWinGet(MV_U32 pexIf, MV_U32 winNum,
  47410. + MV_PEX_DEC_WIN *pAddrDecWin);
  47411. +
  47412. +/* mvPexTargetWinEnable - Enable/disable a PEX BAR window*/
  47413. +MV_STATUS mvPexTargetWinEnable(MV_U32 pexIf,MV_U32 winNum, MV_BOOL enable);
  47414. +
  47415. +/* mvPexTargetWinRemap - Set PEX to target address window remap.*/
  47416. +MV_STATUS mvPexTargetWinRemap(MV_U32 pexIf, MV_U32 winNum,
  47417. + MV_PEX_REMAP_WIN *pAddrWin);
  47418. +
  47419. +/* mvPexTargetWinRemapEnable -enable\disable a PEX Window remap.*/
  47420. +MV_STATUS mvPexTargetWinRemapEnable(MV_U32 pexIf, MV_U32 winNum,
  47421. + MV_BOOL enable);
  47422. +
  47423. +/* mvPexBarSet - Set PEX bar address and size */
  47424. +MV_STATUS mvPexBarSet(MV_U32 pexIf, MV_U32 barNum, MV_PEX_BAR *addrWin);
  47425. +
  47426. +/* mvPexBarGet - Get PEX bar address and size */
  47427. +MV_STATUS mvPexBarGet(MV_U32 pexIf, MV_U32 barNum, MV_PEX_BAR *addrWin);
  47428. +
  47429. +/* mvPexBarEnable - enable\disable a PEX bar*/
  47430. +MV_STATUS mvPexBarEnable(MV_U32 pexIf, MV_U32 barNum, MV_BOOL enable);
  47431. +
  47432. +/* mvPexAddrDecShow - Display address decode windows attributes */
  47433. +MV_VOID mvPexAddrDecShow(MV_VOID);
  47434. +
  47435. +#endif
  47436. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c
  47437. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c 1970-01-01 01:00:00.000000000 +0100
  47438. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.c 2011-08-01 14:38:19.000000000 +0200
  47439. @@ -0,0 +1,430 @@
  47440. +/*******************************************************************************
  47441. +Copyright (C) Marvell International Ltd. and its affiliates
  47442. +
  47443. +This software file (the "File") is owned and distributed by Marvell
  47444. +International Ltd. and/or its affiliates ("Marvell") under the following
  47445. +alternative licensing terms. Once you have made an election to distribute the
  47446. +File under one of the following license alternatives, please (i) delete this
  47447. +introductory statement regarding license alternatives, (ii) delete the two
  47448. +license alternatives that you have not elected to use and (iii) preserve the
  47449. +Marvell copyright notice above.
  47450. +
  47451. +********************************************************************************
  47452. +Marvell Commercial License Option
  47453. +
  47454. +If you received this File from Marvell and you have entered into a commercial
  47455. +license agreement (a "Commercial License") with Marvell, the File is licensed
  47456. +to you under the terms of the applicable Commercial License.
  47457. +
  47458. +********************************************************************************
  47459. +Marvell GPL License Option
  47460. +
  47461. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47462. +modify this File in accordance with the terms and conditions of the General
  47463. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  47464. +available along with the File in the license.txt file or by writing to the Free
  47465. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  47466. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  47467. +
  47468. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  47469. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  47470. +DISCLAIMED. The GPL License provides additional details about this warranty
  47471. +disclaimer.
  47472. +********************************************************************************
  47473. +Marvell BSD License Option
  47474. +
  47475. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47476. +modify this File under the following licensing terms.
  47477. +Redistribution and use in source and binary forms, with or without modification,
  47478. +are permitted provided that the following conditions are met:
  47479. +
  47480. + * Redistributions of source code must retain the above copyright notice,
  47481. + this list of conditions and the following disclaimer.
  47482. +
  47483. + * Redistributions in binary form must reproduce the above copyright
  47484. + notice, this list of conditions and the following disclaimer in the
  47485. + documentation and/or other materials provided with the distribution.
  47486. +
  47487. + * Neither the name of Marvell nor the names of its contributors may be
  47488. + used to endorse or promote products derived from this software without
  47489. + specific prior written permission.
  47490. +
  47491. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  47492. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  47493. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  47494. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  47495. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  47496. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  47497. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  47498. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  47499. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  47500. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  47501. +
  47502. +*******************************************************************************/
  47503. +
  47504. +
  47505. +#include "mvTypes.h"
  47506. +#include "mvCommon.h"
  47507. +#include "mvOs.h"
  47508. +#include "ctrlEnv/mvCtrlEnvLib.h"
  47509. +#include "cpu/mvCpu.h"
  47510. +#include "ctrlEnv/sys/mvCpuIf.h"
  47511. +#include "sata/CoreDriver/mvRegs.h"
  47512. +#include "ctrlEnv/sys/mvSysSata.h"
  47513. +
  47514. +MV_TARGET sataAddrDecPrioTab[] =
  47515. +{
  47516. +#if defined(MV_INCLUDE_SDRAM_CS0)
  47517. + SDRAM_CS0,
  47518. +#endif
  47519. +#if defined(MV_INCLUDE_SDRAM_CS1)
  47520. + SDRAM_CS1,
  47521. +#endif
  47522. +#if defined(MV_INCLUDE_SDRAM_CS2)
  47523. + SDRAM_CS2,
  47524. +#endif
  47525. +#if defined(MV_INCLUDE_SDRAM_CS3)
  47526. + SDRAM_CS3,
  47527. +#endif
  47528. +#if defined(MV_INCLUDE_PEX)
  47529. + PEX0_MEM,
  47530. +#endif
  47531. + TBL_TERM
  47532. +};
  47533. +
  47534. +
  47535. +/*******************************************************************************
  47536. +* sataWinOverlapDetect - Detect SATA address windows overlapping
  47537. +*
  47538. +* DESCRIPTION:
  47539. +* An unpredicted behaviur is expected in case SATA address decode
  47540. +* windows overlapps.
  47541. +* This function detects SATA address decode windows overlapping of a
  47542. +* specified window. The function does not check the window itself for
  47543. +* overlapping. The function also skipps disabled address decode windows.
  47544. +*
  47545. +* INPUT:
  47546. +* winNum - address decode window number.
  47547. +* pAddrDecWin - An address decode window struct.
  47548. +*
  47549. +* OUTPUT:
  47550. +* None.
  47551. +*
  47552. +* RETURN:
  47553. +* MV_TRUE if the given address window overlap current address
  47554. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  47555. +* from registers.
  47556. +*
  47557. +*******************************************************************************/
  47558. +static MV_STATUS sataWinOverlapDetect(int dev, MV_U32 winNum,
  47559. + MV_ADDR_WIN *pAddrWin)
  47560. +{
  47561. + MV_U32 winNumIndex;
  47562. + MV_SATA_DEC_WIN addrDecWin;
  47563. +
  47564. + for(winNumIndex=0; winNumIndex<MV_SATA_MAX_ADDR_DECODE_WIN; winNumIndex++)
  47565. + {
  47566. + /* Do not check window itself */
  47567. + if (winNumIndex == winNum)
  47568. + {
  47569. + continue;
  47570. + }
  47571. +
  47572. + /* Get window parameters */
  47573. + if (MV_OK != mvSataWinGet(dev, winNumIndex, &addrDecWin))
  47574. + {
  47575. + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
  47576. + return MV_ERROR;
  47577. + }
  47578. +
  47579. + /* Do not check disabled windows */
  47580. + if(addrDecWin.enable == MV_FALSE)
  47581. + {
  47582. + continue;
  47583. + }
  47584. +
  47585. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  47586. + {
  47587. + return MV_TRUE;
  47588. + }
  47589. + }
  47590. + return MV_FALSE;
  47591. +}
  47592. +
  47593. +
  47594. +/*******************************************************************************
  47595. +* mvSataWinSet - Set SATA target address window
  47596. +*
  47597. +* DESCRIPTION:
  47598. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  47599. +* address window, also known as address decode window.
  47600. +* After setting this target window, the SATA will be able to access the
  47601. +* target within the address window.
  47602. +*
  47603. +* INPUT:
  47604. +* winNum - SATA target address decode window number.
  47605. +* pAddrDecWin - SATA target window data structure.
  47606. +*
  47607. +* OUTPUT:
  47608. +* None.
  47609. +*
  47610. +* RETURN:
  47611. +* MV_ERROR if address window overlapps with other address decode windows.
  47612. +* MV_BAD_PARAM if base address is invalid parameter or target is
  47613. +* unknown.
  47614. +*
  47615. +*******************************************************************************/
  47616. +MV_STATUS mvSataWinSet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin)
  47617. +{
  47618. + MV_TARGET_ATTRIB targetAttribs;
  47619. + MV_DEC_REGS decRegs;
  47620. +
  47621. + /* Parameter checking */
  47622. + if (winNum >= MV_SATA_MAX_ADDR_DECODE_WIN)
  47623. + {
  47624. + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
  47625. + return MV_BAD_PARAM;
  47626. + }
  47627. +
  47628. + /* Check if the requested window overlapps with current windows */
  47629. + if (MV_TRUE == sataWinOverlapDetect(dev, winNum, &pAddrDecWin->addrWin))
  47630. + {
  47631. + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
  47632. + return MV_ERROR;
  47633. + }
  47634. +
  47635. + /* check if address is aligned to the size */
  47636. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  47637. + {
  47638. + mvOsPrintf("mvSataWinSet:Error setting SATA window %d to "\
  47639. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  47640. + winNum,
  47641. + mvCtrlTargetNameGet(pAddrDecWin->target),
  47642. + pAddrDecWin->addrWin.baseLow,
  47643. + pAddrDecWin->addrWin.size);
  47644. + return MV_ERROR;
  47645. + }
  47646. +
  47647. + decRegs.baseReg = 0;
  47648. + decRegs.sizeReg = 0;
  47649. +
  47650. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  47651. + {
  47652. + mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
  47653. + return MV_ERROR;
  47654. + }
  47655. +
  47656. + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
  47657. +
  47658. + /* set attributes */
  47659. + decRegs.sizeReg &= ~MV_SATA_WIN_ATTR_MASK;
  47660. + decRegs.sizeReg |= (targetAttribs.attrib << MV_SATA_WIN_ATTR_OFFSET);
  47661. +
  47662. + /* set target ID */
  47663. + decRegs.sizeReg &= ~MV_SATA_WIN_TARGET_MASK;
  47664. + decRegs.sizeReg |= (targetAttribs.targetId << MV_SATA_WIN_TARGET_OFFSET);
  47665. +
  47666. + if (pAddrDecWin->enable == MV_TRUE)
  47667. + {
  47668. + decRegs.sizeReg |= MV_SATA_WIN_ENABLE_MASK;
  47669. + }
  47670. + else
  47671. + {
  47672. + decRegs.sizeReg &= ~MV_SATA_WIN_ENABLE_MASK;
  47673. + }
  47674. +
  47675. + MV_REG_WRITE( MV_SATA_WIN_CTRL_REG(dev, winNum), decRegs.sizeReg);
  47676. + MV_REG_WRITE( MV_SATA_WIN_BASE_REG(dev, winNum), decRegs.baseReg);
  47677. +
  47678. + return MV_OK;
  47679. +}
  47680. +
  47681. +/*******************************************************************************
  47682. +* mvSataWinGet - Get SATA peripheral target address window.
  47683. +*
  47684. +* DESCRIPTION:
  47685. +* Get SATA peripheral target address window.
  47686. +*
  47687. +* INPUT:
  47688. +* winNum - SATA target address decode window number.
  47689. +*
  47690. +* OUTPUT:
  47691. +* pAddrDecWin - SATA target window data structure.
  47692. +*
  47693. +* RETURN:
  47694. +* MV_ERROR if register parameters are invalid.
  47695. +*
  47696. +*******************************************************************************/
  47697. +MV_STATUS mvSataWinGet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin)
  47698. +{
  47699. + MV_DEC_REGS decRegs;
  47700. + MV_TARGET_ATTRIB targetAttrib;
  47701. +
  47702. + /* Parameter checking */
  47703. + if (winNum >= MV_SATA_MAX_ADDR_DECODE_WIN)
  47704. + {
  47705. + mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",
  47706. + __FUNCTION__, dev, winNum);
  47707. + return MV_NOT_SUPPORTED;
  47708. + }
  47709. +
  47710. + decRegs.baseReg = MV_REG_READ( MV_SATA_WIN_BASE_REG(dev, winNum) );
  47711. + decRegs.sizeReg = MV_REG_READ( MV_SATA_WIN_CTRL_REG(dev, winNum) );
  47712. +
  47713. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
  47714. + {
  47715. + mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
  47716. + return MV_ERROR;
  47717. + }
  47718. +
  47719. + /* attrib and targetId */
  47720. + targetAttrib.attrib = (decRegs.sizeReg & MV_SATA_WIN_ATTR_MASK) >>
  47721. + MV_SATA_WIN_ATTR_OFFSET;
  47722. + targetAttrib.targetId = (decRegs.sizeReg & MV_SATA_WIN_TARGET_MASK) >>
  47723. + MV_SATA_WIN_TARGET_OFFSET;
  47724. +
  47725. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  47726. +
  47727. + /* Check if window is enabled */
  47728. + if(decRegs.sizeReg & MV_SATA_WIN_ENABLE_MASK)
  47729. + {
  47730. + pAddrDecWin->enable = MV_TRUE;
  47731. + }
  47732. + else
  47733. + {
  47734. + pAddrDecWin->enable = MV_FALSE;
  47735. + }
  47736. + return MV_OK;
  47737. +}
  47738. +/*******************************************************************************
  47739. +* mvSataAddrDecShow - Print the SATA address decode map.
  47740. +*
  47741. +* DESCRIPTION:
  47742. +* This function print the SATA address decode map.
  47743. +*
  47744. +* INPUT:
  47745. +* None.
  47746. +*
  47747. +* OUTPUT:
  47748. +* None.
  47749. +*
  47750. +* RETURN:
  47751. +* None.
  47752. +*
  47753. +*******************************************************************************/
  47754. +MV_VOID mvSataAddrDecShow(MV_VOID)
  47755. +{
  47756. +
  47757. + MV_SATA_DEC_WIN win;
  47758. + int i,j;
  47759. +
  47760. +
  47761. +
  47762. + for( j = 0; j < MV_SATA_MAX_CHAN; j++ )
  47763. + {
  47764. + if (MV_FALSE == mvCtrlPwrClckGet(SATA_UNIT_ID, j))
  47765. + return;
  47766. +
  47767. + mvOsOutput( "\n" );
  47768. + mvOsOutput( "SATA %d:\n", j );
  47769. + mvOsOutput( "----\n" );
  47770. +
  47771. + for( i = 0; i < MV_SATA_MAX_ADDR_DECODE_WIN; i++ )
  47772. + {
  47773. + memset( &win, 0, sizeof(MV_SATA_DEC_WIN) );
  47774. +
  47775. + mvOsOutput( "win%d - ", i );
  47776. +
  47777. + if( mvSataWinGet(j, i, &win ) == MV_OK )
  47778. + {
  47779. + if( win.enable )
  47780. + {
  47781. + mvOsOutput( "%s base %08x, ",
  47782. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  47783. + mvOsOutput( "...." );
  47784. +
  47785. + mvSizePrint( win.addrWin.size );
  47786. +
  47787. + mvOsOutput( "\n" );
  47788. + }
  47789. + else
  47790. + mvOsOutput( "disable\n" );
  47791. + }
  47792. + }
  47793. + }
  47794. +}
  47795. +
  47796. +
  47797. +/*******************************************************************************
  47798. +* mvSataWinInit - Initialize the integrated SATA target address window.
  47799. +*
  47800. +* DESCRIPTION:
  47801. +* Initialize the SATA peripheral target address window.
  47802. +*
  47803. +* INPUT:
  47804. +*
  47805. +*
  47806. +* OUTPUT:
  47807. +*
  47808. +*
  47809. +* RETURN:
  47810. +* MV_ERROR if register parameters are invalid.
  47811. +*
  47812. +*******************************************************************************/
  47813. +MV_STATUS mvSataWinInit(MV_VOID)
  47814. +{
  47815. + int winNum;
  47816. + MV_SATA_DEC_WIN sataWin;
  47817. + MV_CPU_DEC_WIN cpuAddrDecWin;
  47818. + MV_U32 status, winPrioIndex = 0;
  47819. +
  47820. + /* Initiate Sata address decode */
  47821. +
  47822. + /* First disable all address decode windows */
  47823. + for(winNum = 0; winNum < MV_SATA_MAX_ADDR_DECODE_WIN; winNum++)
  47824. + {
  47825. + MV_U32 regVal = MV_REG_READ(MV_SATA_WIN_CTRL_REG(0, winNum));
  47826. + regVal &= ~MV_SATA_WIN_ENABLE_MASK;
  47827. + MV_REG_WRITE(MV_SATA_WIN_CTRL_REG(0, winNum), regVal);
  47828. + }
  47829. +
  47830. + winNum = 0;
  47831. + while( (sataAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
  47832. + (winNum < MV_SATA_MAX_ADDR_DECODE_WIN) )
  47833. + {
  47834. + /* first get attributes from CPU If */
  47835. + status = mvCpuIfTargetWinGet(sataAddrDecPrioTab[winPrioIndex],
  47836. + &cpuAddrDecWin);
  47837. +
  47838. + if(MV_NO_SUCH == status)
  47839. + {
  47840. + winPrioIndex++;
  47841. + continue;
  47842. + }
  47843. + if (MV_OK != status)
  47844. + {
  47845. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  47846. + return MV_ERROR;
  47847. + }
  47848. +
  47849. + if (cpuAddrDecWin.enable == MV_TRUE)
  47850. + {
  47851. + sataWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  47852. + sataWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  47853. + sataWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  47854. + sataWin.enable = MV_TRUE;
  47855. + sataWin.target = sataAddrDecPrioTab[winPrioIndex];
  47856. +
  47857. + if(MV_OK != mvSataWinSet(0/*dev*/, winNum, &sataWin))
  47858. + {
  47859. + return MV_ERROR;
  47860. + }
  47861. + winNum++;
  47862. + }
  47863. + winPrioIndex++;
  47864. + }
  47865. + return MV_OK;
  47866. +}
  47867. +
  47868. +
  47869. +
  47870. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h
  47871. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h 1970-01-01 01:00:00.000000000 +0100
  47872. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSata.h 2011-08-01 14:38:19.000000000 +0200
  47873. @@ -0,0 +1,128 @@
  47874. +
  47875. +/*******************************************************************************
  47876. +Copyright (C) Marvell International Ltd. and its affiliates
  47877. +
  47878. +This software file (the "File") is owned and distributed by Marvell
  47879. +International Ltd. and/or its affiliates ("Marvell") under the following
  47880. +alternative licensing terms. Once you have made an election to distribute the
  47881. +File under one of the following license alternatives, please (i) delete this
  47882. +introductory statement regarding license alternatives, (ii) delete the two
  47883. +license alternatives that you have not elected to use and (iii) preserve the
  47884. +Marvell copyright notice above.
  47885. +
  47886. +********************************************************************************
  47887. +Marvell Commercial License Option
  47888. +
  47889. +If you received this File from Marvell and you have entered into a commercial
  47890. +license agreement (a "Commercial License") with Marvell, the File is licensed
  47891. +to you under the terms of the applicable Commercial License.
  47892. +
  47893. +********************************************************************************
  47894. +Marvell GPL License Option
  47895. +
  47896. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47897. +modify this File in accordance with the terms and conditions of the General
  47898. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  47899. +available along with the File in the license.txt file or by writing to the Free
  47900. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  47901. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  47902. +
  47903. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  47904. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  47905. +DISCLAIMED. The GPL License provides additional details about this warranty
  47906. +disclaimer.
  47907. +********************************************************************************
  47908. +Marvell BSD License Option
  47909. +
  47910. +If you received this File from Marvell, you may opt to use, redistribute and/or
  47911. +modify this File under the following licensing terms.
  47912. +Redistribution and use in source and binary forms, with or without modification,
  47913. +are permitted provided that the following conditions are met:
  47914. +
  47915. + * Redistributions of source code must retain the above copyright notice,
  47916. + this list of conditions and the following disclaimer.
  47917. +
  47918. + * Redistributions in binary form must reproduce the above copyright
  47919. + notice, this list of conditions and the following disclaimer in the
  47920. + documentation and/or other materials provided with the distribution.
  47921. +
  47922. + * Neither the name of Marvell nor the names of its contributors may be
  47923. + used to endorse or promote products derived from this software without
  47924. + specific prior written permission.
  47925. +
  47926. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  47927. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  47928. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  47929. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  47930. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  47931. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  47932. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  47933. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  47934. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  47935. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  47936. +
  47937. +*******************************************************************************/
  47938. +#ifndef __INCMVSysSataAddrDech
  47939. +#define __INCMVSysSataAddrDech
  47940. +
  47941. +#include "mvCommon.h"
  47942. +#include "ctrlEnv/mvCtrlEnvLib.h"
  47943. +#include "ctrlEnv/sys/mvCpuIf.h"
  47944. +
  47945. +
  47946. +#ifdef __cplusplus
  47947. +extern "C" {
  47948. +#endif
  47949. +
  47950. +typedef struct _mvSataDecWin
  47951. +{
  47952. + MV_TARGET target;
  47953. + MV_ADDR_WIN addrWin; /* An address window*/
  47954. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  47955. +
  47956. +} MV_SATA_DEC_WIN;
  47957. +
  47958. +
  47959. +#define MV_SATA_MAX_ADDR_DECODE_WIN 4
  47960. +
  47961. +#define MV_SATA_WIN_CTRL_REG(dev, win) (SATA_REG_BASE + 0x30 + ((win)<<4))
  47962. +#define MV_SATA_WIN_BASE_REG(dev, win) (SATA_REG_BASE + 0x34 + ((win)<<4))
  47963. +
  47964. +/* BITs in Bridge Interrupt Cause and Mask registers */
  47965. +#define MV_SATA_ADDR_DECODE_ERROR_BIT 0
  47966. +#define MV_SATA_ADDR_DECODE_ERROR_MASK (1<<MV_SATA_ADDR_DECODE_ERROR_BIT)
  47967. +
  47968. +/* BITs in Windows 0-3 Control and Base Registers */
  47969. +#define MV_SATA_WIN_ENABLE_BIT 0
  47970. +#define MV_SATA_WIN_ENABLE_MASK (1<<MV_SATA_WIN_ENABLE_BIT)
  47971. +
  47972. +#define MV_SATA_WIN_TARGET_OFFSET 4
  47973. +#define MV_SATA_WIN_TARGET_MASK (0xF<<MV_SATA_WIN_TARGET_OFFSET)
  47974. +
  47975. +#define MV_SATA_WIN_ATTR_OFFSET 8
  47976. +#define MV_SATA_WIN_ATTR_MASK (0xFF<<MV_SATA_WIN_ATTR_OFFSET)
  47977. +
  47978. +#define MV_SATA_WIN_SIZE_OFFSET 16
  47979. +#define MV_SATA_WIN_SIZE_MASK (0xFFFF<<MV_SATA_WIN_SIZE_OFFSET)
  47980. +
  47981. +#define MV_SATA_WIN_BASE_OFFSET 16
  47982. +#define MV_SATA_WIN_BASE_MASK (0xFFFF<<MV_SATA_WIN_BASE_OFFSET)
  47983. +
  47984. +MV_STATUS mvSataWinGet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin);
  47985. +MV_STATUS mvSataWinSet(int dev, MV_U32 winNum, MV_SATA_DEC_WIN *pAddrDecWin);
  47986. +MV_STATUS mvSataWinByTargetGet(MV_TARGET target, MV_SATA_DEC_WIN *pAddrDecWin);
  47987. +MV_STATUS mvSataWinInit(MV_VOID);
  47988. +MV_VOID mvSataAddrDecShow(MV_VOID);
  47989. +
  47990. +
  47991. +#ifdef __cplusplus
  47992. +}
  47993. +#endif
  47994. +
  47995. +
  47996. +#endif
  47997. +
  47998. +
  47999. +
  48000. +
  48001. +
  48002. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c
  48003. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c 1970-01-01 01:00:00.000000000 +0100
  48004. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.c 2011-08-01 14:38:19.000000000 +0200
  48005. @@ -0,0 +1,427 @@
  48006. +/*******************************************************************************
  48007. +Copyright (C) Marvell International Ltd. and its affiliates
  48008. +
  48009. +This software file (the "File") is owned and distributed by Marvell
  48010. +International Ltd. and/or its affiliates ("Marvell") under the following
  48011. +alternative licensing terms. Once you have made an election to distribute the
  48012. +File under one of the following license alternatives, please (i) delete this
  48013. +introductory statement regarding license alternatives, (ii) delete the two
  48014. +license alternatives that you have not elected to use and (iii) preserve the
  48015. +Marvell copyright notice above.
  48016. +
  48017. +********************************************************************************
  48018. +Marvell Commercial License Option
  48019. +
  48020. +If you received this File from Marvell and you have entered into a commercial
  48021. +license agreement (a "Commercial License") with Marvell, the File is licensed
  48022. +to you under the terms of the applicable Commercial License.
  48023. +
  48024. +********************************************************************************
  48025. +Marvell GPL License Option
  48026. +
  48027. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48028. +modify this File in accordance with the terms and conditions of the General
  48029. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  48030. +available along with the File in the license.txt file or by writing to the Free
  48031. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  48032. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  48033. +
  48034. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  48035. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  48036. +DISCLAIMED. The GPL License provides additional details about this warranty
  48037. +disclaimer.
  48038. +********************************************************************************
  48039. +Marvell BSD License Option
  48040. +
  48041. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48042. +modify this File under the following licensing terms.
  48043. +Redistribution and use in source and binary forms, with or without modification,
  48044. +are permitted provided that the following conditions are met:
  48045. +
  48046. + * Redistributions of source code must retain the above copyright notice,
  48047. + this list of conditions and the following disclaimer.
  48048. +
  48049. + * Redistributions in binary form must reproduce the above copyright
  48050. + notice, this list of conditions and the following disclaimer in the
  48051. + documentation and/or other materials provided with the distribution.
  48052. +
  48053. + * Neither the name of Marvell nor the names of its contributors may be
  48054. + used to endorse or promote products derived from this software without
  48055. + specific prior written permission.
  48056. +
  48057. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  48058. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  48059. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  48060. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  48061. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  48062. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  48063. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  48064. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  48065. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  48066. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  48067. +
  48068. +*******************************************************************************/
  48069. +
  48070. +
  48071. +#include "mvTypes.h"
  48072. +#include "mvCommon.h"
  48073. +#include "mvOs.h"
  48074. +#include "ctrlEnv/mvCtrlEnvLib.h"
  48075. +#include "cpu/mvCpu.h"
  48076. +#include "ctrlEnv/sys/mvCpuIf.h"
  48077. +#include "mvRegs.h"
  48078. +#include "ctrlEnv/sys/mvSysSdmmc.h"
  48079. +
  48080. +MV_TARGET sdmmcAddrDecPrioTab[] =
  48081. +{
  48082. +#if defined(MV_INCLUDE_SDRAM_CS0)
  48083. + SDRAM_CS0,
  48084. +#endif
  48085. +#if defined(MV_INCLUDE_SDRAM_CS1)
  48086. + SDRAM_CS1,
  48087. +#endif
  48088. +#if defined(MV_INCLUDE_SDRAM_CS2)
  48089. + SDRAM_CS2,
  48090. +#endif
  48091. +#if defined(MV_INCLUDE_SDRAM_CS3)
  48092. + SDRAM_CS3,
  48093. +#endif
  48094. +#if defined(MV_INCLUDE_PEX)
  48095. + PEX0_MEM,
  48096. +#endif
  48097. + TBL_TERM
  48098. +};
  48099. +
  48100. +
  48101. +/*******************************************************************************
  48102. +* sdmmcWinOverlapDetect - Detect SDMMC address windows overlapping
  48103. +*
  48104. +* DESCRIPTION:
  48105. +* An unpredicted behaviur is expected in case SDMMC address decode
  48106. +* windows overlapps.
  48107. +* This function detects SDMMC address decode windows overlapping of a
  48108. +* specified window. The function does not check the window itself for
  48109. +* overlapping. The function also skipps disabled address decode windows.
  48110. +*
  48111. +* INPUT:
  48112. +* winNum - address decode window number.
  48113. +* pAddrDecWin - An address decode window struct.
  48114. +*
  48115. +* OUTPUT:
  48116. +* None.
  48117. +*
  48118. +* RETURN:
  48119. +* MV_TRUE if the given address window overlap current address
  48120. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  48121. +* from registers.
  48122. +*
  48123. +*******************************************************************************/
  48124. +static MV_STATUS sdmmcWinOverlapDetect(int dev, MV_U32 winNum,
  48125. + MV_ADDR_WIN *pAddrWin)
  48126. +{
  48127. + MV_U32 winNumIndex;
  48128. + MV_SDMMC_DEC_WIN addrDecWin;
  48129. +
  48130. + for(winNumIndex=0; winNumIndex<MV_SDMMC_MAX_ADDR_DECODE_WIN; winNumIndex++)
  48131. + {
  48132. + /* Do not check window itself */
  48133. + if (winNumIndex == winNum)
  48134. + {
  48135. + continue;
  48136. + }
  48137. +
  48138. + /* Get window parameters */
  48139. + if (MV_OK != mvSdmmcWinGet(dev, winNumIndex, &addrDecWin))
  48140. + {
  48141. + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
  48142. + return MV_ERROR;
  48143. + }
  48144. +
  48145. + /* Do not check disabled windows */
  48146. + if(addrDecWin.enable == MV_FALSE)
  48147. + {
  48148. + continue;
  48149. + }
  48150. +
  48151. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  48152. + {
  48153. + return MV_TRUE;
  48154. + }
  48155. + }
  48156. + return MV_FALSE;
  48157. +}
  48158. +
  48159. +
  48160. +/*******************************************************************************
  48161. +* mvSdmmcWinSet - Set SDMMC target address window
  48162. +*
  48163. +* DESCRIPTION:
  48164. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  48165. +* address window, also known as address decode window.
  48166. +* After setting this target window, the SDMMC will be able to access the
  48167. +* target within the address window.
  48168. +*
  48169. +* INPUT:
  48170. +* winNum - SDMMC target address decode window number.
  48171. +* pAddrDecWin - SDMMC target window data structure.
  48172. +*
  48173. +* OUTPUT:
  48174. +* None.
  48175. +*
  48176. +* RETURN:
  48177. +* MV_ERROR if address window overlapps with other address decode windows.
  48178. +* MV_BAD_PARAM if base address is invalid parameter or target is
  48179. +* unknown.
  48180. +*
  48181. +*******************************************************************************/
  48182. +MV_STATUS mvSdmmcWinSet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin)
  48183. +{
  48184. + MV_TARGET_ATTRIB targetAttribs;
  48185. + MV_DEC_REGS decRegs;
  48186. +
  48187. + /* Parameter checking */
  48188. + if (winNum >= MV_SDMMC_MAX_ADDR_DECODE_WIN)
  48189. + {
  48190. + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
  48191. + return MV_BAD_PARAM;
  48192. + }
  48193. +
  48194. + /* Check if the requested window overlapps with current windows */
  48195. + if (MV_TRUE == sdmmcWinOverlapDetect(dev, winNum, &pAddrDecWin->addrWin))
  48196. + {
  48197. + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
  48198. + return MV_ERROR;
  48199. + }
  48200. +
  48201. + /* check if address is aligned to the size */
  48202. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  48203. + {
  48204. + mvOsPrintf("mvSdmmcWinSet:Error setting SDMMC window %d to "\
  48205. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  48206. + winNum,
  48207. + mvCtrlTargetNameGet(pAddrDecWin->target),
  48208. + pAddrDecWin->addrWin.baseLow,
  48209. + pAddrDecWin->addrWin.size);
  48210. + return MV_ERROR;
  48211. + }
  48212. +
  48213. + decRegs.baseReg = 0;
  48214. + decRegs.sizeReg = 0;
  48215. +
  48216. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  48217. + {
  48218. + mvOsPrintf("%s: mvCtrlAddrDecToReg Failed\n", __FUNCTION__);
  48219. + return MV_ERROR;
  48220. + }
  48221. +
  48222. + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
  48223. +
  48224. + /* set attributes */
  48225. + decRegs.sizeReg &= ~MV_SDMMC_WIN_ATTR_MASK;
  48226. + decRegs.sizeReg |= (targetAttribs.attrib << MV_SDMMC_WIN_ATTR_OFFSET);
  48227. +
  48228. + /* set target ID */
  48229. + decRegs.sizeReg &= ~MV_SDMMC_WIN_TARGET_MASK;
  48230. + decRegs.sizeReg |= (targetAttribs.targetId << MV_SDMMC_WIN_TARGET_OFFSET);
  48231. +
  48232. + if (pAddrDecWin->enable == MV_TRUE)
  48233. + {
  48234. + decRegs.sizeReg |= MV_SDMMC_WIN_ENABLE_MASK;
  48235. + }
  48236. + else
  48237. + {
  48238. + decRegs.sizeReg &= ~MV_SDMMC_WIN_ENABLE_MASK;
  48239. + }
  48240. +
  48241. + MV_REG_WRITE( MV_SDMMC_WIN_CTRL_REG(dev, winNum), decRegs.sizeReg);
  48242. + MV_REG_WRITE( MV_SDMMC_WIN_BASE_REG(dev, winNum), decRegs.baseReg);
  48243. +
  48244. + return MV_OK;
  48245. +}
  48246. +
  48247. +/*******************************************************************************
  48248. +* mvSdmmcWinGet - Get SDMMC peripheral target address window.
  48249. +*
  48250. +* DESCRIPTION:
  48251. +* Get SDMMC peripheral target address window.
  48252. +*
  48253. +* INPUT:
  48254. +* winNum - SDMMC target address decode window number.
  48255. +*d
  48256. +* OUTPUT:
  48257. +* pAddrDecWin - SDMMC target window data structure.
  48258. +*
  48259. +* RETURN:
  48260. +* MV_ERROR if register parameters are invalid.
  48261. +*
  48262. +*******************************************************************************/
  48263. +MV_STATUS mvSdmmcWinGet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin)
  48264. +{
  48265. + MV_DEC_REGS decRegs;
  48266. + MV_TARGET_ATTRIB targetAttrib;
  48267. +
  48268. + /* Parameter checking */
  48269. + if (winNum >= MV_SDMMC_MAX_ADDR_DECODE_WIN)
  48270. + {
  48271. + mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",
  48272. + __FUNCTION__, dev, winNum);
  48273. + return MV_NOT_SUPPORTED;
  48274. + }
  48275. +
  48276. + decRegs.baseReg = MV_REG_READ( MV_SDMMC_WIN_BASE_REG(dev, winNum) );
  48277. + decRegs.sizeReg = MV_REG_READ( MV_SDMMC_WIN_CTRL_REG(dev, winNum) );
  48278. +
  48279. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs, &pAddrDecWin->addrWin) )
  48280. + {
  48281. + mvOsPrintf("%s: mvCtrlRegToAddrDec Failed\n", __FUNCTION__);
  48282. + return MV_ERROR;
  48283. + }
  48284. +
  48285. + /* attrib and targetId */
  48286. + targetAttrib.attrib = (decRegs.sizeReg & MV_SDMMC_WIN_ATTR_MASK) >>
  48287. + MV_SDMMC_WIN_ATTR_OFFSET;
  48288. + targetAttrib.targetId = (decRegs.sizeReg & MV_SDMMC_WIN_TARGET_MASK) >>
  48289. + MV_SDMMC_WIN_TARGET_OFFSET;
  48290. +
  48291. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  48292. +
  48293. + /* Check if window is enabled */
  48294. + if(decRegs.sizeReg & MV_SDMMC_WIN_ENABLE_MASK)
  48295. + {
  48296. + pAddrDecWin->enable = MV_TRUE;
  48297. + }
  48298. + else
  48299. + {
  48300. + pAddrDecWin->enable = MV_FALSE;
  48301. + }
  48302. + return MV_OK;
  48303. +}
  48304. +/*******************************************************************************
  48305. +* mvSdmmcAddrDecShow - Print the SDMMC address decode map.
  48306. +*
  48307. +* DESCRIPTION:
  48308. +* This function print the SDMMC address decode map.
  48309. +*
  48310. +* INPUT:
  48311. +* None.
  48312. +*
  48313. +* OUTPUT:
  48314. +* None.
  48315. +*
  48316. +* RETURN:
  48317. +* None.
  48318. +*
  48319. +*******************************************************************************/
  48320. +MV_VOID mvSdmmcAddrDecShow(MV_VOID)
  48321. +{
  48322. +
  48323. + MV_SDMMC_DEC_WIN win;
  48324. + int i,j=0;
  48325. +
  48326. +
  48327. +
  48328. + if (MV_FALSE == mvCtrlPwrClckGet(SDIO_UNIT_ID, 0))
  48329. + return;
  48330. +
  48331. + mvOsOutput( "\n" );
  48332. + mvOsOutput( "SDMMC %d:\n", j );
  48333. + mvOsOutput( "----\n" );
  48334. +
  48335. + for( i = 0; i < MV_SDMMC_MAX_ADDR_DECODE_WIN; i++ )
  48336. + {
  48337. + memset( &win, 0, sizeof(MV_SDMMC_DEC_WIN) );
  48338. +
  48339. + mvOsOutput( "win%d - ", i );
  48340. +
  48341. + if( mvSdmmcWinGet(j, i, &win ) == MV_OK )
  48342. + {
  48343. + if( win.enable )
  48344. + {
  48345. + mvOsOutput( "%s base %08x, ",
  48346. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  48347. + mvOsOutput( "...." );
  48348. +
  48349. + mvSizePrint( win.addrWin.size );
  48350. +
  48351. + mvOsOutput( "\n" );
  48352. + }
  48353. + else
  48354. + mvOsOutput( "disable\n" );
  48355. + }
  48356. + }
  48357. +}
  48358. +
  48359. +
  48360. +/*******************************************************************************
  48361. +* mvSdmmcWinInit - Initialize the integrated SDMMC target address window.
  48362. +*
  48363. +* DESCRIPTION:
  48364. +* Initialize the SDMMC peripheral target address window.
  48365. +*
  48366. +* INPUT:
  48367. +*
  48368. +*
  48369. +* OUTPUT:
  48370. +*
  48371. +*
  48372. +* RETURN:
  48373. +* MV_ERROR if register parameters are invalid.
  48374. +*
  48375. +*******************************************************************************/
  48376. +MV_STATUS mvSdmmcWinInit(MV_VOID)
  48377. +{
  48378. + int winNum;
  48379. + MV_SDMMC_DEC_WIN sdmmcWin;
  48380. + MV_CPU_DEC_WIN cpuAddrDecWin;
  48381. + MV_U32 status, winPrioIndex = 0;
  48382. +
  48383. + /* Initiate Sdmmc address decode */
  48384. +
  48385. + /* First disable all address decode windows */
  48386. + for(winNum = 0; winNum < MV_SDMMC_MAX_ADDR_DECODE_WIN; winNum++)
  48387. + {
  48388. + MV_U32 regVal = MV_REG_READ(MV_SDMMC_WIN_CTRL_REG(0, winNum));
  48389. + regVal &= ~MV_SDMMC_WIN_ENABLE_MASK;
  48390. + MV_REG_WRITE(MV_SDMMC_WIN_CTRL_REG(0, winNum), regVal);
  48391. + }
  48392. +
  48393. + winNum = 0;
  48394. + while( (sdmmcAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
  48395. + (winNum < MV_SDMMC_MAX_ADDR_DECODE_WIN) )
  48396. + {
  48397. + /* first get attributes from CPU If */
  48398. + status = mvCpuIfTargetWinGet(sdmmcAddrDecPrioTab[winPrioIndex],
  48399. + &cpuAddrDecWin);
  48400. +
  48401. + if(MV_NO_SUCH == status)
  48402. + {
  48403. + winPrioIndex++;
  48404. + continue;
  48405. + }
  48406. + if (MV_OK != status)
  48407. + {
  48408. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  48409. + return MV_ERROR;
  48410. + }
  48411. +
  48412. + if (cpuAddrDecWin.enable == MV_TRUE)
  48413. + {
  48414. + sdmmcWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  48415. + sdmmcWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  48416. + sdmmcWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  48417. + sdmmcWin.enable = MV_TRUE;
  48418. + sdmmcWin.target = sdmmcAddrDecPrioTab[winPrioIndex];
  48419. +
  48420. + if(MV_OK != mvSdmmcWinSet(0/*dev*/, winNum, &sdmmcWin))
  48421. + {
  48422. + return MV_ERROR;
  48423. + }
  48424. + winNum++;
  48425. + }
  48426. + winPrioIndex++;
  48427. + }
  48428. + return MV_OK;
  48429. +}
  48430. +
  48431. +
  48432. +
  48433. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h
  48434. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h 1970-01-01 01:00:00.000000000 +0100
  48435. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysSdmmc.h 2011-08-01 14:38:19.000000000 +0200
  48436. @@ -0,0 +1,125 @@
  48437. +
  48438. +/*******************************************************************************
  48439. +Copyright (C) Marvell International Ltd. and its affiliates
  48440. +
  48441. +This software file (the "File") is owned and distributed by Marvell
  48442. +International Ltd. and/or its affiliates ("Marvell") under the following
  48443. +alternative licensing terms. Once you have made an election to distribute the
  48444. +File under one of the following license alternatives, please (i) delete this
  48445. +introductory statement regarding license alternatives, (ii) delete the two
  48446. +license alternatives that you have not elected to use and (iii) preserve the
  48447. +Marvell copyright notice above.
  48448. +
  48449. +********************************************************************************
  48450. +Marvell Commercial License Option
  48451. +
  48452. +If you received this File from Marvell and you have entered into a commercial
  48453. +license agreement (a "Commercial License") with Marvell, the File is licensed
  48454. +to you under the terms of the applicable Commercial License.
  48455. +
  48456. +********************************************************************************
  48457. +Marvell GPL License Option
  48458. +
  48459. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48460. +modify this File in accordance with the terms and conditions of the General
  48461. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  48462. +available along with the File in the license.txt file or by writing to the Free
  48463. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  48464. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  48465. +
  48466. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  48467. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  48468. +DISCLAIMED. The GPL License provides additional details about this warranty
  48469. +disclaimer.
  48470. +********************************************************************************
  48471. +Marvell BSD License Option
  48472. +
  48473. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48474. +modify this File under the following licensing terms.
  48475. +Redistribution and use in source and binary forms, with or without modification,
  48476. +are permitted provided that the following conditions are met:
  48477. +
  48478. + * Redistributions of source code must retain the above copyright notice,
  48479. + this list of conditions and the following disclaimer.
  48480. +
  48481. + * Redistributions in binary form must reproduce the above copyright
  48482. + notice, this list of conditions and the following disclaimer in the
  48483. + documentation and/or other materials provided with the distribution.
  48484. +
  48485. + * Neither the name of Marvell nor the names of its contributors may be
  48486. + used to endorse or promote products derived from this software without
  48487. + specific prior written permission.
  48488. +
  48489. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  48490. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  48491. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  48492. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  48493. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  48494. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  48495. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  48496. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  48497. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  48498. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  48499. +
  48500. +*******************************************************************************/
  48501. +#ifndef __INCMVSysSdmmcAddrDech
  48502. +#define __INCMVSysSdmmcAddrDech
  48503. +
  48504. +#include "mvCommon.h"
  48505. +#include "ctrlEnv/mvCtrlEnvLib.h"
  48506. +#include "ctrlEnv/sys/mvCpuIf.h"
  48507. +
  48508. +
  48509. +#ifdef __cplusplus
  48510. +extern "C" {
  48511. +#endif
  48512. +
  48513. +typedef struct _mvSdmmcDecWin
  48514. +{
  48515. + MV_TARGET target;
  48516. + MV_ADDR_WIN addrWin; /* An address window*/
  48517. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  48518. +
  48519. +} MV_SDMMC_DEC_WIN;
  48520. +
  48521. +
  48522. +#define MV_SDMMC_MAX_ADDR_DECODE_WIN 4
  48523. +
  48524. +#define MV_SDMMC_WIN_CTRL_REG(dev, win) (MV_SDIO_REG_BASE + 0x108 + ((win)<<3))
  48525. +#define MV_SDMMC_WIN_BASE_REG(dev, win) (MV_SDIO_REG_BASE + 0x10c + ((win)<<3))
  48526. +
  48527. +
  48528. +/* BITs in Windows 0-3 Control and Base Registers */
  48529. +#define MV_SDMMC_WIN_ENABLE_BIT 0
  48530. +#define MV_SDMMC_WIN_ENABLE_MASK (1<<MV_SDMMC_WIN_ENABLE_BIT)
  48531. +
  48532. +#define MV_SDMMC_WIN_TARGET_OFFSET 4
  48533. +#define MV_SDMMC_WIN_TARGET_MASK (0xF<<MV_SDMMC_WIN_TARGET_OFFSET)
  48534. +
  48535. +#define MV_SDMMC_WIN_ATTR_OFFSET 8
  48536. +#define MV_SDMMC_WIN_ATTR_MASK (0xFF<<MV_SDMMC_WIN_ATTR_OFFSET)
  48537. +
  48538. +#define MV_SDMMC_WIN_SIZE_OFFSET 16
  48539. +#define MV_SDMMC_WIN_SIZE_MASK (0xFFFF<<MV_SDMMC_WIN_SIZE_OFFSET)
  48540. +
  48541. +#define MV_SDMMC_WIN_BASE_OFFSET 16
  48542. +#define MV_SDMMC_WIN_BASE_MASK (0xFFFF<<MV_SDMMC_WIN_BASE_OFFSET)
  48543. +
  48544. +MV_STATUS mvSdmmcWinGet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin);
  48545. +MV_STATUS mvSdmmcWinSet(int dev, MV_U32 winNum, MV_SDMMC_DEC_WIN *pAddrDecWin);
  48546. +MV_STATUS mvSdmmcWinByTargetGet(MV_TARGET target, MV_SDMMC_DEC_WIN *pAddrDecWin);
  48547. +MV_STATUS mvSdmmcWinInit(MV_VOID);
  48548. +MV_VOID mvSdmmcAddrDecShow(MV_VOID);
  48549. +
  48550. +
  48551. +#ifdef __cplusplus
  48552. +}
  48553. +#endif
  48554. +
  48555. +
  48556. +#endif
  48557. +
  48558. +
  48559. +
  48560. +
  48561. +
  48562. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c
  48563. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c 1970-01-01 01:00:00.000000000 +0100
  48564. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.c 2011-08-01 14:38:19.000000000 +0200
  48565. @@ -0,0 +1,462 @@
  48566. +/*******************************************************************************
  48567. +Copyright (C) Marvell International Ltd. and its affiliates
  48568. +
  48569. +This software file (the "File") is owned and distributed by Marvell
  48570. +International Ltd. and/or its affiliates ("Marvell") under the following
  48571. +alternative licensing terms. Once you have made an election to distribute the
  48572. +File under one of the following license alternatives, please (i) delete this
  48573. +introductory statement regarding license alternatives, (ii) delete the two
  48574. +license alternatives that you have not elected to use and (iii) preserve the
  48575. +Marvell copyright notice above.
  48576. +
  48577. +********************************************************************************
  48578. +Marvell Commercial License Option
  48579. +
  48580. +If you received this File from Marvell and you have entered into a commercial
  48581. +license agreement (a "Commercial License") with Marvell, the File is licensed
  48582. +to you under the terms of the applicable Commercial License.
  48583. +
  48584. +********************************************************************************
  48585. +Marvell GPL License Option
  48586. +
  48587. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48588. +modify this File in accordance with the terms and conditions of the General
  48589. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  48590. +available along with the File in the license.txt file or by writing to the Free
  48591. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  48592. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  48593. +
  48594. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  48595. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  48596. +DISCLAIMED. The GPL License provides additional details about this warranty
  48597. +disclaimer.
  48598. +********************************************************************************
  48599. +Marvell BSD License Option
  48600. +
  48601. +If you received this File from Marvell, you may opt to use, redistribute and/or
  48602. +modify this File under the following licensing terms.
  48603. +Redistribution and use in source and binary forms, with or without modification,
  48604. +are permitted provided that the following conditions are met:
  48605. +
  48606. + * Redistributions of source code must retain the above copyright notice,
  48607. + this list of conditions and the following disclaimer.
  48608. +
  48609. + * Redistributions in binary form must reproduce the above copyright
  48610. + notice, this list of conditions and the following disclaimer in the
  48611. + documentation and/or other materials provided with the distribution.
  48612. +
  48613. + * Neither the name of Marvell nor the names of its contributors may be
  48614. + used to endorse or promote products derived from this software without
  48615. + specific prior written permission.
  48616. +
  48617. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  48618. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  48619. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  48620. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  48621. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  48622. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  48623. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  48624. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  48625. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  48626. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  48627. +
  48628. +*******************************************************************************/
  48629. +
  48630. +#include "mvSysTdm.h"
  48631. +
  48632. +
  48633. +/* defines */
  48634. +#ifdef MV_DEBUG
  48635. + #define DB(x) x
  48636. +#else
  48637. + #define DB(x)
  48638. +#endif
  48639. +
  48640. +static MV_TARGET tdmAddrDecPrioTap[] =
  48641. +{
  48642. + PEX0_MEM,
  48643. + SDRAM_CS0,
  48644. + SDRAM_CS1,
  48645. + SDRAM_CS2,
  48646. + SDRAM_CS3,
  48647. + DEVICE_CS0,
  48648. + DEVICE_CS1,
  48649. + DEVICE_CS2,
  48650. + DEV_BOOCS,
  48651. + PEX0_IO,
  48652. + TBL_TERM
  48653. +};
  48654. +
  48655. +static MV_STATUS tdmWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
  48656. +
  48657. +/*******************************************************************************
  48658. +* mvTdmWinInit - Initialize TDM address decode windows
  48659. +*
  48660. +* DESCRIPTION:
  48661. +* This function initialize TDM window decode unit. It set the
  48662. +* default address decode
  48663. +* windows of the unit.
  48664. +*
  48665. +* INPUT:
  48666. +* None.
  48667. +*
  48668. +* OUTPUT:
  48669. +* None.
  48670. +*
  48671. +* RETURN:
  48672. +* MV_ERROR if setting fail.
  48673. +*******************************************************************************/
  48674. +
  48675. +MV_STATUS mvTdmWinInit(void)
  48676. +{
  48677. + MV_U32 winNum;
  48678. + MV_U32 winPrioIndex = 0;
  48679. + MV_CPU_DEC_WIN cpuAddrDecWin;
  48680. + MV_TDM_DEC_WIN tdmWin;
  48681. + MV_STATUS status;
  48682. +
  48683. + /*Disable all windows*/
  48684. + for (winNum = 0; winNum < TDM_MBUS_MAX_WIN; winNum++)
  48685. + {
  48686. + mvTdmWinEnable(winNum, MV_FALSE);
  48687. + }
  48688. +
  48689. + for (winNum = 0; ((tdmAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
  48690. + (winNum < TDM_MBUS_MAX_WIN)); )
  48691. + {
  48692. + status = mvCpuIfTargetWinGet(tdmAddrDecPrioTap[winPrioIndex],
  48693. + &cpuAddrDecWin);
  48694. + if (MV_NO_SUCH == status)
  48695. + {
  48696. + winPrioIndex++;
  48697. + continue;
  48698. + }
  48699. + if (MV_OK != status)
  48700. + {
  48701. + mvOsPrintf("mvTdmInit: ERR. mvCpuIfTargetWinGet failed\n");
  48702. + return MV_ERROR;
  48703. + }
  48704. +
  48705. + if (cpuAddrDecWin.enable == MV_TRUE)
  48706. + {
  48707. + tdmWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  48708. + tdmWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  48709. + tdmWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  48710. + tdmWin.enable = MV_TRUE;
  48711. + tdmWin.target = tdmAddrDecPrioTap[winPrioIndex];
  48712. + if (MV_OK != mvTdmWinSet(winNum, &tdmWin))
  48713. + {
  48714. + return MV_ERROR;
  48715. + }
  48716. + winNum++;
  48717. + }
  48718. + winPrioIndex++;
  48719. + }
  48720. + return MV_OK;
  48721. +}
  48722. +
  48723. +/*******************************************************************************
  48724. +* mvTdmWinSet - Set TDM target address window
  48725. +*
  48726. +* DESCRIPTION:
  48727. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  48728. +* address window, also known as address decode window.
  48729. +* After setting this target window, the TDM will be able to access the
  48730. +* target within the address window.
  48731. +*
  48732. +* INPUT:
  48733. +* winNum - TDM to target address decode window number.
  48734. +* pAddrDecWin - TDM target window data structure.
  48735. +*
  48736. +* OUTPUT:
  48737. +* None.
  48738. +*
  48739. +* RETURN:
  48740. +* MV_ERROR if address window overlapps with other address decode windows.
  48741. +* MV_BAD_PARAM if base address is invalid parameter or target is
  48742. +* unknown.
  48743. +*
  48744. +*******************************************************************************/
  48745. +
  48746. +MV_STATUS mvTdmWinSet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)
  48747. +{
  48748. + MV_TARGET_ATTRIB targetAttribs;
  48749. + MV_DEC_REGS decRegs;
  48750. + MV_U32 ctrlReg = 0;
  48751. +
  48752. + /* Parameter checking */
  48753. + if (winNum >= TDM_MBUS_MAX_WIN)
  48754. + {
  48755. + mvOsPrintf("mvTdmWinSet: ERR. Invalid win num %d\n",winNum);
  48756. + return MV_BAD_PARAM;
  48757. + }
  48758. +
  48759. + /* Check if the requested window overlapps with current windows */
  48760. + if (MV_TRUE == tdmWinOverlapDetect(winNum, &pAddrDecWin->addrWin))
  48761. + {
  48762. + mvOsPrintf("mvTdmWinSet: ERR. Window %d overlap\n", winNum);
  48763. + return MV_ERROR;
  48764. + }
  48765. +
  48766. + /* check if address is aligned to the size */
  48767. + if (MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  48768. + {
  48769. + mvOsPrintf("mvTdmWinSet: Error setting TDM window %d to "\
  48770. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  48771. + winNum,
  48772. + mvCtrlTargetNameGet(pAddrDecWin->target),
  48773. + pAddrDecWin->addrWin.baseLow,
  48774. + pAddrDecWin->addrWin.size);
  48775. + return MV_ERROR;
  48776. + }
  48777. +
  48778. + decRegs.baseReg = MV_REG_READ(TDM_WIN_BASE_REG(winNum));
  48779. + decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >> TDM_WIN_SIZE_OFFS;
  48780. +
  48781. + if (MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  48782. + {
  48783. + mvOsPrintf("mvTdmWinSet: mvCtrlAddrDecToReg Failed\n");
  48784. + return MV_ERROR;
  48785. + }
  48786. +
  48787. + mvCtrlAttribGet(pAddrDecWin->target, &targetAttribs);
  48788. +
  48789. + /* for the safe side we disable the window before writing the new
  48790. + values */
  48791. + mvTdmWinEnable(winNum, MV_FALSE);
  48792. +
  48793. + ctrlReg |= (targetAttribs.attrib << TDM_WIN_ATTRIB_OFFS);
  48794. + ctrlReg |= (targetAttribs.targetId << TDM_WIN_TARGET_OFFS);
  48795. + ctrlReg |= (decRegs.sizeReg & TDM_WIN_SIZE_MASK);
  48796. +
  48797. + /* Write to address base and control registers */
  48798. + MV_REG_WRITE(TDM_WIN_BASE_REG(winNum), decRegs.baseReg);
  48799. + MV_REG_WRITE(TDM_WIN_CTRL_REG(winNum), ctrlReg);
  48800. + /* Enable address decode target window */
  48801. + if (pAddrDecWin->enable == MV_TRUE)
  48802. + {
  48803. + mvTdmWinEnable(winNum, MV_TRUE);
  48804. + }
  48805. + return MV_OK;
  48806. +}
  48807. +
  48808. +/*******************************************************************************
  48809. +* mvTdmWinGet - Get peripheral target address window.
  48810. +*
  48811. +* DESCRIPTION:
  48812. +* Get TDM peripheral target address window.
  48813. +*
  48814. +* INPUT:
  48815. +* winNum - TDM to target address decode window number.
  48816. +*
  48817. +* OUTPUT:
  48818. +* pAddrDecWin - TDM target window data structure.
  48819. +*
  48820. +* RETURN:
  48821. +* MV_ERROR if register parameters are invalid.
  48822. +*
  48823. +*******************************************************************************/
  48824. +
  48825. +MV_STATUS mvTdmWinGet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin)
  48826. +{
  48827. +
  48828. + MV_DEC_REGS decRegs;
  48829. + MV_TARGET_ATTRIB targetAttrib;
  48830. +
  48831. + /* Parameter checking */
  48832. + if (winNum >= TDM_MBUS_MAX_WIN)
  48833. + {
  48834. + mvOsPrintf("mvTdmWinGet: ERR. Invalid winNum %d\n", winNum);
  48835. + return MV_NOT_SUPPORTED;
  48836. + }
  48837. +
  48838. + decRegs.baseReg = MV_REG_READ(TDM_WIN_BASE_REG(winNum));
  48839. + decRegs.sizeReg = (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_SIZE_MASK) >> TDM_WIN_SIZE_OFFS;
  48840. +
  48841. + if (MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  48842. + {
  48843. + mvOsPrintf("mvTdmWinGet: mvCtrlRegToAddrDec Failed \n");
  48844. + return MV_ERROR;
  48845. + }
  48846. +
  48847. + /* attrib and targetId */
  48848. + targetAttrib.attrib =
  48849. + (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ATTRIB_MASK) >> TDM_WIN_ATTRIB_OFFS;
  48850. + targetAttrib.targetId =
  48851. + (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_TARGET_MASK) >> TDM_WIN_TARGET_OFFS;
  48852. +
  48853. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  48854. +
  48855. + /* Check if window is enabled */
  48856. + if (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ENABLE_MASK)
  48857. + {
  48858. + pAddrDecWin->enable = MV_TRUE;
  48859. + }
  48860. + else
  48861. + {
  48862. + pAddrDecWin->enable = MV_FALSE;
  48863. + }
  48864. +
  48865. + return MV_OK;
  48866. +}
  48867. +
  48868. +/*******************************************************************************
  48869. +* mvTdmWinEnable - Enable/disable a TDM to target address window
  48870. +*
  48871. +* DESCRIPTION:
  48872. +* This function enable/disable a TDM to target address window.
  48873. +* According to parameter 'enable' the routine will enable the
  48874. +* window, thus enabling TDM accesses (before enabling the window it is
  48875. +* tested for overlapping). Otherwise, the window will be disabled.
  48876. +*
  48877. +* INPUT:
  48878. +* winNum - TDM to target address decode window number.
  48879. +* enable - Enable/disable parameter.
  48880. +*
  48881. +* OUTPUT:
  48882. +* N/A
  48883. +*
  48884. +* RETURN:
  48885. +* MV_ERROR if decode window number was wrong or enabled window overlapps.
  48886. +*
  48887. +*******************************************************************************/
  48888. +MV_STATUS mvTdmWinEnable(int winNum, MV_BOOL enable)
  48889. +{
  48890. + MV_TDM_DEC_WIN addrDecWin;
  48891. +
  48892. + if (MV_TRUE == enable)
  48893. + {
  48894. + if (winNum >= TDM_MBUS_MAX_WIN)
  48895. + {
  48896. + mvOsPrintf("mvTdmWinEnable:ERR. Invalid winNum%d\n",winNum);
  48897. + return MV_ERROR;
  48898. + }
  48899. +
  48900. + /* First check for overlap with other enabled windows */
  48901. + /* Get current window */
  48902. + if (MV_OK != mvTdmWinGet(winNum, &addrDecWin))
  48903. + {
  48904. + mvOsPrintf("mvTdmWinEnable:ERR. targetWinGet fail\n");
  48905. + return MV_ERROR;
  48906. + }
  48907. + /* Check for overlapping */
  48908. + if (MV_FALSE == tdmWinOverlapDetect(winNum, &(addrDecWin.addrWin)))
  48909. + {
  48910. + /* No Overlap. Enable address decode target window */
  48911. + MV_REG_BIT_SET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);
  48912. + }
  48913. + else
  48914. + { /* Overlap detected */
  48915. + mvOsPrintf("mvTdmWinEnable:ERR. Overlap detected\n");
  48916. + return MV_ERROR;
  48917. + }
  48918. + }
  48919. + else
  48920. + {
  48921. + MV_REG_BIT_RESET(TDM_WIN_CTRL_REG(winNum), TDM_WIN_ENABLE_MASK);
  48922. + }
  48923. + return MV_OK;
  48924. +}
  48925. +
  48926. +
  48927. +/*******************************************************************************
  48928. +* tdmWinOverlapDetect - Detect TDM address windows overlapping
  48929. +*
  48930. +* DESCRIPTION:
  48931. +* An unpredicted behaviour is expected in case TDM address decode
  48932. +* windows overlapps.
  48933. +* This function detects TDM address decode windows overlapping of a
  48934. +* specified window. The function does not check the window itself for
  48935. +* overlapping. The function also skipps disabled address decode windows.
  48936. +*
  48937. +* INPUT:
  48938. +* winNum - address decode window number.
  48939. +* pAddrDecWin - An address decode window struct.
  48940. +*
  48941. +* OUTPUT:
  48942. +* None.
  48943. +*
  48944. +* RETURN:
  48945. +* MV_TRUE if the given address window overlap current address
  48946. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  48947. +* from registers.
  48948. +*
  48949. +*******************************************************************************/
  48950. +static MV_STATUS tdmWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  48951. +{
  48952. + MV_U32 winNumIndex;
  48953. + MV_TDM_DEC_WIN addrDecWin;
  48954. +
  48955. + for (winNumIndex = 0; winNumIndex < TDM_MBUS_MAX_WIN; winNumIndex++)
  48956. + {
  48957. + /* Do not check window itself */
  48958. + if (winNumIndex == winNum)
  48959. + {
  48960. + continue;
  48961. + }
  48962. + /* Do not check disabled windows */
  48963. + if (MV_REG_READ(TDM_WIN_CTRL_REG(winNum)) & TDM_WIN_ENABLE_MASK)
  48964. + {
  48965. + /* Get window parameters */
  48966. + if (MV_OK != mvTdmWinGet(winNumIndex, &addrDecWin))
  48967. + {
  48968. + DB(mvOsPrintf("dmaWinOverlapDetect: ERR. TargetWinGet failed\n"));
  48969. + return MV_ERROR;
  48970. + }
  48971. +
  48972. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  48973. + {
  48974. + return MV_TRUE;
  48975. + }
  48976. + }
  48977. + }
  48978. + return MV_FALSE;
  48979. +}
  48980. +
  48981. +/*******************************************************************************
  48982. +* mvTdmAddrDecShow - Print the TDM address decode map.
  48983. +*
  48984. +* DESCRIPTION:
  48985. +* This function print the TDM address decode map.
  48986. +*
  48987. +* INPUT:
  48988. +* None.
  48989. +*
  48990. +* OUTPUT:
  48991. +* None.
  48992. +*
  48993. +* RETURN:
  48994. +* None.
  48995. +*
  48996. +*******************************************************************************/
  48997. +MV_VOID mvTdmAddrDecShow(MV_VOID)
  48998. +{
  48999. + MV_TDM_DEC_WIN win;
  49000. + int i;
  49001. +
  49002. + mvOsOutput( "\n" );
  49003. + mvOsOutput( "TDM:\n" );
  49004. + mvOsOutput( "----\n" );
  49005. +
  49006. + for( i = 0; i < TDM_MBUS_MAX_WIN; i++ )
  49007. + {
  49008. + memset( &win, 0, sizeof(MV_TDM_DEC_WIN) );
  49009. +
  49010. + mvOsOutput( "win%d - ", i );
  49011. +
  49012. + if (mvTdmWinGet(i, &win ) == MV_OK )
  49013. + {
  49014. + if( win.enable )
  49015. + {
  49016. + mvOsOutput( "%s base %08x, ",
  49017. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow);
  49018. + mvOsOutput( "...." );
  49019. + mvSizePrint( win.addrWin.size );
  49020. + mvOsOutput( "\n" );
  49021. + }
  49022. + else
  49023. + mvOsOutput( "disable\n" );
  49024. + }
  49025. + }
  49026. +}
  49027. +
  49028. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h
  49029. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h 1970-01-01 01:00:00.000000000 +0100
  49030. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTdm.h 2011-08-01 14:38:19.000000000 +0200
  49031. @@ -0,0 +1,106 @@
  49032. +/*******************************************************************************
  49033. +Copyright (C) Marvell International Ltd. and its affiliates
  49034. +
  49035. +This software file (the "File") is owned and distributed by Marvell
  49036. +International Ltd. and/or its affiliates ("Marvell") under the following
  49037. +alternative licensing terms. Once you have made an election to distribute the
  49038. +File under one of the following license alternatives, please (i) delete this
  49039. +introductory statement regarding license alternatives, (ii) delete the two
  49040. +license alternatives that you have not elected to use and (iii) preserve the
  49041. +Marvell copyright notice above.
  49042. +
  49043. +********************************************************************************
  49044. +Marvell Commercial License Option
  49045. +
  49046. +If you received this File from Marvell and you have entered into a commercial
  49047. +license agreement (a "Commercial License") with Marvell, the File is licensed
  49048. +to you under the terms of the applicable Commercial License.
  49049. +
  49050. +********************************************************************************
  49051. +Marvell GPL License Option
  49052. +
  49053. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49054. +modify this File in accordance with the terms and conditions of the General
  49055. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  49056. +available along with the File in the license.txt file or by writing to the Free
  49057. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  49058. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  49059. +
  49060. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  49061. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  49062. +DISCLAIMED. The GPL License provides additional details about this warranty
  49063. +disclaimer.
  49064. +********************************************************************************
  49065. +Marvell BSD License Option
  49066. +
  49067. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49068. +modify this File under the following licensing terms.
  49069. +Redistribution and use in source and binary forms, with or without modification,
  49070. +are permitted provided that the following conditions are met:
  49071. +
  49072. + * Redistributions of source code must retain the above copyright notice,
  49073. + this list of conditions and the following disclaimer.
  49074. +
  49075. + * Redistributions in binary form must reproduce the above copyright
  49076. + notice, this list of conditions and the following disclaimer in the
  49077. + documentation and/or other materials provided with the distribution.
  49078. +
  49079. + * Neither the name of Marvell nor the names of its contributors may be
  49080. + used to endorse or promote products derived from this software without
  49081. + specific prior written permission.
  49082. +
  49083. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  49084. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  49085. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  49086. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  49087. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  49088. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  49089. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  49090. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  49091. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  49092. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  49093. +
  49094. +*******************************************************************************/
  49095. +
  49096. +#ifndef __INCmvSysTdmh
  49097. +#define __INCmvSysTdmh
  49098. +
  49099. +#include "ctrlEnv/sys/mvCpuIf.h"
  49100. +#include "ctrlEnv/mvCtrlEnvLib.h"
  49101. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  49102. +
  49103. +typedef struct _mvTdmDecWin
  49104. +{
  49105. + MV_TARGET target;
  49106. + MV_ADDR_WIN addrWin; /* An address window*/
  49107. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  49108. +} MV_TDM_DEC_WIN;
  49109. +
  49110. +MV_STATUS mvTdmWinInit(MV_VOID);
  49111. +MV_STATUS mvTdmWinSet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin);
  49112. +MV_STATUS mvTdmWinGet(MV_U32 winNum, MV_TDM_DEC_WIN *pAddrDecWin);
  49113. +MV_STATUS mvTdmWinEnable(int winNum, MV_BOOL enable);
  49114. +MV_VOID mvTdmAddrDecShow(MV_VOID);
  49115. +
  49116. +
  49117. +#define TDM_MBUS_MAX_WIN 4
  49118. +#define TDM_WIN_CTRL_REG(win) ((TDM_REG_BASE + 0x4030) + (win<<4))
  49119. +#define TDM_WIN_BASE_REG(win) ((TDM_REG_BASE +0x4034) + (win<<4))
  49120. +
  49121. +/* TDM_WIN_CTRL_REG bits */
  49122. +#define TDM_WIN_ENABLE_OFFS 0
  49123. +#define TDM_WIN_ENABLE_MASK (1<<TDM_WIN_ENABLE_OFFS)
  49124. +#define TDM_WIN_ENABLE 1
  49125. +#define TDM_WIN_TARGET_OFFS 4
  49126. +#define TDM_WIN_TARGET_MASK (0xf<<TDM_WIN_TARGET_OFFS)
  49127. +#define TDM_WIN_ATTRIB_OFFS 8
  49128. +#define TDM_WIN_ATTRIB_MASK (0xff<<TDM_WIN_ATTRIB_OFFS)
  49129. +#define TDM_WIN_SIZE_OFFS 16
  49130. +#define TDM_WIN_SIZE_MASK (0xffff<<TDM_WIN_SIZE_OFFS)
  49131. +
  49132. +/* TDM_WIN_BASE_REG bits */
  49133. +#define TDM_BASE_OFFS 16
  49134. +#define TDM_BASE_MASK (0xffff<<TDM_BASE_OFFS)
  49135. +
  49136. +#endif /*__INCmvSysTdmh*/
  49137. +
  49138. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c
  49139. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c 1970-01-01 01:00:00.000000000 +0100
  49140. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.c 2011-08-01 14:38:19.000000000 +0200
  49141. @@ -0,0 +1,591 @@
  49142. +/*******************************************************************************
  49143. +Copyright (C) Marvell International Ltd. and its affiliates
  49144. +
  49145. +This software file (the "File") is owned and distributed by Marvell
  49146. +International Ltd. and/or its affiliates ("Marvell") under the following
  49147. +alternative licensing terms. Once you have made an election to distribute the
  49148. +File under one of the following license alternatives, please (i) delete this
  49149. +introductory statement regarding license alternatives, (ii) delete the two
  49150. +license alternatives that you have not elected to use and (iii) preserve the
  49151. +Marvell copyright notice above.
  49152. +
  49153. +********************************************************************************
  49154. +Marvell Commercial License Option
  49155. +
  49156. +If you received this File from Marvell and you have entered into a commercial
  49157. +license agreement (a "Commercial License") with Marvell, the File is licensed
  49158. +to you under the terms of the applicable Commercial License.
  49159. +
  49160. +********************************************************************************
  49161. +Marvell GPL License Option
  49162. +
  49163. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49164. +modify this File in accordance with the terms and conditions of the General
  49165. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  49166. +available along with the File in the license.txt file or by writing to the Free
  49167. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  49168. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  49169. +
  49170. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  49171. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  49172. +DISCLAIMED. The GPL License provides additional details about this warranty
  49173. +disclaimer.
  49174. +********************************************************************************
  49175. +Marvell BSD License Option
  49176. +
  49177. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49178. +modify this File under the following licensing terms.
  49179. +Redistribution and use in source and binary forms, with or without modification,
  49180. +are permitted provided that the following conditions are met:
  49181. +
  49182. + * Redistributions of source code must retain the above copyright notice,
  49183. + this list of conditions and the following disclaimer.
  49184. +
  49185. + * Redistributions in binary form must reproduce the above copyright
  49186. + notice, this list of conditions and the following disclaimer in the
  49187. + documentation and/or other materials provided with the distribution.
  49188. +
  49189. + * Neither the name of Marvell nor the names of its contributors may be
  49190. + used to endorse or promote products derived from this software without
  49191. + specific prior written permission.
  49192. +
  49193. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  49194. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  49195. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  49196. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  49197. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  49198. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  49199. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  49200. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  49201. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  49202. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  49203. +
  49204. +*******************************************************************************/
  49205. +
  49206. +
  49207. +#include "ctrlEnv/sys/mvSysTs.h"
  49208. +
  49209. +
  49210. +typedef struct _mvTsuDecWin
  49211. +{
  49212. + MV_TARGET target;
  49213. + MV_ADDR_WIN addrWin; /* An address window*/
  49214. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  49215. +
  49216. +}MV_TSU_DEC_WIN;
  49217. +
  49218. +
  49219. +MV_TARGET tsuAddrDecPrioTap[] =
  49220. +{
  49221. +#if defined(MV_INCLUDE_PEX)
  49222. + PEX0_MEM,
  49223. +#endif
  49224. +#if defined(MV_INCLUDE_PCI)
  49225. + PCI0_MEM,
  49226. +#endif
  49227. +#if defined(MV_INCLUDE_SDRAM_CS0)
  49228. + SDRAM_CS0,
  49229. +#endif
  49230. +#if defined(MV_INCLUDE_SDRAM_CS1)
  49231. + SDRAM_CS1,
  49232. +#endif
  49233. +#if defined(MV_INCLUDE_SDRAM_CS2)
  49234. + SDRAM_CS2,
  49235. +#endif
  49236. +#if defined(MV_INCLUDE_SDRAM_CS3)
  49237. + SDRAM_CS3,
  49238. +#endif
  49239. +#if defined(MV_INCLUDE_DEVICE_CS0)
  49240. + DEVICE_CS0,
  49241. +#endif
  49242. +#if defined(MV_INCLUDE_DEVICE_CS1)
  49243. + DEVICE_CS1,
  49244. +#endif
  49245. +#if defined(MV_INCLUDE_DEVICE_CS2)
  49246. + DEVICE_CS2,
  49247. +#endif
  49248. +#if defined(MV_INCLUDE_DEVICE_CS3)
  49249. + DEVICE_CS3,
  49250. +#endif
  49251. +#if defined(MV_INCLUDE_PEX)
  49252. + PEX0_IO,
  49253. +#endif
  49254. +#if defined(MV_INCLUDE_PCI)
  49255. + PCI0_IO,
  49256. +#endif
  49257. + TBL_TERM
  49258. +};
  49259. +
  49260. +static MV_STATUS tsuWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
  49261. +static MV_STATUS mvTsuWinSet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin);
  49262. +static MV_STATUS mvTsuWinGet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin);
  49263. +MV_STATUS mvTsuWinEnable(MV_U32 winNum,MV_BOOL enable);
  49264. +
  49265. +/*******************************************************************************
  49266. +* mvTsuWinInit
  49267. +*
  49268. +* DESCRIPTION:
  49269. +* Initialize the TSU unit address decode windows.
  49270. +*
  49271. +* INPUT:
  49272. +* None.
  49273. +* OUTPUT:
  49274. +* None.
  49275. +* RETURN:
  49276. +* MV_OK - on success,
  49277. +*
  49278. +*******************************************************************************/
  49279. +MV_STATUS mvTsuWinInit(void)
  49280. +{
  49281. + MV_U32 winNum, status, winPrioIndex=0;
  49282. + MV_TSU_DEC_WIN tsuWin;
  49283. + MV_CPU_DEC_WIN cpuAddrDecWin;
  49284. +
  49285. + /* First disable all address decode windows */
  49286. + for(winNum = 0; winNum < TSU_MAX_DECODE_WIN; winNum++)
  49287. + {
  49288. + MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum),
  49289. + TSU_WIN_CTRL_EN_MASK);
  49290. + }
  49291. +
  49292. + /* Go through all windows in user table until table terminator */
  49293. + for(winNum = 0; ((tsuAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
  49294. + (winNum < TSU_MAX_DECODE_WIN));)
  49295. + {
  49296. + /* first get attributes from CPU If */
  49297. + status = mvCpuIfTargetWinGet(tsuAddrDecPrioTap[winPrioIndex],
  49298. + &cpuAddrDecWin);
  49299. +
  49300. + if(MV_NO_SUCH == status)
  49301. + {
  49302. + winPrioIndex++;
  49303. + continue;
  49304. + }
  49305. + if(MV_OK != status)
  49306. + {
  49307. + mvOsPrintf("mvTsuWinInit: ERR. mvCpuIfTargetWinGet failed\n");
  49308. + return MV_ERROR;
  49309. + }
  49310. +
  49311. + if (cpuAddrDecWin.enable == MV_TRUE)
  49312. + {
  49313. + tsuWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  49314. + tsuWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  49315. + tsuWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  49316. + tsuWin.enable = MV_TRUE;
  49317. + tsuWin.target = tsuAddrDecPrioTap[winPrioIndex];
  49318. +
  49319. + if(MV_OK != mvTsuWinSet(winNum, &tsuWin))
  49320. + {
  49321. + mvOsPrintf("mvTsuWinInit: ERR. mvTsuWinSet failed winNum=%d\n",
  49322. + winNum);
  49323. + return MV_ERROR;
  49324. + }
  49325. + winNum++;
  49326. + }
  49327. + winPrioIndex ++;
  49328. + }
  49329. +
  49330. + return MV_OK;
  49331. +}
  49332. +
  49333. +
  49334. +/*******************************************************************************
  49335. +* mvTsuWinSet
  49336. +*
  49337. +* DESCRIPTION:
  49338. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  49339. +* address window, also known as address decode window.
  49340. +* After setting this target window, the TSU will be able to access the
  49341. +* target within the address window.
  49342. +*
  49343. +* INPUT:
  49344. +* winNum - TSU to target address decode window number.
  49345. +* pAddrDecWin - TSU target window data structure.
  49346. +*
  49347. +* OUTPUT:
  49348. +* None.
  49349. +*
  49350. +* RETURN:
  49351. +* MV_ERROR - if address window overlapps with other address decode
  49352. +* windows.
  49353. +* MV_BAD_PARAM - if base address is invalid parameter or target is
  49354. +* unknown.
  49355. +*
  49356. +*******************************************************************************/
  49357. +MV_STATUS mvTsuWinSet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin)
  49358. +{
  49359. + MV_TARGET_ATTRIB targetAttribs;
  49360. + MV_DEC_REGS decRegs;
  49361. +
  49362. + /* Parameter checking */
  49363. + if(winNum >= TSU_MAX_DECODE_WIN)
  49364. + {
  49365. + mvOsPrintf("mvTsuWinSet: ERR. Invalid win num %d\n",winNum);
  49366. + return MV_BAD_PARAM;
  49367. + }
  49368. +
  49369. + /* Check if the requested window overlapps with current windows */
  49370. + if(MV_TRUE == tsuWinOverlapDetect(winNum, &pAddrDecWin->addrWin))
  49371. + {
  49372. + mvOsPrintf("mvTsuWinSet: ERR. Window %d overlap\n", winNum);
  49373. + return MV_ERROR;
  49374. + }
  49375. +
  49376. + /* check if address is aligned to the size */
  49377. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow,pAddrDecWin->addrWin.size))
  49378. + {
  49379. + mvOsPrintf("mvTsuWinSet: Error setting TSU window %d to target "
  49380. + "%s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  49381. + winNum, mvCtrlTargetNameGet(pAddrDecWin->target),
  49382. + pAddrDecWin->addrWin.baseLow,
  49383. + pAddrDecWin->addrWin.size);
  49384. + return MV_ERROR;
  49385. + }
  49386. +
  49387. + decRegs.baseReg = MV_REG_READ(MV_TSU_WIN_BASE_REG(winNum));
  49388. + decRegs.sizeReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum));
  49389. +
  49390. + if(MV_OK != mvCtrlAddrDecToReg(&(pAddrDecWin->addrWin),&decRegs))
  49391. + {
  49392. + mvOsPrintf("mvTsuWinSet: mvCtrlAddrDecToReg Failed\n");
  49393. + return MV_ERROR;
  49394. + }
  49395. +
  49396. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  49397. +
  49398. + /* set attributes */
  49399. + decRegs.sizeReg &= ~TSU_WIN_CTRL_ATTR_MASK;
  49400. + decRegs.sizeReg |= targetAttribs.attrib << TSU_WIN_CTRL_ATTR_OFFS;
  49401. + /* set target ID */
  49402. + decRegs.sizeReg &= ~TSU_WIN_CTRL_TARGET_MASK;
  49403. + decRegs.sizeReg |= targetAttribs.targetId << TSU_WIN_CTRL_TARGET_OFFS;
  49404. +
  49405. + /* for the safe side we disable the window before writing the new */
  49406. + /* values */
  49407. + mvTsuWinEnable(winNum, MV_FALSE);
  49408. + MV_REG_WRITE(MV_TSU_WIN_CTRL_REG(winNum),decRegs.sizeReg);
  49409. +
  49410. + /* Write to address decode Size Register */
  49411. + MV_REG_WRITE(MV_TSU_WIN_BASE_REG(winNum), decRegs.baseReg);
  49412. +
  49413. + /* Enable address decode target window */
  49414. + if(pAddrDecWin->enable == MV_TRUE)
  49415. + {
  49416. + mvTsuWinEnable(winNum,MV_TRUE);
  49417. + }
  49418. +
  49419. + return MV_OK;
  49420. +}
  49421. +
  49422. +
  49423. +/*******************************************************************************
  49424. +* mvTsuWinGet
  49425. +*
  49426. +* DESCRIPTION:
  49427. +* Get TSU peripheral target address window.
  49428. +*
  49429. +* INPUT:
  49430. +* winNum - TSU to target address decode window number.
  49431. +*
  49432. +* OUTPUT:
  49433. +* pAddrDecWin - TSU target window data structure.
  49434. +*
  49435. +* RETURN:
  49436. +* MV_ERROR if register parameters are invalid.
  49437. +*
  49438. +*******************************************************************************/
  49439. +MV_STATUS mvTsuWinGet(MV_U32 winNum, MV_TSU_DEC_WIN *pAddrDecWin)
  49440. +{
  49441. + MV_DEC_REGS decRegs;
  49442. + MV_TARGET_ATTRIB targetAttrib;
  49443. +
  49444. + /* Parameter checking */
  49445. + if(winNum >= TSU_MAX_DECODE_WIN)
  49446. + {
  49447. + mvOsPrintf("mvTsuWinGet: ERR. Invalid winNum %d\n", winNum);
  49448. + return MV_NOT_SUPPORTED;
  49449. + }
  49450. +
  49451. + decRegs.baseReg = MV_REG_READ(MV_TSU_WIN_BASE_REG(winNum));
  49452. + decRegs.sizeReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum));
  49453. +
  49454. + if(MV_OK != mvCtrlRegToAddrDec(&decRegs,&(pAddrDecWin->addrWin)))
  49455. + {
  49456. + mvOsPrintf("mvTsuWinGet: mvCtrlRegToAddrDec Failed \n");
  49457. + return MV_ERROR;
  49458. + }
  49459. +
  49460. + /* attrib and targetId */
  49461. + targetAttrib.attrib =
  49462. + (decRegs.sizeReg & TSU_WIN_CTRL_ATTR_MASK) >> TSU_WIN_CTRL_ATTR_OFFS;
  49463. + targetAttrib.targetId =
  49464. + (decRegs.sizeReg & TSU_WIN_CTRL_TARGET_MASK) >> TSU_WIN_CTRL_TARGET_OFFS;
  49465. +
  49466. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  49467. +
  49468. + /* Check if window is enabled */
  49469. + if((MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNum)) & TSU_WIN_CTRL_EN_MASK))
  49470. + {
  49471. + pAddrDecWin->enable = MV_TRUE;
  49472. + }
  49473. + else
  49474. + {
  49475. + pAddrDecWin->enable = MV_FALSE;
  49476. + }
  49477. +
  49478. + return MV_OK;
  49479. +}
  49480. +
  49481. +
  49482. +/*******************************************************************************
  49483. +* mvTsuWinEnable
  49484. +*
  49485. +* DESCRIPTION:
  49486. +* This function enable/disable a TSU to target address window.
  49487. +* According to parameter 'enable' the routine will enable the
  49488. +* window, thus enabling TSU accesses (before enabling the window it is
  49489. +* tested for overlapping). Otherwise, the window will be disabled.
  49490. +*
  49491. +* INPUT:
  49492. +* winNum - TSU to target address decode window number.
  49493. +* enable - Enable / disable parameter.
  49494. +*
  49495. +* OUTPUT:
  49496. +* N/A
  49497. +*
  49498. +* RETURN:
  49499. +* MV_ERROR if decode window number was wrong or enabled window overlapps.
  49500. +*
  49501. +*******************************************************************************/
  49502. +MV_STATUS mvTsuWinEnable(MV_U32 winNum,MV_BOOL enable)
  49503. +{
  49504. + MV_TSU_DEC_WIN addrDecWin;
  49505. +
  49506. + /* Parameter checking */
  49507. + if(winNum >= TSU_MAX_DECODE_WIN)
  49508. + {
  49509. + mvOsPrintf("mvTsuWinEnable: ERR. Invalid winNum%d\n",winNum);
  49510. + return MV_ERROR;
  49511. + }
  49512. +
  49513. + if(enable == MV_TRUE)
  49514. + {
  49515. + /* First check for overlap with other enabled windows */
  49516. + /* Get current window. */
  49517. + if(MV_OK != mvTsuWinGet(winNum,&addrDecWin))
  49518. + {
  49519. + mvOsPrintf("mvTsuWinEnable: ERR. targetWinGet fail\n");
  49520. + return MV_ERROR;
  49521. + }
  49522. + /* Check for overlapping. */
  49523. + if(MV_FALSE == tsuWinOverlapDetect(winNum,&(addrDecWin.addrWin)))
  49524. + {
  49525. + /* No Overlap. Enable address decode target window */
  49526. + MV_REG_BIT_SET(MV_TSU_WIN_CTRL_REG(winNum),
  49527. + TSU_WIN_CTRL_EN_MASK);
  49528. + }
  49529. + else
  49530. + {
  49531. + /* Overlap detected */
  49532. + mvOsPrintf("mvTsuWinEnable: ERR. Overlap detected\n");
  49533. + return MV_ERROR;
  49534. + }
  49535. + }
  49536. + else
  49537. + {
  49538. + /* Disable address decode target window */
  49539. + MV_REG_BIT_RESET(MV_TSU_WIN_CTRL_REG(winNum),
  49540. + TSU_WIN_CTRL_EN_MASK);
  49541. + }
  49542. + return MV_OK;
  49543. +}
  49544. +
  49545. +/*******************************************************************************
  49546. +* mvTsuWinTargetGet
  49547. +*
  49548. +* DESCRIPTION:
  49549. +* Get Window number associated with target
  49550. +*
  49551. +* INPUT:
  49552. +* target - Target ID to get the window number for.
  49553. +* OUTPUT:
  49554. +*
  49555. +* RETURN:
  49556. +* window number or 0xFFFFFFFF on error.
  49557. +*
  49558. +*******************************************************************************/
  49559. +MV_U32 mvTsuWinTargetGet(MV_TARGET target)
  49560. +{
  49561. + MV_TSU_DEC_WIN decWin;
  49562. + MV_U32 winNum;
  49563. +
  49564. + /* Check parameters */
  49565. + if(target >= MAX_TARGETS)
  49566. + {
  49567. + mvOsPrintf("mvTsuWinTargetGet: target %d is Illigal\n", target);
  49568. + return 0xffffffff;
  49569. + }
  49570. +
  49571. + for(winNum = 0; winNum < TSU_MAX_DECODE_WIN; winNum++)
  49572. + {
  49573. + if(mvTsuWinGet(winNum,&decWin) != MV_OK)
  49574. + {
  49575. + mvOsPrintf("mvTsuWinGet: window returned error\n");
  49576. + return 0xffffffff;
  49577. + }
  49578. +
  49579. + if (decWin.enable == MV_TRUE)
  49580. + {
  49581. + if(decWin.target == target)
  49582. + {
  49583. + return winNum;
  49584. + }
  49585. + }
  49586. + }
  49587. + return 0xFFFFFFFF;
  49588. +}
  49589. +
  49590. +
  49591. +/*******************************************************************************
  49592. +* tsuWinOverlapDetect
  49593. +*
  49594. +* DESCRIPTION:
  49595. +* Detect TSU address windows overlapping
  49596. +* An unpredicted behaviur is expected in case TSU address decode
  49597. +* windows overlapps.
  49598. +* This function detects TSU address decode windows overlapping of a
  49599. +* specified window. The function does not check the window itself for
  49600. +* overlapping. The function also skipps disabled address decode windows.
  49601. +*
  49602. +* INPUT:
  49603. +* winNum - address decode window number.
  49604. +* pAddrDecWin - An address decode window struct.
  49605. +*
  49606. +* OUTPUT:
  49607. +* None.
  49608. +*
  49609. +* RETURN:
  49610. +* MV_TRUE if the given address window overlap current address
  49611. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  49612. +* from registers.
  49613. +*
  49614. +*******************************************************************************/
  49615. +static MV_STATUS tsuWinOverlapDetect(MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  49616. +{
  49617. + MV_U32 ctrlReg;
  49618. + MV_U32 winNumIndex;
  49619. + MV_TSU_DEC_WIN addrDecWin;
  49620. +
  49621. + for(winNumIndex = 0; winNumIndex < TSU_MAX_DECODE_WIN; winNumIndex++)
  49622. + {
  49623. + /* Do not check window itself */
  49624. + if(winNumIndex == winNum)
  49625. + {
  49626. + continue;
  49627. + }
  49628. +
  49629. + /* Do not check disabled windows */
  49630. + ctrlReg = MV_REG_READ(MV_TSU_WIN_CTRL_REG(winNumIndex));
  49631. + if((ctrlReg & TSU_WIN_CTRL_EN_MASK) == 0)
  49632. + {
  49633. + continue;
  49634. + }
  49635. +
  49636. + /* Get window parameters */
  49637. + if (MV_OK != mvTsuWinGet(winNumIndex, &addrDecWin))
  49638. + {
  49639. + mvOsPrintf("tsuWinOverlapDetect: ERR. mvTsuWinGet failed\n");
  49640. + return MV_ERROR;
  49641. + }
  49642. +
  49643. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  49644. + {
  49645. + return MV_TRUE;
  49646. + }
  49647. + }
  49648. + return MV_FALSE;
  49649. +}
  49650. +
  49651. +
  49652. +/*******************************************************************************
  49653. +* mvTsuAddrDecShow
  49654. +*
  49655. +* DESCRIPTION:
  49656. +* Print the TSU address decode map.
  49657. +*
  49658. +* INPUT:
  49659. +* None.
  49660. +*
  49661. +* OUTPUT:
  49662. +* None.
  49663. +*
  49664. +* RETURN:
  49665. +* None.
  49666. +*
  49667. +*******************************************************************************/
  49668. +void mvTsuAddrDecShow(void)
  49669. +{
  49670. + MV_TSU_DEC_WIN win;
  49671. + int i;
  49672. +
  49673. + if (MV_FALSE == mvCtrlPwrClckGet(TS_UNIT_ID, 0))
  49674. + return;
  49675. +
  49676. + mvOsOutput( "\n" );
  49677. + mvOsOutput( "TSU:\n");
  49678. + mvOsOutput( "----\n" );
  49679. +
  49680. + for(i = 0; i < TSU_MAX_DECODE_WIN; i++)
  49681. + {
  49682. + memset(&win, 0, sizeof(TSU_MAX_DECODE_WIN));
  49683. + mvOsOutput( "win%d - ", i );
  49684. +
  49685. + if(mvTsuWinGet(i, &win ) == MV_OK )
  49686. + {
  49687. + if(win.enable == MV_TRUE)
  49688. + {
  49689. + mvOsOutput("%s base %08x, ",
  49690. + mvCtrlTargetNameGet(win.target),
  49691. + win.addrWin.baseLow);
  49692. + mvOsOutput( "...." );
  49693. + mvSizePrint(win.addrWin.size );
  49694. + mvOsOutput( "\n" );
  49695. + }
  49696. + else
  49697. + {
  49698. + mvOsOutput( "disable\n" );
  49699. + }
  49700. + }
  49701. + }
  49702. + return;
  49703. +}
  49704. +
  49705. +
  49706. +/*******************************************************************************
  49707. +* mvTsuInit
  49708. +*
  49709. +* DESCRIPTION:
  49710. +* Initialize the TSU unit, and get unit out of reset.
  49711. +*
  49712. +* INPUT:
  49713. +* coreClock - The core clock at which the TSU should operate.
  49714. +* mode - The mode on configure the unit into (serial/parallel).
  49715. +* memHandle - Memory handle used for memory allocations.
  49716. +* OUTPUT:
  49717. +* None.
  49718. +* RETURN:
  49719. +* MV_OK - on success,
  49720. +*
  49721. +*******************************************************************************/
  49722. +MV_STATUS mvTsuInit(MV_TSU_CORE_CLOCK coreClock, MV_TSU_PORTS_MODE mode,
  49723. + void *osHandle)
  49724. +{
  49725. + MV_STATUS status;
  49726. +
  49727. + status = mvTsuWinInit();
  49728. + if(status == MV_OK)
  49729. + status = mvTsuHalInit(coreClock,mode,osHandle);
  49730. +
  49731. + return status;
  49732. +}
  49733. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h
  49734. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h 1970-01-01 01:00:00.000000000 +0100
  49735. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysTs.h 2011-08-01 14:38:19.000000000 +0200
  49736. @@ -0,0 +1,110 @@
  49737. +/*******************************************************************************
  49738. +Copyright (C) Marvell International Ltd. and its affiliates
  49739. +
  49740. +This software file (the "File") is owned and distributed by Marvell
  49741. +International Ltd. and/or its affiliates ("Marvell") under the following
  49742. +alternative licensing terms. Once you have made an election to distribute the
  49743. +File under one of the following license alternatives, please (i) delete this
  49744. +introductory statement regarding license alternatives, (ii) delete the two
  49745. +license alternatives that you have not elected to use and (iii) preserve the
  49746. +Marvell copyright notice above.
  49747. +
  49748. +********************************************************************************
  49749. +Marvell Commercial License Option
  49750. +
  49751. +If you received this File from Marvell and you have entered into a commercial
  49752. +license agreement (a "Commercial License") with Marvell, the File is licensed
  49753. +to you under the terms of the applicable Commercial License.
  49754. +
  49755. +********************************************************************************
  49756. +Marvell GPL License Option
  49757. +
  49758. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49759. +modify this File in accordance with the terms and conditions of the General
  49760. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  49761. +available along with the File in the license.txt file or by writing to the Free
  49762. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  49763. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  49764. +
  49765. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  49766. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  49767. +DISCLAIMED. The GPL License provides additional details about this warranty
  49768. +disclaimer.
  49769. +********************************************************************************
  49770. +Marvell BSD License Option
  49771. +
  49772. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49773. +modify this File under the following licensing terms.
  49774. +Redistribution and use in source and binary forms, with or without modification,
  49775. +are permitted provided that the following conditions are met:
  49776. +
  49777. + * Redistributions of source code must retain the above copyright notice,
  49778. + this list of conditions and the following disclaimer.
  49779. +
  49780. + * Redistributions in binary form must reproduce the above copyright
  49781. + notice, this list of conditions and the following disclaimer in the
  49782. + documentation and/or other materials provided with the distribution.
  49783. +
  49784. + * Neither the name of Marvell nor the names of its contributors may be
  49785. + used to endorse or promote products derived from this software without
  49786. + specific prior written permission.
  49787. +
  49788. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  49789. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  49790. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  49791. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  49792. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  49793. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  49794. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  49795. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  49796. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  49797. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  49798. +
  49799. +*******************************************************************************/
  49800. +
  49801. +#ifndef __INCmvSysTsh
  49802. +#define __INCmvSysTsh
  49803. +
  49804. +#ifdef __cplusplus
  49805. +extern "C" {
  49806. +#endif /* __cplusplus */
  49807. +
  49808. +/* includes */
  49809. +#include "ts/mvTsu.h"
  49810. +#include "ctrlEnv/sys/mvCpuIf.h"
  49811. +#include "ctrlEnv/mvCtrlEnvLib.h"
  49812. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  49813. +
  49814. +#define TSU_MAX_DECODE_WIN 4
  49815. +
  49816. +
  49817. +/*******************************************/
  49818. +/* TSU Windows Registers */
  49819. +/*******************************************/
  49820. +#define MV_TSU_WIN_CTRL_REG(win) (TSU_GLOBAL_REG_BASE +0x30 + 0x10 * win)
  49821. +#define MV_TSU_WIN_BASE_REG(win) (TSU_GLOBAL_REG_BASE +0x34 + 0x10 * win)
  49822. +
  49823. +/* TSU windows control register. */
  49824. +#define TSU_WIN_CTRL_EN_MASK (0x1 << 0)
  49825. +#define TSU_WIN_CTRL_TARGET_OFFS 4
  49826. +#define TSU_WIN_CTRL_TARGET_MASK (0xF << TSU_WIN_CTRL_TARGET_OFFS)
  49827. +#define TSU_WIN_CTRL_ATTR_OFFS 8
  49828. +#define TSU_WIN_CTRL_ATTR_MASK (0xFF << TSU_WIN_CTRL_ATTR_OFFS)
  49829. +#define TSU_WIN_CTRL_SIZE_OFFS 16
  49830. +#define TSU_WIN_CTRL_SIZE_MASK (0xFFFF << TSU_WIN_CTRL_SIZE_OFFS)
  49831. +
  49832. +/* TSU windows base register. */
  49833. +#define TSU_WIN_BASE_OFFS 16
  49834. +#define TSU_WIN_BASE_MASK (0xFFFF << TSU_WIN_BASE_OFFS)
  49835. +
  49836. +MV_STATUS mvTsuWinInit(void);
  49837. +
  49838. +void mvTsuAddrDecShow(void);
  49839. +MV_STATUS mvTsuInit(MV_TSU_CORE_CLOCK coreClock, MV_TSU_PORTS_MODE mode,
  49840. + void *osHandle);
  49841. +
  49842. +#ifdef __cplusplus
  49843. +}
  49844. +#endif /* __cplusplus */
  49845. +
  49846. +#endif /* __INCmvTsh */
  49847. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c
  49848. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c 1970-01-01 01:00:00.000000000 +0100
  49849. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.c 2011-08-01 14:38:19.000000000 +0200
  49850. @@ -0,0 +1,497 @@
  49851. +/*******************************************************************************
  49852. +Copyright (C) Marvell International Ltd. and its affiliates
  49853. +
  49854. +This software file (the "File") is owned and distributed by Marvell
  49855. +International Ltd. and/or its affiliates ("Marvell") under the following
  49856. +alternative licensing terms. Once you have made an election to distribute the
  49857. +File under one of the following license alternatives, please (i) delete this
  49858. +introductory statement regarding license alternatives, (ii) delete the two
  49859. +license alternatives that you have not elected to use and (iii) preserve the
  49860. +Marvell copyright notice above.
  49861. +
  49862. +********************************************************************************
  49863. +Marvell Commercial License Option
  49864. +
  49865. +If you received this File from Marvell and you have entered into a commercial
  49866. +license agreement (a "Commercial License") with Marvell, the File is licensed
  49867. +to you under the terms of the applicable Commercial License.
  49868. +
  49869. +********************************************************************************
  49870. +Marvell GPL License Option
  49871. +
  49872. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49873. +modify this File in accordance with the terms and conditions of the General
  49874. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  49875. +available along with the File in the license.txt file or by writing to the Free
  49876. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  49877. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  49878. +
  49879. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  49880. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  49881. +DISCLAIMED. The GPL License provides additional details about this warranty
  49882. +disclaimer.
  49883. +********************************************************************************
  49884. +Marvell BSD License Option
  49885. +
  49886. +If you received this File from Marvell, you may opt to use, redistribute and/or
  49887. +modify this File under the following licensing terms.
  49888. +Redistribution and use in source and binary forms, with or without modification,
  49889. +are permitted provided that the following conditions are met:
  49890. +
  49891. + * Redistributions of source code must retain the above copyright notice,
  49892. + this list of conditions and the following disclaimer.
  49893. +
  49894. + * Redistributions in binary form must reproduce the above copyright
  49895. + notice, this list of conditions and the following disclaimer in the
  49896. + documentation and/or other materials provided with the distribution.
  49897. +
  49898. + * Neither the name of Marvell nor the names of its contributors may be
  49899. + used to endorse or promote products derived from this software without
  49900. + specific prior written permission.
  49901. +
  49902. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  49903. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  49904. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  49905. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  49906. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  49907. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  49908. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  49909. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  49910. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  49911. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  49912. +
  49913. +*******************************************************************************/
  49914. +
  49915. +#include "ctrlEnv/sys/mvSysUsb.h"
  49916. +
  49917. +MV_TARGET usbAddrDecPrioTab[] =
  49918. +{
  49919. +#if defined(MV_INCLUDE_SDRAM_CS0)
  49920. + SDRAM_CS0,
  49921. +#endif
  49922. +#if defined(MV_INCLUDE_SDRAM_CS1)
  49923. + SDRAM_CS1,
  49924. +#endif
  49925. +#if defined(MV_INCLUDE_SDRAM_CS2)
  49926. + SDRAM_CS2,
  49927. +#endif
  49928. +#if defined(MV_INCLUDE_SDRAM_CS3)
  49929. + SDRAM_CS3,
  49930. +#endif
  49931. +#if defined(MV_INCLUDE_CESA) && defined(USB_UNDERRUN_WA)
  49932. + CRYPT_ENG,
  49933. +#endif
  49934. +#if defined(MV_INCLUDE_PEX)
  49935. + PEX0_MEM,
  49936. +#endif
  49937. + TBL_TERM
  49938. +};
  49939. +
  49940. +
  49941. +
  49942. +MV_STATUS mvUsbInit(int dev, MV_BOOL isHost)
  49943. +{
  49944. + MV_STATUS status;
  49945. +
  49946. + status = mvUsbWinInit(dev);
  49947. + if(status != MV_OK)
  49948. + return status;
  49949. +
  49950. + return mvUsbHalInit(dev, isHost);
  49951. +}
  49952. +
  49953. +
  49954. +/*******************************************************************************
  49955. +* usbWinOverlapDetect - Detect USB address windows overlapping
  49956. +*
  49957. +* DESCRIPTION:
  49958. +* An unpredicted behaviur is expected in case USB address decode
  49959. +* windows overlapps.
  49960. +* This function detects USB address decode windows overlapping of a
  49961. +* specified window. The function does not check the window itself for
  49962. +* overlapping. The function also skipps disabled address decode windows.
  49963. +*
  49964. +* INPUT:
  49965. +* winNum - address decode window number.
  49966. +* pAddrDecWin - An address decode window struct.
  49967. +*
  49968. +* OUTPUT:
  49969. +* None.
  49970. +*
  49971. +* RETURN:
  49972. +* MV_TRUE if the given address window overlap current address
  49973. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  49974. +* from registers.
  49975. +*
  49976. +*******************************************************************************/
  49977. +static MV_STATUS usbWinOverlapDetect(int dev, MV_U32 winNum,
  49978. + MV_ADDR_WIN *pAddrWin)
  49979. +{
  49980. + MV_U32 winNumIndex;
  49981. + MV_DEC_WIN addrDecWin;
  49982. +
  49983. + for(winNumIndex=0; winNumIndex<MV_USB_MAX_ADDR_DECODE_WIN; winNumIndex++)
  49984. + {
  49985. + /* Do not check window itself */
  49986. + if (winNumIndex == winNum)
  49987. + {
  49988. + continue;
  49989. + }
  49990. +
  49991. + /* Get window parameters */
  49992. + if (MV_OK != mvUsbWinGet(dev, winNumIndex, &addrDecWin))
  49993. + {
  49994. + mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__);
  49995. + return MV_ERROR;
  49996. + }
  49997. +
  49998. + /* Do not check disabled windows */
  49999. + if(addrDecWin.enable == MV_FALSE)
  50000. + {
  50001. + continue;
  50002. + }
  50003. +
  50004. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  50005. + {
  50006. + return MV_TRUE;
  50007. + }
  50008. + }
  50009. + return MV_FALSE;
  50010. +}
  50011. +
  50012. +/*******************************************************************************
  50013. +* mvUsbWinSet - Set USB target address window
  50014. +*
  50015. +* DESCRIPTION:
  50016. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  50017. +* address window, also known as address decode window.
  50018. +* After setting this target window, the USB will be able to access the
  50019. +* target within the address window.
  50020. +*
  50021. +* INPUT:
  50022. +* winNum - USB target address decode window number.
  50023. +* pAddrDecWin - USB target window data structure.
  50024. +*
  50025. +* OUTPUT:
  50026. +* None.
  50027. +*
  50028. +* RETURN:
  50029. +* MV_ERROR if address window overlapps with other address decode windows.
  50030. +* MV_BAD_PARAM if base address is invalid parameter or target is
  50031. +* unknown.
  50032. +*
  50033. +*******************************************************************************/
  50034. +MV_STATUS mvUsbWinSet(int dev, MV_U32 winNum, MV_DEC_WIN *pDecWin)
  50035. +{
  50036. + MV_DEC_WIN_PARAMS winParams;
  50037. + MV_U32 sizeReg, baseReg;
  50038. +
  50039. + /* Parameter checking */
  50040. + if (winNum >= MV_USB_MAX_ADDR_DECODE_WIN)
  50041. + {
  50042. + mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum);
  50043. + return MV_BAD_PARAM;
  50044. + }
  50045. +
  50046. + /* Check if the requested window overlapps with current windows */
  50047. + if (MV_TRUE == usbWinOverlapDetect(dev, winNum, &pDecWin->addrWin))
  50048. + {
  50049. + mvOsPrintf("%s: ERR. Window %d overlap\n", __FUNCTION__, winNum);
  50050. + return MV_ERROR;
  50051. + }
  50052. +
  50053. + /* check if address is aligned to the size */
  50054. + if(MV_IS_NOT_ALIGN(pDecWin->addrWin.baseLow, pDecWin->addrWin.size))
  50055. + {
  50056. + mvOsPrintf("mvUsbWinSet:Error setting USB window %d to "\
  50057. + "target %s.\nAddress 0x%08x is unaligned to size 0x%x.\n",
  50058. + winNum,
  50059. + mvCtrlTargetNameGet(pDecWin->target),
  50060. + pDecWin->addrWin.baseLow,
  50061. + pDecWin->addrWin.size);
  50062. + return MV_ERROR;
  50063. + }
  50064. +
  50065. + if(MV_OK != mvCtrlAddrDecToParams(pDecWin, &winParams))
  50066. + {
  50067. + mvOsPrintf("%s: mvCtrlAddrDecToParams Failed\n", __FUNCTION__);
  50068. + return MV_ERROR;
  50069. + }
  50070. +
  50071. + /* set Size, Attributes and TargetID */
  50072. + sizeReg = (((winParams.targetId << MV_USB_WIN_TARGET_OFFSET) & MV_USB_WIN_TARGET_MASK) |
  50073. + ((winParams.attrib << MV_USB_WIN_ATTR_OFFSET) & MV_USB_WIN_ATTR_MASK) |
  50074. + ((winParams.size << MV_USB_WIN_SIZE_OFFSET) & MV_USB_WIN_SIZE_MASK));
  50075. +
  50076. +#if defined(MV645xx) || defined(MV646xx)
  50077. + /* If window is DRAM with HW cache coherency, make sure bit2 is set */
  50078. + sizeReg &= ~MV_USB_WIN_BURST_WR_LIMIT_MASK;
  50079. +
  50080. + if((MV_TARGET_IS_DRAM(pDecWin->target)) &&
  50081. + (pDecWin->addrWinAttr.cachePolicy != NO_COHERENCY))
  50082. + {
  50083. + sizeReg |= MV_USB_WIN_BURST_WR_32BIT_LIMIT;
  50084. + }
  50085. + else
  50086. + {
  50087. + sizeReg |= MV_USB_WIN_BURST_WR_NO_LIMIT;
  50088. + }
  50089. +#endif /* MV645xx || MV646xx */
  50090. +
  50091. + if (pDecWin->enable == MV_TRUE)
  50092. + {
  50093. + sizeReg |= MV_USB_WIN_ENABLE_MASK;
  50094. + }
  50095. + else
  50096. + {
  50097. + sizeReg &= ~MV_USB_WIN_ENABLE_MASK;
  50098. + }
  50099. +
  50100. + /* Update Base value */
  50101. + baseReg = (winParams.baseAddr & MV_USB_WIN_BASE_MASK);
  50102. +
  50103. + MV_REG_WRITE( MV_USB_WIN_CTRL_REG(dev, winNum), sizeReg);
  50104. + MV_REG_WRITE( MV_USB_WIN_BASE_REG(dev, winNum), baseReg);
  50105. +
  50106. + return MV_OK;
  50107. +}
  50108. +
  50109. +/*******************************************************************************
  50110. +* mvUsbWinGet - Get USB peripheral target address window.
  50111. +*
  50112. +* DESCRIPTION:
  50113. +* Get USB peripheral target address window.
  50114. +*
  50115. +* INPUT:
  50116. +* winNum - USB target address decode window number.
  50117. +*
  50118. +* OUTPUT:
  50119. +* pDecWin - USB target window data structure.
  50120. +*
  50121. +* RETURN:
  50122. +* MV_ERROR if register parameters are invalid.
  50123. +*
  50124. +*******************************************************************************/
  50125. +MV_STATUS mvUsbWinGet(int dev, MV_U32 winNum, MV_DEC_WIN *pDecWin)
  50126. +{
  50127. + MV_DEC_WIN_PARAMS winParam;
  50128. + MV_U32 sizeReg, baseReg;
  50129. +
  50130. + /* Parameter checking */
  50131. + if (winNum >= MV_USB_MAX_ADDR_DECODE_WIN)
  50132. + {
  50133. + mvOsPrintf("%s (dev=%d): ERR. Invalid winNum %d\n",
  50134. + __FUNCTION__, dev, winNum);
  50135. + return MV_NOT_SUPPORTED;
  50136. + }
  50137. +
  50138. + baseReg = MV_REG_READ( MV_USB_WIN_BASE_REG(dev, winNum) );
  50139. + sizeReg = MV_REG_READ( MV_USB_WIN_CTRL_REG(dev, winNum) );
  50140. +
  50141. + /* Check if window is enabled */
  50142. + if(sizeReg & MV_USB_WIN_ENABLE_MASK)
  50143. + {
  50144. + pDecWin->enable = MV_TRUE;
  50145. +
  50146. + /* Extract window parameters from registers */
  50147. + winParam.targetId = (sizeReg & MV_USB_WIN_TARGET_MASK) >> MV_USB_WIN_TARGET_OFFSET;
  50148. + winParam.attrib = (sizeReg & MV_USB_WIN_ATTR_MASK) >> MV_USB_WIN_ATTR_OFFSET;
  50149. + winParam.size = (sizeReg & MV_USB_WIN_SIZE_MASK) >> MV_USB_WIN_SIZE_OFFSET;
  50150. + winParam.baseAddr = (baseReg & MV_USB_WIN_BASE_MASK);
  50151. +
  50152. + /* Translate the decode window parameters to address decode struct */
  50153. + if (MV_OK != mvCtrlParamsToAddrDec(&winParam, pDecWin))
  50154. + {
  50155. + mvOsPrintf("Failed to translate register parameters to USB address" \
  50156. + " decode window structure\n");
  50157. + return MV_ERROR;
  50158. + }
  50159. + }
  50160. + else
  50161. + {
  50162. + pDecWin->enable = MV_FALSE;
  50163. + }
  50164. + return MV_OK;
  50165. +}
  50166. +
  50167. +/*******************************************************************************
  50168. +* mvUsbWinInit -
  50169. +*
  50170. +* INPUT:
  50171. +*
  50172. +* OUTPUT:
  50173. +*
  50174. +* RETURN:
  50175. +* MV_ERROR if register parameters are invalid.
  50176. +*
  50177. +*******************************************************************************/
  50178. +MV_STATUS mvUsbWinInit(int dev)
  50179. +{
  50180. + MV_STATUS status;
  50181. + MV_DEC_WIN usbWin;
  50182. + MV_CPU_DEC_WIN cpuAddrDecWin;
  50183. + int winNum;
  50184. + MV_U32 winPrioIndex = 0;
  50185. +
  50186. + /* First disable all address decode windows */
  50187. + for(winNum = 0; winNum < MV_USB_MAX_ADDR_DECODE_WIN; winNum++)
  50188. + {
  50189. + MV_REG_BIT_RESET(MV_USB_WIN_CTRL_REG(dev, winNum), MV_USB_WIN_ENABLE_MASK);
  50190. + }
  50191. +
  50192. + /* Go through all windows in user table until table terminator */
  50193. + winNum = 0;
  50194. + while( (usbAddrDecPrioTab[winPrioIndex] != TBL_TERM) &&
  50195. + (winNum < MV_USB_MAX_ADDR_DECODE_WIN) )
  50196. + {
  50197. + /* first get attributes from CPU If */
  50198. + status = mvCpuIfTargetWinGet(usbAddrDecPrioTab[winPrioIndex],
  50199. + &cpuAddrDecWin);
  50200. +
  50201. + if(MV_NO_SUCH == status)
  50202. + {
  50203. + winPrioIndex++;
  50204. + continue;
  50205. + }
  50206. + if (MV_OK != status)
  50207. + {
  50208. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  50209. + return MV_ERROR;
  50210. + }
  50211. +
  50212. + if (cpuAddrDecWin.enable == MV_TRUE)
  50213. + {
  50214. + usbWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  50215. + usbWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  50216. + usbWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  50217. + usbWin.enable = MV_TRUE;
  50218. + usbWin.target = usbAddrDecPrioTab[winPrioIndex];
  50219. +
  50220. +#if defined(MV645xx) || defined(MV646xx)
  50221. + /* Get the default attributes for that target window */
  50222. + mvCtrlDefAttribGet(usbWin.target, &usbWin.addrWinAttr);
  50223. +#endif /* MV645xx || MV646xx */
  50224. +
  50225. + if(MV_OK != mvUsbWinSet(dev, winNum, &usbWin))
  50226. + {
  50227. + return MV_ERROR;
  50228. + }
  50229. + winNum++;
  50230. + }
  50231. + winPrioIndex++;
  50232. + }
  50233. + return MV_OK;
  50234. +}
  50235. +
  50236. +/*******************************************************************************
  50237. +* mvUsbAddrDecShow - Print the USB address decode map.
  50238. +*
  50239. +* DESCRIPTION:
  50240. +* This function print the USB address decode map.
  50241. +*
  50242. +* INPUT:
  50243. +* None.
  50244. +*
  50245. +* OUTPUT:
  50246. +* None.
  50247. +*
  50248. +* RETURN:
  50249. +* None.
  50250. +*
  50251. +*******************************************************************************/
  50252. +MV_VOID mvUsbAddrDecShow(MV_VOID)
  50253. +{
  50254. + MV_DEC_WIN addrDecWin;
  50255. + int i, winNum;
  50256. +
  50257. + mvOsOutput( "\n" );
  50258. + mvOsOutput( "USB:\n" );
  50259. + mvOsOutput( "----\n" );
  50260. +
  50261. + for(i=0; i<mvCtrlUsbMaxGet(); i++)
  50262. + {
  50263. + mvOsOutput( "Device %d:\n", i);
  50264. +
  50265. + for(winNum = 0; winNum < MV_USB_MAX_ADDR_DECODE_WIN; winNum++)
  50266. + {
  50267. + memset(&addrDecWin, 0, sizeof(MV_DEC_WIN) );
  50268. +
  50269. + mvOsOutput( "win%d - ", winNum );
  50270. +
  50271. + if( mvUsbWinGet(i, winNum, &addrDecWin ) == MV_OK )
  50272. + {
  50273. + if( addrDecWin.enable )
  50274. + {
  50275. + mvOsOutput( "%s base %08x, ",
  50276. + mvCtrlTargetNameGet(addrDecWin.target), addrDecWin.addrWin.baseLow );
  50277. +
  50278. + mvSizePrint( addrDecWin.addrWin.size );
  50279. +
  50280. +#if defined(MV645xx) || defined(MV646xx)
  50281. + switch( addrDecWin.addrWinAttr.swapType)
  50282. + {
  50283. + case MV_BYTE_SWAP:
  50284. + mvOsOutput( "BYTE_SWAP, " );
  50285. + break;
  50286. + case MV_NO_SWAP:
  50287. + mvOsOutput( "NO_SWAP , " );
  50288. + break;
  50289. + case MV_BYTE_WORD_SWAP:
  50290. + mvOsOutput( "BYTE_WORD_SWAP, " );
  50291. + break;
  50292. + case MV_WORD_SWAP:
  50293. + mvOsOutput( "WORD_SWAP, " );
  50294. + break;
  50295. + default:
  50296. + mvOsOutput( "SWAP N/A , " );
  50297. + }
  50298. +
  50299. + switch( addrDecWin.addrWinAttr.cachePolicy )
  50300. + {
  50301. + case NO_COHERENCY:
  50302. + mvOsOutput( "NO_COHERENCY , " );
  50303. + break;
  50304. + case WT_COHERENCY:
  50305. + mvOsOutput( "WT_COHERENCY , " );
  50306. + break;
  50307. + case WB_COHERENCY:
  50308. + mvOsOutput( "WB_COHERENCY , " );
  50309. + break;
  50310. + default:
  50311. + mvOsOutput( "COHERENCY N/A, " );
  50312. + }
  50313. +
  50314. + switch( addrDecWin.addrWinAttr.pcixNoSnoop )
  50315. + {
  50316. + case 0:
  50317. + mvOsOutput( "PCI-X NS inactive, " );
  50318. + break;
  50319. + case 1:
  50320. + mvOsOutput( "PCI-X NS active , " );
  50321. + break;
  50322. + default:
  50323. + mvOsOutput( "PCI-X NS N/A , " );
  50324. + }
  50325. +
  50326. + switch( addrDecWin.addrWinAttr.p2pReq64 )
  50327. + {
  50328. + case 0:
  50329. + mvOsOutput( "REQ64 force" );
  50330. + break;
  50331. + case 1:
  50332. + mvOsOutput( "REQ64 detect" );
  50333. + break;
  50334. + default:
  50335. + mvOsOutput( "REQ64 N/A" );
  50336. + }
  50337. +#endif /* MV645xx || MV646xx */
  50338. + mvOsOutput( "\n" );
  50339. + }
  50340. + else
  50341. + mvOsOutput( "disable\n" );
  50342. + }
  50343. + }
  50344. + }
  50345. +}
  50346. +
  50347. +
  50348. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h
  50349. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h 1970-01-01 01:00:00.000000000 +0100
  50350. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysUsb.h 2011-08-01 14:38:19.000000000 +0200
  50351. @@ -0,0 +1,125 @@
  50352. +/*******************************************************************************
  50353. +Copyright (C) Marvell International Ltd. and its affiliates
  50354. +
  50355. +This software file (the "File") is owned and distributed by Marvell
  50356. +International Ltd. and/or its affiliates ("Marvell") under the following
  50357. +alternative licensing terms. Once you have made an election to distribute the
  50358. +File under one of the following license alternatives, please (i) delete this
  50359. +introductory statement regarding license alternatives, (ii) delete the two
  50360. +license alternatives that you have not elected to use and (iii) preserve the
  50361. +Marvell copyright notice above.
  50362. +
  50363. +********************************************************************************
  50364. +Marvell Commercial License Option
  50365. +
  50366. +If you received this File from Marvell and you have entered into a commercial
  50367. +license agreement (a "Commercial License") with Marvell, the File is licensed
  50368. +to you under the terms of the applicable Commercial License.
  50369. +
  50370. +********************************************************************************
  50371. +Marvell GPL License Option
  50372. +
  50373. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50374. +modify this File in accordance with the terms and conditions of the General
  50375. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  50376. +available along with the File in the license.txt file or by writing to the Free
  50377. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  50378. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  50379. +
  50380. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  50381. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  50382. +DISCLAIMED. The GPL License provides additional details about this warranty
  50383. +disclaimer.
  50384. +********************************************************************************
  50385. +Marvell BSD License Option
  50386. +
  50387. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50388. +modify this File under the following licensing terms.
  50389. +Redistribution and use in source and binary forms, with or without modification,
  50390. +are permitted provided that the following conditions are met:
  50391. +
  50392. + * Redistributions of source code must retain the above copyright notice,
  50393. + this list of conditions and the following disclaimer.
  50394. +
  50395. + * Redistributions in binary form must reproduce the above copyright
  50396. + notice, this list of conditions and the following disclaimer in the
  50397. + documentation and/or other materials provided with the distribution.
  50398. +
  50399. + * Neither the name of Marvell nor the names of its contributors may be
  50400. + used to endorse or promote products derived from this software without
  50401. + specific prior written permission.
  50402. +
  50403. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  50404. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  50405. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  50406. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  50407. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  50408. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  50409. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  50410. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  50411. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  50412. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50413. +
  50414. +*******************************************************************************/
  50415. +
  50416. +#ifndef __INCmvSysUsbh
  50417. +#define __INCmvSysUsbh
  50418. +
  50419. +#ifdef __cplusplus
  50420. +extern "C" {
  50421. +#endif /* __cplusplus */
  50422. +
  50423. +/* includes */
  50424. +#include "usb/mvUsb.h"
  50425. +#include "ctrlEnv/sys/mvCpuIf.h"
  50426. +#include "ctrlEnv/mvCtrlEnvLib.h"
  50427. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  50428. +
  50429. +#define MV_USB_MAX_ADDR_DECODE_WIN 4
  50430. +
  50431. +/*******************************************/
  50432. +/* USB Bridge Registers */
  50433. +/*******************************************/
  50434. +#define MV_USB_BRIDGE_CTRL_REG(dev) (USB_REG_BASE(dev) + 0x300)
  50435. +
  50436. +#define MV_USB_WIN_CTRL_REG(dev, win) (USB_REG_BASE(dev) + 0x320 + ((win)<<4))
  50437. +#define MV_USB_WIN_BASE_REG(dev, win) (USB_REG_BASE(dev) + 0x324 + ((win)<<4))
  50438. +
  50439. +/* BITs in Windows 0-3 Control and Base Registers */
  50440. +#define MV_USB_WIN_ENABLE_BIT 0
  50441. +#define MV_USB_WIN_ENABLE_MASK (1 << MV_USB_WIN_ENABLE_BIT)
  50442. +
  50443. +#define MV_USB_WIN_BURST_WR_LIMIT_BIT 1
  50444. +#define MV_USB_WIN_BURST_WR_LIMIT_MASK (1 << MV_USB_WIN_BURST_WR_LIMIT_BIT)
  50445. +#define MV_USB_WIN_BURST_WR_NO_LIMIT (0 << MV_USB_WIN_BURST_WR_LIMIT_BIT)
  50446. +#define MV_USB_WIN_BURST_WR_32BIT_LIMIT (1 << MV_USB_WIN_BURST_WR_LIMIT_BIT)
  50447. +
  50448. +#define MV_USB_WIN_TARGET_OFFSET 4
  50449. +#define MV_USB_WIN_TARGET_MASK (0xF << MV_USB_WIN_TARGET_OFFSET)
  50450. +
  50451. +#define MV_USB_WIN_ATTR_OFFSET 8
  50452. +#define MV_USB_WIN_ATTR_MASK (0xFF << MV_USB_WIN_ATTR_OFFSET)
  50453. +
  50454. +#define MV_USB_WIN_SIZE_OFFSET 16
  50455. +#define MV_USB_WIN_SIZE_MASK (0xFFFF << MV_USB_WIN_SIZE_OFFSET)
  50456. +
  50457. +#define MV_USB_WIN_BASE_OFFSET 16
  50458. +#define MV_USB_WIN_BASE_MASK (0xFFFF << MV_USB_WIN_BASE_OFFSET)
  50459. +
  50460. +
  50461. +#define MV_USB_BRIDGE_IPG_REG(dev) (USB_REG_BASE(dev) + 0x360)
  50462. +
  50463. +
  50464. +MV_STATUS mvUsbInit(int dev, MV_BOOL isHost);
  50465. +
  50466. +MV_STATUS mvUsbWinInit(int dev);
  50467. +MV_STATUS mvUsbWinSet(int dev, MV_U32 winNum, MV_DEC_WIN *pAddrWin);
  50468. +MV_STATUS mvUsbWinGet(int dev, MV_U32 winNum, MV_DEC_WIN *pAddrWin);
  50469. +
  50470. +void mvUsbAddrDecShow(void);
  50471. +
  50472. +#ifdef __cplusplus
  50473. +}
  50474. +#endif /* __cplusplus */
  50475. +
  50476. +#endif /* __INCmvUsbh */
  50477. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c
  50478. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c 1970-01-01 01:00:00.000000000 +0100
  50479. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.c 2011-08-01 14:38:19.000000000 +0200
  50480. @@ -0,0 +1,662 @@
  50481. +/*******************************************************************************
  50482. +Copyright (C) Marvell International Ltd. and its affiliates
  50483. +
  50484. +This software file (the "File") is owned and distributed by Marvell
  50485. +International Ltd. and/or its affiliates ("Marvell") under the following
  50486. +alternative licensing terms. Once you have made an election to distribute the
  50487. +File under one of the following license alternatives, please (i) delete this
  50488. +introductory statement regarding license alternatives, (ii) delete the two
  50489. +license alternatives that you have not elected to use and (iii) preserve the
  50490. +Marvell copyright notice above.
  50491. +
  50492. +********************************************************************************
  50493. +Marvell Commercial License Option
  50494. +
  50495. +If you received this File from Marvell and you have entered into a commercial
  50496. +license agreement (a "Commercial License") with Marvell, the File is licensed
  50497. +to you under the terms of the applicable Commercial License.
  50498. +
  50499. +********************************************************************************
  50500. +Marvell GPL License Option
  50501. +
  50502. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50503. +modify this File in accordance with the terms and conditions of the General
  50504. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  50505. +available along with the File in the license.txt file or by writing to the Free
  50506. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  50507. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  50508. +
  50509. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  50510. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  50511. +DISCLAIMED. The GPL License provides additional details about this warranty
  50512. +disclaimer.
  50513. +********************************************************************************
  50514. +Marvell BSD License Option
  50515. +
  50516. +If you received this File from Marvell, you may opt to use, redistribute and/or
  50517. +modify this File under the following licensing terms.
  50518. +Redistribution and use in source and binary forms, with or without modification,
  50519. +are permitted provided that the following conditions are met:
  50520. +
  50521. + * Redistributions of source code must retain the above copyright notice,
  50522. + this list of conditions and the following disclaimer.
  50523. +
  50524. + * Redistributions in binary form must reproduce the above copyright
  50525. + notice, this list of conditions and the following disclaimer in the
  50526. + documentation and/or other materials provided with the distribution.
  50527. +
  50528. + * Neither the name of Marvell nor the names of its contributors may be
  50529. + used to endorse or promote products derived from this software without
  50530. + specific prior written permission.
  50531. +
  50532. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  50533. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  50534. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  50535. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  50536. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  50537. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  50538. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  50539. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  50540. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  50541. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  50542. +
  50543. +*******************************************************************************/
  50544. +
  50545. +#include "xor/mvXor.h"
  50546. +#include "mvSysXor.h"
  50547. +
  50548. +/* defines */
  50549. +#ifdef MV_DEBUG
  50550. + #define DB(x) x
  50551. +#else
  50552. + #define DB(x)
  50553. +#endif
  50554. +
  50555. +
  50556. +static MV_STATUS xorWinOverlapDetect(MV_U32 unit,MV_U32 winNum, MV_ADDR_WIN *pAddrWin);
  50557. +
  50558. +MV_TARGET xorAddrDecPrioTap[] =
  50559. +{
  50560. +#if defined(MV_INCLUDE_DEVICE_CS0)
  50561. + DEVICE_CS0,
  50562. +#endif
  50563. +#if defined(MV_INCLUDE_PEX)
  50564. + PEX0_MEM,
  50565. +#endif
  50566. +#if defined(MV_INCLUDE_SDRAM_CS0)
  50567. + SDRAM_CS0,
  50568. +#endif
  50569. +#if defined(MV_INCLUDE_SDRAM_CS1)
  50570. + SDRAM_CS1,
  50571. +#endif
  50572. +#if defined(MV_INCLUDE_SDRAM_CS2)
  50573. + SDRAM_CS2,
  50574. +#endif
  50575. +#if defined(MV_INCLUDE_SDRAM_CS3)
  50576. + SDRAM_CS3,
  50577. +#endif
  50578. +#if defined(MV_INCLUDE_DEVICE_CS1)
  50579. + DEVICE_CS1,
  50580. +#endif
  50581. +#if defined(MV_INCLUDE_CESA)
  50582. + CRYPT_ENG,
  50583. +#endif
  50584. + TBL_TERM
  50585. +};
  50586. +static MV_STATUS mvXorInitWinsUnit (MV_U32 unit)
  50587. +{
  50588. + MV_U32 winNum;
  50589. + MV_XOR_DEC_WIN addrDecWin;
  50590. + MV_CPU_DEC_WIN cpuAddrDecWin;
  50591. + MV_U32 status;
  50592. + MV_U32 winPrioIndex=0;
  50593. +
  50594. + /* Initiate XOR address decode */
  50595. +
  50596. + /* First disable all address decode windows */
  50597. + for(winNum = 0; winNum < XOR_MAX_ADDR_DEC_WIN; winNum++)
  50598. + {
  50599. + mvXorTargetWinEnable(unit,winNum, MV_FALSE);
  50600. + }
  50601. +
  50602. + /* Go through all windows in user table until table terminator */
  50603. + for (winNum = 0; ((xorAddrDecPrioTap[winPrioIndex] != TBL_TERM) &&
  50604. + (winNum < XOR_MAX_ADDR_DEC_WIN));)
  50605. + {
  50606. + /* first get attributes from CPU If */
  50607. + status = mvCpuIfTargetWinGet(xorAddrDecPrioTap[winPrioIndex],
  50608. + &cpuAddrDecWin);
  50609. +
  50610. + if(MV_NO_SUCH == status)
  50611. + {
  50612. + winPrioIndex++;
  50613. + continue;
  50614. + }
  50615. + if (MV_OK != status)
  50616. + {
  50617. + mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__);
  50618. + return MV_ERROR;
  50619. + }
  50620. +
  50621. +
  50622. + if (cpuAddrDecWin.enable == MV_TRUE)
  50623. + {
  50624. +
  50625. + addrDecWin.target = xorAddrDecPrioTap[winPrioIndex];
  50626. + addrDecWin.addrWin.baseLow = cpuAddrDecWin.addrWin.baseLow;
  50627. + addrDecWin.addrWin.baseHigh = cpuAddrDecWin.addrWin.baseHigh;
  50628. + addrDecWin.addrWin.size = cpuAddrDecWin.addrWin.size;
  50629. + addrDecWin.enable = MV_TRUE;
  50630. +
  50631. + if (MV_OK != mvXorTargetWinSet(unit,winNum, &addrDecWin))
  50632. + {
  50633. + DB(mvOsPrintf("mvXorInit: ERR. mvDmaTargetWinSet failed\n"));
  50634. + return MV_ERROR;
  50635. + }
  50636. + winNum++;
  50637. + }
  50638. + winPrioIndex++;
  50639. +
  50640. + }
  50641. +
  50642. + return MV_OK;
  50643. +}
  50644. +
  50645. +
  50646. +/*******************************************************************************
  50647. +* mvXorInit - Initialize XOR engine
  50648. +*
  50649. +* DESCRIPTION:
  50650. +* This function initialize XOR unit. It set the default address decode
  50651. +* windows of the unit.
  50652. +* Note that if the address window is disabled in xorAddrDecMap, the
  50653. +* window parameters will be set but the window will remain disabled.
  50654. +*
  50655. +* INPUT:
  50656. +* None.
  50657. +*
  50658. +* OUTPUT:
  50659. +* None.
  50660. +*
  50661. +* RETURN:
  50662. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  50663. +*******************************************************************************/
  50664. +MV_STATUS mvXorInit (MV_VOID)
  50665. +{
  50666. + MV_U32 i;
  50667. +
  50668. + /* Initiate XOR address decode */
  50669. + for(i = 0; i < MV_XOR_MAX_UNIT; i++)
  50670. + mvXorInitWinsUnit(i);
  50671. +
  50672. + mvXorHalInit(MV_XOR_MAX_CHAN);
  50673. +
  50674. + return MV_OK;
  50675. +}
  50676. +
  50677. +/*******************************************************************************
  50678. +* mvXorTargetWinSet - Set XOR target address window
  50679. +*
  50680. +* DESCRIPTION:
  50681. +* This function sets a peripheral target (e.g. SDRAM bank0, PCI_MEM0)
  50682. +* address window. After setting this target window, the XOR will be
  50683. +* able to access the target within the address window.
  50684. +*
  50685. +* INPUT:
  50686. +* winNum - One of the possible XOR memory decode windows.
  50687. +* target - Peripheral target enumerator.
  50688. +* base - Window base address.
  50689. +* size - Window size.
  50690. +* enable - Window enable/disable.
  50691. +*
  50692. +* OUTPUT:
  50693. +* None.
  50694. +*
  50695. +* RETURN:
  50696. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  50697. +*
  50698. +*******************************************************************************/
  50699. +MV_STATUS mvXorTargetWinSet(MV_U32 unit, MV_U32 winNum, MV_XOR_DEC_WIN *pAddrDecWin)
  50700. +{
  50701. + MV_DEC_REGS xorDecRegs;
  50702. + MV_TARGET_ATTRIB targetAttribs;
  50703. + MV_U32 chan;
  50704. +
  50705. + /* Parameter checking */
  50706. + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
  50707. + {
  50708. + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__, winNum));
  50709. + return MV_BAD_PARAM;
  50710. + }
  50711. + if (pAddrDecWin == NULL)
  50712. + {
  50713. + DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __FUNCTION__ ));
  50714. + return MV_BAD_PTR;
  50715. + }
  50716. + /* Check if the requested window overlaps with current windows */
  50717. + if (MV_TRUE == xorWinOverlapDetect(unit, winNum, &pAddrDecWin->addrWin))
  50718. + {
  50719. + DB(mvOsPrintf("%s: ERR. Window %d overlap\n",__FUNCTION__,winNum));
  50720. + return MV_ERROR;
  50721. + }
  50722. +
  50723. + xorDecRegs.baseReg = MV_REG_READ(XOR_BASE_ADDR_REG(unit,winNum));
  50724. + xorDecRegs.sizeReg = MV_REG_READ(XOR_SIZE_MASK_REG(unit,winNum));
  50725. +
  50726. + /* Get Base Address and size registers values */
  50727. + if(MV_OK != mvCtrlAddrDecToReg(&pAddrDecWin->addrWin, &xorDecRegs))
  50728. + {
  50729. + DB(mvOsPrintf("%s: ERR. Invalid addr dec window\n",__FUNCTION__));
  50730. + return MV_BAD_PARAM;
  50731. + }
  50732. +
  50733. +
  50734. + mvCtrlAttribGet(pAddrDecWin->target,&targetAttribs);
  50735. +
  50736. + /* set attributes */
  50737. + xorDecRegs.baseReg &= ~XEBARX_ATTR_MASK;
  50738. + xorDecRegs.baseReg |= targetAttribs.attrib << XEBARX_ATTR_OFFS;
  50739. + /* set target ID */
  50740. + xorDecRegs.baseReg &= ~XEBARX_TARGET_MASK;
  50741. + xorDecRegs.baseReg |= targetAttribs.targetId << XEBARX_TARGET_OFFS;
  50742. +
  50743. +
  50744. + /* Write to address decode Base Address Register */
  50745. + MV_REG_WRITE(XOR_BASE_ADDR_REG(unit,winNum), xorDecRegs.baseReg);
  50746. +
  50747. + /* Write to Size Register */
  50748. + MV_REG_WRITE(XOR_SIZE_MASK_REG(unit,winNum), xorDecRegs.sizeReg);
  50749. +
  50750. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
  50751. + {
  50752. + if (pAddrDecWin->enable)
  50753. + {
  50754. + MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit,chan),
  50755. + XEXWCR_WIN_EN_MASK(winNum));
  50756. + }
  50757. + else
  50758. + {
  50759. + MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit,chan),
  50760. + XEXWCR_WIN_EN_MASK(winNum));
  50761. + }
  50762. + }
  50763. + return MV_OK;
  50764. +}
  50765. +
  50766. +/*******************************************************************************
  50767. +* mvXorTargetWinGet - Get xor peripheral target address window.
  50768. +*
  50769. +* DESCRIPTION:
  50770. +* Get xor peripheral target address window.
  50771. +*
  50772. +* INPUT:
  50773. +* winNum - One of the possible XOR memory decode windows.
  50774. +*
  50775. +* OUTPUT:
  50776. +* base - Window base address.
  50777. +* size - Window size.
  50778. +* enable - window enable/disable.
  50779. +*
  50780. +* RETURN:
  50781. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  50782. +*
  50783. +*******************************************************************************/
  50784. +MV_STATUS mvXorTargetWinGet(MV_U32 unit,MV_U32 winNum, MV_XOR_DEC_WIN *pAddrDecWin)
  50785. +{
  50786. + MV_DEC_REGS xorDecRegs;
  50787. + MV_TARGET_ATTRIB targetAttrib;
  50788. + MV_U32 chan=0,chanWinEn;
  50789. +
  50790. + /* Parameter checking */
  50791. + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
  50792. + {
  50793. + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n",__FUNCTION__ , winNum));
  50794. + return MV_ERROR;
  50795. + }
  50796. +
  50797. + if (NULL == pAddrDecWin)
  50798. + {
  50799. + DB(mvOsPrintf("%s: ERR. pAddrDecWin is NULL pointer\n", __FUNCTION__ ));
  50800. + return MV_BAD_PTR;
  50801. + }
  50802. +
  50803. + chanWinEn = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,0)) & XEXWCR_WIN_EN_MASK(winNum);
  50804. +
  50805. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++) /* we should scan here all channels per unit */
  50806. + {
  50807. + /* Check if enable bit is equal for all channels */
  50808. + if ((MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan)) &
  50809. + XEXWCR_WIN_EN_MASK(winNum)) != chanWinEn)
  50810. + {
  50811. + mvOsPrintf("%s: ERR. Window enable field must be equal in "
  50812. + "all channels(chan=%d)\n",__FUNCTION__, chan);
  50813. + return MV_ERROR;
  50814. + }
  50815. + }
  50816. +
  50817. +
  50818. +
  50819. + xorDecRegs.baseReg = MV_REG_READ(XOR_BASE_ADDR_REG(unit,winNum));
  50820. + xorDecRegs.sizeReg = MV_REG_READ(XOR_SIZE_MASK_REG(unit,winNum));
  50821. +
  50822. + if (MV_OK != mvCtrlRegToAddrDec(&xorDecRegs, &pAddrDecWin->addrWin))
  50823. + {
  50824. + mvOsPrintf("%s: ERR. mvCtrlRegToAddrDec failed\n", __FUNCTION__);
  50825. + return MV_ERROR;
  50826. + }
  50827. +
  50828. + /* attrib and targetId */
  50829. + targetAttrib.attrib =
  50830. + (xorDecRegs.baseReg & XEBARX_ATTR_MASK) >> XEBARX_ATTR_OFFS;
  50831. + targetAttrib.targetId =
  50832. + (xorDecRegs.baseReg & XEBARX_TARGET_MASK) >> XEBARX_TARGET_OFFS;
  50833. +
  50834. +
  50835. + pAddrDecWin->target = mvCtrlTargetGet(&targetAttrib);
  50836. +
  50837. + if(chanWinEn)
  50838. + {
  50839. + pAddrDecWin->enable = MV_TRUE;
  50840. + }
  50841. + else pAddrDecWin->enable = MV_FALSE;
  50842. +
  50843. + return MV_OK;
  50844. +}
  50845. +
  50846. +/*******************************************************************************
  50847. +* mvXorTargetWinEnable - Enable/disable a Xor address decode window
  50848. +*
  50849. +* DESCRIPTION:
  50850. +* This function enable/disable a XOR address decode window.
  50851. +* if parameter 'enable' == MV_TRUE the routine will enable the
  50852. +* window, thus enabling XOR accesses (before enabling the window it is
  50853. +* tested for overlapping). Otherwise, the window will be disabled.
  50854. +*
  50855. +* INPUT:
  50856. +* winNum - Decode window number.
  50857. +* enable - Enable/disable parameter.
  50858. +*
  50859. +* OUTPUT:
  50860. +* None.
  50861. +*
  50862. +* RETURN:
  50863. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  50864. +*
  50865. +*******************************************************************************/
  50866. +MV_STATUS mvXorTargetWinEnable(MV_U32 unit,MV_U32 winNum, MV_BOOL enable)
  50867. +{
  50868. + MV_XOR_DEC_WIN addrDecWin;
  50869. + MV_U32 chan;
  50870. +
  50871. + /* Parameter checking */
  50872. + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
  50873. + {
  50874. + DB(mvOsPrintf("%s: ERR. Invalid winNum%d\n", __FUNCTION__, winNum));
  50875. + return MV_ERROR;
  50876. + }
  50877. +
  50878. + if (enable == MV_TRUE)
  50879. + {
  50880. + /* Get current window */
  50881. + if (MV_OK != mvXorTargetWinGet(unit,winNum, &addrDecWin))
  50882. + {
  50883. + DB(mvOsPrintf("%s: ERR. targetWinGet fail\n", __FUNCTION__));
  50884. + return MV_ERROR;
  50885. + }
  50886. +
  50887. + /* Check for overlapping */
  50888. + if (MV_TRUE == xorWinOverlapDetect(unit,winNum, &(addrDecWin.addrWin)))
  50889. + {
  50890. + /* Overlap detected */
  50891. + DB(mvOsPrintf("%s: ERR. Overlap detected\n", __FUNCTION__));
  50892. + return MV_ERROR;
  50893. + }
  50894. +
  50895. + /* No Overlap. Enable address decode target window */
  50896. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
  50897. + {
  50898. + MV_REG_BIT_SET(XOR_WINDOW_CTRL_REG(unit,chan),
  50899. + XEXWCR_WIN_EN_MASK(winNum));
  50900. + }
  50901. +
  50902. + }
  50903. + else
  50904. + {
  50905. + /* Disable address decode target window */
  50906. +
  50907. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
  50908. + {
  50909. + MV_REG_BIT_RESET(XOR_WINDOW_CTRL_REG(unit,chan),
  50910. + XEXWCR_WIN_EN_MASK(winNum));
  50911. + }
  50912. +
  50913. + }
  50914. +
  50915. + return MV_OK;
  50916. +}
  50917. +
  50918. +/*******************************************************************************
  50919. +* mvXorSetProtWinSet - Configure access attributes of a XOR engine
  50920. +* to one of the XOR memory windows.
  50921. +*
  50922. +* DESCRIPTION:
  50923. +* Each engine can be configured with access attributes for each of the
  50924. +* memory spaces. This function sets access attributes
  50925. +* to a given window for the given engine
  50926. +*
  50927. +* INPUTS:
  50928. +* chan - One of the possible engines.
  50929. +* winNum - One of the possible XOR memory spaces.
  50930. +* access - Protection access rights.
  50931. +* write - Write rights.
  50932. +*
  50933. +* OUTPUT:
  50934. +* None.
  50935. +*
  50936. +* RETURN:
  50937. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  50938. +*
  50939. +*******************************************************************************/
  50940. +MV_STATUS mvXorProtWinSet (MV_U32 unit,MV_U32 chan, MV_U32 winNum, MV_BOOL access,
  50941. + MV_BOOL write)
  50942. +{
  50943. + MV_U32 temp;
  50944. +
  50945. + /* Parameter checking */
  50946. + if (chan >= MV_XOR_MAX_CHAN_PER_UNIT)
  50947. + {
  50948. + DB(mvOsPrintf("%s: ERR. Invalid chan num %d\n", __FUNCTION__ , chan));
  50949. + return MV_BAD_PARAM;
  50950. + }
  50951. + if (winNum >= XOR_MAX_ADDR_DEC_WIN)
  50952. + {
  50953. + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n", __FUNCTION__, winNum));
  50954. + return MV_BAD_PARAM;
  50955. + }
  50956. +
  50957. + temp = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan)) &
  50958. + (~XEXWCR_WIN_ACC_MASK(winNum));
  50959. +
  50960. + /* if access is disable */
  50961. + if (!access)
  50962. + {
  50963. + /* disable access */
  50964. + temp |= XEXWCR_WIN_ACC_NO_ACC(winNum);
  50965. + }
  50966. + /* if access is enable */
  50967. + else
  50968. + {
  50969. + /* if write is enable */
  50970. + if (write)
  50971. + {
  50972. + /* enable write */
  50973. + temp |= XEXWCR_WIN_ACC_RW(winNum);
  50974. + }
  50975. + /* if write is disable */
  50976. + else
  50977. + {
  50978. + /* disable write */
  50979. + temp |= XEXWCR_WIN_ACC_RO(winNum);
  50980. + }
  50981. + }
  50982. + MV_REG_WRITE(XOR_WINDOW_CTRL_REG(unit,chan),temp);
  50983. + return MV_OK;
  50984. +}
  50985. +
  50986. +/*******************************************************************************
  50987. +* mvXorPciRemap - Set XOR remap register for PCI address windows.
  50988. +*
  50989. +* DESCRIPTION:
  50990. +* only Windows 0-3 can be remapped.
  50991. +*
  50992. +* INPUT:
  50993. +* winNum - window number
  50994. +* pAddrDecWin - pointer to address space window structure
  50995. +* OUTPUT:
  50996. +* None.
  50997. +*
  50998. +* RETURN:
  50999. +* MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
  51000. +*
  51001. +*******************************************************************************/
  51002. +MV_STATUS mvXorPciRemap(MV_U32 unit,MV_U32 winNum, MV_U32 addrHigh)
  51003. +{
  51004. + /* Parameter checking */
  51005. + if (winNum >= XOR_MAX_REMAP_WIN)
  51006. + {
  51007. + DB(mvOsPrintf("%s: ERR. Invalid win num %d\n", __FUNCTION__, winNum));
  51008. + return MV_BAD_PARAM;
  51009. + }
  51010. +
  51011. + MV_REG_WRITE(XOR_HIGH_ADDR_REMAP_REG(unit,winNum), addrHigh);
  51012. +
  51013. + return MV_OK;
  51014. +}
  51015. +
  51016. +/*******************************************************************************
  51017. +* xorWinOverlapDetect - Detect XOR address windows overlaping
  51018. +*
  51019. +* DESCRIPTION:
  51020. +* An unpredicted behaviour is expected in case XOR address decode
  51021. +* windows overlaps.
  51022. +* This function detects XOR address decode windows overlaping of a
  51023. +* specified window. The function does not check the window itself for
  51024. +* overlaping. The function also skipps disabled address decode windows.
  51025. +*
  51026. +* INPUT:
  51027. +* winNum - address decode window number.
  51028. +* pAddrDecWin - An address decode window struct.
  51029. +*
  51030. +* OUTPUT:
  51031. +* None.
  51032. +*
  51033. +* RETURN:
  51034. +* MV_TRUE if the given address window overlap current address
  51035. +* decode map, MV_FALSE otherwise, MV_ERROR if reading invalid data
  51036. +* from registers.
  51037. +*
  51038. +*******************************************************************************/
  51039. +static MV_STATUS xorWinOverlapDetect(MV_U32 unit,MV_U32 winNum, MV_ADDR_WIN *pAddrWin)
  51040. +{
  51041. + MV_U32 baseAddrEnableReg;
  51042. + MV_U32 winNumIndex,chan;
  51043. + MV_XOR_DEC_WIN addrDecWin;
  51044. +
  51045. + if (pAddrWin == NULL)
  51046. + {
  51047. + DB(mvOsPrintf("%s: ERR. pAddrWin is NULL pointer\n", __FUNCTION__ ));
  51048. + return MV_BAD_PTR;
  51049. + }
  51050. +
  51051. + for (chan = 0; chan < MV_XOR_MAX_CHAN_PER_UNIT; chan++)
  51052. + {
  51053. + /* Read base address enable register. Do not check disabled windows */
  51054. + baseAddrEnableReg = MV_REG_READ(XOR_WINDOW_CTRL_REG(unit,chan));
  51055. +
  51056. + for (winNumIndex = 0; winNumIndex < XOR_MAX_ADDR_DEC_WIN; winNumIndex++)
  51057. + {
  51058. + /* Do not check window itself */
  51059. + if (winNumIndex == winNum)
  51060. + {
  51061. + continue;
  51062. + }
  51063. +
  51064. + /* Do not check disabled windows */
  51065. + if ((baseAddrEnableReg & XEXWCR_WIN_EN_MASK(winNumIndex)) == 0)
  51066. + {
  51067. + continue;
  51068. + }
  51069. +
  51070. + /* Get window parameters */
  51071. + if (MV_OK != mvXorTargetWinGet(unit,winNumIndex, &addrDecWin))
  51072. + {
  51073. + DB(mvOsPrintf("%s: ERR. TargetWinGet failed\n", __FUNCTION__ ));
  51074. + return MV_ERROR;
  51075. + }
  51076. +
  51077. + if (MV_TRUE == ctrlWinOverlapTest(pAddrWin, &(addrDecWin.addrWin)))
  51078. + {
  51079. + return MV_TRUE;
  51080. + }
  51081. + }
  51082. + }
  51083. +
  51084. + return MV_FALSE;
  51085. +}
  51086. +
  51087. +static MV_VOID mvXorAddrDecShowUnit(MV_U32 unit)
  51088. +{
  51089. + MV_XOR_DEC_WIN win;
  51090. + int i;
  51091. +
  51092. + mvOsOutput( "\n" );
  51093. + mvOsOutput( "XOR %d:\n", unit );
  51094. + mvOsOutput( "----\n" );
  51095. +
  51096. + for( i = 0; i < XOR_MAX_ADDR_DEC_WIN; i++ )
  51097. + {
  51098. + memset( &win, 0, sizeof(MV_XOR_DEC_WIN) );
  51099. +
  51100. + mvOsOutput( "win%d - ", i );
  51101. +
  51102. + if( mvXorTargetWinGet(unit, i, &win ) == MV_OK )
  51103. + {
  51104. + if( win.enable )
  51105. + {
  51106. + mvOsOutput( "%s base %x, ",
  51107. + mvCtrlTargetNameGet(win.target), win.addrWin.baseLow );
  51108. +
  51109. + mvSizePrint( win.addrWin.size );
  51110. +
  51111. + mvOsOutput( "\n" );
  51112. + }
  51113. + else
  51114. + mvOsOutput( "disable\n" );
  51115. + }
  51116. + }
  51117. +}
  51118. +
  51119. +/*******************************************************************************
  51120. +* mvXorAddrDecShow - Print the XOR address decode map.
  51121. +*
  51122. +* DESCRIPTION:
  51123. +* This function print the XOR address decode map.
  51124. +*
  51125. +* INPUT:
  51126. +* None.
  51127. +*
  51128. +* OUTPUT:
  51129. +* None.
  51130. +*
  51131. +* RETURN:
  51132. +* None.
  51133. +*
  51134. +*******************************************************************************/
  51135. +MV_VOID mvXorAddrDecShow(MV_VOID)
  51136. +{
  51137. + int i;
  51138. +
  51139. + for( i = 0; i < MV_XOR_MAX_UNIT; i++ )
  51140. + mvXorAddrDecShowUnit(i);
  51141. +
  51142. +}
  51143. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h
  51144. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h 1970-01-01 01:00:00.000000000 +0100
  51145. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/ctrlEnv/sys/mvSysXor.h 2011-08-01 14:38:19.000000000 +0200
  51146. @@ -0,0 +1,140 @@
  51147. +/*******************************************************************************
  51148. +Copyright (C) Marvell International Ltd. and its affiliates
  51149. +
  51150. +This software file (the "File") is owned and distributed by Marvell
  51151. +International Ltd. and/or its affiliates ("Marvell") under the following
  51152. +alternative licensing terms. Once you have made an election to distribute the
  51153. +File under one of the following license alternatives, please (i) delete this
  51154. +introductory statement regarding license alternatives, (ii) delete the two
  51155. +license alternatives that you have not elected to use and (iii) preserve the
  51156. +Marvell copyright notice above.
  51157. +
  51158. +********************************************************************************
  51159. +Marvell Commercial License Option
  51160. +
  51161. +If you received this File from Marvell and you have entered into a commercial
  51162. +license agreement (a "Commercial License") with Marvell, the File is licensed
  51163. +to you under the terms of the applicable Commercial License.
  51164. +
  51165. +********************************************************************************
  51166. +Marvell GPL License Option
  51167. +
  51168. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51169. +modify this File in accordance with the terms and conditions of the General
  51170. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51171. +available along with the File in the license.txt file or by writing to the Free
  51172. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51173. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51174. +
  51175. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51176. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51177. +DISCLAIMED. The GPL License provides additional details about this warranty
  51178. +disclaimer.
  51179. +********************************************************************************
  51180. +Marvell BSD License Option
  51181. +
  51182. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51183. +modify this File under the following licensing terms.
  51184. +Redistribution and use in source and binary forms, with or without modification,
  51185. +are permitted provided that the following conditions are met:
  51186. +
  51187. + * Redistributions of source code must retain the above copyright notice,
  51188. + this list of conditions and the following disclaimer.
  51189. +
  51190. + * Redistributions in binary form must reproduce the above copyright
  51191. + notice, this list of conditions and the following disclaimer in the
  51192. + documentation and/or other materials provided with the distribution.
  51193. +
  51194. + * Neither the name of Marvell nor the names of its contributors may be
  51195. + used to endorse or promote products derived from this software without
  51196. + specific prior written permission.
  51197. +
  51198. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  51199. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  51200. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  51201. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  51202. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  51203. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  51204. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  51205. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  51206. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  51207. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  51208. +
  51209. +*******************************************************************************/
  51210. +
  51211. +#ifndef __INCMVSysXorh
  51212. +#define __INCMVSysXorh
  51213. +
  51214. +
  51215. +#ifdef __cplusplus
  51216. +extern "C" {
  51217. +#endif
  51218. +
  51219. +#include "ctrlEnv/sys/mvCpuIf.h"
  51220. +
  51221. +#include "ctrlEnv/mvCtrlEnvLib.h"
  51222. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  51223. +
  51224. +#define XOR_MAX_ADDR_DEC_WIN 8 /* Maximum address decode windows */
  51225. +#define XOR_MAX_REMAP_WIN 4 /* Maximum address arbiter windows */
  51226. +
  51227. +/* XOR Engine Address Decoding Register Map */
  51228. +#define XOR_WINDOW_CTRL_REG(unit,chan) (XOR_UNIT_BASE(unit)+(0x240 + ((chan) * 4)))
  51229. +#define XOR_BASE_ADDR_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x250 + ((winNum) * 4)))
  51230. +#define XOR_SIZE_MASK_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x270 + ((winNum) * 4)))
  51231. +#define XOR_HIGH_ADDR_REMAP_REG(unit,winNum) (XOR_UNIT_BASE(unit)+(0x290 + ((winNum) * 4)))
  51232. +
  51233. +/* XOR Engine [0..1] Window Control Registers (XExWCR) */
  51234. +#define XEXWCR_WIN_EN_OFFS(winNum) (winNum)
  51235. +#define XEXWCR_WIN_EN_MASK(winNum) (1 << (XEXWCR_WIN_EN_OFFS(winNum)))
  51236. +#define XEXWCR_WIN_EN_ENABLE(winNum) (1 << (XEXWCR_WIN_EN_OFFS(winNum)))
  51237. +#define XEXWCR_WIN_EN_DISABLE(winNum) (0 << (XEXWCR_WIN_EN_OFFS(winNum)))
  51238. +
  51239. +#define XEXWCR_WIN_ACC_OFFS(winNum) ((2 * winNum) + 16)
  51240. +#define XEXWCR_WIN_ACC_MASK(winNum) (3 << (XEXWCR_WIN_ACC_OFFS(winNum)))
  51241. +#define XEXWCR_WIN_ACC_NO_ACC(winNum) (0 << (XEXWCR_WIN_ACC_OFFS(winNum)))
  51242. +#define XEXWCR_WIN_ACC_RO(winNum) (1 << (XEXWCR_WIN_ACC_OFFS(winNum)))
  51243. +#define XEXWCR_WIN_ACC_RW(winNum) (3 << (XEXWCR_WIN_ACC_OFFS(winNum)))
  51244. +
  51245. +/* XOR Engine Base Address Registers (XEBARx) */
  51246. +#define XEBARX_TARGET_OFFS (0)
  51247. +#define XEBARX_TARGET_MASK (0xF << XEBARX_TARGET_OFFS)
  51248. +#define XEBARX_ATTR_OFFS (8)
  51249. +#define XEBARX_ATTR_MASK (0xFF << XEBARX_ATTR_OFFS)
  51250. +#define XEBARX_BASE_OFFS (16)
  51251. +#define XEBARX_BASE_MASK (0xFFFF << XEBARX_BASE_OFFS)
  51252. +
  51253. +/* XOR Engine Size Mask Registers (XESMRx) */
  51254. +#define XESMRX_SIZE_MASK_OFFS (16)
  51255. +#define XESMRX_SIZE_MASK_MASK (0xFFFF << XESMRX_SIZE_MASK_OFFS)
  51256. +
  51257. +/* XOR Engine High Address Remap Register (XEHARRx1) */
  51258. +#define XEHARRX_REMAP_OFFS (0)
  51259. +#define XEHARRX_REMAP_MASK (0xFFFFFFFF << XEHARRX_REMAP_OFFS)
  51260. +
  51261. +typedef struct _mvXorDecWin
  51262. +{
  51263. + MV_TARGET target;
  51264. + MV_ADDR_WIN addrWin; /* An address window*/
  51265. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  51266. +
  51267. +}MV_XOR_DEC_WIN;
  51268. +
  51269. +MV_STATUS mvXorInit (MV_VOID);
  51270. +MV_STATUS mvXorTargetWinSet(MV_U32 unit, MV_U32 winNum,
  51271. + MV_XOR_DEC_WIN *pAddrDecWin);
  51272. +MV_STATUS mvXorTargetWinGet(MV_U32 unit, MV_U32 winNum,
  51273. + MV_XOR_DEC_WIN *pAddrDecWin);
  51274. +MV_STATUS mvXorTargetWinEnable(MV_U32 unit,
  51275. + MV_U32 winNum, MV_BOOL enable);
  51276. +MV_STATUS mvXorProtWinSet (MV_U32 unit,MV_U32 chan, MV_U32 winNum, MV_BOOL access,
  51277. + MV_BOOL write);
  51278. +MV_STATUS mvXorPciRemap(MV_U32 unit, MV_U32 winNum, MV_U32 addrHigh);
  51279. +
  51280. +MV_VOID mvXorAddrDecShow(MV_VOID);
  51281. +
  51282. +#ifdef __cplusplus
  51283. +}
  51284. +#endif
  51285. +
  51286. +#endif
  51287. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c
  51288. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c 1970-01-01 01:00:00.000000000 +0100
  51289. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.c 2011-08-01 14:38:19.000000000 +0200
  51290. @@ -0,0 +1,75 @@
  51291. +/*******************************************************************************
  51292. +Copyright (C) Marvell International Ltd. and its affiliates
  51293. +
  51294. +This software file (the "File") is owned and distributed by Marvell
  51295. +International Ltd. and/or its affiliates ("Marvell") under the following
  51296. +alternative licensing terms. Once you have made an election to distribute the
  51297. +File under one of the following license alternatives, please (i) delete this
  51298. +introductory statement regarding license alternatives, (ii) delete the two
  51299. +license alternatives that you have not elected to use and (iii) preserve the
  51300. +Marvell copyright notice above.
  51301. +
  51302. +********************************************************************************
  51303. +Marvell Commercial License Option
  51304. +
  51305. +If you received this File from Marvell and you have entered into a commercial
  51306. +license agreement (a "Commercial License") with Marvell, the File is licensed
  51307. +to you under the terms of the applicable Commercial License.
  51308. +
  51309. +********************************************************************************
  51310. +Marvell GPL License Option
  51311. +
  51312. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51313. +modify this File in accordance with the terms and conditions of the General
  51314. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51315. +available along with the File in the license.txt file or by writing to the Free
  51316. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51317. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51318. +
  51319. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51320. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51321. +DISCLAIMED. The GPL License provides additional details about this warranty
  51322. +disclaimer.
  51323. +********************************************************************************
  51324. +Marvell BSD License Option
  51325. +
  51326. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51327. +modify this File under the following licensing terms.
  51328. +Redistribution and use in source and binary forms, with or without modification,
  51329. +are permitted provided that the following conditions are met:
  51330. +
  51331. + * Redistributions of source code must retain the above copyright notice,
  51332. + this list of conditions and the following disclaimer.
  51333. +
  51334. + * Redistributions in binary form must reproduce the above copyright
  51335. + notice, this list of conditions and the following disclaimer in the
  51336. + documentation and/or other materials provided with the distribution.
  51337. +
  51338. + * Neither the name of Marvell nor the names of its contributors may be
  51339. + used to endorse or promote products derived from this software without
  51340. + specific prior written permission.
  51341. +
  51342. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  51343. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  51344. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  51345. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  51346. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  51347. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  51348. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  51349. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  51350. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  51351. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  51352. +
  51353. +*******************************************************************************/
  51354. +
  51355. +#include "device/mvDevice.h"
  51356. +
  51357. +/* defines */
  51358. +#ifdef MV_DEBUG
  51359. + #define DB(x) x
  51360. +#else
  51361. + #define DB(x)
  51362. +#endif
  51363. +
  51364. +
  51365. +
  51366. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h
  51367. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h 1970-01-01 01:00:00.000000000 +0100
  51368. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDevice.h 2011-08-01 14:38:19.000000000 +0200
  51369. @@ -0,0 +1,74 @@
  51370. +/*******************************************************************************
  51371. +Copyright (C) Marvell International Ltd. and its affiliates
  51372. +
  51373. +This software file (the "File") is owned and distributed by Marvell
  51374. +International Ltd. and/or its affiliates ("Marvell") under the following
  51375. +alternative licensing terms. Once you have made an election to distribute the
  51376. +File under one of the following license alternatives, please (i) delete this
  51377. +introductory statement regarding license alternatives, (ii) delete the two
  51378. +license alternatives that you have not elected to use and (iii) preserve the
  51379. +Marvell copyright notice above.
  51380. +
  51381. +********************************************************************************
  51382. +Marvell Commercial License Option
  51383. +
  51384. +If you received this File from Marvell and you have entered into a commercial
  51385. +license agreement (a "Commercial License") with Marvell, the File is licensed
  51386. +to you under the terms of the applicable Commercial License.
  51387. +
  51388. +********************************************************************************
  51389. +Marvell GPL License Option
  51390. +
  51391. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51392. +modify this File in accordance with the terms and conditions of the General
  51393. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51394. +available along with the File in the license.txt file or by writing to the Free
  51395. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51396. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51397. +
  51398. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51399. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51400. +DISCLAIMED. The GPL License provides additional details about this warranty
  51401. +disclaimer.
  51402. +********************************************************************************
  51403. +Marvell BSD License Option
  51404. +
  51405. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51406. +modify this File under the following licensing terms.
  51407. +Redistribution and use in source and binary forms, with or without modification,
  51408. +are permitted provided that the following conditions are met:
  51409. +
  51410. + * Redistributions of source code must retain the above copyright notice,
  51411. + this list of conditions and the following disclaimer.
  51412. +
  51413. + * Redistributions in binary form must reproduce the above copyright
  51414. + notice, this list of conditions and the following disclaimer in the
  51415. + documentation and/or other materials provided with the distribution.
  51416. +
  51417. + * Neither the name of Marvell nor the names of its contributors may be
  51418. + used to endorse or promote products derived from this software without
  51419. + specific prior written permission.
  51420. +
  51421. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  51422. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  51423. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  51424. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  51425. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  51426. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  51427. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  51428. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  51429. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  51430. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  51431. +
  51432. +*******************************************************************************/
  51433. +
  51434. +#ifndef __INCmvDeviceH
  51435. +#define __INCmvDeviceH
  51436. +
  51437. +#include "mvCommon.h"
  51438. +#include "mvOs.h"
  51439. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  51440. +#include "device/mvDeviceRegs.h"
  51441. +
  51442. +
  51443. +#endif /* #ifndef __INCmvDeviceH */
  51444. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h
  51445. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h 1970-01-01 01:00:00.000000000 +0100
  51446. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/kw_family/device/mvDeviceRegs.h 2011-08-01 14:38:19.000000000 +0200
  51447. @@ -0,0 +1,101 @@
  51448. +/*******************************************************************************
  51449. +Copyright (C) Marvell International Ltd. and its affiliates
  51450. +
  51451. +This software file (the "File") is owned and distributed by Marvell
  51452. +International Ltd. and/or its affiliates ("Marvell") under the following
  51453. +alternative licensing terms. Once you have made an election to distribute the
  51454. +File under one of the following license alternatives, please (i) delete this
  51455. +introductory statement regarding license alternatives, (ii) delete the two
  51456. +license alternatives that you have not elected to use and (iii) preserve the
  51457. +Marvell copyright notice above.
  51458. +
  51459. +********************************************************************************
  51460. +Marvell Commercial License Option
  51461. +
  51462. +If you received this File from Marvell and you have entered into a commercial
  51463. +license agreement (a "Commercial License") with Marvell, the File is licensed
  51464. +to you under the terms of the applicable Commercial License.
  51465. +
  51466. +********************************************************************************
  51467. +Marvell GPL License Option
  51468. +
  51469. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51470. +modify this File in accordance with the terms and conditions of the General
  51471. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51472. +available along with the File in the license.txt file or by writing to the Free
  51473. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51474. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51475. +
  51476. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51477. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51478. +DISCLAIMED. The GPL License provides additional details about this warranty
  51479. +disclaimer.
  51480. +********************************************************************************
  51481. +Marvell BSD License Option
  51482. +
  51483. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51484. +modify this File under the following licensing terms.
  51485. +Redistribution and use in source and binary forms, with or without modification,
  51486. +are permitted provided that the following conditions are met:
  51487. +
  51488. + * Redistributions of source code must retain the above copyright notice,
  51489. + this list of conditions and the following disclaimer.
  51490. +
  51491. + * Redistributions in binary form must reproduce the above copyright
  51492. + notice, this list of conditions and the following disclaimer in the
  51493. + documentation and/or other materials provided with the distribution.
  51494. +
  51495. + * Neither the name of Marvell nor the names of its contributors may be
  51496. + used to endorse or promote products derived from this software without
  51497. + specific prior written permission.
  51498. +
  51499. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  51500. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  51501. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  51502. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  51503. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  51504. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  51505. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  51506. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  51507. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  51508. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  51509. +
  51510. +*******************************************************************************/
  51511. +
  51512. +#ifndef __INCmvDeviceRegsH
  51513. +#define __INCmvDeviceRegsH
  51514. +
  51515. +#ifndef MV_ASMLANGUAGE
  51516. +#include "ctrlEnv/mvCtrlEnvLib.h"
  51517. +/* This enumerator describes the Marvell controller possible devices that */
  51518. +/* can be connected to its device interface. */
  51519. +typedef enum _mvDevice
  51520. +{
  51521. +#if defined(MV_INCLUDE_DEVICE_CS0)
  51522. + DEV_CS0 = 0, /* Device connected to dev CS[0] */
  51523. +#endif
  51524. +#if defined(MV_INCLUDE_DEVICE_CS1)
  51525. + DEV_CS1 = 1, /* Device connected to dev CS[1] */
  51526. +#endif
  51527. +#if defined(MV_INCLUDE_DEVICE_CS2)
  51528. + DEV_CS2 = 2, /* Device connected to dev CS[2] */
  51529. +#endif
  51530. +#if defined(MV_INCLUDE_DEVICE_CS3)
  51531. + DEV_CS3 = 3, /* Device connected to dev CS[2] */
  51532. +#endif
  51533. +#if defined(MV_INCLUDE_DEVICE_CS4)
  51534. + DEV_CS4 = 4, /* Device connected to BOOT dev */
  51535. +#endif
  51536. + MV_DEV_MAX_CS = MV_DEVICE_MAX_CS
  51537. +}MV_DEVICE;
  51538. +
  51539. +
  51540. +#endif /* MV_ASMLANGUAGE */
  51541. +
  51542. +
  51543. +#define NAND_CTRL_REG 0x10470
  51544. +
  51545. +#define NAND_ACTCEBOOT_BIT BIT1
  51546. +
  51547. +
  51548. +#endif /* #ifndef __INCmvDeviceRegsH */
  51549. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c
  51550. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c 1970-01-01 01:00:00.000000000 +0100
  51551. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.c 2011-08-01 14:38:19.000000000 +0200
  51552. @@ -0,0 +1,211 @@
  51553. +/*******************************************************************************
  51554. +Copyright (C) Marvell International Ltd. and its affiliates
  51555. +
  51556. +This software file (the "File") is owned and distributed by Marvell
  51557. +International Ltd. and/or its affiliates ("Marvell") under the following
  51558. +alternative licensing terms. Once you have made an election to distribute the
  51559. +File under one of the following license alternatives, please (i) delete this
  51560. +introductory statement regarding license alternatives, (ii) delete the two
  51561. +license alternatives that you have not elected to use and (iii) preserve the
  51562. +Marvell copyright notice above.
  51563. +
  51564. +
  51565. +********************************************************************************
  51566. +Marvell GPL License Option
  51567. +
  51568. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51569. +modify this File in accordance with the terms and conditions of the General
  51570. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51571. +available along with the File in the license.txt file or by writing to the Free
  51572. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51573. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51574. +
  51575. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51576. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51577. +DISCLAIMED. The GPL License provides additional details about this warranty
  51578. +disclaimer.
  51579. +*******************************************************************************/
  51580. +/*******************************************************************************
  51581. +* mvOsCpuArchLib.c - Marvell CPU architecture library
  51582. +*
  51583. +* DESCRIPTION:
  51584. +* This library introduce Marvell API for OS dependent CPU architecture
  51585. +* APIs. This library introduce single CPU architecture services APKI
  51586. +* cross OS.
  51587. +*
  51588. +* DEPENDENCIES:
  51589. +* None.
  51590. +*
  51591. +*******************************************************************************/
  51592. +
  51593. +/* includes */
  51594. +#include <asm/processor.h>
  51595. +#include "mvOs.h"
  51596. +
  51597. +static MV_U32 read_p15_c0 (void);
  51598. +
  51599. +/* defines */
  51600. +#define ARM_ID_REVISION_OFFS 0
  51601. +#define ARM_ID_REVISION_MASK (0xf << ARM_ID_REVISION_OFFS)
  51602. +
  51603. +#define ARM_ID_PART_NUM_OFFS 4
  51604. +#define ARM_ID_PART_NUM_MASK (0xfff << ARM_ID_PART_NUM_OFFS)
  51605. +
  51606. +#define ARM_ID_ARCH_OFFS 16
  51607. +#define ARM_ID_ARCH_MASK (0xf << ARM_ID_ARCH_OFFS)
  51608. +
  51609. +#define ARM_ID_VAR_OFFS 20
  51610. +#define ARM_ID_VAR_MASK (0xf << ARM_ID_VAR_OFFS)
  51611. +
  51612. +#define ARM_ID_ASCII_OFFS 24
  51613. +#define ARM_ID_ASCII_MASK (0xff << ARM_ID_ASCII_OFFS)
  51614. +
  51615. +
  51616. +
  51617. +void* mvOsIoCachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr,
  51618. + MV_U32 *memHandle)
  51619. +{
  51620. + void *p = kmalloc( size, GFP_KERNEL );
  51621. + *pPhyAddr = pci_map_single( osHandle, p, 0, PCI_DMA_BIDIRECTIONAL );
  51622. + return p;
  51623. +}
  51624. +void* mvOsIoUncachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr,
  51625. + MV_U32 *memHandle)
  51626. +{
  51627. + return pci_alloc_consistent( osHandle, size, (dma_addr_t *)pPhyAddr );
  51628. +}
  51629. +
  51630. +void mvOsIoUncachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr,
  51631. + MV_U32 memHandle)
  51632. +{
  51633. + return pci_free_consistent( osHandle, size, pVirtAddr, (dma_addr_t)phyAddr );
  51634. +}
  51635. +
  51636. +void mvOsIoCachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr,
  51637. + MV_U32 memHandle )
  51638. +{
  51639. + return kfree( pVirtAddr );
  51640. +}
  51641. +
  51642. +int mvOsRand(void)
  51643. +{
  51644. + int rand;
  51645. + get_random_bytes(&rand, sizeof(rand) );
  51646. + return rand;
  51647. +}
  51648. +
  51649. +/*******************************************************************************
  51650. +* mvOsCpuVerGet() -
  51651. +*
  51652. +* DESCRIPTION:
  51653. +*
  51654. +* INPUT:
  51655. +* None.
  51656. +*
  51657. +* OUTPUT:
  51658. +* None.
  51659. +*
  51660. +* RETURN:
  51661. +* 32bit CPU Revision
  51662. +*
  51663. +*******************************************************************************/
  51664. +MV_U32 mvOsCpuRevGet( MV_VOID )
  51665. +{
  51666. + return ((read_p15_c0() & ARM_ID_REVISION_MASK ) >> ARM_ID_REVISION_OFFS);
  51667. +}
  51668. +/*******************************************************************************
  51669. +* mvOsCpuPartGet() -
  51670. +*
  51671. +* DESCRIPTION:
  51672. +*
  51673. +* INPUT:
  51674. +* None.
  51675. +*
  51676. +* OUTPUT:
  51677. +* None.
  51678. +*
  51679. +* RETURN:
  51680. +* 32bit CPU Part number
  51681. +*
  51682. +*******************************************************************************/
  51683. +MV_U32 mvOsCpuPartGet( MV_VOID )
  51684. +{
  51685. + return ((read_p15_c0() & ARM_ID_PART_NUM_MASK ) >> ARM_ID_PART_NUM_OFFS);
  51686. +}
  51687. +/*******************************************************************************
  51688. +* mvOsCpuArchGet() -
  51689. +*
  51690. +* DESCRIPTION:
  51691. +*
  51692. +* INPUT:
  51693. +* None.
  51694. +*
  51695. +* OUTPUT:
  51696. +* None.
  51697. +*
  51698. +* RETURN:
  51699. +* 32bit CPU Architicture number
  51700. +*
  51701. +*******************************************************************************/
  51702. +MV_U32 mvOsCpuArchGet( MV_VOID )
  51703. +{
  51704. + return ((read_p15_c0() & ARM_ID_ARCH_MASK ) >> ARM_ID_ARCH_OFFS);
  51705. +}
  51706. +/*******************************************************************************
  51707. +* mvOsCpuVarGet() -
  51708. +*
  51709. +* DESCRIPTION:
  51710. +*
  51711. +* INPUT:
  51712. +* None.
  51713. +*
  51714. +* OUTPUT:
  51715. +* None.
  51716. +*
  51717. +* RETURN:
  51718. +* 32bit CPU Variant number
  51719. +*
  51720. +*******************************************************************************/
  51721. +MV_U32 mvOsCpuVarGet( MV_VOID )
  51722. +{
  51723. + return ((read_p15_c0() & ARM_ID_VAR_MASK ) >> ARM_ID_VAR_OFFS);
  51724. +}
  51725. +/*******************************************************************************
  51726. +* mvOsCpuAsciiGet() -
  51727. +*
  51728. +* DESCRIPTION:
  51729. +*
  51730. +* INPUT:
  51731. +* None.
  51732. +*
  51733. +* OUTPUT:
  51734. +* None.
  51735. +*
  51736. +* RETURN:
  51737. +* 32bit CPU Variant number
  51738. +*
  51739. +*******************************************************************************/
  51740. +MV_U32 mvOsCpuAsciiGet( MV_VOID )
  51741. +{
  51742. + return ((read_p15_c0() & ARM_ID_ASCII_MASK ) >> ARM_ID_ASCII_OFFS);
  51743. +}
  51744. +
  51745. +
  51746. +
  51747. +/*
  51748. +static unsigned long read_p15_c0 (void)
  51749. +*/
  51750. +/* read co-processor 15, register #0 (ID register) */
  51751. +static MV_U32 read_p15_c0 (void)
  51752. +{
  51753. + MV_U32 value;
  51754. +
  51755. + __asm__ __volatile__(
  51756. + "mrc p15, 0, %0, c0, c0, 0 @ read control reg\n"
  51757. + : "=r" (value)
  51758. + :
  51759. + : "memory");
  51760. +
  51761. + return value;
  51762. +}
  51763. +
  51764. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h
  51765. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h 1970-01-01 01:00:00.000000000 +0100
  51766. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/linux_oss/mvOs.h 2011-08-01 14:38:19.000000000 +0200
  51767. @@ -0,0 +1,423 @@
  51768. +/*******************************************************************************
  51769. +Copyright (C) Marvell International Ltd. and its affiliates
  51770. +
  51771. +This software file (the "File") is owned and distributed by Marvell
  51772. +International Ltd. and/or its affiliates ("Marvell") under the following
  51773. +alternative licensing terms. Once you have made an election to distribute the
  51774. +File under one of the following license alternatives, please (i) delete this
  51775. +introductory statement regarding license alternatives, (ii) delete the two
  51776. +license alternatives that you have not elected to use and (iii) preserve the
  51777. +Marvell copyright notice above.
  51778. +
  51779. +
  51780. +********************************************************************************
  51781. +Marvell GPL License Option
  51782. +
  51783. +If you received this File from Marvell, you may opt to use, redistribute and/or
  51784. +modify this File in accordance with the terms and conditions of the General
  51785. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  51786. +available along with the File in the license.txt file or by writing to the Free
  51787. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  51788. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  51789. +
  51790. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  51791. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  51792. +DISCLAIMED. The GPL License provides additional details about this warranty
  51793. +disclaimer.
  51794. +*******************************************************************************/
  51795. +#ifndef _MV_OS_LNX_H_
  51796. +#define _MV_OS_LNX_H_
  51797. +
  51798. +
  51799. +#ifdef __KERNEL__
  51800. +/* for kernel space */
  51801. +#include <linux/autoconf.h>
  51802. +#include <linux/interrupt.h>
  51803. +#include <linux/stddef.h>
  51804. +#include <linux/kernel.h>
  51805. +#include <linux/init.h>
  51806. +#include <linux/errno.h>
  51807. +#include <linux/reboot.h>
  51808. +#include <linux/pci.h>
  51809. +#include <linux/kdev_t.h>
  51810. +#include <linux/major.h>
  51811. +#include <linux/blkdev.h>
  51812. +#include <linux/console.h>
  51813. +#include <linux/delay.h>
  51814. +#include <linux/seq_file.h>
  51815. +#include <linux/string.h>
  51816. +#include <linux/slab.h>
  51817. +#include <linux/kernel.h>
  51818. +#include <linux/string.h>
  51819. +#include <linux/slab.h>
  51820. +#include <linux/mm.h>
  51821. +
  51822. +#include <asm/system.h>
  51823. +#include <asm/pgtable.h>
  51824. +#include <asm/page.h>
  51825. +#include <asm/hardirq.h>
  51826. +#include <asm/dma.h>
  51827. +#include <asm/io.h>
  51828. +
  51829. +#include <linux/random.h>
  51830. +
  51831. +#include "dbg-trace.h"
  51832. +
  51833. +extern void mv_early_printk(char *fmt,...);
  51834. +
  51835. +#define MV_ASM __asm__ __volatile__
  51836. +#define INLINE inline
  51837. +#define MV_TRC_REC TRC_REC
  51838. +#define mvOsPrintf printk
  51839. +#define mvOsEarlyPrintf mv_early_printk
  51840. +#define mvOsOutput printk
  51841. +#define mvOsSPrintf sprintf
  51842. +#define mvOsMalloc(_size_) kmalloc(_size_,GFP_ATOMIC)
  51843. +#define mvOsFree kfree
  51844. +#define mvOsMemcpy memcpy
  51845. +#define mvOsSleep(_mils_) mdelay(_mils_)
  51846. +#define mvOsTaskLock()
  51847. +#define mvOsTaskUnlock()
  51848. +#define strtol simple_strtoul
  51849. +#define mvOsDelay(x) mdelay(x)
  51850. +#define mvOsUDelay(x) udelay(x)
  51851. +#define mvCopyFromOs copy_from_user
  51852. +#define mvCopyToOs copy_to_user
  51853. +
  51854. +
  51855. +#include "mvTypes.h"
  51856. +#include "mvCommon.h"
  51857. +
  51858. +#ifdef MV_NDEBUG
  51859. +#define mvOsAssert(cond)
  51860. +#else
  51861. +#define mvOsAssert(cond) { do { if(!(cond)) { BUG(); } }while(0); }
  51862. +#endif /* MV_NDEBUG */
  51863. +
  51864. +#else /* __KERNEL__ */
  51865. +
  51866. +/* for user space applications */
  51867. +#include <stdlib.h>
  51868. +#include <stdio.h>
  51869. +#include <assert.h>
  51870. +#include <string.h>
  51871. +
  51872. +#define INLINE inline
  51873. +#define mvOsPrintf printf
  51874. +#define mvOsOutput printf
  51875. +#define mvOsMalloc(_size_) malloc(_size_)
  51876. +#define mvOsFree free
  51877. +#define mvOsAssert(cond) assert(cond)
  51878. +
  51879. +#endif /* __KERNEL__ */
  51880. +#define mvOsIoVirtToPhy(pDev, pVirtAddr) \
  51881. + pci_map_single( (pDev), (pVirtAddr), 0, PCI_DMA_BIDIRECTIONAL )
  51882. +
  51883. +#define mvOsCacheClear(pDev, p, size ) \
  51884. + pci_map_single( (pDev), (p), (size), PCI_DMA_BIDIRECTIONAL)
  51885. +
  51886. +#define mvOsCacheFlush(pDev, p, size ) \
  51887. + pci_map_single( (pDev), (p), (size), PCI_DMA_TODEVICE)
  51888. +
  51889. +#define mvOsCacheInvalidate(pDev, p, size) \
  51890. + pci_map_single( (pDev), (p), (size), PCI_DMA_FROMDEVICE )
  51891. +
  51892. +#define mvOsCacheUnmap(pDev, phys, size) \
  51893. + pci_unmap_single( (pDev), (dma_addr_t)(phys), (size), PCI_DMA_FROMDEVICE )
  51894. +
  51895. +
  51896. +#define CPU_PHY_MEM(x) (MV_U32)x
  51897. +#define CPU_MEMIO_CACHED_ADDR(x) (void*)x
  51898. +#define CPU_MEMIO_UNCACHED_ADDR(x) (void*)x
  51899. +
  51900. +
  51901. +/* CPU architecture dependent 32, 16, 8 bit read/write IO addresses */
  51902. +#define MV_MEMIO32_WRITE(addr, data) \
  51903. + ((*((volatile unsigned int*)(addr))) = ((unsigned int)(data)))
  51904. +
  51905. +#define MV_MEMIO32_READ(addr) \
  51906. + ((*((volatile unsigned int*)(addr))))
  51907. +
  51908. +#define MV_MEMIO16_WRITE(addr, data) \
  51909. + ((*((volatile unsigned short*)(addr))) = ((unsigned short)(data)))
  51910. +
  51911. +#define MV_MEMIO16_READ(addr) \
  51912. + ((*((volatile unsigned short*)(addr))))
  51913. +
  51914. +#define MV_MEMIO8_WRITE(addr, data) \
  51915. + ((*((volatile unsigned char*)(addr))) = ((unsigned char)(data)))
  51916. +
  51917. +#define MV_MEMIO8_READ(addr) \
  51918. + ((*((volatile unsigned char*)(addr))))
  51919. +
  51920. +
  51921. +/* No Fast Swap implementation (in assembler) for ARM */
  51922. +#define MV_32BIT_LE_FAST(val) MV_32BIT_LE(val)
  51923. +#define MV_16BIT_LE_FAST(val) MV_16BIT_LE(val)
  51924. +#define MV_32BIT_BE_FAST(val) MV_32BIT_BE(val)
  51925. +#define MV_16BIT_BE_FAST(val) MV_16BIT_BE(val)
  51926. +
  51927. +/* 32 and 16 bit read/write in big/little endian mode */
  51928. +
  51929. +/* 16bit write in little endian mode */
  51930. +#define MV_MEMIO_LE16_WRITE(addr, data) \
  51931. + MV_MEMIO16_WRITE(addr, MV_16BIT_LE_FAST(data))
  51932. +
  51933. +/* 16bit read in little endian mode */
  51934. +static __inline MV_U16 MV_MEMIO_LE16_READ(MV_U32 addr)
  51935. +{
  51936. + MV_U16 data;
  51937. +
  51938. + data= (MV_U16)MV_MEMIO16_READ(addr);
  51939. +
  51940. + return (MV_U16)MV_16BIT_LE_FAST(data);
  51941. +}
  51942. +
  51943. +/* 32bit write in little endian mode */
  51944. +#define MV_MEMIO_LE32_WRITE(addr, data) \
  51945. + MV_MEMIO32_WRITE(addr, MV_32BIT_LE_FAST(data))
  51946. +
  51947. +/* 32bit read in little endian mode */
  51948. +static __inline MV_U32 MV_MEMIO_LE32_READ(MV_U32 addr)
  51949. +{
  51950. + MV_U32 data;
  51951. +
  51952. + data= (MV_U32)MV_MEMIO32_READ(addr);
  51953. +
  51954. + return (MV_U32)MV_32BIT_LE_FAST(data);
  51955. +}
  51956. +
  51957. +static __inline void mvOsBCopy(char* srcAddr, char* dstAddr, int byteCount)
  51958. +{
  51959. + while(byteCount != 0)
  51960. + {
  51961. + *dstAddr = *srcAddr;
  51962. + dstAddr++;
  51963. + srcAddr++;
  51964. + byteCount--;
  51965. + }
  51966. +}
  51967. +
  51968. +static INLINE MV_U64 mvOsDivMod64(MV_U64 divided, MV_U64 divisor, MV_U64* modulu)
  51969. +{
  51970. + MV_U64 division = 0;
  51971. +
  51972. + if(divisor == 1)
  51973. + return divided;
  51974. +
  51975. + while(divided >= divisor)
  51976. + {
  51977. + division++;
  51978. + divided -= divisor;
  51979. + }
  51980. + if (modulu != NULL)
  51981. + *modulu = divided;
  51982. +
  51983. + return division;
  51984. +}
  51985. +
  51986. +#if defined(MV_BRIDGE_SYNC_REORDER)
  51987. +extern MV_U32 *mvUncachedParam;
  51988. +
  51989. +static __inline void mvOsBridgeReorderWA(void)
  51990. +{
  51991. + volatile MV_U32 val = 0;
  51992. +
  51993. + val = mvUncachedParam[0];
  51994. +}
  51995. +#endif
  51996. +
  51997. +
  51998. +/* Flash APIs */
  51999. +#define MV_FL_8_READ MV_MEMIO8_READ
  52000. +#define MV_FL_16_READ MV_MEMIO_LE16_READ
  52001. +#define MV_FL_32_READ MV_MEMIO_LE32_READ
  52002. +#define MV_FL_8_DATA_READ MV_MEMIO8_READ
  52003. +#define MV_FL_16_DATA_READ MV_MEMIO16_READ
  52004. +#define MV_FL_32_DATA_READ MV_MEMIO32_READ
  52005. +#define MV_FL_8_WRITE MV_MEMIO8_WRITE
  52006. +#define MV_FL_16_WRITE MV_MEMIO_LE16_WRITE
  52007. +#define MV_FL_32_WRITE MV_MEMIO_LE32_WRITE
  52008. +#define MV_FL_8_DATA_WRITE MV_MEMIO8_WRITE
  52009. +#define MV_FL_16_DATA_WRITE MV_MEMIO16_WRITE
  52010. +#define MV_FL_32_DATA_WRITE MV_MEMIO32_WRITE
  52011. +
  52012. +
  52013. +/* CPU cache information */
  52014. +#define CPU_I_CACHE_LINE_SIZE 32 /* 2do: replace 32 with linux core macro */
  52015. +#define CPU_D_CACHE_LINE_SIZE 32 /* 2do: replace 32 with linux core macro */
  52016. +
  52017. +#ifdef CONFIG_L2_CACHE_ENABLE
  52018. +/* Data cache flush one line */
  52019. +#define mvOsCacheLineFlushInv(handle, addr) \
  52020. +{ \
  52021. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c14, 1" : : "r" (addr));\
  52022. + __asm__ __volatile__ ("mcr p15, 1, %0, c15, c10, 1" : : "r" (addr));\
  52023. + __asm__ __volatile__ ("mcr p15, 0, r0, c7, c10, 4"); \
  52024. +}
  52025. +
  52026. +#else
  52027. +
  52028. +/* Data cache flush one line */
  52029. +#define mvOsCacheLineFlushInv(handle, addr) \
  52030. +{ \
  52031. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c14, 1" : : "r" (addr));\
  52032. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" : : "r" (addr)); \
  52033. +}
  52034. +#endif
  52035. +
  52036. +#ifdef CONFIG_L2_CACHE_ENABLE
  52037. +#define mvOsCacheLineInv(handle,addr) \
  52038. +{ \
  52039. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c6, 1" : : "r" (addr)); \
  52040. + __asm__ __volatile__ ("mcr p15, 1, %0, c15, c11, 1" : : "r" (addr)); \
  52041. +}
  52042. +#else
  52043. +#define mvOsCacheLineInv(handle,addr) \
  52044. +{ \
  52045. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c6, 1" : : "r" (addr)); \
  52046. +}
  52047. +#endif
  52048. +
  52049. +#ifdef CONFIG_L2_CACHE_ENABLE
  52050. +/* Data cache flush one line */
  52051. +#define mvOsCacheLineFlush(handle, addr) \
  52052. +{ \
  52053. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 1" : : "r" (addr));\
  52054. + __asm__ __volatile__ ("mcr p15, 1, %0, c15, c9, 1" : : "r" (addr));\
  52055. + __asm__ __volatile__ ("mcr p15, 0, r0, c7, c10, 4"); \
  52056. +}
  52057. +
  52058. +#else
  52059. +/* Data cache flush one line */
  52060. +#define mvOsCacheLineFlush(handle, addr) \
  52061. +{ \
  52062. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 1" : : "r" (addr));\
  52063. + __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" : : "r" (addr)); \
  52064. +}
  52065. +#endif
  52066. +
  52067. +static __inline void mvOsPrefetch(const void *ptr)
  52068. +{
  52069. +#ifdef CONFIG_USE_DSP
  52070. + __asm__ __volatile__(
  52071. + "pld\t%0"
  52072. + :
  52073. + : "o" (*(char *)ptr)
  52074. + : "cc");
  52075. +#else
  52076. + return;
  52077. +#endif
  52078. +}
  52079. +
  52080. +
  52081. +/* Flush CPU pipe */
  52082. +#define CPU_PIPE_FLUSH
  52083. +
  52084. +
  52085. +
  52086. +
  52087. +
  52088. +/* register manipulations */
  52089. +
  52090. +/******************************************************************************
  52091. +* This debug function enable the write of each register that u-boot access to
  52092. +* to an array in the DRAM, the function record only MV_REG_WRITE access.
  52093. +* The function could not be operate when booting from flash.
  52094. +* In order to print the array we use the printreg command.
  52095. +******************************************************************************/
  52096. +/* #define REG_DEBUG */
  52097. +#if defined(REG_DEBUG)
  52098. +extern int reg_arry[2048][2];
  52099. +extern int reg_arry_index;
  52100. +#endif
  52101. +
  52102. +/* Marvell controller register read/write macros */
  52103. +#define MV_REG_VALUE(offset) \
  52104. + (MV_MEMIO32_READ((INTER_REGS_BASE | (offset))))
  52105. +
  52106. +#define MV_REG_READ(offset) \
  52107. + (MV_MEMIO_LE32_READ(INTER_REGS_BASE | (offset)))
  52108. +
  52109. +#if defined(REG_DEBUG)
  52110. +#define MV_REG_WRITE(offset, val) \
  52111. + MV_MEMIO_LE32_WRITE((INTER_REGS_BASE | (offset)), (val)); \
  52112. + { \
  52113. + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
  52114. + reg_arry[reg_arry_index][1] = (val);\
  52115. + reg_arry_index++;\
  52116. + }
  52117. +#else
  52118. +#define MV_REG_WRITE(offset, val) \
  52119. + MV_MEMIO_LE32_WRITE((INTER_REGS_BASE | (offset)), (val));
  52120. +#endif
  52121. +
  52122. +#define MV_REG_BYTE_READ(offset) \
  52123. + (MV_MEMIO8_READ((INTER_REGS_BASE | (offset))))
  52124. +
  52125. +#if defined(REG_DEBUG)
  52126. +#define MV_REG_BYTE_WRITE(offset, val) \
  52127. + MV_MEMIO8_WRITE((INTER_REGS_BASE | (offset)), (val)); \
  52128. + { \
  52129. + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
  52130. + reg_arry[reg_arry_index][1] = (val);\
  52131. + reg_arry_index++;\
  52132. + }
  52133. +#else
  52134. +#define MV_REG_BYTE_WRITE(offset, val) \
  52135. + MV_MEMIO8_WRITE((INTER_REGS_BASE | (offset)), (val))
  52136. +#endif
  52137. +
  52138. +#if defined(REG_DEBUG)
  52139. +#define MV_REG_BIT_SET(offset, bitMask) \
  52140. + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
  52141. + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) | \
  52142. + MV_32BIT_LE_FAST(bitMask)))); \
  52143. + { \
  52144. + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
  52145. + reg_arry[reg_arry_index][1] = (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)));\
  52146. + reg_arry_index++;\
  52147. + }
  52148. +#else
  52149. +#define MV_REG_BIT_SET(offset, bitMask) \
  52150. + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
  52151. + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) | \
  52152. + MV_32BIT_LE_FAST(bitMask))))
  52153. +#endif
  52154. +
  52155. +#if defined(REG_DEBUG)
  52156. +#define MV_REG_BIT_RESET(offset,bitMask) \
  52157. + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
  52158. + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) & \
  52159. + MV_32BIT_LE_FAST(~bitMask)))); \
  52160. + { \
  52161. + reg_arry[reg_arry_index][0] = (INTER_REGS_BASE | (offset));\
  52162. + reg_arry[reg_arry_index][1] = (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)));\
  52163. + reg_arry_index++;\
  52164. + }
  52165. +#else
  52166. +#define MV_REG_BIT_RESET(offset,bitMask) \
  52167. + (MV_MEMIO32_WRITE((INTER_REGS_BASE | (offset)), \
  52168. + (MV_MEMIO32_READ(INTER_REGS_BASE | (offset)) & \
  52169. + MV_32BIT_LE_FAST(~bitMask))))
  52170. +#endif
  52171. +
  52172. +
  52173. +
  52174. +/* ARM architecture APIs */
  52175. +MV_U32 mvOsCpuRevGet (MV_VOID);
  52176. +MV_U32 mvOsCpuPartGet (MV_VOID);
  52177. +MV_U32 mvOsCpuArchGet (MV_VOID);
  52178. +MV_U32 mvOsCpuVarGet (MV_VOID);
  52179. +MV_U32 mvOsCpuAsciiGet (MV_VOID);
  52180. +
  52181. +/* Other APIs */
  52182. +void* mvOsIoCachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr, MV_U32 *memHandle);
  52183. +void* mvOsIoUncachedMalloc( void* osHandle, MV_U32 size, MV_ULONG* pPhyAddr, MV_U32 *memHandle );
  52184. +void mvOsIoUncachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr, MV_U32 memHandle );
  52185. +void mvOsIoCachedFree( void* osHandle, MV_U32 size, MV_ULONG phyAddr, void* pVirtAddr, MV_U32 memHandle );
  52186. +int mvOsRand(void);
  52187. +
  52188. +#endif /* _MV_OS_LNX_H_ */
  52189. +
  52190. +
  52191. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h
  52192. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h 1970-01-01 01:00:00.000000000 +0100
  52193. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/linux_oss/mvOsSata.h 2011-08-01 14:38:19.000000000 +0200
  52194. @@ -0,0 +1,158 @@
  52195. +/*******************************************************************************
  52196. +Copyright (C) Marvell International Ltd. and its affiliates
  52197. +
  52198. +This software file (the "File") is owned and distributed by Marvell
  52199. +International Ltd. and/or its affiliates ("Marvell") under the following
  52200. +alternative licensing terms. Once you have made an election to distribute the
  52201. +File under one of the following license alternatives, please (i) delete this
  52202. +introductory statement regarding license alternatives, (ii) delete the two
  52203. +license alternatives that you have not elected to use and (iii) preserve the
  52204. +Marvell copyright notice above.
  52205. +
  52206. +
  52207. +********************************************************************************
  52208. +Marvell GPL License Option
  52209. +
  52210. +If you received this File from Marvell, you may opt to use, redistribute and/or
  52211. +modify this File in accordance with the terms and conditions of the General
  52212. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  52213. +available along with the File in the license.txt file or by writing to the Free
  52214. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  52215. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  52216. +
  52217. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  52218. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  52219. +DISCLAIMED. The GPL License provides additional details about this warranty
  52220. +disclaimer.
  52221. +*******************************************************************************/
  52222. +/*******************************************************************************
  52223. +* mvOsLinux.h - O.S. interface header file for Linux
  52224. +*
  52225. +* DESCRIPTION:
  52226. +* This header file contains OS dependent definition under Linux
  52227. +*
  52228. +* DEPENDENCIES:
  52229. +* Linux kernel header files.
  52230. +*
  52231. +* FILE REVISION NUMBER:
  52232. +* $Revision: 1.1 $
  52233. +*******************************************************************************/
  52234. +
  52235. +#ifndef __INCmvOsLinuxh
  52236. +#define __INCmvOsLinuxh
  52237. +
  52238. +/* Includes */
  52239. +#include <linux/autoconf.h>
  52240. +#include <linux/module.h>
  52241. +#include <linux/types.h>
  52242. +#include <linux/string.h>
  52243. +#include <linux/kernel.h>
  52244. +#include <linux/timer.h>
  52245. +#include <linux/mm.h>
  52246. +#include <linux/interrupt.h>
  52247. +#include <linux/major.h>
  52248. +#include <linux/errno.h>
  52249. +#include <linux/genhd.h>
  52250. +#include <linux/slab.h>
  52251. +#include <linux/delay.h>
  52252. +#include <linux/ide.h>
  52253. +#include <linux/pci.h>
  52254. +
  52255. +#include <asm/byteorder.h>
  52256. +#include <asm/irq.h>
  52257. +#include <asm/uaccess.h>
  52258. +#include <asm/io.h>
  52259. +#include "mvOs.h"
  52260. +
  52261. +
  52262. +/* Definitions */
  52263. +#define MV_DEFAULT_QUEUE_DEPTH 2
  52264. +#define MV_SATA_SUPPORT_EDMA_SINGLE_DATA_REGION
  52265. +#define MV_SATA_SUPPORT_GEN2E_128_QUEUE_LEN
  52266. +
  52267. +#ifdef CONFIG_MV88F6082
  52268. + #define MV_SATA_OVERRIDE_SW_QUEUE_SIZE
  52269. + #define MV_SATA_REQUESTED_SW_QUEUE_SIZE 2
  52270. + #undef MV_SATA_SUPPORT_GEN2E_128_QUEUE_LEN
  52271. +#endif
  52272. +
  52273. +/* System dependent macro for flushing CPU write cache */
  52274. +#if defined (MV_BRIDGE_SYNC_REORDER)
  52275. +#define MV_CPU_WRITE_BUFFER_FLUSH() do { \
  52276. + wmb(); \
  52277. + mvOsBridgeReorderWA(); \
  52278. + } while (0)
  52279. +#else
  52280. +#define MV_CPU_WRITE_BUFFER_FLUSH() wmb()
  52281. +#endif /* CONFIG_MV78XX0 */
  52282. +
  52283. +/* System dependent little endian from / to CPU conversions */
  52284. +#define MV_CPU_TO_LE16(x) cpu_to_le16(x)
  52285. +#define MV_CPU_TO_LE32(x) cpu_to_le32(x)
  52286. +
  52287. +#define MV_LE16_TO_CPU(x) le16_to_cpu(x)
  52288. +#define MV_LE32_TO_CPU(x) le32_to_cpu(x)
  52289. +
  52290. +#ifdef __BIG_ENDIAN_BITFIELD
  52291. +#define MV_BIG_ENDIAN_BITFIELD
  52292. +#endif
  52293. +
  52294. +/* System dependent register read / write in byte/word/dword variants */
  52295. +#define MV_REG_WRITE_BYTE(base, offset, val) writeb(val, base + offset)
  52296. +#define MV_REG_WRITE_WORD(base, offset, val) writew(val, base + offset)
  52297. +#define MV_REG_WRITE_DWORD(base, offset, val) writel(val, base + offset)
  52298. +#define MV_REG_READ_BYTE(base, offset) readb(base + offset)
  52299. +#define MV_REG_READ_WORD(base, offset) readw(base + offset)
  52300. +#define MV_REG_READ_DWORD(base, offset) readl(base + offset)
  52301. +
  52302. +
  52303. +/* Typedefs */
  52304. +
  52305. +/* System dependant typedefs */
  52306. +typedef void *MV_VOID_PTR;
  52307. +typedef u32 *MV_U32_PTR;
  52308. +typedef u16 *MV_U16_PTR;
  52309. +typedef u8 *MV_U8_PTR;
  52310. +typedef char *MV_CHAR_PTR;
  52311. +typedef void *MV_BUS_ADDR_T;
  52312. +typedef unsigned long MV_CPU_FLAGS;
  52313. +
  52314. +
  52315. +/* Structures */
  52316. +/* System dependent structure */
  52317. +typedef struct mvOsSemaphore
  52318. +{
  52319. + int notUsed;
  52320. +} MV_OS_SEMAPHORE;
  52321. +
  52322. +
  52323. +/* Functions (User implemented)*/
  52324. +
  52325. +/* Semaphore init, take and release */
  52326. +#define mvOsSemInit(x) MV_TRUE
  52327. +#define mvOsSemTake(x)
  52328. +#define mvOsSemRelease(x)
  52329. +
  52330. +/* Interrupt masking and unmasking functions */
  52331. +MV_CPU_FLAGS mvOsSaveFlagsAndMaskCPUInterrupts(MV_VOID);
  52332. +MV_VOID mvOsRestoreFlags(MV_CPU_FLAGS);
  52333. +
  52334. +/* Delay function in micro seconds resolution */
  52335. +void mvMicroSecondsDelay(MV_VOID_PTR, MV_U32);
  52336. +
  52337. +/* Typedefs */
  52338. +typedef enum mvBoolean
  52339. +{
  52340. + MV_SFALSE, MV_STRUE
  52341. +} MV_BOOLEAN;
  52342. +
  52343. +/* System logging function */
  52344. +#include "mvLog.h"
  52345. +/* Enable READ/WRITE Long SCSI command only when driver is compiled for debugging */
  52346. +#ifdef MV_LOGGER
  52347. +#define MV_SATA_SUPPORT_READ_WRITE_LONG
  52348. +#endif
  52349. +
  52350. +#define MV_IAL_LOG_ID 3
  52351. +
  52352. +#endif /* __INCmvOsLinuxh */
  52353. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h
  52354. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h 1970-01-01 01:00:00.000000000 +0100
  52355. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mvSysHwConfig.h 2011-08-01 14:38:19.000000000 +0200
  52356. @@ -0,0 +1,375 @@
  52357. +/*******************************************************************************
  52358. +Copyright (C) Marvell International Ltd. and its affiliates
  52359. +
  52360. +********************************************************************************
  52361. +Marvell GPL License Option
  52362. +
  52363. +If you received this File from Marvell, you may opt to use, redistribute and/or
  52364. +modify this File in accordance with the terms and conditions of the General
  52365. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  52366. +available along with the File in the license.txt file or by writing to the Free
  52367. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  52368. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  52369. +
  52370. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  52371. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  52372. +DISCLAIMED. The GPL License provides additional details about this warranty
  52373. +disclaimer.
  52374. +
  52375. +*******************************************************************************/
  52376. +/*******************************************************************************
  52377. +* mvSysHwCfg.h - Marvell system HW configuration file
  52378. +*
  52379. +* DESCRIPTION:
  52380. +* None.
  52381. +*
  52382. +* DEPENDENCIES:
  52383. +* None.
  52384. +*
  52385. +*******************************************************************************/
  52386. +
  52387. +#ifndef __INCmvSysHwConfigh
  52388. +#define __INCmvSysHwConfigh
  52389. +
  52390. +#include "../../../../include/linux/autoconf.h"
  52391. +
  52392. +#define CONFIG_MARVELL 1
  52393. +
  52394. +/* includes */
  52395. +#define _1K 0x00000400
  52396. +#define _4K 0x00001000
  52397. +#define _8K 0x00002000
  52398. +#define _16K 0x00004000
  52399. +#define _32K 0x00008000
  52400. +#define _64K 0x00010000
  52401. +#define _128K 0x00020000
  52402. +#define _256K 0x00040000
  52403. +#define _512K 0x00080000
  52404. +
  52405. +#define _1M 0x00100000
  52406. +#define _2M 0x00200000
  52407. +#define _4M 0x00400000
  52408. +#define _8M 0x00800000
  52409. +#define _16M 0x01000000
  52410. +#define _32M 0x02000000
  52411. +#define _64M 0x04000000
  52412. +#define _128M 0x08000000
  52413. +#define _256M 0x10000000
  52414. +#define _512M 0x20000000
  52415. +
  52416. +#define _1G 0x40000000
  52417. +#define _2G 0x80000000
  52418. +
  52419. +/****************************************/
  52420. +/* Soc supporeted Units definitions */
  52421. +/****************************************/
  52422. +
  52423. +#ifdef CONFIG_MV_INCLUDE_PEX
  52424. +#define MV_INCLUDE_PEX
  52425. +#endif
  52426. +#ifdef CONFIG_MV_INCLUDE_TWSI
  52427. +#define MV_INCLUDE_TWSI
  52428. +#endif
  52429. +#ifdef CONFIG_MV_INCLUDE_CESA
  52430. +#define MV_INCLUDE_CESA
  52431. +#endif
  52432. +#ifdef CONFIG_MV_INCLUDE_GIG_ETH
  52433. +#define MV_INCLUDE_GIG_ETH
  52434. +#endif
  52435. +#ifdef CONFIG_MV_INCLUDE_INTEG_SATA
  52436. +#define MV_INCLUDE_INTEG_SATA
  52437. +#define MV_INCLUDE_SATA
  52438. +#endif
  52439. +#ifdef CONFIG_MV_INCLUDE_USB
  52440. +#define MV_INCLUDE_USB
  52441. +#define MV_USB_VOLTAGE_FIX
  52442. +#endif
  52443. +#ifdef CONFIG_MV_INCLUDE_NAND
  52444. +#define MV_INCLUDE_NAND
  52445. +#endif
  52446. +#ifdef CONFIG_MV_INCLUDE_TDM
  52447. +#define MV_INCLUDE_TDM
  52448. +#endif
  52449. +#ifdef CONFIG_MV_INCLUDE_XOR
  52450. +#define MV_INCLUDE_XOR
  52451. +#endif
  52452. +#ifdef CONFIG_MV_INCLUDE_TWSI
  52453. +#define MV_INCLUDE_TWSI
  52454. +#endif
  52455. +#ifdef CONFIG_MV_INCLUDE_UART
  52456. +#define MV_INCLUDE_UART
  52457. +#endif
  52458. +#ifdef CONFIG_MV_INCLUDE_SPI
  52459. +#define MV_INCLUDE_SPI
  52460. +#endif
  52461. +#ifdef CONFIG_MV_INCLUDE_SFLASH_MTD
  52462. +#define MV_INCLUDE_SFLASH_MTD
  52463. +#endif
  52464. +#ifdef CONFIG_MV_INCLUDE_AUDIO
  52465. +#define MV_INCLUDE_AUDIO
  52466. +#endif
  52467. +#ifdef CONFIG_MV_INCLUDE_TS
  52468. +#define MV_INCLUDE_TS
  52469. +#endif
  52470. +#ifdef CONFIG_MV_INCLUDE_SDIO
  52471. +#define MV_INCLUDE_SDIO
  52472. +#endif
  52473. +
  52474. +
  52475. +/* NAND flash stuff */
  52476. +#ifdef CONFIG_MV_NAND_BOOT
  52477. +#define MV_NAND_BOOT
  52478. +#endif
  52479. +#ifdef CONFIG_MV_NAND
  52480. +#define MV_NAND
  52481. +#endif
  52482. +
  52483. +/* SPI flash stuff */
  52484. +#ifdef CONFIG_MV_SPI_BOOT
  52485. +#define MV_SPI_BOOT
  52486. +#endif
  52487. +
  52488. +
  52489. +/****************************************************************/
  52490. +/************* General configuration ********************/
  52491. +/****************************************************************/
  52492. +
  52493. +/* Enable Clock Power Control */
  52494. +#define MV_INCLUDE_CLK_PWR_CNTRL
  52495. +
  52496. +/* Disable the DEVICE BAR in the PEX */
  52497. +#define MV_DISABLE_PEX_DEVICE_BAR
  52498. +
  52499. +/* Allow the usage of early printings during initialization */
  52500. +#define MV_INCLUDE_EARLY_PRINTK
  52501. +
  52502. +/****************************************************************/
  52503. +/************* NFP configuration ********************************/
  52504. +/****************************************************************/
  52505. +#define MV_NFP_SEC_Q_SIZE 64
  52506. +#define MV_NFP_SEC_REQ_Q_SIZE 1000
  52507. +
  52508. +
  52509. +
  52510. +/****************************************************************/
  52511. +/************* CESA configuration ********************/
  52512. +/****************************************************************/
  52513. +
  52514. +#ifdef MV_INCLUDE_CESA
  52515. +
  52516. +#define MV_CESA_MAX_CHAN 4
  52517. +
  52518. +/* Use 2K of SRAM */
  52519. +#define MV_CESA_MAX_BUF_SIZE 1600
  52520. +
  52521. +#endif /* MV_INCLUDE_CESA */
  52522. +
  52523. +#if defined(CONFIG_MV_INCLUDE_GIG_ETH)
  52524. +
  52525. +#ifdef CONFIG_MV_NFP_STATS
  52526. +#define MV_FP_STATISTICS
  52527. +#else
  52528. +#undef MV_FP_STATISTICS
  52529. +#endif
  52530. +/* Default configuration for SKB_REUSE: 0 - Disabled, 1 - Enabled */
  52531. +#define MV_ETH_SKB_REUSE_DEFAULT 1
  52532. +/* Default configuration for TX_EN workaround: 0 - Disabled, 1 - Enabled */
  52533. +#define MV_ETH_TX_EN_DEFAULT 0
  52534. +
  52535. +/* un-comment if you want to perform tx_done from within the poll function */
  52536. +/* #define ETH_TX_DONE_ISR */
  52537. +
  52538. +/* put descriptors in uncached memory */
  52539. +/* #define ETH_DESCR_UNCACHED */
  52540. +
  52541. +/* Descriptors location: DRAM/internal-SRAM */
  52542. +#define ETH_DESCR_IN_SDRAM
  52543. +#undef ETH_DESCR_IN_SRAM /* No integrated SRAM in 88Fxx81 devices */
  52544. +
  52545. +#if defined(ETH_DESCR_IN_SRAM)
  52546. +#if defined(ETH_DESCR_UNCACHED)
  52547. + #define ETH_DESCR_CONFIG_STR "Uncached descriptors in integrated SRAM"
  52548. +#else
  52549. + #define ETH_DESCR_CONFIG_STR "Cached descriptors in integrated SRAM"
  52550. +#endif
  52551. +#elif defined(ETH_DESCR_IN_SDRAM)
  52552. +#if defined(ETH_DESCR_UNCACHED)
  52553. + #define ETH_DESCR_CONFIG_STR "Uncached descriptors in DRAM"
  52554. +#else
  52555. + #define ETH_DESCR_CONFIG_STR "Cached descriptors in DRAM"
  52556. +#endif
  52557. +#else
  52558. + #error "Ethernet descriptors location undefined"
  52559. +#endif /* ETH_DESCR_IN_SRAM or ETH_DESCR_IN_SDRAM*/
  52560. +
  52561. +/* SW Sync-Barrier: not relevant for 88fxx81*/
  52562. +/* Reasnable to define this macro when descriptors in SRAM and buffers in DRAM */
  52563. +/* In RX the CPU theoretically might see himself as the descriptor owner, */
  52564. +/* although the buffer hadn't been written to DRAM yet. Performance cost. */
  52565. +/* #define INCLUDE_SYNC_BARR */
  52566. +
  52567. +/* Buffers cache coherency method (buffers in DRAM) */
  52568. +#ifndef MV_CACHE_COHER_SW
  52569. +/* Taken from mvCommon.h */
  52570. +/* Memory uncached, HW or SW cache coherency is not needed */
  52571. +#define MV_UNCACHED 0
  52572. +/* Memory cached, HW cache coherency supported in WriteThrough mode */
  52573. +#define MV_CACHE_COHER_HW_WT 1
  52574. +/* Memory cached, HW cache coherency supported in WriteBack mode */
  52575. +#define MV_CACHE_COHER_HW_WB 2
  52576. +/* Memory cached, No HW cache coherency, Cache coherency must be in SW */
  52577. +#define MV_CACHE_COHER_SW 3
  52578. +
  52579. +#endif
  52580. +
  52581. +/* DRAM cache coherency configuration */
  52582. +#define MV_CACHE_COHERENCY MV_CACHE_COHER_SW
  52583. +
  52584. +
  52585. +#define ETHER_DRAM_COHER MV_CACHE_COHER_SW /* No HW coherency in 88Fxx81 devices */
  52586. +
  52587. +#if (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WB)
  52588. + #define ETH_SDRAM_CONFIG_STR "DRAM HW cache coherency (write-back)"
  52589. +#elif (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WT)
  52590. + #define ETH_SDRAM_CONFIG_STR "DRAM HW cache coherency (write-through)"
  52591. +#elif (ETHER_DRAM_COHER == MV_CACHE_COHER_SW)
  52592. + #define ETH_SDRAM_CONFIG_STR "DRAM SW cache-coherency"
  52593. +#elif (ETHER_DRAM_COHER == MV_UNCACHED)
  52594. +# define ETH_SDRAM_CONFIG_STR "DRAM uncached"
  52595. +#else
  52596. + #error "Ethernet-DRAM undefined"
  52597. +#endif /* ETHER_DRAM_COHER */
  52598. +
  52599. +
  52600. +/****************************************************************/
  52601. +/************* Ethernet driver configuration ********************/
  52602. +/****************************************************************/
  52603. +
  52604. +/* port's default queueus */
  52605. +#define ETH_DEF_TXQ 0
  52606. +#define ETH_DEF_RXQ 0
  52607. +
  52608. +#define MV_ETH_RX_Q_NUM CONFIG_MV_ETH_RX_Q_NUM
  52609. +#define MV_ETH_TX_Q_NUM CONFIG_MV_ETH_TX_Q_NUM
  52610. +
  52611. +/* interrupt coalescing setting */
  52612. +#define ETH_TX_COAL 200
  52613. +#define ETH_RX_COAL 200
  52614. +
  52615. +/* Checksum offloading */
  52616. +#define TX_CSUM_OFFLOAD
  52617. +#define RX_CSUM_OFFLOAD
  52618. +
  52619. +#endif /* CONFIG_MV_INCLUDE_GIG_ETH */
  52620. +
  52621. +/****************************************************************/
  52622. +/*************** Telephony configuration ************************/
  52623. +/****************************************************************/
  52624. +#if defined(CONFIG_MV_TDM_LINEAR_MODE)
  52625. + #define MV_TDM_LINEAR_MODE
  52626. +#elif defined(CONFIG_MV_TDM_ULAW_MODE)
  52627. + #define MV_TDM_ULAW_MODE
  52628. +#endif
  52629. +
  52630. +#if defined(CONFIG_MV_TDM_5CHANNELS)
  52631. + #define MV_TDM_5CHANNELS
  52632. +#endif
  52633. +
  52634. +#if defined(CONFIG_MV_TDM_USE_EXTERNAL_PCLK_SOURCE)
  52635. + #define MV_TDM_USE_EXTERNAL_PCLK_SOURCE
  52636. +#endif
  52637. +
  52638. +/* We use the following registers to store DRAM interface pre configuration */
  52639. +/* auto-detection results */
  52640. +/* IMPORTANT: We are using mask register for that purpose. Before writing */
  52641. +/* to units mask register, make sure main maks register is set to disable */
  52642. +/* all interrupts. */
  52643. +#define DRAM_BUF_REG0 0x30810 /* sdram bank 0 size */
  52644. +#define DRAM_BUF_REG1 0x30820 /* sdram config */
  52645. +#define DRAM_BUF_REG2 0x30830 /* sdram mode */
  52646. +#define DRAM_BUF_REG3 0x308c4 /* dunit control low */
  52647. +#define DRAM_BUF_REG4 0x60a90 /* sdram address control */
  52648. +#define DRAM_BUF_REG5 0x60a94 /* sdram timing control low */
  52649. +#define DRAM_BUF_REG6 0x60a98 /* sdram timing control high */
  52650. +#define DRAM_BUF_REG7 0x60a9c /* sdram ODT control low */
  52651. +#define DRAM_BUF_REG8 0x60b90 /* sdram ODT control high */
  52652. +#define DRAM_BUF_REG9 0x60b94 /* sdram Dunit ODT control */
  52653. +#define DRAM_BUF_REG10 0x60b98 /* sdram Extended Mode */
  52654. +#define DRAM_BUF_REG11 0x60b9c /* sdram Ddr2 Time Low Reg */
  52655. +#define DRAM_BUF_REG12 0x60a00 /* sdram Ddr2 Time High Reg */
  52656. +#define DRAM_BUF_REG13 0x60a04 /* dunit Ctrl High */
  52657. +#define DRAM_BUF_REG14 0x60b00 /* sdram second DIMM exist */
  52658. +
  52659. +/* Following the pre-configuration registers default values restored after */
  52660. +/* auto-detection is done */
  52661. +#define DRAM_BUF_REG_DV 0
  52662. +
  52663. +/* System Mapping */
  52664. +#define SDRAM_CS0_BASE 0x00000000
  52665. +#define SDRAM_CS0_SIZE _256M
  52666. +
  52667. +#define SDRAM_CS1_BASE 0x10000000
  52668. +#define SDRAM_CS1_SIZE _256M
  52669. +
  52670. +#define SDRAM_CS2_BASE 0x20000000
  52671. +#define SDRAM_CS2_SIZE _256M
  52672. +
  52673. +#define SDRAM_CS3_BASE 0x30000000
  52674. +#define SDRAM_CS3_SIZE _256M
  52675. +
  52676. +/* PEX */
  52677. +#define PEX0_MEM_BASE 0xe8000000
  52678. +#define PEX0_MEM_SIZE _128M
  52679. +
  52680. +#define PEX0_IO_BASE 0xf2000000
  52681. +#define PEX0_IO_SIZE _1M
  52682. +
  52683. +/* Device Chip Selects */
  52684. +#define NFLASH_CS_BASE 0xfa000000
  52685. +#define NFLASH_CS_SIZE _2M
  52686. +
  52687. +#define SPI_CS_BASE 0xf4000000
  52688. +#define SPI_CS_SIZE _16M
  52689. +
  52690. +#define CRYPT_ENG_BASE 0xf0000000
  52691. +#define CRYPT_ENG_SIZE _2M
  52692. +
  52693. +#define BOOTDEV_CS_BASE 0xff800000
  52694. +#define BOOTDEV_CS_SIZE _8M
  52695. +
  52696. +/* CS2 - BOOTROM */
  52697. +#define DEVICE_CS2_BASE 0xff900000
  52698. +#define DEVICE_CS2_SIZE _1M
  52699. +
  52700. +/* PEX Work arround */
  52701. +/* the target we will use for the workarround */
  52702. +#define PEX_CONFIG_RW_WA_TARGET PEX0_MEM
  52703. +/*a flag that indicates if we are going to use the
  52704. +size and base of the target we using for the workarround
  52705. +window */
  52706. +#define PEX_CONFIG_RW_WA_USE_ORIGINAL_WIN_VALUES 1
  52707. +/* if the above flag is 0 then the following values
  52708. +will be used for the workarround window base and size,
  52709. +otherwise the following defines will be ignored */
  52710. +#define PEX_CONFIG_RW_WA_BASE 0xF3000000
  52711. +#define PEX_CONFIG_RW_WA_SIZE _16M
  52712. +
  52713. +/* Internal registers: size is defined in Controllerenvironment */
  52714. +#define INTER_REGS_BASE 0xFEE00000
  52715. +
  52716. +/* DRAM detection stuff */
  52717. +#define MV_DRAM_AUTO_SIZE
  52718. +
  52719. +/* Board clock detection */
  52720. +#define TCLK_AUTO_DETECT /* Use Tclk auto detection */
  52721. +#define SYSCLK_AUTO_DETECT /* Use SysClk auto detection */
  52722. +#define PCLCK_AUTO_DETECT /* Use PClk auto detection */
  52723. +#define L2CLK_AUTO_DETECT /* Use L2Clk auto detection */
  52724. +
  52725. +/* PEX-PCI\PCI-PCI Bridge*/
  52726. +#define PCI0_IF_PTP 0 /* Bridge exist on pciIf0*/
  52727. +
  52728. +
  52729. +
  52730. +#endif /* __INCmvSysHwConfigh */
  52731. +
  52732. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c
  52733. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c 1970-01-01 01:00:00.000000000 +0100
  52734. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.c 2011-08-01 14:38:19.000000000 +0200
  52735. @@ -0,0 +1,376 @@
  52736. +/*******************************************************************************
  52737. +Copyright (C) Marvell International Ltd. and its affiliates
  52738. +
  52739. +This software file (the "File") is owned and distributed by Marvell
  52740. +International Ltd. and/or its affiliates ("Marvell") under the following
  52741. +alternative licensing terms. Once you have made an election to distribute the
  52742. +File under one of the following license alternatives, please (i) delete this
  52743. +introductory statement regarding license alternatives, (ii) delete the two
  52744. +license alternatives that you have not elected to use and (iii) preserve the
  52745. +Marvell copyright notice above.
  52746. +
  52747. +********************************************************************************
  52748. +Marvell Commercial License Option
  52749. +
  52750. +If you received this File from Marvell and you have entered into a commercial
  52751. +license agreement (a "Commercial License") with Marvell, the File is licensed
  52752. +to you under the terms of the applicable Commercial License.
  52753. +
  52754. +********************************************************************************
  52755. +Marvell GPL License Option
  52756. +
  52757. +If you received this File from Marvell, you may opt to use, redistribute and/or
  52758. +modify this File in accordance with the terms and conditions of the General
  52759. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  52760. +available along with the File in the license.txt file or by writing to the Free
  52761. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  52762. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  52763. +
  52764. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  52765. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  52766. +DISCLAIMED. The GPL License provides additional details about this warranty
  52767. +disclaimer.
  52768. +********************************************************************************
  52769. +Marvell BSD License Option
  52770. +
  52771. +If you received this File from Marvell, you may opt to use, redistribute and/or
  52772. +modify this File under the following licensing terms.
  52773. +Redistribution and use in source and binary forms, with or without modification,
  52774. +are permitted provided that the following conditions are met:
  52775. +
  52776. + * Redistributions of source code must retain the above copyright notice,
  52777. + this list of conditions and the following disclaimer.
  52778. +
  52779. + * Redistributions in binary form must reproduce the above copyright
  52780. + notice, this list of conditions and the following disclaimer in the
  52781. + documentation and/or other materials provided with the distribution.
  52782. +
  52783. + * Neither the name of Marvell nor the names of its contributors may be
  52784. + used to endorse or promote products derived from this software without
  52785. + specific prior written permission.
  52786. +
  52787. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  52788. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  52789. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  52790. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  52791. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  52792. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  52793. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  52794. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  52795. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  52796. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  52797. +
  52798. +*******************************************************************************/
  52799. +
  52800. +#include "mvCntmr.h"
  52801. +#include "cpu/mvCpu.h"
  52802. +
  52803. +/* defines */
  52804. +#ifdef MV_DEBUG
  52805. + #define DB(x) x
  52806. +#else
  52807. + #define DB(x)
  52808. +#endif
  52809. +
  52810. +extern unsigned int whoAmI(void);
  52811. +
  52812. +/*******************************************************************************
  52813. +* mvCntmrLoad -
  52814. +*
  52815. +* DESCRIPTION:
  52816. +* Load an init Value to a given counter/timer
  52817. +*
  52818. +* INPUT:
  52819. +* countNum - counter number
  52820. +* value - value to be loaded
  52821. +*
  52822. +* OUTPUT:
  52823. +* None.
  52824. +*
  52825. +* RETURN:
  52826. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  52827. +*******************************************************************************/
  52828. +MV_STATUS mvCntmrLoad(MV_U32 countNum, MV_U32 value)
  52829. +{
  52830. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  52831. + {
  52832. +
  52833. + mvOsPrintf(("mvCntmrLoad: Err. Illigal counter number \n"));
  52834. + return MV_BAD_PARAM;;
  52835. +
  52836. + }
  52837. +
  52838. + MV_REG_WRITE(CNTMR_RELOAD_REG(countNum),value);
  52839. + MV_REG_WRITE(CNTMR_VAL_REG(countNum),value);
  52840. +
  52841. + return MV_OK;
  52842. +}
  52843. +
  52844. +/*******************************************************************************
  52845. +* mvCntmrRead -
  52846. +*
  52847. +* DESCRIPTION:
  52848. +* Returns the value of the given Counter/Timer
  52849. +*
  52850. +* INPUT:
  52851. +* countNum - counter number
  52852. +*
  52853. +* OUTPUT:
  52854. +* None.
  52855. +*
  52856. +* RETURN:
  52857. +* MV_U32 counter value
  52858. +*******************************************************************************/
  52859. +MV_U32 mvCntmrRead(MV_U32 countNum)
  52860. +{
  52861. + return MV_REG_READ(CNTMR_VAL_REG(countNum));
  52862. +}
  52863. +
  52864. +/*******************************************************************************
  52865. +* mvCntmrWrite -
  52866. +*
  52867. +* DESCRIPTION:
  52868. +* Returns the value of the given Counter/Timer
  52869. +*
  52870. +* INPUT:
  52871. +* countNum - counter number
  52872. +* countVal - value to write
  52873. +*
  52874. +* OUTPUT:
  52875. +* None.
  52876. +*
  52877. +* RETURN:
  52878. +* None
  52879. +*******************************************************************************/
  52880. +void mvCntmrWrite(MV_U32 countNum,MV_U32 countVal)
  52881. +{
  52882. + MV_REG_WRITE(CNTMR_VAL_REG(countNum),countVal);
  52883. +}
  52884. +
  52885. +/*******************************************************************************
  52886. +* mvCntmrCtrlSet -
  52887. +*
  52888. +* DESCRIPTION:
  52889. +* Set the Control to a given counter/timer
  52890. +*
  52891. +* INPUT:
  52892. +* countNum - counter number
  52893. +* pCtrl - pointer to MV_CNTMR_CTRL structure
  52894. +*
  52895. +* OUTPUT:
  52896. +* None.
  52897. +*
  52898. +* RETURN:
  52899. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  52900. +*******************************************************************************/
  52901. +MV_STATUS mvCntmrCtrlSet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl)
  52902. +{
  52903. + MV_U32 cntmrCtrl;
  52904. +
  52905. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  52906. + {
  52907. +
  52908. + DB(mvOsPrintf(("mvCntmrCtrlSet: Err. Illigal counter number \n")));
  52909. + return MV_BAD_PARAM;;
  52910. +
  52911. + }
  52912. +
  52913. + /* read control register */
  52914. + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
  52915. +
  52916. +
  52917. + if (pCtrl->enable) /* enable counter\timer */
  52918. + {
  52919. + cntmrCtrl |= CTCR_ARM_TIMER_EN(countNum);
  52920. + }
  52921. + else /* disable counter\timer */
  52922. + {
  52923. + cntmrCtrl &= ~CTCR_ARM_TIMER_EN(countNum);
  52924. + }
  52925. +
  52926. + if ( pCtrl->autoEnable ) /* Auto mode */
  52927. + {
  52928. + cntmrCtrl |= CTCR_ARM_TIMER_AUTO_EN(countNum);
  52929. +
  52930. + }
  52931. + else /* no auto mode */
  52932. + {
  52933. + cntmrCtrl &= ~CTCR_ARM_TIMER_AUTO_EN(countNum);
  52934. + }
  52935. +
  52936. + MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);
  52937. +
  52938. + return MV_OK;
  52939. +
  52940. +}
  52941. +
  52942. +/*******************************************************************************
  52943. +* mvCntmrCtrlGet -
  52944. +*
  52945. +* DESCRIPTION:
  52946. +* Get the Control value of a given counter/timer
  52947. +*
  52948. +* INPUT:
  52949. +* countNum - counter number
  52950. +* pCtrl - pointer to MV_CNTMR_CTRL structure
  52951. +*
  52952. +* OUTPUT:
  52953. +* Counter\Timer control value
  52954. +*
  52955. +* RETURN:
  52956. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  52957. +*******************************************************************************/
  52958. +MV_STATUS mvCntmrCtrlGet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl)
  52959. +{
  52960. + MV_U32 cntmrCtrl;
  52961. +
  52962. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  52963. + {
  52964. + DB(mvOsPrintf(("mvCntmrCtrlGet: Err. Illigal counter number \n")));
  52965. + return MV_BAD_PARAM;;
  52966. + }
  52967. +
  52968. + /* read control register */
  52969. + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
  52970. +
  52971. + /* enable counter\timer */
  52972. + if (cntmrCtrl & CTCR_ARM_TIMER_EN(countNum))
  52973. + {
  52974. + pCtrl->enable = MV_TRUE;
  52975. + }
  52976. + else
  52977. + {
  52978. + pCtrl->enable = MV_FALSE;
  52979. + }
  52980. +
  52981. + /* counter mode */
  52982. + if (cntmrCtrl & CTCR_ARM_TIMER_AUTO_EN(countNum))
  52983. + {
  52984. + pCtrl->autoEnable = MV_TRUE;
  52985. + }
  52986. + else
  52987. + {
  52988. + pCtrl->autoEnable = MV_FALSE;
  52989. + }
  52990. +
  52991. + return MV_OK;
  52992. +}
  52993. +
  52994. +/*******************************************************************************
  52995. +* mvCntmrEnable -
  52996. +*
  52997. +* DESCRIPTION:
  52998. +* Set the Enable-Bit to logic '1' ==> starting the counter
  52999. +*
  53000. +* INPUT:
  53001. +* countNum - counter number
  53002. +*
  53003. +* OUTPUT:
  53004. +* None.
  53005. +*
  53006. +* RETURN:
  53007. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  53008. +*******************************************************************************/
  53009. +MV_STATUS mvCntmrEnable(MV_U32 countNum)
  53010. +{
  53011. + MV_U32 cntmrCtrl;
  53012. +
  53013. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  53014. + {
  53015. +
  53016. + DB(mvOsPrintf(("mvCntmrEnable: Err. Illigal counter number \n")));
  53017. + return MV_BAD_PARAM;;
  53018. +
  53019. + }
  53020. +
  53021. + /* read control register */
  53022. + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
  53023. +
  53024. + /* enable counter\timer */
  53025. + cntmrCtrl |= CTCR_ARM_TIMER_EN(countNum);
  53026. +
  53027. +
  53028. + MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);
  53029. +
  53030. + return MV_OK;
  53031. +}
  53032. +
  53033. +/*******************************************************************************
  53034. +* mvCntmrDisable -
  53035. +*
  53036. +* DESCRIPTION:
  53037. +* Stop the counter/timer running, and returns its Value
  53038. +*
  53039. +* INPUT:
  53040. +* countNum - counter number
  53041. +*
  53042. +* OUTPUT:
  53043. +* None.
  53044. +*
  53045. +* RETURN:
  53046. +* MV_U32 counter\timer value
  53047. +*******************************************************************************/
  53048. +MV_STATUS mvCntmrDisable(MV_U32 countNum)
  53049. +{
  53050. + MV_U32 cntmrCtrl;
  53051. +
  53052. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  53053. + {
  53054. +
  53055. + DB(mvOsPrintf(("mvCntmrDisable: Err. Illigal counter number \n")));
  53056. + return MV_BAD_PARAM;;
  53057. +
  53058. + }
  53059. +
  53060. + /* read control register */
  53061. + cntmrCtrl = MV_REG_READ(CNTMR_CTRL_REG);
  53062. +
  53063. + /* disable counter\timer */
  53064. + cntmrCtrl &= ~CTCR_ARM_TIMER_EN(countNum);
  53065. +
  53066. + MV_REG_WRITE(CNTMR_CTRL_REG,cntmrCtrl);
  53067. +
  53068. + return MV_OK;
  53069. +}
  53070. +
  53071. +/*******************************************************************************
  53072. +* mvCntmrStart -
  53073. +*
  53074. +* DESCRIPTION:
  53075. +* Combined all the sub-operations above to one function: Load,setMode,Enable
  53076. +*
  53077. +* INPUT:
  53078. +* countNum - counter number
  53079. +* value - value of the counter\timer to be set
  53080. +* pCtrl - pointer to MV_CNTMR_CTRL structure
  53081. +*
  53082. +* OUTPUT:
  53083. +* None.
  53084. +*
  53085. +* RETURN:
  53086. +* MV_BAD_PARAM on bad parameters , MV_ERROR on error ,MV_OK on sucess
  53087. +*******************************************************************************/
  53088. +MV_STATUS mvCntmrStart(MV_U32 countNum, MV_U32 value,
  53089. + MV_CNTMR_CTRL *pCtrl)
  53090. +{
  53091. +
  53092. + if (countNum >= MV_CNTMR_MAX_COUNTER )
  53093. + {
  53094. +
  53095. + mvOsPrintf(("mvCntmrDisable: Err. Illigal counter number \n"));
  53096. + return MV_BAD_PARAM;;
  53097. +
  53098. + }
  53099. +
  53100. + /* load value onto counter\timer */
  53101. + mvCntmrLoad(countNum,value);
  53102. +
  53103. + /* set the counter to load in the first time */
  53104. + mvCntmrWrite(countNum,value);
  53105. +
  53106. + /* set control for timer \ cunter and enable */
  53107. + mvCntmrCtrlSet(countNum,pCtrl);
  53108. +
  53109. + return MV_OK;
  53110. +}
  53111. +
  53112. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h
  53113. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h 1970-01-01 01:00:00.000000000 +0100
  53114. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmr.h 2011-08-01 14:38:19.000000000 +0200
  53115. @@ -0,0 +1,121 @@
  53116. +/*******************************************************************************
  53117. +Copyright (C) Marvell International Ltd. and its affiliates
  53118. +
  53119. +This software file (the "File") is owned and distributed by Marvell
  53120. +International Ltd. and/or its affiliates ("Marvell") under the following
  53121. +alternative licensing terms. Once you have made an election to distribute the
  53122. +File under one of the following license alternatives, please (i) delete this
  53123. +introductory statement regarding license alternatives, (ii) delete the two
  53124. +license alternatives that you have not elected to use and (iii) preserve the
  53125. +Marvell copyright notice above.
  53126. +
  53127. +********************************************************************************
  53128. +Marvell Commercial License Option
  53129. +
  53130. +If you received this File from Marvell and you have entered into a commercial
  53131. +license agreement (a "Commercial License") with Marvell, the File is licensed
  53132. +to you under the terms of the applicable Commercial License.
  53133. +
  53134. +********************************************************************************
  53135. +Marvell GPL License Option
  53136. +
  53137. +If you received this File from Marvell, you may opt to use, redistribute and/or
  53138. +modify this File in accordance with the terms and conditions of the General
  53139. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  53140. +available along with the File in the license.txt file or by writing to the Free
  53141. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  53142. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  53143. +
  53144. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  53145. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  53146. +DISCLAIMED. The GPL License provides additional details about this warranty
  53147. +disclaimer.
  53148. +********************************************************************************
  53149. +Marvell BSD License Option
  53150. +
  53151. +If you received this File from Marvell, you may opt to use, redistribute and/or
  53152. +modify this File under the following licensing terms.
  53153. +Redistribution and use in source and binary forms, with or without modification,
  53154. +are permitted provided that the following conditions are met:
  53155. +
  53156. + * Redistributions of source code must retain the above copyright notice,
  53157. + this list of conditions and the following disclaimer.
  53158. +
  53159. + * Redistributions in binary form must reproduce the above copyright
  53160. + notice, this list of conditions and the following disclaimer in the
  53161. + documentation and/or other materials provided with the distribution.
  53162. +
  53163. + * Neither the name of Marvell nor the names of its contributors may be
  53164. + used to endorse or promote products derived from this software without
  53165. + specific prior written permission.
  53166. +
  53167. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  53168. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  53169. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  53170. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  53171. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  53172. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  53173. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  53174. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  53175. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  53176. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  53177. +
  53178. +*******************************************************************************/
  53179. +
  53180. +#ifndef __INCmvTmrWtdgh
  53181. +#define __INCmvTmrWtdgh
  53182. +
  53183. +/* includes */
  53184. +#include "mvCommon.h"
  53185. +#include "mvOs.h"
  53186. +#include "cntmr/mvCntmrRegs.h"
  53187. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  53188. +
  53189. +
  53190. +/* This enumerator describe counters\watchdog numbers */
  53191. +typedef enum _mvCntmrID
  53192. +{
  53193. + TIMER0 = 0,
  53194. + TIMER1,
  53195. + WATCHDOG,
  53196. + TIMER2,
  53197. + TIMER3,
  53198. +}MV_CNTMR_ID;
  53199. +
  53200. +
  53201. +/* Counter / Timer control structure */
  53202. +typedef struct _mvCntmrCtrl
  53203. +{
  53204. + MV_BOOL enable; /* enable */
  53205. + MV_BOOL autoEnable; /* counter/Timer */
  53206. +}MV_CNTMR_CTRL;
  53207. +
  53208. +
  53209. +/* Functions */
  53210. +
  53211. +/* Load an init Value to a given counter/timer */
  53212. +MV_STATUS mvCntmrLoad(MV_U32 countNum, MV_U32 value);
  53213. +
  53214. +/* Returns the value of the given Counter/Timer */
  53215. +MV_U32 mvCntmrRead(MV_U32 countNum);
  53216. +
  53217. +/* Write a value of the given Counter/Timer */
  53218. +void mvCntmrWrite(MV_U32 countNum,MV_U32 countVal);
  53219. +
  53220. +/* Set the Control to a given counter/timer */
  53221. +MV_STATUS mvCntmrCtrlSet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl);
  53222. +
  53223. +/* Get the value of a given counter/timer */
  53224. +MV_STATUS mvCntmrCtrlGet(MV_U32 countNum, MV_CNTMR_CTRL *pCtrl);
  53225. +
  53226. +/* Set the Enable-Bit to logic '1' ==> starting the counter. */
  53227. +MV_STATUS mvCntmrEnable(MV_U32 countNum);
  53228. +
  53229. +/* Stop the counter/timer running, and returns its Value. */
  53230. +MV_STATUS mvCntmrDisable(MV_U32 countNum);
  53231. +
  53232. +/* Combined all the sub-operations above to one function: Load,setMode,Enable */
  53233. +MV_STATUS mvCntmrStart(MV_U32 countNum, MV_U32 value,
  53234. + MV_CNTMR_CTRL *pCtrl);
  53235. +
  53236. +#endif /* __INCmvTmrWtdgh */
  53237. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h
  53238. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h 1970-01-01 01:00:00.000000000 +0100
  53239. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cntmr/mvCntmrRegs.h 2011-08-01 14:38:19.000000000 +0200
  53240. @@ -0,0 +1,121 @@
  53241. +/*******************************************************************************
  53242. +Copyright (C) Marvell International Ltd. and its affiliates
  53243. +
  53244. +This software file (the "File") is owned and distributed by Marvell
  53245. +International Ltd. and/or its affiliates ("Marvell") under the following
  53246. +alternative licensing terms. Once you have made an election to distribute the
  53247. +File under one of the following license alternatives, please (i) delete this
  53248. +introductory statement regarding license alternatives, (ii) delete the two
  53249. +license alternatives that you have not elected to use and (iii) preserve the
  53250. +Marvell copyright notice above.
  53251. +
  53252. +********************************************************************************
  53253. +Marvell Commercial License Option
  53254. +
  53255. +If you received this File from Marvell and you have entered into a commercial
  53256. +license agreement (a "Commercial License") with Marvell, the File is licensed
  53257. +to you under the terms of the applicable Commercial License.
  53258. +
  53259. +********************************************************************************
  53260. +Marvell GPL License Option
  53261. +
  53262. +If you received this File from Marvell, you may opt to use, redistribute and/or
  53263. +modify this File in accordance with the terms and conditions of the General
  53264. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  53265. +available along with the File in the license.txt file or by writing to the Free
  53266. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  53267. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  53268. +
  53269. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  53270. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  53271. +DISCLAIMED. The GPL License provides additional details about this warranty
  53272. +disclaimer.
  53273. +********************************************************************************
  53274. +Marvell BSD License Option
  53275. +
  53276. +If you received this File from Marvell, you may opt to use, redistribute and/or
  53277. +modify this File under the following licensing terms.
  53278. +Redistribution and use in source and binary forms, with or without modification,
  53279. +are permitted provided that the following conditions are met:
  53280. +
  53281. + * Redistributions of source code must retain the above copyright notice,
  53282. + this list of conditions and the following disclaimer.
  53283. +
  53284. + * Redistributions in binary form must reproduce the above copyright
  53285. + notice, this list of conditions and the following disclaimer in the
  53286. + documentation and/or other materials provided with the distribution.
  53287. +
  53288. + * Neither the name of Marvell nor the names of its contributors may be
  53289. + used to endorse or promote products derived from this software without
  53290. + specific prior written permission.
  53291. +
  53292. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  53293. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  53294. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  53295. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  53296. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  53297. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  53298. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  53299. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  53300. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  53301. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  53302. +
  53303. +*******************************************************************************/
  53304. +
  53305. +#ifndef __INCmvTmrwtdgRegsh
  53306. +#define __INCmvTmrwtdgRegsh
  53307. +
  53308. +/*******************************************/
  53309. +/* ARM Timers Registers Map */
  53310. +/*******************************************/
  53311. +
  53312. +#define CNTMR_RELOAD_REG(tmrNum) (CNTMR_BASE + 0x10 + (tmrNum)*8 + \
  53313. + (((tmrNum) <= 3)?0:8))
  53314. +#define CNTMR_VAL_REG(tmrNum) (CNTMR_BASE + 0x14 + (tmrNum)*8 + \
  53315. + (((tmrNum) <= 3)?0:8))
  53316. +#define CNTMR_CTRL_REG (CNTMR_BASE)
  53317. +
  53318. +/*For MV78XX0*/
  53319. +#define CNTMR_CAUSE_REG (CPU_AHB_MBUS_CAUSE_INT_REG(whoAmI()))
  53320. +#define CNTMR_MASK_REG (CPU_AHB_MBUS_MASK_INT_REG(whoAmI()))
  53321. +
  53322. +/* ARM Timers Registers Map */
  53323. +/*******************************************/
  53324. +
  53325. +
  53326. +/* ARM Timers Control Register */
  53327. +/* CPU_TIMERS_CTRL_REG (CTCR) */
  53328. +
  53329. +#define TIMER0_NUM 0
  53330. +#define TIMER1_NUM 1
  53331. +#define WATCHDOG_NUM 2
  53332. +#define TIMER2_NUM 3
  53333. +#define TIMER3_NUM 4
  53334. +
  53335. +#define CTCR_ARM_TIMER_EN_OFFS(cntr) (cntr * 2)
  53336. +#define CTCR_ARM_TIMER_EN_MASK(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS)
  53337. +#define CTCR_ARM_TIMER_EN(cntr) (1 << CTCR_ARM_TIMER_EN_OFFS(cntr))
  53338. +#define CTCR_ARM_TIMER_DIS(cntr) (0 << CTCR_ARM_TIMER_EN_OFFS(cntr))
  53339. +
  53340. +#define CTCR_ARM_TIMER_AUTO_OFFS(cntr) ((cntr * 2) + 1)
  53341. +#define CTCR_ARM_TIMER_AUTO_MASK(cntr) BIT1
  53342. +#define CTCR_ARM_TIMER_AUTO_EN(cntr) (1 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
  53343. +#define CTCR_ARM_TIMER_AUTO_DIS(cntr) (0 << CTCR_ARM_TIMER_AUTO_OFFS(cntr))
  53344. +
  53345. +
  53346. +/* ARM Timer\Watchdog Reload Register */
  53347. +/* CNTMR_RELOAD_REG (TRR) */
  53348. +
  53349. +#define TRG_ARM_TIMER_REL_OFFS 0
  53350. +#define TRG_ARM_TIMER_REL_MASK 0xffffffff
  53351. +
  53352. +/* ARM Timer\Watchdog Register */
  53353. +/* CNTMR_VAL_REG (TVRG) */
  53354. +
  53355. +#define TVR_ARM_TIMER_OFFS 0
  53356. +#define TVR_ARM_TIMER_MASK 0xffffffff
  53357. +#define TVR_ARM_TIMER_MAX 0xffffffff
  53358. +
  53359. +
  53360. +
  53361. +#endif /* __INCmvTmrwtdgRegsh */
  53362. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c
  53363. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c 1970-01-01 01:00:00.000000000 +0100
  53364. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.c 2011-08-01 14:38:19.000000000 +0200
  53365. @@ -0,0 +1,207 @@
  53366. +/*
  53367. + * This program is free software; you can redistribute it and/or modify
  53368. + * it under the terms of the GNU General Public License as published by
  53369. + * the Free Software Foundation; either version 2 of the License, or
  53370. + * (at your option) any later version.
  53371. + *
  53372. + * This program is distributed in the hope that it will be useful,
  53373. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  53374. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  53375. + * GNU General Public License for more details.
  53376. + *
  53377. + * You should have received a copy of the GNU General Public License
  53378. + * along with this program; if not, write to the Free Software
  53379. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  53380. + */
  53381. +
  53382. +#include "mvOs.h"
  53383. +#include "mvCpuCntrs.h"
  53384. +
  53385. +
  53386. +const static MV_CPU_CNTRS_OPS mvCpuCntrsOpsTbl[MV_CPU_CNTRS_NUM][MV_CPU_CNTRS_OPS_NUM] =
  53387. +{
  53388. + /*0*/
  53389. + {
  53390. + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_DCACHE_READ_HIT, MV_CPU_CNTRS_DCACHE_READ_MISS,
  53391. + MV_CPU_CNTRS_DCACHE_WRITE_HIT, MV_CPU_CNTRS_DCACHE_WRITE_MISS, MV_CPU_CNTRS_INSTRUCTIONS,
  53392. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  53393. + MV_CPU_CNTRS_MMU_READ_LATENCY, MV_CPU_CNTRS_ICACHE_READ_LATENCY, MV_CPU_CNTRS_WB_WRITE_LATENCY,
  53394. + MV_CPU_CNTRS_LDM_STM_HOLD, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  53395. + MV_CPU_CNTRS_DATA_WRITE_ACCESS, MV_CPU_CNTRS_DATA_READ_ACCESS, MV_CPU_CNTRS_INVALID,
  53396. + MV_CPU_CNTRS_BRANCH_PREDICT_COUNT,
  53397. + },
  53398. + /*1*/
  53399. + {
  53400. + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_ICACHE_READ_MISS, MV_CPU_CNTRS_DCACHE_READ_MISS,
  53401. + MV_CPU_CNTRS_DCACHE_WRITE_MISS, MV_CPU_CNTRS_ITLB_MISS, MV_CPU_CNTRS_SINGLE_ISSUE,
  53402. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BRANCH_RETIRED, MV_CPU_CNTRS_INVALID,
  53403. + MV_CPU_CNTRS_MMU_READ_BEAT, MV_CPU_CNTRS_ICACHE_READ_LATENCY, MV_CPU_CNTRS_WB_WRITE_BEAT,
  53404. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_IS_HOLD, MV_CPU_CNTRS_DATA_READ_ACCESS,
  53405. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  53406. + MV_CPU_CNTRS_INVALID,
  53407. + },
  53408. + /*2*/
  53409. + {
  53410. + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DCACHE_ACCESS,
  53411. + MV_CPU_CNTRS_DTLB_MISS, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  53412. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BRANCH_PREDICT_MISS, MV_CPU_CNTRS_WB_WRITE_BEAT,
  53413. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DCACHE_READ_LATENCY, MV_CPU_CNTRS_DCACHE_WRITE_LATENCY,
  53414. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BIU_SIMULT_ACCESS,
  53415. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  53416. + MV_CPU_CNTRS_INVALID,
  53417. + },
  53418. + /*3*/
  53419. + {
  53420. + MV_CPU_CNTRS_CYCLES, MV_CPU_CNTRS_DCACHE_READ_MISS, MV_CPU_CNTRS_DCACHE_WRITE_MISS,
  53421. + MV_CPU_CNTRS_TLB_MISS, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID,
  53422. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BRANCH_TAKEN, MV_CPU_CNTRS_WB_FULL_CYCLES,
  53423. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DCACHE_READ_BEAT, MV_CPU_CNTRS_DCACHE_WRITE_BEAT,
  53424. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_BIU_ANY_ACCESS,
  53425. + MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_INVALID, MV_CPU_CNTRS_DATA_WRITE_ACCESS,
  53426. + MV_CPU_CNTRS_INVALID,
  53427. + }
  53428. +};
  53429. +
  53430. +MV_CPU_CNTRS_ENTRY mvCpuCntrsTbl[MV_CPU_CNTRS_NUM];
  53431. +
  53432. +MV_CPU_CNTRS_EVENT* mvCpuCntrsEventTbl[128];
  53433. +
  53434. +void mvCpuCntrsReset(void)
  53435. +{
  53436. + MV_U32 reg = 0;
  53437. +
  53438. + MV_ASM ("mcr p15, 0, %0, c15, c13, 0" : : "r" (reg));
  53439. + MV_ASM ("mcr p15, 0, %0, c15, c13, 1" : : "r" (reg));
  53440. + MV_ASM ("mcr p15, 0, %0, c15, c13, 2" : : "r" (reg));
  53441. + MV_ASM ("mcr p15, 0, %0, c15, c13, 3" : : "r" (reg));
  53442. + MV_ASM ("mcr p15, 0, %0, c15, c13, 4" : : "r" (reg));
  53443. + MV_ASM ("mcr p15, 0, %0, c15, c13, 5" : : "r" (reg));
  53444. + MV_ASM ("mcr p15, 0, %0, c15, c13, 6" : : "r" (reg));
  53445. + MV_ASM ("mcr p15, 0, %0, c15, c13, 7" : : "r" (reg));
  53446. +}
  53447. +
  53448. +void program_counter(int counter, int op)
  53449. +{
  53450. + MV_U32 reg = (1 << op) | 0x1; /*enable*/
  53451. +
  53452. + switch(counter)
  53453. + {
  53454. + case 0:
  53455. + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 0" : : "r" (reg));
  53456. + return;
  53457. +
  53458. + case 1:
  53459. + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 1" : : "r" (reg));
  53460. + return;
  53461. +
  53462. + case 2:
  53463. + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 2" : : "r" (reg));
  53464. + return;
  53465. +
  53466. + case 3:
  53467. + __asm__ __volatile__ ("mcr p15, 0, %0, c15, c12, 3" : : "r" (reg));
  53468. + return;
  53469. +
  53470. + default:
  53471. + mvOsPrintf("error in program_counter: bad counter number (%d)\n", counter);
  53472. + }
  53473. + return;
  53474. +}
  53475. +
  53476. +void mvCpuCntrsEventClear(MV_CPU_CNTRS_EVENT* pEvent)
  53477. +{
  53478. + int i;
  53479. +
  53480. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  53481. + {
  53482. + pEvent->counters_sum[i] = 0;
  53483. + }
  53484. + pEvent->num_of_measurements = 0;
  53485. +}
  53486. +
  53487. +
  53488. +MV_CPU_CNTRS_EVENT* mvCpuCntrsEventCreate(char* name, MV_U32 print_threshold)
  53489. +{
  53490. + int i;
  53491. + MV_CPU_CNTRS_EVENT* event = mvOsMalloc(sizeof(MV_CPU_CNTRS_EVENT));
  53492. +
  53493. + if(event)
  53494. + {
  53495. + strncpy(event->name, name, sizeof(event->name));
  53496. + event->num_of_measurements = 0;
  53497. + event->avg_sample_count = print_threshold;
  53498. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  53499. + {
  53500. + event->counters_before[i] = 0;
  53501. + event->counters_after[i] = 0;
  53502. + event->counters_sum[i] = 0;
  53503. + }
  53504. + }
  53505. + return event;
  53506. +}
  53507. +
  53508. +void mvCpuCntrsEventDelete(MV_CPU_CNTRS_EVENT* event)
  53509. +{
  53510. + if(event != NULL)
  53511. + mvOsFree(event);
  53512. +}
  53513. +
  53514. +
  53515. +MV_STATUS mvCpuCntrsProgram(int counter, MV_CPU_CNTRS_OPS op,
  53516. + char* name, MV_U32 overhead)
  53517. +{
  53518. + int i;
  53519. +
  53520. + /* Find required operations */
  53521. + for(i=0; i<MV_CPU_CNTRS_OPS_NUM; i++)
  53522. + {
  53523. + if( mvCpuCntrsOpsTbl[counter][i] == op)
  53524. + {
  53525. + strncpy(mvCpuCntrsTbl[counter].name, name, sizeof(mvCpuCntrsTbl[counter].name));
  53526. + mvCpuCntrsTbl[counter].operation = op;
  53527. + mvCpuCntrsTbl[counter].opIdx = i+1;
  53528. + mvCpuCntrsTbl[counter].overhead = overhead;
  53529. + program_counter(counter, mvCpuCntrsTbl[counter].opIdx);
  53530. + mvOsPrintf("Counter=%d, opIdx=%d, overhead=%d\n",
  53531. + counter, mvCpuCntrsTbl[counter].opIdx, mvCpuCntrsTbl[counter].overhead);
  53532. + return MV_OK;
  53533. + }
  53534. + }
  53535. + return MV_NOT_FOUND;
  53536. +}
  53537. +
  53538. +void mvCpuCntrsShow(MV_CPU_CNTRS_EVENT* pEvent)
  53539. +{
  53540. + int i;
  53541. + MV_U64 counters_avg;
  53542. +
  53543. + if(pEvent->num_of_measurements < pEvent->avg_sample_count)
  53544. + return;
  53545. +
  53546. + mvOsPrintf("%16s: ", pEvent->name);
  53547. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  53548. + {
  53549. + counters_avg = mvOsDivMod64(pEvent->counters_sum[i],
  53550. + pEvent->num_of_measurements, NULL);
  53551. + if(counters_avg >= mvCpuCntrsTbl[i].overhead)
  53552. + counters_avg -= mvCpuCntrsTbl[i].overhead;
  53553. + else
  53554. + counters_avg = 0;
  53555. +
  53556. + mvOsPrintf("%s=%5llu, ", mvCpuCntrsTbl[i].name, counters_avg);
  53557. + }
  53558. + mvOsPrintf("\n");
  53559. + mvCpuCntrsEventClear(pEvent);
  53560. + mvCpuCntrsReset();
  53561. +}
  53562. +
  53563. +void mvCpuCntrsStatus(void)
  53564. +{
  53565. + int i;
  53566. +
  53567. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  53568. + {
  53569. + mvOsPrintf("#%d: %s, overhead=%d\n",
  53570. + i, mvCpuCntrsTbl[i].name, mvCpuCntrsTbl[i].overhead);
  53571. + }
  53572. +}
  53573. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h
  53574. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h 1970-01-01 01:00:00.000000000 +0100
  53575. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuCntrs.h 2011-08-01 14:38:19.000000000 +0200
  53576. @@ -0,0 +1,213 @@
  53577. +/*******************************************************************************
  53578. +Copyright (C) Marvell International Ltd. and its affiliates
  53579. +
  53580. +This software file (the "File") is owned and distributed by Marvell
  53581. +International Ltd. and/or its affiliates ("Marvell") under the following
  53582. +alternative licensing terms. Once you have made an election to distribute the
  53583. +File under one of the following license alternatives, please (i) delete this
  53584. +introductory statement regarding license alternatives, (ii) delete the two
  53585. +license alternatives that you have not elected to use and (iii) preserve the
  53586. +Marvell copyright notice above.
  53587. +
  53588. +
  53589. +********************************************************************************
  53590. +Marvell GPL License Option
  53591. +
  53592. +If you received this File from Marvell, you may opt to use, redistribute and/or
  53593. +modify this File in accordance with the terms and conditions of the General
  53594. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  53595. +available along with the File in the license.txt file or by writing to the Free
  53596. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  53597. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  53598. +
  53599. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  53600. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  53601. +DISCLAIMED. The GPL License provides additional details about this warranty
  53602. +disclaimer.
  53603. +*******************************************************************************/
  53604. +#ifndef __mvCpuCntrs_h__
  53605. +#define __mvCpuCntrs_h__
  53606. +
  53607. +#include "mvTypes.h"
  53608. +#include "mvOs.h"
  53609. +
  53610. +
  53611. +#define MV_CPU_CNTRS_NUM 4
  53612. +#define MV_CPU_CNTRS_OPS_NUM 32
  53613. +
  53614. +typedef enum
  53615. +{
  53616. + MV_CPU_CNTRS_INVALID = 0,
  53617. + MV_CPU_CNTRS_CYCLES,
  53618. + MV_CPU_CNTRS_ICACHE_READ_MISS,
  53619. + MV_CPU_CNTRS_DCACHE_ACCESS,
  53620. + MV_CPU_CNTRS_DCACHE_READ_MISS,
  53621. + MV_CPU_CNTRS_DCACHE_READ_HIT,
  53622. + MV_CPU_CNTRS_DCACHE_WRITE_MISS,
  53623. + MV_CPU_CNTRS_DCACHE_WRITE_HIT,
  53624. + MV_CPU_CNTRS_DTLB_MISS,
  53625. + MV_CPU_CNTRS_TLB_MISS,
  53626. + MV_CPU_CNTRS_ITLB_MISS,
  53627. + MV_CPU_CNTRS_INSTRUCTIONS,
  53628. + MV_CPU_CNTRS_SINGLE_ISSUE,
  53629. + MV_CPU_CNTRS_MMU_READ_LATENCY,
  53630. + MV_CPU_CNTRS_MMU_READ_BEAT,
  53631. + MV_CPU_CNTRS_BRANCH_RETIRED,
  53632. + MV_CPU_CNTRS_BRANCH_TAKEN,
  53633. + MV_CPU_CNTRS_BRANCH_PREDICT_MISS,
  53634. + MV_CPU_CNTRS_BRANCH_PREDICT_COUNT,
  53635. + MV_CPU_CNTRS_WB_FULL_CYCLES,
  53636. + MV_CPU_CNTRS_WB_WRITE_LATENCY,
  53637. + MV_CPU_CNTRS_WB_WRITE_BEAT,
  53638. + MV_CPU_CNTRS_ICACHE_READ_LATENCY,
  53639. + MV_CPU_CNTRS_ICACHE_READ_BEAT,
  53640. + MV_CPU_CNTRS_DCACHE_READ_LATENCY,
  53641. + MV_CPU_CNTRS_DCACHE_READ_BEAT,
  53642. + MV_CPU_CNTRS_DCACHE_WRITE_LATENCY,
  53643. + MV_CPU_CNTRS_DCACHE_WRITE_BEAT,
  53644. + MV_CPU_CNTRS_LDM_STM_HOLD,
  53645. + MV_CPU_CNTRS_IS_HOLD,
  53646. + MV_CPU_CNTRS_DATA_WRITE_ACCESS,
  53647. + MV_CPU_CNTRS_DATA_READ_ACCESS,
  53648. + MV_CPU_CNTRS_BIU_SIMULT_ACCESS,
  53649. + MV_CPU_CNTRS_BIU_ANY_ACCESS,
  53650. +
  53651. +} MV_CPU_CNTRS_OPS;
  53652. +
  53653. +typedef struct
  53654. +{
  53655. + char name[16];
  53656. + MV_CPU_CNTRS_OPS operation;
  53657. + int opIdx;
  53658. + MV_U32 overhead;
  53659. +
  53660. +} MV_CPU_CNTRS_ENTRY;
  53661. +
  53662. +
  53663. +typedef struct
  53664. +{
  53665. + char name[16];
  53666. + MV_U32 num_of_measurements;
  53667. + MV_U32 avg_sample_count;
  53668. + MV_U64 counters_before[MV_CPU_CNTRS_NUM];
  53669. + MV_U64 counters_after[MV_CPU_CNTRS_NUM];
  53670. + MV_U64 counters_sum[MV_CPU_CNTRS_NUM];
  53671. +
  53672. +} MV_CPU_CNTRS_EVENT;
  53673. +
  53674. +extern MV_CPU_CNTRS_ENTRY mvCpuCntrsTbl[MV_CPU_CNTRS_NUM];
  53675. +
  53676. +
  53677. +MV_STATUS mvCpuCntrsProgram(int counter, MV_CPU_CNTRS_OPS op,
  53678. + char* name, MV_U32 overhead);
  53679. +void mvCpuCntrsInit(void);
  53680. +MV_CPU_CNTRS_EVENT* mvCpuCntrsEventCreate(char* name, MV_U32 print_threshold);
  53681. +void mvCpuCntrsEventDelete(MV_CPU_CNTRS_EVENT* event);
  53682. +void mvCpuCntrsReset(void);
  53683. +void mvCpuCntrsShow(MV_CPU_CNTRS_EVENT* pEvent);
  53684. +void mvCpuCntrsEventClear(MV_CPU_CNTRS_EVENT* pEvent);
  53685. +
  53686. +/* internal */
  53687. +void program_counter(int counter, int op);
  53688. +
  53689. +static INLINE MV_U64 mvCpuCntrsRead(const int counter)
  53690. +{
  53691. + MV_U32 low = 0, high = 0;
  53692. + MV_U32 ll = 0;
  53693. +
  53694. + switch(counter)
  53695. + {
  53696. + case 0:
  53697. + MV_ASM ("mcr p15, 0, %0, c15, c12, 0" : : "r" (ll));
  53698. + MV_ASM ("mrc p15, 0, %0, c15, c13, 0" : "=r" (low));
  53699. + MV_ASM ("mrc p15, 0, %0, c15, c13, 1" : "=r" (high));
  53700. + break;
  53701. +
  53702. + case 1:
  53703. + MV_ASM ("mcr p15, 0, %0, c15, c12, 1" : : "r" (ll));
  53704. + MV_ASM ("mrc p15, 0, %0, c15, c13, 2" : "=r" (low));
  53705. + MV_ASM ("mrc p15, 0, %0, c15, c13, 3" : "=r" (high));
  53706. + break;
  53707. +
  53708. + case 2:
  53709. + MV_ASM ("mcr p15, 0, %0, c15, c12, 2" : : "r" (ll));
  53710. + MV_ASM ("mrc p15, 0, %0, c15, c13, 4" : "=r" (low));
  53711. + MV_ASM ("mrc p15, 0, %0, c15, c13, 5" : "=r" (high));
  53712. + break;
  53713. +
  53714. + case 3:
  53715. + MV_ASM ("mcr p15, 0, %0, c15, c12, 3" : : "r" (ll));
  53716. + MV_ASM ("mrc p15, 0, %0, c15, c13, 6" : "=r" (low));
  53717. + MV_ASM ("mrc p15, 0, %0, c15, c13, 7" : "=r" (high));
  53718. + break;
  53719. +
  53720. + default:
  53721. + mvOsPrintf("mv_cpu_cntrs_read: bad counter number (%d)\n", counter);
  53722. + }
  53723. + program_counter(counter, mvCpuCntrsTbl[counter].opIdx);
  53724. + return (((MV_U64)high << 32 ) | low);
  53725. +
  53726. +}
  53727. +
  53728. +
  53729. +static INLINE void mvCpuCntrsReadBefore(MV_CPU_CNTRS_EVENT* pEvent)
  53730. +{
  53731. +#if 0
  53732. + int i;
  53733. +
  53734. + /* order is important - we want to measure the cycle count last here! */
  53735. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  53736. + pEvent->counters_before[i] = mvCpuCntrsRead(i);
  53737. +#else
  53738. + pEvent->counters_before[1] = mvCpuCntrsRead(1);
  53739. + pEvent->counters_before[3] = mvCpuCntrsRead(3);
  53740. + pEvent->counters_before[0] = mvCpuCntrsRead(0);
  53741. + pEvent->counters_before[2] = mvCpuCntrsRead(2);
  53742. +#endif
  53743. +}
  53744. +
  53745. +static INLINE void mvCpuCntrsReadAfter(MV_CPU_CNTRS_EVENT* pEvent)
  53746. +{
  53747. + int i;
  53748. +
  53749. +#if 0
  53750. + /* order is important - we want to measure the cycle count first here! */
  53751. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  53752. + pEvent->counters_after[i] = mvCpuCntrsRead(i);
  53753. +#else
  53754. + pEvent->counters_after[2] = mvCpuCntrsRead(2);
  53755. + pEvent->counters_after[0] = mvCpuCntrsRead(0);
  53756. + pEvent->counters_after[3] = mvCpuCntrsRead(3);
  53757. + pEvent->counters_after[1] = mvCpuCntrsRead(1);
  53758. +#endif
  53759. +
  53760. + for(i=0; i<MV_CPU_CNTRS_NUM; i++)
  53761. + {
  53762. + pEvent->counters_sum[i] += (pEvent->counters_after[i] - pEvent->counters_before[i]);
  53763. + }
  53764. + pEvent->num_of_measurements++;
  53765. +}
  53766. +
  53767. +
  53768. +#ifdef CONFIG_MV_CPU_PERF_CNTRS
  53769. +
  53770. +#define MV_CPU_CNTRS_READ(counter) mvCpuCntrsRead(counter)
  53771. +
  53772. +#define MV_CPU_CNTRS_START(event) mvCpuCntrsReadBefore(event)
  53773. +
  53774. +#define MV_CPU_CNTRS_STOP(event) mvCpuCntrsReadAfter(event)
  53775. +
  53776. +#define MV_CPU_CNTRS_SHOW(event) mvCpuCntrsShow(event)
  53777. +
  53778. +#else
  53779. +
  53780. +#define MV_CPU_CNTRS_READ(counter)
  53781. +#define MV_CPU_CNTRS_START(event)
  53782. +#define MV_CPU_CNTRS_STOP(event)
  53783. +#define MV_CPU_CNTRS_SHOW(event)
  53784. +
  53785. +#endif /* CONFIG_MV_CPU_PERF_CNTRS */
  53786. +
  53787. +
  53788. +#endif /* __mvCpuCntrs_h__ */
  53789. +
  53790. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c
  53791. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c 1970-01-01 01:00:00.000000000 +0100
  53792. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.c 2011-08-01 14:38:19.000000000 +0200
  53793. @@ -0,0 +1,143 @@
  53794. +/*
  53795. + * This program is free software; you can redistribute it and/or modify
  53796. + * it under the terms of the GNU General Public License as published by
  53797. + * the Free Software Foundation; either version 2 of the License, or
  53798. + * (at your option) any later version.
  53799. + *
  53800. + * This program is distributed in the hope that it will be useful,
  53801. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  53802. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  53803. + * GNU General Public License for more details.
  53804. + *
  53805. + * You should have received a copy of the GNU General Public License
  53806. + * along with this program; if not, write to the Free Software
  53807. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  53808. + */
  53809. +
  53810. +#include "mvOs.h"
  53811. +#include "mvCpuL2Cntrs.h"
  53812. +
  53813. +
  53814. +
  53815. +MV_CPU_L2_CNTRS_ENTRY mvCpuL2CntrsTbl[MV_CPU_L2_CNTRS_NUM];
  53816. +
  53817. +MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventTbl[128];
  53818. +
  53819. +void mvCpuL2CntrsReset(void)
  53820. +{
  53821. + MV_U32 reg = 0;
  53822. +
  53823. + MV_ASM ("mcr p15, 6, %0, c15, c13, 0" : : "r" (reg));
  53824. + MV_ASM ("mcr p15, 6, %0, c15, c13, 1" : : "r" (reg));
  53825. + MV_ASM ("mcr p15, 6, %0, c15, c13, 2" : : "r" (reg));
  53826. + MV_ASM ("mcr p15, 6, %0, c15, c13, 3" : : "r" (reg));
  53827. +}
  53828. +
  53829. +static void mvCpuL2CntrConfig(int counter, int op)
  53830. +{
  53831. + MV_U32 reg = (1 << op) | 0x1; /*enable*/
  53832. +
  53833. + switch(counter)
  53834. + {
  53835. + case 0:
  53836. + MV_ASM ("mcr p15, 6, %0, c15, c12, 0" : : "r" (reg));
  53837. + return;
  53838. +
  53839. + case 1:
  53840. + MV_ASM ("mcr p15, 6, %0, c15, c12, 1" : : "r" (reg));
  53841. + return;
  53842. +
  53843. + default:
  53844. + mvOsPrintf("mvCpuL2CntrConfig: bad counter number (%d)\n", counter);
  53845. + }
  53846. + return;
  53847. +}
  53848. +
  53849. +void mvCpuL2CntrsEventClear(MV_CPU_L2_CNTRS_EVENT* pEvent)
  53850. +{
  53851. + int i;
  53852. +
  53853. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  53854. + {
  53855. + pEvent->counters_sum[i] = 0;
  53856. + }
  53857. + pEvent->num_of_measurements = 0;
  53858. +}
  53859. +
  53860. +
  53861. +MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventCreate(char* name, MV_U32 print_threshold)
  53862. +{
  53863. + int i;
  53864. + MV_CPU_L2_CNTRS_EVENT* event = mvOsMalloc(sizeof(MV_CPU_L2_CNTRS_EVENT));
  53865. +
  53866. + if(event)
  53867. + {
  53868. + strncpy(event->name, name, sizeof(event->name));
  53869. + event->num_of_measurements = 0;
  53870. + event->avg_sample_count = print_threshold;
  53871. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  53872. + {
  53873. + event->counters_before[i] = 0;
  53874. + event->counters_after[i] = 0;
  53875. + event->counters_sum[i] = 0;
  53876. + }
  53877. + }
  53878. + return event;
  53879. +}
  53880. +
  53881. +void mvCpuL2CntrsEventDelete(MV_CPU_L2_CNTRS_EVENT* event)
  53882. +{
  53883. + if(event != NULL)
  53884. + mvOsFree(event);
  53885. +}
  53886. +
  53887. +
  53888. +MV_STATUS mvCpuL2CntrsProgram(int counter, MV_CPU_L2_CNTRS_OPS op,
  53889. + char* name, MV_U32 overhead)
  53890. +{
  53891. + strncpy(mvCpuL2CntrsTbl[counter].name, name, sizeof(mvCpuL2CntrsTbl[counter].name));
  53892. + mvCpuL2CntrsTbl[counter].operation = op;
  53893. + mvCpuL2CntrsTbl[counter].opIdx = op;
  53894. + mvCpuL2CntrsTbl[counter].overhead = overhead;
  53895. + mvCpuL2CntrConfig(counter, op);
  53896. + mvOsPrintf("CPU L2 Counter %d: operation=%d, overhead=%d\n",
  53897. + counter, op, overhead);
  53898. + return MV_OK;
  53899. +}
  53900. +
  53901. +void mvCpuL2CntrsShow(MV_CPU_L2_CNTRS_EVENT* pEvent)
  53902. +{
  53903. + int i;
  53904. + MV_U64 counters_avg;
  53905. +
  53906. + if(pEvent->num_of_measurements < pEvent->avg_sample_count)
  53907. + return;
  53908. +
  53909. + mvOsPrintf("%16s: ", pEvent->name);
  53910. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  53911. + {
  53912. + counters_avg = mvOsDivMod64(pEvent->counters_sum[i],
  53913. + pEvent->num_of_measurements, NULL);
  53914. +
  53915. + if(counters_avg >= mvCpuL2CntrsTbl[i].overhead)
  53916. + counters_avg -= mvCpuL2CntrsTbl[i].overhead;
  53917. + else
  53918. + counters_avg = 0;
  53919. +
  53920. + mvOsPrintf("%s=%5llu, ", mvCpuL2CntrsTbl[i].name, counters_avg);
  53921. + }
  53922. + mvOsPrintf("\n");
  53923. + mvCpuL2CntrsEventClear(pEvent);
  53924. + mvCpuL2CntrsReset();
  53925. +}
  53926. +
  53927. +void mvCpuL2CntrsStatus(void)
  53928. +{
  53929. + int i;
  53930. +
  53931. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  53932. + {
  53933. + mvOsPrintf("#%d: %s, overhead=%d\n",
  53934. + i, mvCpuL2CntrsTbl[i].name, mvCpuL2CntrsTbl[i].overhead);
  53935. + }
  53936. +}
  53937. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h
  53938. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h 1970-01-01 01:00:00.000000000 +0100
  53939. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/cpu/mvCpuL2Cntrs.h 2011-08-01 14:38:19.000000000 +0200
  53940. @@ -0,0 +1,151 @@
  53941. +/*******************************************************************************
  53942. +Copyright (C) Marvell International Ltd. and its affiliates
  53943. +
  53944. +This software file (the "File") is owned and distributed by Marvell
  53945. +International Ltd. and/or its affiliates ("Marvell") under the following
  53946. +alternative licensing terms. Once you have made an election to distribute the
  53947. +File under one of the following license alternatives, please (i) delete this
  53948. +introductory statement regarding license alternatives, (ii) delete the two
  53949. +license alternatives that you have not elected to use and (iii) preserve the
  53950. +Marvell copyright notice above.
  53951. +
  53952. +
  53953. +********************************************************************************
  53954. +Marvell GPL License Option
  53955. +
  53956. +If you received this File from Marvell, you may opt to use, redistribute and/or
  53957. +modify this File in accordance with the terms and conditions of the General
  53958. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  53959. +available along with the File in the license.txt file or by writing to the Free
  53960. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  53961. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  53962. +
  53963. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  53964. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  53965. +DISCLAIMED. The GPL License provides additional details about this warranty
  53966. +disclaimer.
  53967. +*******************************************************************************/
  53968. +#ifndef __mvCpuL2Cntrs_h__
  53969. +#define __mvCpuL2Cntrs_h__
  53970. +
  53971. +#include "mvTypes.h"
  53972. +#include "mvOs.h"
  53973. +
  53974. +
  53975. +#define MV_CPU_L2_CNTRS_NUM 2
  53976. +
  53977. +typedef enum
  53978. +{
  53979. + MV_CPU_L2_CNTRS_ENABLE = 0,
  53980. + MV_CPU_L2_CNTRS_DATA_REQ,
  53981. + MV_CPU_L2_CNTRS_DATA_MISS_REQ,
  53982. + MV_CPU_L2_CNTRS_INST_REQ,
  53983. + MV_CPU_L2_CNTRS_INST_MISS_REQ,
  53984. + MV_CPU_L2_CNTRS_DATA_READ_REQ,
  53985. + MV_CPU_L2_CNTRS_DATA_READ_MISS_REQ,
  53986. + MV_CPU_L2_CNTRS_DATA_WRITE_REQ,
  53987. + MV_CPU_L2_CNTRS_DATA_WRITE_MISS_REQ,
  53988. + MV_CPU_L2_CNTRS_RESERVED,
  53989. + MV_CPU_L2_CNTRS_DIRTY_EVICT_REQ,
  53990. + MV_CPU_L2_CNTRS_EVICT_BUFF_STALL,
  53991. + MV_CPU_L2_CNTRS_ACTIVE_CYCLES,
  53992. +
  53993. +} MV_CPU_L2_CNTRS_OPS;
  53994. +
  53995. +typedef struct
  53996. +{
  53997. + char name[16];
  53998. + MV_CPU_L2_CNTRS_OPS operation;
  53999. + int opIdx;
  54000. + MV_U32 overhead;
  54001. +
  54002. +} MV_CPU_L2_CNTRS_ENTRY;
  54003. +
  54004. +
  54005. +typedef struct
  54006. +{
  54007. + char name[16];
  54008. + MV_U32 num_of_measurements;
  54009. + MV_U32 avg_sample_count;
  54010. + MV_U64 counters_before[MV_CPU_L2_CNTRS_NUM];
  54011. + MV_U64 counters_after[MV_CPU_L2_CNTRS_NUM];
  54012. + MV_U64 counters_sum[MV_CPU_L2_CNTRS_NUM];
  54013. +
  54014. +} MV_CPU_L2_CNTRS_EVENT;
  54015. +
  54016. +
  54017. +MV_STATUS mvCpuL2CntrsProgram(int counter, MV_CPU_L2_CNTRS_OPS op,
  54018. + char* name, MV_U32 overhead);
  54019. +void mvCpuL2CntrsInit(void);
  54020. +MV_CPU_L2_CNTRS_EVENT* mvCpuL2CntrsEventCreate(char* name, MV_U32 print_threshold);
  54021. +void mvCpuL2CntrsEventDelete(MV_CPU_L2_CNTRS_EVENT* event);
  54022. +void mvCpuL2CntrsReset(void);
  54023. +void mvCpuL2CntrsShow(MV_CPU_L2_CNTRS_EVENT* pEvent);
  54024. +void mvCpuL2CntrsEventClear(MV_CPU_L2_CNTRS_EVENT* pEvent);
  54025. +
  54026. +static INLINE MV_U64 mvCpuL2CntrsRead(const int counter)
  54027. +{
  54028. + MV_U32 low = 0, high = 0;
  54029. +
  54030. + switch(counter)
  54031. + {
  54032. + case 0:
  54033. + MV_ASM ("mrc p15, 6, %0, c15, c13, 0" : "=r" (low));
  54034. + MV_ASM ("mrc p15, 6, %0, c15, c13, 1" : "=r" (high));
  54035. + break;
  54036. +
  54037. + case 1:
  54038. + MV_ASM ("mrc p15, 6, %0, c15, c13, 2" : "=r" (low));
  54039. + MV_ASM ("mrc p15, 6, %0, c15, c13, 3" : "=r" (high));
  54040. + break;
  54041. +
  54042. + default:
  54043. + mvOsPrintf("mvCpuL2CntrsRead: bad counter number (%d)\n", counter);
  54044. + }
  54045. + return (((MV_U64)high << 32 ) | low);
  54046. +
  54047. +}
  54048. +
  54049. +static INLINE void mvCpuL2CntrsReadBefore(MV_CPU_L2_CNTRS_EVENT* pEvent)
  54050. +{
  54051. + int i;
  54052. +
  54053. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  54054. + pEvent->counters_before[i] = mvCpuL2CntrsRead(i);
  54055. +}
  54056. +
  54057. +static INLINE void mvCpuL2CntrsReadAfter(MV_CPU_L2_CNTRS_EVENT* pEvent)
  54058. +{
  54059. + int i;
  54060. +
  54061. + for(i=0; i<MV_CPU_L2_CNTRS_NUM; i++)
  54062. + {
  54063. + pEvent->counters_after[i] = mvCpuL2CntrsRead(i);
  54064. + pEvent->counters_sum[i] += (pEvent->counters_after[i] - pEvent->counters_before[i]);
  54065. + }
  54066. + pEvent->num_of_measurements++;
  54067. +}
  54068. +
  54069. +
  54070. +#ifdef CONFIG_MV_CPU_L2_PERF_CNTRS
  54071. +
  54072. +#define MV_CPU_L2_CNTRS_READ(counter) mvCpuL2CntrsRead(counter)
  54073. +
  54074. +#define MV_CPU_L2_CNTRS_START(event) mvCpuL2CntrsReadBefore(event)
  54075. +
  54076. +#define MV_CPU_L2_CNTRS_STOP(event) mvCpuL2CntrsReadAfter(event)
  54077. +
  54078. +#define MV_CPU_L2_CNTRS_SHOW(event) mvCpuL2CntrsShow(event)
  54079. +
  54080. +#else
  54081. +
  54082. +#define MV_CPU_L2_CNTRS_READ(counter)
  54083. +#define MV_CPU_L2_CNTRS_START(event)
  54084. +#define MV_CPU_L2_CNTRS_STOP(event)
  54085. +#define MV_CPU_L2_CNTRS_SHOW(event)
  54086. +
  54087. +#endif /* CONFIG_MV_CPU_L2_PERF_CNTRS */
  54088. +
  54089. +
  54090. +#endif /* __mvCpuL2Cntrs_h__ */
  54091. +
  54092. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c
  54093. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c 1970-01-01 01:00:00.000000000 +0100
  54094. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.c 2011-08-01 14:38:19.000000000 +0200
  54095. @@ -0,0 +1,1479 @@
  54096. +/*******************************************************************************
  54097. +Copyright (C) Marvell International Ltd. and its affiliates
  54098. +
  54099. +This software file (the "File") is owned and distributed by Marvell
  54100. +International Ltd. and/or its affiliates ("Marvell") under the following
  54101. +alternative licensing terms. Once you have made an election to distribute the
  54102. +File under one of the following license alternatives, please (i) delete this
  54103. +introductory statement regarding license alternatives, (ii) delete the two
  54104. +license alternatives that you have not elected to use and (iii) preserve the
  54105. +Marvell copyright notice above.
  54106. +
  54107. +********************************************************************************
  54108. +Marvell Commercial License Option
  54109. +
  54110. +If you received this File from Marvell and you have entered into a commercial
  54111. +license agreement (a "Commercial License") with Marvell, the File is licensed
  54112. +to you under the terms of the applicable Commercial License.
  54113. +
  54114. +********************************************************************************
  54115. +Marvell GPL License Option
  54116. +
  54117. +If you received this File from Marvell, you may opt to use, redistribute and/or
  54118. +modify this File in accordance with the terms and conditions of the General
  54119. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  54120. +available along with the File in the license.txt file or by writing to the Free
  54121. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  54122. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  54123. +
  54124. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  54125. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  54126. +DISCLAIMED. The GPL License provides additional details about this warranty
  54127. +disclaimer.
  54128. +********************************************************************************
  54129. +Marvell BSD License Option
  54130. +
  54131. +If you received this File from Marvell, you may opt to use, redistribute and/or
  54132. +modify this File under the following licensing terms.
  54133. +Redistribution and use in source and binary forms, with or without modification,
  54134. +are permitted provided that the following conditions are met:
  54135. +
  54136. + * Redistributions of source code must retain the above copyright notice,
  54137. + this list of conditions and the following disclaimer.
  54138. +
  54139. + * Redistributions in binary form must reproduce the above copyright
  54140. + notice, this list of conditions and the following disclaimer in the
  54141. + documentation and/or other materials provided with the distribution.
  54142. +
  54143. + * Neither the name of Marvell nor the names of its contributors may be
  54144. + used to endorse or promote products derived from this software without
  54145. + specific prior written permission.
  54146. +
  54147. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  54148. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  54149. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  54150. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  54151. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  54152. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  54153. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  54154. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  54155. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  54156. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  54157. +
  54158. +*******************************************************************************/
  54159. +
  54160. +#include "ddr1_2/mvDram.h"
  54161. +#include "boardEnv/mvBoardEnvLib.h"
  54162. +
  54163. +#undef MV_DEBUG
  54164. +#ifdef MV_DEBUG
  54165. +#define DB(x) x
  54166. +#else
  54167. +#define DB(x)
  54168. +#endif
  54169. +
  54170. +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
  54171. + MV_DRAM_BANK_INFO *pBankInfo);
  54172. +static MV_U32 cas2ps(MV_U8 spd_byte);
  54173. +/*******************************************************************************
  54174. +* mvDramBankGet - Get the DRAM bank paramters.
  54175. +*
  54176. +* DESCRIPTION:
  54177. +* This function retrieves DRAM bank parameters as described in
  54178. +* DRAM_BANK_INFO struct to the controller DRAM unit. In case the board
  54179. +* has its DRAM on DIMMs it will use its EEPROM to extract SPD data
  54180. +* from it. Otherwise, if the DRAM is soldered on board, the function
  54181. +* should insert its bank information into MV_DRAM_BANK_INFO struct.
  54182. +*
  54183. +* INPUT:
  54184. +* bankNum - Board DRAM bank number.
  54185. +*
  54186. +* OUTPUT:
  54187. +* pBankInfo - DRAM bank information struct.
  54188. +*
  54189. +* RETURN:
  54190. +* MV_FAIL - Bank parameters could not be read.
  54191. +*
  54192. +*******************************************************************************/
  54193. +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo)
  54194. +{
  54195. + MV_DIMM_INFO dimmInfo;
  54196. +
  54197. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bank %d\n", bankNum));
  54198. + /* zero pBankInfo structure */
  54199. + memset(pBankInfo, 0, sizeof(*pBankInfo));
  54200. +
  54201. + if((NULL == pBankInfo) || (bankNum >= MV_DRAM_MAX_CS ))
  54202. + {
  54203. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
  54204. + return MV_BAD_PARAM;
  54205. + }
  54206. + if( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
  54207. + {
  54208. + DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
  54209. + return MV_FAIL;
  54210. + }
  54211. + if((dimmInfo.numOfModuleBanks == 1) && ((bankNum % 2) == 1))
  54212. + {
  54213. + DB(mvOsPrintf("Dram: ERR dimmSpdGet. Can't find DIMM bank 2 \n"));
  54214. + return MV_FAIL;
  54215. + }
  54216. +
  54217. + /* convert Dimm info to Bank info */
  54218. + cpyDimm2BankInfo(&dimmInfo, pBankInfo);
  54219. +
  54220. + return MV_OK;
  54221. +}
  54222. +
  54223. +/*******************************************************************************
  54224. +* cpyDimm2BankInfo - Convert a Dimm info struct into a bank info struct.
  54225. +*
  54226. +* DESCRIPTION:
  54227. +* Convert a Dimm info struct into a bank info struct.
  54228. +*
  54229. +* INPUT:
  54230. +* pDimmInfo - DIMM information structure.
  54231. +*
  54232. +* OUTPUT:
  54233. +* pBankInfo - DRAM bank information struct.
  54234. +*
  54235. +* RETURN:
  54236. +* None.
  54237. +*
  54238. +*******************************************************************************/
  54239. +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
  54240. + MV_DRAM_BANK_INFO *pBankInfo)
  54241. +{
  54242. + pBankInfo->memoryType = pDimmInfo->memoryType;
  54243. +
  54244. + /* DIMM dimensions */
  54245. + pBankInfo->numOfRowAddr = pDimmInfo->numOfRowAddr;
  54246. + pBankInfo->numOfColAddr = pDimmInfo->numOfColAddr;
  54247. + pBankInfo->dataWidth = pDimmInfo->dataWidth;
  54248. + pBankInfo->errorCheckType = pDimmInfo->errorCheckType;
  54249. + pBankInfo->sdramWidth = pDimmInfo->sdramWidth;
  54250. + pBankInfo->errorCheckDataWidth = pDimmInfo->errorCheckDataWidth;
  54251. + pBankInfo->numOfBanksOnEachDevice = pDimmInfo->numOfBanksOnEachDevice;
  54252. + pBankInfo->suportedCasLatencies = pDimmInfo->suportedCasLatencies;
  54253. + pBankInfo->refreshInterval = pDimmInfo->refreshInterval;
  54254. +
  54255. + /* DIMM timing parameters */
  54256. + pBankInfo->minCycleTimeAtMaxCasLatPs = pDimmInfo->minCycleTimeAtMaxCasLatPs;
  54257. + pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps =
  54258. + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps;
  54259. + pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps =
  54260. + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps;
  54261. +
  54262. + pBankInfo->minRowPrechargeTime = pDimmInfo->minRowPrechargeTime;
  54263. + pBankInfo->minRowActiveToRowActive = pDimmInfo->minRowActiveToRowActive;
  54264. + pBankInfo->minRasToCasDelay = pDimmInfo->minRasToCasDelay;
  54265. + pBankInfo->minRasPulseWidth = pDimmInfo->minRasPulseWidth;
  54266. + pBankInfo->minWriteRecoveryTime = pDimmInfo->minWriteRecoveryTime;
  54267. + pBankInfo->minWriteToReadCmdDelay = pDimmInfo->minWriteToReadCmdDelay;
  54268. + pBankInfo->minReadToPrechCmdDelay = pDimmInfo->minReadToPrechCmdDelay;
  54269. + pBankInfo->minRefreshToActiveCmd = pDimmInfo->minRefreshToActiveCmd;
  54270. +
  54271. + /* Parameters calculated from the extracted DIMM information */
  54272. + pBankInfo->size = pDimmInfo->size/pDimmInfo->numOfModuleBanks;
  54273. + pBankInfo->deviceDensity = pDimmInfo->deviceDensity;
  54274. + pBankInfo->numberOfDevices = pDimmInfo->numberOfDevices /
  54275. + pDimmInfo->numOfModuleBanks;
  54276. +
  54277. + /* DIMM attributes (MV_TRUE for yes) */
  54278. +
  54279. + if ((pDimmInfo->memoryType == MEM_TYPE_SDRAM) ||
  54280. + (pDimmInfo->memoryType == MEM_TYPE_DDR1) )
  54281. + {
  54282. + if (pDimmInfo->dimmAttributes & BIT1)
  54283. + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
  54284. + else
  54285. + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
  54286. + }
  54287. + else /* pDimmInfo->memoryType == MEM_TYPE_DDR2 */
  54288. + {
  54289. + if (pDimmInfo->dimmTypeInfo & (BIT0 | BIT4))
  54290. + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
  54291. + else
  54292. + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
  54293. + }
  54294. +
  54295. + return;
  54296. +}
  54297. +
  54298. +/*******************************************************************************
  54299. +* dimmSpdCpy - Cpy SPD parameters from dimm 0 to dimm 1.
  54300. +*
  54301. +* DESCRIPTION:
  54302. +* Read the DIMM SPD parameters from dimm 0 into dimm 1 SPD.
  54303. +*
  54304. +* INPUT:
  54305. +* None.
  54306. +*
  54307. +* OUTPUT:
  54308. +* None.
  54309. +*
  54310. +* RETURN:
  54311. +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
  54312. +*
  54313. +*******************************************************************************/
  54314. +MV_STATUS dimmSpdCpy(MV_VOID)
  54315. +{
  54316. + MV_U32 i;
  54317. + MV_U32 spdChecksum;
  54318. +
  54319. + MV_TWSI_SLAVE twsiSlave;
  54320. + MV_U8 data[SPD_SIZE];
  54321. +
  54322. + /* zero dimmInfo structure */
  54323. + memset(data, 0, SPD_SIZE);
  54324. +
  54325. + /* read the dimm eeprom */
  54326. + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
  54327. + twsiSlave.slaveAddr.address = MV_BOARD_DIMM0_I2C_ADDR;
  54328. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  54329. + twsiSlave.validOffset = MV_TRUE;
  54330. + twsiSlave.offset = 0;
  54331. + twsiSlave.moreThen256 = MV_FALSE;
  54332. +
  54333. + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL,
  54334. + &twsiSlave, data, SPD_SIZE) )
  54335. + {
  54336. + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 0\n"));
  54337. + return MV_FAIL;
  54338. + }
  54339. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  54340. +
  54341. + /* calculate SPD checksum */
  54342. + spdChecksum = 0;
  54343. +
  54344. + for(i = 0 ; i <= 62 ; i++)
  54345. + {
  54346. + spdChecksum += data[i];
  54347. + }
  54348. +
  54349. + if ((spdChecksum & 0xff) != data[63])
  54350. + {
  54351. + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
  54352. + (MV_U32)(spdChecksum & 0xff), data[63]));
  54353. + }
  54354. + else
  54355. + {
  54356. + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
  54357. + }
  54358. +
  54359. + /* copy the SPD content 1:1 into the DIMM 1 SPD */
  54360. + twsiSlave.slaveAddr.address = MV_BOARD_DIMM1_I2C_ADDR;
  54361. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  54362. + twsiSlave.validOffset = MV_TRUE;
  54363. + twsiSlave.offset = 0;
  54364. + twsiSlave.moreThen256 = MV_FALSE;
  54365. +
  54366. + for(i = 0 ; i < SPD_SIZE ; i++)
  54367. + {
  54368. + twsiSlave.offset = i;
  54369. + if( MV_OK != mvTwsiWrite (MV_BOARD_DIMM_I2C_CHANNEL,
  54370. + &twsiSlave, &data[i], 1) )
  54371. + {
  54372. + mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 1 byte %d \n",i);
  54373. + return MV_FAIL;
  54374. + }
  54375. + mvOsDelay(5);
  54376. + }
  54377. +
  54378. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  54379. + return MV_OK;
  54380. +}
  54381. +
  54382. +/*******************************************************************************
  54383. +* dimmSpdGet - Get the SPD parameters.
  54384. +*
  54385. +* DESCRIPTION:
  54386. +* Read the DIMM SPD parameters into given struct parameter.
  54387. +*
  54388. +* INPUT:
  54389. +* dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
  54390. +*
  54391. +* OUTPUT:
  54392. +* pDimmInfo - DIMM information structure.
  54393. +*
  54394. +* RETURN:
  54395. +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
  54396. +*
  54397. +*******************************************************************************/
  54398. +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo)
  54399. +{
  54400. + MV_U32 i;
  54401. + MV_U32 density = 1;
  54402. + MV_U32 spdChecksum;
  54403. +
  54404. + MV_TWSI_SLAVE twsiSlave;
  54405. + MV_U8 data[SPD_SIZE];
  54406. +
  54407. + if((NULL == pDimmInfo)|| (dimmNum >= MAX_DIMM_NUM))
  54408. + {
  54409. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
  54410. + return MV_BAD_PARAM;
  54411. + }
  54412. +
  54413. + /* zero dimmInfo structure */
  54414. + memset(data, 0, SPD_SIZE);
  54415. +
  54416. + /* read the dimm eeprom */
  54417. + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
  54418. + twsiSlave.slaveAddr.address = (dimmNum == 0) ?
  54419. + MV_BOARD_DIMM0_I2C_ADDR : MV_BOARD_DIMM1_I2C_ADDR;
  54420. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  54421. + twsiSlave.validOffset = MV_TRUE;
  54422. + twsiSlave.offset = 0;
  54423. + twsiSlave.moreThen256 = MV_FALSE;
  54424. +
  54425. + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL,
  54426. + &twsiSlave, data, SPD_SIZE) )
  54427. + {
  54428. + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum %d \n", dimmNum));
  54429. + return MV_FAIL;
  54430. + }
  54431. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  54432. +
  54433. + /* calculate SPD checksum */
  54434. + spdChecksum = 0;
  54435. +
  54436. + for(i = 0 ; i <= 62 ; i++)
  54437. + {
  54438. + spdChecksum += data[i];
  54439. + }
  54440. +
  54441. + if ((spdChecksum & 0xff) != data[63])
  54442. + {
  54443. + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
  54444. + (MV_U32)(spdChecksum & 0xff), data[63]));
  54445. + }
  54446. + else
  54447. + {
  54448. + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
  54449. + }
  54450. +
  54451. + /* copy the SPD content 1:1 into the dimmInfo structure*/
  54452. + for(i = 0 ; i < SPD_SIZE ; i++)
  54453. + {
  54454. + pDimmInfo->spdRawData[i] = data[i];
  54455. + DB(mvOsPrintf("SPD-EEPROM Byte %3d = %3x (%3d)\n",i, data[i], data[i]));
  54456. + }
  54457. +
  54458. + DB(mvOsPrintf("DRAM SPD Information:\n"));
  54459. +
  54460. + /* Memory type (DDR / SDRAM) */
  54461. + switch (data[DIMM_MEM_TYPE])
  54462. + {
  54463. + case (DIMM_MEM_TYPE_SDRAM):
  54464. + pDimmInfo->memoryType = MEM_TYPE_SDRAM;
  54465. + DB(mvOsPrintf("DRAM Memeory type SDRAM\n"));
  54466. + break;
  54467. + case (DIMM_MEM_TYPE_DDR1):
  54468. + pDimmInfo->memoryType = MEM_TYPE_DDR1;
  54469. + DB(mvOsPrintf("DRAM Memeory type DDR1\n"));
  54470. + break;
  54471. + case (DIMM_MEM_TYPE_DDR2):
  54472. + pDimmInfo->memoryType = MEM_TYPE_DDR2;
  54473. + DB(mvOsPrintf("DRAM Memeory type DDR2\n"));
  54474. + break;
  54475. + default:
  54476. + mvOsPrintf("ERROR: Undefined memory type!\n");
  54477. + return MV_ERROR;
  54478. + }
  54479. +
  54480. +
  54481. + /* Number Of Row Addresses */
  54482. + pDimmInfo->numOfRowAddr = data[DIMM_ROW_NUM];
  54483. + DB(mvOsPrintf("DRAM numOfRowAddr[3] %d\n",pDimmInfo->numOfRowAddr));
  54484. +
  54485. + /* Number Of Column Addresses */
  54486. + pDimmInfo->numOfColAddr = data[DIMM_COL_NUM];
  54487. + DB(mvOsPrintf("DRAM numOfColAddr[4] %d\n",pDimmInfo->numOfColAddr));
  54488. +
  54489. + /* Number Of Module Banks */
  54490. + pDimmInfo->numOfModuleBanks = data[DIMM_MODULE_BANK_NUM];
  54491. + DB(mvOsPrintf("DRAM numOfModuleBanks[5] 0x%x\n",
  54492. + pDimmInfo->numOfModuleBanks));
  54493. +
  54494. + /* Number of module banks encoded differently for DDR2 */
  54495. + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
  54496. + pDimmInfo->numOfModuleBanks = (pDimmInfo->numOfModuleBanks & 0x7)+1;
  54497. +
  54498. + /* Data Width */
  54499. + pDimmInfo->dataWidth = data[DIMM_DATA_WIDTH];
  54500. + DB(mvOsPrintf("DRAM dataWidth[6] 0x%x\n", pDimmInfo->dataWidth));
  54501. +
  54502. + /* Minimum Cycle Time At Max CasLatancy */
  54503. + pDimmInfo->minCycleTimeAtMaxCasLatPs = cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS]);
  54504. +
  54505. + /* Error Check Type */
  54506. + pDimmInfo->errorCheckType = data[DIMM_ERR_CHECK_TYPE];
  54507. + DB(mvOsPrintf("DRAM errorCheckType[11] 0x%x\n",
  54508. + pDimmInfo->errorCheckType));
  54509. +
  54510. + /* Refresh Interval */
  54511. + pDimmInfo->refreshInterval = data[DIMM_REFRESH_INTERVAL];
  54512. + DB(mvOsPrintf("DRAM refreshInterval[12] 0x%x\n",
  54513. + pDimmInfo->refreshInterval));
  54514. +
  54515. + /* Sdram Width */
  54516. + pDimmInfo->sdramWidth = data[DIMM_SDRAM_WIDTH];
  54517. + DB(mvOsPrintf("DRAM sdramWidth[13] 0x%x\n",pDimmInfo->sdramWidth));
  54518. +
  54519. + /* Error Check Data Width */
  54520. + pDimmInfo->errorCheckDataWidth = data[DIMM_ERR_CHECK_DATA_WIDTH];
  54521. + DB(mvOsPrintf("DRAM errorCheckDataWidth[14] 0x%x\n",
  54522. + pDimmInfo->errorCheckDataWidth));
  54523. +
  54524. + /* Burst Length Supported */
  54525. + /* SDRAM/DDR1:
  54526. + *******-******-******-******-******-******-******-*******
  54527. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54528. + *******-******-******-******-******-******-******-*******
  54529. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
  54530. + *********************************************************/
  54531. + /* DDR2:
  54532. + *******-******-******-******-******-******-******-*******
  54533. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54534. + *******-******-******-******-******-******-******-*******
  54535. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
  54536. + *********************************************************/
  54537. +
  54538. + pDimmInfo->burstLengthSupported = data[DIMM_BURST_LEN_SUP];
  54539. + DB(mvOsPrintf("DRAM burstLengthSupported[16] 0x%x\n",
  54540. + pDimmInfo->burstLengthSupported));
  54541. +
  54542. + /* Number Of Banks On Each Device */
  54543. + pDimmInfo->numOfBanksOnEachDevice = data[DIMM_DEV_BANK_NUM];
  54544. + DB(mvOsPrintf("DRAM numOfBanksOnEachDevice[17] 0x%x\n",
  54545. + pDimmInfo->numOfBanksOnEachDevice));
  54546. +
  54547. + /* Suported Cas Latencies */
  54548. +
  54549. + /* SDRAM:
  54550. + *******-******-******-******-******-******-******-*******
  54551. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54552. + *******-******-******-******-******-******-******-*******
  54553. + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
  54554. + ********************************************************/
  54555. +
  54556. + /* DDR 1:
  54557. + *******-******-******-******-******-******-******-*******
  54558. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54559. + *******-******-******-******-******-******-******-*******
  54560. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  54561. + *********************************************************/
  54562. +
  54563. + /* DDR 2:
  54564. + *******-******-******-******-******-******-******-*******
  54565. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54566. + *******-******-******-******-******-******-******-*******
  54567. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  54568. + *********************************************************/
  54569. +
  54570. + pDimmInfo->suportedCasLatencies = data[DIMM_SUP_CAL];
  54571. + DB(mvOsPrintf("DRAM suportedCasLatencies[18] 0x%x\n",
  54572. + pDimmInfo->suportedCasLatencies));
  54573. +
  54574. + /* For DDR2 only, get the DIMM type information */
  54575. + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
  54576. + {
  54577. + pDimmInfo->dimmTypeInfo = data[DIMM_DDR2_TYPE_INFORMATION];
  54578. + DB(mvOsPrintf("DRAM dimmTypeInfo[20] (DDR2) 0x%x\n",
  54579. + pDimmInfo->dimmTypeInfo));
  54580. + }
  54581. +
  54582. + /* SDRAM Modules Attributes */
  54583. + pDimmInfo->dimmAttributes = data[DIMM_BUF_ADDR_CONT_IN];
  54584. + DB(mvOsPrintf("DRAM dimmAttributes[21] 0x%x\n",
  54585. + pDimmInfo->dimmAttributes));
  54586. +
  54587. + /* Minimum Cycle Time At Max CasLatancy Minus 1*/
  54588. + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps =
  54589. + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS1]);
  54590. +
  54591. + /* Minimum Cycle Time At Max CasLatancy Minus 2*/
  54592. + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps =
  54593. + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS2]);
  54594. +
  54595. + pDimmInfo->minRowPrechargeTime = data[DIMM_MIN_ROW_PRECHARGE_TIME];
  54596. + DB(mvOsPrintf("DRAM minRowPrechargeTime[27] 0x%x\n",
  54597. + pDimmInfo->minRowPrechargeTime));
  54598. + pDimmInfo->minRowActiveToRowActive = data[DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE];
  54599. + DB(mvOsPrintf("DRAM minRowActiveToRowActive[28] 0x%x\n",
  54600. + pDimmInfo->minRowActiveToRowActive));
  54601. + pDimmInfo->minRasToCasDelay = data[DIMM_MIN_RAS_TO_CAS_DELAY];
  54602. + DB(mvOsPrintf("DRAM minRasToCasDelay[29] 0x%x\n",
  54603. + pDimmInfo->minRasToCasDelay));
  54604. + pDimmInfo->minRasPulseWidth = data[DIMM_MIN_RAS_PULSE_WIDTH];
  54605. + DB(mvOsPrintf("DRAM minRasPulseWidth[30] 0x%x\n",
  54606. + pDimmInfo->minRasPulseWidth));
  54607. +
  54608. + /* DIMM Bank Density */
  54609. + pDimmInfo->dimmBankDensity = data[DIMM_BANK_DENSITY];
  54610. + DB(mvOsPrintf("DRAM dimmBankDensity[31] 0x%x\n",
  54611. + pDimmInfo->dimmBankDensity));
  54612. +
  54613. + /* Only DDR2 includes Write Recovery Time field. Other SDRAM ignore */
  54614. + pDimmInfo->minWriteRecoveryTime = data[DIMM_MIN_WRITE_RECOVERY_TIME];
  54615. + DB(mvOsPrintf("DRAM minWriteRecoveryTime[36] 0x%x\n",
  54616. + pDimmInfo->minWriteRecoveryTime));
  54617. +
  54618. + /* Only DDR2 includes Internal Write To Read Command Delay field. */
  54619. + pDimmInfo->minWriteToReadCmdDelay = data[DIMM_MIN_WRITE_TO_READ_CMD_DELAY];
  54620. + DB(mvOsPrintf("DRAM minWriteToReadCmdDelay[37] 0x%x\n",
  54621. + pDimmInfo->minWriteToReadCmdDelay));
  54622. +
  54623. + /* Only DDR2 includes Internal Read To Precharge Command Delay field. */
  54624. + pDimmInfo->minReadToPrechCmdDelay = data[DIMM_MIN_READ_TO_PRECH_CMD_DELAY];
  54625. + DB(mvOsPrintf("DRAM minReadToPrechCmdDelay[38] 0x%x\n",
  54626. + pDimmInfo->minReadToPrechCmdDelay));
  54627. +
  54628. + /* Only DDR2 includes Minimum Refresh to Activate/Refresh Command field */
  54629. + pDimmInfo->minRefreshToActiveCmd = data[DIMM_MIN_REFRESH_TO_ACTIVATE_CMD];
  54630. + DB(mvOsPrintf("DRAM minRefreshToActiveCmd[42] 0x%x\n",
  54631. + pDimmInfo->minRefreshToActiveCmd));
  54632. +
  54633. + /* calculating the sdram density. Representing device density from */
  54634. + /* bit 20 to allow representation of 4GB and above. */
  54635. + /* For example, if density is 512Mbit 0x20000000, will be represent in */
  54636. + /* deviceDensity by 0x20000000 >> 16 --> 0x00000200. Another example */
  54637. + /* is density 8GB 0x200000000 >> 16 --> 0x00002000. */
  54638. + density = (1 << ((pDimmInfo->numOfRowAddr + pDimmInfo->numOfColAddr) - 20));
  54639. + pDimmInfo->deviceDensity = density *
  54640. + pDimmInfo->numOfBanksOnEachDevice *
  54641. + pDimmInfo->sdramWidth;
  54642. + DB(mvOsPrintf("DRAM deviceDensity %d\n",pDimmInfo->deviceDensity));
  54643. +
  54644. + /* Number of devices includeing Error correction */
  54645. + pDimmInfo->numberOfDevices = (pDimmInfo->dataWidth/pDimmInfo->sdramWidth) *
  54646. + pDimmInfo->numOfModuleBanks;
  54647. + DB(mvOsPrintf("DRAM numberOfDevices %d\n",
  54648. + pDimmInfo->numberOfDevices));
  54649. +
  54650. + pDimmInfo->size = 0;
  54651. +
  54652. + /* Note that pDimmInfo->size is in MB units */
  54653. + if (pDimmInfo->memoryType == MEM_TYPE_SDRAM)
  54654. + {
  54655. + if (pDimmInfo->dimmBankDensity & BIT0)
  54656. + pDimmInfo->size += 1024; /* Equal to 1GB */
  54657. + else if (pDimmInfo->dimmBankDensity & BIT1)
  54658. + pDimmInfo->size += 8; /* Equal to 8MB */
  54659. + else if (pDimmInfo->dimmBankDensity & BIT2)
  54660. + pDimmInfo->size += 16; /* Equal to 16MB */
  54661. + else if (pDimmInfo->dimmBankDensity & BIT3)
  54662. + pDimmInfo->size += 32; /* Equal to 32MB */
  54663. + else if (pDimmInfo->dimmBankDensity & BIT4)
  54664. + pDimmInfo->size += 64; /* Equal to 64MB */
  54665. + else if (pDimmInfo->dimmBankDensity & BIT5)
  54666. + pDimmInfo->size += 128; /* Equal to 128MB */
  54667. + else if (pDimmInfo->dimmBankDensity & BIT6)
  54668. + pDimmInfo->size += 256; /* Equal to 256MB */
  54669. + else if (pDimmInfo->dimmBankDensity & BIT7)
  54670. + pDimmInfo->size += 512; /* Equal to 512MB */
  54671. + }
  54672. + else if (pDimmInfo->memoryType == MEM_TYPE_DDR1)
  54673. + {
  54674. + if (pDimmInfo->dimmBankDensity & BIT0)
  54675. + pDimmInfo->size += 1024; /* Equal to 1GB */
  54676. + else if (pDimmInfo->dimmBankDensity & BIT1)
  54677. + pDimmInfo->size += 2048; /* Equal to 2GB */
  54678. + else if (pDimmInfo->dimmBankDensity & BIT2)
  54679. + pDimmInfo->size += 16; /* Equal to 16MB */
  54680. + else if (pDimmInfo->dimmBankDensity & BIT3)
  54681. + pDimmInfo->size += 32; /* Equal to 32MB */
  54682. + else if (pDimmInfo->dimmBankDensity & BIT4)
  54683. + pDimmInfo->size += 64; /* Equal to 64MB */
  54684. + else if (pDimmInfo->dimmBankDensity & BIT5)
  54685. + pDimmInfo->size += 128; /* Equal to 128MB */
  54686. + else if (pDimmInfo->dimmBankDensity & BIT6)
  54687. + pDimmInfo->size += 256; /* Equal to 256MB */
  54688. + else if (pDimmInfo->dimmBankDensity & BIT7)
  54689. + pDimmInfo->size += 512; /* Equal to 512MB */
  54690. + }
  54691. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  54692. + {
  54693. + if (pDimmInfo->dimmBankDensity & BIT0)
  54694. + pDimmInfo->size += 1024; /* Equal to 1GB */
  54695. + else if (pDimmInfo->dimmBankDensity & BIT1)
  54696. + pDimmInfo->size += 2048; /* Equal to 2GB */
  54697. + else if (pDimmInfo->dimmBankDensity & BIT2)
  54698. + pDimmInfo->size += 4096; /* Equal to 4GB */
  54699. + else if (pDimmInfo->dimmBankDensity & BIT3)
  54700. + pDimmInfo->size += 8192; /* Equal to 8GB */
  54701. + else if (pDimmInfo->dimmBankDensity & BIT4)
  54702. + pDimmInfo->size += 16384; /* Equal to 16GB */
  54703. + else if (pDimmInfo->dimmBankDensity & BIT5)
  54704. + pDimmInfo->size += 128; /* Equal to 128MB */
  54705. + else if (pDimmInfo->dimmBankDensity & BIT6)
  54706. + pDimmInfo->size += 256; /* Equal to 256MB */
  54707. + else if (pDimmInfo->dimmBankDensity & BIT7)
  54708. + pDimmInfo->size += 512; /* Equal to 512MB */
  54709. + }
  54710. +
  54711. + pDimmInfo->size *= pDimmInfo->numOfModuleBanks;
  54712. +
  54713. + DB(mvOsPrintf("Dram: dimm size %dMB \n",pDimmInfo->size));
  54714. +
  54715. + return MV_OK;
  54716. +}
  54717. +
  54718. +/*******************************************************************************
  54719. +* dimmSpdPrint - Print the SPD parameters.
  54720. +*
  54721. +* DESCRIPTION:
  54722. +* Print the Dimm SPD parameters.
  54723. +*
  54724. +* INPUT:
  54725. +* pDimmInfo - DIMM information structure.
  54726. +*
  54727. +* OUTPUT:
  54728. +* None.
  54729. +*
  54730. +* RETURN:
  54731. +* None.
  54732. +*
  54733. +*******************************************************************************/
  54734. +MV_VOID dimmSpdPrint(MV_U32 dimmNum)
  54735. +{
  54736. + MV_DIMM_INFO dimmInfo;
  54737. + MV_U32 i, temp = 0;
  54738. + MV_U32 k, maskLeftOfPoint = 0, maskRightOfPoint = 0;
  54739. + MV_U32 rightOfPoint = 0,leftOfPoint = 0, div, time_tmp, shift;
  54740. + MV_U32 busClkPs;
  54741. + MV_U8 trp_clocks=0, trcd_clocks, tras_clocks, trrd_clocks,
  54742. + temp_buf[40], *spdRawData;
  54743. +
  54744. + busClkPs = 1000000000 / (mvBoardSysClkGet() / 100); /* in 10 ps units */
  54745. +
  54746. + spdRawData = dimmInfo.spdRawData;
  54747. +
  54748. + if(MV_OK != dimmSpdGet(dimmNum, &dimmInfo))
  54749. + {
  54750. + mvOsOutput("ERROR: Could not read SPD information!\n");
  54751. + return;
  54752. + }
  54753. +
  54754. + /* find Manufactura of Dimm Module */
  54755. + mvOsOutput("\nManufacturer's JEDEC ID Code: ");
  54756. + for(i = 0 ; i < DIMM_MODULE_MANU_SIZE ; i++)
  54757. + {
  54758. + mvOsOutput("%x",spdRawData[DIMM_MODULE_MANU_OFFS + i]);
  54759. + }
  54760. + mvOsOutput("\n");
  54761. +
  54762. + /* Manufacturer's Specific Data */
  54763. + for(i = 0 ; i < DIMM_MODULE_ID_SIZE ; i++)
  54764. + {
  54765. + temp_buf[i] = spdRawData[DIMM_MODULE_ID_OFFS + i];
  54766. + }
  54767. + mvOsOutput("Manufacturer's Specific Data: %s\n", temp_buf);
  54768. +
  54769. + /* Module Part Number */
  54770. + for(i = 0 ; i < DIMM_MODULE_VEN_SIZE ; i++)
  54771. + {
  54772. + temp_buf[i] = spdRawData[DIMM_MODULE_VEN_OFFS + i];
  54773. + }
  54774. + mvOsOutput("Module Part Number: %s\n", temp_buf);
  54775. +
  54776. + /* Module Serial Number */
  54777. + for(i = 0; i < sizeof(MV_U32); i++)
  54778. + {
  54779. + temp |= spdRawData[95+i] << 8*i;
  54780. + }
  54781. + mvOsOutput("DIMM Serial No. %ld (%lx)\n", (long)temp,
  54782. + (long)temp);
  54783. +
  54784. + /* find Manufac-Data of Dimm Module */
  54785. + mvOsOutput("Manufactoring Date: Year 20%d%d/ ww %d%d\n",
  54786. + ((spdRawData[93] & 0xf0) >> 4), (spdRawData[93] & 0xf),
  54787. + ((spdRawData[94] & 0xf0) >> 4), (spdRawData[94] & 0xf));
  54788. + /* find modul_revision of Dimm Module */
  54789. + mvOsOutput("Module Revision: %d.%d\n",
  54790. + spdRawData[91], spdRawData[92]);
  54791. +
  54792. + /* find manufac_place of Dimm Module */
  54793. + mvOsOutput("manufac_place: %d\n", spdRawData[72]);
  54794. +
  54795. + /* go over the first 35 I2C data bytes */
  54796. + for(i = 2 ; i <= 35 ; i++)
  54797. + switch(i)
  54798. + {
  54799. + case 2: /* Memory type (DDR1/2 / SDRAM) */
  54800. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  54801. + mvOsOutput("Dram Type is: SDRAM\n");
  54802. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  54803. + mvOsOutput("Dram Type is: SDRAM DDR1\n");
  54804. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  54805. + mvOsOutput("Dram Type is: SDRAM DDR2\n");
  54806. + else
  54807. + mvOsOutput("Dram Type unknown\n");
  54808. + break;
  54809. +/*----------------------------------------------------------------------------*/
  54810. +
  54811. + case 3: /* Number Of Row Addresses */
  54812. + mvOsOutput("Module Number of row addresses: %d\n",
  54813. + dimmInfo.numOfRowAddr);
  54814. + break;
  54815. +/*----------------------------------------------------------------------------*/
  54816. +
  54817. + case 4: /* Number Of Column Addresses */
  54818. + mvOsOutput("Module Number of col addresses: %d\n",
  54819. + dimmInfo.numOfColAddr);
  54820. + break;
  54821. +/*----------------------------------------------------------------------------*/
  54822. +
  54823. + case 5: /* Number Of Module Banks */
  54824. + mvOsOutput("Number of Banks on Mod.: %d\n",
  54825. + dimmInfo.numOfModuleBanks);
  54826. + break;
  54827. +/*----------------------------------------------------------------------------*/
  54828. +
  54829. + case 6: /* Data Width */
  54830. + mvOsOutput("Module Data Width: %d bit\n",
  54831. + dimmInfo.dataWidth);
  54832. + break;
  54833. +/*----------------------------------------------------------------------------*/
  54834. +
  54835. + case 8: /* Voltage Interface */
  54836. + switch(spdRawData[i])
  54837. + {
  54838. + case 0x0:
  54839. + mvOsOutput("Module is TTL_5V_TOLERANT\n");
  54840. + break;
  54841. + case 0x1:
  54842. + mvOsOutput("Module is LVTTL\n");
  54843. + break;
  54844. + case 0x2:
  54845. + mvOsOutput("Module is HSTL_1_5V\n");
  54846. + break;
  54847. + case 0x3:
  54848. + mvOsOutput("Module is SSTL_3_3V\n");
  54849. + break;
  54850. + case 0x4:
  54851. + mvOsOutput("Module is SSTL_2_5V\n");
  54852. + break;
  54853. + case 0x5:
  54854. + if (dimmInfo.memoryType != MEM_TYPE_SDRAM)
  54855. + {
  54856. + mvOsOutput("Module is SSTL_1_8V\n");
  54857. + break;
  54858. + }
  54859. + default:
  54860. + mvOsOutput("Module is VOLTAGE_UNKNOWN\n");
  54861. + break;
  54862. + }
  54863. + break;
  54864. +/*----------------------------------------------------------------------------*/
  54865. +
  54866. + case 9: /* Minimum Cycle Time At Max CasLatancy */
  54867. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  54868. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  54869. +
  54870. + /* DDR2 addition of right of point */
  54871. + if ((spdRawData[i] & 0x0f) == 0xA)
  54872. + {
  54873. + rightOfPoint = 25;
  54874. + }
  54875. + if ((spdRawData[i] & 0x0f) == 0xB)
  54876. + {
  54877. + rightOfPoint = 33;
  54878. + }
  54879. + if ((spdRawData[i] & 0x0f) == 0xC)
  54880. + {
  54881. + rightOfPoint = 66;
  54882. + }
  54883. + if ((spdRawData[i] & 0x0f) == 0xD)
  54884. + {
  54885. + rightOfPoint = 75;
  54886. + }
  54887. + mvOsOutput("Minimum Cycle Time At Max CL: %d.%d [ns]\n",
  54888. + leftOfPoint, rightOfPoint);
  54889. + break;
  54890. +/*----------------------------------------------------------------------------*/
  54891. +
  54892. + case 10: /* Clock To Data Out */
  54893. + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 10:100;
  54894. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  54895. + ((spdRawData[i] & 0x0f));
  54896. + leftOfPoint = time_tmp / div;
  54897. + rightOfPoint = time_tmp % div;
  54898. + mvOsOutput("Clock To Data Out: %d.%d [ns]\n",
  54899. + leftOfPoint, rightOfPoint);
  54900. + break;
  54901. +/*----------------------------------------------------------------------------*/
  54902. +
  54903. + case 11: /* Error Check Type */
  54904. + mvOsOutput("Error Check Type (0=NONE): %d\n",
  54905. + dimmInfo.errorCheckType);
  54906. + break;
  54907. +/*----------------------------------------------------------------------------*/
  54908. +
  54909. + case 12: /* Refresh Interval */
  54910. + mvOsOutput("Refresh Rate: %x\n",
  54911. + dimmInfo.refreshInterval);
  54912. + break;
  54913. +/*----------------------------------------------------------------------------*/
  54914. +
  54915. + case 13: /* Sdram Width */
  54916. + mvOsOutput("Sdram Width: %d bits\n",
  54917. + dimmInfo.sdramWidth);
  54918. + break;
  54919. +/*----------------------------------------------------------------------------*/
  54920. +
  54921. + case 14: /* Error Check Data Width */
  54922. + mvOsOutput("Error Check Data Width: %d bits\n",
  54923. + dimmInfo.errorCheckDataWidth);
  54924. + break;
  54925. +/*----------------------------------------------------------------------------*/
  54926. +
  54927. + case 15: /* Minimum Clock Delay is unsupported */
  54928. + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
  54929. + (dimmInfo.memoryType == MEM_TYPE_DDR1))
  54930. + {
  54931. + mvOsOutput("Minimum Clk Delay back to back: %d\n",
  54932. + spdRawData[i]);
  54933. + }
  54934. + break;
  54935. +/*----------------------------------------------------------------------------*/
  54936. +
  54937. + case 16: /* Burst Length Supported */
  54938. + /* SDRAM/DDR1:
  54939. + *******-******-******-******-******-******-******-*******
  54940. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54941. + *******-******-******-******-******-******-******-*******
  54942. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
  54943. + *********************************************************/
  54944. + /* DDR2:
  54945. + *******-******-******-******-******-******-******-*******
  54946. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54947. + *******-******-******-******-******-******-******-*******
  54948. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
  54949. + *********************************************************/
  54950. + mvOsOutput("Burst Length Supported: ");
  54951. + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
  54952. + (dimmInfo.memoryType == MEM_TYPE_DDR1))
  54953. + {
  54954. + if (dimmInfo.burstLengthSupported & BIT0)
  54955. + mvOsOutput("1, ");
  54956. + if (dimmInfo.burstLengthSupported & BIT1)
  54957. + mvOsOutput("2, ");
  54958. + }
  54959. + if (dimmInfo.burstLengthSupported & BIT2)
  54960. + mvOsOutput("4, ");
  54961. + if (dimmInfo.burstLengthSupported & BIT3)
  54962. + mvOsOutput("8, ");
  54963. +
  54964. + mvOsOutput(" Bit \n");
  54965. + break;
  54966. +/*----------------------------------------------------------------------------*/
  54967. +
  54968. + case 17: /* Number Of Banks On Each Device */
  54969. + mvOsOutput("Number Of Banks On Each Chip: %d\n",
  54970. + dimmInfo.numOfBanksOnEachDevice);
  54971. + break;
  54972. +/*----------------------------------------------------------------------------*/
  54973. +
  54974. + case 18: /* Suported Cas Latencies */
  54975. +
  54976. + /* SDRAM:
  54977. + *******-******-******-******-******-******-******-*******
  54978. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54979. + *******-******-******-******-******-******-******-*******
  54980. + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
  54981. + ********************************************************/
  54982. +
  54983. + /* DDR 1:
  54984. + *******-******-******-******-******-******-******-*******
  54985. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54986. + *******-******-******-******-******-******-******-*******
  54987. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  54988. + *********************************************************/
  54989. +
  54990. + /* DDR 2:
  54991. + *******-******-******-******-******-******-******-*******
  54992. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  54993. + *******-******-******-******-******-******-******-*******
  54994. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  54995. + *********************************************************/
  54996. +
  54997. + mvOsOutput("Suported Cas Latencies: (CL) ");
  54998. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  54999. + {
  55000. + for (k = 0; k <=7; k++)
  55001. + {
  55002. + if (dimmInfo.suportedCasLatencies & (1 << k))
  55003. + mvOsOutput("%d, ", k+1);
  55004. + }
  55005. + }
  55006. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  55007. + {
  55008. + if (dimmInfo.suportedCasLatencies & BIT0)
  55009. + mvOsOutput("1, ");
  55010. + if (dimmInfo.suportedCasLatencies & BIT1)
  55011. + mvOsOutput("1.5, ");
  55012. + if (dimmInfo.suportedCasLatencies & BIT2)
  55013. + mvOsOutput("2, ");
  55014. + if (dimmInfo.suportedCasLatencies & BIT3)
  55015. + mvOsOutput("2.5, ");
  55016. + if (dimmInfo.suportedCasLatencies & BIT4)
  55017. + mvOsOutput("3, ");
  55018. + if (dimmInfo.suportedCasLatencies & BIT5)
  55019. + mvOsOutput("3.5, ");
  55020. + }
  55021. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  55022. + {
  55023. + if (dimmInfo.suportedCasLatencies & BIT2)
  55024. + mvOsOutput("2, ");
  55025. + if (dimmInfo.suportedCasLatencies & BIT3)
  55026. + mvOsOutput("3, ");
  55027. + if (dimmInfo.suportedCasLatencies & BIT4)
  55028. + mvOsOutput("4, ");
  55029. + if (dimmInfo.suportedCasLatencies & BIT5)
  55030. + mvOsOutput("5, ");
  55031. + }
  55032. + else
  55033. + mvOsOutput("?.?, ");
  55034. + mvOsOutput("\n");
  55035. + break;
  55036. +/*----------------------------------------------------------------------------*/
  55037. +
  55038. + case 20: /* DDR2 DIMM type info */
  55039. + if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  55040. + {
  55041. + if (dimmInfo.dimmTypeInfo & (BIT0 | BIT4))
  55042. + mvOsOutput("Registered DIMM (RDIMM)\n");
  55043. + else if (dimmInfo.dimmTypeInfo & (BIT1 | BIT5))
  55044. + mvOsOutput("Unbuffered DIMM (UDIMM)\n");
  55045. + else
  55046. + mvOsOutput("Unknown DIMM type.\n");
  55047. + }
  55048. +
  55049. + break;
  55050. +/*----------------------------------------------------------------------------*/
  55051. +
  55052. + case 21: /* SDRAM Modules Attributes */
  55053. + mvOsOutput("\nModule Attributes (SPD Byte 21): \n");
  55054. +
  55055. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  55056. + {
  55057. + if (dimmInfo.dimmAttributes & BIT0)
  55058. + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
  55059. + else
  55060. + mvOsOutput(" Buffered Addr/Control Input: No\n");
  55061. +
  55062. + if (dimmInfo.dimmAttributes & BIT1)
  55063. + mvOsOutput(" Registered Addr/Control Input: Yes\n");
  55064. + else
  55065. + mvOsOutput(" Registered Addr/Control Input: No\n");
  55066. +
  55067. + if (dimmInfo.dimmAttributes & BIT2)
  55068. + mvOsOutput(" On-Card PLL (clock): Yes \n");
  55069. + else
  55070. + mvOsOutput(" On-Card PLL (clock): No \n");
  55071. +
  55072. + if (dimmInfo.dimmAttributes & BIT3)
  55073. + mvOsOutput(" Bufferd DQMB Input: Yes \n");
  55074. + else
  55075. + mvOsOutput(" Bufferd DQMB Inputs: No \n");
  55076. +
  55077. + if (dimmInfo.dimmAttributes & BIT4)
  55078. + mvOsOutput(" Registered DQMB Inputs: Yes \n");
  55079. + else
  55080. + mvOsOutput(" Registered DQMB Inputs: No \n");
  55081. +
  55082. + if (dimmInfo.dimmAttributes & BIT5)
  55083. + mvOsOutput(" Differential Clock Input: Yes \n");
  55084. + else
  55085. + mvOsOutput(" Differential Clock Input: No \n");
  55086. +
  55087. + if (dimmInfo.dimmAttributes & BIT6)
  55088. + mvOsOutput(" redundant Row Addressing: Yes \n");
  55089. + else
  55090. + mvOsOutput(" redundant Row Addressing: No \n");
  55091. + }
  55092. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  55093. + {
  55094. + if (dimmInfo.dimmAttributes & BIT0)
  55095. + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
  55096. + else
  55097. + mvOsOutput(" Buffered Addr/Control Input: No\n");
  55098. +
  55099. + if (dimmInfo.dimmAttributes & BIT1)
  55100. + mvOsOutput(" Registered Addr/Control Input: Yes\n");
  55101. + else
  55102. + mvOsOutput(" Registered Addr/Control Input: No\n");
  55103. +
  55104. + if (dimmInfo.dimmAttributes & BIT2)
  55105. + mvOsOutput(" On-Card PLL (clock): Yes \n");
  55106. + else
  55107. + mvOsOutput(" On-Card PLL (clock): No \n");
  55108. +
  55109. + if (dimmInfo.dimmAttributes & BIT3)
  55110. + mvOsOutput(" FET Switch On-Card Enabled: Yes \n");
  55111. + else
  55112. + mvOsOutput(" FET Switch On-Card Enabled: No \n");
  55113. +
  55114. + if (dimmInfo.dimmAttributes & BIT4)
  55115. + mvOsOutput(" FET Switch External Enabled: Yes \n");
  55116. + else
  55117. + mvOsOutput(" FET Switch External Enabled: No \n");
  55118. +
  55119. + if (dimmInfo.dimmAttributes & BIT5)
  55120. + mvOsOutput(" Differential Clock Input: Yes \n");
  55121. + else
  55122. + mvOsOutput(" Differential Clock Input: No \n");
  55123. + }
  55124. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  55125. + {
  55126. + mvOsOutput(" Number of Active Registers on the DIMM: %d\n",
  55127. + (dimmInfo.dimmAttributes & 0x3) + 1);
  55128. +
  55129. + mvOsOutput(" Number of PLLs on the DIMM: %d\n",
  55130. + ((dimmInfo.dimmAttributes) >> 2) & 0x3);
  55131. +
  55132. + if (dimmInfo.dimmAttributes & BIT4)
  55133. + mvOsOutput(" FET Switch External Enabled: Yes \n");
  55134. + else
  55135. + mvOsOutput(" FET Switch External Enabled: No \n");
  55136. +
  55137. + if (dimmInfo.dimmAttributes & BIT6)
  55138. + mvOsOutput(" Analysis probe installed: Yes \n");
  55139. + else
  55140. + mvOsOutput(" Analysis probe installed: No \n");
  55141. + }
  55142. +
  55143. + break;
  55144. +/*----------------------------------------------------------------------------*/
  55145. +
  55146. + case 22: /* Suported AutoPreCharge */
  55147. + mvOsOutput("\nModul Attributes (SPD Byte 22): \n");
  55148. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  55149. + {
  55150. + if ( spdRawData[i] & BIT0 )
  55151. + mvOsOutput(" Early Ras Precharge: Yes \n");
  55152. + else
  55153. + mvOsOutput(" Early Ras Precharge: No \n");
  55154. +
  55155. + if ( spdRawData[i] & BIT1 )
  55156. + mvOsOutput(" AutoPreCharge: Yes \n");
  55157. + else
  55158. + mvOsOutput(" AutoPreCharge: No \n");
  55159. +
  55160. + if ( spdRawData[i] & BIT2 )
  55161. + mvOsOutput(" Precharge All: Yes \n");
  55162. + else
  55163. + mvOsOutput(" Precharge All: No \n");
  55164. +
  55165. + if ( spdRawData[i] & BIT3 )
  55166. + mvOsOutput(" Write 1/ReadBurst: Yes \n");
  55167. + else
  55168. + mvOsOutput(" Write 1/ReadBurst: No \n");
  55169. +
  55170. + if ( spdRawData[i] & BIT4 )
  55171. + mvOsOutput(" lower VCC tolerance: 5%%\n");
  55172. + else
  55173. + mvOsOutput(" lower VCC tolerance: 10%%\n");
  55174. +
  55175. + if ( spdRawData[i] & BIT5 )
  55176. + mvOsOutput(" upper VCC tolerance: 5%%\n");
  55177. + else
  55178. + mvOsOutput(" upper VCC tolerance: 10%%\n");
  55179. + }
  55180. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  55181. + {
  55182. + if ( spdRawData[i] & BIT0 )
  55183. + mvOsOutput(" Supports Weak Driver: Yes \n");
  55184. + else
  55185. + mvOsOutput(" Supports Weak Driver: No \n");
  55186. +
  55187. + if ( !(spdRawData[i] & BIT4) )
  55188. + mvOsOutput(" lower VCC tolerance: 0.2V\n");
  55189. +
  55190. + if ( !(spdRawData[i] & BIT5) )
  55191. + mvOsOutput(" upper VCC tolerance: 0.2V\n");
  55192. +
  55193. + if ( spdRawData[i] & BIT6 )
  55194. + mvOsOutput(" Concurrent Auto Preharge: Yes \n");
  55195. + else
  55196. + mvOsOutput(" Concurrent Auto Preharge: No \n");
  55197. +
  55198. + if ( spdRawData[i] & BIT7 )
  55199. + mvOsOutput(" Supports Fast AP: Yes \n");
  55200. + else
  55201. + mvOsOutput(" Supports Fast AP: No \n");
  55202. + }
  55203. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  55204. + {
  55205. + if ( spdRawData[i] & BIT0 )
  55206. + mvOsOutput(" Supports Weak Driver: Yes \n");
  55207. + else
  55208. + mvOsOutput(" Supports Weak Driver: No \n");
  55209. + }
  55210. + break;
  55211. +/*----------------------------------------------------------------------------*/
  55212. +
  55213. + case 23:
  55214. + /* Minimum Cycle Time At Maximum Cas Latancy Minus 1 (2nd highest CL) */
  55215. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  55216. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  55217. +
  55218. + /* DDR2 addition of right of point */
  55219. + if ((spdRawData[i] & 0x0f) == 0xA)
  55220. + {
  55221. + rightOfPoint = 25;
  55222. + }
  55223. + if ((spdRawData[i] & 0x0f) == 0xB)
  55224. + {
  55225. + rightOfPoint = 33;
  55226. + }
  55227. + if ((spdRawData[i] & 0x0f) == 0xC)
  55228. + {
  55229. + rightOfPoint = 66;
  55230. + }
  55231. + if ((spdRawData[i] & 0x0f) == 0xD)
  55232. + {
  55233. + rightOfPoint = 75;
  55234. + }
  55235. +
  55236. + mvOsOutput("Minimum Cycle Time At 2nd highest CasLatancy"
  55237. + "(0 = Not supported): %d.%d [ns]\n",
  55238. + leftOfPoint, rightOfPoint );
  55239. + break;
  55240. +/*----------------------------------------------------------------------------*/
  55241. +
  55242. + case 24: /* Clock To Data Out 2nd highest Cas Latency Value*/
  55243. + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 10:100;
  55244. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  55245. + ((spdRawData[i] & 0x0f));
  55246. + leftOfPoint = time_tmp / div;
  55247. + rightOfPoint = time_tmp % div;
  55248. + mvOsOutput("Clock To Data Out (2nd CL value): %d.%d [ns]\n",
  55249. + leftOfPoint, rightOfPoint);
  55250. + break;
  55251. +/*----------------------------------------------------------------------------*/
  55252. +
  55253. + case 25:
  55254. + /* Minimum Cycle Time At Maximum Cas Latancy Minus 2 (3rd highest CL) */
  55255. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  55256. + {
  55257. + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
  55258. + rightOfPoint = (spdRawData[i] & 0x3) * 25;
  55259. + }
  55260. + else /* DDR1 or DDR2 */
  55261. + {
  55262. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  55263. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  55264. +
  55265. + /* DDR2 addition of right of point */
  55266. + if ((spdRawData[i] & 0x0f) == 0xA)
  55267. + {
  55268. + rightOfPoint = 25;
  55269. + }
  55270. + if ((spdRawData[i] & 0x0f) == 0xB)
  55271. + {
  55272. + rightOfPoint = 33;
  55273. + }
  55274. + if ((spdRawData[i] & 0x0f) == 0xC)
  55275. + {
  55276. + rightOfPoint = 66;
  55277. + }
  55278. + if ((spdRawData[i] & 0x0f) == 0xD)
  55279. + {
  55280. + rightOfPoint = 75;
  55281. + }
  55282. + }
  55283. + mvOsOutput("Minimum Cycle Time At 3rd highest CasLatancy"
  55284. + "(0 = Not supported): %d.%d [ns]\n",
  55285. + leftOfPoint, rightOfPoint );
  55286. + break;
  55287. +/*----------------------------------------------------------------------------*/
  55288. +
  55289. + case 26: /* Clock To Data Out 3rd highest Cas Latency Value*/
  55290. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  55291. + {
  55292. + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
  55293. + rightOfPoint = (spdRawData[i] & 0x3) * 25;
  55294. + }
  55295. + else /* DDR1 or DDR2 */
  55296. + {
  55297. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  55298. + ((spdRawData[i] & 0x0f));
  55299. + leftOfPoint = 0;
  55300. + rightOfPoint = time_tmp;
  55301. + }
  55302. + mvOsOutput("Clock To Data Out (3rd CL value): %d.%2d[ns]\n",
  55303. + leftOfPoint, rightOfPoint );
  55304. + break;
  55305. +/*----------------------------------------------------------------------------*/
  55306. +
  55307. + case 27: /* Minimum Row Precharge Time */
  55308. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  55309. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  55310. + 0xff : 0xfc;
  55311. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  55312. + 0x00 : 0x03;
  55313. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  55314. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  55315. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 10ps Intervals*/
  55316. + trp_clocks = (temp + (busClkPs-1)) / busClkPs;
  55317. + mvOsOutput("Minimum Row Precharge Time [ns]: %d.%d = "
  55318. + "in Clk cycles %d\n",
  55319. + leftOfPoint, rightOfPoint, trp_clocks);
  55320. + break;
  55321. +/*----------------------------------------------------------------------------*/
  55322. +
  55323. + case 28: /* Minimum Row Active to Row Active Time */
  55324. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  55325. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  55326. + 0xff : 0xfc;
  55327. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  55328. + 0x00 : 0x03;
  55329. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  55330. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  55331. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
  55332. + trrd_clocks = (temp + (busClkPs-1)) / busClkPs;
  55333. + mvOsOutput("Minimum Row Active -To- Row Active Delay [ns]: "
  55334. + "%d.%d = in Clk cycles %d\n",
  55335. + leftOfPoint, rightOfPoint, trp_clocks);
  55336. + break;
  55337. +/*----------------------------------------------------------------------------*/
  55338. +
  55339. + case 29: /* Minimum Ras-To-Cas Delay */
  55340. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  55341. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  55342. + 0xff : 0xfc;
  55343. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  55344. + 0x00 : 0x03;
  55345. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  55346. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  55347. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
  55348. + trcd_clocks = (temp + (busClkPs-1) )/ busClkPs;
  55349. + mvOsOutput("Minimum Ras-To-Cas Delay [ns]: %d.%d = "
  55350. + "in Clk cycles %d\n",
  55351. + leftOfPoint, rightOfPoint, trp_clocks);
  55352. + break;
  55353. +/*----------------------------------------------------------------------------*/
  55354. +
  55355. + case 30: /* Minimum Ras Pulse Width */
  55356. + tras_clocks = (cas2ps(spdRawData[i])+(busClkPs-1)) / busClkPs;
  55357. + mvOsOutput("Minimum Ras Pulse Width [ns]: %d = "
  55358. + "in Clk cycles %d\n", spdRawData[i], tras_clocks);
  55359. + break;
  55360. +/*----------------------------------------------------------------------------*/
  55361. +
  55362. + case 31: /* Module Bank Density */
  55363. + mvOsOutput("Module Bank Density (more than 1= Multisize-Module):");
  55364. +
  55365. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  55366. + {
  55367. + if (dimmInfo.dimmBankDensity & BIT0)
  55368. + mvOsOutput("1GB, ");
  55369. + if (dimmInfo.dimmBankDensity & BIT1)
  55370. + mvOsOutput("8MB, ");
  55371. + if (dimmInfo.dimmBankDensity & BIT2)
  55372. + mvOsOutput("16MB, ");
  55373. + if (dimmInfo.dimmBankDensity & BIT3)
  55374. + mvOsOutput("32MB, ");
  55375. + if (dimmInfo.dimmBankDensity & BIT4)
  55376. + mvOsOutput("64MB, ");
  55377. + if (dimmInfo.dimmBankDensity & BIT5)
  55378. + mvOsOutput("128MB, ");
  55379. + if (dimmInfo.dimmBankDensity & BIT6)
  55380. + mvOsOutput("256MB, ");
  55381. + if (dimmInfo.dimmBankDensity & BIT7)
  55382. + mvOsOutput("512MB, ");
  55383. + }
  55384. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  55385. + {
  55386. + if (dimmInfo.dimmBankDensity & BIT0)
  55387. + mvOsOutput("1GB, ");
  55388. + if (dimmInfo.dimmBankDensity & BIT1)
  55389. + mvOsOutput("2GB, ");
  55390. + if (dimmInfo.dimmBankDensity & BIT2)
  55391. + mvOsOutput("16MB, ");
  55392. + if (dimmInfo.dimmBankDensity & BIT3)
  55393. + mvOsOutput("32MB, ");
  55394. + if (dimmInfo.dimmBankDensity & BIT4)
  55395. + mvOsOutput("64MB, ");
  55396. + if (dimmInfo.dimmBankDensity & BIT5)
  55397. + mvOsOutput("128MB, ");
  55398. + if (dimmInfo.dimmBankDensity & BIT6)
  55399. + mvOsOutput("256MB, ");
  55400. + if (dimmInfo.dimmBankDensity & BIT7)
  55401. + mvOsOutput("512MB, ");
  55402. + }
  55403. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  55404. + {
  55405. + if (dimmInfo.dimmBankDensity & BIT0)
  55406. + mvOsOutput("1GB, ");
  55407. + if (dimmInfo.dimmBankDensity & BIT1)
  55408. + mvOsOutput("2GB, ");
  55409. + if (dimmInfo.dimmBankDensity & BIT2)
  55410. + mvOsOutput("4GB, ");
  55411. + if (dimmInfo.dimmBankDensity & BIT3)
  55412. + mvOsOutput("8GB, ");
  55413. + if (dimmInfo.dimmBankDensity & BIT4)
  55414. + mvOsOutput("16GB, ");
  55415. + if (dimmInfo.dimmBankDensity & BIT5)
  55416. + mvOsOutput("128MB, ");
  55417. + if (dimmInfo.dimmBankDensity & BIT6)
  55418. + mvOsOutput("256MB, ");
  55419. + if (dimmInfo.dimmBankDensity & BIT7)
  55420. + mvOsOutput("512MB, ");
  55421. + }
  55422. + mvOsOutput("\n");
  55423. + break;
  55424. +/*----------------------------------------------------------------------------*/
  55425. +
  55426. + case 32: /* Address And Command Setup Time (measured in ns/1000) */
  55427. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  55428. + {
  55429. + rightOfPoint = (spdRawData[i] & 0x0f);
  55430. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  55431. + if(leftOfPoint > 7)
  55432. + {
  55433. + leftOfPoint *= -1;
  55434. + }
  55435. + }
  55436. + else /* DDR1 or DDR2 */
  55437. + {
  55438. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  55439. + ((spdRawData[i] & 0x0f));
  55440. + leftOfPoint = time_tmp / 100;
  55441. + rightOfPoint = time_tmp % 100;
  55442. + }
  55443. + mvOsOutput("Address And Command Setup Time [ns]: %d.%d\n",
  55444. + leftOfPoint, rightOfPoint);
  55445. + break;
  55446. +/*----------------------------------------------------------------------------*/
  55447. +
  55448. + case 33: /* Address And Command Hold Time */
  55449. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  55450. + {
  55451. + rightOfPoint = (spdRawData[i] & 0x0f);
  55452. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  55453. + if(leftOfPoint > 7)
  55454. + {
  55455. + leftOfPoint *= -1;
  55456. + }
  55457. + }
  55458. + else /* DDR1 or DDR2 */
  55459. + {
  55460. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  55461. + ((spdRawData[i] & 0x0f));
  55462. + leftOfPoint = time_tmp / 100;
  55463. + rightOfPoint = time_tmp % 100;
  55464. + }
  55465. + mvOsOutput("Address And Command Hold Time [ns]: %d.%d\n",
  55466. + leftOfPoint, rightOfPoint);
  55467. + break;
  55468. +/*----------------------------------------------------------------------------*/
  55469. +
  55470. + case 34: /* Data Input Setup Time */
  55471. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  55472. + {
  55473. + rightOfPoint = (spdRawData[i] & 0x0f);
  55474. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  55475. + if(leftOfPoint > 7)
  55476. + {
  55477. + leftOfPoint *= -1;
  55478. + }
  55479. + }
  55480. + else /* DDR1 or DDR2 */
  55481. + {
  55482. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  55483. + ((spdRawData[i] & 0x0f));
  55484. + leftOfPoint = time_tmp / 100;
  55485. + rightOfPoint = time_tmp % 100;
  55486. + }
  55487. + mvOsOutput("Data Input Setup Time [ns]: %d.%d\n",
  55488. + leftOfPoint, rightOfPoint);
  55489. + break;
  55490. +/*----------------------------------------------------------------------------*/
  55491. +
  55492. + case 35: /* Data Input Hold Time */
  55493. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  55494. + {
  55495. + rightOfPoint = (spdRawData[i] & 0x0f);
  55496. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  55497. + if(leftOfPoint > 7)
  55498. + {
  55499. + leftOfPoint *= -1;
  55500. + }
  55501. + }
  55502. + else /* DDR1 or DDR2 */
  55503. + {
  55504. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  55505. + ((spdRawData[i] & 0x0f));
  55506. + leftOfPoint = time_tmp / 100;
  55507. + rightOfPoint = time_tmp % 100;
  55508. + }
  55509. + mvOsOutput("Data Input Hold Time [ns]: %d.%d\n\n",
  55510. + leftOfPoint, rightOfPoint);
  55511. + break;
  55512. +/*----------------------------------------------------------------------------*/
  55513. +
  55514. + case 36: /* Relevant for DDR2 only: Write Recovery Time */
  55515. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> 2);
  55516. + rightOfPoint = (spdRawData[i] & maskRightOfPoint) * 25;
  55517. + mvOsOutput("Write Recovery Time [ns]: %d.%d\n",
  55518. + leftOfPoint, rightOfPoint);
  55519. + break;
  55520. +/*----------------------------------------------------------------------------*/
  55521. + }
  55522. +
  55523. +}
  55524. +
  55525. +
  55526. +/*
  55527. + * translate ns.ns/10 coding of SPD timing values
  55528. + * into ps unit values
  55529. + */
  55530. +/*******************************************************************************
  55531. +* cas2ps - Translate x.y ns parameter to pico-seconds values
  55532. +*
  55533. +* DESCRIPTION:
  55534. +* This function translates x.y nano seconds to its value in pico seconds.
  55535. +* For example 3.75ns will return 3750.
  55536. +*
  55537. +* INPUT:
  55538. +* spd_byte - DIMM SPD byte.
  55539. +*
  55540. +* OUTPUT:
  55541. +* None.
  55542. +*
  55543. +* RETURN:
  55544. +* value in pico seconds.
  55545. +*
  55546. +*******************************************************************************/
  55547. +static MV_U32 cas2ps(MV_U8 spd_byte)
  55548. +{
  55549. + MV_U32 ns, ns10;
  55550. +
  55551. + /* isolate upper nibble */
  55552. + ns = (spd_byte >> 4) & 0x0F;
  55553. + /* isolate lower nibble */
  55554. + ns10 = (spd_byte & 0x0F);
  55555. +
  55556. + if( ns10 < 10 ) {
  55557. + ns10 *= 10;
  55558. + }
  55559. + else if( ns10 == 10 )
  55560. + ns10 = 25;
  55561. + else if( ns10 == 11 )
  55562. + ns10 = 33;
  55563. + else if( ns10 == 12 )
  55564. + ns10 = 66;
  55565. + else if( ns10 == 13 )
  55566. + ns10 = 75;
  55567. + else
  55568. + {
  55569. + mvOsOutput("cas2ps Err. unsupported cycle time.\n");
  55570. + }
  55571. +
  55572. + return (ns*1000 + ns10*10);
  55573. +}
  55574. +
  55575. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h
  55576. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h 1970-01-01 01:00:00.000000000 +0100
  55577. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDram.h 2011-08-01 14:38:19.000000000 +0200
  55578. @@ -0,0 +1,191 @@
  55579. +/*******************************************************************************
  55580. +Copyright (C) Marvell International Ltd. and its affiliates
  55581. +
  55582. +This software file (the "File") is owned and distributed by Marvell
  55583. +International Ltd. and/or its affiliates ("Marvell") under the following
  55584. +alternative licensing terms. Once you have made an election to distribute the
  55585. +File under one of the following license alternatives, please (i) delete this
  55586. +introductory statement regarding license alternatives, (ii) delete the two
  55587. +license alternatives that you have not elected to use and (iii) preserve the
  55588. +Marvell copyright notice above.
  55589. +
  55590. +********************************************************************************
  55591. +Marvell Commercial License Option
  55592. +
  55593. +If you received this File from Marvell and you have entered into a commercial
  55594. +license agreement (a "Commercial License") with Marvell, the File is licensed
  55595. +to you under the terms of the applicable Commercial License.
  55596. +
  55597. +********************************************************************************
  55598. +Marvell GPL License Option
  55599. +
  55600. +If you received this File from Marvell, you may opt to use, redistribute and/or
  55601. +modify this File in accordance with the terms and conditions of the General
  55602. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  55603. +available along with the File in the license.txt file or by writing to the Free
  55604. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  55605. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  55606. +
  55607. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  55608. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  55609. +DISCLAIMED. The GPL License provides additional details about this warranty
  55610. +disclaimer.
  55611. +********************************************************************************
  55612. +Marvell BSD License Option
  55613. +
  55614. +If you received this File from Marvell, you may opt to use, redistribute and/or
  55615. +modify this File under the following licensing terms.
  55616. +Redistribution and use in source and binary forms, with or without modification,
  55617. +are permitted provided that the following conditions are met:
  55618. +
  55619. + * Redistributions of source code must retain the above copyright notice,
  55620. + this list of conditions and the following disclaimer.
  55621. +
  55622. + * Redistributions in binary form must reproduce the above copyright
  55623. + notice, this list of conditions and the following disclaimer in the
  55624. + documentation and/or other materials provided with the distribution.
  55625. +
  55626. + * Neither the name of Marvell nor the names of its contributors may be
  55627. + used to endorse or promote products derived from this software without
  55628. + specific prior written permission.
  55629. +
  55630. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  55631. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  55632. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  55633. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  55634. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  55635. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  55636. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  55637. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  55638. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  55639. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  55640. +
  55641. +*******************************************************************************/
  55642. +
  55643. +#ifndef __INCmvDram
  55644. +#define __INCmvDram
  55645. +
  55646. +#include "ddr1_2/mvDramIf.h"
  55647. +#include "twsi/mvTwsi.h"
  55648. +
  55649. +#define MAX_DIMM_NUM 2
  55650. +#define SPD_SIZE 128
  55651. +
  55652. +/* Dimm spd offsets */
  55653. +#define DIMM_MEM_TYPE 2
  55654. +#define DIMM_ROW_NUM 3
  55655. +#define DIMM_COL_NUM 4
  55656. +#define DIMM_MODULE_BANK_NUM 5
  55657. +#define DIMM_DATA_WIDTH 6
  55658. +#define DIMM_VOLT_IF 8
  55659. +#define DIMM_MIN_CC_AT_MAX_CAS 9
  55660. +#define DIMM_ERR_CHECK_TYPE 11
  55661. +#define DIMM_REFRESH_INTERVAL 12
  55662. +#define DIMM_SDRAM_WIDTH 13
  55663. +#define DIMM_ERR_CHECK_DATA_WIDTH 14
  55664. +#define DIMM_MIN_CLK_DEL 15
  55665. +#define DIMM_BURST_LEN_SUP 16
  55666. +#define DIMM_DEV_BANK_NUM 17
  55667. +#define DIMM_SUP_CAL 18
  55668. +#define DIMM_DDR2_TYPE_INFORMATION 20 /* DDR2 only */
  55669. +#define DIMM_BUF_ADDR_CONT_IN 21
  55670. +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS1 23
  55671. +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS2 25
  55672. +#define DIMM_MIN_ROW_PRECHARGE_TIME 27
  55673. +#define DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE 28
  55674. +#define DIMM_MIN_RAS_TO_CAS_DELAY 29
  55675. +#define DIMM_MIN_RAS_PULSE_WIDTH 30
  55676. +#define DIMM_BANK_DENSITY 31
  55677. +#define DIMM_MIN_WRITE_RECOVERY_TIME 36
  55678. +#define DIMM_MIN_WRITE_TO_READ_CMD_DELAY 37
  55679. +#define DIMM_MIN_READ_TO_PRECH_CMD_DELAY 38
  55680. +#define DIMM_MIN_REFRESH_TO_ACTIVATE_CMD 42
  55681. +
  55682. +/* Dimm Memory Type values */
  55683. +#define DIMM_MEM_TYPE_SDRAM 0x4
  55684. +#define DIMM_MEM_TYPE_DDR1 0x7
  55685. +#define DIMM_MEM_TYPE_DDR2 0x8
  55686. +
  55687. +#define DIMM_MODULE_MANU_OFFS 64
  55688. +#define DIMM_MODULE_MANU_SIZE 8
  55689. +#define DIMM_MODULE_VEN_OFFS 73
  55690. +#define DIMM_MODULE_VEN_SIZE 25
  55691. +#define DIMM_MODULE_ID_OFFS 99
  55692. +#define DIMM_MODULE_ID_SIZE 18
  55693. +
  55694. +/* enumeration for voltage levels. */
  55695. +typedef enum _mvDimmVoltageIf
  55696. +{
  55697. + TTL_5V_TOLERANT,
  55698. + LVTTL,
  55699. + HSTL_1_5V,
  55700. + SSTL_3_3V,
  55701. + SSTL_2_5V,
  55702. + VOLTAGE_UNKNOWN,
  55703. +} MV_DIMM_VOLTAGE_IF;
  55704. +
  55705. +
  55706. +/* enumaration for SDRAM CAS Latencies. */
  55707. +typedef enum _mvDimmSdramCas
  55708. +{
  55709. + SD_CL_1 =1,
  55710. + SD_CL_2,
  55711. + SD_CL_3,
  55712. + SD_CL_4,
  55713. + SD_CL_5,
  55714. + SD_CL_6,
  55715. + SD_CL_7,
  55716. + SD_FAULT
  55717. +}MV_DIMM_SDRAM_CAS;
  55718. +
  55719. +
  55720. +/* DIMM information structure */
  55721. +typedef struct _mvDimmInfo
  55722. +{
  55723. + MV_MEMORY_TYPE memoryType; /* DDR or SDRAM */
  55724. +
  55725. + MV_U8 spdRawData[SPD_SIZE]; /* Content of SPD-EEPROM copied 1:1 */
  55726. +
  55727. + /* DIMM dimensions */
  55728. + MV_U32 numOfRowAddr;
  55729. + MV_U32 numOfColAddr;
  55730. + MV_U32 numOfModuleBanks;
  55731. + MV_U32 dataWidth;
  55732. + MV_U32 errorCheckType; /* ECC , PARITY..*/
  55733. + MV_U32 sdramWidth; /* 4,8,16 or 32 */
  55734. + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
  55735. + MV_U32 burstLengthSupported;
  55736. + MV_U32 numOfBanksOnEachDevice;
  55737. + MV_U32 suportedCasLatencies;
  55738. + MV_U32 refreshInterval;
  55739. + MV_U32 dimmBankDensity;
  55740. + MV_U32 dimmTypeInfo; /* DDR2 only */
  55741. + MV_U32 dimmAttributes;
  55742. +
  55743. + /* DIMM timing parameters */
  55744. + MV_U32 minCycleTimeAtMaxCasLatPs;
  55745. + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
  55746. + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
  55747. + MV_U32 minRowPrechargeTime;
  55748. + MV_U32 minRowActiveToRowActive;
  55749. + MV_U32 minRasToCasDelay;
  55750. + MV_U32 minRasPulseWidth;
  55751. + MV_U32 minWriteRecoveryTime; /* DDR2 only */
  55752. + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
  55753. + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
  55754. + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
  55755. +
  55756. + /* Parameters calculated from the extracted DIMM information */
  55757. + MV_U32 size; /* 16,64,128,256 or 512 MByte in MB units */
  55758. + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit in MB units */
  55759. + MV_U32 numberOfDevices;
  55760. +
  55761. +} MV_DIMM_INFO;
  55762. +
  55763. +
  55764. +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo);
  55765. +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo);
  55766. +MV_VOID dimmSpdPrint(MV_U32 dimmNum);
  55767. +MV_STATUS dimmSpdCpy(MV_VOID);
  55768. +
  55769. +#endif /* __INCmvDram */
  55770. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c
  55771. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c 1970-01-01 01:00:00.000000000 +0100
  55772. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.c 2011-08-01 14:38:19.000000000 +0200
  55773. @@ -0,0 +1,1599 @@
  55774. +/*******************************************************************************
  55775. +Copyright (C) Marvell International Ltd. and its affiliates
  55776. +
  55777. +This software file (the "File") is owned and distributed by Marvell
  55778. +International Ltd. and/or its affiliates ("Marvell") under the following
  55779. +alternative licensing terms. Once you have made an election to distribute the
  55780. +File under one of the following license alternatives, please (i) delete this
  55781. +introductory statement regarding license alternatives, (ii) delete the two
  55782. +license alternatives that you have not elected to use and (iii) preserve the
  55783. +Marvell copyright notice above.
  55784. +
  55785. +********************************************************************************
  55786. +Marvell Commercial License Option
  55787. +
  55788. +If you received this File from Marvell and you have entered into a commercial
  55789. +license agreement (a "Commercial License") with Marvell, the File is licensed
  55790. +to you under the terms of the applicable Commercial License.
  55791. +
  55792. +********************************************************************************
  55793. +Marvell GPL License Option
  55794. +
  55795. +If you received this File from Marvell, you may opt to use, redistribute and/or
  55796. +modify this File in accordance with the terms and conditions of the General
  55797. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  55798. +available along with the File in the license.txt file or by writing to the Free
  55799. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  55800. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  55801. +
  55802. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  55803. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  55804. +DISCLAIMED. The GPL License provides additional details about this warranty
  55805. +disclaimer.
  55806. +********************************************************************************
  55807. +Marvell BSD License Option
  55808. +
  55809. +If you received this File from Marvell, you may opt to use, redistribute and/or
  55810. +modify this File under the following licensing terms.
  55811. +Redistribution and use in source and binary forms, with or without modification,
  55812. +are permitted provided that the following conditions are met:
  55813. +
  55814. + * Redistributions of source code must retain the above copyright notice,
  55815. + this list of conditions and the following disclaimer.
  55816. +
  55817. + * Redistributions in binary form must reproduce the above copyright
  55818. + notice, this list of conditions and the following disclaimer in the
  55819. + documentation and/or other materials provided with the distribution.
  55820. +
  55821. + * Neither the name of Marvell nor the names of its contributors may be
  55822. + used to endorse or promote products derived from this software without
  55823. + specific prior written permission.
  55824. +
  55825. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  55826. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  55827. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  55828. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  55829. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  55830. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  55831. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  55832. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  55833. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  55834. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  55835. +
  55836. +*******************************************************************************/
  55837. +
  55838. +
  55839. +/* includes */
  55840. +#include "ddr1_2/mvDramIf.h"
  55841. +#include "ctrlEnv/sys/mvCpuIf.h"
  55842. +
  55843. +
  55844. +
  55845. +#ifdef MV_DEBUG
  55846. +#define DB(x) x
  55847. +#else
  55848. +#define DB(x)
  55849. +#endif
  55850. +
  55851. +/* DRAM bank presence encoding */
  55852. +#define BANK_PRESENT_CS0 0x1
  55853. +#define BANK_PRESENT_CS0_CS1 0x3
  55854. +#define BANK_PRESENT_CS0_CS2 0x5
  55855. +#define BANK_PRESENT_CS0_CS1_CS2 0x7
  55856. +#define BANK_PRESENT_CS0_CS2_CS3 0xd
  55857. +#define BANK_PRESENT_CS0_CS2_CS3_CS4 0xf
  55858. +
  55859. +/* locals */
  55860. +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin);
  55861. +#if defined(MV_INC_BOARD_DDIM)
  55862. +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo);
  55863. +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas);
  55864. +static MV_U32 sdramModeRegCalc(MV_U32 minCas);
  55865. +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo);
  55866. +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo);
  55867. +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
  55868. +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk,
  55869. + MV_U32 forcedCl);
  55870. +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
  55871. + MV_U32 minCas, MV_U32 busClk);
  55872. +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
  55873. + MV_U32 busClk);
  55874. +
  55875. +/*******************************************************************************
  55876. +* mvDramIfDetect - Prepare DRAM interface configuration values.
  55877. +*
  55878. +* DESCRIPTION:
  55879. +* This function implements the full DRAM detection and timing
  55880. +* configuration for best system performance.
  55881. +* Since this routine runs from a ROM device (Boot Flash), its stack
  55882. +* resides on RAM, that might be the system DRAM. Changing DRAM
  55883. +* configuration values while keeping vital data in DRAM is risky. That
  55884. +* is why the function does not preform the configuration setting but
  55885. +* prepare those in predefined 32bit registers (in this case IDMA
  55886. +* registers are used) for other routine to perform the settings.
  55887. +* The function will call for board DRAM SPD information for each DRAM
  55888. +* chip select. The function will then analyze those SPD parameters of
  55889. +* all DRAM banks in order to decide on DRAM configuration compatible
  55890. +* for all DRAM banks.
  55891. +* The function will set the CPU DRAM address decode registers.
  55892. +* Note: This routine prepares values that will overide configuration of
  55893. +* mvDramBasicAsmInit().
  55894. +*
  55895. +* INPUT:
  55896. +* forcedCl - Forced CAL Latency. If equal to zero, do not force.
  55897. +*
  55898. +* OUTPUT:
  55899. +* None.
  55900. +*
  55901. +* RETURN:
  55902. +* None.
  55903. +*
  55904. +*******************************************************************************/
  55905. +MV_STATUS mvDramIfDetect(MV_U32 forcedCl)
  55906. +{
  55907. + MV_U32 retVal = MV_OK; /* return value */
  55908. + MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
  55909. + MV_U32 busClk, size, base = 0, i, temp, deviceW, dimmW;
  55910. + MV_U8 minCas;
  55911. + MV_DRAM_DEC_WIN dramDecWin;
  55912. +
  55913. + dramDecWin.addrWin.baseHigh = 0;
  55914. +
  55915. + busClk = mvBoardSysClkGet();
  55916. +
  55917. + if (0 == busClk)
  55918. + {
  55919. + mvOsPrintf("Dram: ERR. Can't detect system clock! \n");
  55920. + return MV_ERROR;
  55921. + }
  55922. +
  55923. + /* Close DRAM banks except bank 0 (in case code is excecuting from it...) */
  55924. +#if defined(MV_INCLUDE_SDRAM_CS1)
  55925. + for(i= SDRAM_CS1; i < MV_DRAM_MAX_CS; i++)
  55926. + mvCpuIfTargetWinEnable(i, MV_FALSE);
  55927. +#endif
  55928. +
  55929. + /* we will use bank 0 as the representative of the all the DRAM banks, */
  55930. + /* since bank 0 must exist. */
  55931. + for(i = 0; i < MV_DRAM_MAX_CS; i++)
  55932. + {
  55933. + /* if Bank exist */
  55934. + if(MV_OK == mvDramBankInfoGet(i, &bankInfo[i]))
  55935. + {
  55936. + /* check it isn't SDRAM */
  55937. + if(bankInfo[i].memoryType == MEM_TYPE_SDRAM)
  55938. + {
  55939. + mvOsPrintf("Dram: ERR. SDRAM type not supported !!!\n");
  55940. + return MV_ERROR;
  55941. + }
  55942. + /* All banks must support registry in order to activate it */
  55943. + if(bankInfo[i].registeredAddrAndControlInputs !=
  55944. + bankInfo[0].registeredAddrAndControlInputs)
  55945. + {
  55946. + mvOsPrintf("Dram: ERR. different Registered settings !!!\n");
  55947. + return MV_ERROR;
  55948. + }
  55949. +
  55950. + /* Init the CPU window decode */
  55951. + /* Note that the size in Bank info is in MB units */
  55952. + /* Note that the Dimm width might be different then the device DRAM width */
  55953. + temp = MV_REG_READ(SDRAM_CONFIG_REG);
  55954. +
  55955. + deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_16BIT )? 16 : 32;
  55956. + dimmW = bankInfo[0].dataWidth - (bankInfo[0].dataWidth % 16);
  55957. + size = ((bankInfo[i].size << 20) / (dimmW/deviceW));
  55958. +
  55959. + /* We can not change DRAM window settings while excecuting */
  55960. + /* code from it. That is why we skip the DRAM CS[0], saving */
  55961. + /* it to the ROM configuration routine */
  55962. + if(i == SDRAM_CS0)
  55963. + {
  55964. + MV_U32 sizeToReg;
  55965. +
  55966. + /* Translate the given window size to register format */
  55967. + sizeToReg = ctrlSizeToReg(size, SCSR_SIZE_ALIGNMENT);
  55968. +
  55969. + /* Size parameter validity check. */
  55970. + if (-1 == sizeToReg)
  55971. + {
  55972. + mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n"
  55973. + ,i);
  55974. + return MV_BAD_PARAM;
  55975. + }
  55976. +
  55977. + /* Size is located at upper 16 bits */
  55978. + sizeToReg <<= SCSR_SIZE_OFFS;
  55979. +
  55980. + /* enable it */
  55981. + sizeToReg |= SCSR_WIN_EN;
  55982. +
  55983. + MV_REG_WRITE(DRAM_BUF_REG0, sizeToReg);
  55984. + }
  55985. + else
  55986. + {
  55987. + dramDecWin.addrWin.baseLow = base;
  55988. + dramDecWin.addrWin.size = size;
  55989. + dramDecWin.enable = MV_TRUE;
  55990. +
  55991. + if (MV_OK != mvDramIfWinSet(SDRAM_CS0 + i, &dramDecWin))
  55992. + {
  55993. + mvOsPrintf("Dram: ERR. Fail to set bank %d!!!\n",
  55994. + SDRAM_CS0 + i);
  55995. + return MV_ERROR;
  55996. + }
  55997. + }
  55998. +
  55999. + base += size;
  56000. +
  56001. + /* update the suportedCasLatencies mask */
  56002. + bankInfo[0].suportedCasLatencies &= bankInfo[i].suportedCasLatencies;
  56003. +
  56004. + }
  56005. + else
  56006. + {
  56007. + if( i == 0 ) /* bank 0 doesn't exist */
  56008. + {
  56009. + mvOsPrintf("Dram: ERR. Fail to detect bank 0 !!!\n");
  56010. + return MV_ERROR;
  56011. + }
  56012. + else
  56013. + {
  56014. + DB(mvOsPrintf("Dram: Could not find bank %d\n", i));
  56015. + bankInfo[i].size = 0; /* Mark this bank as non exist */
  56016. + }
  56017. + }
  56018. + }
  56019. +
  56020. + /* calculate minimum CAS */
  56021. + minCas = minCasCalc(&bankInfo[0], busClk, forcedCl);
  56022. + if (0 == minCas)
  56023. + {
  56024. + mvOsOutput("Dram: Warn: Could not find CAS compatible to SysClk %dMhz\n",
  56025. + (busClk / 1000000));
  56026. +
  56027. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  56028. + {
  56029. + minCas = DDR2_CL_4; /* Continue with this CAS */
  56030. + mvOsPrintf("Set default CAS latency 4\n");
  56031. + }
  56032. + else
  56033. + {
  56034. + minCas = DDR1_CL_3; /* Continue with this CAS */
  56035. + mvOsPrintf("Set default CAS latency 3\n");
  56036. + }
  56037. + }
  56038. +
  56039. + /* calc SDRAM_CONFIG_REG and save it to temp register */
  56040. + temp = sdramConfigRegCalc(&bankInfo[0], busClk);
  56041. + if(-1 == temp)
  56042. + {
  56043. + mvOsPrintf("Dram: ERR. sdramConfigRegCalc failed !!!\n");
  56044. + return MV_ERROR;
  56045. + }
  56046. + MV_REG_WRITE(DRAM_BUF_REG1, temp);
  56047. +
  56048. + /* calc SDRAM_MODE_REG and save it to temp register */
  56049. + temp = sdramModeRegCalc(minCas);
  56050. + if(-1 == temp)
  56051. + {
  56052. + mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n");
  56053. + return MV_ERROR;
  56054. + }
  56055. + MV_REG_WRITE(DRAM_BUF_REG2, temp);
  56056. +
  56057. + /* calc SDRAM_EXTENDED_MODE_REG and save it to temp register */
  56058. + temp = sdramExtModeRegCalc(&bankInfo[0]);
  56059. + if(-1 == temp)
  56060. + {
  56061. + mvOsPrintf("Dram: ERR. sdramModeRegCalc failed !!!\n");
  56062. + return MV_ERROR;
  56063. + }
  56064. + MV_REG_WRITE(DRAM_BUF_REG10, temp);
  56065. +
  56066. + /* calc D_UNIT_CONTROL_LOW and save it to temp register */
  56067. + temp = dunitCtrlLowRegCalc(&bankInfo[0], minCas);
  56068. + if(-1 == temp)
  56069. + {
  56070. + mvOsPrintf("Dram: ERR. dunitCtrlLowRegCalc failed !!!\n");
  56071. + return MV_ERROR;
  56072. + }
  56073. + MV_REG_WRITE(DRAM_BUF_REG3, temp);
  56074. +
  56075. + /* calc SDRAM_ADDR_CTRL_REG and save it to temp register */
  56076. + temp = sdramAddrCtrlRegCalc(&bankInfo[0]);
  56077. + if(-1 == temp)
  56078. + {
  56079. + mvOsPrintf("Dram: ERR. sdramAddrCtrlRegCalc failed !!!\n");
  56080. + return MV_ERROR;
  56081. + }
  56082. + MV_REG_WRITE(DRAM_BUF_REG4, temp);
  56083. +
  56084. + /* calc SDRAM_TIMING_CTRL_LOW_REG and save it to temp register */
  56085. + temp = sdramTimeCtrlLowRegCalc(&bankInfo[0], minCas, busClk);
  56086. + if(-1 == temp)
  56087. + {
  56088. + mvOsPrintf("Dram: ERR. sdramTimeCtrlLowRegCalc failed !!!\n");
  56089. + return MV_ERROR;
  56090. + }
  56091. + MV_REG_WRITE(DRAM_BUF_REG5, temp);
  56092. +
  56093. + /* calc SDRAM_TIMING_CTRL_HIGH_REG and save it to temp register */
  56094. + temp = sdramTimeCtrlHighRegCalc(&bankInfo[0], busClk);
  56095. + if(-1 == temp)
  56096. + {
  56097. + mvOsPrintf("Dram: ERR. sdramTimeCtrlHighRegCalc failed !!!\n");
  56098. + return MV_ERROR;
  56099. + }
  56100. + MV_REG_WRITE(DRAM_BUF_REG6, temp);
  56101. +
  56102. + /* Config DDR2 On Die Termination (ODT) registers */
  56103. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  56104. + {
  56105. + sdramDDr2OdtConfig(bankInfo);
  56106. + }
  56107. +
  56108. + /* Note that DDR SDRAM Address/Control and Data pad calibration */
  56109. + /* settings is done in mvSdramIfConfig.s */
  56110. +
  56111. + return retVal;
  56112. +}
  56113. +
  56114. +/*******************************************************************************
  56115. +* minCasCalc - Calculate the Minimum CAS latency which can be used.
  56116. +*
  56117. +* DESCRIPTION:
  56118. +* Calculate the minimum CAS latency that can be used, base on the DRAM
  56119. +* parameters and the SDRAM bus Clock freq.
  56120. +*
  56121. +* INPUT:
  56122. +* busClk - the DRAM bus Clock.
  56123. +* pBankInfo - bank info parameters.
  56124. +*
  56125. +* OUTPUT:
  56126. +* None
  56127. +*
  56128. +* RETURN:
  56129. +* The minimum CAS Latency. The function returns 0 if max CAS latency
  56130. +* supported by banks is incompatible with system bus clock frequancy.
  56131. +*
  56132. +*******************************************************************************/
  56133. +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk,
  56134. + MV_U32 forcedCl)
  56135. +{
  56136. + MV_U32 count = 1, j;
  56137. + MV_U32 busClkPs = 1000000000 / (busClk / 1000); /* in ps units */
  56138. + MV_U32 startBit, stopBit;
  56139. +
  56140. + /* DDR 1:
  56141. + *******-******-******-******-******-******-******-*******
  56142. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  56143. + *******-******-******-******-******-******-******-*******
  56144. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  56145. + *********************************************************/
  56146. +
  56147. + /* DDR 2:
  56148. + *******-******-******-******-******-******-******-*******
  56149. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  56150. + *******-******-******-******-******-******-******-*******
  56151. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  56152. + *********************************************************/
  56153. +
  56154. +
  56155. + /* If we are asked to use the forced CAL */
  56156. + if (forcedCl)
  56157. + {
  56158. + mvOsPrintf("DRAM: Using forced CL %d.%d\n", (forcedCl / 10),
  56159. + (forcedCl % 10));
  56160. +
  56161. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  56162. + {
  56163. + if (forcedCl == 30)
  56164. + pBankInfo->suportedCasLatencies = 0x08;
  56165. + else if (forcedCl == 40)
  56166. + pBankInfo->suportedCasLatencies = 0x10;
  56167. + else
  56168. + {
  56169. + mvOsPrintf("Forced CL %d.%d not supported. Set default CL 4\n",
  56170. + (forcedCl / 10), (forcedCl % 10));
  56171. + pBankInfo->suportedCasLatencies = 0x10;
  56172. + }
  56173. + }
  56174. + else
  56175. + {
  56176. + if (forcedCl == 15)
  56177. + pBankInfo->suportedCasLatencies = 0x02;
  56178. + else if (forcedCl == 20)
  56179. + pBankInfo->suportedCasLatencies = 0x04;
  56180. + else if (forcedCl == 25)
  56181. + pBankInfo->suportedCasLatencies = 0x08;
  56182. + else if (forcedCl == 30)
  56183. + pBankInfo->suportedCasLatencies = 0x10;
  56184. + else if (forcedCl == 40)
  56185. + pBankInfo->suportedCasLatencies = 0x40;
  56186. + else
  56187. + {
  56188. + mvOsPrintf("Forced CL %d.%d not supported. Set default CL 3\n",
  56189. + (forcedCl / 10), (forcedCl % 10));
  56190. + pBankInfo->suportedCasLatencies = 0x10;
  56191. + }
  56192. + }
  56193. +
  56194. + return pBankInfo->suportedCasLatencies;
  56195. + }
  56196. +
  56197. + /* go over the supported cas mask from Max Cas down and check if the */
  56198. + /* SysClk stands in its time requirments. */
  56199. +
  56200. +
  56201. + DB(mvOsPrintf("Dram: minCasCalc supported mask = %x busClkPs = %x \n",
  56202. + pBankInfo->suportedCasLatencies,busClkPs ));
  56203. + for(j = 7; j > 0; j--)
  56204. + {
  56205. + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
  56206. + {
  56207. + /* Reset the bits for CL incompatible for the sysClk */
  56208. + switch (count)
  56209. + {
  56210. + case 1:
  56211. + if (pBankInfo->minCycleTimeAtMaxCasLatPs > busClkPs)
  56212. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  56213. + count++;
  56214. + break;
  56215. + case 2:
  56216. + if (pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
  56217. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  56218. + count++;
  56219. + break;
  56220. + case 3:
  56221. + if (pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
  56222. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  56223. + count++;
  56224. + break;
  56225. + default:
  56226. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  56227. + break;
  56228. + }
  56229. + }
  56230. + }
  56231. +
  56232. + DB(mvOsPrintf("Dram: minCasCalc support = %x (after SysCC calc)\n",
  56233. + pBankInfo->suportedCasLatencies ));
  56234. +
  56235. + /* SDRAM DDR1 controller supports CL 1.5 to 3.5 */
  56236. + /* SDRAM DDR2 controller supports CL 3 to 5 */
  56237. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  56238. + {
  56239. + startBit = 3; /* DDR2 support CL start with CL3 (bit 3) */
  56240. + stopBit = 5; /* DDR2 support CL stops with CL5 (bit 5) */
  56241. + }
  56242. + else
  56243. + {
  56244. + startBit = 1; /* DDR1 support CL start with CL1.5 (bit 3) */
  56245. + stopBit = 4; /* DDR1 support CL stops with CL3 (bit 4) */
  56246. + }
  56247. +
  56248. + for(j = startBit; j <= stopBit ; j++)
  56249. + {
  56250. + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
  56251. + {
  56252. + DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
  56253. + return (BIT0 << j);
  56254. + }
  56255. + }
  56256. +
  56257. + return 0;
  56258. +}
  56259. +
  56260. +/*******************************************************************************
  56261. +* sdramConfigRegCalc - Calculate sdram config register
  56262. +*
  56263. +* DESCRIPTION: Calculate sdram config register optimized value based
  56264. +* on the bank info parameters.
  56265. +*
  56266. +* INPUT:
  56267. +* pBankInfo - sdram bank parameters
  56268. +*
  56269. +* OUTPUT:
  56270. +* None
  56271. +*
  56272. +* RETURN:
  56273. +* sdram config reg value.
  56274. +*
  56275. +*******************************************************************************/
  56276. +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
  56277. +{
  56278. + MV_U32 sdramConfig = 0;
  56279. + MV_U32 refreshPeriod;
  56280. +
  56281. + busClk /= 1000000; /* we work with busClk in MHz */
  56282. +
  56283. + sdramConfig = MV_REG_READ(SDRAM_CONFIG_REG);
  56284. +
  56285. + /* figure out the memory refresh internal */
  56286. + switch (pBankInfo->refreshInterval & 0xf)
  56287. + {
  56288. + case 0x0: /* refresh period is 15.625 usec */
  56289. + refreshPeriod = 15625;
  56290. + break;
  56291. + case 0x1: /* refresh period is 3.9 usec */
  56292. + refreshPeriod = 3900;
  56293. + break;
  56294. + case 0x2: /* refresh period is 7.8 usec */
  56295. + refreshPeriod = 7800;
  56296. + break;
  56297. + case 0x3: /* refresh period is 31.3 usec */
  56298. + refreshPeriod = 31300;
  56299. + break;
  56300. + case 0x4: /* refresh period is 62.5 usec */
  56301. + refreshPeriod = 62500;
  56302. + break;
  56303. + case 0x5: /* refresh period is 125 usec */
  56304. + refreshPeriod = 125000;
  56305. + break;
  56306. + default: /* refresh period undefined */
  56307. + mvOsPrintf("Dram: ERR. DRAM refresh period is unknown!\n");
  56308. + return -1;
  56309. + }
  56310. +
  56311. + /* Now the refreshPeriod is in register format value */
  56312. + refreshPeriod = (busClk * refreshPeriod) / 1000;
  56313. +
  56314. + DB(mvOsPrintf("Dram: sdramConfigRegCalc calculated refresh interval %0x\n",
  56315. + refreshPeriod));
  56316. +
  56317. + /* make sure the refresh value is only 14 bits */
  56318. + if(refreshPeriod > SDRAM_REFRESH_MAX)
  56319. + {
  56320. + refreshPeriod = SDRAM_REFRESH_MAX;
  56321. + DB(mvOsPrintf("Dram: sdramConfigRegCalc adjusted refresh interval %0x\n",
  56322. + refreshPeriod));
  56323. + }
  56324. +
  56325. + /* Clear the refresh field */
  56326. + sdramConfig &= ~SDRAM_REFRESH_MASK;
  56327. +
  56328. + /* Set new value to refresh field */
  56329. + sdramConfig |= (refreshPeriod & SDRAM_REFRESH_MASK);
  56330. +
  56331. + /* registered DRAM ? */
  56332. + if ( pBankInfo->registeredAddrAndControlInputs )
  56333. + {
  56334. + /* it's registered DRAM, so set the reg. DRAM bit */
  56335. + sdramConfig |= SDRAM_REGISTERED;
  56336. + mvOsPrintf("DRAM Attribute: Registered address and control inputs.\n");
  56337. + }
  56338. +
  56339. + /* set DDR SDRAM devices configuration */
  56340. + sdramConfig &= ~SDRAM_DCFG_MASK; /* Clear Dcfg field */
  56341. +
  56342. + switch (pBankInfo->sdramWidth)
  56343. + {
  56344. + case 8: /* memory is x8 */
  56345. + sdramConfig |= SDRAM_DCFG_X8_DEV;
  56346. + DB(mvOsPrintf("Dram: sdramConfigRegCalc SDRAM device width x8\n"));
  56347. + break;
  56348. + case 16:
  56349. + sdramConfig |= SDRAM_DCFG_X16_DEV;
  56350. + DB(mvOsPrintf("Dram: sdramConfigRegCalc SDRAM device width x16\n"));
  56351. + break;
  56352. + default: /* memory width unsupported */
  56353. + mvOsPrintf("Dram: ERR. DRAM chip width is unknown!\n");
  56354. + return -1;
  56355. + }
  56356. +
  56357. + /* Set static default settings */
  56358. + sdramConfig |= SDRAM_CONFIG_DV;
  56359. +
  56360. + DB(mvOsPrintf("Dram: sdramConfigRegCalc set sdramConfig to 0x%x\n",
  56361. + sdramConfig));
  56362. +
  56363. + return sdramConfig;
  56364. +}
  56365. +
  56366. +/*******************************************************************************
  56367. +* sdramModeRegCalc - Calculate sdram mode register
  56368. +*
  56369. +* DESCRIPTION: Calculate sdram mode register optimized value based
  56370. +* on the bank info parameters and the minCas.
  56371. +*
  56372. +* INPUT:
  56373. +* minCas - minimum CAS supported.
  56374. +*
  56375. +* OUTPUT:
  56376. +* None
  56377. +*
  56378. +* RETURN:
  56379. +* sdram mode reg value.
  56380. +*
  56381. +*******************************************************************************/
  56382. +static MV_U32 sdramModeRegCalc(MV_U32 minCas)
  56383. +{
  56384. + MV_U32 sdramMode;
  56385. +
  56386. + sdramMode = MV_REG_READ(SDRAM_MODE_REG);
  56387. +
  56388. + /* Clear CAS Latency field */
  56389. + sdramMode &= ~SDRAM_CL_MASK;
  56390. +
  56391. + mvOsPrintf("DRAM CAS Latency ");
  56392. +
  56393. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  56394. + {
  56395. + switch (minCas)
  56396. + {
  56397. + case DDR2_CL_3:
  56398. + sdramMode |= SDRAM_DDR2_CL_3;
  56399. + mvOsPrintf("3.\n");
  56400. + break;
  56401. + case DDR2_CL_4:
  56402. + sdramMode |= SDRAM_DDR2_CL_4;
  56403. + mvOsPrintf("4.\n");
  56404. + break;
  56405. + case DDR2_CL_5:
  56406. + sdramMode |= SDRAM_DDR2_CL_5;
  56407. + mvOsPrintf("5.\n");
  56408. + break;
  56409. + default:
  56410. + mvOsPrintf("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
  56411. + return -1;
  56412. + }
  56413. + sdramMode |= DDR2_MODE_REG_DV;
  56414. + }
  56415. + else /* DDR1 */
  56416. + {
  56417. + switch (minCas)
  56418. + {
  56419. + case DDR1_CL_1_5:
  56420. + sdramMode |= SDRAM_DDR1_CL_1_5;
  56421. + mvOsPrintf("1.5\n");
  56422. + break;
  56423. + case DDR1_CL_2:
  56424. + sdramMode |= SDRAM_DDR1_CL_2;
  56425. + mvOsPrintf("2\n");
  56426. + break;
  56427. + case DDR1_CL_2_5:
  56428. + sdramMode |= SDRAM_DDR1_CL_2_5;
  56429. + mvOsPrintf("2.5\n");
  56430. + break;
  56431. + case DDR1_CL_3:
  56432. + sdramMode |= SDRAM_DDR1_CL_3;
  56433. + mvOsPrintf("3\n");
  56434. + break;
  56435. + case DDR1_CL_4:
  56436. + sdramMode |= SDRAM_DDR1_CL_4;
  56437. + mvOsPrintf("4\n");
  56438. + break;
  56439. + default:
  56440. + mvOsPrintf("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
  56441. + return -1;
  56442. + }
  56443. + sdramMode |= DDR1_MODE_REG_DV;
  56444. + }
  56445. +
  56446. + DB(mvOsPrintf("nsdramModeRegCalc register 0x%x\n", sdramMode ));
  56447. +
  56448. + return sdramMode;
  56449. +}
  56450. +
  56451. +/*******************************************************************************
  56452. +* sdramExtModeRegCalc - Calculate sdram Extended mode register
  56453. +*
  56454. +* DESCRIPTION:
  56455. +* Return sdram Extended mode register value based
  56456. +* on the bank info parameters and bank presence.
  56457. +*
  56458. +* INPUT:
  56459. +* pBankInfo - sdram bank parameters
  56460. +*
  56461. +* OUTPUT:
  56462. +* None
  56463. +*
  56464. +* RETURN:
  56465. +* sdram Extended mode reg value.
  56466. +*
  56467. +*******************************************************************************/
  56468. +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo)
  56469. +{
  56470. + MV_U32 populateBanks = 0;
  56471. + int bankNum;
  56472. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  56473. + {
  56474. + /* Represent the populate banks in binary form */
  56475. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  56476. + {
  56477. + if (0 != pBankInfo[bankNum].size)
  56478. + {
  56479. + populateBanks |= (1 << bankNum);
  56480. + }
  56481. + }
  56482. +
  56483. + switch(populateBanks)
  56484. + {
  56485. + case(BANK_PRESENT_CS0):
  56486. + return DDR_SDRAM_EXT_MODE_CS0_DV;
  56487. +
  56488. + case(BANK_PRESENT_CS0_CS1):
  56489. + return DDR_SDRAM_EXT_MODE_CS0_DV;
  56490. +
  56491. + case(BANK_PRESENT_CS0_CS2):
  56492. + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
  56493. +
  56494. + case(BANK_PRESENT_CS0_CS1_CS2):
  56495. + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
  56496. +
  56497. + case(BANK_PRESENT_CS0_CS2_CS3):
  56498. + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
  56499. +
  56500. + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
  56501. + return DDR_SDRAM_EXT_MODE_CS0_CS2_DV;
  56502. +
  56503. + default:
  56504. + mvOsPrintf("sdramExtModeRegCalc: Invalid DRAM bank presence\n");
  56505. + return -1;
  56506. + }
  56507. + }
  56508. + return 0;
  56509. +}
  56510. +
  56511. +/*******************************************************************************
  56512. +* dunitCtrlLowRegCalc - Calculate sdram dunit control low register
  56513. +*
  56514. +* DESCRIPTION: Calculate sdram dunit control low register optimized value based
  56515. +* on the bank info parameters and the minCas.
  56516. +*
  56517. +* INPUT:
  56518. +* pBankInfo - sdram bank parameters
  56519. +* minCas - minimum CAS supported.
  56520. +*
  56521. +* OUTPUT:
  56522. +* None
  56523. +*
  56524. +* RETURN:
  56525. +* sdram dunit control low reg value.
  56526. +*
  56527. +*******************************************************************************/
  56528. +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas)
  56529. +{
  56530. + MV_U32 dunitCtrlLow;
  56531. +
  56532. + dunitCtrlLow = MV_REG_READ(SDRAM_DUNIT_CTRL_REG);
  56533. +
  56534. + /* Clear StBurstDel field */
  56535. + dunitCtrlLow &= ~SDRAM_ST_BURST_DEL_MASK;
  56536. +
  56537. +#ifdef MV_88W8660
  56538. + /* Clear address/control output timing field */
  56539. + dunitCtrlLow &= ~SDRAM_CTRL_POS_RISE;
  56540. +#endif /* MV_88W8660 */
  56541. +
  56542. + DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc\n"));
  56543. +
  56544. + /* For proper sample of read data set the Dunit Control register's */
  56545. + /* stBurstDel bits [27:24] */
  56546. + /********-********-********-********-********-*********
  56547. + * CL=1.5 | CL=2 | CL=2.5 | CL=3 | CL=4 | CL=5 *
  56548. + *********-********-********-********-********-*********
  56549. +Not Reg. * 0011 | 0011 | 0100 | 0100 | 0101 | TBD *
  56550. + *********-********-********-********-********-*********
  56551. +Registered * 0100 | 0100 | 0101 | 0101 | 0110 | TBD *
  56552. + *********-********-********-********-********-*********/
  56553. +
  56554. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  56555. + {
  56556. + switch (minCas)
  56557. + {
  56558. + case DDR2_CL_3:
  56559. + /* registerd DDR SDRAM? */
  56560. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  56561. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  56562. + else
  56563. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  56564. + break;
  56565. + case DDR2_CL_4:
  56566. + /* registerd DDR SDRAM? */
  56567. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  56568. + dunitCtrlLow |= 0x6 << SDRAM_ST_BURST_DEL_OFFS;
  56569. + else
  56570. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  56571. + break;
  56572. + default:
  56573. + mvOsPrintf("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n",
  56574. + minCas);
  56575. + return -1;
  56576. + }
  56577. + }
  56578. + else /* DDR1 */
  56579. + {
  56580. + switch (minCas)
  56581. + {
  56582. + case DDR1_CL_1_5:
  56583. + /* registerd DDR SDRAM? */
  56584. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  56585. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  56586. + else
  56587. + dunitCtrlLow |= 0x3 << SDRAM_ST_BURST_DEL_OFFS;
  56588. + break;
  56589. + case DDR1_CL_2:
  56590. + /* registerd DDR SDRAM? */
  56591. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  56592. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  56593. + else
  56594. + dunitCtrlLow |= 0x3 << SDRAM_ST_BURST_DEL_OFFS;
  56595. + break;
  56596. + case DDR1_CL_2_5:
  56597. + /* registerd DDR SDRAM? */
  56598. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  56599. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  56600. + else
  56601. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  56602. + break;
  56603. + case DDR1_CL_3:
  56604. + /* registerd DDR SDRAM? */
  56605. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  56606. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  56607. + else
  56608. + dunitCtrlLow |= 0x4 << SDRAM_ST_BURST_DEL_OFFS;
  56609. + break;
  56610. + case DDR1_CL_4:
  56611. + /* registerd DDR SDRAM? */
  56612. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  56613. + dunitCtrlLow |= 0x6 << SDRAM_ST_BURST_DEL_OFFS;
  56614. + else
  56615. + dunitCtrlLow |= 0x5 << SDRAM_ST_BURST_DEL_OFFS;
  56616. + break;
  56617. + default:
  56618. + mvOsPrintf("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n",
  56619. + minCas);
  56620. + return -1;
  56621. + }
  56622. +
  56623. + }
  56624. + DB(mvOsPrintf("Dram: Reg dunit control low = %x\n", dunitCtrlLow ));
  56625. +
  56626. + return dunitCtrlLow;
  56627. +}
  56628. +
  56629. +/*******************************************************************************
  56630. +* sdramAddrCtrlRegCalc - Calculate sdram address control register
  56631. +*
  56632. +* DESCRIPTION: Calculate sdram address control register optimized value based
  56633. +* on the bank info parameters and the minCas.
  56634. +*
  56635. +* INPUT:
  56636. +* pBankInfo - sdram bank parameters
  56637. +*
  56638. +* OUTPUT:
  56639. +* None
  56640. +*
  56641. +* RETURN:
  56642. +* sdram address control reg value.
  56643. +*
  56644. +*******************************************************************************/
  56645. +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo)
  56646. +{
  56647. + MV_U32 addrCtrl = 0;
  56648. +
  56649. + /* Set Address Control register static configuration bits */
  56650. + addrCtrl = MV_REG_READ(SDRAM_ADDR_CTRL_REG);
  56651. +
  56652. + /* Set address control default value */
  56653. + addrCtrl |= SDRAM_ADDR_CTRL_DV;
  56654. +
  56655. + /* Clear DSize field */
  56656. + addrCtrl &= ~SDRAM_DSIZE_MASK;
  56657. +
  56658. + /* Note that density is in MB units */
  56659. + switch (pBankInfo->deviceDensity)
  56660. + {
  56661. + case 128: /* 128 Mbit */
  56662. + DB(mvOsPrintf("DRAM Device Density 128Mbit\n"));
  56663. + addrCtrl |= SDRAM_DSIZE_128Mb;
  56664. + break;
  56665. + case 256: /* 256 Mbit */
  56666. + DB(mvOsPrintf("DRAM Device Density 256Mbit\n"));
  56667. + addrCtrl |= SDRAM_DSIZE_256Mb;
  56668. + break;
  56669. + case 512: /* 512 Mbit */
  56670. + DB(mvOsPrintf("DRAM Device Density 512Mbit\n"));
  56671. + addrCtrl |= SDRAM_DSIZE_512Mb;
  56672. + break;
  56673. + default:
  56674. + mvOsPrintf("Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
  56675. + pBankInfo->deviceDensity);
  56676. + return -1;
  56677. + }
  56678. +
  56679. + /* SDRAM address control */
  56680. + DB(mvOsPrintf("Dram: setting sdram address control with: %x \n", addrCtrl));
  56681. +
  56682. + return addrCtrl;
  56683. +}
  56684. +
  56685. +/*******************************************************************************
  56686. +* sdramTimeCtrlLowRegCalc - Calculate sdram timing control low register
  56687. +*
  56688. +* DESCRIPTION:
  56689. +* This function calculates sdram timing control low register
  56690. +* optimized value based on the bank info parameters and the minCas.
  56691. +*
  56692. +* INPUT:
  56693. +* pBankInfo - sdram bank parameters
  56694. +* busClk - Bus clock
  56695. +*
  56696. +* OUTPUT:
  56697. +* None
  56698. +*
  56699. +* RETURN:
  56700. +* sdram timinf control low reg value.
  56701. +*
  56702. +*******************************************************************************/
  56703. +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
  56704. + MV_U32 minCas, MV_U32 busClk)
  56705. +{
  56706. + MV_U32 tRp = 0;
  56707. + MV_U32 tRrd = 0;
  56708. + MV_U32 tRcd = 0;
  56709. + MV_U32 tRas = 0;
  56710. + MV_U32 tWr = 0;
  56711. + MV_U32 tWtr = 0;
  56712. + MV_U32 tRtp = 0;
  56713. +
  56714. + MV_U32 bankNum;
  56715. +
  56716. + busClk = busClk / 1000000; /* In MHz */
  56717. +
  56718. + /* Scan all DRAM banks to find maximum timing values */
  56719. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  56720. + {
  56721. + tRp = MV_MAX(tRp, pBankInfo[bankNum].minRowPrechargeTime);
  56722. + tRrd = MV_MAX(tRrd, pBankInfo[bankNum].minRowActiveToRowActive);
  56723. + tRcd = MV_MAX(tRcd, pBankInfo[bankNum].minRasToCasDelay);
  56724. + tRas = MV_MAX(tRas, pBankInfo[bankNum].minRasPulseWidth);
  56725. + }
  56726. +
  56727. + /* Extract timing (in ns) from SPD value. We ignore the tenth ns part. */
  56728. + /* by shifting the data two bits right. */
  56729. + tRp = tRp >> 2; /* For example 0x50 -> 20ns */
  56730. + tRrd = tRrd >> 2;
  56731. + tRcd = tRcd >> 2;
  56732. +
  56733. + /* Extract clock cycles from time parameter. We need to round up */
  56734. + tRp = ((busClk * tRp) / 1000) + (((busClk * tRp) % 1000) ? 1 : 0);
  56735. + /* Micron work around for 133MHz */
  56736. + if (busClk == 133)
  56737. + tRp += 1;
  56738. + DB(mvOsPrintf("Dram Timing Low: tRp = %d ", tRp));
  56739. + tRrd = ((busClk * tRrd) / 1000) + (((busClk * tRrd) % 1000) ? 1 : 0);
  56740. + /* JEDEC min reqeirments tRrd = 2 */
  56741. + if (tRrd < 2)
  56742. + tRrd = 2;
  56743. + DB(mvOsPrintf("tRrd = %d ", tRrd));
  56744. + tRcd = ((busClk * tRcd) / 1000) + (((busClk * tRcd) % 1000) ? 1 : 0);
  56745. + DB(mvOsPrintf("tRcd = %d ", tRcd));
  56746. + tRas = ((busClk * tRas) / 1000) + (((busClk * tRas) % 1000) ? 1 : 0);
  56747. + DB(mvOsPrintf("tRas = %d ", tRas));
  56748. +
  56749. + /* tWr and tWtr is different for DDR1 and DDR2. tRtp is only for DDR2 */
  56750. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  56751. + {
  56752. + /* Scan all DRAM banks to find maximum timing values */
  56753. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  56754. + {
  56755. + tWr = MV_MAX(tWr, pBankInfo[bankNum].minWriteRecoveryTime);
  56756. + tWtr = MV_MAX(tWtr, pBankInfo[bankNum].minWriteToReadCmdDelay);
  56757. + tRtp = MV_MAX(tRtp, pBankInfo[bankNum].minReadToPrechCmdDelay);
  56758. + }
  56759. +
  56760. + /* Extract timing (in ns) from SPD value. We ignore the tenth ns */
  56761. + /* part by shifting the data two bits right. */
  56762. + tWr = tWr >> 2; /* For example 0x50 -> 20ns */
  56763. + tWtr = tWtr >> 2;
  56764. + tRtp = tRtp >> 2;
  56765. +
  56766. + /* Extract clock cycles from time parameter. We need to round up */
  56767. + tWr = ((busClk * tWr) / 1000) + (((busClk * tWr) % 1000) ? 1 : 0);
  56768. + DB(mvOsPrintf("tWr = %d ", tWr));
  56769. + tWtr = ((busClk * tWtr) / 1000) + (((busClk * tWtr) % 1000) ? 1 : 0);
  56770. + /* JEDEC min reqeirments tWtr = 2 */
  56771. + if (tWtr < 2)
  56772. + tWtr = 2;
  56773. + DB(mvOsPrintf("tWtr = %d ", tWtr));
  56774. + tRtp = ((busClk * tRtp) / 1000) + (((busClk * tRtp) % 1000) ? 1 : 0);
  56775. + /* JEDEC min reqeirments tRtp = 2 */
  56776. + if (tRtp < 2)
  56777. + tRtp = 2;
  56778. + DB(mvOsPrintf("tRtp = %d ", tRtp));
  56779. + }
  56780. + else
  56781. + {
  56782. + tWr = ((busClk*SDRAM_TWR) / 1000) + (((busClk*SDRAM_TWR) % 1000)?1:0);
  56783. +
  56784. + if ((200 == busClk) || ((100 == busClk) && (DDR1_CL_1_5 == minCas)))
  56785. + {
  56786. + tWtr = 2;
  56787. + }
  56788. + else
  56789. + {
  56790. + tWtr = 1;
  56791. + }
  56792. +
  56793. + tRtp = 2; /* Must be set to 0x1 (two cycles) when using DDR1 */
  56794. + }
  56795. +
  56796. + DB(mvOsPrintf("tWtr = %d\n", tWtr));
  56797. +
  56798. + /* Note: value of 0 in register means one cycle, 1 means two and so on */
  56799. + return (((tRp - 1) << SDRAM_TRP_OFFS) |
  56800. + ((tRrd - 1) << SDRAM_TRRD_OFFS) |
  56801. + ((tRcd - 1) << SDRAM_TRCD_OFFS) |
  56802. + ((tRas - 1) << SDRAM_TRAS_OFFS) |
  56803. + ((tWr - 1) << SDRAM_TWR_OFFS) |
  56804. + ((tWtr - 1) << SDRAM_TWTR_OFFS) |
  56805. + ((tRtp - 1) << SDRAM_TRTP_OFFS));
  56806. +}
  56807. +
  56808. +/*******************************************************************************
  56809. +* sdramTimeCtrlHighRegCalc - Calculate sdram timing control high register
  56810. +*
  56811. +* DESCRIPTION:
  56812. +* This function calculates sdram timing control high register
  56813. +* optimized value based on the bank info parameters and the bus clock.
  56814. +*
  56815. +* INPUT:
  56816. +* pBankInfo - sdram bank parameters
  56817. +* busClk - Bus clock
  56818. +*
  56819. +* OUTPUT:
  56820. +* None
  56821. +*
  56822. +* RETURN:
  56823. +* sdram timinf control high reg value.
  56824. +*
  56825. +*******************************************************************************/
  56826. +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo,
  56827. + MV_U32 busClk)
  56828. +{
  56829. + MV_U32 tRfc;
  56830. + MV_U32 timeNs = 0;
  56831. + int bankNum;
  56832. + MV_U32 sdramTw2wCyc = 0;
  56833. +
  56834. + busClk = busClk / 1000000; /* In MHz */
  56835. +
  56836. + /* tRfc is different for DDR1 and DDR2. */
  56837. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_DTYPE_DDR2)
  56838. + {
  56839. + MV_U32 bankNum;
  56840. +
  56841. + /* Scan all DRAM banks to find maximum timing values */
  56842. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  56843. + timeNs = MV_MAX(timeNs, pBankInfo[bankNum].minRefreshToActiveCmd);
  56844. + }
  56845. + else
  56846. + {
  56847. + if (pBankInfo[0].deviceDensity == _1G)
  56848. + {
  56849. + timeNs = SDRAM_TRFC_1G;
  56850. + }
  56851. + else
  56852. + {
  56853. + if (200 == busClk)
  56854. + {
  56855. + timeNs = SDRAM_TRFC_64_512M_AT_200MHZ;
  56856. + }
  56857. + else
  56858. + {
  56859. + timeNs = SDRAM_TRFC_64_512M;
  56860. + }
  56861. + }
  56862. + }
  56863. +
  56864. + tRfc = ((busClk * timeNs) / 1000) + (((busClk * timeNs) % 1000) ? 1 : 0);
  56865. +
  56866. + DB(mvOsPrintf("Dram Timing High: tRfc = %d\n", tRfc));
  56867. +
  56868. +
  56869. + /* Represent the populate banks in binary form */
  56870. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  56871. + {
  56872. + if (0 != pBankInfo[bankNum].size)
  56873. + sdramTw2wCyc++;
  56874. + }
  56875. +
  56876. + /* If we have more the 1 bank then we need the TW2W in 1 for ODT switch */
  56877. + if (sdramTw2wCyc > 1)
  56878. + sdramTw2wCyc = 1;
  56879. + else
  56880. + sdramTw2wCyc = 0;
  56881. +
  56882. + /* Note: value of 0 in register means one cycle, 1 means two and so on */
  56883. + return ((((tRfc - 1) & SDRAM_TRFC_MASK) << SDRAM_TRFC_OFFS) |
  56884. + ((SDRAM_TR2R_CYC - 1) << SDRAM_TR2R_OFFS) |
  56885. + ((SDRAM_TR2WW2R_CYC - 1) << SDRAM_TR2W_W2R_OFFS) |
  56886. + (((tRfc - 1) >> 4) << SDRAM_TRFC_EXT_OFFS) |
  56887. + (sdramTw2wCyc << SDRAM_TW2W_OFFS));
  56888. +
  56889. +}
  56890. +
  56891. +/*******************************************************************************
  56892. +* sdramDDr2OdtConfig - Set DRAM DDR2 On Die Termination registers.
  56893. +*
  56894. +* DESCRIPTION:
  56895. +* This function config DDR2 On Die Termination (ODT) registers.
  56896. +* ODT configuration is done according to DIMM presence:
  56897. +*
  56898. +* Presence Ctrl Low Ctrl High Dunit Ctrl Ext Mode
  56899. +* CS0 0x84210000 0x00000000 0x0000780F 0x00000440
  56900. +* CS0+CS1 0x84210000 0x00000000 0x0000780F 0x00000440
  56901. +* CS0+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404
  56902. +* CS0+CS1+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404
  56903. +* CS0+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404
  56904. +* CS0+CS1+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404
  56905. +*
  56906. +* INPUT:
  56907. +* pBankInfo - bank info parameters.
  56908. +*
  56909. +* OUTPUT:
  56910. +* None
  56911. +*
  56912. +* RETURN:
  56913. +* None
  56914. +*******************************************************************************/
  56915. +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo)
  56916. +{
  56917. + MV_U32 populateBanks = 0;
  56918. + MV_U32 odtCtrlLow, odtCtrlHigh, dunitOdtCtrl;
  56919. + int bankNum;
  56920. +
  56921. + /* Represent the populate banks in binary form */
  56922. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  56923. + {
  56924. + if (0 != pBankInfo[bankNum].size)
  56925. + {
  56926. + populateBanks |= (1 << bankNum);
  56927. + }
  56928. + }
  56929. +
  56930. + switch(populateBanks)
  56931. + {
  56932. + case(BANK_PRESENT_CS0):
  56933. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_DV;
  56934. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_DV;
  56935. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_DV;
  56936. + break;
  56937. + case(BANK_PRESENT_CS0_CS1):
  56938. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_DV;
  56939. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_DV;
  56940. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_DV;
  56941. + break;
  56942. + case(BANK_PRESENT_CS0_CS2):
  56943. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
  56944. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
  56945. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
  56946. + break;
  56947. + case(BANK_PRESENT_CS0_CS1_CS2):
  56948. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
  56949. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
  56950. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
  56951. + break;
  56952. + case(BANK_PRESENT_CS0_CS2_CS3):
  56953. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
  56954. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
  56955. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
  56956. + break;
  56957. + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
  56958. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS2_DV;
  56959. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS2_DV;
  56960. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV;
  56961. + break;
  56962. + default:
  56963. + mvOsPrintf("sdramDDr2OdtConfig: Invalid DRAM bank presence\n");
  56964. + return;
  56965. + }
  56966. + MV_REG_WRITE(DRAM_BUF_REG7, odtCtrlLow);
  56967. + MV_REG_WRITE(DRAM_BUF_REG8, odtCtrlHigh);
  56968. + MV_REG_WRITE(DRAM_BUF_REG9, dunitOdtCtrl);
  56969. + return;
  56970. +}
  56971. +#endif /* defined(MV_INC_BOARD_DDIM) */
  56972. +
  56973. +/*******************************************************************************
  56974. +* mvDramIfWinSet - Set DRAM interface address decode window
  56975. +*
  56976. +* DESCRIPTION:
  56977. +* This function sets DRAM interface address decode window.
  56978. +*
  56979. +* INPUT:
  56980. +* target - System target. Use only SDRAM targets.
  56981. +* pAddrDecWin - SDRAM address window structure.
  56982. +*
  56983. +* OUTPUT:
  56984. +* None
  56985. +*
  56986. +* RETURN:
  56987. +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
  56988. +* otherwise.
  56989. +*******************************************************************************/
  56990. +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
  56991. +{
  56992. + MV_U32 baseReg=0,sizeReg=0;
  56993. + MV_U32 baseToReg=0 , sizeToReg=0;
  56994. +
  56995. + /* Check parameters */
  56996. + if (!MV_TARGET_IS_DRAM(target))
  56997. + {
  56998. + mvOsPrintf("mvDramIfWinSet: target %d is not SDRAM\n", target);
  56999. + return MV_BAD_PARAM;
  57000. + }
  57001. +
  57002. + /* Check if the requested window overlaps with current enabled windows */
  57003. + if (MV_TRUE == sdramIfWinOverlap(target, &pAddrDecWin->addrWin))
  57004. + {
  57005. + mvOsPrintf("mvDramIfWinSet: ERR. Target %d overlaps\n", target);
  57006. + return MV_BAD_PARAM;
  57007. + }
  57008. +
  57009. + /* check if address is aligned to the size */
  57010. + if(MV_IS_NOT_ALIGN(pAddrDecWin->addrWin.baseLow, pAddrDecWin->addrWin.size))
  57011. + {
  57012. + mvOsPrintf("mvDramIfWinSet:Error setting DRAM interface window %d."\
  57013. + "\nAddress 0x%08x is unaligned to size 0x%x.\n",
  57014. + target,
  57015. + pAddrDecWin->addrWin.baseLow,
  57016. + pAddrDecWin->addrWin.size);
  57017. + return MV_ERROR;
  57018. + }
  57019. +
  57020. + /* read base register*/
  57021. + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(target));
  57022. +
  57023. + /* read size register */
  57024. + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(target));
  57025. +
  57026. + /* BaseLow[31:16] => base register [31:16] */
  57027. + baseToReg = pAddrDecWin->addrWin.baseLow & SCBAR_BASE_MASK;
  57028. +
  57029. + /* Write to address decode Base Address Register */
  57030. + baseReg &= ~SCBAR_BASE_MASK;
  57031. + baseReg |= baseToReg;
  57032. +
  57033. + /* Translate the given window size to register format */
  57034. + sizeToReg = ctrlSizeToReg(pAddrDecWin->addrWin.size, SCSR_SIZE_ALIGNMENT);
  57035. +
  57036. + /* Size parameter validity check. */
  57037. + if (-1 == sizeToReg)
  57038. + {
  57039. + mvOsPrintf("mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n",target);
  57040. + return MV_BAD_PARAM;
  57041. + }
  57042. +
  57043. + /* set size */
  57044. + sizeReg &= ~SCSR_SIZE_MASK;
  57045. + /* Size is located at upper 16 bits */
  57046. + sizeReg |= (sizeToReg << SCSR_SIZE_OFFS);
  57047. +
  57048. + /* enable/Disable */
  57049. + if (MV_TRUE == pAddrDecWin->enable)
  57050. + {
  57051. + sizeReg |= SCSR_WIN_EN;
  57052. + }
  57053. + else
  57054. + {
  57055. + sizeReg &= ~SCSR_WIN_EN;
  57056. + }
  57057. +
  57058. + /* 3) Write to address decode Base Address Register */
  57059. + MV_REG_WRITE(SDRAM_BASE_ADDR_REG(target), baseReg);
  57060. +
  57061. + /* Write to address decode Size Register */
  57062. + MV_REG_WRITE(SDRAM_SIZE_REG(target), sizeReg);
  57063. +
  57064. + return MV_OK;
  57065. +}
  57066. +/*******************************************************************************
  57067. +* mvDramIfWinGet - Get DRAM interface address decode window
  57068. +*
  57069. +* DESCRIPTION:
  57070. +* This function gets DRAM interface address decode window.
  57071. +*
  57072. +* INPUT:
  57073. +* target - System target. Use only SDRAM targets.
  57074. +*
  57075. +* OUTPUT:
  57076. +* pAddrDecWin - SDRAM address window structure.
  57077. +*
  57078. +* RETURN:
  57079. +* MV_BAD_PARAM if parameters are invalid or window is invalid, MV_OK
  57080. +* otherwise.
  57081. +*******************************************************************************/
  57082. +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin)
  57083. +{
  57084. + MV_U32 baseReg,sizeReg;
  57085. + MV_U32 sizeRegVal;
  57086. +
  57087. + /* Check parameters */
  57088. + if (!MV_TARGET_IS_DRAM(target))
  57089. + {
  57090. + mvOsPrintf("mvDramIfWinGet: target %d is Illigal\n", target);
  57091. + return MV_ERROR;
  57092. + }
  57093. +
  57094. + /* Read base and size registers */
  57095. + sizeReg = MV_REG_READ(SDRAM_SIZE_REG(target));
  57096. + baseReg = MV_REG_READ(SDRAM_BASE_ADDR_REG(target));
  57097. +
  57098. + sizeRegVal = (sizeReg & SCSR_SIZE_MASK) >> SCSR_SIZE_OFFS;
  57099. +
  57100. + pAddrDecWin->addrWin.size = ctrlRegToSize(sizeRegVal,
  57101. + SCSR_SIZE_ALIGNMENT);
  57102. +
  57103. + /* Check if ctrlRegToSize returned OK */
  57104. + if (-1 == pAddrDecWin->addrWin.size)
  57105. + {
  57106. + mvOsPrintf("mvDramIfWinGet: size of target %d is Illigal\n", target);
  57107. + return MV_ERROR;
  57108. + }
  57109. +
  57110. + /* Extract base address */
  57111. + /* Base register [31:16] ==> baseLow[31:16] */
  57112. + pAddrDecWin->addrWin.baseLow = baseReg & SCBAR_BASE_MASK;
  57113. +
  57114. + pAddrDecWin->addrWin.baseHigh = 0;
  57115. +
  57116. +
  57117. + if (sizeReg & SCSR_WIN_EN)
  57118. + {
  57119. + pAddrDecWin->enable = MV_TRUE;
  57120. + }
  57121. + else
  57122. + {
  57123. + pAddrDecWin->enable = MV_FALSE;
  57124. + }
  57125. +
  57126. + return MV_OK;
  57127. +}
  57128. +/*******************************************************************************
  57129. +* mvDramIfWinEnable - Enable/Disable SDRAM address decode window
  57130. +*
  57131. +* DESCRIPTION:
  57132. +* This function enable/Disable SDRAM address decode window.
  57133. +*
  57134. +* INPUT:
  57135. +* target - System target. Use only SDRAM targets.
  57136. +*
  57137. +* OUTPUT:
  57138. +* None.
  57139. +*
  57140. +* RETURN:
  57141. +* MV_ERROR in case function parameter are invalid, MV_OK otherewise.
  57142. +*
  57143. +*******************************************************************************/
  57144. +MV_STATUS mvDramIfWinEnable(MV_TARGET target,MV_BOOL enable)
  57145. +{
  57146. + MV_DRAM_DEC_WIN addrDecWin;
  57147. +
  57148. + /* Check parameters */
  57149. + if (!MV_TARGET_IS_DRAM(target))
  57150. + {
  57151. + mvOsPrintf("mvDramIfWinEnable: target %d is Illigal\n", target);
  57152. + return MV_ERROR;
  57153. + }
  57154. +
  57155. + if (enable == MV_TRUE)
  57156. + { /* First check for overlap with other enabled windows */
  57157. + if (MV_OK != mvDramIfWinGet(target, &addrDecWin))
  57158. + {
  57159. + mvOsPrintf("mvDramIfWinEnable:ERR. Getting target %d failed.\n",
  57160. + target);
  57161. + return MV_ERROR;
  57162. + }
  57163. + /* Check for overlapping */
  57164. + if (MV_FALSE == sdramIfWinOverlap(target, &(addrDecWin.addrWin)))
  57165. + {
  57166. + /* No Overlap. Enable address decode winNum window */
  57167. + MV_REG_BIT_SET(SDRAM_SIZE_REG(target), SCSR_WIN_EN);
  57168. + }
  57169. + else
  57170. + { /* Overlap detected */
  57171. + mvOsPrintf("mvDramIfWinEnable: ERR. Target %d overlap detect\n",
  57172. + target);
  57173. + return MV_ERROR;
  57174. + }
  57175. + }
  57176. + else
  57177. + { /* Disable address decode winNum window */
  57178. + MV_REG_BIT_RESET(SDRAM_SIZE_REG(target), SCSR_WIN_EN);
  57179. + }
  57180. +
  57181. + return MV_OK;
  57182. +}
  57183. +
  57184. +/*******************************************************************************
  57185. +* sdramIfWinOverlap - Check if an address window overlap an SDRAM address window
  57186. +*
  57187. +* DESCRIPTION:
  57188. +* This function scan each SDRAM address decode window to test if it
  57189. +* overlapps the given address windoow
  57190. +*
  57191. +* INPUT:
  57192. +* target - SDRAM target where the function skips checking.
  57193. +* pAddrDecWin - The tested address window for overlapping with
  57194. +* SDRAM windows.
  57195. +*
  57196. +* OUTPUT:
  57197. +* None.
  57198. +*
  57199. +* RETURN:
  57200. +* MV_TRUE if the given address window overlaps any enabled address
  57201. +* decode map, MV_FALSE otherwise.
  57202. +*
  57203. +*******************************************************************************/
  57204. +static MV_BOOL sdramIfWinOverlap(MV_TARGET target, MV_ADDR_WIN *pAddrWin)
  57205. +{
  57206. + MV_TARGET targetNum;
  57207. + MV_DRAM_DEC_WIN addrDecWin;
  57208. +
  57209. + for(targetNum = SDRAM_CS0; targetNum < MV_DRAM_MAX_CS ; targetNum++)
  57210. + {
  57211. + /* don't check our winNum or illegal targets */
  57212. + if (targetNum == target)
  57213. + {
  57214. + continue;
  57215. + }
  57216. +
  57217. + /* Get window parameters */
  57218. + if (MV_OK != mvDramIfWinGet(targetNum, &addrDecWin))
  57219. + {
  57220. + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
  57221. + return MV_ERROR;
  57222. + }
  57223. +
  57224. + /* Do not check disabled windows */
  57225. + if (MV_FALSE == addrDecWin.enable)
  57226. + {
  57227. + continue;
  57228. + }
  57229. +
  57230. + if(MV_TRUE == ctrlWinOverlapTest(pAddrWin, &addrDecWin.addrWin))
  57231. + {
  57232. + mvOsPrintf(
  57233. + "sdramIfWinOverlap: Required target %d overlap winNum %d\n",
  57234. + target, targetNum);
  57235. + return MV_TRUE;
  57236. + }
  57237. + }
  57238. +
  57239. + return MV_FALSE;
  57240. +}
  57241. +
  57242. +/*******************************************************************************
  57243. +* mvDramIfBankSizeGet - Get DRAM interface bank size.
  57244. +*
  57245. +* DESCRIPTION:
  57246. +* This function returns the size of a given DRAM bank.
  57247. +*
  57248. +* INPUT:
  57249. +* bankNum - Bank number.
  57250. +*
  57251. +* OUTPUT:
  57252. +* None.
  57253. +*
  57254. +* RETURN:
  57255. +* DRAM bank size. If bank is disabled the function return '0'. In case
  57256. +* or paramter is invalid, the function returns -1.
  57257. +*
  57258. +*******************************************************************************/
  57259. +MV_32 mvDramIfBankSizeGet(MV_U32 bankNum)
  57260. +{
  57261. + MV_DRAM_DEC_WIN addrDecWin;
  57262. +
  57263. + /* Check parameters */
  57264. + if (!MV_TARGET_IS_DRAM(bankNum))
  57265. + {
  57266. + mvOsPrintf("mvDramIfBankBaseGet: bankNum %d is invalid\n", bankNum);
  57267. + return -1;
  57268. + }
  57269. + /* Get window parameters */
  57270. + if (MV_OK != mvDramIfWinGet(bankNum, &addrDecWin))
  57271. + {
  57272. + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
  57273. + return -1;
  57274. + }
  57275. +
  57276. + if (MV_TRUE == addrDecWin.enable)
  57277. + {
  57278. + return addrDecWin.addrWin.size;
  57279. + }
  57280. + else
  57281. + {
  57282. + return 0;
  57283. + }
  57284. +}
  57285. +
  57286. +
  57287. +/*******************************************************************************
  57288. +* mvDramIfSizeGet - Get DRAM interface total size.
  57289. +*
  57290. +* DESCRIPTION:
  57291. +* This function get the DRAM total size.
  57292. +*
  57293. +* INPUT:
  57294. +* None.
  57295. +*
  57296. +* OUTPUT:
  57297. +* None.
  57298. +*
  57299. +* RETURN:
  57300. +* DRAM total size. In case or paramter is invalid, the function
  57301. +* returns -1.
  57302. +*
  57303. +*******************************************************************************/
  57304. +MV_32 mvDramIfSizeGet(MV_VOID)
  57305. +{
  57306. + MV_U32 totalSize = 0, bankSize = 0, bankNum;
  57307. +
  57308. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  57309. + {
  57310. + bankSize = mvDramIfBankSizeGet(bankNum);
  57311. +
  57312. + if (-1 == bankSize)
  57313. + {
  57314. + mvOsPrintf("Dram: mvDramIfSizeGet error with bank %d \n",bankNum);
  57315. + return -1;
  57316. + }
  57317. + else
  57318. + {
  57319. + totalSize += bankSize;
  57320. + }
  57321. + }
  57322. +
  57323. + DB(mvOsPrintf("Dram: Total DRAM size is 0x%x \n",totalSize));
  57324. +
  57325. + return totalSize;
  57326. +}
  57327. +
  57328. +/*******************************************************************************
  57329. +* mvDramIfBankBaseGet - Get DRAM interface bank base.
  57330. +*
  57331. +* DESCRIPTION:
  57332. +* This function returns the 32 bit base address of a given DRAM bank.
  57333. +*
  57334. +* INPUT:
  57335. +* bankNum - Bank number.
  57336. +*
  57337. +* OUTPUT:
  57338. +* None.
  57339. +*
  57340. +* RETURN:
  57341. +* DRAM bank size. If bank is disabled or paramter is invalid, the
  57342. +* function returns -1.
  57343. +*
  57344. +*******************************************************************************/
  57345. +MV_32 mvDramIfBankBaseGet(MV_U32 bankNum)
  57346. +{
  57347. + MV_DRAM_DEC_WIN addrDecWin;
  57348. +
  57349. + /* Check parameters */
  57350. + if (!MV_TARGET_IS_DRAM(bankNum))
  57351. + {
  57352. + mvOsPrintf("mvDramIfBankBaseGet: bankNum %d is invalid\n", bankNum);
  57353. + return -1;
  57354. + }
  57355. + /* Get window parameters */
  57356. + if (MV_OK != mvDramIfWinGet(bankNum, &addrDecWin))
  57357. + {
  57358. + mvOsPrintf("sdramIfWinOverlap: ERR. TargetWinGet failed\n");
  57359. + return -1;
  57360. + }
  57361. +
  57362. + if (MV_TRUE == addrDecWin.enable)
  57363. + {
  57364. + return addrDecWin.addrWin.baseLow;
  57365. + }
  57366. + else
  57367. + {
  57368. + return -1;
  57369. + }
  57370. +}
  57371. +
  57372. +
  57373. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h
  57374. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h 1970-01-01 01:00:00.000000000 +0100
  57375. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIf.h 2011-08-01 14:38:19.000000000 +0200
  57376. @@ -0,0 +1,179 @@
  57377. +/*******************************************************************************
  57378. +Copyright (C) Marvell International Ltd. and its affiliates
  57379. +
  57380. +This software file (the "File") is owned and distributed by Marvell
  57381. +International Ltd. and/or its affiliates ("Marvell") under the following
  57382. +alternative licensing terms. Once you have made an election to distribute the
  57383. +File under one of the following license alternatives, please (i) delete this
  57384. +introductory statement regarding license alternatives, (ii) delete the two
  57385. +license alternatives that you have not elected to use and (iii) preserve the
  57386. +Marvell copyright notice above.
  57387. +
  57388. +********************************************************************************
  57389. +Marvell Commercial License Option
  57390. +
  57391. +If you received this File from Marvell and you have entered into a commercial
  57392. +license agreement (a "Commercial License") with Marvell, the File is licensed
  57393. +to you under the terms of the applicable Commercial License.
  57394. +
  57395. +********************************************************************************
  57396. +Marvell GPL License Option
  57397. +
  57398. +If you received this File from Marvell, you may opt to use, redistribute and/or
  57399. +modify this File in accordance with the terms and conditions of the General
  57400. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  57401. +available along with the File in the license.txt file or by writing to the Free
  57402. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  57403. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  57404. +
  57405. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  57406. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  57407. +DISCLAIMED. The GPL License provides additional details about this warranty
  57408. +disclaimer.
  57409. +********************************************************************************
  57410. +Marvell BSD License Option
  57411. +
  57412. +If you received this File from Marvell, you may opt to use, redistribute and/or
  57413. +modify this File under the following licensing terms.
  57414. +Redistribution and use in source and binary forms, with or without modification,
  57415. +are permitted provided that the following conditions are met:
  57416. +
  57417. + * Redistributions of source code must retain the above copyright notice,
  57418. + this list of conditions and the following disclaimer.
  57419. +
  57420. + * Redistributions in binary form must reproduce the above copyright
  57421. + notice, this list of conditions and the following disclaimer in the
  57422. + documentation and/or other materials provided with the distribution.
  57423. +
  57424. + * Neither the name of Marvell nor the names of its contributors may be
  57425. + used to endorse or promote products derived from this software without
  57426. + specific prior written permission.
  57427. +
  57428. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  57429. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  57430. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  57431. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  57432. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  57433. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  57434. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  57435. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  57436. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  57437. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  57438. +
  57439. +*******************************************************************************/
  57440. +
  57441. +
  57442. +#ifndef __INCmvDramIfh
  57443. +#define __INCmvDramIfh
  57444. +
  57445. +/* includes */
  57446. +#include "ddr1_2/mvDramIfRegs.h"
  57447. +#include "ddr1_2/mvDramIfConfig.h"
  57448. +#include "ctrlEnv/mvCtrlEnvLib.h"
  57449. +
  57450. +/* defines */
  57451. +/* DRAM Timing parameters */
  57452. +#define SDRAM_TWR 15 /* ns tWr */
  57453. +#define SDRAM_TRFC_64_512M_AT_200MHZ 70 /* ns tRfc for dens 64-512 @ 200MHz */
  57454. +#define SDRAM_TRFC_64_512M 75 /* ns tRfc for dens 64-512 */
  57455. +#define SDRAM_TRFC_1G 120 /* ns tRfc for dens 1GB */
  57456. +#define SDRAM_TR2R_CYC 1 /* cycle for tR2r */
  57457. +#define SDRAM_TR2WW2R_CYC 1 /* cycle for tR2wW2r */
  57458. +
  57459. +/* typedefs */
  57460. +
  57461. +/* enumeration for memory types */
  57462. +typedef enum _mvMemoryType
  57463. +{
  57464. + MEM_TYPE_SDRAM,
  57465. + MEM_TYPE_DDR1,
  57466. + MEM_TYPE_DDR2
  57467. +}MV_MEMORY_TYPE;
  57468. +
  57469. +/* enumeration for DDR1 supported CAS Latencies */
  57470. +typedef enum _mvDimmDdr1Cas
  57471. +{
  57472. + DDR1_CL_1_5 = 0x02,
  57473. + DDR1_CL_2 = 0x04,
  57474. + DDR1_CL_2_5 = 0x08,
  57475. + DDR1_CL_3 = 0x10,
  57476. + DDR1_CL_4 = 0x40,
  57477. + DDR1_CL_FAULT
  57478. +} MV_DIMM_DDR1_CAS;
  57479. +
  57480. +/* enumeration for DDR2 supported CAS Latencies */
  57481. +typedef enum _mvDimmDdr2Cas
  57482. +{
  57483. + DDR2_CL_3 = 0x08,
  57484. + DDR2_CL_4 = 0x10,
  57485. + DDR2_CL_5 = 0x20,
  57486. + DDR2_CL_FAULT
  57487. +} MV_DIMM_DDR2_CAS;
  57488. +
  57489. +
  57490. +typedef struct _mvDramBankInfo
  57491. +{
  57492. + MV_MEMORY_TYPE memoryType; /* DDR1, DDR2 or SDRAM */
  57493. +
  57494. + /* DIMM dimensions */
  57495. + MV_U32 numOfRowAddr;
  57496. + MV_U32 numOfColAddr;
  57497. + MV_U32 dataWidth;
  57498. + MV_U32 errorCheckType; /* ECC , PARITY..*/
  57499. + MV_U32 sdramWidth; /* 4,8,16 or 32 */
  57500. + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
  57501. + MV_U32 burstLengthSupported;
  57502. + MV_U32 numOfBanksOnEachDevice;
  57503. + MV_U32 suportedCasLatencies;
  57504. + MV_U32 refreshInterval;
  57505. +
  57506. + /* DIMM timing parameters */
  57507. + MV_U32 minCycleTimeAtMaxCasLatPs;
  57508. + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
  57509. + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
  57510. + MV_U32 minRowPrechargeTime;
  57511. + MV_U32 minRowActiveToRowActive;
  57512. + MV_U32 minRasToCasDelay;
  57513. + MV_U32 minRasPulseWidth;
  57514. + MV_U32 minWriteRecoveryTime; /* DDR2 only */
  57515. + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
  57516. + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
  57517. + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
  57518. +
  57519. + /* Parameters calculated from the extracted DIMM information */
  57520. + MV_U32 size;
  57521. + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit */
  57522. + MV_U32 numberOfDevices;
  57523. +
  57524. + /* DIMM attributes (MV_TRUE for yes) */
  57525. + MV_BOOL registeredAddrAndControlInputs;
  57526. +
  57527. +}MV_DRAM_BANK_INFO;
  57528. +
  57529. +/* This structure describes CPU interface address decode window */
  57530. +typedef struct _mvDramIfDecWin
  57531. +{
  57532. + MV_ADDR_WIN addrWin; /* An address window*/
  57533. + MV_BOOL enable; /* Address decode window is enabled/disabled */
  57534. +}MV_DRAM_DEC_WIN;
  57535. +
  57536. +#include "ddr1_2/mvDram.h"
  57537. +
  57538. +/* mvDramIf.h API list */
  57539. +MV_VOID mvDramIfBasicAsmInit(MV_VOID);
  57540. +MV_STATUS mvDramIfDetect(MV_U32 forcedCl);
  57541. +MV_VOID _mvDramIfConfig(MV_VOID);
  57542. +
  57543. +MV_STATUS mvDramIfWinSet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
  57544. +MV_STATUS mvDramIfWinGet(MV_TARGET target, MV_DRAM_DEC_WIN *pAddrDecWin);
  57545. +MV_STATUS mvDramIfWinEnable(MV_TARGET target,MV_BOOL enable);
  57546. +MV_32 mvDramIfBankSizeGet(MV_U32 bankNum);
  57547. +MV_32 mvDramIfBankBaseGet(MV_U32 bankNum);
  57548. +MV_32 mvDramIfSizeGet(MV_VOID);
  57549. +
  57550. +#if 0
  57551. +MV_STATUS mvDramIfMbusCtrlSet(MV_XBAR_TARGET *pPizzaArbArray);
  57552. +MV_STATUS mvDramIfMbusToutSet(MV_U32 timeout, MV_BOOL enable);
  57553. +#endif
  57554. +
  57555. +#endif /* __INCmvDramIfh */
  57556. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h
  57557. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h 1970-01-01 01:00:00.000000000 +0100
  57558. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfConfig.h 2011-08-01 14:38:19.000000000 +0200
  57559. @@ -0,0 +1,192 @@
  57560. +/*******************************************************************************
  57561. +Copyright (C) Marvell International Ltd. and its affiliates
  57562. +
  57563. +This software file (the "File") is owned and distributed by Marvell
  57564. +International Ltd. and/or its affiliates ("Marvell") under the following
  57565. +alternative licensing terms. Once you have made an election to distribute the
  57566. +File under one of the following license alternatives, please (i) delete this
  57567. +introductory statement regarding license alternatives, (ii) delete the two
  57568. +license alternatives that you have not elected to use and (iii) preserve the
  57569. +Marvell copyright notice above.
  57570. +
  57571. +********************************************************************************
  57572. +Marvell Commercial License Option
  57573. +
  57574. +If you received this File from Marvell and you have entered into a commercial
  57575. +license agreement (a "Commercial License") with Marvell, the File is licensed
  57576. +to you under the terms of the applicable Commercial License.
  57577. +
  57578. +********************************************************************************
  57579. +Marvell GPL License Option
  57580. +
  57581. +If you received this File from Marvell, you may opt to use, redistribute and/or
  57582. +modify this File in accordance with the terms and conditions of the General
  57583. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  57584. +available along with the File in the license.txt file or by writing to the Free
  57585. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  57586. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  57587. +
  57588. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  57589. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  57590. +DISCLAIMED. The GPL License provides additional details about this warranty
  57591. +disclaimer.
  57592. +********************************************************************************
  57593. +Marvell BSD License Option
  57594. +
  57595. +If you received this File from Marvell, you may opt to use, redistribute and/or
  57596. +modify this File under the following licensing terms.
  57597. +Redistribution and use in source and binary forms, with or without modification,
  57598. +are permitted provided that the following conditions are met:
  57599. +
  57600. + * Redistributions of source code must retain the above copyright notice,
  57601. + this list of conditions and the following disclaimer.
  57602. +
  57603. + * Redistributions in binary form must reproduce the above copyright
  57604. + notice, this list of conditions and the following disclaimer in the
  57605. + documentation and/or other materials provided with the distribution.
  57606. +
  57607. + * Neither the name of Marvell nor the names of its contributors may be
  57608. + used to endorse or promote products derived from this software without
  57609. + specific prior written permission.
  57610. +
  57611. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  57612. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  57613. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  57614. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  57615. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  57616. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  57617. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  57618. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  57619. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  57620. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  57621. +
  57622. +*******************************************************************************/
  57623. +
  57624. +
  57625. +#ifndef __INCmvDramIfConfigh
  57626. +#define __INCmvDramIfConfigh
  57627. +
  57628. +/* includes */
  57629. +
  57630. +/* defines */
  57631. +
  57632. +/* registers defaults values */
  57633. +
  57634. +#define SDRAM_CONFIG_DV \
  57635. + (SDRAM_PERR_WRITE | \
  57636. + SDRAM_SRMODE | \
  57637. + SDRAM_SRCLK_GATED)
  57638. +
  57639. +#define SDRAM_DUNIT_CTRL_LOW_DV \
  57640. + (SDRAM_CTRL_POS_RISE | \
  57641. + SDRAM_CLK1DRV_NORMAL | \
  57642. + SDRAM_LOCKEN_ENABLE)
  57643. +
  57644. +#define SDRAM_ADDR_CTRL_DV 0
  57645. +
  57646. +#define SDRAM_TIMING_CTRL_LOW_REG_DV \
  57647. + ((0x2 << SDRAM_TRCD_OFFS) | \
  57648. + (0x2 << SDRAM_TRP_OFFS) | \
  57649. + (0x1 << SDRAM_TWR_OFFS) | \
  57650. + (0x0 << SDRAM_TWTR_OFFS) | \
  57651. + (0x5 << SDRAM_TRAS_OFFS) | \
  57652. + (0x1 << SDRAM_TRRD_OFFS))
  57653. +/* TRFC 0x27, TW2W 0x1 */
  57654. +#define SDRAM_TIMING_CTRL_HIGH_REG_DV (( 0x7 << SDRAM_TRFC_OFFS ) |\
  57655. + ( 0x2 << SDRAM_TRFC_EXT_OFFS) |\
  57656. + ( 0x1 << SDRAM_TW2W_OFFS))
  57657. +
  57658. +#define SDRAM_OPEN_PAGES_CTRL_REG_DV SDRAM_OPEN_PAGE_EN
  57659. +
  57660. +/* DDR2 ODT default register values */
  57661. +
  57662. +/* Presence Ctrl Low Ctrl High Dunit Ctrl Ext Mode */
  57663. +/* CS0 0x84210000 0x00000000 0x0000780F 0x00000440 */
  57664. +/* CS0+CS1 0x84210000 0x00000000 0x0000780F 0x00000440 */
  57665. +/* CS0+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  57666. +/* CS0+CS1+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  57667. +/* CS0+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  57668. +/* CS0+CS1+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  57669. +
  57670. +#define DDR2_ODT_CTRL_LOW_CS0_DV 0x84210000
  57671. +#define DDR2_ODT_CTRL_HIGH_CS0_DV 0x00000000
  57672. +#define DDR2_DUNIT_ODT_CTRL_CS0_DV 0x0000780F
  57673. +#define DDR_SDRAM_EXT_MODE_CS0_DV 0x00000440
  57674. +
  57675. +#define DDR2_ODT_CTRL_LOW_CS0_CS2_DV 0x030C030C
  57676. +#define DDR2_ODT_CTRL_HIGH_CS0_CS2_DV 0x00000000
  57677. +#define DDR2_DUNIT_ODT_CTRL_CS0_CS2_DV 0x0000740F
  57678. +#define DDR_SDRAM_EXT_MODE_CS0_CS2_DV 0x00000404
  57679. +
  57680. +
  57681. +/* DDR SDRAM Adderss/Control and Data Pads Calibration default values */
  57682. +#define DDR1_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV \
  57683. + (1 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  57684. +#define DDR2_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV \
  57685. + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  57686. +
  57687. +
  57688. +#define DDR1_DATA_PAD_STRENGTH_TYPICAL_DV \
  57689. + (1 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  57690. +#define DDR2_DATA_PAD_STRENGTH_TYPICAL_DV \
  57691. + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  57692. +
  57693. +/* DDR SDRAM Mode Register default value */
  57694. +#define DDR1_MODE_REG_DV 0x00000000
  57695. +#define DDR2_MODE_REG_DV 0x00000400
  57696. +
  57697. +/* DDR SDRAM Timing parameter default values */
  57698. +#define DDR1_TIMING_LOW_DV 0x11602220
  57699. +#define DDR1_TIMING_HIGH_DV 0x0000000d
  57700. +
  57701. +#define DDR2_TIMING_LOW_DV 0x11812220
  57702. +#define DDR2_TIMING_HIGH_DV 0x0000030f
  57703. +
  57704. +/* For Guideline (GL# MEM-4) DQS Reference Delay Tuning */
  57705. +#define FTDLL_DDR1_166MHZ ((0x1 << 0) | \
  57706. + (0x7F<< 12) | \
  57707. + (0x1 << 22))
  57708. +
  57709. +#define FTDLL_DDR1_133MHZ FTDLL_DDR1_166MHZ
  57710. +
  57711. +#define FTDLL_DDR1_200MHZ ((0x1 << 0) | \
  57712. + (0x1 << 12) | \
  57713. + (0x3 << 14) | \
  57714. + (0x1 << 18) | \
  57715. + (0x1 << 22))
  57716. +
  57717. +
  57718. +#define FTDLL_DDR2_166MHZ ((0x1 << 0) | \
  57719. + (0x1 << 12) | \
  57720. + (0x1 << 14) | \
  57721. + (0x1 << 16) | \
  57722. + (0x1 << 19) | \
  57723. + (0xF << 20))
  57724. +
  57725. +#define FTDLL_DDR2_133MHZ FTDLL_DDR2_166MHZ
  57726. +
  57727. +#define FTDLL_DDR2_200MHZ ((0x1 << 0) | \
  57728. + (0x1 << 12) | \
  57729. + (0x1 << 14) | \
  57730. + (0x1 << 16) | \
  57731. + (0x1 << 19) | \
  57732. + (0xF << 20))
  57733. +
  57734. +#define FTDLL_DDR2_250MHZ 0x445001
  57735. +
  57736. +/* Orion 1 B1 and above */
  57737. +#define FTDLL_DDR1_166MHZ_5181_B1 0x45D001
  57738. +
  57739. +/* Orion nas */
  57740. +#define FTDLL_DDR2_166MHZ_5182 0x597001
  57741. +
  57742. +/* Orion 2 D0 and above */
  57743. +#define FTDLL_DDR1_166MHZ_5281_D0 0x8D0001
  57744. +#define FTDLL_DDR1_200MHZ_5281_D0 0x8D0001
  57745. +#define FTDLL_DDR2_166MHZ_5281_D0 0x485001
  57746. +#define FTDLL_DDR2_200MHZ_5281_D0 0x485001
  57747. +#define FTDLL_DDR2_250MHZ_5281_D0 0x445001
  57748. +#define FTDLL_DDR2_200MHZ_5281_D1 0x995001
  57749. +#define FTDLL_DDR2_250MHZ_5281_D1 0x984801
  57750. +
  57751. +#endif /* __INCmvDramIfh */
  57752. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h
  57753. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h 1970-01-01 01:00:00.000000000 +0100
  57754. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr1_2/mvDramIfRegs.h 2011-08-01 14:38:19.000000000 +0200
  57755. @@ -0,0 +1,306 @@
  57756. +/*******************************************************************************
  57757. +Copyright (C) Marvell International Ltd. and its affiliates
  57758. +
  57759. +This software file (the "File") is owned and distributed by Marvell
  57760. +International Ltd. and/or its affiliates ("Marvell") under the following
  57761. +alternative licensing terms. Once you have made an election to distribute the
  57762. +File under one of the following license alternatives, please (i) delete this
  57763. +introductory statement regarding license alternatives, (ii) delete the two
  57764. +license alternatives that you have not elected to use and (iii) preserve the
  57765. +Marvell copyright notice above.
  57766. +
  57767. +********************************************************************************
  57768. +Marvell Commercial License Option
  57769. +
  57770. +If you received this File from Marvell and you have entered into a commercial
  57771. +license agreement (a "Commercial License") with Marvell, the File is licensed
  57772. +to you under the terms of the applicable Commercial License.
  57773. +
  57774. +********************************************************************************
  57775. +Marvell GPL License Option
  57776. +
  57777. +If you received this File from Marvell, you may opt to use, redistribute and/or
  57778. +modify this File in accordance with the terms and conditions of the General
  57779. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  57780. +available along with the File in the license.txt file or by writing to the Free
  57781. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  57782. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  57783. +
  57784. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  57785. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  57786. +DISCLAIMED. The GPL License provides additional details about this warranty
  57787. +disclaimer.
  57788. +********************************************************************************
  57789. +Marvell BSD License Option
  57790. +
  57791. +If you received this File from Marvell, you may opt to use, redistribute and/or
  57792. +modify this File under the following licensing terms.
  57793. +Redistribution and use in source and binary forms, with or without modification,
  57794. +are permitted provided that the following conditions are met:
  57795. +
  57796. + * Redistributions of source code must retain the above copyright notice,
  57797. + this list of conditions and the following disclaimer.
  57798. +
  57799. + * Redistributions in binary form must reproduce the above copyright
  57800. + notice, this list of conditions and the following disclaimer in the
  57801. + documentation and/or other materials provided with the distribution.
  57802. +
  57803. + * Neither the name of Marvell nor the names of its contributors may be
  57804. + used to endorse or promote products derived from this software without
  57805. + specific prior written permission.
  57806. +
  57807. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  57808. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  57809. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  57810. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  57811. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  57812. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  57813. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  57814. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  57815. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  57816. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  57817. +
  57818. +*******************************************************************************/
  57819. +
  57820. +#ifndef __INCmvDramIfRegsh
  57821. +#define __INCmvDramIfRegsh
  57822. +
  57823. +
  57824. +/* DDR SDRAM Controller Address Decode Registers */
  57825. +/* SDRAM CSn Base Address Register (SCBAR) */
  57826. +#define SDRAM_BASE_ADDR_REG(csNum) (0x1500 + (csNum * 8))
  57827. +#define SCBAR_BASE_OFFS 16
  57828. +#define SCBAR_BASE_MASK (0xffff << SCBAR_BASE_OFFS)
  57829. +#define SCBAR_BASE_ALIGNMENT 0x10000
  57830. +
  57831. +/* SDRAM CSn Size Register (SCSR) */
  57832. +#define SDRAM_SIZE_REG(csNum) (0x1504 + (csNum * 8))
  57833. +#define SCSR_WIN_EN BIT0
  57834. +#define SCSR_SIZE_OFFS 16
  57835. +#define SCSR_SIZE_MASK (0xffff << SCSR_SIZE_OFFS)
  57836. +#define SCSR_SIZE_ALIGNMENT 0x10000
  57837. +
  57838. +/* configuration register */
  57839. +#define SDRAM_CONFIG_REG 0x1400
  57840. +#define SDRAM_REFRESH_OFFS 0
  57841. +#define SDRAM_REFRESH_MAX 0x3000
  57842. +#define SDRAM_REFRESH_MASK (SDRAM_REFRESH_MAX << SDRAM_REFRESH_OFFS)
  57843. +#define SDRAM_DWIDTH_OFFS 14
  57844. +#define SDRAM_DWIDTH_MASK (3 << SDRAM_DWIDTH_OFFS)
  57845. +#define SDRAM_DWIDTH_16BIT (1 << SDRAM_DWIDTH_OFFS)
  57846. +#define SDRAM_DWIDTH_32BIT (2 << SDRAM_DWIDTH_OFFS)
  57847. +#define SDRAM_DTYPE_OFFS 16
  57848. +#define SDRAM_DTYPE_MASK (1 << SDRAM_DTYPE_OFFS)
  57849. +#define SDRAM_DTYPE_DDR1 (0 << SDRAM_DTYPE_OFFS)
  57850. +#define SDRAM_DTYPE_DDR2 (1 << SDRAM_DTYPE_OFFS)
  57851. +#define SDRAM_REGISTERED (1 << 17)
  57852. +#define SDRAM_PERR_OFFS 18
  57853. +#define SDRAM_PERR_MASK (1 << SDRAM_PERR_OFFS)
  57854. +#define SDRAM_PERR_NO_WRITE (0 << SDRAM_PERR_OFFS)
  57855. +#define SDRAM_PERR_WRITE (1 << SDRAM_PERR_OFFS)
  57856. +#define SDRAM_DCFG_OFFS 20
  57857. +#define SDRAM_DCFG_MASK (0x3 << SDRAM_DCFG_OFFS)
  57858. +#define SDRAM_DCFG_X16_DEV (1 << SDRAM_DCFG_OFFS)
  57859. +#define SDRAM_DCFG_X8_DEV (2 << SDRAM_DCFG_OFFS)
  57860. +#define SDRAM_SRMODE (1 << 24)
  57861. +#define SDRAM_SRCLK_OFFS 25
  57862. +#define SDRAM_SRCLK_MASK (1 << SDRAM_SRCLK_OFFS)
  57863. +#define SDRAM_SRCLK_KEPT (0 << SDRAM_SRCLK_OFFS)
  57864. +#define SDRAM_SRCLK_GATED (1 << SDRAM_SRCLK_OFFS)
  57865. +#define SDRAM_CATTH_OFFS 26
  57866. +#define SDRAM_CATTHR_EN (1 << SDRAM_CATTH_OFFS)
  57867. +
  57868. +
  57869. +/* dunit control register */
  57870. +#define SDRAM_DUNIT_CTRL_REG 0x1404
  57871. +#define SDRAM_CTRL_POS_OFFS 6
  57872. +#define SDRAM_CTRL_POS_FALL (0 << SDRAM_CTRL_POS_OFFS)
  57873. +#define SDRAM_CTRL_POS_RISE (1 << SDRAM_CTRL_POS_OFFS)
  57874. +#define SDRAM_CLK1DRV_OFFS 12
  57875. +#define SDRAM_CLK1DRV_MASK (1 << SDRAM_CLK1DRV_OFFS)
  57876. +#define SDRAM_CLK1DRV_HIGH_Z (0 << SDRAM_CLK1DRV_OFFS)
  57877. +#define SDRAM_CLK1DRV_NORMAL (1 << SDRAM_CLK1DRV_OFFS)
  57878. +#define SDRAM_LOCKEN_OFFS 18
  57879. +#define SDRAM_LOCKEN_MASK (1 << SDRAM_LOCKEN_OFFS)
  57880. +#define SDRAM_LOCKEN_DISABLE (0 << SDRAM_LOCKEN_OFFS)
  57881. +#define SDRAM_LOCKEN_ENABLE (1 << SDRAM_LOCKEN_OFFS)
  57882. +#define SDRAM_ST_BURST_DEL_OFFS 24
  57883. +#define SDRAM_ST_BURST_DEL_MAX 0xf
  57884. +#define SDRAM_ST_BURST_DEL_MASK (SDRAM_ST_BURST_DEL_MAX<<SDRAM_ST_BURST_DEL_OFFS)
  57885. +
  57886. +/* sdram timing control low register */
  57887. +#define SDRAM_TIMING_CTRL_LOW_REG 0x1408
  57888. +#define SDRAM_TRCD_OFFS 4
  57889. +#define SDRAM_TRCD_MASK (0xF << SDRAM_TRCD_OFFS)
  57890. +#define SDRAM_TRP_OFFS 8
  57891. +#define SDRAM_TRP_MASK (0xF << SDRAM_TRP_OFFS)
  57892. +#define SDRAM_TWR_OFFS 12
  57893. +#define SDRAM_TWR_MASK (0xF << SDRAM_TWR_OFFS)
  57894. +#define SDRAM_TWTR_OFFS 16
  57895. +#define SDRAM_TWTR_MASK (0xF << SDRAM_TWTR_OFFS)
  57896. +#define SDRAM_TRAS_OFFS 20
  57897. +#define SDRAM_TRAS_MASK (0xF << SDRAM_TRAS_OFFS)
  57898. +#define SDRAM_TRRD_OFFS 24
  57899. +#define SDRAM_TRRD_MASK (0xF << SDRAM_TRRD_OFFS)
  57900. +#define SDRAM_TRTP_OFFS 28
  57901. +#define SDRAM_TRTP_MASK (0xF << SDRAM_TRTP_OFFS)
  57902. +
  57903. +/* sdram timing control high register */
  57904. +#define SDRAM_TIMING_CTRL_HIGH_REG 0x140c
  57905. +#define SDRAM_TRFC_OFFS 0
  57906. +#define SDRAM_TRFC_MASK (0xF << SDRAM_TRFC_OFFS)
  57907. +#define SDRAM_TR2R_OFFS 4
  57908. +#define SDRAM_TR2R_MASK (0x3 << SDRAM_TR2R_OFFS)
  57909. +#define SDRAM_TR2W_W2R_OFFS 6
  57910. +#define SDRAM_TR2W_W2R_MASK (0x3 << SDRAM_TR2W_W2R_OFFS)
  57911. +#define SDRAM_TRFC_EXT_OFFS 8
  57912. +#define SDRAM_TRFC_EXT_MASK (0x1 << SDRAM_TRFC_EXT_OFFS)
  57913. +#define SDRAM_TW2W_OFFS 10
  57914. +#define SDRAM_TW2W_MASK (0x1 << SDRAM_TW2W_OFFS)
  57915. +
  57916. +/* address control register */
  57917. +#define SDRAM_ADDR_CTRL_REG 0x1410
  57918. +#define SDRAM_DSIZE_OFFS 4
  57919. +#define SDRAM_DSIZE_MASK (0x3 << SDRAM_DSIZE_OFFS)
  57920. +#define SDRAM_DSIZE_128Mb (0x0 << SDRAM_DSIZE_OFFS)
  57921. +#define SDRAM_DSIZE_256Mb (0x1 << SDRAM_DSIZE_OFFS)
  57922. +#define SDRAM_DSIZE_512Mb (0x2 << SDRAM_DSIZE_OFFS)
  57923. +
  57924. +/* SDRAM Open Pages Control registers */
  57925. +#define SDRAM_OPEN_PAGE_CTRL_REG 0x1414
  57926. +#define SDRAM_OPEN_PAGE_EN (0 << 0)
  57927. +#define SDRAM_OPEN_PAGE_DIS (1 << 0)
  57928. +
  57929. +/* sdram opertion register */
  57930. +#define SDRAM_OPERATION_REG 0x1418
  57931. +#define SDRAM_CMD_OFFS 0
  57932. +#define SDRAM_CMD_MASK (0x7 << SDRAM_CMD_OFFS)
  57933. +#define SDRAM_CMD_NORMAL (0x0 << SDRAM_CMD_OFFS)
  57934. +#define SDRAM_CMD_PRECHARGE_ALL (0x1 << SDRAM_CMD_OFFS)
  57935. +#define SDRAM_CMD_REFRESH_ALL (0x2 << SDRAM_CMD_OFFS)
  57936. +#define SDRAM_CMD_REG_SET_CMD (0x3 << SDRAM_CMD_OFFS)
  57937. +#define SDRAM_CMD_EXT_MODE_SET (0x4 << SDRAM_CMD_OFFS)
  57938. +#define SDRAM_CMD_NOP (0x5 << SDRAM_CMD_OFFS)
  57939. +#define SDRAM_CMD_SLF_RFRSH (0x7 << SDRAM_CMD_OFFS)
  57940. +#define SDRAM_CMD_EMRS2_CMD (0x8 << SDRAM_CMD_OFFS)
  57941. +#define SDRAM_CMD_EMRS3_CMD (0x9 << SDRAM_CMD_OFFS)
  57942. +
  57943. +/* sdram mode register */
  57944. +#define SDRAM_MODE_REG 0x141c
  57945. +#define SDRAM_BURST_LEN_OFFS 0
  57946. +#define SDRAM_BURST_LEN_MASK (0x7 << SDRAM_BURST_LEN_OFFS)
  57947. +#define SDRAM_BURST_LEN_4 (0x2 << SDRAM_BURST_LEN_OFFS)
  57948. +#define SDRAM_CL_OFFS 4
  57949. +#define SDRAM_CL_MASK (0x7 << SDRAM_CL_OFFS)
  57950. +#define SDRAM_DDR1_CL_2 (0x2 << SDRAM_CL_OFFS)
  57951. +#define SDRAM_DDR1_CL_3 (0x3 << SDRAM_CL_OFFS)
  57952. +#define SDRAM_DDR1_CL_4 (0x4 << SDRAM_CL_OFFS)
  57953. +#define SDRAM_DDR1_CL_1_5 (0x5 << SDRAM_CL_OFFS)
  57954. +#define SDRAM_DDR1_CL_2_5 (0x6 << SDRAM_CL_OFFS)
  57955. +#define SDRAM_DDR2_CL_3 (0x3 << SDRAM_CL_OFFS)
  57956. +#define SDRAM_DDR2_CL_4 (0x4 << SDRAM_CL_OFFS)
  57957. +#define SDRAM_DDR2_CL_5 (0x5 << SDRAM_CL_OFFS)
  57958. +#define SDRAM_TM_OFFS 7
  57959. +#define SDRAM_TM_MASK (1 << SDRAM_TM_OFFS)
  57960. +#define SDRAM_TM_NORMAL (0 << SDRAM_TM_OFFS)
  57961. +#define SDRAM_TM_TEST_MODE (1 << SDRAM_TM_OFFS)
  57962. +#define SDRAM_DLL_OFFS 8
  57963. +#define SDRAM_DLL_MASK (1 << SDRAM_DLL_OFFS)
  57964. +#define SDRAM_DLL_NORMAL (0 << SDRAM_DLL_OFFS)
  57965. +#define SDRAM_DLL_RESET (1 << SDRAM_DLL_OFFS)
  57966. +#define SDRAM_WR_OFFS 11
  57967. +#define SDRAM_WR_MAX 7
  57968. +#define SDRAM_WR_MASK (SDRAM_WR_MAX << SDRAM_WR_OFFS)
  57969. +#define SDRAM_PD_OFFS 12
  57970. +#define SDRAM_PD_MASK (1 << SDRAM_PD_OFFS)
  57971. +#define SDRAM_PD_FAST_EXIT (0 << SDRAM_PD_OFFS)
  57972. +#define SDRAM_PD_SLOW_EXIT (1 << SDRAM_PD_OFFS)
  57973. +
  57974. +/* DDR SDRAM Extended Mode register (DSEMR) */
  57975. +#define SDRAM_EXTENDED_MODE_REG 0x1420
  57976. +#define DSEMR_DLL_ENABLE (1 << 0)
  57977. +#define DSEMR_DS_OFFS 1
  57978. +#define DSEMR_DS_MASK (1 << DSEMR_DS_OFFS)
  57979. +#define DSEMR_DS_NORMAL (0 << DSEMR_DS_OFFS)
  57980. +#define DSEMR_DS_REDUCED (1 << DSEMR_DS_OFFS)
  57981. +#define DSEMR_RTT0_OFFS 2
  57982. +#define DSEMR_RTT1_OFFS 6
  57983. +#define DSEMR_RTT_ODT_DISABLE ((0 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
  57984. +#define DSEMR_RTT_ODT_75_OHM ((1 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
  57985. +#define DSEMR_RTT_ODT_150_OHM ((0 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))
  57986. +#define DSEMR_OCD_OFFS 7
  57987. +#define DSEMR_OCD_MASK (0x7 << DSEMR_OCD_OFFS)
  57988. +#define DSEMR_OCD_EXIT_CALIB (0 << DSEMR_OCD_OFFS)
  57989. +#define DSEMR_OCD_DRIVE1 (1 << DSEMR_OCD_OFFS)
  57990. +#define DSEMR_OCD_DRIVE0 (2 << DSEMR_OCD_OFFS)
  57991. +#define DSEMR_OCD_ADJUST_MODE (4 << DSEMR_OCD_OFFS)
  57992. +#define DSEMR_OCD_CALIB_DEFAULT (7 << DSEMR_OCD_OFFS)
  57993. +#define DSEMR_DQS_OFFS 10
  57994. +#define DSEMR_DQS_MASK (1 << DSEMR_DQS_OFFS)
  57995. +#define DSEMR_DQS_DIFFERENTIAL (0 << DSEMR_DQS_OFFS)
  57996. +#define DSEMR_DQS_SINGLE_ENDED (0 << DSEMR_DQS_OFFS)
  57997. +#define DSEMR_RDQS_ENABLE (1 << 11)
  57998. +#define DSEMR_QOFF_OUTPUT_BUFF_EN (1 << 12)
  57999. +
  58000. +/* DDR SDRAM Operation Control Register */
  58001. +#define SDRAM_OPERATION_CTRL_REG 0x142c
  58002. +
  58003. +/* Dunit FTDLL Configuration Register */
  58004. +#define SDRAM_FTDLL_CONFIG_REG 0x1484
  58005. +
  58006. +/* Pads Calibration register */
  58007. +#define SDRAM_ADDR_CTRL_PADS_CAL_REG 0x14c0
  58008. +#define SDRAM_DATA_PADS_CAL_REG 0x14c4
  58009. +#define SDRAM_DRVN_OFFS 0
  58010. +#define SDRAM_DRVN_MASK (0x3F << SDRAM_DRVN_OFFS)
  58011. +#define SDRAM_DRVP_OFFS 6
  58012. +#define SDRAM_DRVP_MASK (0x3F << SDRAM_DRVP_OFFS)
  58013. +#define SDRAM_PRE_DRIVER_STRENGTH_OFFS 12
  58014. +#define SDRAM_PRE_DRIVER_STRENGTH_MASK (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  58015. +#define SDRAM_TUNE_EN BIT16
  58016. +#define SDRAM_LOCK_OFFS 17
  58017. +#define SDRAM_LOCK_MAKS (0x1F << SDRAM_LOCK_OFFS)
  58018. +#define SDRAM_LOCKN_OFFS 17
  58019. +#define SDRAM_LOCKN_MAKS (0x3F << SDRAM_LOCKN_OFFS)
  58020. +#define SDRAM_LOCKP_OFFS 23
  58021. +#define SDRAM_LOCKP_MAKS (0x3F << SDRAM_LOCKP_OFFS)
  58022. +#define SDRAM_WR_EN (1 << 31)
  58023. +
  58024. +/* DDR2 SDRAM ODT Control (Low) Register (DSOCLR) */
  58025. +#define DDR2_SDRAM_ODT_CTRL_LOW_REG 0x1494
  58026. +#define DSOCLR_ODT_RD_OFFS(odtNum) (odtNum * 4)
  58027. +#define DSOCLR_ODT_RD_MASK(odtNum) (0xf << DSOCLR_ODT_RD_OFFS(odtNum))
  58028. +#define DSOCLR_ODT_RD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_RD_OFFS(odtNum))
  58029. +#define DSOCLR_ODT_WR_OFFS(odtNum) (16 + (odtNum * 4))
  58030. +#define DSOCLR_ODT_WR_MASK(odtNum) (0xf << DSOCLR_ODT_WR_OFFS(odtNum))
  58031. +#define DSOCLR_ODT_WD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_WR_OFFS(odtNum))
  58032. +
  58033. +/* DDR2 SDRAM ODT Control (High) Register (DSOCHR) */
  58034. +#define DDR2_SDRAM_ODT_CTRL_HIGH_REG 0x1498
  58035. +/* Optional control values to DSOCHR_ODT_EN macro */
  58036. +#define DDR2_ODT_CTRL_DUNIT 0
  58037. +#define DDR2_ODT_CTRL_NEVER 1
  58038. +#define DDR2_ODT_CTRL_ALWAYS 3
  58039. +#define DSOCHR_ODT_EN_OFFS(odtNum) (odtNum * 2)
  58040. +#define DSOCHR_ODT_EN_MASK(odtNum) (0x3 << DSOCHR_ODT_EN_OFFS(odtNum))
  58041. +#define DSOCHR_ODT_EN(odtNum, ctrl) ((1 << ctrl) << DSOCHR_ODT_RD_OFFS(odtNum))
  58042. +
  58043. +/* DDR2 Dunit ODT Control Register (DDOCR)*/
  58044. +#define DDR2_DUNIT_ODT_CONTROL_REG 0x149c
  58045. +#define DDOCR_ODT_RD_OFFS 0
  58046. +#define DDOCR_ODT_RD_MASK (0xf << DDOCR_ODT_RD_OFFS)
  58047. +#define DDOCR_ODT_RD(bank) ((1 << bank) << DDOCR_ODT_RD_OFFS)
  58048. +#define DDOCR_ODT_WR_OFFS 4
  58049. +#define DDOCR_ODT_WR_MASK (0xf << DDOCR_ODT_WR_OFFS)
  58050. +#define DDOCR_ODT_WR(bank) ((1 << bank) << DDOCR_ODT_WR_OFFS)
  58051. +#define DSOCR_ODT_EN_OFFS 8
  58052. +#define DSOCR_ODT_EN_MASK (0x3 << DSOCR_ODT_EN_OFFS)
  58053. +#define DSOCR_ODT_EN(ctrl) ((1 << ctrl) << DSOCR_ODT_EN_OFFS)
  58054. +#define DSOCR_ODT_SEL_OFFS 10
  58055. +#define DSOCR_ODT_SEL_MASK (0x3 << DSOCR_ODT_SEL_OFFS)
  58056. +
  58057. +/* DDR SDRAM Initialization Control Register (DSICR) */
  58058. +#define DDR_SDRAM_INIT_CTRL_REG 0x1480
  58059. +#define DSICR_INIT_EN (1 << 0)
  58060. +
  58061. +#endif /* __INCmvDramIfRegsh */
  58062. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c
  58063. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c 1970-01-01 01:00:00.000000000 +0100
  58064. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.c 2011-08-01 14:38:19.000000000 +0200
  58065. @@ -0,0 +1,1855 @@
  58066. +/*******************************************************************************
  58067. +Copyright (C) Marvell International Ltd. and its affiliates
  58068. +
  58069. +This software file (the "File") is owned and distributed by Marvell
  58070. +International Ltd. and/or its affiliates ("Marvell") under the following
  58071. +alternative licensing terms. Once you have made an election to distribute the
  58072. +File under one of the following license alternatives, please (i) delete this
  58073. +introductory statement regarding license alternatives, (ii) delete the two
  58074. +license alternatives that you have not elected to use and (iii) preserve the
  58075. +Marvell copyright notice above.
  58076. +
  58077. +********************************************************************************
  58078. +Marvell Commercial License Option
  58079. +
  58080. +If you received this File from Marvell and you have entered into a commercial
  58081. +license agreement (a "Commercial License") with Marvell, the File is licensed
  58082. +to you under the terms of the applicable Commercial License.
  58083. +
  58084. +********************************************************************************
  58085. +Marvell GPL License Option
  58086. +
  58087. +If you received this File from Marvell, you may opt to use, redistribute and/or
  58088. +modify this File in accordance with the terms and conditions of the General
  58089. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  58090. +available along with the File in the license.txt file or by writing to the Free
  58091. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  58092. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  58093. +
  58094. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  58095. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  58096. +DISCLAIMED. The GPL License provides additional details about this warranty
  58097. +disclaimer.
  58098. +********************************************************************************
  58099. +Marvell BSD License Option
  58100. +
  58101. +If you received this File from Marvell, you may opt to use, redistribute and/or
  58102. +modify this File under the following licensing terms.
  58103. +Redistribution and use in source and binary forms, with or without modification,
  58104. +are permitted provided that the following conditions are met:
  58105. +
  58106. + * Redistributions of source code must retain the above copyright notice,
  58107. + this list of conditions and the following disclaimer.
  58108. +
  58109. + * Redistributions in binary form must reproduce the above copyright
  58110. + notice, this list of conditions and the following disclaimer in the
  58111. + documentation and/or other materials provided with the distribution.
  58112. +
  58113. + * Neither the name of Marvell nor the names of its contributors may be
  58114. + used to endorse or promote products derived from this software without
  58115. + specific prior written permission.
  58116. +
  58117. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  58118. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  58119. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  58120. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  58121. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  58122. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  58123. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  58124. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  58125. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  58126. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  58127. +
  58128. +*******************************************************************************/
  58129. +
  58130. +
  58131. +/* includes */
  58132. +#include "ddr2/mvDramIf.h"
  58133. +#include "ctrlEnv/sys/mvCpuIf.h"
  58134. +
  58135. +#include "ddr2/mvDramIfStaticInit.h"
  58136. +
  58137. +/* #define MV_DEBUG */
  58138. +#ifdef MV_DEBUG
  58139. +#define DB(x) x
  58140. +#else
  58141. +#define DB(x)
  58142. +#endif
  58143. +
  58144. +/* DRAM bank presence encoding */
  58145. +#define BANK_PRESENT_CS0 0x1
  58146. +#define BANK_PRESENT_CS0_CS1 0x3
  58147. +#define BANK_PRESENT_CS0_CS2 0x5
  58148. +#define BANK_PRESENT_CS0_CS1_CS2 0x7
  58149. +#define BANK_PRESENT_CS0_CS2_CS3 0xd
  58150. +#define BANK_PRESENT_CS0_CS2_CS3_CS4 0xf
  58151. +
  58152. +/* locals */
  58153. +#ifndef MV_STATIC_DRAM_ON_BOARD
  58154. +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo);
  58155. +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk, MV_STATUS TTmode );
  58156. +static MV_U32 dunitCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
  58157. +static MV_U32 sdramModeRegCalc(MV_U32 minCas);
  58158. +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
  58159. +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfoDIMM1);
  58160. +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk);
  58161. +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk, MV_U32 forcedCl);
  58162. +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk);
  58163. +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk);
  58164. +static MV_U32 sdramDdr2TimeLoRegCalc(MV_U32 minCas);
  58165. +static MV_U32 sdramDdr2TimeHiRegCalc(MV_U32 minCas);
  58166. +#endif
  58167. +MV_32 DRAM_CS_Order[MV_DRAM_MAX_CS] = {N_A
  58168. +
  58169. +#ifdef MV_INCLUDE_SDRAM_CS1
  58170. + ,N_A
  58171. +#endif
  58172. +#ifdef MV_INCLUDE_SDRAM_CS2
  58173. + ,N_A
  58174. +#endif
  58175. +#ifdef MV_INCLUDE_SDRAM_CS3
  58176. + ,N_A
  58177. +#endif
  58178. + };
  58179. +/* Get DRAM size of CS num */
  58180. +MV_U32 mvDramCsSizeGet(MV_U32 csNum)
  58181. +{
  58182. + MV_DRAM_BANK_INFO bankInfo;
  58183. + MV_U32 size, deviceW, dimmW;
  58184. +#ifdef MV78XX0
  58185. + MV_U32 temp;
  58186. +#endif
  58187. +
  58188. + if(MV_OK == mvDramBankInfoGet(csNum, &bankInfo))
  58189. + {
  58190. + if (0 == bankInfo.size)
  58191. + return 0;
  58192. +
  58193. + /* Note that the Dimm width might be different then the device DRAM width */
  58194. +#ifdef MV78XX0
  58195. + temp = MV_REG_READ(SDRAM_CONFIG_REG);
  58196. + deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_32BIT )? 32 : 64;
  58197. +#else
  58198. + deviceW = 16 /* KW family */;
  58199. +#endif
  58200. + dimmW = bankInfo.dataWidth - (bankInfo.dataWidth % 16);
  58201. + size = ((bankInfo.size << 20) / (dimmW/deviceW));
  58202. + return size;
  58203. + }
  58204. + else
  58205. + return 0;
  58206. +}
  58207. +/*******************************************************************************
  58208. +* mvDramIfDetect - Prepare DRAM interface configuration values.
  58209. +*
  58210. +* DESCRIPTION:
  58211. +* This function implements the full DRAM detection and timing
  58212. +* configuration for best system performance.
  58213. +* Since this routine runs from a ROM device (Boot Flash), its stack
  58214. +* resides on RAM, that might be the system DRAM. Changing DRAM
  58215. +* configuration values while keeping vital data in DRAM is risky. That
  58216. +* is why the function does not preform the configuration setting but
  58217. +* prepare those in predefined 32bit registers (in this case IDMA
  58218. +* registers are used) for other routine to perform the settings.
  58219. +* The function will call for board DRAM SPD information for each DRAM
  58220. +* chip select. The function will then analyze those SPD parameters of
  58221. +* all DRAM banks in order to decide on DRAM configuration compatible
  58222. +* for all DRAM banks.
  58223. +* The function will set the CPU DRAM address decode registers.
  58224. +* Note: This routine prepares values that will overide configuration of
  58225. +* mvDramBasicAsmInit().
  58226. +*
  58227. +* INPUT:
  58228. +* forcedCl - Forced CAL Latency. If equal to zero, do not force.
  58229. +* eccDisable - Force down the ECC.
  58230. +*
  58231. +* OUTPUT:
  58232. +* None.
  58233. +*
  58234. +* RETURN:
  58235. +* None.
  58236. +*
  58237. +*******************************************************************************/
  58238. +MV_STATUS mvDramIfDetect(MV_U32 forcedCl, MV_BOOL eccDisable)
  58239. +{
  58240. + MV_32 MV_DRAM_CS_order[MV_DRAM_MAX_CS] = {
  58241. + SDRAM_CS0
  58242. +#ifdef MV_INCLUDE_SDRAM_CS1
  58243. + ,SDRAM_CS1
  58244. +#endif
  58245. +#ifdef MV_INCLUDE_SDRAM_CS2
  58246. + ,SDRAM_CS2
  58247. +#endif
  58248. +#ifdef MV_INCLUDE_SDRAM_CS3
  58249. + ,SDRAM_CS3
  58250. +#endif
  58251. + };
  58252. + MV_U32 busClk, deviceW, dimmW;
  58253. + MV_U32 numOfAllDevices = 0;
  58254. + MV_STATUS TTMode;
  58255. +#ifndef MV_STATIC_DRAM_ON_BOARD
  58256. + MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
  58257. + MV_U32 size, base = 0, i, j, temp, busClkPs;
  58258. + MV_U8 minCas;
  58259. + MV_CPU_DEC_WIN dramDecWin;
  58260. + dramDecWin.addrWin.baseHigh = 0;
  58261. +#endif
  58262. +
  58263. + busClk = mvBoardSysClkGet();
  58264. +
  58265. + if (0 == busClk)
  58266. + {
  58267. + mvOsPrintf("Dram: ERR. Can't detect system clock! \n");
  58268. + return MV_ERROR;
  58269. + }
  58270. +
  58271. +#ifndef MV_STATIC_DRAM_ON_BOARD
  58272. +
  58273. + busClkPs = 1000000000 / (busClk / 1000); /* in ps units */
  58274. + /* we will use bank 0 as the representative of the all the DRAM banks, */
  58275. + /* since bank 0 must exist. */
  58276. + for(i = 0; i < MV_DRAM_MAX_CS; i++)
  58277. + {
  58278. + /* if Bank exist */
  58279. + if(MV_OK == mvDramBankInfoGet(i, &bankInfo[i]))
  58280. + {
  58281. + DB(mvOsPrintf("Dram: Find bank %d\n", i));
  58282. + /* check it isn't SDRAM */
  58283. + if(bankInfo[i].memoryType != MEM_TYPE_DDR2)
  58284. + {
  58285. + mvOsOutput("Dram: ERR. SDRAM type not supported !!!\n");
  58286. + return MV_ERROR;
  58287. + }
  58288. +
  58289. + /* All banks must support the Mclk freqency */
  58290. + if(bankInfo[i].minCycleTimeAtMaxCasLatPs > busClkPs)
  58291. + {
  58292. + mvOsOutput("Dram: ERR. Bank %d doesn't support memory clock!!!\n", i);
  58293. + return MV_ERROR;
  58294. + }
  58295. +
  58296. + /* All banks must support registry in order to activate it */
  58297. + if(bankInfo[i].registeredAddrAndControlInputs !=
  58298. + bankInfo[0].registeredAddrAndControlInputs)
  58299. + {
  58300. + mvOsOutput("Dram: ERR. different Registered settings !!!\n");
  58301. + return MV_ERROR;
  58302. + }
  58303. +
  58304. + /* All banks must support same ECC mode */
  58305. + if(bankInfo[i].errorCheckType !=
  58306. + bankInfo[0].errorCheckType)
  58307. + {
  58308. + mvOsOutput("Dram: ERR. different ECC settings !!!\n");
  58309. + return MV_ERROR;
  58310. + }
  58311. +
  58312. + }
  58313. + else
  58314. + {
  58315. + if( i == 0 ) /* bank 0 doesn't exist */
  58316. + {
  58317. + mvOsOutput("Dram: ERR. Fail to detect bank 0 !!!\n");
  58318. + return MV_ERROR;
  58319. + }
  58320. + else
  58321. + {
  58322. + DB(mvOsPrintf("Dram: Could not find bank %d\n", i));
  58323. + bankInfo[i].size = 0; /* Mark this bank as non exist */
  58324. + }
  58325. + }
  58326. + }
  58327. +
  58328. +#ifdef MV_INCLUDE_SDRAM_CS2
  58329. + if (bankInfo[SDRAM_CS0].size < bankInfo[SDRAM_CS2].size)
  58330. + {
  58331. + MV_DRAM_CS_order[0] = SDRAM_CS2;
  58332. + MV_DRAM_CS_order[1] = SDRAM_CS3;
  58333. + MV_DRAM_CS_order[2] = SDRAM_CS0;
  58334. + MV_DRAM_CS_order[3] = SDRAM_CS1;
  58335. + DRAM_CS_Order[0] = SDRAM_CS2;
  58336. + DRAM_CS_Order[1] = SDRAM_CS3;
  58337. + DRAM_CS_Order[2] = SDRAM_CS0;
  58338. + DRAM_CS_Order[3] = SDRAM_CS1;
  58339. +
  58340. + }
  58341. + else
  58342. +#endif
  58343. + {
  58344. + MV_DRAM_CS_order[0] = SDRAM_CS0;
  58345. + MV_DRAM_CS_order[1] = SDRAM_CS1;
  58346. + DRAM_CS_Order[0] = SDRAM_CS0;
  58347. + DRAM_CS_Order[1] = SDRAM_CS1;
  58348. +#ifdef MV_INCLUDE_SDRAM_CS2
  58349. + MV_DRAM_CS_order[2] = SDRAM_CS2;
  58350. + MV_DRAM_CS_order[3] = SDRAM_CS3;
  58351. + DRAM_CS_Order[2] = SDRAM_CS2;
  58352. + DRAM_CS_Order[3] = SDRAM_CS3;
  58353. +#endif
  58354. + }
  58355. +
  58356. + for(j = 0; j < MV_DRAM_MAX_CS; j++)
  58357. + {
  58358. + i = MV_DRAM_CS_order[j];
  58359. +
  58360. + if (0 == bankInfo[i].size)
  58361. + continue;
  58362. +
  58363. + /* Init the CPU window decode */
  58364. + /* Note that the Dimm width might be different then the device DRAM width */
  58365. +#ifdef MV78XX0
  58366. + temp = MV_REG_READ(SDRAM_CONFIG_REG);
  58367. + deviceW = ((temp & SDRAM_DWIDTH_MASK) == SDRAM_DWIDTH_32BIT )? 32 : 64;
  58368. +#else
  58369. + deviceW = 16 /* KW family */;
  58370. +#endif
  58371. + dimmW = bankInfo[0].dataWidth - (bankInfo[0].dataWidth % 16);
  58372. + size = ((bankInfo[i].size << 20) / (dimmW/deviceW));
  58373. +
  58374. + /* We can not change DRAM window settings while excecuting */
  58375. + /* code from it. That is why we skip the DRAM CS[0], saving */
  58376. + /* it to the ROM configuration routine */
  58377. +
  58378. + numOfAllDevices += bankInfo[i].numberOfDevices;
  58379. + if (i == MV_DRAM_CS_order[0])
  58380. + {
  58381. + MV_U32 sizeToReg;
  58382. + /* Translate the given window size to register format */
  58383. + sizeToReg = ctrlSizeToReg(size, SCSR_SIZE_ALIGNMENT);
  58384. + /* Size parameter validity check. */
  58385. + if (-1 == sizeToReg)
  58386. + {
  58387. + mvOsOutput("DRAM: mvCtrlAddrDecToReg: ERR. Win %d size invalid.\n"
  58388. + ,i);
  58389. + return MV_BAD_PARAM;
  58390. + }
  58391. +
  58392. + DB(mvOsPrintf("Dram: Bank 0 Size - %x\n",sizeToReg);)
  58393. + sizeToReg = (sizeToReg << SCSR_SIZE_OFFS);
  58394. + sizeToReg |= SCSR_WIN_EN;
  58395. + MV_REG_WRITE(DRAM_BUF_REG0, sizeToReg);
  58396. + }
  58397. + else
  58398. + {
  58399. + dramDecWin.addrWin.baseLow = base;
  58400. + dramDecWin.addrWin.size = size;
  58401. + dramDecWin.enable = MV_TRUE;
  58402. + DB(mvOsPrintf("Dram: Enable window %d base 0x%x, size=0x%x\n",i, base, size));
  58403. +
  58404. + /* Check if the DRAM size is more then 3GByte */
  58405. + if (base < 0xC0000000)
  58406. + {
  58407. + DB(mvOsPrintf("Dram: Enable window %d base 0x%x, size=0x%x\n",i, base, size));
  58408. + if (MV_OK != mvCpuIfTargetWinSet(i, &dramDecWin))
  58409. + {
  58410. + mvOsPrintf("Dram: ERR. Fail to set bank %d!!!\n", SDRAM_CS0 + i);
  58411. + return MV_ERROR;
  58412. + }
  58413. + }
  58414. + }
  58415. +
  58416. + base += size;
  58417. +
  58418. + /* update the suportedCasLatencies mask */
  58419. + bankInfo[0].suportedCasLatencies &= bankInfo[i].suportedCasLatencies;
  58420. + }
  58421. +
  58422. + /* calculate minimum CAS */
  58423. + minCas = minCasCalc(&bankInfo[0], &bankInfo[2], busClk, forcedCl);
  58424. + if (0 == minCas)
  58425. + {
  58426. + mvOsOutput("Dram: Warn: Could not find CAS compatible to SysClk %dMhz\n",
  58427. + (busClk / 1000000));
  58428. +
  58429. + minCas = DDR2_CL_4; /* Continue with this CAS */
  58430. + mvOsOutput("Set default CAS latency 4\n");
  58431. + }
  58432. +
  58433. + /* calc SDRAM_CONFIG_REG and save it to temp register */
  58434. + temp = sdramConfigRegCalc(&bankInfo[0],&bankInfo[2], busClk);
  58435. + if(-1 == temp)
  58436. + {
  58437. + mvOsOutput("Dram: ERR. sdramConfigRegCalc failed !!!\n");
  58438. + return MV_ERROR;
  58439. + }
  58440. +
  58441. + /* check if ECC is enabled by the user */
  58442. + if(eccDisable)
  58443. + {
  58444. + /* turn off ECC*/
  58445. + temp &= ~BIT18;
  58446. + }
  58447. + DB(mvOsPrintf("Dram: sdramConfigRegCalc - %x\n",temp);)
  58448. + MV_REG_WRITE(DRAM_BUF_REG1, temp);
  58449. +
  58450. + /* calc SDRAM_MODE_REG and save it to temp register */
  58451. + temp = sdramModeRegCalc(minCas);
  58452. + if(-1 == temp)
  58453. + {
  58454. + mvOsOutput("Dram: ERR. sdramModeRegCalc failed !!!\n");
  58455. + return MV_ERROR;
  58456. + }
  58457. + DB(mvOsPrintf("Dram: sdramModeRegCalc - %x\n",temp);)
  58458. + MV_REG_WRITE(DRAM_BUF_REG2, temp);
  58459. +
  58460. + /* calc SDRAM_EXTENDED_MODE_REG and save it to temp register */
  58461. + temp = sdramExtModeRegCalc(&bankInfo[0], busClk);
  58462. + if(-1 == temp)
  58463. + {
  58464. + mvOsOutput("Dram: ERR. sdramExtModeRegCalc failed !!!\n");
  58465. + return MV_ERROR;
  58466. + }
  58467. + DB(mvOsPrintf("Dram: sdramExtModeRegCalc - %x\n",temp);)
  58468. + MV_REG_WRITE(DRAM_BUF_REG10, temp);
  58469. +
  58470. + /* calc D_UNIT_CONTROL_LOW and save it to temp register */
  58471. + TTMode = MV_FALSE;
  58472. + DB(mvOsPrintf("Dram: numOfAllDevices = %x\n",numOfAllDevices);)
  58473. + if( (numOfAllDevices > 9) && (bankInfo[0].registeredAddrAndControlInputs == MV_FALSE) )
  58474. + {
  58475. + if ( ( (numOfAllDevices > 9) && (busClk > MV_BOARD_SYSCLK_200MHZ) ) ||
  58476. + (numOfAllDevices > 18) )
  58477. + {
  58478. + mvOsOutput("Enable 2T ");
  58479. + TTMode = MV_TRUE;
  58480. + }
  58481. + }
  58482. +
  58483. + temp = dunitCtrlLowRegCalc(&bankInfo[0], minCas, busClk, TTMode );
  58484. + if(-1 == temp)
  58485. + {
  58486. + mvOsOutput("Dram: ERR. dunitCtrlLowRegCalc failed !!!\n");
  58487. + return MV_ERROR;
  58488. + }
  58489. + DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc - %x\n",temp);)
  58490. + MV_REG_WRITE(DRAM_BUF_REG3, temp);
  58491. +
  58492. + /* calc D_UNIT_CONTROL_HIGH and save it to temp register */
  58493. + temp = dunitCtrlHighRegCalc(&bankInfo[0], busClk);
  58494. + if(-1 == temp)
  58495. + {
  58496. + mvOsOutput("Dram: ERR. dunitCtrlHighRegCalc failed !!!\n");
  58497. + return MV_ERROR;
  58498. + }
  58499. + DB(mvOsPrintf("Dram: dunitCtrlHighRegCalc - %x\n",temp);)
  58500. + /* check if ECC is enabled by the user */
  58501. + if(eccDisable)
  58502. + {
  58503. + /* turn off sample stage if no ecc */
  58504. + temp &= ~SDRAM__D2P_EN;;
  58505. + }
  58506. + MV_REG_WRITE(DRAM_BUF_REG13, temp);
  58507. +
  58508. + /* calc SDRAM_ADDR_CTRL_REG and save it to temp register */
  58509. + temp = sdramAddrCtrlRegCalc(&bankInfo[0],&bankInfo[2]);
  58510. + if(-1 == temp)
  58511. + {
  58512. + mvOsOutput("Dram: ERR. sdramAddrCtrlRegCalc failed !!!\n");
  58513. + return MV_ERROR;
  58514. + }
  58515. + DB(mvOsPrintf("Dram: sdramAddrCtrlRegCalc - %x\n",temp);)
  58516. + MV_REG_WRITE(DRAM_BUF_REG4, temp);
  58517. +
  58518. + /* calc SDRAM_TIMING_CTRL_LOW_REG and save it to temp register */
  58519. + temp = sdramTimeCtrlLowRegCalc(&bankInfo[0], minCas, busClk);
  58520. + if(-1 == temp)
  58521. + {
  58522. + mvOsOutput("Dram: ERR. sdramTimeCtrlLowRegCalc failed !!!\n");
  58523. + return MV_ERROR;
  58524. + }
  58525. + DB(mvOsPrintf("Dram: sdramTimeCtrlLowRegCalc - %x\n",temp);)
  58526. + MV_REG_WRITE(DRAM_BUF_REG5, temp);
  58527. +
  58528. + /* calc SDRAM_TIMING_CTRL_HIGH_REG and save it to temp register */
  58529. + temp = sdramTimeCtrlHighRegCalc(&bankInfo[0], busClk);
  58530. + if(-1 == temp)
  58531. + {
  58532. + mvOsOutput("Dram: ERR. sdramTimeCtrlHighRegCalc failed !!!\n");
  58533. + return MV_ERROR;
  58534. + }
  58535. + DB(mvOsPrintf("Dram: sdramTimeCtrlHighRegCalc - %x\n",temp);)
  58536. + MV_REG_WRITE(DRAM_BUF_REG6, temp);
  58537. +
  58538. + sdramDDr2OdtConfig(bankInfo);
  58539. +
  58540. + /* calc DDR2_SDRAM_TIMING_LOW_REG and save it to temp register */
  58541. + temp = sdramDdr2TimeLoRegCalc(minCas);
  58542. + if(-1 == temp)
  58543. + {
  58544. + mvOsOutput("Dram: ERR. sdramDdr2TimeLoRegCalc failed !!!\n");
  58545. + return MV_ERROR;
  58546. + }
  58547. + DB(mvOsPrintf("Dram: sdramDdr2TimeLoRegCalc - %x\n",temp);)
  58548. + MV_REG_WRITE(DRAM_BUF_REG11, temp);
  58549. +
  58550. + /* calc DDR2_SDRAM_TIMING_HIGH_REG and save it to temp register */
  58551. + temp = sdramDdr2TimeHiRegCalc(minCas);
  58552. + if(-1 == temp)
  58553. + {
  58554. + mvOsOutput("Dram: ERR. sdramDdr2TimeHiRegCalc failed !!!\n");
  58555. + return MV_ERROR;
  58556. + }
  58557. + DB(mvOsPrintf("Dram: sdramDdr2TimeHiRegCalc - %x\n",temp);)
  58558. + MV_REG_WRITE(DRAM_BUF_REG12, temp);
  58559. +#endif
  58560. +
  58561. + /* Note that DDR SDRAM Address/Control and Data pad calibration */
  58562. + /* settings is done in mvSdramIfConfig.s */
  58563. +
  58564. + return MV_OK;
  58565. +}
  58566. +
  58567. +
  58568. +/*******************************************************************************
  58569. +* mvDramIfBankBaseGet - Get DRAM interface bank base.
  58570. +*
  58571. +* DESCRIPTION:
  58572. +* This function returns the 32 bit base address of a given DRAM bank.
  58573. +*
  58574. +* INPUT:
  58575. +* bankNum - Bank number.
  58576. +*
  58577. +* OUTPUT:
  58578. +* None.
  58579. +*
  58580. +* RETURN:
  58581. +* DRAM bank size. If bank is disabled or paramter is invalid, the
  58582. +* function returns -1.
  58583. +*
  58584. +*******************************************************************************/
  58585. +MV_U32 mvDramIfBankBaseGet(MV_U32 bankNum)
  58586. +{
  58587. + DB(mvOsPrintf("Dram: mvDramIfBankBaseGet Bank %d base addr is %x \n",
  58588. + bankNum, mvCpuIfTargetWinBaseLowGet(SDRAM_CS0 + bankNum)));
  58589. + return mvCpuIfTargetWinBaseLowGet(SDRAM_CS0 + bankNum);
  58590. +}
  58591. +
  58592. +/*******************************************************************************
  58593. +* mvDramIfBankSizeGet - Get DRAM interface bank size.
  58594. +*
  58595. +* DESCRIPTION:
  58596. +* This function returns the size of a given DRAM bank.
  58597. +*
  58598. +* INPUT:
  58599. +* bankNum - Bank number.
  58600. +*
  58601. +* OUTPUT:
  58602. +* None.
  58603. +*
  58604. +* RETURN:
  58605. +* DRAM bank size. If bank is disabled the function return '0'. In case
  58606. +* or paramter is invalid, the function returns -1.
  58607. +*
  58608. +*******************************************************************************/
  58609. +MV_U32 mvDramIfBankSizeGet(MV_U32 bankNum)
  58610. +{
  58611. + DB(mvOsPrintf("Dram: mvDramIfBankSizeGet Bank %d size is %x \n",
  58612. + bankNum, mvCpuIfTargetWinSizeGet(SDRAM_CS0 + bankNum)));
  58613. + return mvCpuIfTargetWinSizeGet(SDRAM_CS0 + bankNum);
  58614. +}
  58615. +
  58616. +
  58617. +/*******************************************************************************
  58618. +* mvDramIfSizeGet - Get DRAM interface total size.
  58619. +*
  58620. +* DESCRIPTION:
  58621. +* This function get the DRAM total size.
  58622. +*
  58623. +* INPUT:
  58624. +* None.
  58625. +*
  58626. +* OUTPUT:
  58627. +* None.
  58628. +*
  58629. +* RETURN:
  58630. +* DRAM total size. In case or paramter is invalid, the function
  58631. +* returns -1.
  58632. +*
  58633. +*******************************************************************************/
  58634. +MV_U32 mvDramIfSizeGet(MV_VOID)
  58635. +{
  58636. + MV_U32 size = 0, i;
  58637. +
  58638. + for(i = 0; i < MV_DRAM_MAX_CS; i++)
  58639. + size += mvDramIfBankSizeGet(i);
  58640. +
  58641. + DB(mvOsPrintf("Dram: mvDramIfSizeGet size is %x \n",size));
  58642. + return size;
  58643. +}
  58644. +
  58645. +/*******************************************************************************
  58646. +* mvDramIfSingleBitErrThresholdSet - Set single bit ECC threshold.
  58647. +*
  58648. +* DESCRIPTION:
  58649. +* The ECC single bit error threshold is the number of single bit
  58650. +* errors to happen before the Dunit generates an interrupt.
  58651. +* This function set single bit ECC threshold.
  58652. +*
  58653. +* INPUT:
  58654. +* threshold - threshold.
  58655. +*
  58656. +* OUTPUT:
  58657. +* None.
  58658. +*
  58659. +* RETURN:
  58660. +* MV_BAD_PARAM if threshold is to big, MV_OK otherwise.
  58661. +*
  58662. +*******************************************************************************/
  58663. +MV_STATUS mvDramIfSingleBitErrThresholdSet(MV_U32 threshold)
  58664. +{
  58665. + MV_U32 regVal;
  58666. +
  58667. + if (threshold > SECR_THRECC_MAX)
  58668. + {
  58669. + return MV_BAD_PARAM;
  58670. + }
  58671. +
  58672. + regVal = MV_REG_READ(SDRAM_ECC_CONTROL_REG);
  58673. + regVal &= ~SECR_THRECC_MASK;
  58674. + regVal |= ((SECR_THRECC(threshold) & SECR_THRECC_MASK));
  58675. + MV_REG_WRITE(SDRAM_ECC_CONTROL_REG, regVal);
  58676. +
  58677. + return MV_OK;
  58678. +}
  58679. +
  58680. +#ifndef MV_STATIC_DRAM_ON_BOARD
  58681. +/*******************************************************************************
  58682. +* minCasCalc - Calculate the Minimum CAS latency which can be used.
  58683. +*
  58684. +* DESCRIPTION:
  58685. +* Calculate the minimum CAS latency that can be used, base on the DRAM
  58686. +* parameters and the SDRAM bus Clock freq.
  58687. +*
  58688. +* INPUT:
  58689. +* busClk - the DRAM bus Clock.
  58690. +* pBankInfo - bank info parameters.
  58691. +* forcedCl - Forced CAS Latency multiplied by 10. If equal to zero, do not force.
  58692. +*
  58693. +* OUTPUT:
  58694. +* None
  58695. +*
  58696. +* RETURN:
  58697. +* The minimum CAS Latency. The function returns 0 if max CAS latency
  58698. +* supported by banks is incompatible with system bus clock frequancy.
  58699. +*
  58700. +*******************************************************************************/
  58701. +
  58702. +static MV_U32 minCasCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk, MV_U32 forcedCl)
  58703. +{
  58704. + MV_U32 count = 1, j;
  58705. + MV_U32 busClkPs = 1000000000 / (busClk / 1000); /* in ps units */
  58706. + MV_U32 startBit, stopBit;
  58707. + MV_U32 minCas0 = 0, minCas2 = 0;
  58708. +
  58709. +
  58710. + /* DDR 2:
  58711. + *******-******-******-******-******-******-******-*******
  58712. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  58713. + *******-******-******-******-******-******-******-*******
  58714. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  58715. + Disco VI= * TBD | TBD | 5 | 4 | 3 | TBD | TBD | TBD *
  58716. + Disco Duo= * TBD | 6 | 5 | 4 | 3 | TBD | TBD | TBD *
  58717. + *********************************************************/
  58718. +
  58719. +
  58720. + /* If we are asked to use the forced CAL we change the suported CAL to be forcedCl only */
  58721. + if (forcedCl)
  58722. + {
  58723. + mvOsOutput("DRAM: Using forced CL %d.%d\n", (forcedCl / 10), (forcedCl % 10));
  58724. +
  58725. + if (forcedCl == 30)
  58726. + pBankInfo->suportedCasLatencies = 0x08;
  58727. + else if (forcedCl == 40)
  58728. + pBankInfo->suportedCasLatencies = 0x10;
  58729. + else if (forcedCl == 50)
  58730. + pBankInfo->suportedCasLatencies = 0x20;
  58731. + else if (forcedCl == 60)
  58732. + pBankInfo->suportedCasLatencies = 0x40;
  58733. + else
  58734. + {
  58735. + mvOsPrintf("Forced CL %d.%d not supported. Set default CL 4\n",
  58736. + (forcedCl / 10), (forcedCl % 10));
  58737. + pBankInfo->suportedCasLatencies = 0x10;
  58738. + }
  58739. +
  58740. + return pBankInfo->suportedCasLatencies;
  58741. + }
  58742. +
  58743. + /* go over the supported cas mask from Max Cas down and check if the */
  58744. + /* SysClk stands in its time requirments. */
  58745. +
  58746. + DB(mvOsPrintf("Dram: minCasCalc supported mask = %x busClkPs = %x \n",
  58747. + pBankInfo->suportedCasLatencies,busClkPs ));
  58748. + count = 1;
  58749. + for(j = 7; j > 0; j--)
  58750. + {
  58751. + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
  58752. + {
  58753. + /* Reset the bits for CL incompatible for the sysClk */
  58754. + switch (count)
  58755. + {
  58756. + case 1:
  58757. + if (pBankInfo->minCycleTimeAtMaxCasLatPs > busClkPs)
  58758. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  58759. + count++;
  58760. + break;
  58761. + case 2:
  58762. + if (pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
  58763. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  58764. + count++;
  58765. + break;
  58766. + case 3:
  58767. + if (pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
  58768. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  58769. + count++;
  58770. + break;
  58771. + default:
  58772. + pBankInfo->suportedCasLatencies &= ~(BIT0 << j);
  58773. + break;
  58774. + }
  58775. + }
  58776. + }
  58777. +
  58778. + DB(mvOsPrintf("Dram: minCasCalc support = %x (after SysCC calc)\n",
  58779. + pBankInfo->suportedCasLatencies ));
  58780. +
  58781. + count = 1;
  58782. + DB(mvOsPrintf("Dram2: minCasCalc supported mask = %x busClkPs = %x \n",
  58783. + pBankInfo2->suportedCasLatencies,busClkPs ));
  58784. + for(j = 7; j > 0; j--)
  58785. + {
  58786. + if((pBankInfo2->suportedCasLatencies >> j) & BIT0 )
  58787. + {
  58788. + /* Reset the bits for CL incompatible for the sysClk */
  58789. + switch (count)
  58790. + {
  58791. + case 1:
  58792. + if (pBankInfo2->minCycleTimeAtMaxCasLatPs > busClkPs)
  58793. + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
  58794. + count++;
  58795. + break;
  58796. + case 2:
  58797. + if (pBankInfo2->minCycleTimeAtMaxCasLatMinus1Ps > busClkPs)
  58798. + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
  58799. + count++;
  58800. + break;
  58801. + case 3:
  58802. + if (pBankInfo2->minCycleTimeAtMaxCasLatMinus2Ps > busClkPs)
  58803. + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
  58804. + count++;
  58805. + break;
  58806. + default:
  58807. + pBankInfo2->suportedCasLatencies &= ~(BIT0 << j);
  58808. + break;
  58809. + }
  58810. + }
  58811. + }
  58812. +
  58813. + DB(mvOsPrintf("Dram2: minCasCalc support = %x (after SysCC calc)\n",
  58814. + pBankInfo2->suportedCasLatencies ));
  58815. +
  58816. + startBit = 3; /* DDR2 support CL start with CL3 (bit 3) */
  58817. + stopBit = 6; /* DDR2 support CL stops with CL6 (bit 6) */
  58818. +
  58819. + for(j = startBit; j <= stopBit ; j++)
  58820. + {
  58821. + if((pBankInfo->suportedCasLatencies >> j) & BIT0 )
  58822. + {
  58823. + DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
  58824. + minCas0 = (BIT0 << j);
  58825. + break;
  58826. + }
  58827. + }
  58828. +
  58829. + for(j = startBit; j <= stopBit ; j++)
  58830. + {
  58831. + if((pBankInfo2->suportedCasLatencies >> j) & BIT0 )
  58832. + {
  58833. + DB(mvOsPrintf("Dram: minCasCalc choose CAS %x \n",(BIT0 << j)));
  58834. + minCas2 = (BIT0 << j);
  58835. + break;
  58836. + }
  58837. + }
  58838. +
  58839. + if (minCas2 > minCas0)
  58840. + return minCas2;
  58841. + else
  58842. + return minCas0;
  58843. +
  58844. + return 0;
  58845. +}
  58846. +
  58847. +/*******************************************************************************
  58848. +* sdramConfigRegCalc - Calculate sdram config register
  58849. +*
  58850. +* DESCRIPTION: Calculate sdram config register optimized value based
  58851. +* on the bank info parameters.
  58852. +*
  58853. +* INPUT:
  58854. +* busClk - the DRAM bus Clock.
  58855. +* pBankInfo - sdram bank parameters
  58856. +*
  58857. +* OUTPUT:
  58858. +* None
  58859. +*
  58860. +* RETURN:
  58861. +* sdram config reg value.
  58862. +*
  58863. +*******************************************************************************/
  58864. +static MV_U32 sdramConfigRegCalc(MV_DRAM_BANK_INFO *pBankInfo,MV_DRAM_BANK_INFO *pBankInfo2, MV_U32 busClk)
  58865. +{
  58866. + MV_U32 sdramConfig = 0;
  58867. + MV_U32 refreshPeriod;
  58868. +
  58869. + busClk /= 1000000; /* we work with busClk in MHz */
  58870. +
  58871. + sdramConfig = MV_REG_READ(SDRAM_CONFIG_REG);
  58872. +
  58873. + /* figure out the memory refresh internal */
  58874. + switch (pBankInfo->refreshInterval & 0xf)
  58875. + {
  58876. + case 0x0: /* refresh period is 15.625 usec */
  58877. + refreshPeriod = 15625;
  58878. + break;
  58879. + case 0x1: /* refresh period is 3.9 usec */
  58880. + refreshPeriod = 3900;
  58881. + break;
  58882. + case 0x2: /* refresh period is 7.8 usec */
  58883. + refreshPeriod = 7800;
  58884. + break;
  58885. + case 0x3: /* refresh period is 31.3 usec */
  58886. + refreshPeriod = 31300;
  58887. + break;
  58888. + case 0x4: /* refresh period is 62.5 usec */
  58889. + refreshPeriod = 62500;
  58890. + break;
  58891. + case 0x5: /* refresh period is 125 usec */
  58892. + refreshPeriod = 125000;
  58893. + break;
  58894. + default: /* refresh period undefined */
  58895. + mvOsPrintf("Dram: ERR. DRAM refresh period is unknown!\n");
  58896. + return -1;
  58897. + }
  58898. +
  58899. + /* Now the refreshPeriod is in register format value */
  58900. + refreshPeriod = (busClk * refreshPeriod) / 1000;
  58901. +
  58902. + DB(mvOsPrintf("Dram: sdramConfigRegCalc calculated refresh interval %0x\n",
  58903. + refreshPeriod));
  58904. +
  58905. + /* make sure the refresh value is only 14 bits */
  58906. + if(refreshPeriod > SDRAM_REFRESH_MAX)
  58907. + {
  58908. + refreshPeriod = SDRAM_REFRESH_MAX;
  58909. + DB(mvOsPrintf("Dram: sdramConfigRegCalc adjusted refresh interval %0x\n",
  58910. + refreshPeriod));
  58911. + }
  58912. +
  58913. + /* Clear the refresh field */
  58914. + sdramConfig &= ~SDRAM_REFRESH_MASK;
  58915. +
  58916. + /* Set new value to refresh field */
  58917. + sdramConfig |= (refreshPeriod & SDRAM_REFRESH_MASK);
  58918. +
  58919. + /* registered DRAM ? */
  58920. + if ( pBankInfo->registeredAddrAndControlInputs )
  58921. + {
  58922. + /* it's registered DRAM, so set the reg. DRAM bit */
  58923. + sdramConfig |= SDRAM_REGISTERED;
  58924. + DB(mvOsPrintf("DRAM Attribute: Registered address and control inputs.\n");)
  58925. + }
  58926. +
  58927. + /* ECC and IERR support */
  58928. + sdramConfig &= ~SDRAM_ECC_MASK; /* Clear ECC field */
  58929. + sdramConfig &= ~SDRAM_IERR_MASK; /* Clear IErr field */
  58930. +
  58931. + if ( pBankInfo->errorCheckType )
  58932. + {
  58933. + sdramConfig |= SDRAM_ECC_EN;
  58934. + sdramConfig |= SDRAM_IERR_REPORTE;
  58935. + DB(mvOsPrintf("Dram: mvDramIfDetect Enabling ECC\n"));
  58936. + }
  58937. + else
  58938. + {
  58939. + sdramConfig |= SDRAM_ECC_DIS;
  58940. + sdramConfig |= SDRAM_IERR_IGNORE;
  58941. + DB(mvOsPrintf("Dram: mvDramIfDetect Disabling ECC!\n"));
  58942. + }
  58943. + /* Set static default settings */
  58944. + sdramConfig |= SDRAM_CONFIG_DV;
  58945. +
  58946. + DB(mvOsPrintf("Dram: sdramConfigRegCalc set sdramConfig to 0x%x\n",
  58947. + sdramConfig));
  58948. +
  58949. + return sdramConfig;
  58950. +}
  58951. +
  58952. +/*******************************************************************************
  58953. +* sdramModeRegCalc - Calculate sdram mode register
  58954. +*
  58955. +* DESCRIPTION: Calculate sdram mode register optimized value based
  58956. +* on the bank info parameters and the minCas.
  58957. +*
  58958. +* INPUT:
  58959. +* minCas - minimum CAS supported.
  58960. +*
  58961. +* OUTPUT:
  58962. +* None
  58963. +*
  58964. +* RETURN:
  58965. +* sdram mode reg value.
  58966. +*
  58967. +*******************************************************************************/
  58968. +static MV_U32 sdramModeRegCalc(MV_U32 minCas)
  58969. +{
  58970. + MV_U32 sdramMode;
  58971. +
  58972. + sdramMode = MV_REG_READ(SDRAM_MODE_REG);
  58973. +
  58974. + /* Clear CAS Latency field */
  58975. + sdramMode &= ~SDRAM_CL_MASK;
  58976. +
  58977. + DB(mvOsPrintf("DRAM CAS Latency ");)
  58978. +
  58979. + switch (minCas)
  58980. + {
  58981. + case DDR2_CL_3:
  58982. + sdramMode |= SDRAM_DDR2_CL_3;
  58983. + DB(mvOsPrintf("3.\n");)
  58984. + break;
  58985. + case DDR2_CL_4:
  58986. + sdramMode |= SDRAM_DDR2_CL_4;
  58987. + DB(mvOsPrintf("4.\n");)
  58988. + break;
  58989. + case DDR2_CL_5:
  58990. + sdramMode |= SDRAM_DDR2_CL_5;
  58991. + DB(mvOsPrintf("5.\n");)
  58992. + break;
  58993. + case DDR2_CL_6:
  58994. + sdramMode |= SDRAM_DDR2_CL_6;
  58995. + DB(mvOsPrintf("6.\n");)
  58996. + break;
  58997. + default:
  58998. + mvOsOutput("\nsdramModeRegCalc ERROR: Max. CL out of range\n");
  58999. + return -1;
  59000. + }
  59001. +
  59002. + DB(mvOsPrintf("\nsdramModeRegCalc register 0x%x\n", sdramMode ));
  59003. +
  59004. + return sdramMode;
  59005. +}
  59006. +/*******************************************************************************
  59007. +* sdramExtModeRegCalc - Calculate sdram Extended mode register
  59008. +*
  59009. +* DESCRIPTION:
  59010. +* Return sdram Extended mode register value based
  59011. +* on the bank info parameters and bank presence.
  59012. +*
  59013. +* INPUT:
  59014. +* pBankInfo - sdram bank parameters
  59015. +* busClk - DRAM frequency
  59016. +*
  59017. +* OUTPUT:
  59018. +* None
  59019. +*
  59020. +* RETURN:
  59021. +* sdram Extended mode reg value.
  59022. +*
  59023. +*******************************************************************************/
  59024. +static MV_U32 sdramExtModeRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
  59025. +{
  59026. + MV_U32 populateBanks = 0;
  59027. + int bankNum;
  59028. +
  59029. + /* Represent the populate banks in binary form */
  59030. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  59031. + {
  59032. + if (0 != pBankInfo[bankNum].size)
  59033. + {
  59034. + populateBanks |= (1 << bankNum);
  59035. + }
  59036. + }
  59037. +
  59038. + switch(populateBanks)
  59039. + {
  59040. + case(BANK_PRESENT_CS0):
  59041. + case(BANK_PRESENT_CS0_CS1):
  59042. + return DDR_SDRAM_EXT_MODE_CS0_CS1_DV;
  59043. +
  59044. + case(BANK_PRESENT_CS0_CS2):
  59045. + case(BANK_PRESENT_CS0_CS1_CS2):
  59046. + case(BANK_PRESENT_CS0_CS2_CS3):
  59047. + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
  59048. + if (busClk >= MV_BOARD_SYSCLK_267MHZ)
  59049. + return DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV;
  59050. + else
  59051. + return DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV;
  59052. +
  59053. + default:
  59054. + mvOsOutput("sdramExtModeRegCalc: Invalid DRAM bank presence\n");
  59055. + return -1;
  59056. + }
  59057. + return 0;
  59058. +}
  59059. +
  59060. +/*******************************************************************************
  59061. +* dunitCtrlLowRegCalc - Calculate sdram dunit control low register
  59062. +*
  59063. +* DESCRIPTION: Calculate sdram dunit control low register optimized value based
  59064. +* on the bank info parameters and the minCas.
  59065. +*
  59066. +* INPUT:
  59067. +* pBankInfo - sdram bank parameters
  59068. +* minCas - minimum CAS supported.
  59069. +*
  59070. +* OUTPUT:
  59071. +* None
  59072. +*
  59073. +* RETURN:
  59074. +* sdram dunit control low reg value.
  59075. +*
  59076. +*******************************************************************************/
  59077. +static MV_U32 dunitCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk, MV_STATUS TTMode)
  59078. +{
  59079. + MV_U32 dunitCtrlLow, cl;
  59080. + MV_U32 sbOutR[4]={3,5,7,9} ;
  59081. + MV_U32 sbOutU[4]={1,3,5,7} ;
  59082. +
  59083. + dunitCtrlLow = MV_REG_READ(SDRAM_DUNIT_CTRL_REG);
  59084. +
  59085. + DB(mvOsPrintf("Dram: dunitCtrlLowRegCalc\n"));
  59086. +
  59087. + /* Clear StBurstOutDel field */
  59088. + dunitCtrlLow &= ~SDRAM_SB_OUT_MASK;
  59089. +
  59090. + /* Clear StBurstInDel field */
  59091. + dunitCtrlLow &= ~SDRAM_SB_IN_MASK;
  59092. +
  59093. + /* Clear CtrlPos field */
  59094. + dunitCtrlLow &= ~SDRAM_CTRL_POS_MASK;
  59095. +
  59096. + /* Clear 2T field */
  59097. + dunitCtrlLow &= ~SDRAM_2T_MASK;
  59098. + if (TTMode == MV_TRUE)
  59099. + {
  59100. + dunitCtrlLow |= SDRAM_2T_MODE;
  59101. + }
  59102. +
  59103. + /* For proper sample of read data set the Dunit Control register's */
  59104. + /* stBurstInDel bits [27:24] */
  59105. + /* 200MHz - 267MHz None reg = CL + 1 */
  59106. + /* 200MHz - 267MHz reg = CL + 2 */
  59107. + /* > 267MHz None reg = CL + 2 */
  59108. + /* > 267MHz reg = CL + 3 */
  59109. +
  59110. + /* For proper sample of read data set the Dunit Control register's */
  59111. + /* stBurstOutDel bits [23:20] */
  59112. + /********-********-********-********-
  59113. + * CL=3 | CL=4 | CL=5 | CL=6 |
  59114. + *********-********-********-********-
  59115. + Not Reg. * 0001 | 0011 | 0101 | 0111 |
  59116. + *********-********-********-********-
  59117. + Registered * 0011 | 0101 | 0111 | 1001 |
  59118. + *********-********-********-********/
  59119. +
  59120. + /* Set Dunit Control low default value */
  59121. + dunitCtrlLow |= SDRAM_DUNIT_CTRL_LOW_DDR2_DV;
  59122. +
  59123. + switch (minCas)
  59124. + {
  59125. + case DDR2_CL_3: cl = 3; break;
  59126. + case DDR2_CL_4: cl = 4; break;
  59127. + case DDR2_CL_5: cl = 5; break;
  59128. + case DDR2_CL_6: cl = 6; break;
  59129. + default:
  59130. + mvOsOutput("Dram: dunitCtrlLowRegCalc Max. CL out of range %d\n", minCas);
  59131. + return -1;
  59132. + }
  59133. +
  59134. + /* registerd DDR SDRAM? */
  59135. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  59136. + {
  59137. + dunitCtrlLow |= (sbOutR[cl-3]) << SDRAM_SB_OUT_DEL_OFFS;
  59138. + }
  59139. + else
  59140. + {
  59141. + dunitCtrlLow |= (sbOutU[cl-3]) << SDRAM_SB_OUT_DEL_OFFS;
  59142. + }
  59143. +
  59144. + DB(mvOsPrintf("\n\ndunitCtrlLowRegCalc: CL = %d, frequencies=%d\n", cl, busClk));
  59145. +
  59146. + if (busClk <= MV_BOARD_SYSCLK_267MHZ)
  59147. + {
  59148. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  59149. + cl = cl + 2;
  59150. + else
  59151. + cl = cl + 1;
  59152. + }
  59153. + else
  59154. + {
  59155. + if (pBankInfo->registeredAddrAndControlInputs == MV_TRUE)
  59156. + cl = cl + 3;
  59157. + else
  59158. + cl = cl + 2;
  59159. + }
  59160. +
  59161. + DB(mvOsPrintf("dunitCtrlLowRegCalc: SDRAM_SB_IN_DEL_OFFS = %d \n", cl));
  59162. + dunitCtrlLow |= cl << SDRAM_SB_IN_DEL_OFFS;
  59163. +
  59164. + DB(mvOsPrintf("Dram: Reg dunit control low = %x\n", dunitCtrlLow ));
  59165. +
  59166. + return dunitCtrlLow;
  59167. +}
  59168. +
  59169. +/*******************************************************************************
  59170. +* dunitCtrlHighRegCalc - Calculate sdram dunit control high register
  59171. +*
  59172. +* DESCRIPTION: Calculate sdram dunit control high register optimized value based
  59173. +* on the bus clock.
  59174. +*
  59175. +* INPUT:
  59176. +* busClk - DRAM frequency.
  59177. +*
  59178. +* OUTPUT:
  59179. +* None
  59180. +*
  59181. +* RETURN:
  59182. +* sdram dunit control high reg value.
  59183. +*
  59184. +*******************************************************************************/
  59185. +static MV_U32 dunitCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
  59186. +{
  59187. + MV_U32 dunitCtrlHigh;
  59188. + dunitCtrlHigh = MV_REG_READ(SDRAM_DUNIT_CTRL_HI_REG);
  59189. + if(busClk > MV_BOARD_SYSCLK_300MHZ)
  59190. + dunitCtrlHigh |= SDRAM__P2D_EN;
  59191. + else
  59192. + dunitCtrlHigh &= ~SDRAM__P2D_EN;
  59193. +
  59194. + if(busClk > MV_BOARD_SYSCLK_267MHZ)
  59195. + dunitCtrlHigh |= (SDRAM__WR_MESH_DELAY_EN | SDRAM__PUP_ZERO_SKEW_EN | SDRAM__ADD_HALF_FCC_EN);
  59196. +
  59197. + /* If ECC support we turn on D2P sample */
  59198. + dunitCtrlHigh &= ~SDRAM__D2P_EN; /* Clear D2P bit */
  59199. + if (( pBankInfo->errorCheckType ) && (busClk > MV_BOARD_SYSCLK_267MHZ))
  59200. + dunitCtrlHigh |= SDRAM__D2P_EN;
  59201. +
  59202. + return dunitCtrlHigh;
  59203. +}
  59204. +
  59205. +/*******************************************************************************
  59206. +* sdramAddrCtrlRegCalc - Calculate sdram address control register
  59207. +*
  59208. +* DESCRIPTION: Calculate sdram address control register optimized value based
  59209. +* on the bank info parameters and the minCas.
  59210. +*
  59211. +* INPUT:
  59212. +* pBankInfo - sdram bank parameters
  59213. +*
  59214. +* OUTPUT:
  59215. +* None
  59216. +*
  59217. +* RETURN:
  59218. +* sdram address control reg value.
  59219. +*
  59220. +*******************************************************************************/
  59221. +static MV_U32 sdramAddrCtrlRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_DRAM_BANK_INFO *pBankInfoDIMM1)
  59222. +{
  59223. + MV_U32 addrCtrl = 0;
  59224. +
  59225. + if (pBankInfoDIMM1->size)
  59226. + {
  59227. + switch (pBankInfoDIMM1->sdramWidth)
  59228. + {
  59229. + case 4: /* memory is x4 */
  59230. + mvOsOutput("sdramAddrCtrlRegCalc: Error - x4 not supported!\n");
  59231. + return -1;
  59232. + break;
  59233. + case 8: /* memory is x8 */
  59234. + addrCtrl |= SDRAM_ADDRSEL_X8(2) | SDRAM_ADDRSEL_X8(3);
  59235. + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device DIMM2 width x8\n"));
  59236. + break;
  59237. + case 16:
  59238. + addrCtrl |= SDRAM_ADDRSEL_X16(2) | SDRAM_ADDRSEL_X16(3);
  59239. + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device DIMM2 width x16\n"));
  59240. + break;
  59241. + default: /* memory width unsupported */
  59242. + mvOsOutput("sdramAddrCtrlRegCalc: ERR. DRAM chip width is unknown!\n");
  59243. + return -1;
  59244. + }
  59245. + }
  59246. +
  59247. + switch (pBankInfo->sdramWidth)
  59248. + {
  59249. + case 4: /* memory is x4 */
  59250. + mvOsOutput("sdramAddrCtrlRegCalc: Error - x4 not supported!\n");
  59251. + return -1;
  59252. + break;
  59253. + case 8: /* memory is x8 */
  59254. + addrCtrl |= SDRAM_ADDRSEL_X8(0) | SDRAM_ADDRSEL_X8(1);
  59255. + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device width x8\n"));
  59256. + break;
  59257. + case 16:
  59258. + addrCtrl |= SDRAM_ADDRSEL_X16(0) | SDRAM_ADDRSEL_X16(1);
  59259. + DB(mvOsPrintf("sdramAddrCtrlRegCalc: sdramAddrCtrlRegCalc SDRAM device width x16\n"));
  59260. + break;
  59261. + default: /* memory width unsupported */
  59262. + mvOsOutput("sdramAddrCtrlRegCalc: ERR. DRAM chip width is unknown!\n");
  59263. + return -1;
  59264. + }
  59265. +
  59266. + /* Note that density is in MB units */
  59267. + switch (pBankInfo->deviceDensity)
  59268. + {
  59269. + case 256: /* 256 Mbit */
  59270. + DB(mvOsPrintf("DRAM Device Density 256Mbit\n"));
  59271. + addrCtrl |= SDRAM_DSIZE_256Mb(0) | SDRAM_DSIZE_256Mb(1);
  59272. + break;
  59273. + case 512: /* 512 Mbit */
  59274. + DB(mvOsPrintf("DRAM Device Density 512Mbit\n"));
  59275. + addrCtrl |= SDRAM_DSIZE_512Mb(0) | SDRAM_DSIZE_512Mb(1);
  59276. + break;
  59277. + case 1024: /* 1 Gbit */
  59278. + DB(mvOsPrintf("DRAM Device Density 1Gbit\n"));
  59279. + addrCtrl |= SDRAM_DSIZE_1Gb(0) | SDRAM_DSIZE_1Gb(1);
  59280. + break;
  59281. + case 2048: /* 2 Gbit */
  59282. + DB(mvOsPrintf("DRAM Device Density 2Gbit\n"));
  59283. + addrCtrl |= SDRAM_DSIZE_2Gb(0) | SDRAM_DSIZE_2Gb(1);
  59284. + break;
  59285. + default:
  59286. + mvOsOutput("Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
  59287. + pBankInfo->deviceDensity);
  59288. + return -1;
  59289. + }
  59290. +
  59291. + if (pBankInfoDIMM1->size)
  59292. + {
  59293. + switch (pBankInfoDIMM1->deviceDensity)
  59294. + {
  59295. + case 256: /* 256 Mbit */
  59296. + DB(mvOsPrintf("DIMM2: DRAM Device Density 256Mbit\n"));
  59297. + addrCtrl |= SDRAM_DSIZE_256Mb(2) | SDRAM_DSIZE_256Mb(3);
  59298. + break;
  59299. + case 512: /* 512 Mbit */
  59300. + DB(mvOsPrintf("DIMM2: DRAM Device Density 512Mbit\n"));
  59301. + addrCtrl |= SDRAM_DSIZE_512Mb(2) | SDRAM_DSIZE_512Mb(3);
  59302. + break;
  59303. + case 1024: /* 1 Gbit */
  59304. + DB(mvOsPrintf("DIMM2: DRAM Device Density 1Gbit\n"));
  59305. + addrCtrl |= SDRAM_DSIZE_1Gb(2) | SDRAM_DSIZE_1Gb(3);
  59306. + break;
  59307. + case 2048: /* 2 Gbit */
  59308. + DB(mvOsPrintf("DIMM2: DRAM Device Density 2Gbit\n"));
  59309. + addrCtrl |= SDRAM_DSIZE_2Gb(2) | SDRAM_DSIZE_2Gb(3);
  59310. + break;
  59311. + default:
  59312. + mvOsOutput("DIMM2: Dram: sdramAddrCtrl unsupported RAM-Device size %d\n",
  59313. + pBankInfoDIMM1->deviceDensity);
  59314. + return -1;
  59315. + }
  59316. + }
  59317. + /* SDRAM address control */
  59318. + DB(mvOsPrintf("Dram: setting sdram address control with: %x \n", addrCtrl));
  59319. +
  59320. + return addrCtrl;
  59321. +}
  59322. +
  59323. +/*******************************************************************************
  59324. +* sdramTimeCtrlLowRegCalc - Calculate sdram timing control low register
  59325. +*
  59326. +* DESCRIPTION:
  59327. +* This function calculates sdram timing control low register
  59328. +* optimized value based on the bank info parameters and the minCas.
  59329. +*
  59330. +* INPUT:
  59331. +* pBankInfo - sdram bank parameters
  59332. +* minCas - minimum CAS supported.
  59333. +* busClk - Bus clock
  59334. +*
  59335. +* OUTPUT:
  59336. +* None
  59337. +*
  59338. +* RETURN:
  59339. +* sdram timing control low reg value.
  59340. +*
  59341. +*******************************************************************************/
  59342. +static MV_U32 sdramTimeCtrlLowRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 minCas, MV_U32 busClk)
  59343. +{
  59344. + MV_U32 tRp = 0;
  59345. + MV_U32 tRrd = 0;
  59346. + MV_U32 tRcd = 0;
  59347. + MV_U32 tRas = 0;
  59348. + MV_U32 tWr = 0;
  59349. + MV_U32 tWtr = 0;
  59350. + MV_U32 tRtp = 0;
  59351. + MV_U32 timeCtrlLow = 0;
  59352. +
  59353. + MV_U32 bankNum;
  59354. +
  59355. + busClk = busClk / 1000000; /* In MHz */
  59356. +
  59357. + /* Scan all DRAM banks to find maximum timing values */
  59358. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  59359. + {
  59360. + tRp = MV_MAX(tRp, pBankInfo[bankNum].minRowPrechargeTime);
  59361. + tRrd = MV_MAX(tRrd, pBankInfo[bankNum].minRowActiveToRowActive);
  59362. + tRcd = MV_MAX(tRcd, pBankInfo[bankNum].minRasToCasDelay);
  59363. + tRas = MV_MAX(tRas, pBankInfo[bankNum].minRasPulseWidth);
  59364. + }
  59365. +
  59366. + /* Extract timing (in ns) from SPD value. We ignore the tenth ns part. */
  59367. + /* by shifting the data two bits right. */
  59368. + tRp = tRp >> 2; /* For example 0x50 -> 20ns */
  59369. + tRrd = tRrd >> 2;
  59370. + tRcd = tRcd >> 2;
  59371. +
  59372. + /* Extract clock cycles from time parameter. We need to round up */
  59373. + tRp = ((busClk * tRp) / 1000) + (((busClk * tRp) % 1000) ? 1 : 0);
  59374. + DB(mvOsPrintf("Dram Timing Low: tRp = %d ", tRp));
  59375. + tRrd = ((busClk * tRrd) / 1000) + (((busClk * tRrd) % 1000) ? 1 : 0);
  59376. + /* JEDEC min reqeirments tRrd = 2 */
  59377. + if (tRrd < 2)
  59378. + tRrd = 2;
  59379. + DB(mvOsPrintf("tRrd = %d ", tRrd));
  59380. + tRcd = ((busClk * tRcd) / 1000) + (((busClk * tRcd) % 1000) ? 1 : 0);
  59381. + DB(mvOsPrintf("tRcd = %d ", tRcd));
  59382. + tRas = ((busClk * tRas) / 1000) + (((busClk * tRas) % 1000) ? 1 : 0);
  59383. + DB(mvOsPrintf("tRas = %d ", tRas));
  59384. +
  59385. + /* tWr and tWtr is different for DDR1 and DDR2. tRtp is only for DDR2 */
  59386. + /* Scan all DRAM banks to find maximum timing values */
  59387. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  59388. + {
  59389. + tWr = MV_MAX(tWr, pBankInfo[bankNum].minWriteRecoveryTime);
  59390. + tWtr = MV_MAX(tWtr, pBankInfo[bankNum].minWriteToReadCmdDelay);
  59391. + tRtp = MV_MAX(tRtp, pBankInfo[bankNum].minReadToPrechCmdDelay);
  59392. + }
  59393. +
  59394. + /* Extract timing (in ns) from SPD value. We ignore the tenth ns */
  59395. + /* part by shifting the data two bits right. */
  59396. + tWr = tWr >> 2; /* For example 0x50 -> 20ns */
  59397. + tWtr = tWtr >> 2;
  59398. + tRtp = tRtp >> 2;
  59399. + /* Extract clock cycles from time parameter. We need to round up */
  59400. + tWr = ((busClk * tWr) / 1000) + (((busClk * tWr) % 1000) ? 1 : 0);
  59401. + DB(mvOsPrintf("tWr = %d ", tWr));
  59402. + tWtr = ((busClk * tWtr) / 1000) + (((busClk * tWtr) % 1000) ? 1 : 0);
  59403. + /* JEDEC min reqeirments tWtr = 2 */
  59404. + if (tWtr < 2)
  59405. + tWtr = 2;
  59406. + DB(mvOsPrintf("tWtr = %d ", tWtr));
  59407. + tRtp = ((busClk * tRtp) / 1000) + (((busClk * tRtp) % 1000) ? 1 : 0);
  59408. + /* JEDEC min reqeirments tRtp = 2 */
  59409. + if (tRtp < 2)
  59410. + tRtp = 2;
  59411. + DB(mvOsPrintf("tRtp = %d ", tRtp));
  59412. +
  59413. + /* Note: value of 0 in register means one cycle, 1 means two and so on */
  59414. + timeCtrlLow = (((tRp - 1) << SDRAM_TRP_OFFS) |
  59415. + ((tRrd - 1) << SDRAM_TRRD_OFFS) |
  59416. + ((tRcd - 1) << SDRAM_TRCD_OFFS) |
  59417. + (((tRas - 1) << SDRAM_TRAS_OFFS) & SDRAM_TRAS_MASK)|
  59418. + ((tWr - 1) << SDRAM_TWR_OFFS) |
  59419. + ((tWtr - 1) << SDRAM_TWTR_OFFS) |
  59420. + ((tRtp - 1) << SDRAM_TRTP_OFFS));
  59421. +
  59422. + /* Check extended tRas bit */
  59423. + if ((tRas - 1) & BIT4)
  59424. + timeCtrlLow |= (1 << SDRAM_EXT_TRAS_OFFS);
  59425. +
  59426. + return timeCtrlLow;
  59427. +}
  59428. +
  59429. +/*******************************************************************************
  59430. +* sdramTimeCtrlHighRegCalc - Calculate sdram timing control high register
  59431. +*
  59432. +* DESCRIPTION:
  59433. +* This function calculates sdram timing control high register
  59434. +* optimized value based on the bank info parameters and the bus clock.
  59435. +*
  59436. +* INPUT:
  59437. +* pBankInfo - sdram bank parameters
  59438. +* busClk - Bus clock
  59439. +*
  59440. +* OUTPUT:
  59441. +* None
  59442. +*
  59443. +* RETURN:
  59444. +* sdram timing control high reg value.
  59445. +*
  59446. +*******************************************************************************/
  59447. +static MV_U32 sdramTimeCtrlHighRegCalc(MV_DRAM_BANK_INFO *pBankInfo, MV_U32 busClk)
  59448. +{
  59449. + MV_U32 tRfc;
  59450. + MV_U32 timingHigh;
  59451. + MV_U32 timeNs = 0;
  59452. + MV_U32 bankNum;
  59453. +
  59454. + busClk = busClk / 1000000; /* In MHz */
  59455. +
  59456. + /* Set DDR timing high register static configuration bits */
  59457. + timingHigh = MV_REG_READ(SDRAM_TIMING_CTRL_HIGH_REG);
  59458. +
  59459. + /* Set DDR timing high register default value */
  59460. + timingHigh |= SDRAM_TIMING_CTRL_HIGH_REG_DV;
  59461. +
  59462. + /* Clear tRfc field */
  59463. + timingHigh &= ~SDRAM_TRFC_MASK;
  59464. +
  59465. + /* Scan all DRAM banks to find maximum timing values */
  59466. + for (bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  59467. + {
  59468. + timeNs = MV_MAX(timeNs, pBankInfo[bankNum].minRefreshToActiveCmd);
  59469. + DB(mvOsPrintf("Dram: Timing High: minRefreshToActiveCmd = %d\n",
  59470. + pBankInfo[bankNum].minRefreshToActiveCmd));
  59471. + }
  59472. + if(busClk >= 333 && mvCtrlModelGet() == MV_78XX0_A1_REV)
  59473. + {
  59474. + timingHigh |= 0x1 << SDRAM_TR2W_W2R_OFFS;
  59475. + }
  59476. +
  59477. + tRfc = ((busClk * timeNs) / 1000) + (((busClk * timeNs) % 1000) ? 1 : 0);
  59478. + /* Note: value of 0 in register means one cycle, 1 means two and so on */
  59479. + DB(mvOsPrintf("Dram: Timing High: tRfc = %d\n", tRfc));
  59480. + timingHigh |= (((tRfc - 1) & SDRAM_TRFC_MASK) << SDRAM_TRFC_OFFS);
  59481. + DB(mvOsPrintf("Dram: Timing High: tRfc = %d\n", tRfc));
  59482. +
  59483. + /* SDRAM timing high */
  59484. + DB(mvOsPrintf("Dram: setting timing high with: %x \n", timingHigh));
  59485. +
  59486. + return timingHigh;
  59487. +}
  59488. +/*******************************************************************************
  59489. +* sdramDDr2OdtConfig - Set DRAM DDR2 On Die Termination registers.
  59490. +*
  59491. +* DESCRIPTION:
  59492. +* This function config DDR2 On Die Termination (ODT) registers.
  59493. +*
  59494. +* INPUT:
  59495. +* pBankInfo - bank info parameters.
  59496. +*
  59497. +* OUTPUT:
  59498. +* None
  59499. +*
  59500. +* RETURN:
  59501. +* None
  59502. +*******************************************************************************/
  59503. +static void sdramDDr2OdtConfig(MV_DRAM_BANK_INFO *pBankInfo)
  59504. +{
  59505. + MV_U32 populateBanks = 0;
  59506. + MV_U32 odtCtrlLow, odtCtrlHigh, dunitOdtCtrl;
  59507. + int bankNum;
  59508. +
  59509. + /* Represent the populate banks in binary form */
  59510. + for(bankNum = 0; bankNum < MV_DRAM_MAX_CS; bankNum++)
  59511. + {
  59512. + if (0 != pBankInfo[bankNum].size)
  59513. + {
  59514. + populateBanks |= (1 << bankNum);
  59515. + }
  59516. + }
  59517. +
  59518. + switch(populateBanks)
  59519. + {
  59520. + case(BANK_PRESENT_CS0):
  59521. + case(BANK_PRESENT_CS0_CS1):
  59522. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS1_DV;
  59523. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS1_DV;
  59524. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS1_DV;
  59525. + break;
  59526. + case(BANK_PRESENT_CS0_CS2):
  59527. + case(BANK_PRESENT_CS0_CS1_CS2):
  59528. + case(BANK_PRESENT_CS0_CS2_CS3):
  59529. + case(BANK_PRESENT_CS0_CS2_CS3_CS4):
  59530. + odtCtrlLow = DDR2_ODT_CTRL_LOW_CS0_CS1_CS2_CS3_DV;
  59531. + odtCtrlHigh = DDR2_ODT_CTRL_HIGH_CS0_CS1_CS2_CS3_DV;
  59532. + dunitOdtCtrl = DDR2_DUNIT_ODT_CTRL_CS0_CS1_CS2_CS3_DV;
  59533. + break;
  59534. + default:
  59535. + DB(mvOsPrintf("sdramDDr2OdtConfig: Invalid DRAM bank presence\n"));
  59536. + return;
  59537. + }
  59538. + /* DDR2 SDRAM ODT ctrl low */
  59539. + DB(mvOsPrintf("Dram: DDR2 setting ODT ctrl low with: %x \n", odtCtrlLow));
  59540. + MV_REG_WRITE(DRAM_BUF_REG7, odtCtrlLow);
  59541. +
  59542. + /* DDR2 SDRAM ODT ctrl high */
  59543. + DB(mvOsPrintf("Dram: DDR2 setting ODT ctrl high with: %x \n", odtCtrlHigh));
  59544. + MV_REG_WRITE(DRAM_BUF_REG8, odtCtrlHigh);
  59545. +
  59546. + /* DDR2 DUNIT ODT ctrl */
  59547. + if ( ((mvCtrlModelGet() == MV_78XX0_DEV_ID) && (mvCtrlRevGet() == MV_78XX0_Y0_REV)) ||
  59548. + (mvCtrlModelGet() == MV_76100_DEV_ID) ||
  59549. + (mvCtrlModelGet() == MV_78100_DEV_ID) ||
  59550. + (mvCtrlModelGet() == MV_78200_DEV_ID) )
  59551. + dunitOdtCtrl &= ~(BIT9|BIT8); /* Clear ODT always on */
  59552. +
  59553. + DB(mvOsPrintf("DUNIT: DDR2 setting ODT ctrl with: %x \n", dunitOdtCtrl));
  59554. + MV_REG_WRITE(DRAM_BUF_REG9, dunitOdtCtrl);
  59555. + return;
  59556. +}
  59557. +/*******************************************************************************
  59558. +* sdramDdr2TimeLoRegCalc - Set DDR2 DRAM Timing Low registers.
  59559. +*
  59560. +* DESCRIPTION:
  59561. +* This function config DDR2 DRAM Timing low registers.
  59562. +*
  59563. +* INPUT:
  59564. +* minCas - minimum CAS supported.
  59565. +*
  59566. +* OUTPUT:
  59567. +* None
  59568. +*
  59569. +* RETURN:
  59570. +* DDR2 sdram timing low reg value.
  59571. +*******************************************************************************/
  59572. +static MV_U32 sdramDdr2TimeLoRegCalc(MV_U32 minCas)
  59573. +{
  59574. + MV_U8 cl = -1;
  59575. + MV_U32 ddr2TimeLoReg;
  59576. +
  59577. + /* read and clear the feilds we are going to set */
  59578. + ddr2TimeLoReg = MV_REG_READ(SDRAM_DDR2_TIMING_LO_REG);
  59579. + ddr2TimeLoReg &= ~(SD2TLR_TODT_ON_RD_MASK |
  59580. + SD2TLR_TODT_OFF_RD_MASK |
  59581. + SD2TLR_TODT_ON_CTRL_RD_MASK |
  59582. + SD2TLR_TODT_OFF_CTRL_RD_MASK);
  59583. +
  59584. + if( minCas == DDR2_CL_3 )
  59585. + {
  59586. + cl = 3;
  59587. + }
  59588. + else if( minCas == DDR2_CL_4 )
  59589. + {
  59590. + cl = 4;
  59591. + }
  59592. + else if( minCas == DDR2_CL_5 )
  59593. + {
  59594. + cl = 5;
  59595. + }
  59596. + else if( minCas == DDR2_CL_6 )
  59597. + {
  59598. + cl = 6;
  59599. + }
  59600. + else
  59601. + {
  59602. + DB(mvOsPrintf("sdramDdr2TimeLoRegCalc: CAS latency %d unsupported. using CAS latency 4\n",
  59603. + minCas));
  59604. + cl = 4;
  59605. + }
  59606. +
  59607. + ddr2TimeLoReg |= ((cl-3) << SD2TLR_TODT_ON_RD_OFFS);
  59608. + ddr2TimeLoReg |= ( cl << SD2TLR_TODT_OFF_RD_OFFS);
  59609. + ddr2TimeLoReg |= ( cl << SD2TLR_TODT_ON_CTRL_RD_OFFS);
  59610. + ddr2TimeLoReg |= ((cl+3) << SD2TLR_TODT_OFF_CTRL_RD_OFFS);
  59611. +
  59612. + /* DDR2 SDRAM timing low */
  59613. + DB(mvOsPrintf("Dram: DDR2 setting timing low with: %x \n", ddr2TimeLoReg));
  59614. +
  59615. + return ddr2TimeLoReg;
  59616. +}
  59617. +
  59618. +/*******************************************************************************
  59619. +* sdramDdr2TimeHiRegCalc - Set DDR2 DRAM Timing High registers.
  59620. +*
  59621. +* DESCRIPTION:
  59622. +* This function config DDR2 DRAM Timing high registers.
  59623. +*
  59624. +* INPUT:
  59625. +* minCas - minimum CAS supported.
  59626. +*
  59627. +* OUTPUT:
  59628. +* None
  59629. +*
  59630. +* RETURN:
  59631. +* DDR2 sdram timing high reg value.
  59632. +*******************************************************************************/
  59633. +static MV_U32 sdramDdr2TimeHiRegCalc(MV_U32 minCas)
  59634. +{
  59635. + MV_U8 cl = -1;
  59636. + MV_U32 ddr2TimeHiReg;
  59637. +
  59638. + /* read and clear the feilds we are going to set */
  59639. + ddr2TimeHiReg = MV_REG_READ(SDRAM_DDR2_TIMING_HI_REG);
  59640. + ddr2TimeHiReg &= ~(SD2THR_TODT_ON_WR_MASK |
  59641. + SD2THR_TODT_OFF_WR_MASK |
  59642. + SD2THR_TODT_ON_CTRL_WR_MASK |
  59643. + SD2THR_TODT_OFF_CTRL_WR_MASK);
  59644. +
  59645. + if( minCas == DDR2_CL_3 )
  59646. + {
  59647. + cl = 3;
  59648. + }
  59649. + else if( minCas == DDR2_CL_4 )
  59650. + {
  59651. + cl = 4;
  59652. + }
  59653. + else if( minCas == DDR2_CL_5 )
  59654. + {
  59655. + cl = 5;
  59656. + }
  59657. + else if( minCas == DDR2_CL_6 )
  59658. + {
  59659. + cl = 6;
  59660. + }
  59661. + else
  59662. + {
  59663. + mvOsOutput("sdramDdr2TimeHiRegCalc: CAS latency %d unsupported. using CAS latency 4\n",
  59664. + minCas);
  59665. + cl = 4;
  59666. + }
  59667. +
  59668. + ddr2TimeHiReg |= ((cl-3) << SD2THR_TODT_ON_WR_OFFS);
  59669. + ddr2TimeHiReg |= ( cl << SD2THR_TODT_OFF_WR_OFFS);
  59670. + ddr2TimeHiReg |= ( cl << SD2THR_TODT_ON_CTRL_WR_OFFS);
  59671. + ddr2TimeHiReg |= ((cl+3) << SD2THR_TODT_OFF_CTRL_WR_OFFS);
  59672. +
  59673. + /* DDR2 SDRAM timin high */
  59674. + DB(mvOsPrintf("Dram: DDR2 setting timing high with: %x \n", ddr2TimeHiReg));
  59675. +
  59676. + return ddr2TimeHiReg;
  59677. +}
  59678. +#endif
  59679. +
  59680. +/*******************************************************************************
  59681. +* mvDramIfCalGet - Get CAS Latency
  59682. +*
  59683. +* DESCRIPTION:
  59684. +* This function get the CAS Latency.
  59685. +*
  59686. +* INPUT:
  59687. +* None
  59688. +*
  59689. +* OUTPUT:
  59690. +* None
  59691. +*
  59692. +* RETURN:
  59693. +* CAS latency times 10 (to avoid using floating point).
  59694. +*
  59695. +*******************************************************************************/
  59696. +MV_U32 mvDramIfCalGet(void)
  59697. +{
  59698. + MV_U32 sdramCasLat, casLatMask;
  59699. +
  59700. + casLatMask = (MV_REG_READ(SDRAM_MODE_REG) & SDRAM_CL_MASK);
  59701. +
  59702. + switch (casLatMask)
  59703. + {
  59704. + case SDRAM_DDR2_CL_3:
  59705. + sdramCasLat = 30;
  59706. + break;
  59707. + case SDRAM_DDR2_CL_4:
  59708. + sdramCasLat = 40;
  59709. + break;
  59710. + case SDRAM_DDR2_CL_5:
  59711. + sdramCasLat = 50;
  59712. + break;
  59713. + case SDRAM_DDR2_CL_6:
  59714. + sdramCasLat = 60;
  59715. + break;
  59716. + default:
  59717. + mvOsOutput("mvDramIfCalGet: Err, unknown DDR2 CAL\n");
  59718. + return -1;
  59719. + }
  59720. +
  59721. + return sdramCasLat;
  59722. +}
  59723. +
  59724. +
  59725. +/*******************************************************************************
  59726. +* mvDramIfSelfRefreshSet - Put the dram in self refresh mode -
  59727. +*
  59728. +* DESCRIPTION:
  59729. +* add support in power management.
  59730. +*
  59731. +*
  59732. +* INPUT:
  59733. +* None
  59734. +*
  59735. +* OUTPUT:
  59736. +* None
  59737. +*
  59738. +* RETURN:
  59739. +* None
  59740. +*
  59741. +*******************************************************************************/
  59742. +
  59743. +MV_VOID mvDramIfSelfRefreshSet()
  59744. +{
  59745. + MV_U32 operReg;
  59746. +
  59747. + operReg = MV_REG_READ(SDRAM_OPERATION_REG);
  59748. + MV_REG_WRITE(SDRAM_OPERATION_REG ,operReg |SDRAM_CMD_SLF_RFRSH);
  59749. + /* Read until register is reset to 0 */
  59750. + while(MV_REG_READ(SDRAM_OPERATION_REG));
  59751. +}
  59752. +/*******************************************************************************
  59753. +* mvDramIfDimGetSPDversion - return DIMM SPD version.
  59754. +*
  59755. +* DESCRIPTION:
  59756. +* This function prints the DRAM controller information.
  59757. +*
  59758. +* INPUT:
  59759. +* None.
  59760. +*
  59761. +* OUTPUT:
  59762. +* None.
  59763. +*
  59764. +* RETURN:
  59765. +* None.
  59766. +*
  59767. +*******************************************************************************/
  59768. +static void mvDramIfDimGetSPDversion(MV_U32 *pMajor, MV_U32 *pMinor, MV_U32 bankNum)
  59769. +{
  59770. + MV_DIMM_INFO dimmInfo;
  59771. + if (bankNum >= MV_DRAM_MAX_CS )
  59772. + {
  59773. + DB(mvOsPrintf("Dram: mvDramIfDimGetSPDversion bad params \n"));
  59774. + return ;
  59775. + }
  59776. + memset(&dimmInfo,0,sizeof(dimmInfo));
  59777. + if ( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
  59778. + {
  59779. + DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
  59780. + return ;
  59781. + }
  59782. + *pMajor = dimmInfo.spdRawData[DIMM_SPD_VERSION]/10;
  59783. + *pMinor = dimmInfo.spdRawData[DIMM_SPD_VERSION]%10;
  59784. +}
  59785. +/*******************************************************************************
  59786. +* mvDramIfShow - Show DRAM controller information.
  59787. +*
  59788. +* DESCRIPTION:
  59789. +* This function prints the DRAM controller information.
  59790. +*
  59791. +* INPUT:
  59792. +* None.
  59793. +*
  59794. +* OUTPUT:
  59795. +* None.
  59796. +*
  59797. +* RETURN:
  59798. +* None.
  59799. +*
  59800. +*******************************************************************************/
  59801. +void mvDramIfShow(void)
  59802. +{
  59803. + int i, sdramCasLat, sdramCsSize;
  59804. + MV_U32 Major=0, Minor=0;
  59805. +
  59806. + mvOsOutput("DRAM Controller info:\n");
  59807. +
  59808. + mvOsOutput("Total DRAM ");
  59809. + mvSizePrint(mvDramIfSizeGet());
  59810. + mvOsOutput("\n");
  59811. +
  59812. + for(i = 0; i < MV_DRAM_MAX_CS; i++)
  59813. + {
  59814. + sdramCsSize = mvDramIfBankSizeGet(i);
  59815. + if (sdramCsSize)
  59816. + {
  59817. + if (0 == (i & 1))
  59818. + {
  59819. + mvDramIfDimGetSPDversion(&Major, &Minor,i);
  59820. + mvOsOutput("DIMM %d version %d.%d\n", i/2, Major, Minor);
  59821. + }
  59822. + mvOsOutput("\tDRAM CS[%d] ", i);
  59823. + mvSizePrint(sdramCsSize);
  59824. + mvOsOutput("\n");
  59825. + }
  59826. + }
  59827. + sdramCasLat = mvDramIfCalGet();
  59828. +
  59829. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_ECC_EN)
  59830. + {
  59831. + mvOsOutput("ECC enabled, ");
  59832. + }
  59833. + else
  59834. + {
  59835. + mvOsOutput("ECC Disabled, ");
  59836. + }
  59837. +
  59838. + if (MV_REG_READ(SDRAM_CONFIG_REG) & SDRAM_REGISTERED)
  59839. + {
  59840. + mvOsOutput("Registered DIMM\n");
  59841. + }
  59842. + else
  59843. + {
  59844. + mvOsOutput("Non registered DIMM\n");
  59845. + }
  59846. +
  59847. + mvOsOutput("Configured CAS Latency %d.%d\n", sdramCasLat/10, sdramCasLat%10);
  59848. +}
  59849. +/*******************************************************************************
  59850. +* mvDramIfGetFirstCS - find the DRAM bank on the lower address
  59851. +*
  59852. +*
  59853. +* DESCRIPTION:
  59854. +* This function return the fisrt CS on address 0
  59855. +*
  59856. +* INPUT:
  59857. +* None.
  59858. +*
  59859. +* OUTPUT:
  59860. +* None.
  59861. +*
  59862. +* RETURN:
  59863. +* SDRAM_CS0 or SDRAM_CS2
  59864. +*
  59865. +*******************************************************************************/
  59866. +MV_U32 mvDramIfGetFirstCS(void)
  59867. +{
  59868. + MV_DRAM_BANK_INFO bankInfo[MV_DRAM_MAX_CS];
  59869. +
  59870. + if (DRAM_CS_Order[0] == N_A)
  59871. + {
  59872. + mvDramBankInfoGet(SDRAM_CS0, &bankInfo[SDRAM_CS0]);
  59873. +#ifdef MV_INCLUDE_SDRAM_CS2
  59874. + mvDramBankInfoGet(SDRAM_CS2, &bankInfo[SDRAM_CS2]);
  59875. +#endif
  59876. +
  59877. +#ifdef MV_INCLUDE_SDRAM_CS2
  59878. + if (bankInfo[SDRAM_CS0].size < bankInfo[SDRAM_CS2].size)
  59879. + {
  59880. + DRAM_CS_Order[0] = SDRAM_CS2;
  59881. + DRAM_CS_Order[1] = SDRAM_CS3;
  59882. + DRAM_CS_Order[2] = SDRAM_CS0;
  59883. + DRAM_CS_Order[3] = SDRAM_CS1;
  59884. +
  59885. + return SDRAM_CS2;
  59886. + }
  59887. +#endif
  59888. + DRAM_CS_Order[0] = SDRAM_CS0;
  59889. + DRAM_CS_Order[1] = SDRAM_CS1;
  59890. +#ifdef MV_INCLUDE_SDRAM_CS2
  59891. + DRAM_CS_Order[2] = SDRAM_CS2;
  59892. + DRAM_CS_Order[3] = SDRAM_CS3;
  59893. +#endif
  59894. + return SDRAM_CS0;
  59895. + }
  59896. + return DRAM_CS_Order[0];
  59897. +}
  59898. +/*******************************************************************************
  59899. +* mvDramIfGetCSorder -
  59900. +*
  59901. +*
  59902. +* DESCRIPTION:
  59903. +* This function return the fisrt CS on address 0
  59904. +*
  59905. +* INPUT:
  59906. +* CS number.
  59907. +*
  59908. +* OUTPUT:
  59909. +* CS order.
  59910. +*
  59911. +* RETURN:
  59912. +* SDRAM_CS0 or SDRAM_CS2
  59913. +*
  59914. +* NOTE: mvDramIfGetFirstCS must be caled before this subroutine
  59915. +*******************************************************************************/
  59916. +MV_U32 mvDramIfGetCSorder(MV_U32 csOrder )
  59917. +{
  59918. + return DRAM_CS_Order[csOrder];
  59919. +}
  59920. +
  59921. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h
  59922. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h 1970-01-01 01:00:00.000000000 +0100
  59923. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIf.h 2011-08-01 14:38:19.000000000 +0200
  59924. @@ -0,0 +1,172 @@
  59925. +/*******************************************************************************
  59926. +Copyright (C) Marvell International Ltd. and its affiliates
  59927. +
  59928. +This software file (the "File") is owned and distributed by Marvell
  59929. +International Ltd. and/or its affiliates ("Marvell") under the following
  59930. +alternative licensing terms. Once you have made an election to distribute the
  59931. +File under one of the following license alternatives, please (i) delete this
  59932. +introductory statement regarding license alternatives, (ii) delete the two
  59933. +license alternatives that you have not elected to use and (iii) preserve the
  59934. +Marvell copyright notice above.
  59935. +
  59936. +********************************************************************************
  59937. +Marvell Commercial License Option
  59938. +
  59939. +If you received this File from Marvell and you have entered into a commercial
  59940. +license agreement (a "Commercial License") with Marvell, the File is licensed
  59941. +to you under the terms of the applicable Commercial License.
  59942. +
  59943. +********************************************************************************
  59944. +Marvell GPL License Option
  59945. +
  59946. +If you received this File from Marvell, you may opt to use, redistribute and/or
  59947. +modify this File in accordance with the terms and conditions of the General
  59948. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  59949. +available along with the File in the license.txt file or by writing to the Free
  59950. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  59951. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  59952. +
  59953. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  59954. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  59955. +DISCLAIMED. The GPL License provides additional details about this warranty
  59956. +disclaimer.
  59957. +********************************************************************************
  59958. +Marvell BSD License Option
  59959. +
  59960. +If you received this File from Marvell, you may opt to use, redistribute and/or
  59961. +modify this File under the following licensing terms.
  59962. +Redistribution and use in source and binary forms, with or without modification,
  59963. +are permitted provided that the following conditions are met:
  59964. +
  59965. + * Redistributions of source code must retain the above copyright notice,
  59966. + this list of conditions and the following disclaimer.
  59967. +
  59968. + * Redistributions in binary form must reproduce the above copyright
  59969. + notice, this list of conditions and the following disclaimer in the
  59970. + documentation and/or other materials provided with the distribution.
  59971. +
  59972. + * Neither the name of Marvell nor the names of its contributors may be
  59973. + used to endorse or promote products derived from this software without
  59974. + specific prior written permission.
  59975. +
  59976. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  59977. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  59978. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  59979. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  59980. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  59981. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  59982. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  59983. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  59984. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  59985. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  59986. +
  59987. +*******************************************************************************/
  59988. +
  59989. +
  59990. +#ifndef __INCmvDramIfh
  59991. +#define __INCmvDramIfh
  59992. +
  59993. +#ifdef __cplusplus
  59994. +extern "C" {
  59995. +#endif /* __cplusplus */
  59996. +
  59997. +/* includes */
  59998. +#include "ddr2/mvDramIfRegs.h"
  59999. +#include "ddr2/mvDramIfConfig.h"
  60000. +#include "ctrlEnv/mvCtrlEnvLib.h"
  60001. +
  60002. +/* defines */
  60003. +/* DRAM Timing parameters */
  60004. +#define SDRAM_TWR 15 /* ns tWr */
  60005. +#define SDRAM_TRFC_64_512M_AT_200MHZ 70 /* ns tRfc for dens 64-512 @ 200MHz */
  60006. +#define SDRAM_TRFC_64_512M 75 /* ns tRfc for dens 64-512 */
  60007. +#define SDRAM_TRFC_1G 120 /* ns tRfc for dens 1GB */
  60008. +#define SDRAM_TR2R_CYC 1 /* cycle for tR2r */
  60009. +
  60010. +#define CAL_AUTO_DETECT 0 /* Do not force CAS latancy (mvDramIfDetect) */
  60011. +#define ECC_DISABLE 1 /* Force ECC to Disable */
  60012. +#define ECC_ENABLE 0 /* Force ECC to ENABLE */
  60013. +/* typedefs */
  60014. +
  60015. +/* enumeration for memory types */
  60016. +typedef enum _mvMemoryType
  60017. +{
  60018. + MEM_TYPE_SDRAM,
  60019. + MEM_TYPE_DDR1,
  60020. + MEM_TYPE_DDR2
  60021. +}MV_MEMORY_TYPE;
  60022. +
  60023. +/* enumeration for DDR2 supported CAS Latencies */
  60024. +typedef enum _mvDimmDdr2Cas
  60025. +{
  60026. + DDR2_CL_3 = 0x08,
  60027. + DDR2_CL_4 = 0x10,
  60028. + DDR2_CL_5 = 0x20,
  60029. + DDR2_CL_6 = 0x40,
  60030. + DDR2_CL_FAULT
  60031. +} MV_DIMM_DDR2_CAS;
  60032. +
  60033. +
  60034. +typedef struct _mvDramBankInfo
  60035. +{
  60036. + MV_MEMORY_TYPE memoryType; /* DDR1, DDR2 or SDRAM */
  60037. +
  60038. + /* DIMM dimensions */
  60039. + MV_U32 numOfRowAddr;
  60040. + MV_U32 numOfColAddr;
  60041. + MV_U32 dataWidth;
  60042. + MV_U32 errorCheckType; /* ECC , PARITY..*/
  60043. + MV_U32 sdramWidth; /* 4,8,16 or 32 */
  60044. + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
  60045. + MV_U32 burstLengthSupported;
  60046. + MV_U32 numOfBanksOnEachDevice;
  60047. + MV_U32 suportedCasLatencies;
  60048. + MV_U32 refreshInterval;
  60049. +
  60050. + /* DIMM timing parameters */
  60051. + MV_U32 minCycleTimeAtMaxCasLatPs;
  60052. + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
  60053. + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
  60054. + MV_U32 minRowPrechargeTime;
  60055. + MV_U32 minRowActiveToRowActive;
  60056. + MV_U32 minRasToCasDelay;
  60057. + MV_U32 minRasPulseWidth;
  60058. + MV_U32 minWriteRecoveryTime; /* DDR2 only */
  60059. + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
  60060. + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
  60061. + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
  60062. +
  60063. + /* Parameters calculated from the extracted DIMM information */
  60064. + MV_U32 size;
  60065. + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit */
  60066. + MV_U32 numberOfDevices;
  60067. +
  60068. + /* DIMM attributes (MV_TRUE for yes) */
  60069. + MV_BOOL registeredAddrAndControlInputs;
  60070. + MV_BOOL registeredDQMBinputs;
  60071. +
  60072. +}MV_DRAM_BANK_INFO;
  60073. +
  60074. +#include "ddr2/spd/mvSpd.h"
  60075. +
  60076. +/* mvDramIf.h API list */
  60077. +MV_VOID mvDramIfBasicAsmInit(MV_VOID);
  60078. +MV_STATUS mvDramIfDetect(MV_U32 forcedCl, MV_BOOL eccDisable);
  60079. +MV_VOID _mvDramIfConfig(int entryNum);
  60080. +
  60081. +MV_U32 mvDramIfBankSizeGet(MV_U32 bankNum);
  60082. +MV_U32 mvDramIfBankBaseGet(MV_U32 bankNum);
  60083. +MV_U32 mvDramIfSizeGet(MV_VOID);
  60084. +MV_U32 mvDramIfCalGet(void);
  60085. +MV_STATUS mvDramIfSingleBitErrThresholdSet(MV_U32 threshold);
  60086. +MV_VOID mvDramIfSelfRefreshSet(void);
  60087. +void mvDramIfShow(void);
  60088. +MV_U32 mvDramIfGetFirstCS(void);
  60089. +MV_U32 mvDramIfGetCSorder(MV_U32 csOrder );
  60090. +MV_U32 mvDramCsSizeGet(MV_U32 csNum);
  60091. +
  60092. +#ifdef __cplusplus
  60093. +}
  60094. +#endif /* __cplusplus */
  60095. +
  60096. +#endif /* __INCmvDramIfh */
  60097. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h
  60098. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h 1970-01-01 01:00:00.000000000 +0100
  60099. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfConfig.h 2011-08-01 14:38:19.000000000 +0200
  60100. @@ -0,0 +1,157 @@
  60101. +/*******************************************************************************
  60102. +Copyright (C) Marvell International Ltd. and its affiliates
  60103. +
  60104. +This software file (the "File") is owned and distributed by Marvell
  60105. +International Ltd. and/or its affiliates ("Marvell") under the following
  60106. +alternative licensing terms. Once you have made an election to distribute the
  60107. +File under one of the following license alternatives, please (i) delete this
  60108. +introductory statement regarding license alternatives, (ii) delete the two
  60109. +license alternatives that you have not elected to use and (iii) preserve the
  60110. +Marvell copyright notice above.
  60111. +
  60112. +********************************************************************************
  60113. +Marvell Commercial License Option
  60114. +
  60115. +If you received this File from Marvell and you have entered into a commercial
  60116. +license agreement (a "Commercial License") with Marvell, the File is licensed
  60117. +to you under the terms of the applicable Commercial License.
  60118. +
  60119. +********************************************************************************
  60120. +Marvell GPL License Option
  60121. +
  60122. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60123. +modify this File in accordance with the terms and conditions of the General
  60124. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  60125. +available along with the File in the license.txt file or by writing to the Free
  60126. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  60127. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  60128. +
  60129. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  60130. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  60131. +DISCLAIMED. The GPL License provides additional details about this warranty
  60132. +disclaimer.
  60133. +********************************************************************************
  60134. +Marvell BSD License Option
  60135. +
  60136. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60137. +modify this File under the following licensing terms.
  60138. +Redistribution and use in source and binary forms, with or without modification,
  60139. +are permitted provided that the following conditions are met:
  60140. +
  60141. + * Redistributions of source code must retain the above copyright notice,
  60142. + this list of conditions and the following disclaimer.
  60143. +
  60144. + * Redistributions in binary form must reproduce the above copyright
  60145. + notice, this list of conditions and the following disclaimer in the
  60146. + documentation and/or other materials provided with the distribution.
  60147. +
  60148. + * Neither the name of Marvell nor the names of its contributors may be
  60149. + used to endorse or promote products derived from this software without
  60150. + specific prior written permission.
  60151. +
  60152. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  60153. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  60154. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  60155. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  60156. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  60157. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  60158. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  60159. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  60160. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  60161. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  60162. +
  60163. +*******************************************************************************/
  60164. +
  60165. +
  60166. +#ifndef __INCmvDramIfConfigh
  60167. +#define __INCmvDramIfConfigh
  60168. +
  60169. +#ifdef __cplusplus
  60170. +extern "C" {
  60171. +#endif /* __cplusplus */
  60172. +
  60173. +/* includes */
  60174. +
  60175. +/* defines */
  60176. +
  60177. +/* registers defaults values */
  60178. +
  60179. +#define SDRAM_CONFIG_DV (SDRAM_SRMODE_DRAM | BIT25 | BIT30)
  60180. +
  60181. +#define SDRAM_DUNIT_CTRL_LOW_DDR2_DV \
  60182. + (SDRAM_SRCLK_KEPT | \
  60183. + SDRAM_CLK1DRV_NORMAL | \
  60184. + (BIT28 | BIT29))
  60185. +
  60186. +#define SDRAM_ADDR_CTRL_DV 2
  60187. +
  60188. +#define SDRAM_TIMING_CTRL_LOW_REG_DV \
  60189. + ((0x2 << SDRAM_TRCD_OFFS) | \
  60190. + (0x2 << SDRAM_TRP_OFFS) | \
  60191. + (0x1 << SDRAM_TWR_OFFS) | \
  60192. + (0x0 << SDRAM_TWTR_OFFS) | \
  60193. + (0x5 << SDRAM_TRAS_OFFS) | \
  60194. + (0x1 << SDRAM_TRRD_OFFS))
  60195. +
  60196. +/* Note: value of 0 in register means one cycle, 1 means two and so on */
  60197. +#define SDRAM_TIMING_CTRL_HIGH_REG_DV \
  60198. + ((0x0 << SDRAM_TR2R_OFFS) | \
  60199. + (0x0 << SDRAM_TR2W_W2R_OFFS) | \
  60200. + (0x1 << SDRAM_TW2W_OFFS))
  60201. +
  60202. +#define SDRAM_OPEN_PAGES_CTRL_REG_DV SDRAM_OPEN_PAGE_EN
  60203. +
  60204. +/* Presence Ctrl Low Ctrl High Dunit Ctrl Ext Mode */
  60205. +/* CS0 0x84210000 0x00000000 0x0000780F 0x00000440 */
  60206. +/* CS0+CS1 0x84210000 0x00000000 0x0000780F 0x00000440 */
  60207. +/* CS0+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  60208. +/* CS0+CS1+CS2 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  60209. +/* CS0+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  60210. +/* CS0+CS1+CS2+CS3 0x030C030C 0x00000000 0x0000740F 0x00000404 */
  60211. +
  60212. +#define DDR2_ODT_CTRL_LOW_CS0_CS1_DV 0x84210000
  60213. +#define DDR2_ODT_CTRL_HIGH_CS0_CS1_DV 0x00000000
  60214. +#define DDR2_DUNIT_ODT_CTRL_CS0_CS1_DV 0x0000E80F
  60215. +#ifdef MV78XX0
  60216. +#define DDR_SDRAM_EXT_MODE_CS0_CS1_DV 0x00000040
  60217. +#else
  60218. +#define DDR_SDRAM_EXT_MODE_CS0_CS1_DV 0x00000440
  60219. +#endif
  60220. +
  60221. +#define DDR2_ODT_CTRL_LOW_CS0_CS1_CS2_CS3_DV 0x030C030C
  60222. +#define DDR2_ODT_CTRL_HIGH_CS0_CS1_CS2_CS3_DV 0x00000000
  60223. +#define DDR2_DUNIT_ODT_CTRL_CS0_CS1_CS2_CS3_DV 0x0000F40F
  60224. +#ifdef MV78XX0
  60225. +#define DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV 0x00000004
  60226. +#define DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV 0x00000044
  60227. +#else
  60228. +#define DDR_SDRAM_EXT_MODE_CS0_CS1_CS2_CS3_DV 0x00000404
  60229. +#define DDR_SDRAM_EXT_MODE_FAST_CS0_CS1_CS2_CS3_DV 0x00000444
  60230. +#endif
  60231. +
  60232. +/* DDR SDRAM Adderss/Control and Data Pads Calibration default values */
  60233. +#define DDR2_ADDR_CTRL_PAD_STRENGTH_TYPICAL_DV \
  60234. + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  60235. +
  60236. +#define DDR2_DATA_PAD_STRENGTH_TYPICAL_DV \
  60237. + (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  60238. +
  60239. +/* DDR SDRAM Mode Register default value */
  60240. +#define DDR2_MODE_REG_DV (SDRAM_BURST_LEN_4 | SDRAM_WR_3_CYC)
  60241. +/* DDR SDRAM Timing parameter default values */
  60242. +#define SDRAM_TIMING_CTRL_LOW_REG_DEFAULT 0x33136552
  60243. +#define SDRAM_TRFC_DEFAULT_VALUE 0x34
  60244. +#define SDRAM_TRFC_DEFAULT SDRAM_TRFC_DEFAULT_VALUE
  60245. +#define SDRAM_TW2W_DEFALT (0x1 << SDRAM_TW2W_OFFS)
  60246. +
  60247. +#define SDRAM_TIMING_CTRL_HIGH_REG_DEFAULT (SDRAM_TRFC_DEFAULT | SDRAM_TW2W_DEFALT)
  60248. +
  60249. +#define SDRAM_FTDLL_REG_DEFAULT_LEFT 0x88C800
  60250. +#define SDRAM_FTDLL_REG_DEFAULT_RIGHT 0x88C800
  60251. +#define SDRAM_FTDLL_REG_DEFAULT_UP 0x88C800
  60252. +
  60253. +#ifdef __cplusplus
  60254. +}
  60255. +#endif /* __cplusplus */
  60256. +
  60257. +#endif /* __INCmvDramIfh */
  60258. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h
  60259. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h 1970-01-01 01:00:00.000000000 +0100
  60260. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfRegs.h 2011-08-01 14:38:19.000000000 +0200
  60261. @@ -0,0 +1,423 @@
  60262. +/*******************************************************************************
  60263. +Copyright (C) Marvell International Ltd. and its affiliates
  60264. +
  60265. +This software file (the "File") is owned and distributed by Marvell
  60266. +International Ltd. and/or its affiliates ("Marvell") under the following
  60267. +alternative licensing terms. Once you have made an election to distribute the
  60268. +File under one of the following license alternatives, please (i) delete this
  60269. +introductory statement regarding license alternatives, (ii) delete the two
  60270. +license alternatives that you have not elected to use and (iii) preserve the
  60271. +Marvell copyright notice above.
  60272. +
  60273. +********************************************************************************
  60274. +Marvell Commercial License Option
  60275. +
  60276. +If you received this File from Marvell and you have entered into a commercial
  60277. +license agreement (a "Commercial License") with Marvell, the File is licensed
  60278. +to you under the terms of the applicable Commercial License.
  60279. +
  60280. +********************************************************************************
  60281. +Marvell GPL License Option
  60282. +
  60283. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60284. +modify this File in accordance with the terms and conditions of the General
  60285. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  60286. +available along with the File in the license.txt file or by writing to the Free
  60287. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  60288. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  60289. +
  60290. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  60291. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  60292. +DISCLAIMED. The GPL License provides additional details about this warranty
  60293. +disclaimer.
  60294. +********************************************************************************
  60295. +Marvell BSD License Option
  60296. +
  60297. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60298. +modify this File under the following licensing terms.
  60299. +Redistribution and use in source and binary forms, with or without modification,
  60300. +are permitted provided that the following conditions are met:
  60301. +
  60302. + * Redistributions of source code must retain the above copyright notice,
  60303. + this list of conditions and the following disclaimer.
  60304. +
  60305. + * Redistributions in binary form must reproduce the above copyright
  60306. + notice, this list of conditions and the following disclaimer in the
  60307. + documentation and/or other materials provided with the distribution.
  60308. +
  60309. + * Neither the name of Marvell nor the names of its contributors may be
  60310. + used to endorse or promote products derived from this software without
  60311. + specific prior written permission.
  60312. +
  60313. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  60314. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  60315. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  60316. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  60317. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  60318. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  60319. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  60320. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  60321. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  60322. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  60323. +
  60324. +*******************************************************************************/
  60325. +
  60326. +#ifndef __INCmvDramIfRegsh
  60327. +#define __INCmvDramIfRegsh
  60328. +
  60329. +#ifdef __cplusplus
  60330. +extern "C" {
  60331. +#endif /* __cplusplus */
  60332. +
  60333. +/* DDR SDRAM Controller Address Decode Registers */
  60334. + /* SDRAM CSn Base Address Register (SCBAR) */
  60335. +#define SDRAM_BASE_ADDR_REG(cpu,csNum) (0x1500 + ((csNum) * 8) + ((cpu) * 0x70))
  60336. +#define SCBAR_BASE_OFFS 16
  60337. +#define SCBAR_BASE_MASK (0xffff << SCBAR_BASE_OFFS)
  60338. +#define SCBAR_BASE_ALIGNMENT 0x10000
  60339. +
  60340. +/* SDRAM CSn Size Register (SCSR) */
  60341. +#define SDRAM_SIZE_REG(cpu,csNum) (0x1504 + ((csNum) * 8) + ((cpu) * 0x70))
  60342. +#define SCSR_SIZE_OFFS 24
  60343. +#define SCSR_SIZE_MASK (0xff << SCSR_SIZE_OFFS)
  60344. +#define SCSR_SIZE_ALIGNMENT 0x1000000
  60345. +#define SCSR_WIN_EN BIT0
  60346. +
  60347. +/* configuration register */
  60348. +#define SDRAM_CONFIG_REG (DRAM_BASE + 0x1400)
  60349. +#define SDRAM_REFRESH_OFFS 0
  60350. +#define SDRAM_REFRESH_MAX 0x3FFF
  60351. +#define SDRAM_REFRESH_MASK (SDRAM_REFRESH_MAX << SDRAM_REFRESH_OFFS)
  60352. +#define SDRAM_DWIDTH_OFFS 15
  60353. +#define SDRAM_DWIDTH_MASK (1 << SDRAM_DWIDTH_OFFS)
  60354. +#define SDRAM_DWIDTH_32BIT (0 << SDRAM_DWIDTH_OFFS)
  60355. +#define SDRAM_DWIDTH_64BIT (1 << SDRAM_DWIDTH_OFFS)
  60356. +#define SDRAM_REGISTERED (1 << 17)
  60357. +#define SDRAM_ECC_OFFS 18
  60358. +#define SDRAM_ECC_MASK (1 << SDRAM_ECC_OFFS)
  60359. +#define SDRAM_ECC_DIS (0 << SDRAM_ECC_OFFS)
  60360. +#define SDRAM_ECC_EN (1 << SDRAM_ECC_OFFS)
  60361. +#define SDRAM_IERR_OFFS 19
  60362. +#define SDRAM_IERR_MASK (1 << SDRAM_IERR_OFFS)
  60363. +#define SDRAM_IERR_REPORTE (0 << SDRAM_IERR_OFFS)
  60364. +#define SDRAM_IERR_IGNORE (1 << SDRAM_IERR_OFFS)
  60365. +#define SDRAM_SRMODE_OFFS 24
  60366. +#define SDRAM_SRMODE_MASK (1 << SDRAM_SRMODE_OFFS)
  60367. +#define SDRAM_SRMODE_POWER (0 << SDRAM_SRMODE_OFFS)
  60368. +#define SDRAM_SRMODE_DRAM (1 << SDRAM_SRMODE_OFFS)
  60369. +
  60370. +/* dunit control low register */
  60371. +#define SDRAM_DUNIT_CTRL_REG (DRAM_BASE + 0x1404)
  60372. +#define SDRAM_2T_OFFS 4
  60373. +#define SDRAM_2T_MASK (1 << SDRAM_2T_OFFS)
  60374. +#define SDRAM_2T_MODE (1 << SDRAM_2T_OFFS)
  60375. +
  60376. +#define SDRAM_SRCLK_OFFS 5
  60377. +#define SDRAM_SRCLK_MASK (1 << SDRAM_SRCLK_OFFS)
  60378. +#define SDRAM_SRCLK_KEPT (0 << SDRAM_SRCLK_OFFS)
  60379. +#define SDRAM_SRCLK_GATED (1 << SDRAM_SRCLK_OFFS)
  60380. +#define SDRAM_CTRL_POS_OFFS 6
  60381. +#define SDRAM_CTRL_POS_MASK (1 << SDRAM_CTRL_POS_OFFS)
  60382. +#define SDRAM_CTRL_POS_FALL (0 << SDRAM_CTRL_POS_OFFS)
  60383. +#define SDRAM_CTRL_POS_RISE (1 << SDRAM_CTRL_POS_OFFS)
  60384. +#define SDRAM_CLK1DRV_OFFS 12
  60385. +#define SDRAM_CLK1DRV_MASK (1 << SDRAM_CLK1DRV_OFFS)
  60386. +#define SDRAM_CLK1DRV_HIGH_Z (0 << SDRAM_CLK1DRV_OFFS)
  60387. +#define SDRAM_CLK1DRV_NORMAL (1 << SDRAM_CLK1DRV_OFFS)
  60388. +#define SDRAM_CLK2DRV_OFFS 13
  60389. +#define SDRAM_CLK2DRV_MASK (1 << SDRAM_CLK2DRV_OFFS)
  60390. +#define SDRAM_CLK2DRV_HIGH_Z (0 << SDRAM_CLK2DRV_OFFS)
  60391. +#define SDRAM_CLK2DRV_NORMAL (1 << SDRAM_CLK2DRV_OFFS)
  60392. +#define SDRAM_SB_OUT_DEL_OFFS 20
  60393. +#define SDRAM_SB_OUT_DEL_MAX 0xf
  60394. +#define SDRAM_SB_OUT_MASK (SDRAM_SB_OUT_DEL_MAX<<SDRAM_SB_OUT_DEL_OFFS)
  60395. +#define SDRAM_SB_IN_DEL_OFFS 24
  60396. +#define SDRAM_SB_IN_DEL_MAX 0xf
  60397. +#define SDRAM_SB_IN_MASK (SDRAM_SB_IN_DEL_MAX<<SDRAM_SB_IN_DEL_OFFS)
  60398. +
  60399. +/* dunit control hight register */
  60400. +#define SDRAM_DUNIT_CTRL_HI_REG (DRAM_BASE + 0x1424)
  60401. +#define SDRAM__D2P_OFFS 7
  60402. +#define SDRAM__D2P_EN (1 << SDRAM__D2P_OFFS)
  60403. +#define SDRAM__P2D_OFFS 8
  60404. +#define SDRAM__P2D_EN (1 << SDRAM__P2D_OFFS)
  60405. +#define SDRAM__ADD_HALF_FCC_OFFS 9
  60406. +#define SDRAM__ADD_HALF_FCC_EN (1 << SDRAM__ADD_HALF_FCC_OFFS)
  60407. +#define SDRAM__PUP_ZERO_SKEW_OFFS 10
  60408. +#define SDRAM__PUP_ZERO_SKEW_EN (1 << SDRAM__PUP_ZERO_SKEW_OFFS)
  60409. +#define SDRAM__WR_MESH_DELAY_OFFS 11
  60410. +#define SDRAM__WR_MESH_DELAY_EN (1 << SDRAM__WR_MESH_DELAY_OFFS)
  60411. +
  60412. +/* sdram timing control low register */
  60413. +#define SDRAM_TIMING_CTRL_LOW_REG (DRAM_BASE + 0x1408)
  60414. +#define SDRAM_TRCD_OFFS 4
  60415. +#define SDRAM_TRCD_MASK (0xF << SDRAM_TRCD_OFFS)
  60416. +#define SDRAM_TRP_OFFS 8
  60417. +#define SDRAM_TRP_MASK (0xF << SDRAM_TRP_OFFS)
  60418. +#define SDRAM_TWR_OFFS 12
  60419. +#define SDRAM_TWR_MASK (0xF << SDRAM_TWR_OFFS)
  60420. +#define SDRAM_TWTR_OFFS 16
  60421. +#define SDRAM_TWTR_MASK (0xF << SDRAM_TWTR_OFFS)
  60422. +#define SDRAM_TRAS_OFFS 0
  60423. +#define SDRAM_TRAS_MASK (0xF << SDRAM_TRAS_OFFS)
  60424. +#define SDRAM_EXT_TRAS_OFFS 20
  60425. +#define SDRAM_EXT_TRAS_MASK (0x1 << SDRAM_EXT_TRAS_OFFS)
  60426. +#define SDRAM_TRRD_OFFS 24
  60427. +#define SDRAM_TRRD_MASK (0xF << SDRAM_TRRD_OFFS)
  60428. +#define SDRAM_TRTP_OFFS 28
  60429. +#define SDRAM_TRTP_MASK (0xF << SDRAM_TRTP_OFFS)
  60430. +#define SDRAM_TRTP_DDR1 (0x1 << SDRAM_TRTP_OFFS)
  60431. +
  60432. +/* sdram timing control high register */
  60433. +#define SDRAM_TIMING_CTRL_HIGH_REG (DRAM_BASE + 0x140c)
  60434. +#define SDRAM_TRFC_OFFS 0
  60435. +#define SDRAM_TRFC_MASK (0x3F << SDRAM_TRFC_OFFS)
  60436. +#define SDRAM_TR2R_OFFS 7
  60437. +#define SDRAM_TR2R_MASK (0x3 << SDRAM_TR2R_OFFS)
  60438. +#define SDRAM_TR2W_W2R_OFFS 9
  60439. +#define SDRAM_TR2W_W2R_MASK (0x3 << SDRAM_TR2W_W2R_OFFS)
  60440. +#define SDRAM_TW2W_OFFS 11
  60441. +#define SDRAM_TW2W_MASK (0x3 << SDRAM_TW2W_OFFS)
  60442. +
  60443. +/* sdram DDR2 timing low register (SD2TLR) */
  60444. +#define SDRAM_DDR2_TIMING_LO_REG (DRAM_BASE + 0x1428)
  60445. +#define SD2TLR_TODT_ON_RD_OFFS 4
  60446. +#define SD2TLR_TODT_ON_RD_MASK (0xF << SD2TLR_TODT_ON_RD_OFFS)
  60447. +#define SD2TLR_TODT_OFF_RD_OFFS 8
  60448. +#define SD2TLR_TODT_OFF_RD_MASK (0xF << SD2TLR_TODT_OFF_RD_OFFS)
  60449. +#define SD2TLR_TODT_ON_CTRL_RD_OFFS 12
  60450. +#define SD2TLR_TODT_ON_CTRL_RD_MASK (0xF << SD2TLR_TODT_ON_CTRL_RD_OFFS)
  60451. +#define SD2TLR_TODT_OFF_CTRL_RD_OFFS 16
  60452. +#define SD2TLR_TODT_OFF_CTRL_RD_MASK (0xF << SD2TLR_TODT_OFF_CTRL_RD_OFFS)
  60453. +
  60454. +/* sdram DDR2 timing high register (SD2TLR) */
  60455. +#define SDRAM_DDR2_TIMING_HI_REG (DRAM_BASE + 0x147C)
  60456. +#define SD2THR_TODT_ON_WR_OFFS 0
  60457. +#define SD2THR_TODT_ON_WR_MASK (0xF << SD2THR_TODT_ON_WR_OFFS)
  60458. +#define SD2THR_TODT_OFF_WR_OFFS 4
  60459. +#define SD2THR_TODT_OFF_WR_MASK (0xF << SD2THR_TODT_OFF_WR_OFFS)
  60460. +#define SD2THR_TODT_ON_CTRL_WR_OFFS 8
  60461. +#define SD2THR_TODT_ON_CTRL_WR_MASK (0xF << SD2THR_TODT_ON_CTRL_WR_OFFS)
  60462. +#define SD2THR_TODT_OFF_CTRL_WR_OFFS 12
  60463. +#define SD2THR_TODT_OFF_CTRL_WR_MASK (0xF << SD2THR_TODT_OFF_CTRL_WR_OFFS)
  60464. +
  60465. +/* address control register */
  60466. +#define SDRAM_ADDR_CTRL_REG (DRAM_BASE + 0x1410)
  60467. +#define SDRAM_ADDRSEL_OFFS(cs) (4 * (cs))
  60468. +#define SDRAM_ADDRSEL_MASK(cs) (0x3 << SDRAM_ADDRSEL_OFFS(cs))
  60469. +#define SDRAM_ADDRSEL_X8(cs) (0x0 << SDRAM_ADDRSEL_OFFS(cs))
  60470. +#define SDRAM_ADDRSEL_X16(cs) (0x1 << SDRAM_ADDRSEL_OFFS(cs))
  60471. +#define SDRAM_DSIZE_OFFS(cs) (2 + 4 * (cs))
  60472. +#define SDRAM_DSIZE_MASK(cs) (0x3 << SDRAM_DSIZE_OFFS(cs))
  60473. +#define SDRAM_DSIZE_256Mb(cs) (0x1 << SDRAM_DSIZE_OFFS(cs))
  60474. +#define SDRAM_DSIZE_512Mb(cs) (0x2 << SDRAM_DSIZE_OFFS(cs))
  60475. +#define SDRAM_DSIZE_1Gb(cs) (0x3 << SDRAM_DSIZE_OFFS(cs))
  60476. +#define SDRAM_DSIZE_2Gb(cs) (0x0 << SDRAM_DSIZE_OFFS(cs))
  60477. +
  60478. +/* SDRAM Open Pages Control registers */
  60479. +#define SDRAM_OPEN_PAGE_CTRL_REG (DRAM_BASE + 0x1414)
  60480. +#define SDRAM_OPEN_PAGE_EN (0 << 0)
  60481. +#define SDRAM_OPEN_PAGE_DIS (1 << 0)
  60482. +
  60483. +/* sdram opertion register */
  60484. +#define SDRAM_OPERATION_REG (DRAM_BASE + 0x1418)
  60485. +#define SDRAM_CMD_OFFS 0
  60486. +#define SDRAM_CMD_MASK (0xF << SDRAM_CMD_OFFS)
  60487. +#define SDRAM_CMD_NORMAL (0x0 << SDRAM_CMD_OFFS)
  60488. +#define SDRAM_CMD_PRECHARGE_ALL (0x1 << SDRAM_CMD_OFFS)
  60489. +#define SDRAM_CMD_REFRESH_ALL (0x2 << SDRAM_CMD_OFFS)
  60490. +#define SDRAM_CMD_REG_SET_CMD (0x3 << SDRAM_CMD_OFFS)
  60491. +#define SDRAM_CMD_EXT_MODE_SET (0x4 << SDRAM_CMD_OFFS)
  60492. +#define SDRAM_CMD_NOP (0x5 << SDRAM_CMD_OFFS)
  60493. +#define SDRAM_CMD_SLF_RFRSH (0x7 << SDRAM_CMD_OFFS)
  60494. +#define SDRAM_CMD_EMRS2_CMD (0x8 << SDRAM_CMD_OFFS)
  60495. +#define SDRAM_CMD_EMRS3_CMD (0x9 << SDRAM_CMD_OFFS)
  60496. +
  60497. +/* sdram mode register */
  60498. +#define SDRAM_MODE_REG (DRAM_BASE + 0x141c)
  60499. +#define SDRAM_BURST_LEN_OFFS 0
  60500. +#define SDRAM_BURST_LEN_MASK (0x7 << SDRAM_BURST_LEN_OFFS)
  60501. +#define SDRAM_BURST_LEN_4 (0x2 << SDRAM_BURST_LEN_OFFS)
  60502. +#define SDRAM_CL_OFFS 4
  60503. +#define SDRAM_CL_MASK (0x7 << SDRAM_CL_OFFS)
  60504. +#define SDRAM_DDR2_CL_3 (0x3 << SDRAM_CL_OFFS)
  60505. +#define SDRAM_DDR2_CL_4 (0x4 << SDRAM_CL_OFFS)
  60506. +#define SDRAM_DDR2_CL_5 (0x5 << SDRAM_CL_OFFS)
  60507. +#define SDRAM_DDR2_CL_6 (0x6 << SDRAM_CL_OFFS)
  60508. +
  60509. +#define SDRAM_TM_OFFS 7
  60510. +#define SDRAM_TM_MASK (1 << SDRAM_TM_OFFS)
  60511. +#define SDRAM_TM_NORMAL (0 << SDRAM_TM_OFFS)
  60512. +#define SDRAM_TM_TEST_MODE (1 << SDRAM_TM_OFFS)
  60513. +#define SDRAM_DLL_OFFS 8
  60514. +#define SDRAM_DLL_MASK (1 << SDRAM_DLL_OFFS)
  60515. +#define SDRAM_DLL_NORMAL (0 << SDRAM_DLL_OFFS)
  60516. +#define SDRAM_DLL_RESET (1 << SDRAM_DLL_OFFS)
  60517. +#define SDRAM_WR_OFFS 9
  60518. +#define SDRAM_WR_MAX 7
  60519. +#define SDRAM_WR_MASK (SDRAM_WR_MAX << SDRAM_WR_OFFS)
  60520. +#define SDRAM_WR_2_CYC (1 << SDRAM_WR_OFFS)
  60521. +#define SDRAM_WR_3_CYC (2 << SDRAM_WR_OFFS)
  60522. +#define SDRAM_WR_4_CYC (3 << SDRAM_WR_OFFS)
  60523. +#define SDRAM_WR_5_CYC (4 << SDRAM_WR_OFFS)
  60524. +#define SDRAM_WR_6_CYC (5 << SDRAM_WR_OFFS)
  60525. +#define SDRAM_PD_OFFS 12
  60526. +#define SDRAM_PD_MASK (1 << SDRAM_PD_OFFS)
  60527. +#define SDRAM_PD_FAST_EXIT (0 << SDRAM_PD_OFFS)
  60528. +#define SDRAM_PD_SLOW_EXIT (1 << SDRAM_PD_OFFS)
  60529. +
  60530. +/* DDR SDRAM Extended Mode register (DSEMR) */
  60531. +#define SDRAM_EXTENDED_MODE_REG (DRAM_BASE + 0x1420)
  60532. +#define DSEMR_DLL_ENABLE 0
  60533. +#define DSEMR_DLL_DISABLE 1
  60534. +#define DSEMR_DS_OFFS 1
  60535. +#define DSEMR_DS_MASK (1 << DSEMR_DS_OFFS)
  60536. +#define DSEMR_DS_NORMAL (0 << DSEMR_DS_OFFS)
  60537. +#define DSEMR_DS_REDUCED (1 << DSEMR_DS_OFFS)
  60538. +#define DSEMR_QOFF_OUTPUT_BUFF_EN (0 << 12)
  60539. +#define DSEMR_RTT0_OFFS 2
  60540. +#define DSEMR_RTT1_OFFS 6
  60541. +#define DSEMR_RTT_ODT_DISABLE ((0 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
  60542. +#define DSEMR_RTT_ODT_75_OHM ((1 << DSEMR_RTT0_OFFS)||(0 << DSEMR_RTT1_OFFS))
  60543. +#define DSEMR_RTT_ODT_150_OHM ((0 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))
  60544. +#define DSEMR_RTT_ODT_50_OHM ((1 << DSEMR_RTT0_OFFS)||(1 << DSEMR_RTT1_OFFS))
  60545. +#define DSEMR_DQS_OFFS 10
  60546. +#define DSEMR_DQS_MASK (1 << DSEMR_DQS_OFFS)
  60547. +#define DSEMR_DQS_DIFFERENTIAL (0 << DSEMR_DQS_OFFS)
  60548. +#define DSEMR_DQS_SINGLE_ENDED (1 << DSEMR_DQS_OFFS)
  60549. +#define DSEMR_RDQS_ENABLE (1 << 11)
  60550. +#define DSEMR_QOFF_OUTPUT_BUFF_EN (0 << 12)
  60551. +#define DSEMR_QOFF_OUTPUT_BUFF_DIS (1 << 12)
  60552. +
  60553. +/* DDR SDRAM Operation Control Register */
  60554. +#define SDRAM_OPERATION_CTRL_REG (DRAM_BASE + 0x142c)
  60555. +
  60556. +/* Dunit FTDLL Configuration Register */
  60557. +#define SDRAM_FTDLL_CONFIG_LEFT_REG (DRAM_BASE + 0x1484)
  60558. +#define SDRAM_FTDLL_CONFIG_RIGHT_REG (DRAM_BASE + 0x161C)
  60559. +#define SDRAM_FTDLL_CONFIG_UP_REG (DRAM_BASE + 0x1620)
  60560. +
  60561. +/* Pads Calibration register */
  60562. +#define SDRAM_ADDR_CTRL_PADS_CAL_REG (DRAM_BASE + 0x14c0)
  60563. +#define SDRAM_DATA_PADS_CAL_REG (DRAM_BASE + 0x14c4)
  60564. +#define SDRAM_DRVN_OFFS 0
  60565. +#define SDRAM_DRVN_MASK (0x3F << SDRAM_DRVN_OFFS)
  60566. +#define SDRAM_DRVP_OFFS 6
  60567. +#define SDRAM_DRVP_MASK (0x3F << SDRAM_DRVP_OFFS)
  60568. +#define SDRAM_PRE_DRIVER_STRENGTH_OFFS 12
  60569. +#define SDRAM_PRE_DRIVER_STRENGTH_MASK (3 << SDRAM_PRE_DRIVER_STRENGTH_OFFS)
  60570. +#define SDRAM_TUNE_EN BIT16
  60571. +#define SDRAM_LOCKN_OFFS 17
  60572. +#define SDRAM_LOCKN_MAKS (0x3F << SDRAM_LOCKN_OFFS)
  60573. +#define SDRAM_LOCKP_OFFS 23
  60574. +#define SDRAM_LOCKP_MAKS (0x3F << SDRAM_LOCKP_OFFS)
  60575. +#define SDRAM_WR_EN (1 << 31)
  60576. +
  60577. +/* DDR2 SDRAM ODT Control (Low) Register (DSOCLR) */
  60578. +#define DDR2_SDRAM_ODT_CTRL_LOW_REG (DRAM_BASE + 0x1494)
  60579. +#define DSOCLR_ODT_RD_OFFS(odtNum) (odtNum * 4)
  60580. +#define DSOCLR_ODT_RD_MASK(odtNum) (0xf << DSOCLR_ODT_RD_OFFS(odtNum))
  60581. +#define DSOCLR_ODT_RD(odtNum, bank) ((1 << bank) << DSOCLR_ODT_RD_OFFS(odtNum))
  60582. +#define DSOCLR_ODT_WR_OFFS(odtNum) (16 + (odtNum * 4))
  60583. +#define DSOCLR_ODT_WR_MASK(odtNum) (0xf << DSOCLR_ODT_WR_OFFS(odtNum))
  60584. +#define DSOCLR_ODT_WR(odtNum, bank) ((1 << bank) << DSOCLR_ODT_WR_OFFS(odtNum))
  60585. +
  60586. +/* DDR2 SDRAM ODT Control (High) Register (DSOCHR) */
  60587. +#define DDR2_SDRAM_ODT_CTRL_HIGH_REG (DRAM_BASE + 0x1498)
  60588. +/* Optional control values to DSOCHR_ODT_EN macro */
  60589. +#define DDR2_ODT_CTRL_DUNIT 0
  60590. +#define DDR2_ODT_CTRL_NEVER 1
  60591. +#define DDR2_ODT_CTRL_ALWAYS 3
  60592. +#define DSOCHR_ODT_EN_OFFS(odtNum) (odtNum * 2)
  60593. +#define DSOCHR_ODT_EN_MASK(odtNum) (0x3 << DSOCHR_ODT_EN_OFFS(odtNum))
  60594. +#define DSOCHR_ODT_EN(odtNum, ctrl) (ctrl << DSOCHR_ODT_EN_OFFS(odtNum))
  60595. +
  60596. +/* DDR2 Dunit ODT Control Register (DDOCR)*/
  60597. +#define DDR2_DUNIT_ODT_CONTROL_REG (DRAM_BASE + 0x149c)
  60598. +#define DDOCR_ODT_RD_OFFS 0
  60599. +#define DDOCR_ODT_RD_MASK (0xf << DDOCR_ODT_RD_OFFS)
  60600. +#define DDOCR_ODT_RD(bank) ((1 << bank) << DDOCR_ODT_RD_OFFS)
  60601. +#define DDOCR_ODT_WR_OFFS 4
  60602. +#define DDOCR_ODT_WR_MASK (0xf << DDOCR_ODT_WR_OFFS)
  60603. +#define DDOCR_ODT_WR(bank) ((1 << bank) << DDOCR_ODT_WR_OFFS)
  60604. +#define DSOCR_ODT_EN_OFFS 8
  60605. +#define DSOCR_ODT_EN_MASK (0x3 << DSOCR_ODT_EN_OFFS)
  60606. +/* For ctrl parameters see DDR2 SDRAM ODT Control (High) Register (0x1498) above. */
  60607. +#define DSOCR_ODT_EN(ctrl) (ctrl << DSOCR_ODT_EN_OFFS)
  60608. +#define DSOCR_ODT_SEL_DISABLE 0
  60609. +#define DSOCR_ODT_SEL_75_OHM 2
  60610. +#define DSOCR_ODT_SEL_150_OHM 1
  60611. +#define DSOCR_ODT_SEL_50_OHM 3
  60612. +#define DSOCR_DQ_ODT_SEL_OFFS 10
  60613. +#define DSOCR_DQ_ODT_SEL_MASK (0x3 << DSOCR_DQ_ODT_SEL_OFFS)
  60614. +#define DSOCR_DQ_ODT_SEL(odtSel) (odtSel << DSOCR_DQ_ODT_SEL_OFFS)
  60615. +#define DSOCR_ST_ODT_SEL_OFFS 12
  60616. +#define DSOCR_ST_ODT_SEL_MASK (0x3 << DSOCR_ST_ODT_SEL_OFFS)
  60617. +#define DSOCR_ST_ODT_SEL(odtSel) (odtSel << DSOCR_ST_ODT_SEL_OFFS)
  60618. +#define DSOCR_ST_ODT_EN (1 << 14)
  60619. +
  60620. +/* DDR SDRAM Initialization Control Register (DSICR) */
  60621. +#define DDR_SDRAM_INIT_CTRL_REG (DRAM_BASE + 0x1480)
  60622. +#define DSICR_INIT_EN (1 << 0)
  60623. +#define DSICR_T200_SET (1 << 8)
  60624. +
  60625. +/* sdram extended mode2 register (SEM2R) */
  60626. +#define SDRAM_EXTENDED_MODE2_REG (DRAM_BASE + 0x148C)
  60627. +#define SEM2R_EMRS2_DDR2_OFFS 0
  60628. +#define SEM2R_EMRS2_DDR2_MASK (0x7FFF << SEM2R_EMRS2_DDR2_OFFS)
  60629. +
  60630. +/* sdram extended mode3 register (SEM3R) */
  60631. +#define SDRAM_EXTENDED_MODE3_REG (DRAM_BASE + 0x1490)
  60632. +#define SEM3R_EMRS3_DDR2_OFFS 0
  60633. +#define SEM3R_EMRS3_DDR2_MASK (0x7FFF << SEM3R_EMRS3_DDR2_OFFS)
  60634. +
  60635. +/* sdram error registers */
  60636. +#define SDRAM_ERROR_CAUSE_REG (DRAM_BASE + 0x14d0)
  60637. +#define SDRAM_ERROR_MASK_REG (DRAM_BASE + 0x14d4)
  60638. +#define SDRAM_ERROR_DATA_LOW_REG (DRAM_BASE + 0x1444)
  60639. +#define SDRAM_ERROR_DATA_HIGH_REG (DRAM_BASE + 0x1440)
  60640. +#define SDRAM_ERROR_ADDR_REG (DRAM_BASE + 0x1450)
  60641. +#define SDRAM_ERROR_ECC_REG (DRAM_BASE + 0x1448)
  60642. +#define SDRAM_CALC_ECC_REG (DRAM_BASE + 0x144c)
  60643. +#define SDRAM_ECC_CONTROL_REG (DRAM_BASE + 0x1454)
  60644. +#define SDRAM_SINGLE_BIT_ERR_CNTR_REG (DRAM_BASE + 0x1458)
  60645. +#define SDRAM_DOUBLE_BIT_ERR_CNTR_REG (DRAM_BASE + 0x145c)
  60646. +
  60647. +/* SDRAM Error Cause Register (SECR) */
  60648. +#define SECR_SINGLE_BIT_ERR BIT0
  60649. +#define SECR_DOUBLE_BIT_ERR BIT1
  60650. +#define SECR_DATA_PATH_PARITY_ERR BIT2
  60651. +/* SDRAM Error Address Register (SEAR) */
  60652. +#define SEAR_ERR_TYPE_OFFS 0
  60653. +#define SEAR_ERR_TYPE_MASK (1 << SEAR_ERR_TYPE_OFFS)
  60654. +#define SEAR_ERR_TYPE_SINGLE 0
  60655. +#define SEAR_ERR_TYPE_DOUBLE (1 << SEAR_ERR_TYPE_OFFS)
  60656. +#define SEAR_ERR_CS_OFFS 1
  60657. +#define SEAR_ERR_CS_MASK (3 << SEAR_ERR_CS_OFFS)
  60658. +#define SEAR_ERR_CS(csNum) (csNum << SEAR_ERR_CS_OFFS)
  60659. +#define SEAR_ERR_ADDR_OFFS 3
  60660. +#define SEAR_ERR_ADDR_MASK (0x1FFFFFFF << SEAR_ERR_ADDR_OFFS)
  60661. +
  60662. +/* SDRAM ECC Control Register (SECR) */
  60663. +#define SECR_FORCEECC_OFFS 0
  60664. +#define SECR_FORCEECC_MASK (0xFF << SECR_FORCEECC_OFFS)
  60665. +#define SECR_FORCEEN_OFFS 8
  60666. +#define SECR_FORCEEN_MASK (1 << SECR_FORCEEN_OFFS)
  60667. +#define SECR_ECC_CALC_MASK (0 << SECR_FORCEEN_OFFS)
  60668. +#define SECR_ECC_USER_MASK (1 << SECR_FORCEEN_OFFS)
  60669. +#define SECR_PERRPROP_EN BIT9
  60670. +#define SECR_CNTMODE_OFFS 10
  60671. +#define SECR_CNTMODE_MASK (1 << SECR_CNTMODE_OFFS)
  60672. +#define SECR_ALL_IN_CS0 (0 << SECR_CNTMODE_OFFS)
  60673. +#define SECR_NORMAL_COUNTER (1 << SECR_CNTMODE_OFFS)
  60674. +#define SECR_THRECC_OFFS 16
  60675. +#define SECR_THRECC_MAX 0xFF
  60676. +#define SECR_THRECC_MASK (SECR_THRECC_MAX << SECR_THRECC_OFFS)
  60677. +#define SECR_THRECC(threshold) (threshold << SECR_THRECC_OFFS)
  60678. +
  60679. +
  60680. +#ifdef __cplusplus
  60681. +}
  60682. +#endif /* __cplusplus */
  60683. +
  60684. +#endif /* __INCmvDramIfRegsh */
  60685. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h
  60686. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h 1970-01-01 01:00:00.000000000 +0100
  60687. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/mvDramIfStaticInit.h 2011-08-01 14:38:19.000000000 +0200
  60688. @@ -0,0 +1,179 @@
  60689. +/*******************************************************************************
  60690. +Copyright (C) Marvell International Ltd. and its affiliates
  60691. +
  60692. +This software file (the "File") is owned and distributed by Marvell
  60693. +International Ltd. and/or its affiliates ("Marvell") under the following
  60694. +alternative licensing terms. Once you have made an election to distribute the
  60695. +File under one of the following license alternatives, please (i) delete this
  60696. +introductory statement regarding license alternatives, (ii) delete the two
  60697. +license alternatives that you have not elected to use and (iii) preserve the
  60698. +Marvell copyright notice above.
  60699. +
  60700. +********************************************************************************
  60701. +Marvell Commercial License Option
  60702. +
  60703. +If you received this File from Marvell and you have entered into a commercial
  60704. +license agreement (a "Commercial License") with Marvell, the File is licensed
  60705. +to you under the terms of the applicable Commercial License.
  60706. +
  60707. +********************************************************************************
  60708. +Marvell GPL License Option
  60709. +
  60710. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60711. +modify this File in accordance with the terms and conditions of the General
  60712. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  60713. +available along with the File in the license.txt file or by writing to the Free
  60714. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  60715. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  60716. +
  60717. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  60718. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  60719. +DISCLAIMED. The GPL License provides additional details about this warranty
  60720. +disclaimer.
  60721. +********************************************************************************
  60722. +Marvell BSD License Option
  60723. +
  60724. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60725. +modify this File under the following licensing terms.
  60726. +Redistribution and use in source and binary forms, with or without modification,
  60727. +are permitted provided that the following conditions are met:
  60728. +
  60729. + * Redistributions of source code must retain the above copyright notice,
  60730. + this list of conditions and the following disclaimer.
  60731. +
  60732. + * Redistributions in binary form must reproduce the above copyright
  60733. + notice, this list of conditions and the following disclaimer in the
  60734. + documentation and/or other materials provided with the distribution.
  60735. +
  60736. + * Neither the name of Marvell nor the names of its contributors may be
  60737. + used to endorse or promote products derived from this software without
  60738. + specific prior written permission.
  60739. +
  60740. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  60741. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  60742. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  60743. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  60744. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  60745. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  60746. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  60747. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  60748. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  60749. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  60750. +
  60751. +*******************************************************************************/
  60752. +
  60753. +
  60754. +#ifndef __INCmvDramIfStaticInith
  60755. +#define __INCmvDramIfStaticInith
  60756. +
  60757. +#ifdef MV_STATIC_DRAM_ON_BOARD
  60758. +#define STATIC_DRAM_BANK_1
  60759. +#undef STATIC_DRAM_BANK_2
  60760. +#undef STATIC_DRAM_BANK_3
  60761. +#undef STATIC_DRAM_BANK_4
  60762. +
  60763. +
  60764. +#ifdef MV_DIMM_TS256MLQ72V5U
  60765. +#define STATIC_DRAM_BANK_2
  60766. +#define STATIC_DRAM_BANK_3
  60767. +#undef STATIC_DRAM_BANK_4
  60768. +
  60769. +#define STATIC_SDRAM_CONFIG_REG 0x4724481A /* offset 0x1400 - DMA reg-0xf1000814 */
  60770. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0x37707450 /* offset 0x1404 - DMA reg-0xf100081c */
  60771. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x11A13330 /* offset 0x1408 - DMA reg-0xf1000824 */
  60772. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000601 /* offset 0x140c - DMA reg-0xf1000828 */
  60773. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00001CB2 /* offset 0x1410 - DMA reg-0xf1000820 */
  60774. +#define STATIC_SDRAM_MODE_REG 0x00000642 /* offset 0x141c - DMA reg-0xf1000818 */
  60775. +#define STATIC_SDRAM_ODT_CTRL_LOW 0x030C030C /* 0x1494 */
  60776. +#define STATIC_SDRAM_ODT_CTRL_HI 0x00000000 /* 0x1498 */
  60777. +#define STATIC_SDRAM_DUNIT_ODT_CTRL 0x0000740F /* 0x149c */
  60778. +#define STATIC_SDRAM_EXT_MODE 0x00000404 /* 0x1420 */
  60779. +#define STATIC_SDRAM_DDR2_TIMING_LO 0x00074410 /* 0x1428 */
  60780. +#define STATIC_SDRAM_DDR2_TIMING_HI 0x00007441 /* 0x147C */
  60781. +
  60782. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x3FFF /* size bank0 dimm0 - DMA reg-0xf1000810 */
  60783. +#define STATIC_SDRAM_RANK1_SIZE_DIMM0 0x3FFF /* size bank1 dimm0 */
  60784. +#define STATIC_SDRAM_RANK0_SIZE_DIMM1 0x3FFF /* size bank0 dimm1 */
  60785. +#define STATIC_SDRAM_RANK1_SIZE_DIMM1 0x0 /* size bank1 dimm1 */
  60786. +
  60787. +#endif /* TS256MLQ72V5U */
  60788. +
  60789. +
  60790. +#ifdef MV_MT9VDDT3272AG
  60791. +/* one DIMM 256M */
  60792. +#define STATIC_SDRAM_CONFIG_REG 0x5820040d /* offset 0x1400 - DMA reg-0xf1000814 */
  60793. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xC4000540 /* offset 0x1404 - DMA reg-0xf100081c */
  60794. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x01602220 /* offset 0x1408 - DMA reg-0xf1000824 */
  60795. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x0000000b /* offset 0x140c - DMA reg-0xf1000828 */
  60796. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000012 /* offset 0x1410 - DMA reg-0xf1000820 */
  60797. +#define STATIC_SDRAM_MODE_REG 0x00000062 /* offset 0x141c - DMA reg-0xf1000818 */
  60798. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x0fff /* size bank0 dimm0 - DMA reg-0xf1000810 */
  60799. +#define STATIC_SDRAM_RANK0_SIZE_DIMM1 0x0 /* size bank0 dimm1 */
  60800. +
  60801. +#endif /* MV_MT9VDDT3272AG */
  60802. +
  60803. +
  60804. +
  60805. +#ifdef MV_D27RB12P
  60806. +/*
  60807. +Two DIMM 512M + ECC enabled, Registered DIMM CAS Latency 2.5
  60808. +*/
  60809. +
  60810. +#define STATIC_SDRAM_CONFIG_REG 0x6826081E /* offset 0x1400 - DMA reg-0xf1000814 */
  60811. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xC5000540 /* offset 0x1404 - DMA reg-0xf100081c */
  60812. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x01501220 /* offset 0x1408 - DMA reg-0xf1000824 */
  60813. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000009 /* offset 0x140c - DMA reg-0xf1000828 */
  60814. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000012 /* offset 0x1410 - DMA reg-0xf1000820 */
  60815. +#define STATIC_SDRAM_MODE_REG 0x00000062 /* offset 0x141c - DMA reg-0xf1000818 */
  60816. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x0FFF /* size bank0 dimm0 - DMA reg-0xf1000810 */
  60817. +#define STATIC_SDRAM_RANK0_SIZE_DIMM1 0x0FFF /* size bank0 dimm1 */
  60818. +
  60819. +#define STATIC_DRAM_BANK_2
  60820. +
  60821. +#define STATIC_DRAM_BANK_3
  60822. +#define STATIC_DRAM_BANK_4
  60823. +
  60824. +#endif /* mv_D27RB12P */
  60825. +
  60826. +#ifdef RD_MV645XX
  60827. +
  60828. +#define STATIC_MEM_TYPE MEM_TYPE_DDR2
  60829. +#define STATIC_DIMM_INFO_BANK0_SIZE 256
  60830. +/* DDR2 boards 256 MB*/
  60831. +
  60832. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x00000fff /* size bank0 dimm0 - DMA reg-0xf1000810 */
  60833. +#define STATIC_SDRAM_CONFIG_REG 0x07190618
  60834. +#define STATIC_SDRAM_MODE_REG 0x00000432
  60835. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xf4a03440
  60836. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000022
  60837. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x11712220
  60838. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000504
  60839. +#define STATIC_SDRAM_ODT_CTRL_LOW 0x84210000
  60840. +#define STATIC_SDRAM_ODT_CTRL_HI 0x00000000
  60841. +#define STATIC_SDRAM_DUNIT_ODT_CTRL 0x0000780f
  60842. +#define STATIC_SDRAM_EXT_MODE 0x00000440
  60843. +#define STATIC_SDRAM_DDR2_TIMING_LO 0x00063300
  60844. +#define STATIC_SDRAM_DDR2_TIMING_HI 0x00006330
  60845. +#endif /* RD_MV645XX */
  60846. +
  60847. +#if MV_DIMM_M3783354CZ3_CE6
  60848. +
  60849. +#define STATIC_SDRAM_RANK0_SIZE_DIMM0 0x00000FFF /* 0x2010 size bank0 dimm0 - DMA reg-0xf1000810 */
  60850. +#define STATIC_SDRAM_CONFIG_REG 0x07190618 /* 0x1400 */
  60851. +#define STATIC_SDRAM_MODE_REG 0x00000432 /* 0x141c */
  60852. +#define STATIC_SDRAM_DUNIT_CTRL_REG 0xf4a03440 /* 0x1404 */
  60853. +#define STATIC_SDRAM_ADDR_CTRL_REG 0x00000022 /* 0x1410 */
  60854. +#define STATIC_SDRAM_TIMING_CTRL_LOW_REG 0x11712220 /* 0x1408 */
  60855. +#define STATIC_SDRAM_TIMING_CTRL_HIGH_REG 0x00000504 /* 0x140c */
  60856. +#define STATIC_SDRAM_ODT_CTRL_LOW 0x84210000 /* 0x1494 */
  60857. +#define STATIC_SDRAM_ODT_CTRL_HI 0x00000000 /* 0x1498 */
  60858. +#define STATIC_SDRAM_DUNIT_ODT_CTRL 0x0000780f /* 0x149c */
  60859. +#define STATIC_SDRAM_EXT_MODE 0x00000440 /* 0x1420 */
  60860. +#define STATIC_SDRAM_DDR2_TIMING_LO 0x00063300 /* 0x1428 */
  60861. +#define STATIC_SDRAM_DDR2_TIMING_HI 0x00006330 /* 0x147C */
  60862. +
  60863. +#endif /* MV_DIMM_M3783354CZ3_CE6 */
  60864. +
  60865. +#endif /* MV_STATIC_DRAM_ON_BOARD */
  60866. +#endif /* __INCmvDramIfStaticInith */
  60867. +
  60868. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c
  60869. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c 1970-01-01 01:00:00.000000000 +0100
  60870. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.c 2011-08-01 14:38:19.000000000 +0200
  60871. @@ -0,0 +1,1474 @@
  60872. +/*******************************************************************************
  60873. +Copyright (C) Marvell International Ltd. and its affiliates
  60874. +
  60875. +This software file (the "File") is owned and distributed by Marvell
  60876. +International Ltd. and/or its affiliates ("Marvell") under the following
  60877. +alternative licensing terms. Once you have made an election to distribute the
  60878. +File under one of the following license alternatives, please (i) delete this
  60879. +introductory statement regarding license alternatives, (ii) delete the two
  60880. +license alternatives that you have not elected to use and (iii) preserve the
  60881. +Marvell copyright notice above.
  60882. +
  60883. +********************************************************************************
  60884. +Marvell Commercial License Option
  60885. +
  60886. +If you received this File from Marvell and you have entered into a commercial
  60887. +license agreement (a "Commercial License") with Marvell, the File is licensed
  60888. +to you under the terms of the applicable Commercial License.
  60889. +
  60890. +********************************************************************************
  60891. +Marvell GPL License Option
  60892. +
  60893. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60894. +modify this File in accordance with the terms and conditions of the General
  60895. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  60896. +available along with the File in the license.txt file or by writing to the Free
  60897. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  60898. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  60899. +
  60900. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  60901. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  60902. +DISCLAIMED. The GPL License provides additional details about this warranty
  60903. +disclaimer.
  60904. +********************************************************************************
  60905. +Marvell BSD License Option
  60906. +
  60907. +If you received this File from Marvell, you may opt to use, redistribute and/or
  60908. +modify this File under the following licensing terms.
  60909. +Redistribution and use in source and binary forms, with or without modification,
  60910. +are permitted provided that the following conditions are met:
  60911. +
  60912. + * Redistributions of source code must retain the above copyright notice,
  60913. + this list of conditions and the following disclaimer.
  60914. +
  60915. + * Redistributions in binary form must reproduce the above copyright
  60916. + notice, this list of conditions and the following disclaimer in the
  60917. + documentation and/or other materials provided with the distribution.
  60918. +
  60919. + * Neither the name of Marvell nor the names of its contributors may be
  60920. + used to endorse or promote products derived from this software without
  60921. + specific prior written permission.
  60922. +
  60923. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  60924. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  60925. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  60926. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  60927. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  60928. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  60929. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  60930. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  60931. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  60932. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  60933. +
  60934. +*******************************************************************************/
  60935. +
  60936. +#include "ddr2/spd/mvSpd.h"
  60937. +#include "boardEnv/mvBoardEnvLib.h"
  60938. +
  60939. +/* #define MV_DEBUG */
  60940. +#ifdef MV_DEBUG
  60941. +#define DB(x) x
  60942. +#else
  60943. +#define DB(x)
  60944. +#endif
  60945. +
  60946. +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
  60947. + MV_DRAM_BANK_INFO *pBankInfo);
  60948. +static MV_U32 cas2ps(MV_U8 spd_byte);
  60949. +/*******************************************************************************
  60950. +* mvDramBankGet - Get the DRAM bank paramters.
  60951. +*
  60952. +* DESCRIPTION:
  60953. +* This function retrieves DRAM bank parameters as described in
  60954. +* DRAM_BANK_INFO struct to the controller DRAM unit. In case the board
  60955. +* has its DRAM on DIMMs it will use its EEPROM to extract SPD data
  60956. +* from it. Otherwise, if the DRAM is soldered on board, the function
  60957. +* should insert its bank information into MV_DRAM_BANK_INFO struct.
  60958. +*
  60959. +* INPUT:
  60960. +* bankNum - Board DRAM bank number.
  60961. +*
  60962. +* OUTPUT:
  60963. +* pBankInfo - DRAM bank information struct.
  60964. +*
  60965. +* RETURN:
  60966. +* MV_FAIL - Bank parameters could not be read.
  60967. +*
  60968. +*******************************************************************************/
  60969. +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo)
  60970. +{
  60971. + MV_DIMM_INFO dimmInfo;
  60972. +
  60973. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bank %d\n", bankNum));
  60974. + /* zero pBankInfo structure */
  60975. +
  60976. + if((NULL == pBankInfo) || (bankNum >= MV_DRAM_MAX_CS ))
  60977. + {
  60978. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
  60979. + return MV_BAD_PARAM;
  60980. + }
  60981. + memset(pBankInfo, 0, sizeof(*pBankInfo));
  60982. +
  60983. + if ( MV_OK != dimmSpdGet((MV_U32)(bankNum/2), &dimmInfo))
  60984. + {
  60985. + DB(mvOsPrintf("Dram: ERR dimmSpdGet failed to get dimm info \n"));
  60986. + return MV_FAIL;
  60987. + }
  60988. + if ((dimmInfo.numOfModuleBanks == 1) && ((bankNum % 2) == 1))
  60989. + {
  60990. + DB(mvOsPrintf("Dram: ERR dimmSpdGet. Can't find DIMM bank 2 \n"));
  60991. + return MV_FAIL;
  60992. + }
  60993. + /* convert Dimm info to Bank info */
  60994. + cpyDimm2BankInfo(&dimmInfo, pBankInfo);
  60995. + return MV_OK;
  60996. +}
  60997. +
  60998. +/*******************************************************************************
  60999. +* cpyDimm2BankInfo - Convert a Dimm info struct into a bank info struct.
  61000. +*
  61001. +* DESCRIPTION:
  61002. +* Convert a Dimm info struct into a bank info struct.
  61003. +*
  61004. +* INPUT:
  61005. +* pDimmInfo - DIMM information structure.
  61006. +*
  61007. +* OUTPUT:
  61008. +* pBankInfo - DRAM bank information struct.
  61009. +*
  61010. +* RETURN:
  61011. +* None.
  61012. +*
  61013. +*******************************************************************************/
  61014. +static MV_VOID cpyDimm2BankInfo(MV_DIMM_INFO *pDimmInfo,
  61015. + MV_DRAM_BANK_INFO *pBankInfo)
  61016. +{
  61017. + pBankInfo->memoryType = pDimmInfo->memoryType;
  61018. +
  61019. + /* DIMM dimensions */
  61020. + pBankInfo->numOfRowAddr = pDimmInfo->numOfRowAddr;
  61021. + pBankInfo->numOfColAddr = pDimmInfo->numOfColAddr;
  61022. + pBankInfo->dataWidth = pDimmInfo->dataWidth;
  61023. + pBankInfo->errorCheckType = pDimmInfo->errorCheckType;
  61024. + pBankInfo->sdramWidth = pDimmInfo->sdramWidth;
  61025. + pBankInfo->errorCheckDataWidth = pDimmInfo->errorCheckDataWidth;
  61026. + pBankInfo->numOfBanksOnEachDevice = pDimmInfo->numOfBanksOnEachDevice;
  61027. + pBankInfo->suportedCasLatencies = pDimmInfo->suportedCasLatencies;
  61028. + pBankInfo->refreshInterval = pDimmInfo->refreshInterval;
  61029. +
  61030. + /* DIMM timing parameters */
  61031. + pBankInfo->minCycleTimeAtMaxCasLatPs = pDimmInfo->minCycleTimeAtMaxCasLatPs;
  61032. + pBankInfo->minCycleTimeAtMaxCasLatMinus1Ps =
  61033. + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps;
  61034. + pBankInfo->minCycleTimeAtMaxCasLatMinus2Ps =
  61035. + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps;
  61036. +
  61037. + pBankInfo->minRowPrechargeTime = pDimmInfo->minRowPrechargeTime;
  61038. + pBankInfo->minRowActiveToRowActive = pDimmInfo->minRowActiveToRowActive;
  61039. + pBankInfo->minRasToCasDelay = pDimmInfo->minRasToCasDelay;
  61040. + pBankInfo->minRasPulseWidth = pDimmInfo->minRasPulseWidth;
  61041. + pBankInfo->minWriteRecoveryTime = pDimmInfo->minWriteRecoveryTime;
  61042. + pBankInfo->minWriteToReadCmdDelay = pDimmInfo->minWriteToReadCmdDelay;
  61043. + pBankInfo->minReadToPrechCmdDelay = pDimmInfo->minReadToPrechCmdDelay;
  61044. + pBankInfo->minRefreshToActiveCmd = pDimmInfo->minRefreshToActiveCmd;
  61045. +
  61046. + /* Parameters calculated from the extracted DIMM information */
  61047. + pBankInfo->size = pDimmInfo->size/pDimmInfo->numOfModuleBanks;
  61048. + pBankInfo->deviceDensity = pDimmInfo->deviceDensity;
  61049. + pBankInfo->numberOfDevices = pDimmInfo->numberOfDevices /
  61050. + pDimmInfo->numOfModuleBanks;
  61051. +
  61052. + /* DIMM attributes (MV_TRUE for yes) */
  61053. +
  61054. + if ((pDimmInfo->memoryType == MEM_TYPE_SDRAM) ||
  61055. + (pDimmInfo->memoryType == MEM_TYPE_DDR1) )
  61056. + {
  61057. + if (pDimmInfo->dimmAttributes & BIT1)
  61058. + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
  61059. + else
  61060. + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
  61061. + }
  61062. + else /* pDimmInfo->memoryType == MEM_TYPE_DDR2 */
  61063. + {
  61064. + if (pDimmInfo->dimmTypeInfo & (BIT0 | BIT4))
  61065. + pBankInfo->registeredAddrAndControlInputs = MV_TRUE;
  61066. + else
  61067. + pBankInfo->registeredAddrAndControlInputs = MV_FALSE;
  61068. + }
  61069. +
  61070. + return;
  61071. +}
  61072. +/*******************************************************************************
  61073. +* dimmSpdCpy - Cpy SPD parameters from dimm 0 to dimm 1.
  61074. +*
  61075. +* DESCRIPTION:
  61076. +* Read the DIMM SPD parameters from dimm 0 into dimm 1 SPD.
  61077. +*
  61078. +* INPUT:
  61079. +* None.
  61080. +*
  61081. +* OUTPUT:
  61082. +* None.
  61083. +*
  61084. +* RETURN:
  61085. +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
  61086. +*
  61087. +*******************************************************************************/
  61088. +MV_STATUS dimmSpdCpy(MV_VOID)
  61089. +{
  61090. + MV_U32 i;
  61091. + MV_U32 spdChecksum;
  61092. +
  61093. + MV_TWSI_SLAVE twsiSlave;
  61094. + MV_U8 data[SPD_SIZE];
  61095. +
  61096. + /* zero dimmInfo structure */
  61097. + memset(data, 0, SPD_SIZE);
  61098. +
  61099. + /* read the dimm eeprom */
  61100. + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
  61101. + twsiSlave.slaveAddr.address = MV_BOARD_DIMM0_I2C_ADDR;
  61102. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  61103. + twsiSlave.validOffset = MV_TRUE;
  61104. + twsiSlave.offset = 0;
  61105. + twsiSlave.moreThen256 = MV_FALSE;
  61106. +
  61107. + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, data, SPD_SIZE) )
  61108. + {
  61109. + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 0\n"));
  61110. + return MV_FAIL;
  61111. + }
  61112. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  61113. +
  61114. + /* calculate SPD checksum */
  61115. + spdChecksum = 0;
  61116. +
  61117. + for(i = 0 ; i <= 62 ; i++)
  61118. + {
  61119. + spdChecksum += data[i];
  61120. + }
  61121. +
  61122. + if ((spdChecksum & 0xff) != data[63])
  61123. + {
  61124. + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
  61125. + (MV_U32)(spdChecksum & 0xff), data[63]));
  61126. + }
  61127. + else
  61128. + {
  61129. + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
  61130. + }
  61131. +
  61132. + /* copy the SPD content 1:1 into the DIMM 1 SPD */
  61133. + twsiSlave.slaveAddr.address = MV_BOARD_DIMM1_I2C_ADDR;
  61134. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  61135. + twsiSlave.validOffset = MV_TRUE;
  61136. + twsiSlave.offset = 0;
  61137. + twsiSlave.moreThen256 = MV_FALSE;
  61138. +
  61139. + for(i = 0 ; i < SPD_SIZE ; i++)
  61140. + {
  61141. + twsiSlave.offset = i;
  61142. + if( MV_OK != mvTwsiWrite (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, &data[i], 1) )
  61143. + {
  61144. + mvOsPrintf("DRAM: ERR. no DIMM in dimmNum 1 byte %d \n",i);
  61145. + return MV_FAIL;
  61146. + }
  61147. + mvOsDelay(5);
  61148. + }
  61149. +
  61150. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  61151. + return MV_OK;
  61152. +}
  61153. +
  61154. +/*******************************************************************************
  61155. +* dimmSpdGet - Get the SPD parameters.
  61156. +*
  61157. +* DESCRIPTION:
  61158. +* Read the DIMM SPD parameters into given struct parameter.
  61159. +*
  61160. +* INPUT:
  61161. +* dimmNum - DIMM number. See MV_BOARD_DIMM_NUM enumerator.
  61162. +*
  61163. +* OUTPUT:
  61164. +* pDimmInfo - DIMM information structure.
  61165. +*
  61166. +* RETURN:
  61167. +* MV_TRUE if function could read DIMM parameters, MV_FALSE otherwise.
  61168. +*
  61169. +*******************************************************************************/
  61170. +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo)
  61171. +{
  61172. + MV_U32 i;
  61173. + MV_U32 density = 1;
  61174. + MV_U32 spdChecksum;
  61175. +
  61176. + MV_TWSI_SLAVE twsiSlave;
  61177. + MV_U8 data[SPD_SIZE];
  61178. +
  61179. + if((NULL == pDimmInfo)|| (dimmNum >= MAX_DIMM_NUM))
  61180. + {
  61181. + DB(mvOsPrintf("Dram: mvDramBankInfoGet bad params \n"));
  61182. + return MV_BAD_PARAM;
  61183. + }
  61184. +
  61185. + /* zero dimmInfo structure */
  61186. + memset(data, 0, SPD_SIZE);
  61187. +
  61188. + /* read the dimm eeprom */
  61189. + DB(mvOsPrintf("DRAM: Read Dimm eeprom\n"));
  61190. + twsiSlave.slaveAddr.address = (dimmNum == 0) ?
  61191. + MV_BOARD_DIMM0_I2C_ADDR : MV_BOARD_DIMM1_I2C_ADDR;
  61192. + twsiSlave.slaveAddr.type = ADDR7_BIT;
  61193. + twsiSlave.validOffset = MV_TRUE;
  61194. + twsiSlave.offset = 0;
  61195. + twsiSlave.moreThen256 = MV_FALSE;
  61196. +
  61197. + if( MV_OK != mvTwsiRead (MV_BOARD_DIMM_I2C_CHANNEL, &twsiSlave, data, SPD_SIZE) )
  61198. + {
  61199. + DB(mvOsPrintf("DRAM: ERR. no DIMM in dimmNum %d \n", dimmNum));
  61200. + return MV_FAIL;
  61201. + }
  61202. + DB(puts("DRAM: Reading dimm info succeded.\n"));
  61203. +
  61204. + /* calculate SPD checksum */
  61205. + spdChecksum = 0;
  61206. +
  61207. + for(i = 0 ; i <= 62 ; i++)
  61208. + {
  61209. + spdChecksum += data[i];
  61210. + }
  61211. +
  61212. + if ((spdChecksum & 0xff) != data[63])
  61213. + {
  61214. + DB(mvOsPrintf("DRAM: Warning. Wrong SPD Checksum %2x, expValue=%2x\n",
  61215. + (MV_U32)(spdChecksum & 0xff), data[63]));
  61216. + }
  61217. + else
  61218. + {
  61219. + DB(mvOsPrintf("DRAM: SPD Checksum ok!\n"));
  61220. + }
  61221. +
  61222. + /* copy the SPD content 1:1 into the dimmInfo structure*/
  61223. + for(i = 0 ; i < SPD_SIZE ; i++)
  61224. + {
  61225. + pDimmInfo->spdRawData[i] = data[i];
  61226. + DB(mvOsPrintf("SPD-EEPROM Byte %3d = %3x (%3d)\n",i, data[i], data[i]));
  61227. + }
  61228. +
  61229. + DB(mvOsPrintf("DRAM SPD Information:\n"));
  61230. +
  61231. + /* Memory type (DDR / SDRAM) */
  61232. + switch (data[DIMM_MEM_TYPE])
  61233. + {
  61234. + case (DIMM_MEM_TYPE_SDRAM):
  61235. + pDimmInfo->memoryType = MEM_TYPE_SDRAM;
  61236. + DB(mvOsPrintf("DRAM Memeory type SDRAM\n"));
  61237. + break;
  61238. + case (DIMM_MEM_TYPE_DDR1):
  61239. + pDimmInfo->memoryType = MEM_TYPE_DDR1;
  61240. + DB(mvOsPrintf("DRAM Memeory type DDR1\n"));
  61241. + break;
  61242. + case (DIMM_MEM_TYPE_DDR2):
  61243. + pDimmInfo->memoryType = MEM_TYPE_DDR2;
  61244. + DB(mvOsPrintf("DRAM Memeory type DDR2\n"));
  61245. + break;
  61246. + default:
  61247. + mvOsPrintf("ERROR: Undefined memory type!\n");
  61248. + return MV_ERROR;
  61249. + }
  61250. +
  61251. +
  61252. + /* Number Of Row Addresses */
  61253. + pDimmInfo->numOfRowAddr = data[DIMM_ROW_NUM];
  61254. + DB(mvOsPrintf("DRAM numOfRowAddr[3] %d\n",pDimmInfo->numOfRowAddr));
  61255. +
  61256. + /* Number Of Column Addresses */
  61257. + pDimmInfo->numOfColAddr = data[DIMM_COL_NUM];
  61258. + DB(mvOsPrintf("DRAM numOfColAddr[4] %d\n",pDimmInfo->numOfColAddr));
  61259. +
  61260. + /* Number Of Module Banks */
  61261. + pDimmInfo->numOfModuleBanks = data[DIMM_MODULE_BANK_NUM];
  61262. + DB(mvOsPrintf("DRAM numOfModuleBanks[5] 0x%x\n",
  61263. + pDimmInfo->numOfModuleBanks));
  61264. +
  61265. + /* Number of module banks encoded differently for DDR2 */
  61266. + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
  61267. + pDimmInfo->numOfModuleBanks = (pDimmInfo->numOfModuleBanks & 0x7)+1;
  61268. +
  61269. + /* Data Width */
  61270. + pDimmInfo->dataWidth = data[DIMM_DATA_WIDTH];
  61271. + DB(mvOsPrintf("DRAM dataWidth[6] 0x%x\n", pDimmInfo->dataWidth));
  61272. +
  61273. + /* Minimum Cycle Time At Max CasLatancy */
  61274. + pDimmInfo->minCycleTimeAtMaxCasLatPs = cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS]);
  61275. +
  61276. + /* Error Check Type */
  61277. + pDimmInfo->errorCheckType = data[DIMM_ERR_CHECK_TYPE];
  61278. + DB(mvOsPrintf("DRAM errorCheckType[11] 0x%x\n",
  61279. + pDimmInfo->errorCheckType));
  61280. +
  61281. + /* Refresh Interval */
  61282. + pDimmInfo->refreshInterval = data[DIMM_REFRESH_INTERVAL];
  61283. + DB(mvOsPrintf("DRAM refreshInterval[12] 0x%x\n",
  61284. + pDimmInfo->refreshInterval));
  61285. +
  61286. + /* Sdram Width */
  61287. + pDimmInfo->sdramWidth = data[DIMM_SDRAM_WIDTH];
  61288. + DB(mvOsPrintf("DRAM sdramWidth[13] 0x%x\n",pDimmInfo->sdramWidth));
  61289. +
  61290. + /* Error Check Data Width */
  61291. + pDimmInfo->errorCheckDataWidth = data[DIMM_ERR_CHECK_DATA_WIDTH];
  61292. + DB(mvOsPrintf("DRAM errorCheckDataWidth[14] 0x%x\n",
  61293. + pDimmInfo->errorCheckDataWidth));
  61294. +
  61295. + /* Burst Length Supported */
  61296. + /* SDRAM/DDR1:
  61297. + *******-******-******-******-******-******-******-*******
  61298. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  61299. + *******-******-******-******-******-******-******-*******
  61300. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
  61301. + *********************************************************/
  61302. + /* DDR2:
  61303. + *******-******-******-******-******-******-******-*******
  61304. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  61305. + *******-******-******-******-******-******-******-*******
  61306. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
  61307. + *********************************************************/
  61308. +
  61309. + pDimmInfo->burstLengthSupported = data[DIMM_BURST_LEN_SUP];
  61310. + DB(mvOsPrintf("DRAM burstLengthSupported[16] 0x%x\n",
  61311. + pDimmInfo->burstLengthSupported));
  61312. +
  61313. + /* Number Of Banks On Each Device */
  61314. + pDimmInfo->numOfBanksOnEachDevice = data[DIMM_DEV_BANK_NUM];
  61315. + DB(mvOsPrintf("DRAM numOfBanksOnEachDevice[17] 0x%x\n",
  61316. + pDimmInfo->numOfBanksOnEachDevice));
  61317. +
  61318. + /* Suported Cas Latencies */
  61319. +
  61320. + /* SDRAM:
  61321. + *******-******-******-******-******-******-******-*******
  61322. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  61323. + *******-******-******-******-******-******-******-*******
  61324. + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
  61325. + ********************************************************/
  61326. +
  61327. + /* DDR 1:
  61328. + *******-******-******-******-******-******-******-*******
  61329. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  61330. + *******-******-******-******-******-******-******-*******
  61331. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  61332. + *********************************************************/
  61333. +
  61334. + /* DDR 2:
  61335. + *******-******-******-******-******-******-******-*******
  61336. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  61337. + *******-******-******-******-******-******-******-*******
  61338. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  61339. + *********************************************************/
  61340. +
  61341. + pDimmInfo->suportedCasLatencies = data[DIMM_SUP_CAL];
  61342. + DB(mvOsPrintf("DRAM suportedCasLatencies[18] 0x%x\n",
  61343. + pDimmInfo->suportedCasLatencies));
  61344. +
  61345. + /* For DDR2 only, get the DIMM type information */
  61346. + if (pDimmInfo->memoryType == MEM_TYPE_DDR2)
  61347. + {
  61348. + pDimmInfo->dimmTypeInfo = data[DIMM_DDR2_TYPE_INFORMATION];
  61349. + DB(mvOsPrintf("DRAM dimmTypeInfo[20] (DDR2) 0x%x\n",
  61350. + pDimmInfo->dimmTypeInfo));
  61351. + }
  61352. +
  61353. + /* SDRAM Modules Attributes */
  61354. + pDimmInfo->dimmAttributes = data[DIMM_BUF_ADDR_CONT_IN];
  61355. + DB(mvOsPrintf("DRAM dimmAttributes[21] 0x%x\n",
  61356. + pDimmInfo->dimmAttributes));
  61357. +
  61358. + /* Minimum Cycle Time At Max CasLatancy Minus 1*/
  61359. + pDimmInfo->minCycleTimeAtMaxCasLatMinus1Ps =
  61360. + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS1]);
  61361. +
  61362. + /* Minimum Cycle Time At Max CasLatancy Minus 2*/
  61363. + pDimmInfo->minCycleTimeAtMaxCasLatMinus2Ps =
  61364. + cas2ps(data[DIMM_MIN_CC_AT_MAX_CAS_MINUS2]);
  61365. +
  61366. + pDimmInfo->minRowPrechargeTime = data[DIMM_MIN_ROW_PRECHARGE_TIME];
  61367. + DB(mvOsPrintf("DRAM minRowPrechargeTime[27] 0x%x\n",
  61368. + pDimmInfo->minRowPrechargeTime));
  61369. + pDimmInfo->minRowActiveToRowActive = data[DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE];
  61370. + DB(mvOsPrintf("DRAM minRowActiveToRowActive[28] 0x%x\n",
  61371. + pDimmInfo->minRowActiveToRowActive));
  61372. + pDimmInfo->minRasToCasDelay = data[DIMM_MIN_RAS_TO_CAS_DELAY];
  61373. + DB(mvOsPrintf("DRAM minRasToCasDelay[29] 0x%x\n",
  61374. + pDimmInfo->minRasToCasDelay));
  61375. + pDimmInfo->minRasPulseWidth = data[DIMM_MIN_RAS_PULSE_WIDTH];
  61376. + DB(mvOsPrintf("DRAM minRasPulseWidth[30] 0x%x\n",
  61377. + pDimmInfo->minRasPulseWidth));
  61378. +
  61379. + /* DIMM Bank Density */
  61380. + pDimmInfo->dimmBankDensity = data[DIMM_BANK_DENSITY];
  61381. + DB(mvOsPrintf("DRAM dimmBankDensity[31] 0x%x\n",
  61382. + pDimmInfo->dimmBankDensity));
  61383. +
  61384. + /* Only DDR2 includes Write Recovery Time field. Other SDRAM ignore */
  61385. + pDimmInfo->minWriteRecoveryTime = data[DIMM_MIN_WRITE_RECOVERY_TIME];
  61386. + DB(mvOsPrintf("DRAM minWriteRecoveryTime[36] 0x%x\n",
  61387. + pDimmInfo->minWriteRecoveryTime));
  61388. +
  61389. + /* Only DDR2 includes Internal Write To Read Command Delay field. */
  61390. + pDimmInfo->minWriteToReadCmdDelay = data[DIMM_MIN_WRITE_TO_READ_CMD_DELAY];
  61391. + DB(mvOsPrintf("DRAM minWriteToReadCmdDelay[37] 0x%x\n",
  61392. + pDimmInfo->minWriteToReadCmdDelay));
  61393. +
  61394. + /* Only DDR2 includes Internal Read To Precharge Command Delay field. */
  61395. + pDimmInfo->minReadToPrechCmdDelay = data[DIMM_MIN_READ_TO_PRECH_CMD_DELAY];
  61396. + DB(mvOsPrintf("DRAM minReadToPrechCmdDelay[38] 0x%x\n",
  61397. + pDimmInfo->minReadToPrechCmdDelay));
  61398. +
  61399. + /* Only DDR2 includes Minimum Refresh to Activate/Refresh Command field */
  61400. + pDimmInfo->minRefreshToActiveCmd = data[DIMM_MIN_REFRESH_TO_ACTIVATE_CMD];
  61401. + DB(mvOsPrintf("DRAM minRefreshToActiveCmd[42] 0x%x\n",
  61402. + pDimmInfo->minRefreshToActiveCmd));
  61403. +
  61404. + /* calculating the sdram density. Representing device density from */
  61405. + /* bit 20 to allow representation of 4GB and above. */
  61406. + /* For example, if density is 512Mbit 0x20000000, will be represent in */
  61407. + /* deviceDensity by 0x20000000 >> 16 --> 0x00000200. Another example */
  61408. + /* is density 8GB 0x200000000 >> 16 --> 0x00002000. */
  61409. + density = (1 << ((pDimmInfo->numOfRowAddr + pDimmInfo->numOfColAddr) - 20));
  61410. + pDimmInfo->deviceDensity = density *
  61411. + pDimmInfo->numOfBanksOnEachDevice *
  61412. + pDimmInfo->sdramWidth;
  61413. + DB(mvOsPrintf("DRAM deviceDensity %d\n",pDimmInfo->deviceDensity));
  61414. +
  61415. + /* Number of devices includeing Error correction */
  61416. + pDimmInfo->numberOfDevices = (pDimmInfo->dataWidth/pDimmInfo->sdramWidth) *
  61417. + pDimmInfo->numOfModuleBanks;
  61418. + DB(mvOsPrintf("DRAM numberOfDevices %d\n",
  61419. + pDimmInfo->numberOfDevices));
  61420. +
  61421. + pDimmInfo->size = 0;
  61422. +
  61423. + /* Note that pDimmInfo->size is in MB units */
  61424. + if (pDimmInfo->memoryType == MEM_TYPE_SDRAM)
  61425. + {
  61426. + if (pDimmInfo->dimmBankDensity & BIT0)
  61427. + pDimmInfo->size += 1024; /* Equal to 1GB */
  61428. + else if (pDimmInfo->dimmBankDensity & BIT1)
  61429. + pDimmInfo->size += 8; /* Equal to 8MB */
  61430. + else if (pDimmInfo->dimmBankDensity & BIT2)
  61431. + pDimmInfo->size += 16; /* Equal to 16MB */
  61432. + else if (pDimmInfo->dimmBankDensity & BIT3)
  61433. + pDimmInfo->size += 32; /* Equal to 32MB */
  61434. + else if (pDimmInfo->dimmBankDensity & BIT4)
  61435. + pDimmInfo->size += 64; /* Equal to 64MB */
  61436. + else if (pDimmInfo->dimmBankDensity & BIT5)
  61437. + pDimmInfo->size += 128; /* Equal to 128MB */
  61438. + else if (pDimmInfo->dimmBankDensity & BIT6)
  61439. + pDimmInfo->size += 256; /* Equal to 256MB */
  61440. + else if (pDimmInfo->dimmBankDensity & BIT7)
  61441. + pDimmInfo->size += 512; /* Equal to 512MB */
  61442. + }
  61443. + else if (pDimmInfo->memoryType == MEM_TYPE_DDR1)
  61444. + {
  61445. + if (pDimmInfo->dimmBankDensity & BIT0)
  61446. + pDimmInfo->size += 1024; /* Equal to 1GB */
  61447. + else if (pDimmInfo->dimmBankDensity & BIT1)
  61448. + pDimmInfo->size += 2048; /* Equal to 2GB */
  61449. + else if (pDimmInfo->dimmBankDensity & BIT2)
  61450. + pDimmInfo->size += 16; /* Equal to 16MB */
  61451. + else if (pDimmInfo->dimmBankDensity & BIT3)
  61452. + pDimmInfo->size += 32; /* Equal to 32MB */
  61453. + else if (pDimmInfo->dimmBankDensity & BIT4)
  61454. + pDimmInfo->size += 64; /* Equal to 64MB */
  61455. + else if (pDimmInfo->dimmBankDensity & BIT5)
  61456. + pDimmInfo->size += 128; /* Equal to 128MB */
  61457. + else if (pDimmInfo->dimmBankDensity & BIT6)
  61458. + pDimmInfo->size += 256; /* Equal to 256MB */
  61459. + else if (pDimmInfo->dimmBankDensity & BIT7)
  61460. + pDimmInfo->size += 512; /* Equal to 512MB */
  61461. + }
  61462. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  61463. + {
  61464. + if (pDimmInfo->dimmBankDensity & BIT0)
  61465. + pDimmInfo->size += 1024; /* Equal to 1GB */
  61466. + else if (pDimmInfo->dimmBankDensity & BIT1)
  61467. + pDimmInfo->size += 2048; /* Equal to 2GB */
  61468. + else if (pDimmInfo->dimmBankDensity & BIT2)
  61469. + pDimmInfo->size += 4096; /* Equal to 4GB */
  61470. + else if (pDimmInfo->dimmBankDensity & BIT3)
  61471. + pDimmInfo->size += 8192; /* Equal to 8GB */
  61472. + else if (pDimmInfo->dimmBankDensity & BIT4)
  61473. + pDimmInfo->size += 16384; /* Equal to 16GB */
  61474. + else if (pDimmInfo->dimmBankDensity & BIT5)
  61475. + pDimmInfo->size += 128; /* Equal to 128MB */
  61476. + else if (pDimmInfo->dimmBankDensity & BIT6)
  61477. + pDimmInfo->size += 256; /* Equal to 256MB */
  61478. + else if (pDimmInfo->dimmBankDensity & BIT7)
  61479. + pDimmInfo->size += 512; /* Equal to 512MB */
  61480. + }
  61481. +
  61482. + pDimmInfo->size *= pDimmInfo->numOfModuleBanks;
  61483. +
  61484. + DB(mvOsPrintf("Dram: dimm size %dMB \n",pDimmInfo->size));
  61485. +
  61486. + return MV_OK;
  61487. +}
  61488. +
  61489. +/*******************************************************************************
  61490. +* dimmSpdPrint - Print the SPD parameters.
  61491. +*
  61492. +* DESCRIPTION:
  61493. +* Print the Dimm SPD parameters.
  61494. +*
  61495. +* INPUT:
  61496. +* pDimmInfo - DIMM information structure.
  61497. +*
  61498. +* OUTPUT:
  61499. +* None.
  61500. +*
  61501. +* RETURN:
  61502. +* None.
  61503. +*
  61504. +*******************************************************************************/
  61505. +MV_VOID dimmSpdPrint(MV_U32 dimmNum)
  61506. +{
  61507. + MV_DIMM_INFO dimmInfo;
  61508. + MV_U32 i, temp = 0;
  61509. + MV_U32 k, maskLeftOfPoint = 0, maskRightOfPoint = 0;
  61510. + MV_U32 rightOfPoint = 0,leftOfPoint = 0, div, time_tmp, shift;
  61511. + MV_U32 busClkPs;
  61512. + MV_U8 trp_clocks=0, trcd_clocks, tras_clocks, trrd_clocks,
  61513. + temp_buf[40], *spdRawData;
  61514. +
  61515. + busClkPs = 1000000000 / (mvBoardSysClkGet() / 100); /* in 10 ps units */
  61516. +
  61517. + spdRawData = dimmInfo.spdRawData;
  61518. +
  61519. + if(MV_OK != dimmSpdGet(dimmNum, &dimmInfo))
  61520. + {
  61521. + mvOsOutput("ERROR: Could not read SPD information!\n");
  61522. + return;
  61523. + }
  61524. +
  61525. + /* find Manufactura of Dimm Module */
  61526. + mvOsOutput("\nManufacturer's JEDEC ID Code: ");
  61527. + for(i = 0 ; i < DIMM_MODULE_MANU_SIZE ; i++)
  61528. + {
  61529. + mvOsOutput("%x",spdRawData[DIMM_MODULE_MANU_OFFS + i]);
  61530. + }
  61531. + mvOsOutput("\n");
  61532. +
  61533. + /* Manufacturer's Specific Data */
  61534. + for(i = 0 ; i < DIMM_MODULE_ID_SIZE ; i++)
  61535. + {
  61536. + temp_buf[i] = spdRawData[DIMM_MODULE_ID_OFFS + i];
  61537. + }
  61538. + mvOsOutput("Manufacturer's Specific Data: %s\n", temp_buf);
  61539. +
  61540. + /* Module Part Number */
  61541. + for(i = 0 ; i < DIMM_MODULE_VEN_SIZE ; i++)
  61542. + {
  61543. + temp_buf[i] = spdRawData[DIMM_MODULE_VEN_OFFS + i];
  61544. + }
  61545. + mvOsOutput("Module Part Number: %s\n", temp_buf);
  61546. +
  61547. + /* Module Serial Number */
  61548. + for(i = 0; i < sizeof(MV_U32); i++)
  61549. + {
  61550. + temp |= spdRawData[95+i] << 8*i;
  61551. + }
  61552. + mvOsOutput("DIMM Serial No. %ld (%lx)\n", (long)temp,
  61553. + (long)temp);
  61554. +
  61555. + /* find Manufac-Data of Dimm Module */
  61556. + mvOsOutput("Manufactoring Date: Year 20%d%d/ ww %d%d\n",
  61557. + ((spdRawData[93] & 0xf0) >> 4), (spdRawData[93] & 0xf),
  61558. + ((spdRawData[94] & 0xf0) >> 4), (spdRawData[94] & 0xf));
  61559. + /* find modul_revision of Dimm Module */
  61560. + mvOsOutput("Module Revision: %d.%d\n",
  61561. + spdRawData[62]/10, spdRawData[62]%10);
  61562. +
  61563. + /* find manufac_place of Dimm Module */
  61564. + mvOsOutput("manufac_place: %d\n", spdRawData[72]);
  61565. +
  61566. + /* go over the first 35 I2C data bytes */
  61567. + for(i = 2 ; i <= 35 ; i++)
  61568. + switch(i)
  61569. + {
  61570. + case 2: /* Memory type (DDR1/2 / SDRAM) */
  61571. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  61572. + mvOsOutput("Dram Type is: SDRAM\n");
  61573. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  61574. + mvOsOutput("Dram Type is: SDRAM DDR1\n");
  61575. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  61576. + mvOsOutput("Dram Type is: SDRAM DDR2\n");
  61577. + else
  61578. + mvOsOutput("Dram Type unknown\n");
  61579. + break;
  61580. +/*----------------------------------------------------------------------------*/
  61581. +
  61582. + case 3: /* Number Of Row Addresses */
  61583. + mvOsOutput("Module Number of row addresses: %d\n",
  61584. + dimmInfo.numOfRowAddr);
  61585. + break;
  61586. +/*----------------------------------------------------------------------------*/
  61587. +
  61588. + case 4: /* Number Of Column Addresses */
  61589. + mvOsOutput("Module Number of col addresses: %d\n",
  61590. + dimmInfo.numOfColAddr);
  61591. + break;
  61592. +/*----------------------------------------------------------------------------*/
  61593. +
  61594. + case 5: /* Number Of Module Banks */
  61595. + mvOsOutput("Number of Banks on Mod.: %d\n",
  61596. + dimmInfo.numOfModuleBanks);
  61597. + break;
  61598. +/*----------------------------------------------------------------------------*/
  61599. +
  61600. + case 6: /* Data Width */
  61601. + mvOsOutput("Module Data Width: %d bit\n",
  61602. + dimmInfo.dataWidth);
  61603. + break;
  61604. +/*----------------------------------------------------------------------------*/
  61605. +
  61606. + case 8: /* Voltage Interface */
  61607. + switch(spdRawData[i])
  61608. + {
  61609. + case 0x0:
  61610. + mvOsOutput("Module is TTL_5V_TOLERANT\n");
  61611. + break;
  61612. + case 0x1:
  61613. + mvOsOutput("Module is LVTTL\n");
  61614. + break;
  61615. + case 0x2:
  61616. + mvOsOutput("Module is HSTL_1_5V\n");
  61617. + break;
  61618. + case 0x3:
  61619. + mvOsOutput("Module is SSTL_3_3V\n");
  61620. + break;
  61621. + case 0x4:
  61622. + mvOsOutput("Module is SSTL_2_5V\n");
  61623. + break;
  61624. + case 0x5:
  61625. + if (dimmInfo.memoryType != MEM_TYPE_SDRAM)
  61626. + {
  61627. + mvOsOutput("Module is SSTL_1_8V\n");
  61628. + break;
  61629. + }
  61630. + default:
  61631. + mvOsOutput("Module is VOLTAGE_UNKNOWN\n");
  61632. + break;
  61633. + }
  61634. + break;
  61635. +/*----------------------------------------------------------------------------*/
  61636. +
  61637. + case 9: /* Minimum Cycle Time At Max CasLatancy */
  61638. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  61639. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  61640. +
  61641. + /* DDR2 addition of right of point */
  61642. + if ((spdRawData[i] & 0x0f) == 0xA)
  61643. + {
  61644. + rightOfPoint = 25;
  61645. + }
  61646. + if ((spdRawData[i] & 0x0f) == 0xB)
  61647. + {
  61648. + rightOfPoint = 33;
  61649. + }
  61650. + if ((spdRawData[i] & 0x0f) == 0xC)
  61651. + {
  61652. + rightOfPoint = 66;
  61653. + }
  61654. + if ((spdRawData[i] & 0x0f) == 0xD)
  61655. + {
  61656. + rightOfPoint = 75;
  61657. + }
  61658. + mvOsOutput("Minimum Cycle Time At Max CL: %d.%d [ns]\n",
  61659. + leftOfPoint, rightOfPoint);
  61660. + break;
  61661. +/*----------------------------------------------------------------------------*/
  61662. +
  61663. + case 10: /* Clock To Data Out */
  61664. + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 10:100;
  61665. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  61666. + ((spdRawData[i] & 0x0f));
  61667. + leftOfPoint = time_tmp / div;
  61668. + rightOfPoint = time_tmp % div;
  61669. + mvOsOutput("Clock To Data Out: %d.%d [ns]\n",
  61670. + leftOfPoint, rightOfPoint);
  61671. + break;
  61672. +/*----------------------------------------------------------------------------*/
  61673. +
  61674. + case 11: /* Error Check Type */
  61675. + mvOsOutput("Error Check Type (0=NONE): %d\n",
  61676. + dimmInfo.errorCheckType);
  61677. + break;
  61678. +/*----------------------------------------------------------------------------*/
  61679. +
  61680. + case 12: /* Refresh Interval */
  61681. + mvOsOutput("Refresh Rate: %x\n",
  61682. + dimmInfo.refreshInterval);
  61683. + break;
  61684. +/*----------------------------------------------------------------------------*/
  61685. +
  61686. + case 13: /* Sdram Width */
  61687. + mvOsOutput("Sdram Width: %d bits\n",
  61688. + dimmInfo.sdramWidth);
  61689. + break;
  61690. +/*----------------------------------------------------------------------------*/
  61691. +
  61692. + case 14: /* Error Check Data Width */
  61693. + mvOsOutput("Error Check Data Width: %d bits\n",
  61694. + dimmInfo.errorCheckDataWidth);
  61695. + break;
  61696. +/*----------------------------------------------------------------------------*/
  61697. +
  61698. + case 15: /* Minimum Clock Delay is unsupported */
  61699. + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
  61700. + (dimmInfo.memoryType == MEM_TYPE_DDR1))
  61701. + {
  61702. + mvOsOutput("Minimum Clk Delay back to back: %d\n",
  61703. + spdRawData[i]);
  61704. + }
  61705. + break;
  61706. +/*----------------------------------------------------------------------------*/
  61707. +
  61708. + case 16: /* Burst Length Supported */
  61709. + /* SDRAM/DDR1:
  61710. + *******-******-******-******-******-******-******-*******
  61711. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  61712. + *******-******-******-******-******-******-******-*******
  61713. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | 2 | 1 *
  61714. + *********************************************************/
  61715. + /* DDR2:
  61716. + *******-******-******-******-******-******-******-*******
  61717. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  61718. + *******-******-******-******-******-******-******-*******
  61719. + burst length = * Page | TBD | TBD | TBD | 8 | 4 | TBD | TBD *
  61720. + *********************************************************/
  61721. + mvOsOutput("Burst Length Supported: ");
  61722. + if ((dimmInfo.memoryType == MEM_TYPE_SDRAM) ||
  61723. + (dimmInfo.memoryType == MEM_TYPE_DDR1))
  61724. + {
  61725. + if (dimmInfo.burstLengthSupported & BIT0)
  61726. + mvOsOutput("1, ");
  61727. + if (dimmInfo.burstLengthSupported & BIT1)
  61728. + mvOsOutput("2, ");
  61729. + }
  61730. + if (dimmInfo.burstLengthSupported & BIT2)
  61731. + mvOsOutput("4, ");
  61732. + if (dimmInfo.burstLengthSupported & BIT3)
  61733. + mvOsOutput("8, ");
  61734. +
  61735. + mvOsOutput(" Bit \n");
  61736. + break;
  61737. +/*----------------------------------------------------------------------------*/
  61738. +
  61739. + case 17: /* Number Of Banks On Each Device */
  61740. + mvOsOutput("Number Of Banks On Each Chip: %d\n",
  61741. + dimmInfo.numOfBanksOnEachDevice);
  61742. + break;
  61743. +/*----------------------------------------------------------------------------*/
  61744. +
  61745. + case 18: /* Suported Cas Latencies */
  61746. +
  61747. + /* SDRAM:
  61748. + *******-******-******-******-******-******-******-*******
  61749. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  61750. + *******-******-******-******-******-******-******-*******
  61751. + CAS = * TBD | 7 | 6 | 5 | 4 | 3 | 2 | 1 *
  61752. + ********************************************************/
  61753. +
  61754. + /* DDR 1:
  61755. + *******-******-******-******-******-******-******-*******
  61756. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  61757. + *******-******-******-******-******-******-******-*******
  61758. + CAS = * TBD | 4 | 3.5 | 3 | 2.5 | 2 | 1.5 | 1 *
  61759. + *********************************************************/
  61760. +
  61761. + /* DDR 2:
  61762. + *******-******-******-******-******-******-******-*******
  61763. + * bit7 | bit6 | bit5 | bit4 | bit3 | bit2 | bit1 | bit0 *
  61764. + *******-******-******-******-******-******-******-*******
  61765. + CAS = * TBD | TBD | 5 | 4 | 3 | 2 | TBD | TBD *
  61766. + *********************************************************/
  61767. +
  61768. + mvOsOutput("Suported Cas Latencies: (CL) ");
  61769. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  61770. + {
  61771. + for (k = 0; k <=7; k++)
  61772. + {
  61773. + if (dimmInfo.suportedCasLatencies & (1 << k))
  61774. + mvOsOutput("%d, ", k+1);
  61775. + }
  61776. + }
  61777. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  61778. + {
  61779. + if (dimmInfo.suportedCasLatencies & BIT0)
  61780. + mvOsOutput("1, ");
  61781. + if (dimmInfo.suportedCasLatencies & BIT1)
  61782. + mvOsOutput("1.5, ");
  61783. + if (dimmInfo.suportedCasLatencies & BIT2)
  61784. + mvOsOutput("2, ");
  61785. + if (dimmInfo.suportedCasLatencies & BIT3)
  61786. + mvOsOutput("2.5, ");
  61787. + if (dimmInfo.suportedCasLatencies & BIT4)
  61788. + mvOsOutput("3, ");
  61789. + if (dimmInfo.suportedCasLatencies & BIT5)
  61790. + mvOsOutput("3.5, ");
  61791. + }
  61792. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  61793. + {
  61794. + if (dimmInfo.suportedCasLatencies & BIT2)
  61795. + mvOsOutput("2, ");
  61796. + if (dimmInfo.suportedCasLatencies & BIT3)
  61797. + mvOsOutput("3, ");
  61798. + if (dimmInfo.suportedCasLatencies & BIT4)
  61799. + mvOsOutput("4, ");
  61800. + if (dimmInfo.suportedCasLatencies & BIT5)
  61801. + mvOsOutput("5, ");
  61802. + }
  61803. + else
  61804. + mvOsOutput("?.?, ");
  61805. + mvOsOutput("\n");
  61806. + break;
  61807. +/*----------------------------------------------------------------------------*/
  61808. +
  61809. + case 20: /* DDR2 DIMM type info */
  61810. + if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  61811. + {
  61812. + if (dimmInfo.dimmTypeInfo & (BIT0 | BIT4))
  61813. + mvOsOutput("Registered DIMM (RDIMM)\n");
  61814. + else if (dimmInfo.dimmTypeInfo & (BIT1 | BIT5))
  61815. + mvOsOutput("Unbuffered DIMM (UDIMM)\n");
  61816. + else
  61817. + mvOsOutput("Unknown DIMM type.\n");
  61818. + }
  61819. +
  61820. + break;
  61821. +/*----------------------------------------------------------------------------*/
  61822. +
  61823. + case 21: /* SDRAM Modules Attributes */
  61824. + mvOsOutput("\nModule Attributes (SPD Byte 21): \n");
  61825. +
  61826. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  61827. + {
  61828. + if (dimmInfo.dimmAttributes & BIT0)
  61829. + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
  61830. + else
  61831. + mvOsOutput(" Buffered Addr/Control Input: No\n");
  61832. +
  61833. + if (dimmInfo.dimmAttributes & BIT1)
  61834. + mvOsOutput(" Registered Addr/Control Input: Yes\n");
  61835. + else
  61836. + mvOsOutput(" Registered Addr/Control Input: No\n");
  61837. +
  61838. + if (dimmInfo.dimmAttributes & BIT2)
  61839. + mvOsOutput(" On-Card PLL (clock): Yes \n");
  61840. + else
  61841. + mvOsOutput(" On-Card PLL (clock): No \n");
  61842. +
  61843. + if (dimmInfo.dimmAttributes & BIT3)
  61844. + mvOsOutput(" Bufferd DQMB Input: Yes \n");
  61845. + else
  61846. + mvOsOutput(" Bufferd DQMB Inputs: No \n");
  61847. +
  61848. + if (dimmInfo.dimmAttributes & BIT4)
  61849. + mvOsOutput(" Registered DQMB Inputs: Yes \n");
  61850. + else
  61851. + mvOsOutput(" Registered DQMB Inputs: No \n");
  61852. +
  61853. + if (dimmInfo.dimmAttributes & BIT5)
  61854. + mvOsOutput(" Differential Clock Input: Yes \n");
  61855. + else
  61856. + mvOsOutput(" Differential Clock Input: No \n");
  61857. +
  61858. + if (dimmInfo.dimmAttributes & BIT6)
  61859. + mvOsOutput(" redundant Row Addressing: Yes \n");
  61860. + else
  61861. + mvOsOutput(" redundant Row Addressing: No \n");
  61862. + }
  61863. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  61864. + {
  61865. + if (dimmInfo.dimmAttributes & BIT0)
  61866. + mvOsOutput(" Buffered Addr/Control Input: Yes\n");
  61867. + else
  61868. + mvOsOutput(" Buffered Addr/Control Input: No\n");
  61869. +
  61870. + if (dimmInfo.dimmAttributes & BIT1)
  61871. + mvOsOutput(" Registered Addr/Control Input: Yes\n");
  61872. + else
  61873. + mvOsOutput(" Registered Addr/Control Input: No\n");
  61874. +
  61875. + if (dimmInfo.dimmAttributes & BIT2)
  61876. + mvOsOutput(" On-Card PLL (clock): Yes \n");
  61877. + else
  61878. + mvOsOutput(" On-Card PLL (clock): No \n");
  61879. +
  61880. + if (dimmInfo.dimmAttributes & BIT3)
  61881. + mvOsOutput(" FET Switch On-Card Enabled: Yes \n");
  61882. + else
  61883. + mvOsOutput(" FET Switch On-Card Enabled: No \n");
  61884. +
  61885. + if (dimmInfo.dimmAttributes & BIT4)
  61886. + mvOsOutput(" FET Switch External Enabled: Yes \n");
  61887. + else
  61888. + mvOsOutput(" FET Switch External Enabled: No \n");
  61889. +
  61890. + if (dimmInfo.dimmAttributes & BIT5)
  61891. + mvOsOutput(" Differential Clock Input: Yes \n");
  61892. + else
  61893. + mvOsOutput(" Differential Clock Input: No \n");
  61894. + }
  61895. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  61896. + {
  61897. + mvOsOutput(" Number of Active Registers on the DIMM: %d\n",
  61898. + (dimmInfo.dimmAttributes & 0x3) + 1);
  61899. +
  61900. + mvOsOutput(" Number of PLLs on the DIMM: %d\n",
  61901. + ((dimmInfo.dimmAttributes) >> 2) & 0x3);
  61902. +
  61903. + if (dimmInfo.dimmAttributes & BIT4)
  61904. + mvOsOutput(" FET Switch External Enabled: Yes \n");
  61905. + else
  61906. + mvOsOutput(" FET Switch External Enabled: No \n");
  61907. +
  61908. + if (dimmInfo.dimmAttributes & BIT6)
  61909. + mvOsOutput(" Analysis probe installed: Yes \n");
  61910. + else
  61911. + mvOsOutput(" Analysis probe installed: No \n");
  61912. + }
  61913. +
  61914. + break;
  61915. +/*----------------------------------------------------------------------------*/
  61916. +
  61917. + case 22: /* Suported AutoPreCharge */
  61918. + mvOsOutput("\nModul Attributes (SPD Byte 22): \n");
  61919. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  61920. + {
  61921. + if ( spdRawData[i] & BIT0 )
  61922. + mvOsOutput(" Early Ras Precharge: Yes \n");
  61923. + else
  61924. + mvOsOutput(" Early Ras Precharge: No \n");
  61925. +
  61926. + if ( spdRawData[i] & BIT1 )
  61927. + mvOsOutput(" AutoPreCharge: Yes \n");
  61928. + else
  61929. + mvOsOutput(" AutoPreCharge: No \n");
  61930. +
  61931. + if ( spdRawData[i] & BIT2 )
  61932. + mvOsOutput(" Precharge All: Yes \n");
  61933. + else
  61934. + mvOsOutput(" Precharge All: No \n");
  61935. +
  61936. + if ( spdRawData[i] & BIT3 )
  61937. + mvOsOutput(" Write 1/ReadBurst: Yes \n");
  61938. + else
  61939. + mvOsOutput(" Write 1/ReadBurst: No \n");
  61940. +
  61941. + if ( spdRawData[i] & BIT4 )
  61942. + mvOsOutput(" lower VCC tolerance: 5%%\n");
  61943. + else
  61944. + mvOsOutput(" lower VCC tolerance: 10%%\n");
  61945. +
  61946. + if ( spdRawData[i] & BIT5 )
  61947. + mvOsOutput(" upper VCC tolerance: 5%%\n");
  61948. + else
  61949. + mvOsOutput(" upper VCC tolerance: 10%%\n");
  61950. + }
  61951. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  61952. + {
  61953. + if ( spdRawData[i] & BIT0 )
  61954. + mvOsOutput(" Supports Weak Driver: Yes \n");
  61955. + else
  61956. + mvOsOutput(" Supports Weak Driver: No \n");
  61957. +
  61958. + if ( !(spdRawData[i] & BIT4) )
  61959. + mvOsOutput(" lower VCC tolerance: 0.2V\n");
  61960. +
  61961. + if ( !(spdRawData[i] & BIT5) )
  61962. + mvOsOutput(" upper VCC tolerance: 0.2V\n");
  61963. +
  61964. + if ( spdRawData[i] & BIT6 )
  61965. + mvOsOutput(" Concurrent Auto Preharge: Yes \n");
  61966. + else
  61967. + mvOsOutput(" Concurrent Auto Preharge: No \n");
  61968. +
  61969. + if ( spdRawData[i] & BIT7 )
  61970. + mvOsOutput(" Supports Fast AP: Yes \n");
  61971. + else
  61972. + mvOsOutput(" Supports Fast AP: No \n");
  61973. + }
  61974. + else if (dimmInfo.memoryType == MEM_TYPE_DDR2)
  61975. + {
  61976. + if ( spdRawData[i] & BIT0 )
  61977. + mvOsOutput(" Supports Weak Driver: Yes \n");
  61978. + else
  61979. + mvOsOutput(" Supports Weak Driver: No \n");
  61980. + }
  61981. + break;
  61982. +/*----------------------------------------------------------------------------*/
  61983. +
  61984. + case 23:
  61985. + /* Minimum Cycle Time At Maximum Cas Latancy Minus 1 (2nd highest CL) */
  61986. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  61987. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  61988. +
  61989. + /* DDR2 addition of right of point */
  61990. + if ((spdRawData[i] & 0x0f) == 0xA)
  61991. + {
  61992. + rightOfPoint = 25;
  61993. + }
  61994. + if ((spdRawData[i] & 0x0f) == 0xB)
  61995. + {
  61996. + rightOfPoint = 33;
  61997. + }
  61998. + if ((spdRawData[i] & 0x0f) == 0xC)
  61999. + {
  62000. + rightOfPoint = 66;
  62001. + }
  62002. + if ((spdRawData[i] & 0x0f) == 0xD)
  62003. + {
  62004. + rightOfPoint = 75;
  62005. + }
  62006. +
  62007. + mvOsOutput("Minimum Cycle Time At 2nd highest CasLatancy"
  62008. + "(0 = Not supported): %d.%d [ns]\n",
  62009. + leftOfPoint, rightOfPoint );
  62010. + break;
  62011. +/*----------------------------------------------------------------------------*/
  62012. +
  62013. + case 24: /* Clock To Data Out 2nd highest Cas Latency Value*/
  62014. + div = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ? 10:100;
  62015. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  62016. + ((spdRawData[i] & 0x0f));
  62017. + leftOfPoint = time_tmp / div;
  62018. + rightOfPoint = time_tmp % div;
  62019. + mvOsOutput("Clock To Data Out (2nd CL value): %d.%d [ns]\n",
  62020. + leftOfPoint, rightOfPoint);
  62021. + break;
  62022. +/*----------------------------------------------------------------------------*/
  62023. +
  62024. + case 25:
  62025. + /* Minimum Cycle Time At Maximum Cas Latancy Minus 2 (3rd highest CL) */
  62026. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  62027. + {
  62028. + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
  62029. + rightOfPoint = (spdRawData[i] & 0x3) * 25;
  62030. + }
  62031. + else /* DDR1 or DDR2 */
  62032. + {
  62033. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  62034. + rightOfPoint = (spdRawData[i] & 0x0f) * 10;
  62035. +
  62036. + /* DDR2 addition of right of point */
  62037. + if ((spdRawData[i] & 0x0f) == 0xA)
  62038. + {
  62039. + rightOfPoint = 25;
  62040. + }
  62041. + if ((spdRawData[i] & 0x0f) == 0xB)
  62042. + {
  62043. + rightOfPoint = 33;
  62044. + }
  62045. + if ((spdRawData[i] & 0x0f) == 0xC)
  62046. + {
  62047. + rightOfPoint = 66;
  62048. + }
  62049. + if ((spdRawData[i] & 0x0f) == 0xD)
  62050. + {
  62051. + rightOfPoint = 75;
  62052. + }
  62053. + }
  62054. + mvOsOutput("Minimum Cycle Time At 3rd highest CasLatancy"
  62055. + "(0 = Not supported): %d.%d [ns]\n",
  62056. + leftOfPoint, rightOfPoint );
  62057. + break;
  62058. +/*----------------------------------------------------------------------------*/
  62059. +
  62060. + case 26: /* Clock To Data Out 3rd highest Cas Latency Value*/
  62061. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  62062. + {
  62063. + leftOfPoint = (spdRawData[i] & 0xfc) >> 2;
  62064. + rightOfPoint = (spdRawData[i] & 0x3) * 25;
  62065. + }
  62066. + else /* DDR1 or DDR2 */
  62067. + {
  62068. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  62069. + ((spdRawData[i] & 0x0f));
  62070. + leftOfPoint = 0;
  62071. + rightOfPoint = time_tmp;
  62072. + }
  62073. + mvOsOutput("Clock To Data Out (3rd CL value): %d.%2d[ns]\n",
  62074. + leftOfPoint, rightOfPoint );
  62075. + break;
  62076. +/*----------------------------------------------------------------------------*/
  62077. +
  62078. + case 27: /* Minimum Row Precharge Time */
  62079. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  62080. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  62081. + 0xff : 0xfc;
  62082. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  62083. + 0x00 : 0x03;
  62084. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  62085. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  62086. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 10ps Intervals*/
  62087. + trp_clocks = (temp + (busClkPs-1)) / busClkPs;
  62088. + mvOsOutput("Minimum Row Precharge Time [ns]: %d.%d = "
  62089. + "in Clk cycles %d\n",
  62090. + leftOfPoint, rightOfPoint, trp_clocks);
  62091. + break;
  62092. +/*----------------------------------------------------------------------------*/
  62093. +
  62094. + case 28: /* Minimum Row Active to Row Active Time */
  62095. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  62096. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  62097. + 0xff : 0xfc;
  62098. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  62099. + 0x00 : 0x03;
  62100. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  62101. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  62102. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
  62103. + trrd_clocks = (temp + (busClkPs-1)) / busClkPs;
  62104. + mvOsOutput("Minimum Row Active -To- Row Active Delay [ns]: "
  62105. + "%d.%d = in Clk cycles %d\n",
  62106. + leftOfPoint, rightOfPoint, trp_clocks);
  62107. + break;
  62108. +/*----------------------------------------------------------------------------*/
  62109. +
  62110. + case 29: /* Minimum Ras-To-Cas Delay */
  62111. + shift = (dimmInfo.memoryType == MEM_TYPE_SDRAM)? 0:2;
  62112. + maskLeftOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  62113. + 0xff : 0xfc;
  62114. + maskRightOfPoint = (dimmInfo.memoryType == MEM_TYPE_SDRAM) ?
  62115. + 0x00 : 0x03;
  62116. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> shift);
  62117. + rightOfPoint = (spdRawData[i] & maskRightOfPoint)*25;
  62118. + temp = ((leftOfPoint*100) + rightOfPoint);/* in 100ns Interval*/
  62119. + trcd_clocks = (temp + (busClkPs-1) )/ busClkPs;
  62120. + mvOsOutput("Minimum Ras-To-Cas Delay [ns]: %d.%d = "
  62121. + "in Clk cycles %d\n",
  62122. + leftOfPoint, rightOfPoint, trp_clocks);
  62123. + break;
  62124. +/*----------------------------------------------------------------------------*/
  62125. +
  62126. + case 30: /* Minimum Ras Pulse Width */
  62127. + tras_clocks = (cas2ps(spdRawData[i])+(busClkPs-1)) / busClkPs;
  62128. + mvOsOutput("Minimum Ras Pulse Width [ns]: %d = "
  62129. + "in Clk cycles %d\n", spdRawData[i], tras_clocks);
  62130. + break;
  62131. +/*----------------------------------------------------------------------------*/
  62132. +
  62133. + case 31: /* Module Bank Density */
  62134. + mvOsOutput("Module Bank Density (more than 1= Multisize-Module):");
  62135. +
  62136. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  62137. + {
  62138. + if (dimmInfo.dimmBankDensity & BIT0)
  62139. + mvOsOutput("1GB, ");
  62140. + if (dimmInfo.dimmBankDensity & BIT1)
  62141. + mvOsOutput("8MB, ");
  62142. + if (dimmInfo.dimmBankDensity & BIT2)
  62143. + mvOsOutput("16MB, ");
  62144. + if (dimmInfo.dimmBankDensity & BIT3)
  62145. + mvOsOutput("32MB, ");
  62146. + if (dimmInfo.dimmBankDensity & BIT4)
  62147. + mvOsOutput("64MB, ");
  62148. + if (dimmInfo.dimmBankDensity & BIT5)
  62149. + mvOsOutput("128MB, ");
  62150. + if (dimmInfo.dimmBankDensity & BIT6)
  62151. + mvOsOutput("256MB, ");
  62152. + if (dimmInfo.dimmBankDensity & BIT7)
  62153. + mvOsOutput("512MB, ");
  62154. + }
  62155. + else if (dimmInfo.memoryType == MEM_TYPE_DDR1)
  62156. + {
  62157. + if (dimmInfo.dimmBankDensity & BIT0)
  62158. + mvOsOutput("1GB, ");
  62159. + if (dimmInfo.dimmBankDensity & BIT1)
  62160. + mvOsOutput("2GB, ");
  62161. + if (dimmInfo.dimmBankDensity & BIT2)
  62162. + mvOsOutput("16MB, ");
  62163. + if (dimmInfo.dimmBankDensity & BIT3)
  62164. + mvOsOutput("32MB, ");
  62165. + if (dimmInfo.dimmBankDensity & BIT4)
  62166. + mvOsOutput("64MB, ");
  62167. + if (dimmInfo.dimmBankDensity & BIT5)
  62168. + mvOsOutput("128MB, ");
  62169. + if (dimmInfo.dimmBankDensity & BIT6)
  62170. + mvOsOutput("256MB, ");
  62171. + if (dimmInfo.dimmBankDensity & BIT7)
  62172. + mvOsOutput("512MB, ");
  62173. + }
  62174. + else /* if (dimmInfo.memoryType == MEM_TYPE_DDR2) */
  62175. + {
  62176. + if (dimmInfo.dimmBankDensity & BIT0)
  62177. + mvOsOutput("1GB, ");
  62178. + if (dimmInfo.dimmBankDensity & BIT1)
  62179. + mvOsOutput("2GB, ");
  62180. + if (dimmInfo.dimmBankDensity & BIT2)
  62181. + mvOsOutput("4GB, ");
  62182. + if (dimmInfo.dimmBankDensity & BIT3)
  62183. + mvOsOutput("8GB, ");
  62184. + if (dimmInfo.dimmBankDensity & BIT4)
  62185. + mvOsOutput("16GB, ");
  62186. + if (dimmInfo.dimmBankDensity & BIT5)
  62187. + mvOsOutput("128MB, ");
  62188. + if (dimmInfo.dimmBankDensity & BIT6)
  62189. + mvOsOutput("256MB, ");
  62190. + if (dimmInfo.dimmBankDensity & BIT7)
  62191. + mvOsOutput("512MB, ");
  62192. + }
  62193. + mvOsOutput("\n");
  62194. + break;
  62195. +/*----------------------------------------------------------------------------*/
  62196. +
  62197. + case 32: /* Address And Command Setup Time (measured in ns/1000) */
  62198. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  62199. + {
  62200. + rightOfPoint = (spdRawData[i] & 0x0f);
  62201. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  62202. + if(leftOfPoint > 7)
  62203. + {
  62204. + leftOfPoint *= -1;
  62205. + }
  62206. + }
  62207. + else /* DDR1 or DDR2 */
  62208. + {
  62209. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  62210. + ((spdRawData[i] & 0x0f));
  62211. + leftOfPoint = time_tmp / 100;
  62212. + rightOfPoint = time_tmp % 100;
  62213. + }
  62214. + mvOsOutput("Address And Command Setup Time [ns]: %d.%d\n",
  62215. + leftOfPoint, rightOfPoint);
  62216. + break;
  62217. +/*----------------------------------------------------------------------------*/
  62218. +
  62219. + case 33: /* Address And Command Hold Time */
  62220. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  62221. + {
  62222. + rightOfPoint = (spdRawData[i] & 0x0f);
  62223. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  62224. + if(leftOfPoint > 7)
  62225. + {
  62226. + leftOfPoint *= -1;
  62227. + }
  62228. + }
  62229. + else /* DDR1 or DDR2 */
  62230. + {
  62231. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  62232. + ((spdRawData[i] & 0x0f));
  62233. + leftOfPoint = time_tmp / 100;
  62234. + rightOfPoint = time_tmp % 100;
  62235. + }
  62236. + mvOsOutput("Address And Command Hold Time [ns]: %d.%d\n",
  62237. + leftOfPoint, rightOfPoint);
  62238. + break;
  62239. +/*----------------------------------------------------------------------------*/
  62240. +
  62241. + case 34: /* Data Input Setup Time */
  62242. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  62243. + {
  62244. + rightOfPoint = (spdRawData[i] & 0x0f);
  62245. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  62246. + if(leftOfPoint > 7)
  62247. + {
  62248. + leftOfPoint *= -1;
  62249. + }
  62250. + }
  62251. + else /* DDR1 or DDR2 */
  62252. + {
  62253. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  62254. + ((spdRawData[i] & 0x0f));
  62255. + leftOfPoint = time_tmp / 100;
  62256. + rightOfPoint = time_tmp % 100;
  62257. + }
  62258. + mvOsOutput("Data Input Setup Time [ns]: %d.%d\n",
  62259. + leftOfPoint, rightOfPoint);
  62260. + break;
  62261. +/*----------------------------------------------------------------------------*/
  62262. +
  62263. + case 35: /* Data Input Hold Time */
  62264. + if (dimmInfo.memoryType == MEM_TYPE_SDRAM)
  62265. + {
  62266. + rightOfPoint = (spdRawData[i] & 0x0f);
  62267. + leftOfPoint = (spdRawData[i] & 0xf0) >> 4;
  62268. + if(leftOfPoint > 7)
  62269. + {
  62270. + leftOfPoint *= -1;
  62271. + }
  62272. + }
  62273. + else /* DDR1 or DDR2 */
  62274. + {
  62275. + time_tmp = (((spdRawData[i] & 0xf0) >> 4)*10) +
  62276. + ((spdRawData[i] & 0x0f));
  62277. + leftOfPoint = time_tmp / 100;
  62278. + rightOfPoint = time_tmp % 100;
  62279. + }
  62280. + mvOsOutput("Data Input Hold Time [ns]: %d.%d\n\n",
  62281. + leftOfPoint, rightOfPoint);
  62282. + break;
  62283. +/*----------------------------------------------------------------------------*/
  62284. +
  62285. + case 36: /* Relevant for DDR2 only: Write Recovery Time */
  62286. + leftOfPoint = ((spdRawData[i] & maskLeftOfPoint) >> 2);
  62287. + rightOfPoint = (spdRawData[i] & maskRightOfPoint) * 25;
  62288. + mvOsOutput("Write Recovery Time [ns]: %d.%d\n",
  62289. + leftOfPoint, rightOfPoint);
  62290. + break;
  62291. +/*----------------------------------------------------------------------------*/
  62292. + }
  62293. +
  62294. +}
  62295. +
  62296. +
  62297. +/*
  62298. + * translate ns.ns/10 coding of SPD timing values
  62299. + * into ps unit values
  62300. + */
  62301. +/*******************************************************************************
  62302. +* cas2ps - Translate x.y ns parameter to pico-seconds values
  62303. +*
  62304. +* DESCRIPTION:
  62305. +* This function translates x.y nano seconds to its value in pico seconds.
  62306. +* For example 3.75ns will return 3750.
  62307. +*
  62308. +* INPUT:
  62309. +* spd_byte - DIMM SPD byte.
  62310. +*
  62311. +* OUTPUT:
  62312. +* None.
  62313. +*
  62314. +* RETURN:
  62315. +* value in pico seconds.
  62316. +*
  62317. +*******************************************************************************/
  62318. +static MV_U32 cas2ps(MV_U8 spd_byte)
  62319. +{
  62320. + MV_U32 ns, ns10;
  62321. +
  62322. + /* isolate upper nibble */
  62323. + ns = (spd_byte >> 4) & 0x0F;
  62324. + /* isolate lower nibble */
  62325. + ns10 = (spd_byte & 0x0F);
  62326. +
  62327. + if( ns10 < 10 ) {
  62328. + ns10 *= 10;
  62329. + }
  62330. + else if( ns10 == 10 )
  62331. + ns10 = 25;
  62332. + else if( ns10 == 11 )
  62333. + ns10 = 33;
  62334. + else if( ns10 == 12 )
  62335. + ns10 = 66;
  62336. + else if( ns10 == 13 )
  62337. + ns10 = 75;
  62338. + else
  62339. + {
  62340. + mvOsOutput("cas2ps Err. unsupported cycle time.\n");
  62341. + }
  62342. +
  62343. + return (ns*1000 + ns10*10);
  62344. +}
  62345. +
  62346. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h
  62347. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h 1970-01-01 01:00:00.000000000 +0100
  62348. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/ddr2/spd/mvSpd.h 2011-08-01 14:38:19.000000000 +0200
  62349. @@ -0,0 +1,192 @@
  62350. +/*******************************************************************************
  62351. +Copyright (C) Marvell International Ltd. and its affiliates
  62352. +
  62353. +This software file (the "File") is owned and distributed by Marvell
  62354. +International Ltd. and/or its affiliates ("Marvell") under the following
  62355. +alternative licensing terms. Once you have made an election to distribute the
  62356. +File under one of the following license alternatives, please (i) delete this
  62357. +introductory statement regarding license alternatives, (ii) delete the two
  62358. +license alternatives that you have not elected to use and (iii) preserve the
  62359. +Marvell copyright notice above.
  62360. +
  62361. +********************************************************************************
  62362. +Marvell Commercial License Option
  62363. +
  62364. +If you received this File from Marvell and you have entered into a commercial
  62365. +license agreement (a "Commercial License") with Marvell, the File is licensed
  62366. +to you under the terms of the applicable Commercial License.
  62367. +
  62368. +********************************************************************************
  62369. +Marvell GPL License Option
  62370. +
  62371. +If you received this File from Marvell, you may opt to use, redistribute and/or
  62372. +modify this File in accordance with the terms and conditions of the General
  62373. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  62374. +available along with the File in the license.txt file or by writing to the Free
  62375. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  62376. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  62377. +
  62378. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  62379. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  62380. +DISCLAIMED. The GPL License provides additional details about this warranty
  62381. +disclaimer.
  62382. +********************************************************************************
  62383. +Marvell BSD License Option
  62384. +
  62385. +If you received this File from Marvell, you may opt to use, redistribute and/or
  62386. +modify this File under the following licensing terms.
  62387. +Redistribution and use in source and binary forms, with or without modification,
  62388. +are permitted provided that the following conditions are met:
  62389. +
  62390. + * Redistributions of source code must retain the above copyright notice,
  62391. + this list of conditions and the following disclaimer.
  62392. +
  62393. + * Redistributions in binary form must reproduce the above copyright
  62394. + notice, this list of conditions and the following disclaimer in the
  62395. + documentation and/or other materials provided with the distribution.
  62396. +
  62397. + * Neither the name of Marvell nor the names of its contributors may be
  62398. + used to endorse or promote products derived from this software without
  62399. + specific prior written permission.
  62400. +
  62401. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  62402. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  62403. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  62404. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  62405. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  62406. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  62407. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  62408. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  62409. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  62410. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  62411. +
  62412. +*******************************************************************************/
  62413. +
  62414. +#ifndef __INCmvDram
  62415. +#define __INCmvDram
  62416. +
  62417. +#include "ddr2/mvDramIf.h"
  62418. +#include "twsi/mvTwsi.h"
  62419. +
  62420. +#define MAX_DIMM_NUM 2
  62421. +#define SPD_SIZE 128
  62422. +
  62423. +/* Dimm spd offsets */
  62424. +#define DIMM_MEM_TYPE 2
  62425. +#define DIMM_ROW_NUM 3
  62426. +#define DIMM_COL_NUM 4
  62427. +#define DIMM_MODULE_BANK_NUM 5
  62428. +#define DIMM_DATA_WIDTH 6
  62429. +#define DIMM_VOLT_IF 8
  62430. +#define DIMM_MIN_CC_AT_MAX_CAS 9
  62431. +#define DIMM_ERR_CHECK_TYPE 11
  62432. +#define DIMM_REFRESH_INTERVAL 12
  62433. +#define DIMM_SDRAM_WIDTH 13
  62434. +#define DIMM_ERR_CHECK_DATA_WIDTH 14
  62435. +#define DIMM_MIN_CLK_DEL 15
  62436. +#define DIMM_BURST_LEN_SUP 16
  62437. +#define DIMM_DEV_BANK_NUM 17
  62438. +#define DIMM_SUP_CAL 18
  62439. +#define DIMM_DDR2_TYPE_INFORMATION 20 /* DDR2 only */
  62440. +#define DIMM_BUF_ADDR_CONT_IN 21
  62441. +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS1 23
  62442. +#define DIMM_MIN_CC_AT_MAX_CAS_MINUS2 25
  62443. +#define DIMM_MIN_ROW_PRECHARGE_TIME 27
  62444. +#define DIMM_MIN_ROW_ACTIVE_TO_ROW_ACTIVE 28
  62445. +#define DIMM_MIN_RAS_TO_CAS_DELAY 29
  62446. +#define DIMM_MIN_RAS_PULSE_WIDTH 30
  62447. +#define DIMM_BANK_DENSITY 31
  62448. +#define DIMM_MIN_WRITE_RECOVERY_TIME 36
  62449. +#define DIMM_MIN_WRITE_TO_READ_CMD_DELAY 37
  62450. +#define DIMM_MIN_READ_TO_PRECH_CMD_DELAY 38
  62451. +#define DIMM_MIN_REFRESH_TO_ACTIVATE_CMD 42
  62452. +#define DIMM_SPD_VERSION 62
  62453. +
  62454. +/* Dimm Memory Type values */
  62455. +#define DIMM_MEM_TYPE_SDRAM 0x4
  62456. +#define DIMM_MEM_TYPE_DDR1 0x7
  62457. +#define DIMM_MEM_TYPE_DDR2 0x8
  62458. +
  62459. +#define DIMM_MODULE_MANU_OFFS 64
  62460. +#define DIMM_MODULE_MANU_SIZE 8
  62461. +#define DIMM_MODULE_VEN_OFFS 73
  62462. +#define DIMM_MODULE_VEN_SIZE 25
  62463. +#define DIMM_MODULE_ID_OFFS 99
  62464. +#define DIMM_MODULE_ID_SIZE 18
  62465. +
  62466. +/* enumeration for voltage levels. */
  62467. +typedef enum _mvDimmVoltageIf
  62468. +{
  62469. + TTL_5V_TOLERANT,
  62470. + LVTTL,
  62471. + HSTL_1_5V,
  62472. + SSTL_3_3V,
  62473. + SSTL_2_5V,
  62474. + VOLTAGE_UNKNOWN,
  62475. +} MV_DIMM_VOLTAGE_IF;
  62476. +
  62477. +
  62478. +/* enumaration for SDRAM CAS Latencies. */
  62479. +typedef enum _mvDimmSdramCas
  62480. +{
  62481. + SD_CL_1 =1,
  62482. + SD_CL_2,
  62483. + SD_CL_3,
  62484. + SD_CL_4,
  62485. + SD_CL_5,
  62486. + SD_CL_6,
  62487. + SD_CL_7,
  62488. + SD_FAULT
  62489. +}MV_DIMM_SDRAM_CAS;
  62490. +
  62491. +
  62492. +/* DIMM information structure */
  62493. +typedef struct _mvDimmInfo
  62494. +{
  62495. + MV_MEMORY_TYPE memoryType; /* DDR or SDRAM */
  62496. +
  62497. + MV_U8 spdRawData[SPD_SIZE]; /* Content of SPD-EEPROM copied 1:1 */
  62498. +
  62499. + /* DIMM dimensions */
  62500. + MV_U32 numOfRowAddr;
  62501. + MV_U32 numOfColAddr;
  62502. + MV_U32 numOfModuleBanks;
  62503. + MV_U32 dataWidth;
  62504. + MV_U32 errorCheckType; /* ECC , PARITY..*/
  62505. + MV_U32 sdramWidth; /* 4,8,16 or 32 */
  62506. + MV_U32 errorCheckDataWidth; /* 0 - no, 1 - Yes */
  62507. + MV_U32 burstLengthSupported;
  62508. + MV_U32 numOfBanksOnEachDevice;
  62509. + MV_U32 suportedCasLatencies;
  62510. + MV_U32 refreshInterval;
  62511. + MV_U32 dimmBankDensity;
  62512. + MV_U32 dimmTypeInfo; /* DDR2 only */
  62513. + MV_U32 dimmAttributes;
  62514. +
  62515. + /* DIMM timing parameters */
  62516. + MV_U32 minCycleTimeAtMaxCasLatPs;
  62517. + MV_U32 minCycleTimeAtMaxCasLatMinus1Ps;
  62518. + MV_U32 minCycleTimeAtMaxCasLatMinus2Ps;
  62519. + MV_U32 minRowPrechargeTime;
  62520. + MV_U32 minRowActiveToRowActive;
  62521. + MV_U32 minRasToCasDelay;
  62522. + MV_U32 minRasPulseWidth;
  62523. + MV_U32 minWriteRecoveryTime; /* DDR2 only */
  62524. + MV_U32 minWriteToReadCmdDelay; /* DDR2 only */
  62525. + MV_U32 minReadToPrechCmdDelay; /* DDR2 only */
  62526. + MV_U32 minRefreshToActiveCmd; /* DDR2 only */
  62527. +
  62528. + /* Parameters calculated from the extracted DIMM information */
  62529. + MV_U32 size; /* 16,64,128,256 or 512 MByte in MB units */
  62530. + MV_U32 deviceDensity; /* 16,64,128,256 or 512 Mbit in MB units */
  62531. + MV_U32 numberOfDevices;
  62532. +
  62533. +} MV_DIMM_INFO;
  62534. +
  62535. +
  62536. +MV_STATUS mvDramBankInfoGet(MV_U32 bankNum, MV_DRAM_BANK_INFO *pBankInfo);
  62537. +MV_STATUS dimmSpdGet(MV_U32 dimmNum, MV_DIMM_INFO *pDimmInfo);
  62538. +MV_VOID dimmSpdPrint(MV_U32 dimmNum);
  62539. +MV_STATUS dimmSpdCpy(MV_VOID);
  62540. +
  62541. +#endif /* __INCmvDram */
  62542. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c
  62543. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c 1970-01-01 01:00:00.000000000 +0100
  62544. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEth.c 2011-08-01 14:38:19.000000000 +0200
  62545. @@ -0,0 +1,2952 @@
  62546. +/*******************************************************************************
  62547. +Copyright (C) Marvell International Ltd. and its affiliates
  62548. +
  62549. +This software file (the "File") is owned and distributed by Marvell
  62550. +International Ltd. and/or its affiliates ("Marvell") under the following
  62551. +alternative licensing terms. Once you have made an election to distribute the
  62552. +File under one of the following license alternatives, please (i) delete this
  62553. +introductory statement regarding license alternatives, (ii) delete the two
  62554. +license alternatives that you have not elected to use and (iii) preserve the
  62555. +Marvell copyright notice above.
  62556. +
  62557. +********************************************************************************
  62558. +Marvell Commercial License Option
  62559. +
  62560. +If you received this File from Marvell and you have entered into a commercial
  62561. +license agreement (a "Commercial License") with Marvell, the File is licensed
  62562. +to you under the terms of the applicable Commercial License.
  62563. +
  62564. +********************************************************************************
  62565. +Marvell GPL License Option
  62566. +
  62567. +If you received this File from Marvell, you may opt to use, redistribute and/or
  62568. +modify this File in accordance with the terms and conditions of the General
  62569. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  62570. +available along with the File in the license.txt file or by writing to the Free
  62571. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  62572. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  62573. +
  62574. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  62575. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  62576. +DISCLAIMED. The GPL License provides additional details about this warranty
  62577. +disclaimer.
  62578. +********************************************************************************
  62579. +Marvell BSD License Option
  62580. +
  62581. +If you received this File from Marvell, you may opt to use, redistribute and/or
  62582. +modify this File under the following licensing terms.
  62583. +Redistribution and use in source and binary forms, with or without modification,
  62584. +are permitted provided that the following conditions are met:
  62585. +
  62586. + * Redistributions of source code must retain the above copyright notice,
  62587. + this list of conditions and the following disclaimer.
  62588. +
  62589. + * Redistributions in binary form must reproduce the above copyright
  62590. + notice, this list of conditions and the following disclaimer in the
  62591. + documentation and/or other materials provided with the distribution.
  62592. +
  62593. + * Neither the name of Marvell nor the names of its contributors may be
  62594. + used to endorse or promote products derived from this software without
  62595. + specific prior written permission.
  62596. +
  62597. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  62598. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  62599. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  62600. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  62601. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  62602. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  62603. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  62604. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  62605. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  62606. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  62607. +
  62608. +*******************************************************************************/
  62609. +
  62610. +/*******************************************************************************
  62611. +* mvEth.c - Marvell's Gigabit Ethernet controller low level driver
  62612. +*
  62613. +* DESCRIPTION:
  62614. +* This file introduce OS independent APIs to Marvell's Gigabit Ethernet
  62615. +* controller. This Gigabit Ethernet Controller driver API controls
  62616. +* 1) Operations (i.e. port Init, Finish, Up, Down, PhyReset etc').
  62617. +* 2) Data flow (i.e. port Send, Receive etc').
  62618. +* 3) MAC Filtering functions (ethSetMcastAddr, ethSetRxFilterMode, etc.)
  62619. +* 4) MIB counters support (ethReadMibCounter)
  62620. +* 5) Debug functions (ethPortRegs, ethPortCounters, ethPortQueues, etc.)
  62621. +* Each Gigabit Ethernet port is controlled via ETH_PORT_CTRL struct.
  62622. +* This struct includes configuration information as well as driver
  62623. +* internal data needed for its operations.
  62624. +*
  62625. +* Supported Features:
  62626. +* - OS independent. All required OS services are implemented via external
  62627. +* OS dependent components (like osLayer or ethOsg)
  62628. +* - The user is free from Rx/Tx queue managing.
  62629. +* - Simple Gigabit Ethernet port operation API.
  62630. +* - Simple Gigabit Ethernet port data flow API.
  62631. +* - Data flow and operation API support per queue functionality.
  62632. +* - Support cached descriptors for better performance.
  62633. +* - PHY access and control API.
  62634. +* - Port Configuration API.
  62635. +* - Full control over Special and Other Multicast MAC tables.
  62636. +*
  62637. +*******************************************************************************/
  62638. +/* includes */
  62639. +#include "mvTypes.h"
  62640. +#include "mv802_3.h"
  62641. +#include "mvDebug.h"
  62642. +#include "mvCommon.h"
  62643. +#include "mvOs.h"
  62644. +#include "ctrlEnv/mvCtrlEnvLib.h"
  62645. +#include "eth-phy/mvEthPhy.h"
  62646. +#include "eth/mvEth.h"
  62647. +#include "eth/gbe/mvEthGbe.h"
  62648. +#include "cpu/mvCpu.h"
  62649. +
  62650. +#ifdef INCLUDE_SYNC_BARR
  62651. +#include "sys/mvCpuIf.h"
  62652. +#endif
  62653. +
  62654. +#ifdef MV_RT_DEBUG
  62655. +# define ETH_DEBUG
  62656. +#endif
  62657. +
  62658. +
  62659. +/* locals */
  62660. +MV_BOOL ethDescInSram;
  62661. +MV_BOOL ethDescSwCoher;
  62662. +
  62663. +/* This array holds the control structure of each port */
  62664. +ETH_PORT_CTRL* ethPortCtrl[MV_ETH_MAX_PORTS];
  62665. +
  62666. +/* Ethernet Port Local routines */
  62667. +
  62668. +static void ethInitRxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue);
  62669. +
  62670. +static void ethInitTxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue);
  62671. +
  62672. +static void ethSetUcastTable(int portNo, int queue);
  62673. +
  62674. +static MV_BOOL ethSetUcastAddr (int ethPortNum, MV_U8 lastNibble, int queue);
  62675. +static MV_BOOL ethSetSpecialMcastAddr(int ethPortNum, MV_U8 lastByte, int queue);
  62676. +static MV_BOOL ethSetOtherMcastAddr(int ethPortNum, MV_U8 crc8, int queue);
  62677. +
  62678. +static void ethFreeDescrMemory(ETH_PORT_CTRL* pEthPortCtrl, MV_BUF_INFO* pDescBuf);
  62679. +static MV_U8* ethAllocDescrMemory(ETH_PORT_CTRL* pEthPortCtrl, int size,
  62680. + MV_ULONG* pPhysAddr, MV_U32 *memHandle);
  62681. +
  62682. +static MV_U32 mvEthMruGet(MV_U32 maxRxPktSize);
  62683. +
  62684. +static void mvEthPortSgmiiConfig(int port);
  62685. +
  62686. +
  62687. +
  62688. +/******************************************************************************/
  62689. +/* EthDrv Initialization functions */
  62690. +/******************************************************************************/
  62691. +
  62692. +/*******************************************************************************
  62693. +* mvEthHalInit - Initialize the Giga Ethernet unit
  62694. +*
  62695. +* DESCRIPTION:
  62696. +* This function initialize the Giga Ethernet unit.
  62697. +* 1) Configure Address decode windows of the unit
  62698. +* 2) Set registers to HW default values.
  62699. +* 3) Clear and Disable interrupts
  62700. +*
  62701. +* INPUT: NONE
  62702. +*
  62703. +* RETURN: NONE
  62704. +*
  62705. +* NOTE: this function is called once in the boot process.
  62706. +*******************************************************************************/
  62707. +void mvEthHalInit(void)
  62708. +{
  62709. + int port;
  62710. +
  62711. + /* Init static data structures */
  62712. + for (port=0; port<MV_ETH_MAX_PORTS; port++)
  62713. + {
  62714. + ethPortCtrl[port] = NULL;
  62715. + }
  62716. + /* Power down all existing ports */
  62717. + for(port=0; port<mvCtrlEthMaxPortGet(); port++)
  62718. + {
  62719. +
  62720. +#if defined (MV78200)
  62721. + /* Skip ports mapped to another CPU*/
  62722. + if (MV_FALSE == mvSocUnitIsMappedToThisCpu(GIGA0+port))
  62723. + {
  62724. + continue;
  62725. + }
  62726. +#endif
  62727. +
  62728. + /* Skip power down ports */
  62729. + if (MV_FALSE == mvCtrlPwrClckGet(ETH_GIG_UNIT_ID, port)) continue;
  62730. +
  62731. + /* Disable Giga Ethernet Unit interrupts */
  62732. + MV_REG_WRITE(ETH_UNIT_INTR_MASK_REG(port), 0);
  62733. +
  62734. + /* Clear ETH_UNIT_INTR_CAUSE_REG register */
  62735. + MV_REG_WRITE(ETH_UNIT_INTR_CAUSE_REG(port), 0);
  62736. +
  62737. + }
  62738. +
  62739. + mvEthMemAttrGet(&ethDescInSram, &ethDescSwCoher);
  62740. +
  62741. +#if defined(ETH_DESCR_IN_SRAM)
  62742. + if(ethDescInSram == MV_FALSE)
  62743. + {
  62744. + mvOsPrintf("ethDrv: WARNING! Descriptors will be allocated in DRAM instead of SRAM.\n");
  62745. + }
  62746. +#endif /* ETH_DESCR_IN_SRAM */
  62747. +}
  62748. +
  62749. +/*******************************************************************************
  62750. +* mvEthMemAttrGet - Define properties (SRAM/DRAM, SW_COHER / HW_COHER / UNCACHED)
  62751. +* of of memory location for RX and TX descriptors.
  62752. +*
  62753. +* DESCRIPTION:
  62754. +* This function allocates memory for RX and TX descriptors.
  62755. +* - If ETH_DESCR_IN_SRAM defined, allocate from SRAM memory.
  62756. +* - If ETH_DESCR_IN_SDRAM defined, allocate from SDRAM memory.
  62757. +*
  62758. +* INPUT:
  62759. +* MV_BOOL* pIsSram - place of descriptors:
  62760. +* MV_TRUE - in SRAM
  62761. +* MV_FALSE - in DRAM
  62762. +* MV_BOOL* pIsSwCoher - cache coherency of descriptors:
  62763. +* MV_TRUE - driver is responsible for cache coherency
  62764. +* MV_FALSE - driver is not responsible for cache coherency
  62765. +*
  62766. +* RETURN:
  62767. +*
  62768. +*******************************************************************************/
  62769. +void mvEthMemAttrGet(MV_BOOL* pIsSram, MV_BOOL* pIsSwCoher)
  62770. +{
  62771. + MV_BOOL isSram, isSwCoher;
  62772. +
  62773. + isSram = MV_FALSE;
  62774. +#if (ETHER_DRAM_COHER == MV_CACHE_COHER_SW)
  62775. + isSwCoher = MV_TRUE;
  62776. +#else
  62777. + isSwCoher = MV_FALSE;
  62778. +#endif
  62779. +
  62780. +#if defined(ETH_DESCR_IN_SRAM)
  62781. + if( mvCtrlSramSizeGet() > 0)
  62782. + {
  62783. + isSram = MV_TRUE;
  62784. + #if (INTEG_SRAM_COHER == MV_CACHE_COHER_SW)
  62785. + isSwCoher = MV_TRUE;
  62786. + #else
  62787. + isSwCoher = MV_FALSE;
  62788. + #endif
  62789. + }
  62790. +#endif /* ETH_DESCR_IN_SRAM */
  62791. +
  62792. + if(pIsSram != NULL)
  62793. + *pIsSram = isSram;
  62794. +
  62795. + if(pIsSwCoher != NULL)
  62796. + *pIsSwCoher = isSwCoher;
  62797. +}
  62798. +
  62799. +
  62800. +
  62801. +/******************************************************************************/
  62802. +/* Port Initialization functions */
  62803. +/******************************************************************************/
  62804. +
  62805. +/*******************************************************************************
  62806. +* mvEthPortInit - Initialize the Ethernet port driver
  62807. +*
  62808. +* DESCRIPTION:
  62809. +* This function initialize the ethernet port.
  62810. +* 1) Allocate and initialize internal port Control structure.
  62811. +* 2) Create RX and TX descriptor rings for default RX and TX queues
  62812. +* 3) Disable RX and TX operations, clear cause registers and
  62813. +* mask all interrupts.
  62814. +* 4) Set all registers to default values and clean all MAC tables.
  62815. +*
  62816. +* INPUT:
  62817. +* int portNo - Ethernet port number
  62818. +* ETH_PORT_INIT *pEthPortInit - Ethernet port init structure
  62819. +*
  62820. +* RETURN:
  62821. +* void* - ethernet port handler, that should be passed to the most other
  62822. +* functions dealing with this port.
  62823. +*
  62824. +* NOTE: This function is called once per port when loading the eth module.
  62825. +*******************************************************************************/
  62826. +void* mvEthPortInit(int portNo, MV_ETH_PORT_INIT *pEthPortInit)
  62827. +{
  62828. + int queue, descSize;
  62829. + ETH_PORT_CTRL* pPortCtrl;
  62830. +
  62831. + /* Check validity of parameters */
  62832. + if( (portNo >= (int)mvCtrlEthMaxPortGet()) ||
  62833. + (pEthPortInit->rxDefQ >= MV_ETH_RX_Q_NUM) ||
  62834. + (pEthPortInit->maxRxPktSize < 1518) )
  62835. + {
  62836. + mvOsPrintf("EthPort #%d: Bad initialization parameters\n", portNo);
  62837. + return NULL;
  62838. + }
  62839. + if( (pEthPortInit->rxDescrNum[pEthPortInit->rxDefQ]) == 0)
  62840. + {
  62841. + mvOsPrintf("EthPort #%d: rxDefQ (%d) must be created\n",
  62842. + portNo, pEthPortInit->rxDefQ);
  62843. + return NULL;
  62844. + }
  62845. +
  62846. + pPortCtrl = (ETH_PORT_CTRL*)mvOsMalloc( sizeof(ETH_PORT_CTRL) );
  62847. + if(pPortCtrl == NULL)
  62848. + {
  62849. + mvOsPrintf("EthDrv: Can't allocate %dB for port #%d control structure!\n",
  62850. + (int)sizeof(ETH_PORT_CTRL), portNo);
  62851. + return NULL;
  62852. + }
  62853. +
  62854. + memset(pPortCtrl, 0, sizeof(ETH_PORT_CTRL) );
  62855. + ethPortCtrl[portNo] = pPortCtrl;
  62856. +
  62857. + pPortCtrl->portState = MV_UNDEFINED_STATE;
  62858. +
  62859. + pPortCtrl->portNo = portNo;
  62860. +
  62861. + pPortCtrl->osHandle = pEthPortInit->osHandle;
  62862. +
  62863. + /* Copy Configuration parameters */
  62864. + pPortCtrl->portConfig.maxRxPktSize = pEthPortInit->maxRxPktSize;
  62865. + pPortCtrl->portConfig.rxDefQ = pEthPortInit->rxDefQ;
  62866. + pPortCtrl->portConfig.ejpMode = 0;
  62867. +
  62868. + for( queue=0; queue<MV_ETH_RX_Q_NUM; queue++ )
  62869. + {
  62870. + pPortCtrl->rxQueueConfig[queue].descrNum = pEthPortInit->rxDescrNum[queue];
  62871. + }
  62872. + for( queue=0; queue<MV_ETH_TX_Q_NUM; queue++ )
  62873. + {
  62874. + pPortCtrl->txQueueConfig[queue].descrNum = pEthPortInit->txDescrNum[queue];
  62875. + }
  62876. +
  62877. + mvEthPortDisable(pPortCtrl);
  62878. +
  62879. + /* Set the board information regarding PHY address */
  62880. + mvEthPhyAddrSet(pPortCtrl, mvBoardPhyAddrGet(portNo) );
  62881. +
  62882. + /* Create all requested RX queues */
  62883. + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
  62884. + {
  62885. + if(pPortCtrl->rxQueueConfig[queue].descrNum == 0)
  62886. + continue;
  62887. +
  62888. + /* Allocate memory for RX descriptors */
  62889. + descSize = ((pPortCtrl->rxQueueConfig[queue].descrNum * ETH_RX_DESC_ALIGNED_SIZE) +
  62890. + CPU_D_CACHE_LINE_SIZE);
  62891. +
  62892. + pPortCtrl->rxQueue[queue].descBuf.bufVirtPtr =
  62893. + ethAllocDescrMemory(pPortCtrl, descSize,
  62894. + &pPortCtrl->rxQueue[queue].descBuf.bufPhysAddr,
  62895. + &pPortCtrl->rxQueue[queue].descBuf.memHandle);
  62896. + pPortCtrl->rxQueue[queue].descBuf.bufSize = descSize;
  62897. + if(pPortCtrl->rxQueue[queue].descBuf.bufVirtPtr == NULL)
  62898. + {
  62899. + mvOsPrintf("EthPort #%d, rxQ=%d: Can't allocate %d bytes in %s for %d RX descr\n",
  62900. + pPortCtrl->portNo, queue, descSize,
  62901. + ethDescInSram ? "SRAM" : "DRAM",
  62902. + pPortCtrl->rxQueueConfig[queue].descrNum);
  62903. + return NULL;
  62904. + }
  62905. +
  62906. + ethInitRxDescRing(pPortCtrl, queue);
  62907. + }
  62908. + /* Create TX queues */
  62909. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  62910. + {
  62911. + if(pPortCtrl->txQueueConfig[queue].descrNum == 0)
  62912. + continue;
  62913. +
  62914. + /* Allocate memory for TX descriptors */
  62915. + descSize = ((pPortCtrl->txQueueConfig[queue].descrNum * ETH_TX_DESC_ALIGNED_SIZE) +
  62916. + CPU_D_CACHE_LINE_SIZE);
  62917. +
  62918. + pPortCtrl->txQueue[queue].descBuf.bufVirtPtr =
  62919. + ethAllocDescrMemory(pPortCtrl, descSize,
  62920. + &pPortCtrl->txQueue[queue].descBuf.bufPhysAddr,
  62921. + &pPortCtrl->txQueue[queue].descBuf.memHandle);
  62922. + pPortCtrl->txQueue[queue].descBuf.bufSize = descSize;
  62923. + if(pPortCtrl->txQueue[queue].descBuf.bufVirtPtr == NULL)
  62924. + {
  62925. + mvOsPrintf("EthPort #%d, txQ=%d: Can't allocate %d bytes in %s for %d TX descr\n",
  62926. + pPortCtrl->portNo, queue, descSize, ethDescInSram ? "SRAM" : "DRAM",
  62927. + pPortCtrl->txQueueConfig[queue].descrNum);
  62928. + return NULL;
  62929. + }
  62930. +
  62931. + ethInitTxDescRing(pPortCtrl, queue);
  62932. + }
  62933. + mvEthDefaultsSet(pPortCtrl);
  62934. +
  62935. + pPortCtrl->portState = MV_IDLE;
  62936. + return pPortCtrl;
  62937. +}
  62938. +
  62939. +/*******************************************************************************
  62940. +* ethPortFinish - Finish the Ethernet port driver
  62941. +*
  62942. +* DESCRIPTION:
  62943. +* This function finish the ethernet port.
  62944. +* 1) Down ethernet port if needed.
  62945. +* 2) Delete RX and TX descriptor rings for all created RX and TX queues
  62946. +* 3) Free internal port Control structure.
  62947. +*
  62948. +* INPUT:
  62949. +* void* pEthPortHndl - Ethernet port handler
  62950. +*
  62951. +* RETURN: NONE.
  62952. +*
  62953. +*******************************************************************************/
  62954. +void mvEthPortFinish(void* pPortHndl)
  62955. +{
  62956. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  62957. + int queue, portNo = pPortCtrl->portNo;
  62958. +
  62959. + if(pPortCtrl->portState == MV_ACTIVE)
  62960. + {
  62961. + mvOsPrintf("ethPort #%d: Warning !!! Finish port in Active state\n",
  62962. + portNo);
  62963. + mvEthPortDisable(pPortHndl);
  62964. + }
  62965. +
  62966. + /* Free all allocated RX queues */
  62967. + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
  62968. + {
  62969. + ethFreeDescrMemory(pPortCtrl, &pPortCtrl->rxQueue[queue].descBuf);
  62970. + }
  62971. +
  62972. + /* Free all allocated TX queues */
  62973. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  62974. + {
  62975. + ethFreeDescrMemory(pPortCtrl, &pPortCtrl->txQueue[queue].descBuf);
  62976. + }
  62977. +
  62978. + /* Free port control structure */
  62979. + mvOsFree(pPortCtrl);
  62980. +
  62981. + ethPortCtrl[portNo] = NULL;
  62982. +}
  62983. +
  62984. +/*******************************************************************************
  62985. +* mvEthDefaultsSet - Set defaults to the ethernet port
  62986. +*
  62987. +* DESCRIPTION:
  62988. +* This function set default values to the ethernet port.
  62989. +* 1) Clear Cause registers and Mask all interrupts
  62990. +* 2) Clear all MAC tables
  62991. +* 3) Set defaults to all registers
  62992. +* 4) Reset all created RX and TX descriptors ring
  62993. +* 5) Reset PHY
  62994. +*
  62995. +* INPUT:
  62996. +* void* pEthPortHndl - Ethernet port handler
  62997. +*
  62998. +* RETURN: MV_STATUS
  62999. +* MV_OK - Success, Others - Failure
  63000. +* NOTE:
  63001. +* This function update all the port configuration except those set
  63002. +* Initialy by the OsGlue by MV_ETH_PORT_INIT.
  63003. +* This function can be called after portDown to return the port setting
  63004. +* to defaults.
  63005. +*******************************************************************************/
  63006. +MV_STATUS mvEthDefaultsSet(void* pPortHndl)
  63007. +{
  63008. + int ethPortNo, queue;
  63009. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  63010. + ETH_QUEUE_CTRL* pQueueCtrl;
  63011. + MV_U32 txPrio;
  63012. + MV_U32 portCfgReg, portCfgExtReg, portSerialCtrlReg, portSerialCtrl1Reg, portSdmaCfgReg;
  63013. + MV_BOARD_MAC_SPEED boardMacCfg;
  63014. +
  63015. + ethPortNo = pPortCtrl->portNo;
  63016. +
  63017. + /* Clear Cause registers */
  63018. + MV_REG_WRITE(ETH_INTR_CAUSE_REG(ethPortNo),0);
  63019. + MV_REG_WRITE(ETH_INTR_CAUSE_EXT_REG(ethPortNo),0);
  63020. +
  63021. + /* Mask all interrupts */
  63022. + MV_REG_WRITE(ETH_INTR_MASK_REG(ethPortNo),0);
  63023. + MV_REG_WRITE(ETH_INTR_MASK_EXT_REG(ethPortNo),0);
  63024. +
  63025. + portCfgReg = PORT_CONFIG_VALUE;
  63026. + portCfgExtReg = PORT_CONFIG_EXTEND_VALUE;
  63027. +
  63028. + boardMacCfg = mvBoardMacSpeedGet(ethPortNo);
  63029. +
  63030. + if(boardMacCfg == BOARD_MAC_SPEED_100M)
  63031. + {
  63032. + portSerialCtrlReg = PORT_SERIAL_CONTROL_100MB_FORCE_VALUE;
  63033. + }
  63034. + else if(boardMacCfg == BOARD_MAC_SPEED_1000M)
  63035. + {
  63036. + portSerialCtrlReg = PORT_SERIAL_CONTROL_1000MB_FORCE_VALUE;
  63037. + }
  63038. + else
  63039. + {
  63040. + portSerialCtrlReg = PORT_SERIAL_CONTROL_VALUE;
  63041. + }
  63042. +
  63043. + /* build PORT_SDMA_CONFIG_REG */
  63044. + portSdmaCfgReg = ETH_TX_INTR_COAL_MASK(0);
  63045. + portSdmaCfgReg |= ETH_TX_BURST_SIZE_MASK(ETH_BURST_SIZE_16_64BIT_VALUE);
  63046. +
  63047. +#if ( (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WB) || \
  63048. + (ETHER_DRAM_COHER == MV_CACHE_COHER_HW_WT) )
  63049. + /* some devices have restricted RX burst size when using HW coherency */
  63050. + portSdmaCfgReg |= ETH_RX_BURST_SIZE_MASK(ETH_BURST_SIZE_4_64BIT_VALUE);
  63051. +#else
  63052. + portSdmaCfgReg |= ETH_RX_BURST_SIZE_MASK(ETH_BURST_SIZE_16_64BIT_VALUE);
  63053. +#endif
  63054. +
  63055. +#if defined(MV_CPU_BE)
  63056. + /* big endian */
  63057. +# if defined(MV_ARM)
  63058. + portSdmaCfgReg |= (ETH_RX_NO_DATA_SWAP_MASK |
  63059. + ETH_TX_NO_DATA_SWAP_MASK |
  63060. + ETH_DESC_SWAP_MASK);
  63061. +# elif defined(MV_PPC)
  63062. + portSdmaCfgReg |= (ETH_RX_DATA_SWAP_MASK |
  63063. + ETH_TX_DATA_SWAP_MASK |
  63064. + ETH_NO_DESC_SWAP_MASK);
  63065. +# else
  63066. +# error "Giga Ethernet Swap policy is not defined for the CPU_ARCH"
  63067. +# endif /* MV_ARM / MV_PPC */
  63068. +
  63069. +#else /* MV_CPU_LE */
  63070. + /* little endian */
  63071. + portSdmaCfgReg |= (ETH_RX_NO_DATA_SWAP_MASK |
  63072. + ETH_TX_NO_DATA_SWAP_MASK |
  63073. + ETH_NO_DESC_SWAP_MASK);
  63074. +#endif /* MV_CPU_BE / MV_CPU_LE */
  63075. +
  63076. + pPortCtrl->portRxQueueCmdReg = 0;
  63077. + pPortCtrl->portTxQueueCmdReg = 0;
  63078. +
  63079. +#if (MV_ETH_VERSION >= 4)
  63080. + if(pPortCtrl->portConfig.ejpMode == MV_TRUE)
  63081. + {
  63082. + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(ethPortNo), ETH_TX_EJP_ENABLE_MASK);
  63083. + }
  63084. + else
  63085. + {
  63086. + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(ethPortNo), 0)
  63087. + }
  63088. +#endif /* (MV_ETH_VERSION >= 4) */
  63089. +
  63090. + ethSetUcastTable(ethPortNo, -1);
  63091. + mvEthSetSpecialMcastTable(ethPortNo, -1);
  63092. + mvEthSetOtherMcastTable(ethPortNo, -1);
  63093. +
  63094. + portSerialCtrlReg &= ~ETH_MAX_RX_PACKET_SIZE_MASK;
  63095. +
  63096. + portSerialCtrlReg |= mvEthMruGet(pPortCtrl->portConfig.maxRxPktSize);
  63097. +
  63098. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNo), portSerialCtrlReg);
  63099. +
  63100. + /* Update value of PortConfig register accordingly with all RxQueue types */
  63101. + pPortCtrl->portConfig.rxArpQ = pPortCtrl->portConfig.rxDefQ;
  63102. + pPortCtrl->portConfig.rxBpduQ = pPortCtrl->portConfig.rxDefQ;
  63103. + pPortCtrl->portConfig.rxTcpQ = pPortCtrl->portConfig.rxDefQ;
  63104. + pPortCtrl->portConfig.rxUdpQ = pPortCtrl->portConfig.rxDefQ;
  63105. +
  63106. + portCfgReg &= ~ETH_DEF_RX_QUEUE_ALL_MASK;
  63107. + portCfgReg |= ETH_DEF_RX_QUEUE_MASK(pPortCtrl->portConfig.rxDefQ);
  63108. +
  63109. + portCfgReg &= ~ETH_DEF_RX_ARP_QUEUE_ALL_MASK;
  63110. + portCfgReg |= ETH_DEF_RX_ARP_QUEUE_MASK(pPortCtrl->portConfig.rxArpQ);
  63111. +
  63112. + portCfgReg &= ~ETH_DEF_RX_BPDU_QUEUE_ALL_MASK;
  63113. + portCfgReg |= ETH_DEF_RX_BPDU_QUEUE_MASK(pPortCtrl->portConfig.rxBpduQ);
  63114. +
  63115. + portCfgReg &= ~ETH_DEF_RX_TCP_QUEUE_ALL_MASK;
  63116. + portCfgReg |= ETH_DEF_RX_TCP_QUEUE_MASK(pPortCtrl->portConfig.rxTcpQ);
  63117. +
  63118. + portCfgReg &= ~ETH_DEF_RX_UDP_QUEUE_ALL_MASK;
  63119. + portCfgReg |= ETH_DEF_RX_UDP_QUEUE_MASK(pPortCtrl->portConfig.rxUdpQ);
  63120. +
  63121. + /* Assignment of Tx CTRP of given queue */
  63122. + txPrio = 0;
  63123. +
  63124. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  63125. + {
  63126. + pQueueCtrl = &pPortCtrl->txQueue[queue];
  63127. +
  63128. + if(pQueueCtrl->pFirstDescr != NULL)
  63129. + {
  63130. + ethResetTxDescRing(pPortCtrl, queue);
  63131. +
  63132. + MV_REG_WRITE(ETH_TXQ_TOKEN_COUNT_REG(ethPortNo, queue),
  63133. + 0x3fffffff);
  63134. + MV_REG_WRITE(ETH_TXQ_TOKEN_CFG_REG(ethPortNo, queue),
  63135. + 0x03ffffff);
  63136. + }
  63137. + else
  63138. + {
  63139. + MV_REG_WRITE(ETH_TXQ_TOKEN_COUNT_REG(ethPortNo, queue), 0x0);
  63140. + MV_REG_WRITE(ETH_TXQ_TOKEN_CFG_REG(ethPortNo, queue), 0x0);
  63141. + }
  63142. + }
  63143. +
  63144. + /* Assignment of Rx CRDP of given queue */
  63145. + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
  63146. + {
  63147. + ethResetRxDescRing(pPortCtrl, queue);
  63148. + }
  63149. +
  63150. + /* Allow receiving packes with odd number of preamble nibbles */
  63151. + portSerialCtrl1Reg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(ethPortNo));
  63152. + portSerialCtrl1Reg |= ETH_EN_MII_ODD_PRE_MASK;
  63153. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(ethPortNo), portSerialCtrl1Reg);
  63154. +
  63155. + /* Assign port configuration and command. */
  63156. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(ethPortNo), portCfgReg);
  63157. +
  63158. + MV_REG_WRITE(ETH_PORT_CONFIG_EXTEND_REG(ethPortNo), portCfgExtReg);
  63159. +
  63160. + /* Assign port SDMA configuration */
  63161. + MV_REG_WRITE(ETH_SDMA_CONFIG_REG(ethPortNo), portSdmaCfgReg);
  63162. +
  63163. + /* Turn off the port/queue bandwidth limitation */
  63164. + MV_REG_WRITE(ETH_MAX_TRANSMIT_UNIT_REG(ethPortNo), 0x0);
  63165. +
  63166. + return MV_OK;
  63167. +}
  63168. +
  63169. +/*******************************************************************************
  63170. +* ethPortUp - Start the Ethernet port RX and TX activity.
  63171. +*
  63172. +* DESCRIPTION:
  63173. +* This routine start Rx and Tx activity:
  63174. +*
  63175. +* Note: Each Rx and Tx queue descriptor's list must be initialized prior
  63176. +* to calling this function (use etherInitTxDescRing for Tx queues and
  63177. +* etherInitRxDescRing for Rx queues).
  63178. +*
  63179. +* INPUT:
  63180. +* void* pEthPortHndl - Ethernet port handler
  63181. +*
  63182. +* RETURN: MV_STATUS
  63183. +* MV_OK - Success, Others - Failure.
  63184. +*
  63185. +* NOTE : used for port link up.
  63186. +*******************************************************************************/
  63187. +MV_STATUS mvEthPortUp(void* pEthPortHndl)
  63188. +{
  63189. + int ethPortNo;
  63190. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  63191. +
  63192. + ethPortNo = pPortCtrl->portNo;
  63193. +
  63194. + if( (pPortCtrl->portState != MV_ACTIVE) &&
  63195. + (pPortCtrl->portState != MV_PAUSED) )
  63196. + {
  63197. + mvOsPrintf("ethDrv port%d: Unexpected port state %d\n",
  63198. + ethPortNo, pPortCtrl->portState);
  63199. + return MV_BAD_STATE;
  63200. + }
  63201. +
  63202. + ethPortNo = pPortCtrl->portNo;
  63203. +
  63204. + /* Enable port RX. */
  63205. + MV_REG_WRITE(ETH_RX_QUEUE_COMMAND_REG(ethPortNo), pPortCtrl->portRxQueueCmdReg);
  63206. +
  63207. + /* Enable port TX. */
  63208. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(ethPortNo)) = pPortCtrl->portTxQueueCmdReg;
  63209. +
  63210. + pPortCtrl->portState = MV_ACTIVE;
  63211. +
  63212. + return MV_OK;
  63213. +}
  63214. +
  63215. +/*******************************************************************************
  63216. +* ethPortDown - Stop the Ethernet port activity.
  63217. +*
  63218. +* DESCRIPTION:
  63219. +*
  63220. +* INPUT:
  63221. +* void* pEthPortHndl - Ethernet port handler
  63222. +*
  63223. +* RETURN: MV_STATUS
  63224. +* MV_OK - Success, Others - Failure.
  63225. +*
  63226. +* NOTE : used for port link down.
  63227. +*******************************************************************************/
  63228. +MV_STATUS mvEthPortDown(void* pEthPortHndl)
  63229. +{
  63230. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  63231. + int ethPortNum = pPortCtrl->portNo;
  63232. + unsigned int regData;
  63233. + volatile int uDelay, mDelay;
  63234. +
  63235. + /* Stop Rx port activity. Check port Rx activity. */
  63236. + regData = (MV_REG_READ(ETH_RX_QUEUE_COMMAND_REG(ethPortNum))) & ETH_RXQ_ENABLE_MASK;
  63237. + if(regData != 0)
  63238. + {
  63239. + /* Issue stop command for active channels only */
  63240. + MV_REG_WRITE(ETH_RX_QUEUE_COMMAND_REG(ethPortNum), (regData << ETH_RXQ_DISABLE_OFFSET));
  63241. + }
  63242. +
  63243. + /* Stop Tx port activity. Check port Tx activity. */
  63244. + regData = (MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(ethPortNum))) & ETH_TXQ_ENABLE_MASK;
  63245. + if(regData != 0)
  63246. + {
  63247. + /* Issue stop command for active channels only */
  63248. + MV_REG_WRITE(ETH_TX_QUEUE_COMMAND_REG(ethPortNum),
  63249. + (regData << ETH_TXQ_DISABLE_OFFSET) );
  63250. + }
  63251. +
  63252. + /* Force link down */
  63253. +/*
  63254. + regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));
  63255. + regData &= ~(ETH_DO_NOT_FORCE_LINK_FAIL_MASK);
  63256. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);
  63257. +*/
  63258. + /* Wait for all Rx activity to terminate. */
  63259. + mDelay = 0;
  63260. + do
  63261. + {
  63262. + if(mDelay >= RX_DISABLE_TIMEOUT_MSEC)
  63263. + {
  63264. + mvOsPrintf("ethPort_%d: TIMEOUT for RX stopped !!! rxQueueCmd - 0x08%x\n",
  63265. + ethPortNum, regData);
  63266. + break;
  63267. + }
  63268. + mvOsDelay(1);
  63269. + mDelay++;
  63270. +
  63271. + /* Check port RX Command register that all Rx queues are stopped */
  63272. + regData = MV_REG_READ(ETH_RX_QUEUE_COMMAND_REG(ethPortNum));
  63273. + }
  63274. + while(regData & 0xFF);
  63275. +
  63276. + /* Wait for all Tx activity to terminate. */
  63277. + mDelay = 0;
  63278. + do
  63279. + {
  63280. + if(mDelay >= TX_DISABLE_TIMEOUT_MSEC)
  63281. + {
  63282. + mvOsPrintf("ethPort_%d: TIMEOUT for TX stoped !!! txQueueCmd - 0x08%x\n",
  63283. + ethPortNum, regData);
  63284. + break;
  63285. + }
  63286. + mvOsDelay(1);
  63287. + mDelay++;
  63288. +
  63289. + /* Check port TX Command register that all Tx queues are stopped */
  63290. + regData = MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(ethPortNum));
  63291. + }
  63292. + while(regData & 0xFF);
  63293. +
  63294. + /* Double check to Verify that TX FIFO is Empty */
  63295. + mDelay = 0;
  63296. + while(MV_TRUE)
  63297. + {
  63298. + do
  63299. + {
  63300. + if(mDelay >= TX_FIFO_EMPTY_TIMEOUT_MSEC)
  63301. + {
  63302. + mvOsPrintf("\n ethPort_%d: TIMEOUT for TX FIFO empty !!! portStatus - 0x08%x\n",
  63303. + ethPortNum, regData);
  63304. + break;
  63305. + }
  63306. + mvOsDelay(1);
  63307. + mDelay++;
  63308. +
  63309. + regData = MV_REG_READ(ETH_PORT_STATUS_REG(ethPortNum));
  63310. + }
  63311. + while( ((regData & ETH_TX_FIFO_EMPTY_MASK) == 0) ||
  63312. + ((regData & ETH_TX_IN_PROGRESS_MASK) != 0) );
  63313. +
  63314. + if(mDelay >= TX_FIFO_EMPTY_TIMEOUT_MSEC)
  63315. + break;
  63316. +
  63317. + /* Double check */
  63318. + regData = MV_REG_READ(ETH_PORT_STATUS_REG(ethPortNum));
  63319. + if( ((regData & ETH_TX_FIFO_EMPTY_MASK) != 0) &&
  63320. + ((regData & ETH_TX_IN_PROGRESS_MASK) == 0) )
  63321. + {
  63322. + break;
  63323. + }
  63324. + else
  63325. + mvOsPrintf("ethPort_%d: TX FIFO Empty double check failed. %d msec, portStatus=0x%x\n",
  63326. + ethPortNum, mDelay, regData);
  63327. + }
  63328. +
  63329. + /* Do NOT force link down */
  63330. +/*
  63331. + regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));
  63332. + regData |= (ETH_DO_NOT_FORCE_LINK_FAIL_MASK);
  63333. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);
  63334. +*/
  63335. + /* Wait about 2500 tclk cycles */
  63336. + uDelay = (PORT_DISABLE_WAIT_TCLOCKS/(mvBoardTclkGet()/1000000));
  63337. + mvOsUDelay(uDelay);
  63338. +
  63339. + pPortCtrl->portState = MV_PAUSED;
  63340. +
  63341. + return MV_OK;
  63342. +}
  63343. +
  63344. +
  63345. +/*******************************************************************************
  63346. +* ethPortEnable - Enable the Ethernet port and Start RX and TX.
  63347. +*
  63348. +* DESCRIPTION:
  63349. +* This routine enable the Ethernet port and Rx and Tx activity:
  63350. +*
  63351. +* Note: Each Rx and Tx queue descriptor's list must be initialized prior
  63352. +* to calling this function (use etherInitTxDescRing for Tx queues and
  63353. +* etherInitRxDescRing for Rx queues).
  63354. +*
  63355. +* INPUT:
  63356. +* void* pEthPortHndl - Ethernet port handler
  63357. +*
  63358. +* RETURN: MV_STATUS
  63359. +* MV_OK - Success, Others - Failure.
  63360. +*
  63361. +* NOTE: main usage is to enable the port after ifconfig up.
  63362. +*******************************************************************************/
  63363. +MV_STATUS mvEthPortEnable(void* pEthPortHndl)
  63364. +{
  63365. + int ethPortNo;
  63366. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  63367. + MV_U32 portSerialCtrlReg;
  63368. +
  63369. + ethPortNo = pPortCtrl->portNo;
  63370. +
  63371. + /* Enable port */
  63372. + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNo));
  63373. + portSerialCtrlReg |= (ETH_DO_NOT_FORCE_LINK_FAIL_MASK | ETH_PORT_ENABLE_MASK);
  63374. +
  63375. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNo), portSerialCtrlReg);
  63376. +
  63377. + mvEthMibCountersClear(pEthPortHndl);
  63378. +
  63379. + pPortCtrl->portState = MV_PAUSED;
  63380. +
  63381. + /* If Link is UP, Start RX and TX traffic */
  63382. + if( MV_REG_READ( ETH_PORT_STATUS_REG(ethPortNo) ) & ETH_LINK_UP_MASK)
  63383. + return( mvEthPortUp(pEthPortHndl) );
  63384. +
  63385. + return MV_NOT_READY;
  63386. +}
  63387. +
  63388. +
  63389. +/*******************************************************************************
  63390. +* mvEthPortDisable - Stop RX and TX activities and Disable the Ethernet port.
  63391. +*
  63392. +* DESCRIPTION:
  63393. +*
  63394. +* INPUT:
  63395. +* void* pEthPortHndl - Ethernet port handler
  63396. +*
  63397. +* RETURN: MV_STATUS
  63398. +* MV_OK - Success, Others - Failure.
  63399. +*
  63400. +* NOTE: main usage is to disable the port after ifconfig down.
  63401. +*******************************************************************************/
  63402. +MV_STATUS mvEthPortDisable(void* pEthPortHndl)
  63403. +{
  63404. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  63405. + int ethPortNum = pPortCtrl->portNo;
  63406. + unsigned int regData;
  63407. + volatile int mvDelay;
  63408. +
  63409. + if(pPortCtrl->portState == MV_ACTIVE)
  63410. + {
  63411. + /* Stop RX and TX activities */
  63412. + mvEthPortDown(pEthPortHndl);
  63413. + }
  63414. +
  63415. + /* Reset the Enable bit in the Serial Control Register */
  63416. + regData = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(ethPortNum));
  63417. + regData &= ~(ETH_PORT_ENABLE_MASK);
  63418. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(ethPortNum), regData);
  63419. +
  63420. + /* Wait about 2500 tclk cycles */
  63421. + mvDelay = (PORT_DISABLE_WAIT_TCLOCKS*(mvCpuPclkGet()/mvBoardTclkGet()));
  63422. + for(mvDelay; mvDelay>0; mvDelay--);
  63423. +
  63424. + pPortCtrl->portState = MV_IDLE;
  63425. + return MV_OK;
  63426. +}
  63427. +
  63428. +/*******************************************************************************
  63429. +* mvEthPortForceTxDone - Get next buffer from TX queue in spite of buffer ownership.
  63430. +*
  63431. +* DESCRIPTION:
  63432. +* This routine used to free buffers attached to the Tx ring and should
  63433. +* be called only when Giga Ethernet port is Down
  63434. +*
  63435. +* INPUT:
  63436. +* void* pEthPortHndl - Ethernet Port handler.
  63437. +* int txQueue - Number of TX queue.
  63438. +*
  63439. +* OUTPUT:
  63440. +* MV_PKT_INFO *pPktInfo - Pointer to packet was sent.
  63441. +*
  63442. +* RETURN:
  63443. +* MV_EMPTY - There is no more buffers in this queue.
  63444. +* MV_OK - Buffer detached from the queue and pPktInfo structure
  63445. +* filled with relevant information.
  63446. +*
  63447. +*******************************************************************************/
  63448. +MV_PKT_INFO* mvEthPortForceTxDone(void* pEthPortHndl, int txQueue)
  63449. +{
  63450. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  63451. + ETH_QUEUE_CTRL* pQueueCtrl;
  63452. + MV_PKT_INFO* pPktInfo;
  63453. + ETH_TX_DESC* pTxDesc;
  63454. + int port = pPortCtrl->portNo;
  63455. +
  63456. + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  63457. +
  63458. + while( (pQueueCtrl->pUsedDescr != pQueueCtrl->pCurrentDescr) ||
  63459. + (pQueueCtrl->resource == 0) )
  63460. + {
  63461. + /* Free next descriptor */
  63462. + pQueueCtrl->resource++;
  63463. + pTxDesc = (ETH_TX_DESC*)pQueueCtrl->pUsedDescr;
  63464. +
  63465. + /* pPktInfo is available only in descriptors which are last descriptors */
  63466. + pPktInfo = (MV_PKT_INFO*)pTxDesc->returnInfo;
  63467. + if (pPktInfo)
  63468. + pPktInfo->status = pTxDesc->cmdSts;
  63469. +
  63470. + pTxDesc->cmdSts = 0x0;
  63471. + pTxDesc->returnInfo = 0x0;
  63472. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxDesc);
  63473. +
  63474. + pQueueCtrl->pUsedDescr = TX_NEXT_DESC_PTR(pTxDesc, pQueueCtrl);
  63475. +
  63476. + if (pPktInfo)
  63477. + if (pPktInfo->status & ETH_TX_LAST_DESC_MASK)
  63478. + return pPktInfo;
  63479. + }
  63480. + MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(port, txQueue),
  63481. + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
  63482. + return NULL;
  63483. +}
  63484. +
  63485. +
  63486. +
  63487. +/*******************************************************************************
  63488. +* mvEthPortForceRx - Get next buffer from RX queue in spite of buffer ownership.
  63489. +*
  63490. +* DESCRIPTION:
  63491. +* This routine used to free buffers attached to the Rx ring and should
  63492. +* be called only when Giga Ethernet port is Down
  63493. +*
  63494. +* INPUT:
  63495. +* void* pEthPortHndl - Ethernet Port handler.
  63496. +* int rxQueue - Number of Rx queue.
  63497. +*
  63498. +* OUTPUT:
  63499. +* MV_PKT_INFO *pPktInfo - Pointer to received packet.
  63500. +*
  63501. +* RETURN:
  63502. +* MV_EMPTY - There is no more buffers in this queue.
  63503. +* MV_OK - Buffer detached from the queue and pBufInfo structure
  63504. +* filled with relevant information.
  63505. +*
  63506. +*******************************************************************************/
  63507. +MV_PKT_INFO* mvEthPortForceRx(void* pEthPortHndl, int rxQueue)
  63508. +{
  63509. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  63510. + ETH_QUEUE_CTRL* pQueueCtrl;
  63511. + ETH_RX_DESC* pRxDesc;
  63512. + MV_PKT_INFO* pPktInfo;
  63513. + int port = pPortCtrl->portNo;
  63514. +
  63515. + pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];
  63516. +
  63517. + if(pQueueCtrl->resource == 0)
  63518. + {
  63519. + MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(port, rxQueue),
  63520. + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
  63521. +
  63522. + return NULL;
  63523. + }
  63524. + /* Free next descriptor */
  63525. + pQueueCtrl->resource--;
  63526. + pRxDesc = (ETH_RX_DESC*)pQueueCtrl->pCurrentDescr;
  63527. + pPktInfo = (MV_PKT_INFO*)pRxDesc->returnInfo;
  63528. +
  63529. + pPktInfo->status = pRxDesc->cmdSts;
  63530. + pRxDesc->cmdSts = 0x0;
  63531. + pRxDesc->returnInfo = 0x0;
  63532. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxDesc);
  63533. +
  63534. + pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxDesc, pQueueCtrl);
  63535. + return pPktInfo;
  63536. +}
  63537. +
  63538. +
  63539. +/******************************************************************************/
  63540. +/* Port Configuration functions */
  63541. +/******************************************************************************/
  63542. +/*******************************************************************************
  63543. +* mvEthMruGet - Get MRU configuration for Max Rx packet size.
  63544. +*
  63545. +* INPUT:
  63546. +* MV_U32 maxRxPktSize - max packet size.
  63547. +*
  63548. +* RETURN: MV_U32 - MRU configuration.
  63549. +*
  63550. +*******************************************************************************/
  63551. +static MV_U32 mvEthMruGet(MV_U32 maxRxPktSize)
  63552. +{
  63553. + MV_U32 portSerialCtrlReg = 0;
  63554. +
  63555. + if(maxRxPktSize > 9192)
  63556. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_9700BYTE;
  63557. + else if(maxRxPktSize > 9022)
  63558. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_9192BYTE;
  63559. + else if(maxRxPktSize > 1552)
  63560. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_9022BYTE;
  63561. + else if(maxRxPktSize > 1522)
  63562. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_1552BYTE;
  63563. + else if(maxRxPktSize > 1518)
  63564. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_1522BYTE;
  63565. + else
  63566. + portSerialCtrlReg |= ETH_MAX_RX_PACKET_1518BYTE;
  63567. +
  63568. + return portSerialCtrlReg;
  63569. +}
  63570. +
  63571. +/*******************************************************************************
  63572. +* mvEthRxCoalSet - Sets coalescing interrupt mechanism on RX path
  63573. +*
  63574. +* DESCRIPTION:
  63575. +* This routine sets the RX coalescing interrupt mechanism parameter.
  63576. +* This parameter is a timeout counter, that counts in 64 tClk
  63577. +* chunks, that when timeout event occurs a maskable interrupt occurs.
  63578. +* The parameter is calculated using the tCLK frequency of the
  63579. +* MV-64xxx chip, and the required number is in micro seconds.
  63580. +*
  63581. +* INPUT:
  63582. +* void* pPortHndl - Ethernet Port handler.
  63583. +* MV_U32 uSec - Number of micro seconds between
  63584. +* RX interrupts
  63585. +*
  63586. +* RETURN:
  63587. +* None.
  63588. +*
  63589. +* COMMENT:
  63590. +* 1 sec - TCLK_RATE clocks
  63591. +* 1 uSec - TCLK_RATE / 1,000,000 clocks
  63592. +*
  63593. +* Register Value for N micro seconds - ((N * ( (TCLK_RATE / 1,000,000)) / 64)
  63594. +*
  63595. +* RETURN:
  63596. +* None.
  63597. +*
  63598. +*******************************************************************************/
  63599. +MV_U32 mvEthRxCoalSet (void* pPortHndl, MV_U32 uSec)
  63600. +{
  63601. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  63602. + MV_U32 coal = ((uSec * (mvBoardTclkGet() / 1000000)) / 64);
  63603. + MV_U32 portSdmaCfgReg;
  63604. +
  63605. + portSdmaCfgReg = MV_REG_READ(ETH_SDMA_CONFIG_REG(pPortCtrl->portNo));
  63606. + portSdmaCfgReg &= ~ETH_RX_INTR_COAL_ALL_MASK;
  63607. +
  63608. + portSdmaCfgReg |= ETH_RX_INTR_COAL_MASK(coal);
  63609. +
  63610. +#if (MV_ETH_VERSION >= 2)
  63611. + /* Set additional bit if needed ETH_RX_INTR_COAL_MSB_BIT (25) */
  63612. + if(ETH_RX_INTR_COAL_MASK(coal) > ETH_RX_INTR_COAL_ALL_MASK)
  63613. + portSdmaCfgReg |= ETH_RX_INTR_COAL_MSB_MASK;
  63614. +#endif /* MV_ETH_VERSION >= 2 */
  63615. +
  63616. + MV_REG_WRITE (ETH_SDMA_CONFIG_REG(pPortCtrl->portNo), portSdmaCfgReg);
  63617. + return coal;
  63618. +}
  63619. +
  63620. +/*******************************************************************************
  63621. +* mvEthTxCoalSet - Sets coalescing interrupt mechanism on TX path
  63622. +*
  63623. +* DESCRIPTION:
  63624. +* This routine sets the TX coalescing interrupt mechanism parameter.
  63625. +* This parameter is a timeout counter, that counts in 64 tClk
  63626. +* chunks, that when timeout event occurs a maskable interrupt
  63627. +* occurs.
  63628. +* The parameter is calculated using the tCLK frequency of the
  63629. +* MV-64xxx chip, and the required number is in micro seconds.
  63630. +*
  63631. +* INPUT:
  63632. +* void* pPortHndl - Ethernet Port handler.
  63633. +* MV_U32 uSec - Number of micro seconds between
  63634. +* RX interrupts
  63635. +*
  63636. +* RETURN:
  63637. +* None.
  63638. +*
  63639. +* COMMENT:
  63640. +* 1 sec - TCLK_RATE clocks
  63641. +* 1 uSec - TCLK_RATE / 1,000,000 clocks
  63642. +*
  63643. +* Register Value for N micro seconds - ((N * ( (TCLK_RATE / 1,000,000)) / 64)
  63644. +*
  63645. +*******************************************************************************/
  63646. +MV_U32 mvEthTxCoalSet(void* pPortHndl, MV_U32 uSec)
  63647. +{
  63648. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  63649. + MV_U32 coal = ((uSec * (mvBoardTclkGet() / 1000000)) / 64);
  63650. + MV_U32 regVal;
  63651. +
  63652. + regVal = MV_REG_READ(ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo));
  63653. + regVal &= ~ETH_TX_INTR_COAL_ALL_MASK;
  63654. + regVal |= ETH_TX_INTR_COAL_MASK(coal);
  63655. +
  63656. + /* Set TX Coalescing mechanism */
  63657. + MV_REG_WRITE (ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo), regVal);
  63658. + return coal;
  63659. +}
  63660. +
  63661. +/*******************************************************************************
  63662. +* mvEthCoalGet - Gets RX and TX coalescing values in micro seconds
  63663. +*
  63664. +* DESCRIPTION:
  63665. +* This routine gets the RX and TX coalescing interrupt values.
  63666. +* The parameter is calculated using the tCLK frequency of the
  63667. +* MV-64xxx chip, and the returned numbers are in micro seconds.
  63668. +*
  63669. +* INPUTs:
  63670. +* void* pPortHndl - Ethernet Port handler.
  63671. +*
  63672. +* OUTPUTs:
  63673. +* MV_U32* pRxCoal - Number of micro seconds between RX interrupts
  63674. +* MV_U32* pTxCoal - Number of micro seconds between TX interrupts
  63675. +*
  63676. +* RETURN:
  63677. +* MV_STATUS MV_OK - success
  63678. +* Others - failure.
  63679. +*
  63680. +* COMMENT:
  63681. +* 1 sec - TCLK_RATE clocks
  63682. +* 1 uSec - TCLK_RATE / 1,000,000 clocks
  63683. +*
  63684. +* Register Value for N micro seconds - ((N * ( (TCLK_RATE / 1,000,000)) / 64)
  63685. +*
  63686. +*******************************************************************************/
  63687. +MV_STATUS mvEthCoalGet(void* pPortHndl, MV_U32* pRxCoal, MV_U32* pTxCoal)
  63688. +{
  63689. + MV_U32 regVal, coal, usec;
  63690. +
  63691. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  63692. +
  63693. + /* get TX Coalescing */
  63694. + regVal = MV_REG_READ (ETH_TX_FIFO_URGENT_THRESH_REG(pPortCtrl->portNo));
  63695. + coal = ((regVal & ETH_TX_INTR_COAL_ALL_MASK) >> ETH_TX_INTR_COAL_OFFSET);
  63696. +
  63697. + usec = (coal * 64) / (mvBoardTclkGet() / 1000000);
  63698. + if(pTxCoal != NULL)
  63699. + *pTxCoal = usec;
  63700. +
  63701. + /* Get RX Coalescing */
  63702. + regVal = MV_REG_READ(ETH_SDMA_CONFIG_REG(pPortCtrl->portNo));
  63703. + coal = ((regVal & ETH_RX_INTR_COAL_ALL_MASK) >> ETH_RX_INTR_COAL_OFFSET);
  63704. +
  63705. +#if (MV_ETH_VERSION >= 2)
  63706. + if(regVal & ETH_RX_INTR_COAL_MSB_MASK)
  63707. + {
  63708. + /* Add MSB */
  63709. + coal |= (ETH_RX_INTR_COAL_ALL_MASK + 1);
  63710. + }
  63711. +#endif /* MV_ETH_VERSION >= 2 */
  63712. +
  63713. + usec = (coal * 64) / (mvBoardTclkGet() / 1000000);
  63714. + if(pRxCoal != NULL)
  63715. + *pRxCoal = usec;
  63716. +
  63717. + return MV_OK;
  63718. +}
  63719. +
  63720. +/*******************************************************************************
  63721. +* mvEthMaxRxSizeSet -
  63722. +*
  63723. +* DESCRIPTION:
  63724. +* Change maximum receive size of the port. This configuration will take place
  63725. +* after next call of ethPortSetDefaults() function.
  63726. +*
  63727. +* INPUT:
  63728. +*
  63729. +* RETURN:
  63730. +*******************************************************************************/
  63731. +MV_STATUS mvEthMaxRxSizeSet(void* pPortHndl, int maxRxSize)
  63732. +{
  63733. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  63734. + MV_U32 portSerialCtrlReg;
  63735. +
  63736. + if((maxRxSize < 1518) || (maxRxSize & ~ETH_RX_BUFFER_MASK))
  63737. + return MV_BAD_PARAM;
  63738. +
  63739. + pPortCtrl->portConfig.maxRxPktSize = maxRxSize;
  63740. +
  63741. + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(pPortCtrl->portNo));
  63742. + portSerialCtrlReg &= ~ETH_MAX_RX_PACKET_SIZE_MASK;
  63743. + portSerialCtrlReg |= mvEthMruGet(pPortCtrl->portConfig.maxRxPktSize);
  63744. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(pPortCtrl->portNo), portSerialCtrlReg);
  63745. +
  63746. + return MV_OK;
  63747. +}
  63748. +
  63749. +
  63750. +/******************************************************************************/
  63751. +/* MAC Filtering functions */
  63752. +/******************************************************************************/
  63753. +
  63754. +/*******************************************************************************
  63755. +* mvEthRxFilterModeSet - Configure Fitering mode of Ethernet port
  63756. +*
  63757. +* DESCRIPTION:
  63758. +* This routine used to free buffers attached to the Rx ring and should
  63759. +* be called only when Giga Ethernet port is Down
  63760. +*
  63761. +* INPUT:
  63762. +* void* pEthPortHndl - Ethernet Port handler.
  63763. +* MV_BOOL isPromisc - Promiscous mode
  63764. +* MV_TRUE - accept all Broadcast, Multicast
  63765. +* and Unicast packets
  63766. +* MV_FALSE - accept all Broadcast,
  63767. +* specially added Multicast and
  63768. +* single Unicast packets
  63769. +*
  63770. +* RETURN: MV_STATUS MV_OK - Success, Other - Failure
  63771. +*
  63772. +*******************************************************************************/
  63773. +MV_STATUS mvEthRxFilterModeSet(void* pEthPortHndl, MV_BOOL isPromisc)
  63774. +{
  63775. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  63776. + int queue;
  63777. + MV_U32 portCfgReg;
  63778. +
  63779. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  63780. + /* Set / Clear UPM bit in port configuration register */
  63781. + if(isPromisc)
  63782. + {
  63783. + /* Accept all multicast packets to RX default queue */
  63784. + queue = pPortCtrl->portConfig.rxDefQ;
  63785. + portCfgReg |= ETH_UNICAST_PROMISCUOUS_MODE_MASK;
  63786. + memset(pPortCtrl->mcastCount, 1, sizeof(pPortCtrl->mcastCount));
  63787. + MV_REG_WRITE(ETH_MAC_ADDR_LOW_REG(pPortCtrl->portNo),0xFFFF);
  63788. + MV_REG_WRITE(ETH_MAC_ADDR_HIGH_REG(pPortCtrl->portNo),0xFFFFFFFF);
  63789. + }
  63790. + else
  63791. + {
  63792. + /* Reject all Multicast addresses */
  63793. + queue = -1;
  63794. + portCfgReg &= ~ETH_UNICAST_PROMISCUOUS_MODE_MASK;
  63795. + /* Clear all mcastCount */
  63796. + memset(pPortCtrl->mcastCount, 0, sizeof(pPortCtrl->mcastCount));
  63797. + }
  63798. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  63799. +
  63800. + /* Set Special Multicast and Other Multicast tables */
  63801. + mvEthSetSpecialMcastTable(pPortCtrl->portNo, queue);
  63802. + mvEthSetOtherMcastTable(pPortCtrl->portNo, queue);
  63803. + ethSetUcastTable(pPortCtrl->portNo, queue);
  63804. +
  63805. + return MV_OK;
  63806. +}
  63807. +
  63808. +/*******************************************************************************
  63809. +* mvEthMacAddrSet - This function Set the port Unicast address.
  63810. +*
  63811. +* DESCRIPTION:
  63812. +* This function Set the port Ethernet MAC address. This address
  63813. +* will be used to send Pause frames if enabled. Packets with this
  63814. +* address will be accepted and dispatched to default RX queue
  63815. +*
  63816. +* INPUT:
  63817. +* void* pEthPortHndl - Ethernet port handler.
  63818. +* char* pAddr - Address to be set
  63819. +*
  63820. +* RETURN: MV_STATUS
  63821. +* MV_OK - Success, Other - Faulure
  63822. +*
  63823. +*******************************************************************************/
  63824. +MV_STATUS mvEthMacAddrSet(void* pPortHndl, unsigned char *pAddr, int queue)
  63825. +{
  63826. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  63827. + unsigned int macH;
  63828. + unsigned int macL;
  63829. +
  63830. + if(queue >= MV_ETH_RX_Q_NUM)
  63831. + {
  63832. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", queue);
  63833. + return MV_BAD_PARAM;
  63834. + }
  63835. +
  63836. + if(queue != -1)
  63837. + {
  63838. + macL = (pAddr[4] << 8) | (pAddr[5]);
  63839. + macH = (pAddr[0] << 24)| (pAddr[1] << 16) |
  63840. + (pAddr[2] << 8) | (pAddr[3] << 0);
  63841. +
  63842. + MV_REG_WRITE(ETH_MAC_ADDR_LOW_REG(pPortCtrl->portNo), macL);
  63843. + MV_REG_WRITE(ETH_MAC_ADDR_HIGH_REG(pPortCtrl->portNo), macH);
  63844. + }
  63845. +
  63846. + /* Accept frames of this address */
  63847. + ethSetUcastAddr(pPortCtrl->portNo, pAddr[5], queue);
  63848. +
  63849. + return MV_OK;
  63850. +}
  63851. +
  63852. +/*******************************************************************************
  63853. +* mvEthMacAddrGet - This function returns the port Unicast address.
  63854. +*
  63855. +* DESCRIPTION:
  63856. +* This function returns the port Ethernet MAC address.
  63857. +*
  63858. +* INPUT:
  63859. +* int portNo - Ethernet port number.
  63860. +* char* pAddr - Pointer where address will be written to
  63861. +*
  63862. +* RETURN: MV_STATUS
  63863. +* MV_OK - Success, Other - Faulure
  63864. +*
  63865. +*******************************************************************************/
  63866. +MV_STATUS mvEthMacAddrGet(int portNo, unsigned char *pAddr)
  63867. +{
  63868. + unsigned int macH;
  63869. + unsigned int macL;
  63870. +
  63871. + if(pAddr == NULL)
  63872. + {
  63873. + mvOsPrintf("mvEthMacAddrGet: NULL pointer.\n");
  63874. + return MV_BAD_PARAM;
  63875. + }
  63876. +
  63877. + macH = MV_REG_READ(ETH_MAC_ADDR_HIGH_REG(portNo));
  63878. + macL = MV_REG_READ(ETH_MAC_ADDR_LOW_REG(portNo));
  63879. + pAddr[0] = (macH >> 24) & 0xff;
  63880. + pAddr[1] = (macH >> 16) & 0xff;
  63881. + pAddr[2] = (macH >> 8) & 0xff;
  63882. + pAddr[3] = macH & 0xff;
  63883. + pAddr[4] = (macL >> 8) & 0xff;
  63884. + pAddr[5] = macL & 0xff;
  63885. +
  63886. + return MV_OK;
  63887. +}
  63888. +
  63889. +/*******************************************************************************
  63890. +* mvEthMcastCrc8Get - Calculate CRC8 of MAC address.
  63891. +*
  63892. +* DESCRIPTION:
  63893. +*
  63894. +* INPUT:
  63895. +* MV_U8* pAddr - Address to calculate CRC-8
  63896. +*
  63897. +* RETURN: MV_U8 - CRC-8 of this MAC address
  63898. +*
  63899. +*******************************************************************************/
  63900. +MV_U8 mvEthMcastCrc8Get(MV_U8* pAddr)
  63901. +{
  63902. + unsigned int macH;
  63903. + unsigned int macL;
  63904. + int macArray[48];
  63905. + int crc[8];
  63906. + int i;
  63907. + unsigned char crcResult = 0;
  63908. +
  63909. + /* Calculate CRC-8 out of the given address */
  63910. + macH = (pAddr[0] << 8) | (pAddr[1]);
  63911. + macL = (pAddr[2] << 24)| (pAddr[3] << 16) |
  63912. + (pAddr[4] << 8) | (pAddr[5] << 0);
  63913. +
  63914. + for(i=0; i<32; i++)
  63915. + macArray[i] = (macL >> i) & 0x1;
  63916. +
  63917. + for(i=32; i<48; i++)
  63918. + macArray[i] = (macH >> (i - 32)) & 0x1;
  63919. +
  63920. + crc[0] = macArray[45] ^ macArray[43] ^ macArray[40] ^ macArray[39] ^
  63921. + macArray[35] ^ macArray[34] ^ macArray[31] ^ macArray[30] ^
  63922. + macArray[28] ^ macArray[23] ^ macArray[21] ^ macArray[19] ^
  63923. + macArray[18] ^ macArray[16] ^ macArray[14] ^ macArray[12] ^
  63924. + macArray[8] ^ macArray[7] ^ macArray[6] ^ macArray[0];
  63925. +
  63926. + crc[1] = macArray[46] ^ macArray[45] ^ macArray[44] ^ macArray[43] ^
  63927. + macArray[41] ^ macArray[39] ^ macArray[36] ^ macArray[34] ^
  63928. + macArray[32] ^ macArray[30] ^ macArray[29] ^ macArray[28] ^
  63929. + macArray[24] ^ macArray[23] ^ macArray[22] ^ macArray[21] ^
  63930. + macArray[20] ^ macArray[18] ^ macArray[17] ^ macArray[16] ^
  63931. + macArray[15] ^ macArray[14] ^ macArray[13] ^ macArray[12] ^
  63932. + macArray[9] ^ macArray[6] ^ macArray[1] ^ macArray[0];
  63933. +
  63934. + crc[2] = macArray[47] ^ macArray[46] ^ macArray[44] ^ macArray[43] ^
  63935. + macArray[42] ^ macArray[39] ^ macArray[37] ^ macArray[34] ^
  63936. + macArray[33] ^ macArray[29] ^ macArray[28] ^ macArray[25] ^
  63937. + macArray[24] ^ macArray[22] ^ macArray[17] ^ macArray[15] ^
  63938. + macArray[13] ^ macArray[12] ^ macArray[10] ^ macArray[8] ^
  63939. + macArray[6] ^ macArray[2] ^ macArray[1] ^ macArray[0];
  63940. +
  63941. + crc[3] = macArray[47] ^ macArray[45] ^ macArray[44] ^ macArray[43] ^
  63942. + macArray[40] ^ macArray[38] ^ macArray[35] ^ macArray[34] ^
  63943. + macArray[30] ^ macArray[29] ^ macArray[26] ^ macArray[25] ^
  63944. + macArray[23] ^ macArray[18] ^ macArray[16] ^ macArray[14] ^
  63945. + macArray[13] ^ macArray[11] ^ macArray[9] ^ macArray[7] ^
  63946. + macArray[3] ^ macArray[2] ^ macArray[1];
  63947. +
  63948. + crc[4] = macArray[46] ^ macArray[45] ^ macArray[44] ^ macArray[41] ^
  63949. + macArray[39] ^ macArray[36] ^ macArray[35] ^ macArray[31] ^
  63950. + macArray[30] ^ macArray[27] ^ macArray[26] ^ macArray[24] ^
  63951. + macArray[19] ^ macArray[17] ^ macArray[15] ^ macArray[14] ^
  63952. + macArray[12] ^ macArray[10] ^ macArray[8] ^ macArray[4] ^
  63953. + macArray[3] ^ macArray[2];
  63954. +
  63955. + crc[5] = macArray[47] ^ macArray[46] ^ macArray[45] ^ macArray[42] ^
  63956. + macArray[40] ^ macArray[37] ^ macArray[36] ^ macArray[32] ^
  63957. + macArray[31] ^ macArray[28] ^ macArray[27] ^ macArray[25] ^
  63958. + macArray[20] ^ macArray[18] ^ macArray[16] ^ macArray[15] ^
  63959. + macArray[13] ^ macArray[11] ^ macArray[9] ^ macArray[5] ^
  63960. + macArray[4] ^ macArray[3];
  63961. +
  63962. + crc[6] = macArray[47] ^ macArray[46] ^ macArray[43] ^ macArray[41] ^
  63963. + macArray[38] ^ macArray[37] ^ macArray[33] ^ macArray[32] ^
  63964. + macArray[29] ^ macArray[28] ^ macArray[26] ^ macArray[21] ^
  63965. + macArray[19] ^ macArray[17] ^ macArray[16] ^ macArray[14] ^
  63966. + macArray[12] ^ macArray[10] ^ macArray[6] ^ macArray[5] ^
  63967. + macArray[4];
  63968. +
  63969. + crc[7] = macArray[47] ^ macArray[44] ^ macArray[42] ^ macArray[39] ^
  63970. + macArray[38] ^ macArray[34] ^ macArray[33] ^ macArray[30] ^
  63971. + macArray[29] ^ macArray[27] ^ macArray[22] ^ macArray[20] ^
  63972. + macArray[18] ^ macArray[17] ^ macArray[15] ^ macArray[13] ^
  63973. + macArray[11] ^ macArray[7] ^ macArray[6] ^ macArray[5];
  63974. +
  63975. + for(i=0; i<8; i++)
  63976. + crcResult = crcResult | (crc[i] << i);
  63977. +
  63978. + return crcResult;
  63979. +}
  63980. +/*******************************************************************************
  63981. +* mvEthMcastAddrSet - Multicast address settings.
  63982. +*
  63983. +* DESCRIPTION:
  63984. +* This API controls the MV device MAC multicast support.
  63985. +* The MV device supports multicast using two tables:
  63986. +* 1) Special Multicast Table for MAC addresses of the form
  63987. +* 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0xFF).
  63988. +* The MAC DA[7:0] bits are used as a pointer to the Special Multicast
  63989. +* Table entries in the DA-Filter table.
  63990. +* In this case, the function calls ethPortSmcAddr() routine to set the
  63991. +* Special Multicast Table.
  63992. +* 2) Other Multicast Table for multicast of another type. A CRC-8bit
  63993. +* is used as an index to the Other Multicast Table entries in the
  63994. +* DA-Filter table.
  63995. +* In this case, the function calculates the CRC-8bit value and calls
  63996. +* ethPortOmcAddr() routine to set the Other Multicast Table.
  63997. +*
  63998. +* INPUT:
  63999. +* void* pEthPortHndl - Ethernet port handler.
  64000. +* MV_U8* pAddr - Address to be set
  64001. +* int queue - RX queue to capture all packets with this
  64002. +* Multicast MAC address.
  64003. +* -1 means delete this Multicast address.
  64004. +*
  64005. +* RETURN: MV_STATUS
  64006. +* MV_TRUE - Success, Other - Failure
  64007. +*
  64008. +*******************************************************************************/
  64009. +MV_STATUS mvEthMcastAddrSet(void* pPortHndl, MV_U8 *pAddr, int queue)
  64010. +{
  64011. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  64012. + unsigned char crcResult = 0;
  64013. +
  64014. + if(queue >= MV_ETH_RX_Q_NUM)
  64015. + {
  64016. + mvOsPrintf("ethPort %d: RX queue #%d is out of range\n",
  64017. + pPortCtrl->portNo, queue);
  64018. + return MV_BAD_PARAM;
  64019. + }
  64020. +
  64021. + if((pAddr[0] == 0x01) &&
  64022. + (pAddr[1] == 0x00) &&
  64023. + (pAddr[2] == 0x5E) &&
  64024. + (pAddr[3] == 0x00) &&
  64025. + (pAddr[4] == 0x00))
  64026. + {
  64027. + ethSetSpecialMcastAddr(pPortCtrl->portNo, pAddr[5], queue);
  64028. + }
  64029. + else
  64030. + {
  64031. + crcResult = mvEthMcastCrc8Get(pAddr);
  64032. +
  64033. + /* Check Add counter for this CRC value */
  64034. + if(queue == -1)
  64035. + {
  64036. + if(pPortCtrl->mcastCount[crcResult] == 0)
  64037. + {
  64038. + mvOsPrintf("ethPort #%d: No valid Mcast for crc8=0x%02x\n",
  64039. + pPortCtrl->portNo, (unsigned)crcResult);
  64040. + return MV_NO_SUCH;
  64041. + }
  64042. +
  64043. + pPortCtrl->mcastCount[crcResult]--;
  64044. + if(pPortCtrl->mcastCount[crcResult] != 0)
  64045. + {
  64046. + mvOsPrintf("ethPort #%d: After delete there are %d valid Mcast for crc8=0x%02x\n",
  64047. + pPortCtrl->portNo, pPortCtrl->mcastCount[crcResult],
  64048. + (unsigned)crcResult);
  64049. + return MV_NO_CHANGE;
  64050. + }
  64051. + }
  64052. + else
  64053. + {
  64054. + pPortCtrl->mcastCount[crcResult]++;
  64055. + if(pPortCtrl->mcastCount[crcResult] > 1)
  64056. + {
  64057. + mvOsPrintf("ethPort #%d: Valid Mcast for crc8=0x%02x already exists\n",
  64058. + pPortCtrl->portNo, (unsigned)crcResult);
  64059. + return MV_NO_CHANGE;
  64060. + }
  64061. + }
  64062. + ethSetOtherMcastAddr(pPortCtrl->portNo, crcResult, queue);
  64063. + }
  64064. + return MV_OK;
  64065. +}
  64066. +
  64067. +/*******************************************************************************
  64068. +* ethSetUcastTable - Unicast address settings.
  64069. +*
  64070. +* DESCRIPTION:
  64071. +* Set all entries in the Unicast MAC Table queue==-1 means reject all
  64072. +* INPUT:
  64073. +*
  64074. +* RETURN:
  64075. +*
  64076. +*******************************************************************************/
  64077. +static void ethSetUcastTable(int portNo, int queue)
  64078. +{
  64079. + int offset;
  64080. + MV_U32 regValue;
  64081. +
  64082. + if(queue == -1)
  64083. + {
  64084. + regValue = 0;
  64085. + }
  64086. + else
  64087. + {
  64088. + regValue = (((0x01 | (queue<<1)) << 0) |
  64089. + ((0x01 | (queue<<1)) << 8) |
  64090. + ((0x01 | (queue<<1)) << 16) |
  64091. + ((0x01 | (queue<<1)) << 24));
  64092. + }
  64093. +
  64094. + for (offset=0; offset<=0xC; offset+=4)
  64095. + MV_REG_WRITE((ETH_DA_FILTER_UCAST_BASE(portNo) + offset), regValue);
  64096. +}
  64097. +
  64098. +/*******************************************************************************
  64099. +* mvEthSetSpecialMcastTable - Special Multicast address settings.
  64100. +*
  64101. +* DESCRIPTION:
  64102. +* Set all entries to the Special Multicast MAC Table. queue==-1 means reject all
  64103. +* INPUT:
  64104. +*
  64105. +* RETURN:
  64106. +*
  64107. +*******************************************************************************/
  64108. +MV_VOID mvEthSetSpecialMcastTable(int portNo, int queue)
  64109. +{
  64110. + int offset;
  64111. + MV_U32 regValue;
  64112. +
  64113. + if(queue == -1)
  64114. + {
  64115. + regValue = 0;
  64116. + }
  64117. + else
  64118. + {
  64119. + regValue = (((0x01 | (queue<<1)) << 0) |
  64120. + ((0x01 | (queue<<1)) << 8) |
  64121. + ((0x01 | (queue<<1)) << 16) |
  64122. + ((0x01 | (queue<<1)) << 24));
  64123. + }
  64124. +
  64125. + for (offset=0; offset<=0xFC; offset+=4)
  64126. + {
  64127. + MV_REG_WRITE((ETH_DA_FILTER_SPEC_MCAST_BASE(portNo) +
  64128. + offset), regValue);
  64129. + }
  64130. +}
  64131. +
  64132. +/*******************************************************************************
  64133. +* mvEthSetOtherMcastTable - Other Multicast address settings.
  64134. +*
  64135. +* DESCRIPTION:
  64136. +* Set all entries to the Other Multicast MAC Table. queue==-1 means reject all
  64137. +* INPUT:
  64138. +*
  64139. +* RETURN:
  64140. +*
  64141. +*******************************************************************************/
  64142. +MV_VOID mvEthSetOtherMcastTable(int portNo, int queue)
  64143. +{
  64144. + int offset;
  64145. + MV_U32 regValue;
  64146. +
  64147. + if(queue == -1)
  64148. + {
  64149. + regValue = 0;
  64150. + }
  64151. + else
  64152. + {
  64153. + regValue = (((0x01 | (queue<<1)) << 0) |
  64154. + ((0x01 | (queue<<1)) << 8) |
  64155. + ((0x01 | (queue<<1)) << 16) |
  64156. + ((0x01 | (queue<<1)) << 24));
  64157. + }
  64158. +
  64159. + for (offset=0; offset<=0xFC; offset+=4)
  64160. + {
  64161. + MV_REG_WRITE((ETH_DA_FILTER_OTH_MCAST_BASE(portNo) +
  64162. + offset), regValue);
  64163. + }
  64164. +}
  64165. +
  64166. +/*******************************************************************************
  64167. +* ethSetUcastAddr - This function Set the port unicast address table
  64168. +*
  64169. +* DESCRIPTION:
  64170. +* This function locates the proper entry in the Unicast table for the
  64171. +* specified MAC nibble and sets its properties according to function
  64172. +* parameters.
  64173. +*
  64174. +* INPUT:
  64175. +* int ethPortNum - Port number.
  64176. +* MV_U8 lastNibble - Unicast MAC Address last nibble.
  64177. +* int queue - Rx queue number for this MAC address.
  64178. +* value "-1" means remove address
  64179. +*
  64180. +* OUTPUT:
  64181. +* This function add/removes MAC addresses from the port unicast address
  64182. +* table.
  64183. +*
  64184. +* RETURN:
  64185. +* MV_TRUE is output succeeded.
  64186. +* MV_FALSE if option parameter is invalid.
  64187. +*
  64188. +*******************************************************************************/
  64189. +static MV_BOOL ethSetUcastAddr(int portNo, MV_U8 lastNibble, int queue)
  64190. +{
  64191. + unsigned int unicastReg;
  64192. + unsigned int tblOffset;
  64193. + unsigned int regOffset;
  64194. +
  64195. + /* Locate the Unicast table entry */
  64196. + lastNibble = (0xf & lastNibble);
  64197. + tblOffset = (lastNibble / 4) * 4; /* Register offset from unicast table base*/
  64198. + regOffset = lastNibble % 4; /* Entry offset within the above register */
  64199. +
  64200. +
  64201. + unicastReg = MV_REG_READ( (ETH_DA_FILTER_UCAST_BASE(portNo) +
  64202. + tblOffset));
  64203. +
  64204. +
  64205. + if(queue == -1)
  64206. + {
  64207. + /* Clear accepts frame bit at specified unicast DA table entry */
  64208. + unicastReg &= ~(0xFF << (8*regOffset));
  64209. + }
  64210. + else
  64211. + {
  64212. + unicastReg &= ~(0xFF << (8*regOffset));
  64213. + unicastReg |= ((0x01 | (queue<<1)) << (8*regOffset));
  64214. + }
  64215. + MV_REG_WRITE( (ETH_DA_FILTER_UCAST_BASE(portNo) + tblOffset),
  64216. + unicastReg);
  64217. +
  64218. + return MV_TRUE;
  64219. +}
  64220. +
  64221. +/*******************************************************************************
  64222. +* ethSetSpecialMcastAddr - Special Multicast address settings.
  64223. +*
  64224. +* DESCRIPTION:
  64225. +* This routine controls the MV device special MAC multicast support.
  64226. +* The Special Multicast Table for MAC addresses supports MAC of the form
  64227. +* 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0xFF).
  64228. +* The MAC DA[7:0] bits are used as a pointer to the Special Multicast
  64229. +* Table entries in the DA-Filter table.
  64230. +* This function set the Special Multicast Table appropriate entry
  64231. +* according to the argument given.
  64232. +*
  64233. +* INPUT:
  64234. +* int ethPortNum Port number.
  64235. +* unsigned char mcByte Multicast addr last byte (MAC DA[7:0] bits).
  64236. +* int queue Rx queue number for this MAC address.
  64237. +* int option 0 = Add, 1 = remove address.
  64238. +*
  64239. +* OUTPUT:
  64240. +* See description.
  64241. +*
  64242. +* RETURN:
  64243. +* MV_TRUE is output succeeded.
  64244. +* MV_FALSE if option parameter is invalid.
  64245. +*
  64246. +*******************************************************************************/
  64247. +static MV_BOOL ethSetSpecialMcastAddr(int ethPortNum, MV_U8 lastByte, int queue)
  64248. +{
  64249. + unsigned int smcTableReg;
  64250. + unsigned int tblOffset;
  64251. + unsigned int regOffset;
  64252. +
  64253. + /* Locate the SMC table entry */
  64254. + tblOffset = (lastByte / 4); /* Register offset from SMC table base */
  64255. + regOffset = lastByte % 4; /* Entry offset within the above register */
  64256. +
  64257. + smcTableReg = MV_REG_READ((ETH_DA_FILTER_SPEC_MCAST_BASE(ethPortNum) + tblOffset*4));
  64258. +
  64259. + if(queue == -1)
  64260. + {
  64261. + /* Clear accepts frame bit at specified Special DA table entry */
  64262. + smcTableReg &= ~(0xFF << (8 * regOffset));
  64263. + }
  64264. + else
  64265. + {
  64266. + smcTableReg &= ~(0xFF << (8 * regOffset));
  64267. + smcTableReg |= ((0x01 | (queue<<1)) << (8 * regOffset));
  64268. + }
  64269. + MV_REG_WRITE((ETH_DA_FILTER_SPEC_MCAST_BASE(ethPortNum) +
  64270. + tblOffset*4), smcTableReg);
  64271. +
  64272. + return MV_TRUE;
  64273. +}
  64274. +
  64275. +/*******************************************************************************
  64276. +* ethSetOtherMcastAddr - Multicast address settings.
  64277. +*
  64278. +* DESCRIPTION:
  64279. +* This routine controls the MV device Other MAC multicast support.
  64280. +* The Other Multicast Table is used for multicast of another type.
  64281. +* A CRC-8bit is used as an index to the Other Multicast Table entries
  64282. +* in the DA-Filter table.
  64283. +* The function gets the CRC-8bit value from the calling routine and
  64284. +* set the Other Multicast Table appropriate entry according to the
  64285. +* CRC-8 argument given.
  64286. +*
  64287. +* INPUT:
  64288. +* int ethPortNum Port number.
  64289. +* MV_U8 crc8 A CRC-8bit (Polynomial: x^8+x^2+x^1+1).
  64290. +* int queue Rx queue number for this MAC address.
  64291. +*
  64292. +* OUTPUT:
  64293. +* See description.
  64294. +*
  64295. +* RETURN:
  64296. +* MV_TRUE is output succeeded.
  64297. +* MV_FALSE if option parameter is invalid.
  64298. +*
  64299. +*******************************************************************************/
  64300. +static MV_BOOL ethSetOtherMcastAddr(int ethPortNum, MV_U8 crc8, int queue)
  64301. +{
  64302. + unsigned int omcTableReg;
  64303. + unsigned int tblOffset;
  64304. + unsigned int regOffset;
  64305. +
  64306. + /* Locate the OMC table entry */
  64307. + tblOffset = (crc8 / 4) * 4; /* Register offset from OMC table base */
  64308. + regOffset = crc8 % 4; /* Entry offset within the above register */
  64309. +
  64310. + omcTableReg = MV_REG_READ(
  64311. + (ETH_DA_FILTER_OTH_MCAST_BASE(ethPortNum) + tblOffset));
  64312. +
  64313. + if(queue == -1)
  64314. + {
  64315. + /* Clear accepts frame bit at specified Other DA table entry */
  64316. + omcTableReg &= ~(0xFF << (8 * regOffset));
  64317. + }
  64318. + else
  64319. + {
  64320. + omcTableReg &= ~(0xFF << (8 * regOffset));
  64321. + omcTableReg |= ((0x01 | (queue<<1)) << (8 * regOffset));
  64322. + }
  64323. +
  64324. + MV_REG_WRITE((ETH_DA_FILTER_OTH_MCAST_BASE(ethPortNum) + tblOffset),
  64325. + omcTableReg);
  64326. +
  64327. + return MV_TRUE;
  64328. +}
  64329. +
  64330. +
  64331. +/******************************************************************************/
  64332. +/* MIB Counters functions */
  64333. +/******************************************************************************/
  64334. +
  64335. +
  64336. +/*******************************************************************************
  64337. +* mvEthMibCounterRead - Read a MIB counter
  64338. +*
  64339. +* DESCRIPTION:
  64340. +* This function reads a MIB counter of a specific ethernet port.
  64341. +* NOTE - Read from ETH_MIB_GOOD_OCTETS_RECEIVED_LOW or
  64342. +* ETH_MIB_GOOD_OCTETS_SENT_LOW counters will return 64 bits value,
  64343. +* so pHigh32 pointer should not be NULL in this case.
  64344. +*
  64345. +* INPUT:
  64346. +* int ethPortNum - Ethernet Port number.
  64347. +* unsigned int mibOffset - MIB counter offset.
  64348. +*
  64349. +* OUTPUT:
  64350. +* MV_U32* pHigh32 - pointer to place where 32 most significant bits
  64351. +* of the counter will be stored.
  64352. +*
  64353. +* RETURN:
  64354. +* 32 low sgnificant bits of MIB counter value.
  64355. +*
  64356. +*******************************************************************************/
  64357. +MV_U32 mvEthMibCounterRead(void* pPortHandle, unsigned int mibOffset,
  64358. + MV_U32* pHigh32)
  64359. +{
  64360. + int portNo;
  64361. + MV_U32 valLow32, valHigh32;
  64362. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64363. +
  64364. + portNo = pPortCtrl->portNo;
  64365. +
  64366. + valLow32 = MV_REG_READ(ETH_MIB_COUNTERS_BASE(portNo) + mibOffset);
  64367. +
  64368. + /* Implement FEr ETH. Erroneous Value when Reading the Upper 32-bits */
  64369. + /* of a 64-bit MIB Counter. */
  64370. + if( (mibOffset == ETH_MIB_GOOD_OCTETS_RECEIVED_LOW) ||
  64371. + (mibOffset == ETH_MIB_GOOD_OCTETS_SENT_LOW) )
  64372. + {
  64373. + valHigh32 = MV_REG_READ(ETH_MIB_COUNTERS_BASE(portNo) + mibOffset + 4);
  64374. + if(pHigh32 != NULL)
  64375. + *pHigh32 = valHigh32;
  64376. + }
  64377. + return valLow32;
  64378. +}
  64379. +
  64380. +/*******************************************************************************
  64381. +* mvEthMibCountersClear - Clear all MIB counters
  64382. +*
  64383. +* DESCRIPTION:
  64384. +* This function clears all MIB counters
  64385. +*
  64386. +* INPUT:
  64387. +* int ethPortNum - Ethernet Port number.
  64388. +*
  64389. +*
  64390. +* RETURN: void
  64391. +*
  64392. +*******************************************************************************/
  64393. +void mvEthMibCountersClear(void* pPortHandle)
  64394. +{
  64395. + int i, portNo;
  64396. + unsigned int dummy;
  64397. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64398. +
  64399. + portNo = pPortCtrl->portNo;
  64400. +
  64401. + /* Perform dummy reads from MIB counters */
  64402. + for(i=ETH_MIB_GOOD_OCTETS_RECEIVED_LOW; i<ETH_MIB_LATE_COLLISION; i+=4)
  64403. + dummy = MV_REG_READ((ETH_MIB_COUNTERS_BASE(portNo) + i));
  64404. +}
  64405. +
  64406. +
  64407. +/******************************************************************************/
  64408. +/* RX Dispatching configuration routines */
  64409. +/******************************************************************************/
  64410. +
  64411. +int mvEthTosToRxqGet(void* pPortHandle, int tos)
  64412. +{
  64413. + MV_U32 regValue;
  64414. + int regIdx, regOffs, rxq;
  64415. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64416. +
  64417. + if(tos > 0xFF)
  64418. + {
  64419. + mvOsPrintf("eth_%d: tos=0x%x is out of range\n", pPortCtrl->portNo, tos);
  64420. + return -1;
  64421. + }
  64422. + regIdx = mvOsDivide(tos>>2, 10);
  64423. + regOffs = mvOsReminder(tos>>2, 10);
  64424. +
  64425. + regValue = MV_REG_READ(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx) );
  64426. + rxq = (regValue >> (regOffs*3));
  64427. + rxq &= 0x7;
  64428. +
  64429. + return rxq;
  64430. +}
  64431. +
  64432. +/*******************************************************************************
  64433. +* mvEthTosToRxqSet - Map packets with special TOS value to special RX queue
  64434. +*
  64435. +* DESCRIPTION:
  64436. +*
  64437. +* INPUT:
  64438. +* void* pPortHandle - Pointer to port specific handler;
  64439. +* int tos - TOS value in the IP header of the packet
  64440. +* int rxq - RX Queue for packets with the configured TOS value
  64441. +* Negative value (-1) means no special processing for these packets,
  64442. +* so they will be processed as regular packets.
  64443. +*
  64444. +* RETURN: MV_STATUS
  64445. +*******************************************************************************/
  64446. +MV_STATUS mvEthTosToRxqSet(void* pPortHandle, int tos, int rxq)
  64447. +{
  64448. + MV_U32 regValue;
  64449. + int regIdx, regOffs;
  64450. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64451. +
  64452. + if( (rxq < 0) || (rxq >= MV_ETH_RX_Q_NUM) )
  64453. + {
  64454. + mvOsPrintf("eth_%d: RX queue #%d is out of range\n", pPortCtrl->portNo, rxq);
  64455. + return MV_BAD_PARAM;
  64456. + }
  64457. + if(tos > 0xFF)
  64458. + {
  64459. + mvOsPrintf("eth_%d: tos=0x%x is out of range\n", pPortCtrl->portNo, tos);
  64460. + return MV_BAD_PARAM;
  64461. + }
  64462. + regIdx = mvOsDivide(tos>>2, 10);
  64463. + regOffs = mvOsReminder(tos>>2, 10);
  64464. +
  64465. + regValue = MV_REG_READ(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx) );
  64466. + regValue &= ~(0x7 << (regOffs*3));
  64467. + regValue |= (rxq << (regOffs*3));
  64468. +
  64469. + MV_REG_WRITE(ETH_DIFF_SERV_PRIO_REG(pPortCtrl->portNo, regIdx), regValue);
  64470. + return MV_OK;
  64471. +}
  64472. +
  64473. +/*******************************************************************************
  64474. +* mvEthVlanPrioRxQueue - Configure RX queue to capture VLAN tagged packets with
  64475. +* special priority bits [0-2]
  64476. +*
  64477. +* DESCRIPTION:
  64478. +*
  64479. +* INPUT:
  64480. +* void* pPortHandle - Pointer to port specific handler;
  64481. +* int bpduQueue - Special queue to capture VLAN tagged packets with special
  64482. +* priority.
  64483. +* Negative value (-1) means no special processing for these packets,
  64484. +* so they will be processed as regular packets.
  64485. +*
  64486. +* RETURN: MV_STATUS
  64487. +* MV_OK - Success
  64488. +* MV_FAIL - Failed.
  64489. +*
  64490. +*******************************************************************************/
  64491. +MV_STATUS mvEthVlanPrioRxQueue(void* pPortHandle, int vlanPrio, int vlanPrioQueue)
  64492. +{
  64493. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64494. + MV_U32 vlanPrioReg;
  64495. +
  64496. + if(vlanPrioQueue >= MV_ETH_RX_Q_NUM)
  64497. + {
  64498. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", vlanPrioQueue);
  64499. + return MV_BAD_PARAM;
  64500. + }
  64501. + if(vlanPrio >= 8)
  64502. + {
  64503. + mvOsPrintf("ethDrv: vlanPrio=%d is out of range\n", vlanPrio);
  64504. + return MV_BAD_PARAM;
  64505. + }
  64506. +
  64507. + vlanPrioReg = MV_REG_READ(ETH_VLAN_TAG_TO_PRIO_REG(pPortCtrl->portNo));
  64508. + vlanPrioReg &= ~(0x7 << (vlanPrio*3));
  64509. + vlanPrioReg |= (vlanPrioQueue << (vlanPrio*3));
  64510. + MV_REG_WRITE(ETH_VLAN_TAG_TO_PRIO_REG(pPortCtrl->portNo), vlanPrioReg);
  64511. +
  64512. + return MV_OK;
  64513. +}
  64514. +
  64515. +
  64516. +/*******************************************************************************
  64517. +* mvEthBpduRxQueue - Configure RX queue to capture BPDU packets.
  64518. +*
  64519. +* DESCRIPTION:
  64520. +* This function defines processing of BPDU packets.
  64521. +* BPDU packets can be accepted and captured to one of RX queues
  64522. +* or can be processing as regular Multicast packets.
  64523. +*
  64524. +* INPUT:
  64525. +* void* pPortHandle - Pointer to port specific handler;
  64526. +* int bpduQueue - Special queue to capture BPDU packets (DA is equal to
  64527. +* 01-80-C2-00-00-00 through 01-80-C2-00-00-FF,
  64528. +* except for the Flow-Control Pause packets).
  64529. +* Negative value (-1) means no special processing for BPDU,
  64530. +* packets so they will be processed as regular Multicast packets.
  64531. +*
  64532. +* RETURN: MV_STATUS
  64533. +* MV_OK - Success
  64534. +* MV_FAIL - Failed.
  64535. +*
  64536. +*******************************************************************************/
  64537. +MV_STATUS mvEthBpduRxQueue(void* pPortHandle, int bpduQueue)
  64538. +{
  64539. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64540. + MV_U32 portCfgReg;
  64541. + MV_U32 portCfgExtReg;
  64542. +
  64543. + if(bpduQueue >= MV_ETH_RX_Q_NUM)
  64544. + {
  64545. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", bpduQueue);
  64546. + return MV_BAD_PARAM;
  64547. + }
  64548. +
  64549. + portCfgExtReg = MV_REG_READ(ETH_PORT_CONFIG_EXTEND_REG(pPortCtrl->portNo));
  64550. +
  64551. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  64552. + if(bpduQueue >= 0)
  64553. + {
  64554. + pPortCtrl->portConfig.rxBpduQ = bpduQueue;
  64555. +
  64556. + portCfgReg &= ~ETH_DEF_RX_BPDU_QUEUE_ALL_MASK;
  64557. + portCfgReg |= ETH_DEF_RX_BPDU_QUEUE_MASK(pPortCtrl->portConfig.rxBpduQ);
  64558. +
  64559. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  64560. +
  64561. + portCfgExtReg |= ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK;
  64562. + }
  64563. + else
  64564. + {
  64565. + pPortCtrl->portConfig.rxBpduQ = -1;
  64566. + /* no special processing for BPDU packets */
  64567. + portCfgExtReg &= (~ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK);
  64568. + }
  64569. +
  64570. + MV_REG_WRITE(ETH_PORT_CONFIG_EXTEND_REG(pPortCtrl->portNo), portCfgExtReg);
  64571. +
  64572. + return MV_OK;
  64573. +}
  64574. +
  64575. +
  64576. +/*******************************************************************************
  64577. +* mvEthArpRxQueue - Configure RX queue to capture ARP packets.
  64578. +*
  64579. +* DESCRIPTION:
  64580. +* This function defines processing of ARP (type=0x0806) packets.
  64581. +* ARP packets can be accepted and captured to one of RX queues
  64582. +* or can be processed as other Broadcast packets.
  64583. +*
  64584. +* INPUT:
  64585. +* void* pPortHandle - Pointer to port specific handler;
  64586. +* int arpQueue - Special queue to capture ARP packets (type=0x806).
  64587. +* Negative value (-1) means discard ARP packets
  64588. +*
  64589. +* RETURN: MV_STATUS
  64590. +* MV_OK - Success
  64591. +* MV_FAIL - Failed.
  64592. +*
  64593. +*******************************************************************************/
  64594. +MV_STATUS mvEthArpRxQueue(void* pPortHandle, int arpQueue)
  64595. +{
  64596. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64597. + MV_U32 portCfgReg;
  64598. +
  64599. + if(arpQueue >= MV_ETH_RX_Q_NUM)
  64600. + {
  64601. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", arpQueue);
  64602. + return MV_BAD_PARAM;
  64603. + }
  64604. +
  64605. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  64606. +
  64607. + if(arpQueue >= 0)
  64608. + {
  64609. + pPortCtrl->portConfig.rxArpQ = arpQueue;
  64610. + portCfgReg &= ~ETH_DEF_RX_ARP_QUEUE_ALL_MASK;
  64611. + portCfgReg |= ETH_DEF_RX_ARP_QUEUE_MASK(pPortCtrl->portConfig.rxArpQ);
  64612. +
  64613. + portCfgReg &= (~ETH_REJECT_ARP_BCAST_MASK);
  64614. + }
  64615. + else
  64616. + {
  64617. + pPortCtrl->portConfig.rxArpQ = -1;
  64618. + portCfgReg |= ETH_REJECT_ARP_BCAST_MASK;
  64619. + }
  64620. +
  64621. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  64622. +
  64623. + return MV_OK;
  64624. +}
  64625. +
  64626. +
  64627. +/*******************************************************************************
  64628. +* mvEthTcpRxQueue - Configure RX queue to capture TCP packets.
  64629. +*
  64630. +* DESCRIPTION:
  64631. +* This function defines processing of TCP packets.
  64632. +* TCP packets can be accepted and captured to one of RX queues
  64633. +* or can be processed as regular Unicast packets.
  64634. +*
  64635. +* INPUT:
  64636. +* void* pPortHandle - Pointer to port specific handler;
  64637. +* int tcpQueue - Special queue to capture TCP packets. Value "-1"
  64638. +* means no special processing for TCP packets,
  64639. +* so they will be processed as regular
  64640. +*
  64641. +* RETURN: MV_STATUS
  64642. +* MV_OK - Success
  64643. +* MV_FAIL - Failed.
  64644. +*
  64645. +*******************************************************************************/
  64646. +MV_STATUS mvEthTcpRxQueue(void* pPortHandle, int tcpQueue)
  64647. +{
  64648. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64649. + MV_U32 portCfgReg;
  64650. +
  64651. + if(tcpQueue >= MV_ETH_RX_Q_NUM)
  64652. + {
  64653. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", tcpQueue);
  64654. + return MV_BAD_PARAM;
  64655. + }
  64656. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  64657. +
  64658. + if(tcpQueue >= 0)
  64659. + {
  64660. + pPortCtrl->portConfig.rxTcpQ = tcpQueue;
  64661. + portCfgReg &= ~ETH_DEF_RX_TCP_QUEUE_ALL_MASK;
  64662. + portCfgReg |= ETH_DEF_RX_TCP_QUEUE_MASK(pPortCtrl->portConfig.rxTcpQ);
  64663. +
  64664. + portCfgReg |= ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK;
  64665. + }
  64666. + else
  64667. + {
  64668. + pPortCtrl->portConfig.rxTcpQ = -1;
  64669. + portCfgReg &= (~ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK);
  64670. + }
  64671. +
  64672. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  64673. +
  64674. + return MV_OK;
  64675. +}
  64676. +
  64677. +
  64678. +/*******************************************************************************
  64679. +* mvEthUdpRxQueue - Configure RX queue to capture UDP packets.
  64680. +*
  64681. +* DESCRIPTION:
  64682. +* This function defines processing of UDP packets.
  64683. +* TCP packets can be accepted and captured to one of RX queues
  64684. +* or can be processed as regular Unicast packets.
  64685. +*
  64686. +* INPUT:
  64687. +* void* pPortHandle - Pointer to port specific handler;
  64688. +* int udpQueue - Special queue to capture UDP packets. Value "-1"
  64689. +* means no special processing for UDP packets,
  64690. +* so they will be processed as regular
  64691. +*
  64692. +* RETURN: MV_STATUS
  64693. +* MV_OK - Success
  64694. +* MV_FAIL - Failed.
  64695. +*
  64696. +*******************************************************************************/
  64697. +MV_STATUS mvEthUdpRxQueue(void* pPortHandle, int udpQueue)
  64698. +{
  64699. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64700. + MV_U32 portCfgReg;
  64701. +
  64702. + if(udpQueue >= MV_ETH_RX_Q_NUM)
  64703. + {
  64704. + mvOsPrintf("ethDrv: RX queue #%d is out of range\n", udpQueue);
  64705. + return MV_BAD_PARAM;
  64706. + }
  64707. +
  64708. + portCfgReg = MV_REG_READ(ETH_PORT_CONFIG_REG(pPortCtrl->portNo));
  64709. +
  64710. + if(udpQueue >= 0)
  64711. + {
  64712. + pPortCtrl->portConfig.rxUdpQ = udpQueue;
  64713. + portCfgReg &= ~ETH_DEF_RX_UDP_QUEUE_ALL_MASK;
  64714. + portCfgReg |= ETH_DEF_RX_UDP_QUEUE_MASK(pPortCtrl->portConfig.rxUdpQ);
  64715. +
  64716. + portCfgReg |= ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK;
  64717. + }
  64718. + else
  64719. + {
  64720. + pPortCtrl->portConfig.rxUdpQ = -1;
  64721. + portCfgReg &= ~ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK;
  64722. + }
  64723. +
  64724. + MV_REG_WRITE(ETH_PORT_CONFIG_REG(pPortCtrl->portNo), portCfgReg);
  64725. +
  64726. + return MV_OK;
  64727. +}
  64728. +
  64729. +
  64730. +/******************************************************************************/
  64731. +/* Speed, Duplex, FlowControl routines */
  64732. +/******************************************************************************/
  64733. +
  64734. +/*******************************************************************************
  64735. +* mvEthSpeedDuplexSet - Set Speed and Duplex of the port.
  64736. +*
  64737. +* DESCRIPTION:
  64738. +* This function configure the port to work with desirable Duplex and Speed.
  64739. +* Changing of these parameters are allowed only when port is disabled.
  64740. +* This function disable the port if was enabled, change duplex and speed
  64741. +* and, enable the port back if needed.
  64742. +*
  64743. +* INPUT:
  64744. +* void* pPortHandle - Pointer to port specific handler;
  64745. +* ETH_PORT_SPEED speed - Speed of the port.
  64746. +* ETH_PORT_SPEED duplex - Duplex of the port.
  64747. +*
  64748. +* RETURN: MV_STATUS
  64749. +* MV_OK - Success
  64750. +* MV_OUT_OF_RANGE - Failed. Port is out of valid range
  64751. +* MV_NOT_FOUND - Failed. Port is not initialized.
  64752. +* MV_BAD_PARAM - Input parameters (speed/duplex) in conflict.
  64753. +* MV_BAD_VALUE - Value of one of input parameters (speed, duplex)
  64754. +* is not valid
  64755. +*
  64756. +*******************************************************************************/
  64757. +MV_STATUS mvEthSpeedDuplexSet(void* pPortHandle, MV_ETH_PORT_SPEED speed,
  64758. + MV_ETH_PORT_DUPLEX duplex)
  64759. +{
  64760. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64761. + int port = pPortCtrl->portNo;
  64762. + MV_U32 portSerialCtrlReg;
  64763. +
  64764. + if( (port < 0) || (port >= (int)mvCtrlEthMaxPortGet()) )
  64765. + return MV_OUT_OF_RANGE;
  64766. +
  64767. + pPortCtrl = ethPortCtrl[port];
  64768. + if(pPortCtrl == NULL)
  64769. + return MV_NOT_FOUND;
  64770. +
  64771. + /* Check validity */
  64772. + if( (speed == MV_ETH_SPEED_1000) && (duplex == MV_ETH_DUPLEX_HALF) )
  64773. + return MV_BAD_PARAM;
  64774. +
  64775. + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));
  64776. + /* Set Speed */
  64777. + switch(speed)
  64778. + {
  64779. + case MV_ETH_SPEED_AN:
  64780. + portSerialCtrlReg &= ~ETH_DISABLE_SPEED_AUTO_NEG_MASK;
  64781. + break;
  64782. +
  64783. + case MV_ETH_SPEED_10:
  64784. + portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;
  64785. + portSerialCtrlReg &= ~ETH_SET_GMII_SPEED_1000_MASK;
  64786. + portSerialCtrlReg &= ~ETH_SET_MII_SPEED_100_MASK;
  64787. + break;
  64788. +
  64789. + case MV_ETH_SPEED_100:
  64790. + portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;
  64791. + portSerialCtrlReg &= ~ETH_SET_GMII_SPEED_1000_MASK;
  64792. + portSerialCtrlReg |= ETH_SET_MII_SPEED_100_MASK;
  64793. + break;
  64794. +
  64795. + case MV_ETH_SPEED_1000:
  64796. + portSerialCtrlReg |= ETH_DISABLE_SPEED_AUTO_NEG_MASK;
  64797. + portSerialCtrlReg |= ETH_SET_GMII_SPEED_1000_MASK;
  64798. + break;
  64799. +
  64800. + default:
  64801. + mvOsPrintf("ethDrv: Unexpected Speed value %d\n", speed);
  64802. + return MV_BAD_VALUE;
  64803. + }
  64804. + /* Set duplex */
  64805. + switch(duplex)
  64806. + {
  64807. + case MV_ETH_DUPLEX_AN:
  64808. + portSerialCtrlReg &= ~ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;
  64809. + break;
  64810. +
  64811. + case MV_ETH_DUPLEX_HALF:
  64812. + portSerialCtrlReg |= ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;
  64813. + portSerialCtrlReg &= ~ETH_SET_FULL_DUPLEX_MASK;
  64814. + break;
  64815. +
  64816. + case MV_ETH_DUPLEX_FULL:
  64817. + portSerialCtrlReg |= ETH_DISABLE_DUPLEX_AUTO_NEG_MASK;
  64818. + portSerialCtrlReg |= ETH_SET_FULL_DUPLEX_MASK;
  64819. + break;
  64820. +
  64821. + default:
  64822. + mvOsPrintf("ethDrv: Unexpected Duplex value %d\n", duplex);
  64823. + return MV_BAD_VALUE;
  64824. + }
  64825. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(port), portSerialCtrlReg);
  64826. +
  64827. + return MV_OK;
  64828. +}
  64829. +
  64830. +/*******************************************************************************
  64831. +* mvEthFlowCtrlSet - Set Flow Control of the port.
  64832. +*
  64833. +* DESCRIPTION:
  64834. +* This function configure the port to work with desirable Duplex and
  64835. +* Speed. Changing of these parameters are allowed only when port is
  64836. +* disabled. This function disable the port if was enabled, change
  64837. +* duplex and speed and, enable the port back if needed.
  64838. +*
  64839. +* INPUT:
  64840. +* void* pPortHandle - Pointer to port specific handler;
  64841. +* MV_ETH_PORT_FC flowControl - Flow control of the port.
  64842. +*
  64843. +* RETURN: MV_STATUS
  64844. +* MV_OK - Success
  64845. +* MV_OUT_OF_RANGE - Failed. Port is out of valid range
  64846. +* MV_NOT_FOUND - Failed. Port is not initialized.
  64847. +* MV_BAD_VALUE - Value flowControl parameters is not valid
  64848. +*
  64849. +*******************************************************************************/
  64850. +MV_STATUS mvEthFlowCtrlSet(void* pPortHandle, MV_ETH_PORT_FC flowControl)
  64851. +{
  64852. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64853. + int port = pPortCtrl->portNo;
  64854. + MV_U32 portSerialCtrlReg;
  64855. +
  64856. + if( (port < 0) || (port >= (int)mvCtrlEthMaxPortGet() ) )
  64857. + return MV_OUT_OF_RANGE;
  64858. +
  64859. + pPortCtrl = ethPortCtrl[port];
  64860. + if(pPortCtrl == NULL)
  64861. + return MV_NOT_FOUND;
  64862. +
  64863. + portSerialCtrlReg = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));
  64864. + switch(flowControl)
  64865. + {
  64866. + case MV_ETH_FC_AN_ADV_DIS:
  64867. + portSerialCtrlReg &= ~ETH_DISABLE_FC_AUTO_NEG_MASK;
  64868. + portSerialCtrlReg &= ~ETH_ADVERTISE_SYM_FC_MASK;
  64869. + break;
  64870. +
  64871. + case MV_ETH_FC_AN_ADV_SYM:
  64872. + portSerialCtrlReg &= ~ETH_DISABLE_FC_AUTO_NEG_MASK;
  64873. + portSerialCtrlReg |= ETH_ADVERTISE_SYM_FC_MASK;
  64874. + break;
  64875. +
  64876. + case MV_ETH_FC_DISABLE:
  64877. + portSerialCtrlReg |= ETH_DISABLE_FC_AUTO_NEG_MASK;
  64878. + portSerialCtrlReg &= ~ETH_SET_FLOW_CTRL_MASK;
  64879. + break;
  64880. +
  64881. + case MV_ETH_FC_ENABLE:
  64882. + portSerialCtrlReg |= ETH_DISABLE_FC_AUTO_NEG_MASK;
  64883. + portSerialCtrlReg |= ETH_SET_FLOW_CTRL_MASK;
  64884. + break;
  64885. +
  64886. + default:
  64887. + mvOsPrintf("ethDrv: Unexpected FlowControl value %d\n", flowControl);
  64888. + return MV_BAD_VALUE;
  64889. + }
  64890. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_REG(port), portSerialCtrlReg);
  64891. +
  64892. + return MV_OK;
  64893. +}
  64894. +
  64895. +/*******************************************************************************
  64896. +* mvEthHeaderModeSet - Set port header mode.
  64897. +*
  64898. +* DESCRIPTION:
  64899. +* This function configures the port to work in Marvell-Header mode.
  64900. +*
  64901. +* INPUT:
  64902. +* void* pPortHandle - Pointer to port specific handler;
  64903. +* MV_ETH_HEADER_MODE headerMode - The header mode to set the port in.
  64904. +*
  64905. +* RETURN: MV_STATUS
  64906. +* MV_OK - Success
  64907. +* MV_NOT_SUPPORTED- Feature not supported.
  64908. +* MV_OUT_OF_RANGE - Failed. Port is out of valid range
  64909. +* MV_NOT_FOUND - Failed. Port is not initialized.
  64910. +* MV_BAD_VALUE - Value of headerMode or numRxQueue parameter is not valid.
  64911. +*
  64912. +*******************************************************************************/
  64913. +MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode)
  64914. +{
  64915. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64916. + int port = pPortCtrl->portNo;
  64917. + MV_U32 mvHeaderReg;
  64918. + MV_U32 numRxQ = MV_ETH_RX_Q_NUM;
  64919. +
  64920. + if((port < 0) || (port >= mvCtrlEthMaxPortGet()))
  64921. + return MV_OUT_OF_RANGE;
  64922. +
  64923. + pPortCtrl = ethPortCtrl[port];
  64924. + if(pPortCtrl == NULL)
  64925. + return MV_NOT_FOUND;
  64926. +
  64927. + mvHeaderReg = MV_REG_READ(ETH_PORT_MARVELL_HEADER_REG(port));
  64928. + /* Disable header mode. */
  64929. + mvHeaderReg &= ~ETH_MVHDR_EN_MASK;
  64930. +
  64931. + if(headerMode != MV_ETH_DISABLE_HEADER_MODE)
  64932. + {
  64933. + /* Enable Header mode. */
  64934. + mvHeaderReg |= ETH_MVHDR_EN_MASK;
  64935. +
  64936. + /* Clear DA-Prefix & MHMask fields.*/
  64937. + mvHeaderReg &= ~(ETH_MVHDR_DAPREFIX_MASK | ETH_MVHDR_MHMASK_MASK);
  64938. +
  64939. + if(numRxQ > 1)
  64940. + {
  64941. + switch (headerMode)
  64942. + {
  64943. + case(MV_ETH_ENABLE_HEADER_MODE_PRI_2_1):
  64944. + mvHeaderReg |= ETH_MVHDR_DAPREFIX_PRI_1_2;
  64945. + break;
  64946. + case(MV_ETH_ENABLE_HEADER_MODE_PRI_DBNUM):
  64947. + mvHeaderReg |= ETH_MVHDR_DAPREFIX_DBNUM_PRI;
  64948. + break;
  64949. + case(MV_ETH_ENABLE_HEADER_MODE_PRI_SPID):
  64950. + mvHeaderReg |= ETH_MVHDR_DAPREFIX_SPID_PRI;
  64951. + break;
  64952. + default:
  64953. + break;
  64954. + }
  64955. +
  64956. + switch (numRxQ)
  64957. + {
  64958. + case (4):
  64959. + mvHeaderReg |= ETH_MVHDR_MHMASK_4_QUEUE;
  64960. + break;
  64961. + case (8):
  64962. + mvHeaderReg |= ETH_MVHDR_MHMASK_8_QUEUE;
  64963. + break;
  64964. + default:
  64965. + break;
  64966. + }
  64967. + }
  64968. + }
  64969. +
  64970. + MV_REG_WRITE(ETH_PORT_MARVELL_HEADER_REG(port), mvHeaderReg);
  64971. +
  64972. + return MV_OK;
  64973. +}
  64974. +
  64975. +#if (MV_ETH_VERSION >= 4)
  64976. +/*******************************************************************************
  64977. +* mvEthEjpModeSet - Enable / Disable EJP policy for TX.
  64978. +*
  64979. +* DESCRIPTION:
  64980. +* This function
  64981. +*
  64982. +* INPUT:
  64983. +* void* pPortHandle - Pointer to port specific handler;
  64984. +* MV_BOOL TRUE - enable EJP mode
  64985. +* FALSE - disable EJP mode
  64986. +*
  64987. +* OUTPUT: MV_STATUS
  64988. +* MV_OK - Success
  64989. +* Other - Failure
  64990. +*
  64991. +* RETURN: None.
  64992. +*
  64993. +*******************************************************************************/
  64994. +MV_STATUS mvEthEjpModeSet(void* pPortHandle, int mode)
  64995. +{
  64996. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  64997. + int port = pPortCtrl->portNo;
  64998. +
  64999. + if((port < 0) || (port >= mvCtrlEthMaxPortGet()))
  65000. + return MV_OUT_OF_RANGE;
  65001. +
  65002. + pPortCtrl = ethPortCtrl[port];
  65003. + if(pPortCtrl == NULL)
  65004. + return MV_NOT_FOUND;
  65005. +
  65006. + pPortCtrl->portConfig.ejpMode = mode;
  65007. + if(mode)
  65008. + {
  65009. + /* EJP enabled */
  65010. + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(port), ETH_TX_EJP_ENABLE_MASK);
  65011. + }
  65012. + else
  65013. + {
  65014. + /* EJP disabled */
  65015. + MV_REG_WRITE(ETH_TXQ_CMD_1_REG(port), 0);
  65016. + }
  65017. + mvOsPrintf("eth_%d: EJP %s - ETH_TXQ_CMD_1_REG: 0x%x = 0x%08x\n",
  65018. + port, mode ? "Enabled" : "Disabled", ETH_TXQ_CMD_1_REG(port),
  65019. + MV_REG_READ(ETH_TXQ_CMD_1_REG(port)));
  65020. +
  65021. + return MV_OK;
  65022. +}
  65023. +#endif /* MV_ETH_VERSION >= 4 */
  65024. +
  65025. +/*******************************************************************************
  65026. +* mvEthStatusGet - Get major properties of the port .
  65027. +*
  65028. +* DESCRIPTION:
  65029. +* This function get major properties of the port (link, speed, duplex,
  65030. +* flowControl, etc) and return them using the single structure.
  65031. +*
  65032. +* INPUT:
  65033. +* void* pPortHandle - Pointer to port specific handler;
  65034. +*
  65035. +* OUTPUT:
  65036. +* MV_ETH_PORT_STATUS* pStatus - Pointer to structure, were port status
  65037. +* will be placed.
  65038. +*
  65039. +* RETURN: None.
  65040. +*
  65041. +*******************************************************************************/
  65042. +void mvEthStatusGet(void* pPortHandle, MV_ETH_PORT_STATUS* pStatus)
  65043. +{
  65044. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  65045. + int port = pPortCtrl->portNo;
  65046. +
  65047. + MV_U32 regValue;
  65048. +
  65049. + regValue = MV_REG_READ( ETH_PORT_STATUS_REG(port) );
  65050. +
  65051. + if(regValue & ETH_GMII_SPEED_1000_MASK)
  65052. + pStatus->speed = MV_ETH_SPEED_1000;
  65053. + else if(regValue & ETH_MII_SPEED_100_MASK)
  65054. + pStatus->speed = MV_ETH_SPEED_100;
  65055. + else
  65056. + pStatus->speed = MV_ETH_SPEED_10;
  65057. +
  65058. + if(regValue & ETH_LINK_UP_MASK)
  65059. + pStatus->isLinkUp = MV_TRUE;
  65060. + else
  65061. + pStatus->isLinkUp = MV_FALSE;
  65062. +
  65063. + if(regValue & ETH_FULL_DUPLEX_MASK)
  65064. + pStatus->duplex = MV_ETH_DUPLEX_FULL;
  65065. + else
  65066. + pStatus->duplex = MV_ETH_DUPLEX_HALF;
  65067. +
  65068. +
  65069. + if(regValue & ETH_ENABLE_RCV_FLOW_CTRL_MASK)
  65070. + pStatus->flowControl = MV_ETH_FC_ENABLE;
  65071. + else
  65072. + pStatus->flowControl = MV_ETH_FC_DISABLE;
  65073. +}
  65074. +
  65075. +
  65076. +/******************************************************************************/
  65077. +/* PHY Control Functions */
  65078. +/******************************************************************************/
  65079. +
  65080. +
  65081. +/*******************************************************************************
  65082. +* mvEthPhyAddrSet - Set the ethernet port PHY address.
  65083. +*
  65084. +* DESCRIPTION:
  65085. +* This routine set the ethernet port PHY address according to given
  65086. +* parameter.
  65087. +*
  65088. +* INPUT:
  65089. +* void* pPortHandle - Pointer to port specific handler;
  65090. +* int phyAddr - PHY address
  65091. +*
  65092. +* RETURN:
  65093. +* None.
  65094. +*
  65095. +*******************************************************************************/
  65096. +void mvEthPhyAddrSet(void* pPortHandle, int phyAddr)
  65097. +{
  65098. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  65099. + int port = pPortCtrl->portNo;
  65100. + unsigned int regData;
  65101. +
  65102. + regData = MV_REG_READ(ETH_PHY_ADDR_REG(port));
  65103. +
  65104. + regData &= ~ETH_PHY_ADDR_MASK;
  65105. + regData |= phyAddr;
  65106. +
  65107. + MV_REG_WRITE(ETH_PHY_ADDR_REG(port), regData);
  65108. +
  65109. + return;
  65110. +}
  65111. +
  65112. +/*******************************************************************************
  65113. +* mvEthPhyAddrGet - Get the ethernet port PHY address.
  65114. +*
  65115. +* DESCRIPTION:
  65116. +* This routine returns the given ethernet port PHY address.
  65117. +*
  65118. +* INPUT:
  65119. +* void* pPortHandle - Pointer to port specific handler;
  65120. +*
  65121. +*
  65122. +* RETURN: int - PHY address.
  65123. +*
  65124. +*******************************************************************************/
  65125. +int mvEthPhyAddrGet(void* pPortHandle)
  65126. +{
  65127. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHandle;
  65128. + int port = pPortCtrl->portNo;
  65129. + unsigned int regData;
  65130. +
  65131. + regData = MV_REG_READ(ETH_PHY_ADDR_REG(port));
  65132. +
  65133. + return ((regData >> (5 * port)) & 0x1f);
  65134. +}
  65135. +
  65136. +/******************************************************************************/
  65137. +/* Descriptor handling Functions */
  65138. +/******************************************************************************/
  65139. +
  65140. +/*******************************************************************************
  65141. +* etherInitRxDescRing - Curve a Rx chain desc list and buffer in memory.
  65142. +*
  65143. +* DESCRIPTION:
  65144. +* This function prepares a Rx chained list of descriptors and packet
  65145. +* buffers in a form of a ring. The routine must be called after port
  65146. +* initialization routine and before port start routine.
  65147. +* The Ethernet SDMA engine uses CPU bus addresses to access the various
  65148. +* devices in the system (i.e. DRAM). This function uses the ethernet
  65149. +* struct 'virtual to physical' routine (set by the user) to set the ring
  65150. +* with physical addresses.
  65151. +*
  65152. +* INPUT:
  65153. +* ETH_QUEUE_CTRL *pEthPortCtrl Ethernet Port Control srtuct.
  65154. +* int rxQueue Number of Rx queue.
  65155. +* int rxDescNum Number of Rx descriptors
  65156. +* MV_U8* rxDescBaseAddr Rx descriptors memory area base addr.
  65157. +*
  65158. +* OUTPUT:
  65159. +* The routine updates the Ethernet port control struct with information
  65160. +* regarding the Rx descriptors and buffers.
  65161. +*
  65162. +* RETURN: None
  65163. +*
  65164. +*******************************************************************************/
  65165. +static void ethInitRxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue)
  65166. +{
  65167. + ETH_RX_DESC *pRxDescBase, *pRxDesc, *pRxPrevDesc;
  65168. + int ix, rxDescNum = pPortCtrl->rxQueueConfig[queue].descrNum;
  65169. + ETH_QUEUE_CTRL *pQueueCtrl = &pPortCtrl->rxQueue[queue];
  65170. +
  65171. + /* Make sure descriptor address is cache line size aligned */
  65172. + pRxDescBase = (ETH_RX_DESC*)MV_ALIGN_UP((MV_ULONG)pQueueCtrl->descBuf.bufVirtPtr,
  65173. + CPU_D_CACHE_LINE_SIZE);
  65174. +
  65175. + pRxDesc = (ETH_RX_DESC*)pRxDescBase;
  65176. + pRxPrevDesc = pRxDesc;
  65177. +
  65178. + /* initialize the Rx descriptors ring */
  65179. + for (ix=0; ix<rxDescNum; ix++)
  65180. + {
  65181. + pRxDesc->bufSize = 0x0;
  65182. + pRxDesc->byteCnt = 0x0;
  65183. + pRxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
  65184. + pRxDesc->bufPtr = 0x0;
  65185. + pRxDesc->returnInfo = 0x0;
  65186. + pRxPrevDesc = pRxDesc;
  65187. + if(ix == (rxDescNum-1))
  65188. + {
  65189. + /* Closing Rx descriptors ring */
  65190. + pRxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pRxDescBase);
  65191. + }
  65192. + else
  65193. + {
  65194. + pRxDesc = (ETH_RX_DESC*)((MV_ULONG)pRxDesc + ETH_RX_DESC_ALIGNED_SIZE);
  65195. + pRxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pRxDesc);
  65196. + }
  65197. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxPrevDesc);
  65198. + }
  65199. +
  65200. + pQueueCtrl->pCurrentDescr = pRxDescBase;
  65201. + pQueueCtrl->pUsedDescr = pRxDescBase;
  65202. +
  65203. + pQueueCtrl->pFirstDescr = pRxDescBase;
  65204. + pQueueCtrl->pLastDescr = pRxDesc;
  65205. + pQueueCtrl->resource = 0;
  65206. +}
  65207. +
  65208. +void ethResetRxDescRing(void* pPortHndl, int queue)
  65209. +{
  65210. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65211. + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->rxQueue[queue];
  65212. + ETH_RX_DESC* pRxDesc = (ETH_RX_DESC*)pQueueCtrl->pFirstDescr;
  65213. +
  65214. + pQueueCtrl->resource = 0;
  65215. + if(pQueueCtrl->pFirstDescr != NULL)
  65216. + {
  65217. + while(MV_TRUE)
  65218. + {
  65219. + pRxDesc->bufSize = 0x0;
  65220. + pRxDesc->byteCnt = 0x0;
  65221. + pRxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
  65222. + pRxDesc->bufPtr = 0x0;
  65223. + pRxDesc->returnInfo = 0x0;
  65224. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxDesc);
  65225. + if( (void*)pRxDesc == pQueueCtrl->pLastDescr)
  65226. + break;
  65227. + pRxDesc = RX_NEXT_DESC_PTR(pRxDesc, pQueueCtrl);
  65228. + }
  65229. + pQueueCtrl->pCurrentDescr = pQueueCtrl->pFirstDescr;
  65230. + pQueueCtrl->pUsedDescr = pQueueCtrl->pFirstDescr;
  65231. +
  65232. + /* Update RX Command register */
  65233. + pPortCtrl->portRxQueueCmdReg |= (1 << queue);
  65234. +
  65235. + /* update HW */
  65236. + MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue),
  65237. + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
  65238. + }
  65239. + else
  65240. + {
  65241. + /* Update RX Command register */
  65242. + pPortCtrl->portRxQueueCmdReg &= ~(1 << queue);
  65243. +
  65244. + /* update HW */
  65245. + MV_REG_WRITE( ETH_RX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue), 0);
  65246. + }
  65247. +}
  65248. +
  65249. +/*******************************************************************************
  65250. +* etherInitTxDescRing - Curve a Tx chain desc list and buffer in memory.
  65251. +*
  65252. +* DESCRIPTION:
  65253. +* This function prepares a Tx chained list of descriptors and packet
  65254. +* buffers in a form of a ring. The routine must be called after port
  65255. +* initialization routine and before port start routine.
  65256. +* The Ethernet SDMA engine uses CPU bus addresses to access the various
  65257. +* devices in the system (i.e. DRAM). This function uses the ethernet
  65258. +* struct 'virtual to physical' routine (set by the user) to set the ring
  65259. +* with physical addresses.
  65260. +*
  65261. +* INPUT:
  65262. +* ETH_PORT_CTRL *pEthPortCtrl Ethernet Port Control srtuct.
  65263. +* int txQueue Number of Tx queue.
  65264. +* int txDescNum Number of Tx descriptors
  65265. +* int txBuffSize Size of Tx buffer
  65266. +* MV_U8* pTxDescBase Tx descriptors memory area base addr.
  65267. +*
  65268. +* OUTPUT:
  65269. +* The routine updates the Ethernet port control struct with information
  65270. +* regarding the Tx descriptors and buffers.
  65271. +*
  65272. +* RETURN: None.
  65273. +*
  65274. +*******************************************************************************/
  65275. +static void ethInitTxDescRing(ETH_PORT_CTRL* pPortCtrl, int queue)
  65276. +{
  65277. + ETH_TX_DESC *pTxDescBase, *pTxDesc, *pTxPrevDesc;
  65278. + int ix, txDescNum = pPortCtrl->txQueueConfig[queue].descrNum;
  65279. + ETH_QUEUE_CTRL *pQueueCtrl = &pPortCtrl->txQueue[queue];
  65280. +
  65281. + /* Make sure descriptor address is cache line size aligned */
  65282. + pTxDescBase = (ETH_TX_DESC*)MV_ALIGN_UP((MV_ULONG)pQueueCtrl->descBuf.bufVirtPtr,
  65283. + CPU_D_CACHE_LINE_SIZE);
  65284. +
  65285. + pTxDesc = (ETH_TX_DESC*)pTxDescBase;
  65286. + pTxPrevDesc = pTxDesc;
  65287. +
  65288. + /* initialize the Tx descriptors ring */
  65289. + for (ix=0; ix<txDescNum; ix++)
  65290. + {
  65291. + pTxDesc->byteCnt = 0x0000;
  65292. + pTxDesc->L4iChk = 0x0000;
  65293. + pTxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
  65294. + pTxDesc->bufPtr = 0x0;
  65295. + pTxDesc->returnInfo = 0x0;
  65296. +
  65297. + pTxPrevDesc = pTxDesc;
  65298. +
  65299. + if(ix == (txDescNum-1))
  65300. + {
  65301. + /* Closing Tx descriptors ring */
  65302. + pTxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pTxDescBase);
  65303. + }
  65304. + else
  65305. + {
  65306. + pTxDesc = (ETH_TX_DESC*)((MV_ULONG)pTxDesc + ETH_TX_DESC_ALIGNED_SIZE);
  65307. + pTxPrevDesc->nextDescPtr = (MV_U32)ethDescVirtToPhy(pQueueCtrl, (void*)pTxDesc);
  65308. + }
  65309. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxPrevDesc);
  65310. + }
  65311. +
  65312. + pQueueCtrl->pCurrentDescr = pTxDescBase;
  65313. + pQueueCtrl->pUsedDescr = pTxDescBase;
  65314. +
  65315. + pQueueCtrl->pFirstDescr = pTxDescBase;
  65316. + pQueueCtrl->pLastDescr = pTxDesc;
  65317. + /* Leave one TX descriptor out of use */
  65318. + pQueueCtrl->resource = txDescNum - 1;
  65319. +}
  65320. +
  65321. +void ethResetTxDescRing(void* pPortHndl, int queue)
  65322. +{
  65323. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  65324. + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->txQueue[queue];
  65325. + ETH_TX_DESC* pTxDesc = (ETH_TX_DESC*)pQueueCtrl->pFirstDescr;
  65326. +
  65327. + pQueueCtrl->resource = 0;
  65328. + if(pQueueCtrl->pFirstDescr != NULL)
  65329. + {
  65330. + while(MV_TRUE)
  65331. + {
  65332. + pTxDesc->byteCnt = 0x0000;
  65333. + pTxDesc->L4iChk = 0x0000;
  65334. + pTxDesc->cmdSts = ETH_BUFFER_OWNED_BY_HOST;
  65335. + pTxDesc->bufPtr = 0x0;
  65336. + pTxDesc->returnInfo = 0x0;
  65337. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxDesc);
  65338. + pQueueCtrl->resource++;
  65339. + if( (void*)pTxDesc == pQueueCtrl->pLastDescr)
  65340. + break;
  65341. + pTxDesc = TX_NEXT_DESC_PTR(pTxDesc, pQueueCtrl);
  65342. + }
  65343. + /* Leave one TX descriptor out of use */
  65344. + pQueueCtrl->resource--;
  65345. + pQueueCtrl->pCurrentDescr = pQueueCtrl->pFirstDescr;
  65346. + pQueueCtrl->pUsedDescr = pQueueCtrl->pFirstDescr;
  65347. +
  65348. + /* Update TX Command register */
  65349. + pPortCtrl->portTxQueueCmdReg |= MV_32BIT_LE_FAST(1 << queue);
  65350. + /* update HW */
  65351. + MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue),
  65352. + (MV_U32)ethDescVirtToPhy(pQueueCtrl, pQueueCtrl->pCurrentDescr) );
  65353. + }
  65354. + else
  65355. + {
  65356. + /* Update TX Command register */
  65357. + pPortCtrl->portTxQueueCmdReg &= MV_32BIT_LE_FAST(~(1 << queue));
  65358. + /* update HW */
  65359. + MV_REG_WRITE( ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue), 0 );
  65360. + }
  65361. +}
  65362. +
  65363. +/*******************************************************************************
  65364. +* ethAllocDescrMemory - Free memory allocated for RX and TX descriptors.
  65365. +*
  65366. +* DESCRIPTION:
  65367. +* This function allocates memory for RX and TX descriptors.
  65368. +* - If ETH_DESCR_IN_SRAM defined, allocate memory from SRAM.
  65369. +* - If ETH_DESCR_IN_SDRAM defined, allocate memory in SDRAM.
  65370. +*
  65371. +* INPUT:
  65372. +* int size - size of memory should be allocated.
  65373. +*
  65374. +* RETURN: None
  65375. +*
  65376. +*******************************************************************************/
  65377. +static MV_U8* ethAllocDescrMemory(ETH_PORT_CTRL* pPortCtrl, int descSize,
  65378. + MV_ULONG* pPhysAddr, MV_U32 *memHandle)
  65379. +{
  65380. + MV_U8* pVirt;
  65381. +
  65382. +#if defined(ETH_DESCR_IN_SRAM)
  65383. + if(ethDescInSram == MV_TRUE)
  65384. + pVirt = (char*)mvSramMalloc(descSize, pPhysAddr);
  65385. + else
  65386. +#endif /* ETH_DESCR_IN_SRAM */
  65387. + {
  65388. +#ifdef ETH_DESCR_UNCACHED
  65389. + pVirt = (MV_U8*)mvOsIoUncachedMalloc(pPortCtrl->osHandle, descSize,
  65390. + pPhysAddr,memHandle);
  65391. +#else
  65392. + pVirt = (MV_U8*)mvOsIoCachedMalloc(pPortCtrl->osHandle, descSize,
  65393. + pPhysAddr, memHandle);
  65394. +#endif /* ETH_DESCR_UNCACHED */
  65395. + }
  65396. + memset(pVirt, 0, descSize);
  65397. +
  65398. + return pVirt;
  65399. +}
  65400. +
  65401. +/*******************************************************************************
  65402. +* ethFreeDescrMemory - Free memory allocated for RX and TX descriptors.
  65403. +*
  65404. +* DESCRIPTION:
  65405. +* This function frees memory allocated for RX and TX descriptors.
  65406. +* - If ETH_DESCR_IN_SRAM defined, free memory using gtSramFree() function.
  65407. +* - If ETH_DESCR_IN_SDRAM defined, free memory using mvOsFree() function.
  65408. +*
  65409. +* INPUT:
  65410. +* void* pVirtAddr - virtual pointer to memory allocated for RX and TX
  65411. +* desriptors.
  65412. +*
  65413. +* RETURN: None
  65414. +*
  65415. +*******************************************************************************/
  65416. +void ethFreeDescrMemory(ETH_PORT_CTRL* pPortCtrl, MV_BUF_INFO* pDescBuf)
  65417. +{
  65418. + if( (pDescBuf == NULL) || (pDescBuf->bufVirtPtr == NULL) )
  65419. + return;
  65420. +
  65421. +#if defined(ETH_DESCR_IN_SRAM)
  65422. + if( ethDescInSram )
  65423. + {
  65424. + mvSramFree(pDescBuf->bufSize, pDescBuf->bufPhysAddr, pDescBuf->bufVirtPtr);
  65425. + return;
  65426. + }
  65427. +#endif /* ETH_DESCR_IN_SRAM */
  65428. +
  65429. +#ifdef ETH_DESCR_UNCACHED
  65430. + mvOsIoUncachedFree(pPortCtrl->osHandle, pDescBuf->bufSize, pDescBuf->bufPhysAddr,
  65431. + pDescBuf->bufVirtPtr,pDescBuf->memHandle);
  65432. +#else
  65433. + mvOsIoCachedFree(pPortCtrl->osHandle, pDescBuf->bufSize, pDescBuf->bufPhysAddr,
  65434. + pDescBuf->bufVirtPtr,pDescBuf->memHandle);
  65435. +#endif /* ETH_DESCR_UNCACHED */
  65436. +}
  65437. +
  65438. +/******************************************************************************/
  65439. +/* Other Functions */
  65440. +/******************************************************************************/
  65441. +
  65442. +void mvEthPortPowerUp(int port)
  65443. +{
  65444. + MV_U32 regVal;
  65445. +
  65446. + /* MAC Cause register should be cleared */
  65447. + MV_REG_WRITE(ETH_UNIT_INTR_CAUSE_REG(port), 0);
  65448. +
  65449. + if (mvBoardIsPortInSgmii(port))
  65450. + mvEthPortSgmiiConfig(port);
  65451. +
  65452. + /* Cancel Port Reset */
  65453. + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));
  65454. + regVal &= (~ETH_PORT_RESET_MASK);
  65455. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal);
  65456. + while( (MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port)) & ETH_PORT_RESET_MASK) != 0);
  65457. +}
  65458. +
  65459. +void mvEthPortPowerDown(int port)
  65460. +{
  65461. + MV_U32 regVal;
  65462. +
  65463. + /* Port must be DISABLED */
  65464. + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_REG(port));
  65465. + if( (regVal & ETH_PORT_ENABLE_MASK) != 0)
  65466. + {
  65467. + mvOsPrintf("ethPort #%d: PowerDown - port must be Disabled (PSC=0x%x)\n",
  65468. + port, regVal);
  65469. + return;
  65470. + }
  65471. +
  65472. + /* Port Reset (Read after write the register as a precaution) */
  65473. + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));
  65474. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal | ETH_PORT_RESET_MASK);
  65475. + while((MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port)) & ETH_PORT_RESET_MASK) == 0);
  65476. +}
  65477. +
  65478. +static void mvEthPortSgmiiConfig(int port)
  65479. +{
  65480. + MV_U32 regVal;
  65481. +
  65482. + regVal = MV_REG_READ(ETH_PORT_SERIAL_CTRL_1_REG(port));
  65483. +
  65484. + regVal |= (ETH_SGMII_MODE_MASK /*| ETH_INBAND_AUTO_NEG_ENABLE_MASK */);
  65485. + regVal &= (~ETH_INBAND_AUTO_NEG_BYPASS_MASK);
  65486. +
  65487. + MV_REG_WRITE(ETH_PORT_SERIAL_CTRL_1_REG(port), regVal);
  65488. +}
  65489. +
  65490. +
  65491. +
  65492. +
  65493. +
  65494. +
  65495. +
  65496. +
  65497. +
  65498. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c
  65499. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c 1970-01-01 01:00:00.000000000 +0100
  65500. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.c 2011-08-01 14:38:19.000000000 +0200
  65501. @@ -0,0 +1,748 @@
  65502. +/*******************************************************************************
  65503. +Copyright (C) Marvell International Ltd. and its affiliates
  65504. +
  65505. +This software file (the "File") is owned and distributed by Marvell
  65506. +International Ltd. and/or its affiliates ("Marvell") under the following
  65507. +alternative licensing terms. Once you have made an election to distribute the
  65508. +File under one of the following license alternatives, please (i) delete this
  65509. +introductory statement regarding license alternatives, (ii) delete the two
  65510. +license alternatives that you have not elected to use and (iii) preserve the
  65511. +Marvell copyright notice above.
  65512. +
  65513. +********************************************************************************
  65514. +Marvell Commercial License Option
  65515. +
  65516. +If you received this File from Marvell and you have entered into a commercial
  65517. +license agreement (a "Commercial License") with Marvell, the File is licensed
  65518. +to you under the terms of the applicable Commercial License.
  65519. +
  65520. +********************************************************************************
  65521. +Marvell GPL License Option
  65522. +
  65523. +If you received this File from Marvell, you may opt to use, redistribute and/or
  65524. +modify this File in accordance with the terms and conditions of the General
  65525. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  65526. +available along with the File in the license.txt file or by writing to the Free
  65527. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  65528. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  65529. +
  65530. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  65531. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  65532. +DISCLAIMED. The GPL License provides additional details about this warranty
  65533. +disclaimer.
  65534. +********************************************************************************
  65535. +Marvell BSD License Option
  65536. +
  65537. +If you received this File from Marvell, you may opt to use, redistribute and/or
  65538. +modify this File under the following licensing terms.
  65539. +Redistribution and use in source and binary forms, with or without modification,
  65540. +are permitted provided that the following conditions are met:
  65541. +
  65542. + * Redistributions of source code must retain the above copyright notice,
  65543. + this list of conditions and the following disclaimer.
  65544. +
  65545. + * Redistributions in binary form must reproduce the above copyright
  65546. + notice, this list of conditions and the following disclaimer in the
  65547. + documentation and/or other materials provided with the distribution.
  65548. +
  65549. + * Neither the name of Marvell nor the names of its contributors may be
  65550. + used to endorse or promote products derived from this software without
  65551. + specific prior written permission.
  65552. +
  65553. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  65554. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  65555. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  65556. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  65557. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  65558. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  65559. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  65560. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  65561. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  65562. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  65563. +
  65564. +*******************************************************************************/
  65565. +
  65566. +/*******************************************************************************
  65567. +* mvEthDebug.c - Source file for user friendly debug functions
  65568. +*
  65569. +* DESCRIPTION:
  65570. +*
  65571. +* DEPENDENCIES:
  65572. +* None.
  65573. +*
  65574. +*******************************************************************************/
  65575. +
  65576. +#include "mvOs.h"
  65577. +#include "mvCommon.h"
  65578. +#include "mvTypes.h"
  65579. +#include "mv802_3.h"
  65580. +#include "mvDebug.h"
  65581. +#include "ctrlEnv/mvCtrlEnvLib.h"
  65582. +#include "eth-phy/mvEthPhy.h"
  65583. +#include "eth/mvEth.h"
  65584. +#include "eth/gbe/mvEthDebug.h"
  65585. +
  65586. +/* #define mvOsPrintf printf */
  65587. +
  65588. +void mvEthPortShow(void* pHndl);
  65589. +void mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode);
  65590. +
  65591. +/******************************************************************************/
  65592. +/* Debug functions */
  65593. +/******************************************************************************/
  65594. +void ethRxCoal(int port, int usec)
  65595. +{
  65596. + void* pHndl;
  65597. +
  65598. + pHndl = mvEthPortHndlGet(port);
  65599. + if(pHndl != NULL)
  65600. + {
  65601. + mvEthRxCoalSet(pHndl, usec);
  65602. + }
  65603. +}
  65604. +
  65605. +void ethTxCoal(int port, int usec)
  65606. +{
  65607. + void* pHndl;
  65608. +
  65609. + pHndl = mvEthPortHndlGet(port);
  65610. + if(pHndl != NULL)
  65611. + {
  65612. + mvEthTxCoalSet(pHndl, usec);
  65613. + }
  65614. +}
  65615. +
  65616. +#if (MV_ETH_VERSION >= 4)
  65617. +void ethEjpModeSet(int port, int mode)
  65618. +{
  65619. + void* pHndl;
  65620. +
  65621. + pHndl = mvEthPortHndlGet(port);
  65622. + if(pHndl != NULL)
  65623. + {
  65624. + mvEthEjpModeSet(pHndl, mode);
  65625. + }
  65626. +}
  65627. +#endif /* (MV_ETH_VERSION >= 4) */
  65628. +
  65629. +void ethBpduRxQ(int port, int bpduQueue)
  65630. +{
  65631. + void* pHndl;
  65632. +
  65633. + pHndl = mvEthPortHndlGet(port);
  65634. + if(pHndl != NULL)
  65635. + {
  65636. + mvEthBpduRxQueue(pHndl, bpduQueue);
  65637. + }
  65638. +}
  65639. +
  65640. +void ethArpRxQ(int port, int arpQueue)
  65641. +{
  65642. + void* pHndl;
  65643. +
  65644. + pHndl = mvEthPortHndlGet(port);
  65645. + if(pHndl != NULL)
  65646. + {
  65647. + mvEthArpRxQueue(pHndl, arpQueue);
  65648. + }
  65649. +}
  65650. +
  65651. +void ethTcpRxQ(int port, int tcpQueue)
  65652. +{
  65653. + void* pHndl;
  65654. +
  65655. + pHndl = mvEthPortHndlGet(port);
  65656. + if(pHndl != NULL)
  65657. + {
  65658. + mvEthTcpRxQueue(pHndl, tcpQueue);
  65659. + }
  65660. +}
  65661. +
  65662. +void ethUdpRxQ(int port, int udpQueue)
  65663. +{
  65664. + void* pHndl;
  65665. +
  65666. + pHndl = mvEthPortHndlGet(port);
  65667. + if(pHndl != NULL)
  65668. + {
  65669. + mvEthUdpRxQueue(pHndl, udpQueue);
  65670. + }
  65671. +}
  65672. +
  65673. +void ethTxPolicyRegs(int port)
  65674. +{
  65675. + int queue;
  65676. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)mvEthPortHndlGet(port);
  65677. +
  65678. + if(pPortCtrl == NULL)
  65679. + {
  65680. + return;
  65681. + }
  65682. + mvOsPrintf("Port #%d TX Policy: EJP=%d, TXQs: ",
  65683. + port, pPortCtrl->portConfig.ejpMode);
  65684. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  65685. + {
  65686. + if(pPortCtrl->txQueueConfig[queue].descrNum > 0)
  65687. + mvOsPrintf("%d, ", queue);
  65688. + }
  65689. + mvOsPrintf("\n");
  65690. +
  65691. + mvOsPrintf("\n\t TX policy Port #%d configuration registers\n", port);
  65692. +
  65693. + mvOsPrintf("ETH_TX_QUEUE_COMMAND_REG : 0x%X = 0x%08x\n",
  65694. + ETH_TX_QUEUE_COMMAND_REG(port),
  65695. + MV_REG_READ( ETH_TX_QUEUE_COMMAND_REG(port) ) );
  65696. +
  65697. + mvOsPrintf("ETH_TX_FIXED_PRIO_CFG_REG : 0x%X = 0x%08x\n",
  65698. + ETH_TX_FIXED_PRIO_CFG_REG(port),
  65699. + MV_REG_READ( ETH_TX_FIXED_PRIO_CFG_REG(port) ) );
  65700. +
  65701. + mvOsPrintf("ETH_TX_TOKEN_RATE_CFG_REG : 0x%X = 0x%08x\n",
  65702. + ETH_TX_TOKEN_RATE_CFG_REG(port),
  65703. + MV_REG_READ( ETH_TX_TOKEN_RATE_CFG_REG(port) ) );
  65704. +
  65705. + mvOsPrintf("ETH_MAX_TRANSMIT_UNIT_REG : 0x%X = 0x%08x\n",
  65706. + ETH_MAX_TRANSMIT_UNIT_REG(port),
  65707. + MV_REG_READ( ETH_MAX_TRANSMIT_UNIT_REG(port) ) );
  65708. +
  65709. + mvOsPrintf("ETH_TX_TOKEN_BUCKET_SIZE_REG : 0x%X = 0x%08x\n",
  65710. + ETH_TX_TOKEN_BUCKET_SIZE_REG(port),
  65711. + MV_REG_READ( ETH_TX_TOKEN_BUCKET_SIZE_REG(port) ) );
  65712. +
  65713. + mvOsPrintf("ETH_TX_TOKEN_BUCKET_COUNT_REG : 0x%X = 0x%08x\n",
  65714. + ETH_TX_TOKEN_BUCKET_COUNT_REG(port),
  65715. + MV_REG_READ( ETH_TX_TOKEN_BUCKET_COUNT_REG(port) ) );
  65716. +
  65717. + for(queue=0; queue<MV_ETH_MAX_TXQ; queue++)
  65718. + {
  65719. + mvOsPrintf("\n\t TX policy Port #%d, Queue #%d configuration registers\n", port, queue);
  65720. +
  65721. + mvOsPrintf("ETH_TXQ_TOKEN_COUNT_REG : 0x%X = 0x%08x\n",
  65722. + ETH_TXQ_TOKEN_COUNT_REG(port, queue),
  65723. + MV_REG_READ( ETH_TXQ_TOKEN_COUNT_REG(port, queue) ) );
  65724. +
  65725. + mvOsPrintf("ETH_TXQ_TOKEN_CFG_REG : 0x%X = 0x%08x\n",
  65726. + ETH_TXQ_TOKEN_CFG_REG(port, queue),
  65727. + MV_REG_READ( ETH_TXQ_TOKEN_CFG_REG(port, queue) ) );
  65728. +
  65729. + mvOsPrintf("ETH_TXQ_ARBITER_CFG_REG : 0x%X = 0x%08x\n",
  65730. + ETH_TXQ_ARBITER_CFG_REG(port, queue),
  65731. + MV_REG_READ( ETH_TXQ_ARBITER_CFG_REG(port, queue) ) );
  65732. + }
  65733. + mvOsPrintf("\n");
  65734. +}
  65735. +
  65736. +/* Print important registers of Ethernet port */
  65737. +void ethPortRegs(int port)
  65738. +{
  65739. + mvOsPrintf("\n\t ethGiga #%d port Registers:\n", port);
  65740. +
  65741. + mvOsPrintf("ETH_PORT_STATUS_REG : 0x%X = 0x%08x\n",
  65742. + ETH_PORT_STATUS_REG(port),
  65743. + MV_REG_READ( ETH_PORT_STATUS_REG(port) ) );
  65744. +
  65745. + mvOsPrintf("ETH_PORT_SERIAL_CTRL_REG : 0x%X = 0x%08x\n",
  65746. + ETH_PORT_SERIAL_CTRL_REG(port),
  65747. + MV_REG_READ( ETH_PORT_SERIAL_CTRL_REG(port) ) );
  65748. +
  65749. + mvOsPrintf("ETH_PORT_CONFIG_REG : 0x%X = 0x%08x\n",
  65750. + ETH_PORT_CONFIG_REG(port),
  65751. + MV_REG_READ( ETH_PORT_CONFIG_REG(port) ) );
  65752. +
  65753. + mvOsPrintf("ETH_PORT_CONFIG_EXTEND_REG : 0x%X = 0x%08x\n",
  65754. + ETH_PORT_CONFIG_EXTEND_REG(port),
  65755. + MV_REG_READ( ETH_PORT_CONFIG_EXTEND_REG(port) ) );
  65756. +
  65757. + mvOsPrintf("ETH_SDMA_CONFIG_REG : 0x%X = 0x%08x\n",
  65758. + ETH_SDMA_CONFIG_REG(port),
  65759. + MV_REG_READ( ETH_SDMA_CONFIG_REG(port) ) );
  65760. +
  65761. + mvOsPrintf("ETH_TX_FIFO_URGENT_THRESH_REG : 0x%X = 0x%08x\n",
  65762. + ETH_TX_FIFO_URGENT_THRESH_REG(port),
  65763. + MV_REG_READ( ETH_TX_FIFO_URGENT_THRESH_REG(port) ) );
  65764. +
  65765. + mvOsPrintf("ETH_RX_QUEUE_COMMAND_REG : 0x%X = 0x%08x\n",
  65766. + ETH_RX_QUEUE_COMMAND_REG(port),
  65767. + MV_REG_READ( ETH_RX_QUEUE_COMMAND_REG(port) ) );
  65768. +
  65769. + mvOsPrintf("ETH_TX_QUEUE_COMMAND_REG : 0x%X = 0x%08x\n",
  65770. + ETH_TX_QUEUE_COMMAND_REG(port),
  65771. + MV_REG_READ( ETH_TX_QUEUE_COMMAND_REG(port) ) );
  65772. +
  65773. + mvOsPrintf("ETH_INTR_CAUSE_REG : 0x%X = 0x%08x\n",
  65774. + ETH_INTR_CAUSE_REG(port),
  65775. + MV_REG_READ( ETH_INTR_CAUSE_REG(port) ) );
  65776. +
  65777. + mvOsPrintf("ETH_INTR_EXTEND_CAUSE_REG : 0x%X = 0x%08x\n",
  65778. + ETH_INTR_CAUSE_EXT_REG(port),
  65779. + MV_REG_READ( ETH_INTR_CAUSE_EXT_REG(port) ) );
  65780. +
  65781. + mvOsPrintf("ETH_INTR_MASK_REG : 0x%X = 0x%08x\n",
  65782. + ETH_INTR_MASK_REG(port),
  65783. + MV_REG_READ( ETH_INTR_MASK_REG(port) ) );
  65784. +
  65785. + mvOsPrintf("ETH_INTR_EXTEND_MASK_REG : 0x%X = 0x%08x\n",
  65786. + ETH_INTR_MASK_EXT_REG(port),
  65787. + MV_REG_READ( ETH_INTR_MASK_EXT_REG(port) ) );
  65788. +
  65789. + mvOsPrintf("ETH_RX_DESCR_STAT_CMD_REG : 0x%X = 0x%08x\n",
  65790. + ETH_RX_DESCR_STAT_CMD_REG(port, 0),
  65791. + MV_REG_READ( ETH_RX_DESCR_STAT_CMD_REG(port, 0) ) );
  65792. +
  65793. + mvOsPrintf("ETH_RX_BYTE_COUNT_REG : 0x%X = 0x%08x\n",
  65794. + ETH_RX_BYTE_COUNT_REG(port, 0),
  65795. + MV_REG_READ( ETH_RX_BYTE_COUNT_REG(port, 0) ) );
  65796. +
  65797. + mvOsPrintf("ETH_RX_BUF_PTR_REG : 0x%X = 0x%08x\n",
  65798. + ETH_RX_BUF_PTR_REG(port, 0),
  65799. + MV_REG_READ( ETH_RX_BUF_PTR_REG(port, 0) ) );
  65800. +
  65801. + mvOsPrintf("ETH_RX_CUR_DESC_PTR_REG : 0x%X = 0x%08x\n",
  65802. + ETH_RX_CUR_DESC_PTR_REG(port, 0),
  65803. + MV_REG_READ( ETH_RX_CUR_DESC_PTR_REG(port, 0) ) );
  65804. +}
  65805. +
  65806. +
  65807. +/* Print Giga Ethernet UNIT registers */
  65808. +void ethRegs(int port)
  65809. +{
  65810. + mvOsPrintf("ETH_PHY_ADDR_REG : 0x%X = 0x%08x\n",
  65811. + ETH_PHY_ADDR_REG(port),
  65812. + MV_REG_READ(ETH_PHY_ADDR_REG(port)) );
  65813. +
  65814. + mvOsPrintf("ETH_UNIT_INTR_CAUSE_REG : 0x%X = 0x%08x\n",
  65815. + ETH_UNIT_INTR_CAUSE_REG(port),
  65816. + MV_REG_READ( ETH_UNIT_INTR_CAUSE_REG(port)) );
  65817. +
  65818. + mvOsPrintf("ETH_UNIT_INTR_MASK_REG : 0x%X = 0x%08x\n",
  65819. + ETH_UNIT_INTR_MASK_REG(port),
  65820. + MV_REG_READ( ETH_UNIT_INTR_MASK_REG(port)) );
  65821. +
  65822. + mvOsPrintf("ETH_UNIT_ERROR_ADDR_REG : 0x%X = 0x%08x\n",
  65823. + ETH_UNIT_ERROR_ADDR_REG(port),
  65824. + MV_REG_READ(ETH_UNIT_ERROR_ADDR_REG(port)) );
  65825. +
  65826. + mvOsPrintf("ETH_UNIT_INT_ADDR_ERROR_REG : 0x%X = 0x%08x\n",
  65827. + ETH_UNIT_INT_ADDR_ERROR_REG(port),
  65828. + MV_REG_READ(ETH_UNIT_INT_ADDR_ERROR_REG(port)) );
  65829. +
  65830. +}
  65831. +
  65832. +/******************************************************************************/
  65833. +/* MIB Counters functions */
  65834. +/******************************************************************************/
  65835. +
  65836. +/*******************************************************************************
  65837. +* ethClearMibCounters - Clear all MIB counters
  65838. +*
  65839. +* DESCRIPTION:
  65840. +* This function clears all MIB counters of a specific ethernet port.
  65841. +* A read from the MIB counter will reset the counter.
  65842. +*
  65843. +* INPUT:
  65844. +* int port - Ethernet Port number.
  65845. +*
  65846. +* RETURN: None
  65847. +*
  65848. +*******************************************************************************/
  65849. +void ethClearCounters(int port)
  65850. +{
  65851. + void* pHndl;
  65852. +
  65853. + pHndl = mvEthPortHndlGet(port);
  65854. + if(pHndl != NULL)
  65855. + mvEthMibCountersClear(pHndl);
  65856. +
  65857. + return;
  65858. +}
  65859. +
  65860. +
  65861. +/* Print counters of the Ethernet port */
  65862. +void ethPortCounters(int port)
  65863. +{
  65864. + MV_U32 regValue, regValHigh;
  65865. + void* pHndl;
  65866. +
  65867. + pHndl = mvEthPortHndlGet(port);
  65868. + if(pHndl == NULL)
  65869. + return;
  65870. +
  65871. + mvOsPrintf("\n\t Port #%d MIB Counters\n\n", port);
  65872. +
  65873. + mvOsPrintf("GoodFramesReceived = %u\n",
  65874. + mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FRAMES_RECEIVED, NULL));
  65875. + mvOsPrintf("BadFramesReceived = %u\n",
  65876. + mvEthMibCounterRead(pHndl, ETH_MIB_BAD_FRAMES_RECEIVED, NULL));
  65877. + mvOsPrintf("BroadcastFramesReceived = %u\n",
  65878. + mvEthMibCounterRead(pHndl, ETH_MIB_BROADCAST_FRAMES_RECEIVED, NULL));
  65879. + mvOsPrintf("MulticastFramesReceived = %u\n",
  65880. + mvEthMibCounterRead(pHndl, ETH_MIB_MULTICAST_FRAMES_RECEIVED, NULL));
  65881. +
  65882. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_OCTETS_RECEIVED_LOW,
  65883. + &regValHigh);
  65884. + mvOsPrintf("GoodOctetsReceived = 0x%08x%08x\n",
  65885. + regValHigh, regValue);
  65886. +
  65887. + mvOsPrintf("\n");
  65888. + mvOsPrintf("GoodFramesSent = %u\n",
  65889. + mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FRAMES_SENT, NULL));
  65890. + mvOsPrintf("BroadcastFramesSent = %u\n",
  65891. + mvEthMibCounterRead(pHndl, ETH_MIB_BROADCAST_FRAMES_SENT, NULL));
  65892. + mvOsPrintf("MulticastFramesSent = %u\n",
  65893. + mvEthMibCounterRead(pHndl, ETH_MIB_MULTICAST_FRAMES_SENT, NULL));
  65894. +
  65895. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_OCTETS_SENT_LOW,
  65896. + &regValHigh);
  65897. + mvOsPrintf("GoodOctetsSent = 0x%08x%08x\n", regValHigh, regValue);
  65898. +
  65899. +
  65900. + mvOsPrintf("\n\t FC Control Counters\n");
  65901. +
  65902. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_UNREC_MAC_CONTROL_RECEIVED, NULL);
  65903. + mvOsPrintf("UnrecogMacControlReceived = %u\n", regValue);
  65904. +
  65905. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_GOOD_FC_RECEIVED, NULL);
  65906. + mvOsPrintf("GoodFCFramesReceived = %u\n", regValue);
  65907. +
  65908. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_FC_RECEIVED, NULL);
  65909. + mvOsPrintf("BadFCFramesReceived = %u\n", regValue);
  65910. +
  65911. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_FC_SENT, NULL);
  65912. + mvOsPrintf("FCFramesSent = %u\n", regValue);
  65913. +
  65914. +
  65915. + mvOsPrintf("\n\t RX Errors\n");
  65916. +
  65917. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_OCTETS_RECEIVED, NULL);
  65918. + mvOsPrintf("BadOctetsReceived = %u\n", regValue);
  65919. +
  65920. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_UNDERSIZE_RECEIVED, NULL);
  65921. + mvOsPrintf("UndersizeFramesReceived = %u\n", regValue);
  65922. +
  65923. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_FRAGMENTS_RECEIVED, NULL);
  65924. + mvOsPrintf("FragmentsReceived = %u\n", regValue);
  65925. +
  65926. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_OVERSIZE_RECEIVED, NULL);
  65927. + mvOsPrintf("OversizeFramesReceived = %u\n", regValue);
  65928. +
  65929. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_JABBER_RECEIVED, NULL);
  65930. + mvOsPrintf("JabbersReceived = %u\n", regValue);
  65931. +
  65932. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_MAC_RECEIVE_ERROR, NULL);
  65933. + mvOsPrintf("MacReceiveErrors = %u\n", regValue);
  65934. +
  65935. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_BAD_CRC_EVENT, NULL);
  65936. + mvOsPrintf("BadCrcReceived = %u\n", regValue);
  65937. +
  65938. + mvOsPrintf("\n\t TX Errors\n");
  65939. +
  65940. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR, NULL);
  65941. + mvOsPrintf("TxMacErrors = %u\n", regValue);
  65942. +
  65943. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_EXCESSIVE_COLLISION, NULL);
  65944. + mvOsPrintf("TxExcessiveCollisions = %u\n", regValue);
  65945. +
  65946. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_COLLISION, NULL);
  65947. + mvOsPrintf("TxCollisions = %u\n", regValue);
  65948. +
  65949. + regValue = mvEthMibCounterRead(pHndl, ETH_MIB_LATE_COLLISION, NULL);
  65950. + mvOsPrintf("TxLateCollisions = %u\n", regValue);
  65951. +
  65952. +
  65953. + mvOsPrintf("\n");
  65954. + regValue = MV_REG_READ( ETH_RX_DISCARD_PKTS_CNTR_REG(port));
  65955. + mvOsPrintf("Rx Discard packets counter = %u\n", regValue);
  65956. +
  65957. + regValue = MV_REG_READ(ETH_RX_OVERRUN_PKTS_CNTR_REG(port));
  65958. + mvOsPrintf("Rx Overrun packets counter = %u\n", regValue);
  65959. +}
  65960. +
  65961. +/* Print RMON counters of the Ethernet port */
  65962. +void ethPortRmonCounters(int port)
  65963. +{
  65964. + void* pHndl;
  65965. +
  65966. + pHndl = mvEthPortHndlGet(port);
  65967. + if(pHndl == NULL)
  65968. + return;
  65969. +
  65970. + mvOsPrintf("\n\t Port #%d RMON MIB Counters\n\n", port);
  65971. +
  65972. + mvOsPrintf("64 ByteFramesReceived = %u\n",
  65973. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_64_OCTETS, NULL));
  65974. + mvOsPrintf("65...127 ByteFramesReceived = %u\n",
  65975. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_65_TO_127_OCTETS, NULL));
  65976. + mvOsPrintf("128...255 ByteFramesReceived = %u\n",
  65977. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_128_TO_255_OCTETS, NULL));
  65978. + mvOsPrintf("256...511 ByteFramesReceived = %u\n",
  65979. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_256_TO_511_OCTETS, NULL));
  65980. + mvOsPrintf("512...1023 ByteFramesReceived = %u\n",
  65981. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_512_TO_1023_OCTETS, NULL));
  65982. + mvOsPrintf("1024...Max ByteFramesReceived = %u\n",
  65983. + mvEthMibCounterRead(pHndl, ETH_MIB_FRAMES_1024_TO_MAX_OCTETS, NULL));
  65984. +}
  65985. +
  65986. +/* Print port information */
  65987. +void ethPortStatus(int port)
  65988. +{
  65989. + void* pHndl;
  65990. +
  65991. + pHndl = mvEthPortHndlGet(port);
  65992. + if(pHndl != NULL)
  65993. + {
  65994. + mvEthPortShow(pHndl);
  65995. + }
  65996. +}
  65997. +
  65998. +/* Print port queues information */
  65999. +void ethPortQueues(int port, int rxQueue, int txQueue, int mode)
  66000. +{
  66001. + void* pHndl;
  66002. +
  66003. + pHndl = mvEthPortHndlGet(port);
  66004. + if(pHndl != NULL)
  66005. + {
  66006. + mvEthQueuesShow(pHndl, rxQueue, txQueue, mode);
  66007. + }
  66008. +}
  66009. +
  66010. +void ethUcastSet(int port, char* macStr, int queue)
  66011. +{
  66012. + void* pHndl;
  66013. + MV_U8 macAddr[MV_MAC_ADDR_SIZE];
  66014. +
  66015. + pHndl = mvEthPortHndlGet(port);
  66016. + if(pHndl != NULL)
  66017. + {
  66018. + mvMacStrToHex(macStr, macAddr);
  66019. + mvEthMacAddrSet(pHndl, macAddr, queue);
  66020. + }
  66021. +}
  66022. +
  66023. +
  66024. +void ethPortUcastShow(int port)
  66025. +{
  66026. + MV_U32 unicastReg, macL, macH;
  66027. + int i, j;
  66028. +
  66029. + macL = MV_REG_READ(ETH_MAC_ADDR_LOW_REG(port));
  66030. + macH = MV_REG_READ(ETH_MAC_ADDR_HIGH_REG(port));
  66031. +
  66032. + mvOsPrintf("\n\t Port #%d Unicast MAC table: %02x:%02x:%02x:%02x:%02x:%02x\n\n",
  66033. + port, ((macH >> 24) & 0xff), ((macH >> 16) & 0xff),
  66034. + ((macH >> 8) & 0xff), (macH & 0xff),
  66035. + ((macL >> 8) & 0xff), (macL & 0xff) );
  66036. +
  66037. + for (i=0; i<4; i++)
  66038. + {
  66039. + unicastReg = MV_REG_READ( (ETH_DA_FILTER_UCAST_BASE(port) + i*4));
  66040. + for(j=0; j<4; j++)
  66041. + {
  66042. + MV_U8 macEntry = (unicastReg >> (8*j)) & 0xFF;
  66043. +
  66044. + mvOsPrintf("%X: %8s, Q = %d\n", i*4+j,
  66045. + (macEntry & BIT0) ? "Accept" : "Reject", (macEntry >> 1) & 0x7);
  66046. + }
  66047. + }
  66048. +}
  66049. +
  66050. +void ethMcastAdd(int port, char* macStr, int queue)
  66051. +{
  66052. + void* pHndl;
  66053. + MV_U8 macAddr[MV_MAC_ADDR_SIZE];
  66054. +
  66055. + pHndl = mvEthPortHndlGet(port);
  66056. + if(pHndl != NULL)
  66057. + {
  66058. + mvMacStrToHex(macStr, macAddr);
  66059. + mvEthMcastAddrSet(pHndl, macAddr, queue);
  66060. + }
  66061. +}
  66062. +
  66063. +void ethPortMcast(int port)
  66064. +{
  66065. + int tblIdx, regIdx;
  66066. + MV_U32 regVal;
  66067. +
  66068. + mvOsPrintf("\n\t Port #%d Special (IP) Multicast table: 01:00:5E:00:00:XX\n\n",
  66069. + port);
  66070. +
  66071. + for(tblIdx=0; tblIdx<(256/4); tblIdx++)
  66072. + {
  66073. + regVal = MV_REG_READ((ETH_DA_FILTER_SPEC_MCAST_BASE(port) + tblIdx*4));
  66074. + for(regIdx=0; regIdx<4; regIdx++)
  66075. + {
  66076. + if((regVal & (0x01 << (regIdx*8))) != 0)
  66077. + {
  66078. + mvOsPrintf("0x%02X: Accepted, rxQ = %d\n",
  66079. + tblIdx*4+regIdx, ((regVal >> (regIdx*8+1)) & 0x07));
  66080. + }
  66081. + }
  66082. + }
  66083. + mvOsPrintf("\n\t Port #%d Other Multicast table\n\n", port);
  66084. + for(tblIdx=0; tblIdx<(256/4); tblIdx++)
  66085. + {
  66086. + regVal = MV_REG_READ((ETH_DA_FILTER_OTH_MCAST_BASE(port) + tblIdx*4));
  66087. + for(regIdx=0; regIdx<4; regIdx++)
  66088. + {
  66089. + if((regVal & (0x01 << (regIdx*8))) != 0)
  66090. + {
  66091. + mvOsPrintf("Crc8=0x%02X: Accepted, rxQ = %d\n",
  66092. + tblIdx*4+regIdx, ((regVal >> (regIdx*8+1)) & 0x07));
  66093. + }
  66094. + }
  66095. + }
  66096. +}
  66097. +
  66098. +
  66099. +/* Print status of Ethernet port */
  66100. +void mvEthPortShow(void* pHndl)
  66101. +{
  66102. + MV_U32 regValue, rxCoal, txCoal;
  66103. + int speed, queue, port;
  66104. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pHndl;
  66105. +
  66106. + port = pPortCtrl->portNo;
  66107. +
  66108. + regValue = MV_REG_READ( ETH_PORT_STATUS_REG(port) );
  66109. +
  66110. + mvOsPrintf("\n\t ethGiga #%d port Status: 0x%04x = 0x%08x\n\n",
  66111. + port, ETH_PORT_STATUS_REG(port), regValue);
  66112. +
  66113. + mvOsPrintf("descInSram=%d, descSwCoher=%d\n",
  66114. + ethDescInSram, ethDescSwCoher);
  66115. +
  66116. + if(regValue & ETH_GMII_SPEED_1000_MASK)
  66117. + speed = 1000;
  66118. + else if(regValue & ETH_MII_SPEED_100_MASK)
  66119. + speed = 100;
  66120. + else
  66121. + speed = 10;
  66122. +
  66123. + mvEthCoalGet(pPortCtrl, &rxCoal, &txCoal);
  66124. +
  66125. + /* Link, Speed, Duplex, FlowControl */
  66126. + mvOsPrintf("Link=%s, Speed=%d, Duplex=%s, RxFlowControl=%s",
  66127. + (regValue & ETH_LINK_UP_MASK) ? "UP" : "DOWN",
  66128. + speed,
  66129. + (regValue & ETH_FULL_DUPLEX_MASK) ? "FULL" : "HALF",
  66130. + (regValue & ETH_ENABLE_RCV_FLOW_CTRL_MASK) ? "ENABLE" : "DISABLE");
  66131. +
  66132. + mvOsPrintf("\n");
  66133. +
  66134. + mvOsPrintf("RxCoal = %d usec, TxCoal = %d usec\n",
  66135. + rxCoal, txCoal);
  66136. +
  66137. + mvOsPrintf("rxDefQ=%d, arpQ=%d, bpduQ=%d, tcpQ=%d, udpQ=%d\n\n",
  66138. + pPortCtrl->portConfig.rxDefQ, pPortCtrl->portConfig.rxArpQ,
  66139. + pPortCtrl->portConfig.rxBpduQ,
  66140. + pPortCtrl->portConfig.rxTcpQ, pPortCtrl->portConfig.rxUdpQ);
  66141. +
  66142. + /* Print all RX and TX queues */
  66143. + for(queue=0; queue<MV_ETH_RX_Q_NUM; queue++)
  66144. + {
  66145. + mvOsPrintf("RX Queue #%d: base=0x%lx, free=%d\n",
  66146. + queue, (MV_ULONG)pPortCtrl->rxQueue[queue].pFirstDescr,
  66147. + mvEthRxResourceGet(pPortCtrl, queue) );
  66148. + }
  66149. + mvOsPrintf("\n");
  66150. + for(queue=0; queue<MV_ETH_TX_Q_NUM; queue++)
  66151. + {
  66152. + mvOsPrintf("TX Queue #%d: base=0x%lx, free=%d\n",
  66153. + queue, (MV_ULONG)pPortCtrl->txQueue[queue].pFirstDescr,
  66154. + mvEthTxResourceGet(pPortCtrl, queue) );
  66155. + }
  66156. +}
  66157. +
  66158. +/* Print RX and TX queue of the Ethernet port */
  66159. +void mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode)
  66160. +{
  66161. + ETH_PORT_CTRL *pPortCtrl = (ETH_PORT_CTRL*)pHndl;
  66162. + ETH_QUEUE_CTRL *pQueueCtrl;
  66163. + MV_U32 regValue;
  66164. + ETH_RX_DESC *pRxDescr;
  66165. + ETH_TX_DESC *pTxDescr;
  66166. + int i, port = pPortCtrl->portNo;
  66167. +
  66168. + if( (rxQueue >=0) && (rxQueue < MV_ETH_RX_Q_NUM) )
  66169. + {
  66170. + pQueueCtrl = &(pPortCtrl->rxQueue[rxQueue]);
  66171. + mvOsPrintf("Port #%d, RX Queue #%d\n\n", port, rxQueue);
  66172. +
  66173. + mvOsPrintf("CURR_RX_DESC_PTR : 0x%X = 0x%08x\n",
  66174. + ETH_RX_CUR_DESC_PTR_REG(port, rxQueue),
  66175. + MV_REG_READ( ETH_RX_CUR_DESC_PTR_REG(port, rxQueue)));
  66176. +
  66177. +
  66178. + if(pQueueCtrl->pFirstDescr != NULL)
  66179. + {
  66180. + mvOsPrintf("pFirstDescr=0x%lx, pLastDescr=0x%lx, numOfResources=%d\n",
  66181. + (MV_ULONG)pQueueCtrl->pFirstDescr, (MV_ULONG)pQueueCtrl->pLastDescr,
  66182. + pQueueCtrl->resource);
  66183. + mvOsPrintf("pCurrDescr: 0x%lx, pUsedDescr: 0x%lx\n",
  66184. + (MV_ULONG)pQueueCtrl->pCurrentDescr,
  66185. + (MV_ULONG)pQueueCtrl->pUsedDescr);
  66186. +
  66187. + if(mode == 1)
  66188. + {
  66189. + pRxDescr = (ETH_RX_DESC*)pQueueCtrl->pFirstDescr;
  66190. + i = 0;
  66191. + do
  66192. + {
  66193. + mvOsPrintf("%3d. desc=%08x (%08x), cmd=%08x, data=%4d, buf=%4d, buf=%08x, pkt=%lx, os=%lx\n",
  66194. + i, (MV_U32)pRxDescr, (MV_U32)ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pRxDescr),
  66195. + pRxDescr->cmdSts, pRxDescr->byteCnt, (MV_U32)pRxDescr->bufSize,
  66196. + (unsigned int)pRxDescr->bufPtr, (MV_ULONG)pRxDescr->returnInfo,
  66197. + ((MV_PKT_INFO*)pRxDescr->returnInfo)->osInfo);
  66198. +
  66199. + ETH_DESCR_INV(pPortCtrl, pRxDescr);
  66200. + pRxDescr = RX_NEXT_DESC_PTR(pRxDescr, pQueueCtrl);
  66201. + i++;
  66202. + } while (pRxDescr != pQueueCtrl->pFirstDescr);
  66203. + }
  66204. + }
  66205. + else
  66206. + mvOsPrintf("RX Queue #%d is NOT CREATED\n", rxQueue);
  66207. + }
  66208. +
  66209. + if( (txQueue >=0) && (txQueue < MV_ETH_TX_Q_NUM) )
  66210. + {
  66211. + pQueueCtrl = &(pPortCtrl->txQueue[txQueue]);
  66212. + mvOsPrintf("Port #%d, TX Queue #%d\n\n", port, txQueue);
  66213. +
  66214. + regValue = MV_REG_READ( ETH_TX_CUR_DESC_PTR_REG(port, txQueue));
  66215. + mvOsPrintf("CURR_TX_DESC_PTR : 0x%X = 0x%08x\n",
  66216. + ETH_TX_CUR_DESC_PTR_REG(port, txQueue), regValue);
  66217. +
  66218. + if(pQueueCtrl->pFirstDescr != NULL)
  66219. + {
  66220. + mvOsPrintf("pFirstDescr=0x%lx, pLastDescr=0x%lx, numOfResources=%d\n",
  66221. + (MV_ULONG)pQueueCtrl->pFirstDescr,
  66222. + (MV_ULONG)pQueueCtrl->pLastDescr,
  66223. + pQueueCtrl->resource);
  66224. + mvOsPrintf("pCurrDescr: 0x%lx, pUsedDescr: 0x%lx\n",
  66225. + (MV_ULONG)pQueueCtrl->pCurrentDescr,
  66226. + (MV_ULONG)pQueueCtrl->pUsedDescr);
  66227. +
  66228. + if(mode == 1)
  66229. + {
  66230. + pTxDescr = (ETH_TX_DESC*)pQueueCtrl->pFirstDescr;
  66231. + i = 0;
  66232. + do
  66233. + {
  66234. + mvOsPrintf("%3d. desc=%08x (%08x), cmd=%08x, data=%4d, buf=%08x, pkt=%lx, os=%lx\n",
  66235. + i, (MV_U32)pTxDescr, (MV_U32)ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxDescr),
  66236. + pTxDescr->cmdSts, pTxDescr->byteCnt,
  66237. + (MV_U32)pTxDescr->bufPtr, (MV_ULONG)pTxDescr->returnInfo,
  66238. + pTxDescr->returnInfo ? (((MV_PKT_INFO*)pTxDescr->returnInfo)->osInfo) : 0x0);
  66239. +
  66240. + ETH_DESCR_INV(pPortCtrl, pTxDescr);
  66241. + pTxDescr = TX_NEXT_DESC_PTR(pTxDescr, pQueueCtrl);
  66242. + i++;
  66243. + } while (pTxDescr != pQueueCtrl->pFirstDescr);
  66244. + }
  66245. + }
  66246. + else
  66247. + mvOsPrintf("TX Queue #%d is NOT CREATED\n", txQueue);
  66248. + }
  66249. +}
  66250. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h
  66251. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h 1970-01-01 01:00:00.000000000 +0100
  66252. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthDebug.h 2011-08-01 14:38:19.000000000 +0200
  66253. @@ -0,0 +1,146 @@
  66254. +/*******************************************************************************
  66255. +Copyright (C) Marvell International Ltd. and its affiliates
  66256. +
  66257. +This software file (the "File") is owned and distributed by Marvell
  66258. +International Ltd. and/or its affiliates ("Marvell") under the following
  66259. +alternative licensing terms. Once you have made an election to distribute the
  66260. +File under one of the following license alternatives, please (i) delete this
  66261. +introductory statement regarding license alternatives, (ii) delete the two
  66262. +license alternatives that you have not elected to use and (iii) preserve the
  66263. +Marvell copyright notice above.
  66264. +
  66265. +********************************************************************************
  66266. +Marvell Commercial License Option
  66267. +
  66268. +If you received this File from Marvell and you have entered into a commercial
  66269. +license agreement (a "Commercial License") with Marvell, the File is licensed
  66270. +to you under the terms of the applicable Commercial License.
  66271. +
  66272. +********************************************************************************
  66273. +Marvell GPL License Option
  66274. +
  66275. +If you received this File from Marvell, you may opt to use, redistribute and/or
  66276. +modify this File in accordance with the terms and conditions of the General
  66277. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  66278. +available along with the File in the license.txt file or by writing to the Free
  66279. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  66280. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  66281. +
  66282. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  66283. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  66284. +DISCLAIMED. The GPL License provides additional details about this warranty
  66285. +disclaimer.
  66286. +********************************************************************************
  66287. +Marvell BSD License Option
  66288. +
  66289. +If you received this File from Marvell, you may opt to use, redistribute and/or
  66290. +modify this File under the following licensing terms.
  66291. +Redistribution and use in source and binary forms, with or without modification,
  66292. +are permitted provided that the following conditions are met:
  66293. +
  66294. + * Redistributions of source code must retain the above copyright notice,
  66295. + this list of conditions and the following disclaimer.
  66296. +
  66297. + * Redistributions in binary form must reproduce the above copyright
  66298. + notice, this list of conditions and the following disclaimer in the
  66299. + documentation and/or other materials provided with the distribution.
  66300. +
  66301. + * Neither the name of Marvell nor the names of its contributors may be
  66302. + used to endorse or promote products derived from this software without
  66303. + specific prior written permission.
  66304. +
  66305. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  66306. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  66307. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  66308. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  66309. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  66310. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  66311. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  66312. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  66313. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  66314. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  66315. +
  66316. +*******************************************************************************/
  66317. +#ifndef __MV_ETH_DEBUG_H__
  66318. +#define __MV_ETH_DEBUG_H__
  66319. +
  66320. +#if 0
  66321. +/*
  66322. + ** Externs
  66323. + */
  66324. +void ethBpduRxQ(int port, int bpduQueue);
  66325. +void ethArpRxQ(int port, int bpduQueue);
  66326. +void ethTcpRxQ(int port, int bpduQueue);
  66327. +void ethUdpRxQ(int port, int bpduQueue);
  66328. +void ethMcastAdd(int port, char* macStr, int queue);
  66329. +
  66330. +#ifdef INCLUDE_MULTI_QUEUE
  66331. +void ethRxPolicy( int port);
  66332. +void ethTxPolicy( int port);
  66333. +void ethTxPolDA(int port, char* macStr, int txQ, char* headerHexStr);
  66334. +void ethRxPolMode(int port, MV_ETH_PRIO_MODE prioMode);
  66335. +void ethRxPolQ(int port, int rxQueue, int rxQuota);
  66336. +#endif /* INCLUDE_MULTI_QUEUE */
  66337. +
  66338. +void print_egiga_stat(void *sc, unsigned int port);
  66339. +void ethPortStatus (int port);
  66340. +void ethPortQueues( int port, int rxQueue, int txQueue, int mode);
  66341. +void ethPortMcast(int port);
  66342. +void ethPortRegs(int port);
  66343. +void ethPortCounters(int port);
  66344. +void ethPortRmonCounters(int port);
  66345. +void ethRxCoal(int port, int usec);
  66346. +void ethTxCoal(int port, int usec);
  66347. +
  66348. +void ethRegs(int port);
  66349. +void ethClearCounters(int port);
  66350. +void ethUcastSet(int port, char* macStr, int queue);
  66351. +void ethPortUcastShow(int port);
  66352. +
  66353. +#ifdef CONFIG_MV_ETH_HEADER
  66354. +void run_com_header(const char *buffer);
  66355. +#endif
  66356. +
  66357. +#ifdef INCLUDE_MULTI_QUEUE
  66358. +void ethRxPolMode(int port, MV_ETH_PRIO_MODE prioMode);
  66359. +void ethRxPolQ(int port, int queue, int quota);
  66360. +void ethRxPolicy(int port);
  66361. +void ethTxPolDef(int port, int txQ, char* headerHexStr);
  66362. +void ethTxPolDA(int port, char* macStr, int txQ, char* headerHexStr);
  66363. +void ethTxPolicy(int port);
  66364. +#endif /* INCLUDE_MULTI_QUEUE */
  66365. +
  66366. +#if (MV_ETH_VERSION >= 4)
  66367. +void ethEjpModeSet(int port, int mode)
  66368. +#endif
  66369. +#endif /* 0 */
  66370. +
  66371. +
  66372. +
  66373. +
  66374. +void ethRxCoal(int port, int usec);
  66375. +void ethTxCoal(int port, int usec);
  66376. +#if (MV_ETH_VERSION >= 4)
  66377. +void ethEjpModeSet(int port, int mode);
  66378. +#endif /* (MV_ETH_VERSION >= 4) */
  66379. +
  66380. +void ethBpduRxQ(int port, int bpduQueue);
  66381. +void ethArpRxQ(int port, int arpQueue);
  66382. +void ethTcpRxQ(int port, int tcpQueue);
  66383. +void ethUdpRxQ(int port, int udpQueue);
  66384. +void ethTxPolicyRegs(int port);
  66385. +void ethPortRegs(int port);
  66386. +void ethRegs(int port);
  66387. +void ethClearCounters(int port);
  66388. +void ethPortCounters(int port);
  66389. +void ethPortRmonCounters(int port);
  66390. +void ethPortStatus(int port);
  66391. +void ethPortQueues(int port, int rxQueue, int txQueue, int mode);
  66392. +void ethUcastSet(int port, char* macStr, int queue);
  66393. +void ethPortUcastShow(int port);
  66394. +void ethMcastAdd(int port, char* macStr, int queue);
  66395. +void ethPortMcast(int port);
  66396. +void mvEthPortShow(void* pHndl);
  66397. +void mvEthQueuesShow(void* pHndl, int rxQueue, int txQueue, int mode);
  66398. +
  66399. +#endif
  66400. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h
  66401. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h 1970-01-01 01:00:00.000000000 +0100
  66402. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthGbe.h 2011-08-01 14:38:19.000000000 +0200
  66403. @@ -0,0 +1,751 @@
  66404. +/*******************************************************************************
  66405. +Copyright (C) Marvell International Ltd. and its affiliates
  66406. +
  66407. +This software file (the "File") is owned and distributed by Marvell
  66408. +International Ltd. and/or its affiliates ("Marvell") under the following
  66409. +alternative licensing terms. Once you have made an election to distribute the
  66410. +File under one of the following license alternatives, please (i) delete this
  66411. +introductory statement regarding license alternatives, (ii) delete the two
  66412. +license alternatives that you have not elected to use and (iii) preserve the
  66413. +Marvell copyright notice above.
  66414. +
  66415. +********************************************************************************
  66416. +Marvell Commercial License Option
  66417. +
  66418. +If you received this File from Marvell and you have entered into a commercial
  66419. +license agreement (a "Commercial License") with Marvell, the File is licensed
  66420. +to you under the terms of the applicable Commercial License.
  66421. +
  66422. +********************************************************************************
  66423. +Marvell GPL License Option
  66424. +
  66425. +If you received this File from Marvell, you may opt to use, redistribute and/or
  66426. +modify this File in accordance with the terms and conditions of the General
  66427. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  66428. +available along with the File in the license.txt file or by writing to the Free
  66429. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  66430. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  66431. +
  66432. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  66433. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  66434. +DISCLAIMED. The GPL License provides additional details about this warranty
  66435. +disclaimer.
  66436. +********************************************************************************
  66437. +Marvell BSD License Option
  66438. +
  66439. +If you received this File from Marvell, you may opt to use, redistribute and/or
  66440. +modify this File under the following licensing terms.
  66441. +Redistribution and use in source and binary forms, with or without modification,
  66442. +are permitted provided that the following conditions are met:
  66443. +
  66444. + * Redistributions of source code must retain the above copyright notice,
  66445. + this list of conditions and the following disclaimer.
  66446. +
  66447. + * Redistributions in binary form must reproduce the above copyright
  66448. + notice, this list of conditions and the following disclaimer in the
  66449. + documentation and/or other materials provided with the distribution.
  66450. +
  66451. + * Neither the name of Marvell nor the names of its contributors may be
  66452. + used to endorse or promote products derived from this software without
  66453. + specific prior written permission.
  66454. +
  66455. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  66456. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  66457. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  66458. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  66459. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  66460. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  66461. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  66462. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  66463. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  66464. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  66465. +
  66466. +*******************************************************************************/
  66467. +
  66468. +/*******************************************************************************
  66469. +* mvEth.h - Header File for : Marvell Gigabit Ethernet Controller
  66470. +*
  66471. +* DESCRIPTION:
  66472. +* This header file contains macros typedefs and function declaration specific to
  66473. +* the Marvell Gigabit Ethernet Controller.
  66474. +*
  66475. +* DEPENDENCIES:
  66476. +* None.
  66477. +*
  66478. +*******************************************************************************/
  66479. +
  66480. +#ifndef __mvEthGbe_h__
  66481. +#define __mvEthGbe_h__
  66482. +
  66483. +extern MV_BOOL ethDescInSram;
  66484. +extern MV_BOOL ethDescSwCoher;
  66485. +extern ETH_PORT_CTRL* ethPortCtrl[];
  66486. +
  66487. +static INLINE MV_ULONG ethDescVirtToPhy(ETH_QUEUE_CTRL* pQueueCtrl, MV_U8* pDesc)
  66488. +{
  66489. +#if defined (ETH_DESCR_IN_SRAM)
  66490. + if( ethDescInSram )
  66491. + return mvSramVirtToPhy(pDesc);
  66492. + else
  66493. +#endif /* ETH_DESCR_IN_SRAM */
  66494. + return (pQueueCtrl->descBuf.bufPhysAddr + (pDesc - pQueueCtrl->descBuf.bufVirtPtr));
  66495. +}
  66496. +/* Return port handler */
  66497. +#define mvEthPortHndlGet(port) ethPortCtrl[port]
  66498. +
  66499. +/* Used as WA for HW/SW race on TX */
  66500. +static INLINE int mvEthPortTxEnable(void* pPortHndl, int queue, int max_deep)
  66501. +{
  66502. + int deep = 0;
  66503. + MV_U32 txCurrReg, txEnReg;
  66504. + ETH_TX_DESC* pTxLastDesc;
  66505. + ETH_QUEUE_CTRL* pQueueCtrl;
  66506. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  66507. +
  66508. + txEnReg = MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo));
  66509. + if( (txEnReg & MV_32BIT_LE_FAST(ETH_TXQ_ENABLE_MASK)) == 0)
  66510. + {
  66511. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;
  66512. + return 0;
  66513. + }
  66514. +
  66515. + pQueueCtrl = &pPortCtrl->txQueue[queue];
  66516. + pTxLastDesc = pQueueCtrl->pCurrentDescr;
  66517. + txCurrReg = MV_REG_READ(ETH_TX_CUR_DESC_PTR_REG(pPortCtrl->portNo, queue));
  66518. + if(ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxLastDesc) == txCurrReg)
  66519. + {
  66520. + /* All descriptors are processed, no chance for race */
  66521. + return 0;
  66522. + }
  66523. +
  66524. + /* Check distance betwee HW and SW location: */
  66525. + /* If distance between HW and SW pointers is less than max_deep descriptors */
  66526. + /* Race condition is possible, so wait end of TX and restart TXQ */
  66527. + while(deep < max_deep)
  66528. + {
  66529. + pTxLastDesc = TX_PREV_DESC_PTR(pTxLastDesc, pQueueCtrl);
  66530. + if(ethDescVirtToPhy(pQueueCtrl, (MV_U8*)pTxLastDesc) == txCurrReg)
  66531. + {
  66532. + int count = 0;
  66533. +
  66534. + while( (txEnReg & MV_32BIT_LE_FAST(ETH_TXQ_ENABLE_MASK)) != 0)
  66535. + {
  66536. + count++;
  66537. + if(count > 10000)
  66538. + {
  66539. + mvOsPrintf("mvEthPortTxEnable: timeout - TXQ_CMD=0x%08x\n",
  66540. + MV_REG_READ(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) );
  66541. + break;
  66542. + }
  66543. + txEnReg = MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo));
  66544. + }
  66545. +
  66546. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;
  66547. + return count;
  66548. + }
  66549. + deep++;
  66550. + }
  66551. + /* Distance between HW and SW pointers is more than max_deep descriptors, */
  66552. + /* So NO race condition - do nothing */
  66553. + return -1;
  66554. +}
  66555. +
  66556. +
  66557. +/* defines */
  66558. +#define ETH_CSUM_MIN_BYTE_COUNT 72
  66559. +
  66560. +/* Tailgate and Kirwood have only 2K TX FIFO */
  66561. +#if (MV_ETH_VERSION == 2) || (MV_ETH_VERSION == 4)
  66562. +#define ETH_CSUM_MAX_BYTE_COUNT 1600
  66563. +#else
  66564. +#define ETH_CSUM_MAX_BYTE_COUNT 9*1024
  66565. +#endif /* MV_ETH_VERSION */
  66566. +
  66567. +#define ETH_MV_HEADER_SIZE 2
  66568. +#define ETH_MV_TX_EN
  66569. +
  66570. +/* An offest in Tx descriptors to store data for buffers less than 8 Bytes */
  66571. +#define MIN_TX_BUFF_LOAD 8
  66572. +#define TX_BUF_OFFSET_IN_DESC (ETH_TX_DESC_ALIGNED_SIZE - MIN_TX_BUFF_LOAD)
  66573. +
  66574. +/* Default port configuration value */
  66575. +#define PORT_CONFIG_VALUE \
  66576. + ETH_DEF_RX_QUEUE_MASK(0) | \
  66577. + ETH_DEF_RX_ARP_QUEUE_MASK(0) | \
  66578. + ETH_DEF_RX_TCP_QUEUE_MASK(0) | \
  66579. + ETH_DEF_RX_UDP_QUEUE_MASK(0) | \
  66580. + ETH_DEF_RX_BPDU_QUEUE_MASK(0) | \
  66581. + ETH_RX_CHECKSUM_WITH_PSEUDO_HDR
  66582. +
  66583. +/* Default port extend configuration value */
  66584. +#define PORT_CONFIG_EXTEND_VALUE 0
  66585. +
  66586. +#define PORT_SERIAL_CONTROL_VALUE \
  66587. + ETH_DISABLE_FC_AUTO_NEG_MASK | \
  66588. + BIT9 | \
  66589. + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
  66590. + ETH_MAX_RX_PACKET_1552BYTE | \
  66591. + ETH_SET_FULL_DUPLEX_MASK
  66592. +
  66593. +#define PORT_SERIAL_CONTROL_100MB_FORCE_VALUE \
  66594. + ETH_FORCE_LINK_PASS_MASK | \
  66595. + ETH_DISABLE_DUPLEX_AUTO_NEG_MASK | \
  66596. + ETH_DISABLE_FC_AUTO_NEG_MASK | \
  66597. + BIT9 | \
  66598. + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
  66599. + ETH_DISABLE_SPEED_AUTO_NEG_MASK | \
  66600. + ETH_SET_FULL_DUPLEX_MASK | \
  66601. + ETH_SET_MII_SPEED_100_MASK | \
  66602. + ETH_MAX_RX_PACKET_1552BYTE
  66603. +
  66604. +
  66605. +#define PORT_SERIAL_CONTROL_1000MB_FORCE_VALUE \
  66606. + ETH_FORCE_LINK_PASS_MASK | \
  66607. + ETH_DISABLE_DUPLEX_AUTO_NEG_MASK | \
  66608. + ETH_DISABLE_FC_AUTO_NEG_MASK | \
  66609. + BIT9 | \
  66610. + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
  66611. + ETH_DISABLE_SPEED_AUTO_NEG_MASK | \
  66612. + ETH_SET_FULL_DUPLEX_MASK | \
  66613. + ETH_SET_GMII_SPEED_1000_MASK | \
  66614. + ETH_MAX_RX_PACKET_1552BYTE
  66615. +
  66616. +#define PORT_SERIAL_CONTROL_SGMII_IBAN_VALUE \
  66617. + ETH_DISABLE_FC_AUTO_NEG_MASK | \
  66618. + BIT9 | \
  66619. + ETH_IN_BAND_AN_EN_MASK | \
  66620. + ETH_DO_NOT_FORCE_LINK_FAIL_MASK | \
  66621. + ETH_MAX_RX_PACKET_1552BYTE
  66622. +
  66623. +/* Function headers: */
  66624. +MV_VOID mvEthSetSpecialMcastTable(int portNo, int queue);
  66625. +MV_STATUS mvEthArpRxQueue(void* pPortHandle, int arpQueue);
  66626. +MV_STATUS mvEthUdpRxQueue(void* pPortHandle, int udpQueue);
  66627. +MV_STATUS mvEthTcpRxQueue(void* pPortHandle, int tcpQueue);
  66628. +MV_STATUS mvEthMacAddrGet(int portNo, unsigned char *pAddr);
  66629. +MV_VOID mvEthSetOtherMcastTable(int portNo, int queue);
  66630. +MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode);
  66631. +/* Interrupt Coalesting functions */
  66632. +MV_U32 mvEthRxCoalSet(void* pPortHndl, MV_U32 uSec);
  66633. +MV_U32 mvEthTxCoalSet(void* pPortHndl, MV_U32 uSec);
  66634. +MV_STATUS mvEthCoalGet(void* pPortHndl, MV_U32* pRxCoal, MV_U32* pTxCoal);
  66635. +
  66636. +/******************************************************************************/
  66637. +/* Data Flow functions */
  66638. +/******************************************************************************/
  66639. +static INLINE void mvEthPortTxRestart(void* pPortHndl)
  66640. +{
  66641. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  66642. +
  66643. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(pPortCtrl->portNo)) = pPortCtrl->portTxQueueCmdReg;
  66644. +}
  66645. +
  66646. +/* Get number of Free resources in specific TX queue */
  66647. +static INLINE int mvEthTxResourceGet(void* pPortHndl, int txQueue)
  66648. +{
  66649. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  66650. +
  66651. + return (pPortCtrl->txQueue[txQueue].resource);
  66652. +}
  66653. +
  66654. +/* Get number of Free resources in specific RX queue */
  66655. +static INLINE int mvEthRxResourceGet(void* pPortHndl, int rxQueue)
  66656. +{
  66657. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  66658. +
  66659. + return (pPortCtrl->rxQueue[rxQueue].resource);
  66660. +}
  66661. +
  66662. +static INLINE int mvEthTxQueueIsFull(void* pPortHndl, int txQueue)
  66663. +{
  66664. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  66665. +
  66666. + if(pPortCtrl->txQueue[txQueue].resource == 0)
  66667. + return MV_TRUE;
  66668. +
  66669. + return MV_FALSE;
  66670. +}
  66671. +
  66672. +/* Get number of Free resources in specific RX queue */
  66673. +static INLINE int mvEthRxQueueIsFull(void* pPortHndl, int rxQueue)
  66674. +{
  66675. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  66676. + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];
  66677. +
  66678. + if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&
  66679. + (pQueueCtrl->resource != 0) )
  66680. + return MV_TRUE;
  66681. +
  66682. + return MV_FALSE;
  66683. +}
  66684. +
  66685. +static INLINE int mvEthTxQueueIsEmpty(void* pPortHndl, int txQueue)
  66686. +{
  66687. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  66688. + ETH_QUEUE_CTRL* pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  66689. +
  66690. + if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&
  66691. + (pQueueCtrl->resource != 0) )
  66692. + {
  66693. + return MV_TRUE;
  66694. + }
  66695. + return MV_FALSE;
  66696. +}
  66697. +
  66698. +/* Get number of Free resources in specific RX queue */
  66699. +static INLINE int mvEthRxQueueIsEmpty(void* pPortHndl, int rxQueue)
  66700. +{
  66701. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pPortHndl;
  66702. +
  66703. + if(pPortCtrl->rxQueue[rxQueue].resource == 0)
  66704. + return MV_TRUE;
  66705. +
  66706. + return MV_FALSE;
  66707. +}
  66708. +
  66709. +/*******************************************************************************
  66710. +* mvEthPortTx - Send an Ethernet packet
  66711. +*
  66712. +* DESCRIPTION:
  66713. +* This routine send a given packet described by pPktInfo parameter.
  66714. +* Single buffer only.
  66715. +*
  66716. +* INPUT:
  66717. +* void* pEthPortHndl - Ethernet Port handler.
  66718. +* int txQueue - Number of Tx queue.
  66719. +* MV_PKT_INFO *pPktInfo - User packet to send.
  66720. +*
  66721. +* RETURN:
  66722. +* MV_NO_RESOURCE - No enough resources to send this packet.
  66723. +* MV_ERROR - Unexpected Fatal error.
  66724. +* MV_OK - Packet send successfully.
  66725. +*
  66726. +*******************************************************************************/
  66727. +static INLINE MV_STATUS mvEthPortTx(void* pEthPortHndl, int txQueue, MV_PKT_INFO* pPktInfo)
  66728. +{
  66729. + ETH_TX_DESC* pTxCurrDesc;
  66730. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  66731. + ETH_QUEUE_CTRL* pQueueCtrl;
  66732. + int portNo;
  66733. + MV_BUF_INFO* pBufInfo = pPktInfo->pFrags;
  66734. +
  66735. +#ifdef ETH_DEBUG
  66736. + if(pPortCtrl->portState != MV_ACTIVE)
  66737. + return MV_BAD_STATE;
  66738. +#endif /* ETH_DEBUG */
  66739. +
  66740. + portNo = pPortCtrl->portNo;
  66741. + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  66742. +
  66743. + /* Get the Tx Desc ring indexes */
  66744. + pTxCurrDesc = pQueueCtrl->pCurrentDescr;
  66745. +
  66746. + /* Check if there is enough resources to send the packet */
  66747. + if(pQueueCtrl->resource == 0)
  66748. + return MV_NO_RESOURCE;
  66749. +
  66750. + pTxCurrDesc->byteCnt = pBufInfo->dataSize;
  66751. +
  66752. + /* Flash Buffer */
  66753. + if(pPktInfo->pktSize != 0)
  66754. + {
  66755. +#ifdef MV_NETBSD
  66756. + pTxCurrDesc->bufPtr = pBufInfo->bufPhysAddr;
  66757. + ETH_PACKET_CACHE_FLUSH(pBufInfo->bufVirtPtr, pPktInfo->pktSize);
  66758. +#else
  66759. + pTxCurrDesc->bufPtr = ETH_PACKET_CACHE_FLUSH(pBufInfo->bufVirtPtr, pPktInfo->pktSize);
  66760. +#endif
  66761. + pPktInfo->pktSize = 0;
  66762. + }
  66763. + else
  66764. + pTxCurrDesc->bufPtr = pBufInfo->bufPhysAddr;
  66765. +
  66766. + pTxCurrDesc->returnInfo = (MV_ULONG)pPktInfo;
  66767. +
  66768. + /* There is only one buffer in the packet */
  66769. + /* The OSG might set some bits for checksum offload, so add them to first descriptor */
  66770. + pTxCurrDesc->cmdSts = pPktInfo->status |
  66771. + ETH_BUFFER_OWNED_BY_DMA |
  66772. + ETH_TX_GENERATE_CRC_MASK |
  66773. + ETH_TX_ENABLE_INTERRUPT_MASK |
  66774. + ETH_TX_ZERO_PADDING_MASK |
  66775. + ETH_TX_FIRST_DESC_MASK |
  66776. + ETH_TX_LAST_DESC_MASK;
  66777. +
  66778. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
  66779. +
  66780. + pQueueCtrl->resource--;
  66781. + pQueueCtrl->pCurrentDescr = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);
  66782. +
  66783. + /* Apply send command */
  66784. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(portNo)) = pPortCtrl->portTxQueueCmdReg;
  66785. +
  66786. + return MV_OK;
  66787. +}
  66788. +
  66789. +
  66790. +/*******************************************************************************
  66791. +* mvEthPortSgTx - Send an Ethernet packet
  66792. +*
  66793. +* DESCRIPTION:
  66794. +* This routine send a given packet described by pBufInfo parameter. It
  66795. +* supports transmitting of a packet spaned over multiple buffers.
  66796. +*
  66797. +* INPUT:
  66798. +* void* pEthPortHndl - Ethernet Port handler.
  66799. +* int txQueue - Number of Tx queue.
  66800. +* MV_PKT_INFO *pPktInfo - User packet to send.
  66801. +*
  66802. +* RETURN:
  66803. +* MV_NO_RESOURCE - No enough resources to send this packet.
  66804. +* MV_ERROR - Unexpected Fatal error.
  66805. +* MV_OK - Packet send successfully.
  66806. +*
  66807. +*******************************************************************************/
  66808. +static INLINE MV_STATUS mvEthPortSgTx(void* pEthPortHndl, int txQueue, MV_PKT_INFO* pPktInfo)
  66809. +{
  66810. + ETH_TX_DESC* pTxFirstDesc;
  66811. + ETH_TX_DESC* pTxCurrDesc;
  66812. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  66813. + ETH_QUEUE_CTRL* pQueueCtrl;
  66814. + int portNo, bufCount;
  66815. + MV_BUF_INFO* pBufInfo = pPktInfo->pFrags;
  66816. + MV_U8* pTxBuf;
  66817. +
  66818. +#ifdef ETH_DEBUG
  66819. + if(pPortCtrl->portState != MV_ACTIVE)
  66820. + return MV_BAD_STATE;
  66821. +#endif /* ETH_DEBUG */
  66822. +
  66823. + portNo = pPortCtrl->portNo;
  66824. + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  66825. +
  66826. + /* Get the Tx Desc ring indexes */
  66827. + pTxCurrDesc = pQueueCtrl->pCurrentDescr;
  66828. +
  66829. + /* Check if there is enough resources to send the packet */
  66830. + if(pQueueCtrl->resource < pPktInfo->numFrags)
  66831. + return MV_NO_RESOURCE;
  66832. +
  66833. + /* Remember first desc */
  66834. + pTxFirstDesc = pTxCurrDesc;
  66835. +
  66836. + bufCount = 0;
  66837. + while(MV_TRUE)
  66838. + {
  66839. + if(pBufInfo[bufCount].dataSize <= MIN_TX_BUFF_LOAD)
  66840. + {
  66841. + /* Buffers with a payload smaller than MIN_TX_BUFF_LOAD (8 bytes) must be aligned */
  66842. + /* to 64-bit boundary. Two options here: */
  66843. + /* 1) Usually, copy the payload to the reserved 8 bytes inside descriptor. */
  66844. + /* 2) In the Half duplex workaround, the reserved 8 bytes inside descriptor are used */
  66845. + /* as a pointer to the aligned buffer, copy the small payload to this buffer. */
  66846. + pTxBuf = ((MV_U8*)pTxCurrDesc)+TX_BUF_OFFSET_IN_DESC;
  66847. + mvOsBCopy(pBufInfo[bufCount].bufVirtPtr, pTxBuf, pBufInfo[bufCount].dataSize);
  66848. + pTxCurrDesc->bufPtr = ethDescVirtToPhy(pQueueCtrl, pTxBuf);
  66849. + }
  66850. + else
  66851. + {
  66852. + /* Flash Buffer */
  66853. +#ifdef MV_NETBSD
  66854. + pTxCurrDesc->bufPtr = pBufInfo[bufCount].bufPhysAddr;
  66855. + ETH_PACKET_CACHE_FLUSH(pBufInfo[bufCount].bufVirtPtr, pBufInfo[bufCount].dataSize);
  66856. +#else
  66857. + pTxCurrDesc->bufPtr = ETH_PACKET_CACHE_FLUSH(pBufInfo[bufCount].bufVirtPtr, pBufInfo[bufCount].dataSize);
  66858. +#endif
  66859. + }
  66860. +
  66861. + pTxCurrDesc->byteCnt = pBufInfo[bufCount].dataSize;
  66862. + bufCount++;
  66863. +
  66864. + if(bufCount >= pPktInfo->numFrags)
  66865. + break;
  66866. +
  66867. + if(bufCount > 1)
  66868. + {
  66869. + /* There is middle buffer of the packet Not First and Not Last */
  66870. + pTxCurrDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA;
  66871. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
  66872. + }
  66873. + /* Go to next descriptor and next buffer */
  66874. + pTxCurrDesc = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);
  66875. + }
  66876. + /* Set last desc with DMA ownership and interrupt enable. */
  66877. + pTxCurrDesc->returnInfo = (MV_ULONG)pPktInfo;
  66878. + if(bufCount == 1)
  66879. + {
  66880. + /* There is only one buffer in the packet */
  66881. + /* The OSG might set some bits for checksum offload, so add them to first descriptor */
  66882. + pTxCurrDesc->cmdSts = pPktInfo->status |
  66883. + ETH_BUFFER_OWNED_BY_DMA |
  66884. + ETH_TX_GENERATE_CRC_MASK |
  66885. + ETH_TX_ENABLE_INTERRUPT_MASK |
  66886. + ETH_TX_ZERO_PADDING_MASK |
  66887. + ETH_TX_FIRST_DESC_MASK |
  66888. + ETH_TX_LAST_DESC_MASK;
  66889. +
  66890. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
  66891. + }
  66892. + else
  66893. + {
  66894. + /* Last but not First */
  66895. + pTxCurrDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA |
  66896. + ETH_TX_ENABLE_INTERRUPT_MASK |
  66897. + ETH_TX_ZERO_PADDING_MASK |
  66898. + ETH_TX_LAST_DESC_MASK;
  66899. +
  66900. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxCurrDesc);
  66901. +
  66902. + /* Update First when more than one buffer in the packet */
  66903. + /* The OSG might set some bits for checksum offload, so add them to first descriptor */
  66904. + pTxFirstDesc->cmdSts = pPktInfo->status |
  66905. + ETH_BUFFER_OWNED_BY_DMA |
  66906. + ETH_TX_GENERATE_CRC_MASK |
  66907. + ETH_TX_FIRST_DESC_MASK;
  66908. +
  66909. + ETH_DESCR_FLUSH_INV(pPortCtrl, pTxFirstDesc);
  66910. + }
  66911. + /* Update txQueue state */
  66912. + pQueueCtrl->resource -= bufCount;
  66913. + pQueueCtrl->pCurrentDescr = TX_NEXT_DESC_PTR(pTxCurrDesc, pQueueCtrl);
  66914. +
  66915. + /* Apply send command */
  66916. + MV_REG_VALUE(ETH_TX_QUEUE_COMMAND_REG(portNo)) = pPortCtrl->portTxQueueCmdReg;
  66917. +
  66918. + return MV_OK;
  66919. +}
  66920. +
  66921. +/*******************************************************************************
  66922. +* mvEthPortTxDone - Free all used Tx descriptors and mBlks.
  66923. +*
  66924. +* DESCRIPTION:
  66925. +* This routine returns the transmitted packet information to the caller.
  66926. +*
  66927. +* INPUT:
  66928. +* void* pEthPortHndl - Ethernet Port handler.
  66929. +* int txQueue - Number of Tx queue.
  66930. +*
  66931. +* OUTPUT:
  66932. +* MV_PKT_INFO *pPktInfo - Pointer to packet was sent.
  66933. +*
  66934. +* RETURN:
  66935. +* MV_NOT_FOUND - No transmitted packets to return. Transmit in progress.
  66936. +* MV_EMPTY - No transmitted packets to return. TX Queue is empty.
  66937. +* MV_ERROR - Unexpected Fatal error.
  66938. +* MV_OK - There is transmitted packet in the queue,
  66939. +* 'pPktInfo' filled with relevant information.
  66940. +*
  66941. +*******************************************************************************/
  66942. +static INLINE MV_PKT_INFO* mvEthPortTxDone(void* pEthPortHndl, int txQueue)
  66943. +{
  66944. + ETH_TX_DESC* pTxCurrDesc;
  66945. + ETH_TX_DESC* pTxUsedDesc;
  66946. + ETH_QUEUE_CTRL* pQueueCtrl;
  66947. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  66948. + MV_PKT_INFO* pPktInfo;
  66949. + MV_U32 commandStatus;
  66950. +
  66951. + pQueueCtrl = &pPortCtrl->txQueue[txQueue];
  66952. +
  66953. + pTxUsedDesc = pQueueCtrl->pUsedDescr;
  66954. + pTxCurrDesc = pQueueCtrl->pCurrentDescr;
  66955. +
  66956. + while(MV_TRUE)
  66957. + {
  66958. + /* No more used descriptors */
  66959. + commandStatus = pTxUsedDesc->cmdSts;
  66960. + if (commandStatus & (ETH_BUFFER_OWNED_BY_DMA))
  66961. + {
  66962. + ETH_DESCR_INV(pPortCtrl, pTxUsedDesc);
  66963. + return NULL;
  66964. + }
  66965. + if( (pTxUsedDesc == pTxCurrDesc) &&
  66966. + (pQueueCtrl->resource != 0) )
  66967. + {
  66968. + return NULL;
  66969. + }
  66970. + pQueueCtrl->resource++;
  66971. + pQueueCtrl->pUsedDescr = TX_NEXT_DESC_PTR(pTxUsedDesc, pQueueCtrl);
  66972. + if(commandStatus & (ETH_TX_LAST_DESC_MASK))
  66973. + {
  66974. + pPktInfo = (MV_PKT_INFO*)pTxUsedDesc->returnInfo;
  66975. + pPktInfo->status = commandStatus;
  66976. + return pPktInfo;
  66977. + }
  66978. + pTxUsedDesc = pQueueCtrl->pUsedDescr;
  66979. + }
  66980. +}
  66981. +
  66982. +/*******************************************************************************
  66983. +* mvEthPortRx - Get new received packets from Rx queue.
  66984. +*
  66985. +* DESCRIPTION:
  66986. +* This routine returns the received data to the caller. There is no
  66987. +* data copying during routine operation. All information is returned
  66988. +* using pointer to packet information struct passed from the caller.
  66989. +*
  66990. +* INPUT:
  66991. +* void* pEthPortHndl - Ethernet Port handler.
  66992. +* int rxQueue - Number of Rx queue.
  66993. +*
  66994. +* OUTPUT:
  66995. +* MV_PKT_INFO *pPktInfo - Pointer to received packet.
  66996. +*
  66997. +* RETURN:
  66998. +* MV_NO_RESOURCE - No free resources in RX queue.
  66999. +* MV_ERROR - Unexpected Fatal error.
  67000. +* MV_OK - New packet received and 'pBufInfo' structure filled
  67001. +* with relevant information.
  67002. +*
  67003. +*******************************************************************************/
  67004. +static INLINE MV_PKT_INFO* mvEthPortRx(void* pEthPortHndl, int rxQueue)
  67005. +{
  67006. + ETH_RX_DESC *pRxCurrDesc;
  67007. + MV_U32 commandStatus;
  67008. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  67009. + ETH_QUEUE_CTRL* pQueueCtrl;
  67010. + MV_PKT_INFO* pPktInfo;
  67011. +
  67012. + pQueueCtrl = &(pPortCtrl->rxQueue[rxQueue]);
  67013. +
  67014. + /* Check resources */
  67015. + if(pQueueCtrl->resource == 0)
  67016. + {
  67017. + mvOsPrintf("ethPortRx: no more resources\n");
  67018. + return NULL;
  67019. + }
  67020. + while(MV_TRUE)
  67021. + {
  67022. + /* Get the Rx Desc ring 'curr and 'used' indexes */
  67023. + pRxCurrDesc = pQueueCtrl->pCurrentDescr;
  67024. +
  67025. + commandStatus = pRxCurrDesc->cmdSts;
  67026. + if (commandStatus & (ETH_BUFFER_OWNED_BY_DMA))
  67027. + {
  67028. + /* Nothing to receive... */
  67029. + ETH_DESCR_INV(pPortCtrl, pRxCurrDesc);
  67030. + return NULL;
  67031. + }
  67032. +
  67033. + /* Valid RX only if FIRST and LAST bits are set */
  67034. + if( (commandStatus & (ETH_RX_LAST_DESC_MASK | ETH_RX_FIRST_DESC_MASK)) ==
  67035. + (ETH_RX_LAST_DESC_MASK | ETH_RX_FIRST_DESC_MASK) )
  67036. + {
  67037. + pPktInfo = (MV_PKT_INFO*)pRxCurrDesc->returnInfo;
  67038. + pPktInfo->pFrags->dataSize = pRxCurrDesc->byteCnt - 4;
  67039. + pPktInfo->status = commandStatus;
  67040. + pPktInfo->fragIP = pRxCurrDesc->bufSize & ETH_RX_IP_FRAGMENTED_FRAME_MASK;
  67041. +
  67042. + pQueueCtrl->resource--;
  67043. + /* Update 'curr' in data structure */
  67044. + pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxCurrDesc, pQueueCtrl);
  67045. +
  67046. +#ifdef INCLUDE_SYNC_BARR
  67047. + mvCpuIfSyncBarr(DRAM_TARGET);
  67048. +#endif
  67049. + return pPktInfo;
  67050. + }
  67051. + else
  67052. + {
  67053. + ETH_RX_DESC* pRxUsedDesc = pQueueCtrl->pUsedDescr;
  67054. +
  67055. +#ifdef ETH_DEBUG
  67056. + mvOsPrintf("ethDrv: Unexpected Jumbo frame: "
  67057. + "status=0x%08x, byteCnt=%d, pData=0x%x\n",
  67058. + commandStatus, pRxCurrDesc->byteCnt, pRxCurrDesc->bufPtr);
  67059. +#endif /* ETH_DEBUG */
  67060. +
  67061. + /* move buffer from pCurrentDescr position to pUsedDescr position */
  67062. + pRxUsedDesc->bufPtr = pRxCurrDesc->bufPtr;
  67063. + pRxUsedDesc->returnInfo = pRxCurrDesc->returnInfo;
  67064. + pRxUsedDesc->bufSize = pRxCurrDesc->bufSize & ETH_RX_BUFFER_MASK;
  67065. +
  67066. + /* Return the descriptor to DMA ownership */
  67067. + pRxUsedDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA |
  67068. + ETH_RX_ENABLE_INTERRUPT_MASK;
  67069. +
  67070. + /* Flush descriptor and CPU pipe */
  67071. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxUsedDesc);
  67072. +
  67073. + /* Move the used descriptor pointer to the next descriptor */
  67074. + pQueueCtrl->pUsedDescr = RX_NEXT_DESC_PTR(pRxUsedDesc, pQueueCtrl);
  67075. + pQueueCtrl->pCurrentDescr = RX_NEXT_DESC_PTR(pRxCurrDesc, pQueueCtrl);
  67076. + }
  67077. + }
  67078. +}
  67079. +
  67080. +/*******************************************************************************
  67081. +* mvEthPortRxDone - Returns a Rx buffer back to the Rx ring.
  67082. +*
  67083. +* DESCRIPTION:
  67084. +* This routine returns a Rx buffer back to the Rx ring.
  67085. +*
  67086. +* INPUT:
  67087. +* void* pEthPortHndl - Ethernet Port handler.
  67088. +* int rxQueue - Number of Rx queue.
  67089. +* MV_PKT_INFO *pPktInfo - Pointer to received packet.
  67090. +*
  67091. +* RETURN:
  67092. +* MV_ERROR - Unexpected Fatal error.
  67093. +* MV_OUT_OF_RANGE - RX queue is already FULL, so this buffer can't be
  67094. +* returned to this queue.
  67095. +* MV_FULL - Buffer returned successfully and RX queue became full.
  67096. +* More buffers should not be returned at the time.
  67097. +* MV_OK - Buffer returned successfully and there are more free
  67098. +* places in the queue.
  67099. +*
  67100. +*******************************************************************************/
  67101. +static INLINE MV_STATUS mvEthPortRxDone(void* pEthPortHndl, int rxQueue, MV_PKT_INFO *pPktInfo)
  67102. +{
  67103. + ETH_RX_DESC* pRxUsedDesc;
  67104. + ETH_QUEUE_CTRL* pQueueCtrl;
  67105. + ETH_PORT_CTRL* pPortCtrl = (ETH_PORT_CTRL*)pEthPortHndl;
  67106. +
  67107. + pQueueCtrl = &pPortCtrl->rxQueue[rxQueue];
  67108. +
  67109. + /* Get 'used' Rx descriptor */
  67110. + pRxUsedDesc = pQueueCtrl->pUsedDescr;
  67111. +
  67112. + /* Check that ring is not FULL */
  67113. + if( (pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr) &&
  67114. + (pQueueCtrl->resource != 0) )
  67115. + {
  67116. + mvOsPrintf("%s %d: out of range Error resource=%d, curr=%p, used=%p\n",
  67117. + __FUNCTION__, pPortCtrl->portNo, pQueueCtrl->resource,
  67118. + pQueueCtrl->pCurrentDescr, pQueueCtrl->pUsedDescr);
  67119. + return MV_OUT_OF_RANGE;
  67120. + }
  67121. +
  67122. + pRxUsedDesc->bufPtr = pPktInfo->pFrags->bufPhysAddr;
  67123. + pRxUsedDesc->returnInfo = (MV_ULONG)pPktInfo;
  67124. + pRxUsedDesc->bufSize = pPktInfo->pFrags->bufSize & ETH_RX_BUFFER_MASK;
  67125. +
  67126. + /* Invalidate data buffer accordingly with pktSize */
  67127. + if(pPktInfo->pktSize != 0)
  67128. + {
  67129. + ETH_PACKET_CACHE_INVALIDATE(pPktInfo->pFrags->bufVirtPtr, pPktInfo->pktSize);
  67130. + pPktInfo->pktSize = 0;
  67131. + }
  67132. +
  67133. + /* Return the descriptor to DMA ownership */
  67134. + pRxUsedDesc->cmdSts = ETH_BUFFER_OWNED_BY_DMA | ETH_RX_ENABLE_INTERRUPT_MASK;
  67135. +
  67136. + /* Flush descriptor and CPU pipe */
  67137. + ETH_DESCR_FLUSH_INV(pPortCtrl, pRxUsedDesc);
  67138. +
  67139. + pQueueCtrl->resource++;
  67140. +
  67141. + /* Move the used descriptor pointer to the next descriptor */
  67142. + pQueueCtrl->pUsedDescr = RX_NEXT_DESC_PTR(pRxUsedDesc, pQueueCtrl);
  67143. +
  67144. + /* If ring became Full return MV_FULL */
  67145. + if(pQueueCtrl->pUsedDescr == pQueueCtrl->pCurrentDescr)
  67146. + return MV_FULL;
  67147. +
  67148. + return MV_OK;
  67149. +}
  67150. +
  67151. +
  67152. +#endif /* __mvEthGbe_h__ */
  67153. +
  67154. +
  67155. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h
  67156. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h 1970-01-01 01:00:00.000000000 +0100
  67157. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/gbe/mvEthRegs.h 2011-08-01 14:38:19.000000000 +0200
  67158. @@ -0,0 +1,700 @@
  67159. +/*******************************************************************************
  67160. +Copyright (C) Marvell International Ltd. and its affiliates
  67161. +
  67162. +This software file (the "File") is owned and distributed by Marvell
  67163. +International Ltd. and/or its affiliates ("Marvell") under the following
  67164. +alternative licensing terms. Once you have made an election to distribute the
  67165. +File under one of the following license alternatives, please (i) delete this
  67166. +introductory statement regarding license alternatives, (ii) delete the two
  67167. +license alternatives that you have not elected to use and (iii) preserve the
  67168. +Marvell copyright notice above.
  67169. +
  67170. +********************************************************************************
  67171. +Marvell Commercial License Option
  67172. +
  67173. +If you received this File from Marvell and you have entered into a commercial
  67174. +license agreement (a "Commercial License") with Marvell, the File is licensed
  67175. +to you under the terms of the applicable Commercial License.
  67176. +
  67177. +********************************************************************************
  67178. +Marvell GPL License Option
  67179. +
  67180. +If you received this File from Marvell, you may opt to use, redistribute and/or
  67181. +modify this File in accordance with the terms and conditions of the General
  67182. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  67183. +available along with the File in the license.txt file or by writing to the Free
  67184. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  67185. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  67186. +
  67187. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  67188. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  67189. +DISCLAIMED. The GPL License provides additional details about this warranty
  67190. +disclaimer.
  67191. +********************************************************************************
  67192. +Marvell BSD License Option
  67193. +
  67194. +If you received this File from Marvell, you may opt to use, redistribute and/or
  67195. +modify this File under the following licensing terms.
  67196. +Redistribution and use in source and binary forms, with or without modification,
  67197. +are permitted provided that the following conditions are met:
  67198. +
  67199. + * Redistributions of source code must retain the above copyright notice,
  67200. + this list of conditions and the following disclaimer.
  67201. +
  67202. + * Redistributions in binary form must reproduce the above copyright
  67203. + notice, this list of conditions and the following disclaimer in the
  67204. + documentation and/or other materials provided with the distribution.
  67205. +
  67206. + * Neither the name of Marvell nor the names of its contributors may be
  67207. + used to endorse or promote products derived from this software without
  67208. + specific prior written permission.
  67209. +
  67210. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  67211. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  67212. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  67213. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  67214. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  67215. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  67216. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  67217. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  67218. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  67219. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  67220. +
  67221. +*******************************************************************************/
  67222. +
  67223. +
  67224. +#ifndef __INCmvEthRegsh
  67225. +#define __INCmvEthRegsh
  67226. +
  67227. +#ifdef __cplusplus
  67228. +extern "C" {
  67229. +#endif /* __cplusplus */
  67230. +
  67231. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  67232. +
  67233. +/****************************************/
  67234. +/* Ethernet Unit Registers */
  67235. +/****************************************/
  67236. +#define ETH_REG_BASE MV_ETH_REG_BASE
  67237. +
  67238. +#define ETH_PHY_ADDR_REG(port) (ETH_REG_BASE(port) + 0x000)
  67239. +#define ETH_SMI_REG(port) (ETH_REG_BASE(port) + 0x004)
  67240. +#define ETH_UNIT_DEF_ADDR_REG(port) (ETH_REG_BASE(port) + 0x008)
  67241. +#define ETH_UNIT_DEF_ID_REG(port) (ETH_REG_BASE(port) + 0x00c)
  67242. +#define ETH_UNIT_RESERVED(port) (ETH_REG_BASE(port) + 0x014)
  67243. +#define ETH_UNIT_INTR_CAUSE_REG(port) (ETH_REG_BASE(port) + 0x080)
  67244. +#define ETH_UNIT_INTR_MASK_REG(port) (ETH_REG_BASE(port) + 0x084)
  67245. +
  67246. +
  67247. +#define ETH_UNIT_ERROR_ADDR_REG(port) (ETH_REG_BASE(port) + 0x094)
  67248. +#define ETH_UNIT_INT_ADDR_ERROR_REG(port) (ETH_REG_BASE(port) + 0x098)
  67249. +#define ETH_UNIT_CONTROL_REG(port) (ETH_REG_BASE(port) + 0x0B0)
  67250. +
  67251. +#define ETH_PORT_CONFIG_REG(port) (ETH_REG_BASE(port) + 0x400)
  67252. +#define ETH_PORT_CONFIG_EXTEND_REG(port) (ETH_REG_BASE(port) + 0x404)
  67253. +#define ETH_MII_SERIAL_PARAM_REG(port) (ETH_REG_BASE(port) + 0x408)
  67254. +#define ETH_GMII_SERIAL_PARAM_REG(port) (ETH_REG_BASE(port) + 0x40c)
  67255. +#define ETH_VLAN_ETHER_TYPE_REG(port) (ETH_REG_BASE(port) + 0x410)
  67256. +#define ETH_MAC_ADDR_LOW_REG(port) (ETH_REG_BASE(port) + 0x414)
  67257. +#define ETH_MAC_ADDR_HIGH_REG(port) (ETH_REG_BASE(port) + 0x418)
  67258. +#define ETH_SDMA_CONFIG_REG(port) (ETH_REG_BASE(port) + 0x41c)
  67259. +#define ETH_DIFF_SERV_PRIO_REG(port, code) (ETH_REG_BASE(port) + 0x420 + ((code)<<2))
  67260. +#define ETH_PORT_SERIAL_CTRL_REG(port) (ETH_REG_BASE(port) + 0x43c)
  67261. +#define ETH_VLAN_TAG_TO_PRIO_REG(port) (ETH_REG_BASE(port) + 0x440)
  67262. +#define ETH_PORT_STATUS_REG(port) (ETH_REG_BASE(port) + 0x444)
  67263. +
  67264. +#define ETH_RX_QUEUE_COMMAND_REG(port) (ETH_REG_BASE(port) + 0x680)
  67265. +#define ETH_TX_QUEUE_COMMAND_REG(port) (ETH_REG_BASE(port) + 0x448)
  67266. +
  67267. +#define ETH_PORT_SERIAL_CTRL_1_REG(port) (ETH_REG_BASE(port) + 0x44c)
  67268. +#define ETH_PORT_STATUS_1_REG(port) (ETH_REG_BASE(port) + 0x450)
  67269. +#define ETH_PORT_MARVELL_HEADER_REG(port) (ETH_REG_BASE(port) + 0x454)
  67270. +#define ETH_PORT_FIFO_PARAMS_REG(port) (ETH_REG_BASE(port) + 0x458)
  67271. +#define ETH_MAX_TOKEN_BUCKET_SIZE_REG(port) (ETH_REG_BASE(port) + 0x45c)
  67272. +#define ETH_INTR_CAUSE_REG(port) (ETH_REG_BASE(port) + 0x460)
  67273. +#define ETH_INTR_CAUSE_EXT_REG(port) (ETH_REG_BASE(port) + 0x464)
  67274. +#define ETH_INTR_MASK_REG(port) (ETH_REG_BASE(port) + 0x468)
  67275. +#define ETH_INTR_MASK_EXT_REG(port) (ETH_REG_BASE(port) + 0x46c)
  67276. +#define ETH_TX_FIFO_URGENT_THRESH_REG(port) (ETH_REG_BASE(port) + 0x474)
  67277. +#define ETH_RX_MINIMAL_FRAME_SIZE_REG(port) (ETH_REG_BASE(port) + 0x47c)
  67278. +#define ETH_RX_DISCARD_PKTS_CNTR_REG(port) (ETH_REG_BASE(port) + 0x484)
  67279. +#define ETH_RX_OVERRUN_PKTS_CNTR_REG(port) (ETH_REG_BASE(port) + 0x488)
  67280. +#define ETH_INTERNAL_ADDR_ERROR_REG(port) (ETH_REG_BASE(port) + 0x494)
  67281. +#define ETH_TX_FIXED_PRIO_CFG_REG(port) (ETH_REG_BASE(port) + 0x4dc)
  67282. +#define ETH_TX_TOKEN_RATE_CFG_REG(port) (ETH_REG_BASE(port) + 0x4e0)
  67283. +#define ETH_TX_QUEUE_COMMAND1_REG(port) (ETH_REG_BASE(port) + 0x4e4)
  67284. +#define ETH_MAX_TRANSMIT_UNIT_REG(port) (ETH_REG_BASE(port) + 0x4e8)
  67285. +#define ETH_TX_TOKEN_BUCKET_SIZE_REG(port) (ETH_REG_BASE(port) + 0x4ec)
  67286. +#define ETH_TX_TOKEN_BUCKET_COUNT_REG(port) (ETH_REG_BASE(port) + 0x780)
  67287. +#define ETH_RX_DESCR_STAT_CMD_REG(port, q) (ETH_REG_BASE(port) + 0x600 + ((q)<<4))
  67288. +#define ETH_RX_BYTE_COUNT_REG(port, q) (ETH_REG_BASE(port) + 0x604 + ((q)<<4))
  67289. +#define ETH_RX_BUF_PTR_REG(port, q) (ETH_REG_BASE(port) + 0x608 + ((q)<<4))
  67290. +#define ETH_RX_CUR_DESC_PTR_REG(port, q) (ETH_REG_BASE(port) + 0x60c + ((q)<<4))
  67291. +#define ETH_TX_CUR_DESC_PTR_REG(port, q) (ETH_REG_BASE(port) + 0x6c0 + ((q)<<2))
  67292. +
  67293. +#define ETH_TXQ_TOKEN_COUNT_REG(port, q) (ETH_REG_BASE(port) + 0x700 + ((q)<<4))
  67294. +#define ETH_TXQ_TOKEN_CFG_REG(port, q) (ETH_REG_BASE(port) + 0x704 + ((q)<<4))
  67295. +#define ETH_TXQ_ARBITER_CFG_REG(port, q) (ETH_REG_BASE(port) + 0x708 + ((q)<<4))
  67296. +
  67297. +#if (MV_ETH_VERSION >= 4)
  67298. +#define ETH_TXQ_CMD_1_REG(port) (ETH_REG_BASE(port) + 0x4E4)
  67299. +#define ETH_EJP_TX_HI_IPG_REG(port) (ETH_REG_BASE(port) + 0x7A8)
  67300. +#define ETH_EJP_TX_LO_IPG_REG(port) (ETH_REG_BASE(port) + 0x7B8)
  67301. +#define ETH_EJP_HI_TKN_LO_PKT_REG(port) (ETH_REG_BASE(port) + 0x7C0)
  67302. +#define ETH_EJP_HI_TKN_ASYNC_PKT_REG(port) (ETH_REG_BASE(port) + 0x7C4)
  67303. +#define ETH_EJP_LO_TKN_ASYNC_PKT_REG(port) (ETH_REG_BASE(port) + 0x7C8)
  67304. +#define ETH_EJP_TX_SPEED_REG(port) (ETH_REG_BASE(port) + 0x7D0)
  67305. +#endif /* MV_ETH_VERSION >= 4 */
  67306. +
  67307. +#define ETH_MIB_COUNTERS_BASE(port) (ETH_REG_BASE(port) + 0x1000)
  67308. +#define ETH_DA_FILTER_SPEC_MCAST_BASE(port) (ETH_REG_BASE(port) + 0x1400)
  67309. +#define ETH_DA_FILTER_OTH_MCAST_BASE(port) (ETH_REG_BASE(port) + 0x1500)
  67310. +#define ETH_DA_FILTER_UCAST_BASE(port) (ETH_REG_BASE(port) + 0x1600)
  67311. +
  67312. +/* Phy address register definitions */
  67313. +#define ETH_PHY_ADDR_OFFS 0
  67314. +#define ETH_PHY_ADDR_MASK (0x1f <<ETH_PHY_ADDR_OFFS)
  67315. +
  67316. +/* MIB Counters register definitions */
  67317. +#define ETH_MIB_GOOD_OCTETS_RECEIVED_LOW 0x0
  67318. +#define ETH_MIB_GOOD_OCTETS_RECEIVED_HIGH 0x4
  67319. +#define ETH_MIB_BAD_OCTETS_RECEIVED 0x8
  67320. +#define ETH_MIB_INTERNAL_MAC_TRANSMIT_ERR 0xc
  67321. +#define ETH_MIB_GOOD_FRAMES_RECEIVED 0x10
  67322. +#define ETH_MIB_BAD_FRAMES_RECEIVED 0x14
  67323. +#define ETH_MIB_BROADCAST_FRAMES_RECEIVED 0x18
  67324. +#define ETH_MIB_MULTICAST_FRAMES_RECEIVED 0x1c
  67325. +#define ETH_MIB_FRAMES_64_OCTETS 0x20
  67326. +#define ETH_MIB_FRAMES_65_TO_127_OCTETS 0x24
  67327. +#define ETH_MIB_FRAMES_128_TO_255_OCTETS 0x28
  67328. +#define ETH_MIB_FRAMES_256_TO_511_OCTETS 0x2c
  67329. +#define ETH_MIB_FRAMES_512_TO_1023_OCTETS 0x30
  67330. +#define ETH_MIB_FRAMES_1024_TO_MAX_OCTETS 0x34
  67331. +#define ETH_MIB_GOOD_OCTETS_SENT_LOW 0x38
  67332. +#define ETH_MIB_GOOD_OCTETS_SENT_HIGH 0x3c
  67333. +#define ETH_MIB_GOOD_FRAMES_SENT 0x40
  67334. +#define ETH_MIB_EXCESSIVE_COLLISION 0x44
  67335. +#define ETH_MIB_MULTICAST_FRAMES_SENT 0x48
  67336. +#define ETH_MIB_BROADCAST_FRAMES_SENT 0x4c
  67337. +#define ETH_MIB_UNREC_MAC_CONTROL_RECEIVED 0x50
  67338. +#define ETH_MIB_FC_SENT 0x54
  67339. +#define ETH_MIB_GOOD_FC_RECEIVED 0x58
  67340. +#define ETH_MIB_BAD_FC_RECEIVED 0x5c
  67341. +#define ETH_MIB_UNDERSIZE_RECEIVED 0x60
  67342. +#define ETH_MIB_FRAGMENTS_RECEIVED 0x64
  67343. +#define ETH_MIB_OVERSIZE_RECEIVED 0x68
  67344. +#define ETH_MIB_JABBER_RECEIVED 0x6c
  67345. +#define ETH_MIB_MAC_RECEIVE_ERROR 0x70
  67346. +#define ETH_MIB_BAD_CRC_EVENT 0x74
  67347. +#define ETH_MIB_COLLISION 0x78
  67348. +#define ETH_MIB_LATE_COLLISION 0x7c
  67349. +
  67350. +
  67351. +/****************************************/
  67352. +/* Ethernet Unit Register BITs */
  67353. +/****************************************/
  67354. +
  67355. +#define ETH_RXQ_ENABLE_OFFSET 0
  67356. +#define ETH_RXQ_ENABLE_MASK (0x000000FF << ETH_RXQ_ENABLE_OFFSET)
  67357. +
  67358. +#define ETH_RXQ_DISABLE_OFFSET 8
  67359. +#define ETH_RXQ_DISABLE_MASK (0x000000FF << ETH_RXQ_DISABLE_OFFSET)
  67360. +
  67361. +/***** BITs of Transmit Queue Command (TQC) register *****/
  67362. +#define ETH_TXQ_ENABLE_OFFSET 0
  67363. +#define ETH_TXQ_ENABLE_MASK (0x000000FF << ETH_TXQ_ENABLE_OFFSET)
  67364. +
  67365. +#define ETH_TXQ_DISABLE_OFFSET 8
  67366. +#define ETH_TXQ_DISABLE_MASK (0x000000FF << ETH_TXQ_DISABLE_OFFSET)
  67367. +
  67368. +#if (MV_ETH_VERSION >= 4)
  67369. +#define ETH_TX_EJP_RESET_BIT 0
  67370. +#define ETH_TX_EJP_RESET_MASK (1 << ETH_TX_EJP_RESET_BIT)
  67371. +
  67372. +#define ETH_TX_EJP_ENABLE_BIT 2
  67373. +#define ETH_TX_EJP_ENABLE_MASK (1 << ETH_TX_EJP_ENABLE_BIT)
  67374. +
  67375. +#define ETH_TX_LEGACY_WRR_BIT 3
  67376. +#define ETH_TX_LEGACY_WRR_MASK (1 << ETH_TX_LEGACY_WRR_BIT)
  67377. +#endif /* (MV_ETH_VERSION >= 4) */
  67378. +
  67379. +/***** BITs of Ethernet Port Status reg (PSR) *****/
  67380. +#define ETH_LINK_UP_BIT 1
  67381. +#define ETH_LINK_UP_MASK (1<<ETH_LINK_UP_BIT)
  67382. +
  67383. +#define ETH_FULL_DUPLEX_BIT 2
  67384. +#define ETH_FULL_DUPLEX_MASK (1<<ETH_FULL_DUPLEX_BIT)
  67385. +
  67386. +#define ETH_ENABLE_RCV_FLOW_CTRL_BIT 3
  67387. +#define ETH_ENABLE_RCV_FLOW_CTRL_MASK (1<<ETH_ENABLE_RCV_FLOW_CTRL_BIT)
  67388. +
  67389. +#define ETH_GMII_SPEED_1000_BIT 4
  67390. +#define ETH_GMII_SPEED_1000_MASK (1<<ETH_GMII_SPEED_1000_BIT)
  67391. +
  67392. +#define ETH_MII_SPEED_100_BIT 5
  67393. +#define ETH_MII_SPEED_100_MASK (1<<ETH_MII_SPEED_100_BIT)
  67394. +
  67395. +#define ETH_TX_IN_PROGRESS_BIT 7
  67396. +#define ETH_TX_IN_PROGRESS_MASK (1<<ETH_TX_IN_PROGRESS_BIT)
  67397. +
  67398. +#define ETH_TX_FIFO_EMPTY_BIT 10
  67399. +#define ETH_TX_FIFO_EMPTY_MASK (1<<ETH_TX_FIFO_EMPTY_BIT)
  67400. +
  67401. +/***** BITs of Ethernet Port Status 1 reg (PS1R) *****/
  67402. +#define ETH_AUTO_NEG_DONE_BIT 4
  67403. +#define ETH_AUTO_NEG_DONE_MASK (1<<ETH_AUTO_NEG_DONE_BIT)
  67404. +
  67405. +#define ETH_SERDES_PLL_LOCKED_BIT 6
  67406. +#define ETH_SERDES_PLL_LOCKED_MASK (1<<ETH_SERDES_PLL_LOCKED_BIT)
  67407. +
  67408. +/***** BITs of Port Configuration reg (PxCR) *****/
  67409. +#define ETH_UNICAST_PROMISCUOUS_MODE_BIT 0
  67410. +#define ETH_UNICAST_PROMISCUOUS_MODE_MASK (1<<ETH_UNICAST_PROMISCUOUS_MODE_BIT)
  67411. +
  67412. +#define ETH_DEF_RX_QUEUE_OFFSET 1
  67413. +#define ETH_DEF_RX_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_QUEUE_OFFSET)
  67414. +#define ETH_DEF_RX_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_QUEUE_OFFSET)
  67415. +
  67416. +#define ETH_DEF_RX_ARP_QUEUE_OFFSET 4
  67417. +#define ETH_DEF_RX_ARP_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_ARP_QUEUE_OFFSET)
  67418. +#define ETH_DEF_RX_ARP_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_ARP_QUEUE_OFFSET)
  67419. +
  67420. +#define ETH_REJECT_NOT_IP_ARP_BCAST_BIT 7
  67421. +#define ETH_REJECT_NOT_IP_ARP_BCAST_MASK (1<<ETH_REJECT_NOT_IP_ARP_BCAST_BIT)
  67422. +
  67423. +#define ETH_REJECT_IP_BCAST_BIT 8
  67424. +#define ETH_REJECT_IP_BCAST_MASK (1<<ETH_REJECT_IP_BCAST_BIT)
  67425. +
  67426. +#define ETH_REJECT_ARP_BCAST_BIT 9
  67427. +#define ETH_REJECT_ARP_BCAST_MASK (1<<ETH_REJECT_ARP_BCAST_BIT)
  67428. +
  67429. +#define ETH_TX_NO_SET_ERROR_SUMMARY_BIT 12
  67430. +#define ETH_TX_NO_SET_ERROR_SUMMARY_MASK (1<<ETH_TX_NO_SET_ERROR_SUMMARY_BIT)
  67431. +
  67432. +#define ETH_CAPTURE_TCP_FRAMES_ENABLE_BIT 14
  67433. +#define ETH_CAPTURE_TCP_FRAMES_ENABLE_MASK (1<<ETH_CAPTURE_TCP_FRAMES_ENABLE_BIT)
  67434. +
  67435. +#define ETH_CAPTURE_UDP_FRAMES_ENABLE_BIT 15
  67436. +#define ETH_CAPTURE_UDP_FRAMES_ENABLE_MASK (1<<ETH_CAPTURE_UDP_FRAMES_ENABLE_BIT)
  67437. +
  67438. +#define ETH_DEF_RX_TCP_QUEUE_OFFSET 16
  67439. +#define ETH_DEF_RX_TCP_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_TCP_QUEUE_OFFSET)
  67440. +#define ETH_DEF_RX_TCP_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_TCP_QUEUE_OFFSET)
  67441. +
  67442. +#define ETH_DEF_RX_UDP_QUEUE_OFFSET 19
  67443. +#define ETH_DEF_RX_UDP_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_UDP_QUEUE_OFFSET)
  67444. +#define ETH_DEF_RX_UDP_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_UDP_QUEUE_OFFSET)
  67445. +
  67446. +#define ETH_DEF_RX_BPDU_QUEUE_OFFSET 22
  67447. +#define ETH_DEF_RX_BPDU_QUEUE_ALL_MASK (0x7<<ETH_DEF_RX_BPDU_QUEUE_OFFSET)
  67448. +#define ETH_DEF_RX_BPDU_QUEUE_MASK(queue) ((queue)<<ETH_DEF_RX_BPDU_QUEUE_OFFSET)
  67449. +
  67450. +#define ETH_RX_CHECKSUM_MODE_OFFSET 25
  67451. +#define ETH_RX_CHECKSUM_NO_PSEUDO_HDR (0<<ETH_RX_CHECKSUM_MODE_OFFSET)
  67452. +#define ETH_RX_CHECKSUM_WITH_PSEUDO_HDR (1<<ETH_RX_CHECKSUM_MODE_OFFSET)
  67453. +
  67454. +/***** BITs of Port Configuration Extend reg (PxCXR) *****/
  67455. +#define ETH_CAPTURE_SPAN_BPDU_ENABLE_BIT 1
  67456. +#define ETH_CAPTURE_SPAN_BPDU_ENABLE_MASK (1<<ETH_CAPTURE_SPAN_BPDU_ENABLE_BIT)
  67457. +
  67458. +#define ETH_TX_DISABLE_GEN_CRC_BIT 3
  67459. +#define ETH_TX_DISABLE_GEN_CRC_MASK (1<<ETH_TX_DISABLE_GEN_CRC_BIT)
  67460. +
  67461. +/***** BITs of Tx/Rx queue command reg (RQCR/TQCR) *****/
  67462. +#define ETH_QUEUE_ENABLE_OFFSET 0
  67463. +#define ETH_QUEUE_ENABLE_ALL_MASK (0xFF<<ETH_QUEUE_ENABLE_OFFSET)
  67464. +#define ETH_QUEUE_ENABLE_MASK(queue) (1<<((queue)+ETH_QUEUE_ENABLE_OFFSET))
  67465. +
  67466. +#define ETH_QUEUE_DISABLE_OFFSET 8
  67467. +#define ETH_QUEUE_DISABLE_ALL_MASK (0xFF<<ETH_QUEUE_DISABLE_OFFSET)
  67468. +#define ETH_QUEUE_DISABLE_MASK(queue) (1<<((queue)+ETH_QUEUE_DISABLE_OFFSET))
  67469. +
  67470. +
  67471. +/***** BITs of Port Sdma Configuration reg (SDCR) *****/
  67472. +#define ETH_RX_FRAME_INTERRUPT_BIT 0
  67473. +#define ETH_RX_FRAME_INTERRUPT_MASK (1<<ETH_RX_FRAME_INTERRUPT_BIT)
  67474. +
  67475. +#define ETH_BURST_SIZE_1_64BIT_VALUE 0
  67476. +#define ETH_BURST_SIZE_2_64BIT_VALUE 1
  67477. +#define ETH_BURST_SIZE_4_64BIT_VALUE 2
  67478. +#define ETH_BURST_SIZE_8_64BIT_VALUE 3
  67479. +#define ETH_BURST_SIZE_16_64BIT_VALUE 4
  67480. +
  67481. +#define ETH_RX_BURST_SIZE_OFFSET 1
  67482. +#define ETH_RX_BURST_SIZE_ALL_MASK (0x7<<ETH_RX_BURST_SIZE_OFFSET)
  67483. +#define ETH_RX_BURST_SIZE_MASK(burst) ((burst)<<ETH_RX_BURST_SIZE_OFFSET)
  67484. +
  67485. +#define ETH_RX_NO_DATA_SWAP_BIT 4
  67486. +#define ETH_RX_NO_DATA_SWAP_MASK (1<<ETH_RX_NO_DATA_SWAP_BIT)
  67487. +#define ETH_RX_DATA_SWAP_MASK (0<<ETH_RX_NO_DATA_SWAP_BIT)
  67488. +
  67489. +#define ETH_TX_NO_DATA_SWAP_BIT 5
  67490. +#define ETH_TX_NO_DATA_SWAP_MASK (1<<ETH_TX_NO_DATA_SWAP_BIT)
  67491. +#define ETH_TX_DATA_SWAP_MASK (0<<ETH_TX_NO_DATA_SWAP_BIT)
  67492. +
  67493. +#define ETH_DESC_SWAP_BIT 6
  67494. +#define ETH_DESC_SWAP_MASK (1<<ETH_DESC_SWAP_BIT)
  67495. +#define ETH_NO_DESC_SWAP_MASK (0<<ETH_DESC_SWAP_BIT)
  67496. +
  67497. +#define ETH_RX_INTR_COAL_OFFSET 7
  67498. +#define ETH_RX_INTR_COAL_ALL_MASK (0x3fff<<ETH_RX_INTR_COAL_OFFSET)
  67499. +#define ETH_RX_INTR_COAL_MASK(value) (((value)<<ETH_RX_INTR_COAL_OFFSET) \
  67500. + & ETH_RX_INTR_COAL_ALL_MASK)
  67501. +
  67502. +#define ETH_TX_BURST_SIZE_OFFSET 22
  67503. +#define ETH_TX_BURST_SIZE_ALL_MASK (0x7<<ETH_TX_BURST_SIZE_OFFSET)
  67504. +#define ETH_TX_BURST_SIZE_MASK(burst) ((burst)<<ETH_TX_BURST_SIZE_OFFSET)
  67505. +
  67506. +#define ETH_RX_INTR_COAL_MSB_BIT 25
  67507. +#define ETH_RX_INTR_COAL_MSB_MASK (1<<ETH_RX_INTR_COAL_MSB_BIT)
  67508. +
  67509. +/* BITs Port #x Tx FIFO Urgent Threshold (PxTFUT) */
  67510. +#define ETH_TX_INTR_COAL_OFFSET 4
  67511. +#define ETH_TX_INTR_COAL_ALL_MASK (0x3fff << ETH_TX_INTR_COAL_OFFSET)
  67512. +#define ETH_TX_INTR_COAL_MASK(value) (((value) << ETH_TX_INTR_COAL_OFFSET) \
  67513. + & ETH_TX_INTR_COAL_ALL_MASK)
  67514. +
  67515. +/* BITs of Port Serial Control reg (PSCR) */
  67516. +#define ETH_PORT_ENABLE_BIT 0
  67517. +#define ETH_PORT_ENABLE_MASK (1<<ETH_PORT_ENABLE_BIT)
  67518. +
  67519. +#define ETH_FORCE_LINK_PASS_BIT 1
  67520. +#define ETH_FORCE_LINK_PASS_MASK (1<<ETH_FORCE_LINK_PASS_BIT)
  67521. +
  67522. +#define ETH_DISABLE_DUPLEX_AUTO_NEG_BIT 2
  67523. +#define ETH_DISABLE_DUPLEX_AUTO_NEG_MASK (1<<ETH_DISABLE_DUPLEX_AUTO_NEG_BIT)
  67524. +
  67525. +#define ETH_DISABLE_FC_AUTO_NEG_BIT 3
  67526. +#define ETH_DISABLE_FC_AUTO_NEG_MASK (1<<ETH_DISABLE_FC_AUTO_NEG_BIT)
  67527. +
  67528. +#define ETH_ADVERTISE_SYM_FC_BIT 4
  67529. +#define ETH_ADVERTISE_SYM_FC_MASK (1<<ETH_ADVERTISE_SYM_FC_BIT)
  67530. +
  67531. +#define ETH_TX_FC_MODE_OFFSET 5
  67532. +#define ETH_TX_FC_MODE_MASK (3<<ETH_TX_FC_MODE_OFFSET)
  67533. +#define ETH_TX_FC_NO_PAUSE (0<<ETH_TX_FC_MODE_OFFSET)
  67534. +#define ETH_TX_FC_SEND_PAUSE (1<<ETH_TX_FC_MODE_OFFSET)
  67535. +
  67536. +#define ETH_TX_BP_MODE_OFFSET 7
  67537. +#define ETH_TX_BP_MODE_MASK (3<<ETH_TX_BP_MODE_OFFSET)
  67538. +#define ETH_TX_BP_NO_JAM (0<<ETH_TX_BP_MODE_OFFSET)
  67539. +#define ETH_TX_BP_SEND_JAM (1<<ETH_TX_BP_MODE_OFFSET)
  67540. +
  67541. +#define ETH_DO_NOT_FORCE_LINK_FAIL_BIT 10
  67542. +#define ETH_DO_NOT_FORCE_LINK_FAIL_MASK (1<<ETH_DO_NOT_FORCE_LINK_FAIL_BIT)
  67543. +
  67544. +#define ETH_RETRANSMIT_FOREVER_BIT 11
  67545. +#define ETH_RETRANSMIT_FOREVER_MASK (1<<ETH_RETRANSMIT_FOREVER_BIT)
  67546. +
  67547. +#define ETH_DISABLE_SPEED_AUTO_NEG_BIT 13
  67548. +#define ETH_DISABLE_SPEED_AUTO_NEG_MASK (1<<ETH_DISABLE_SPEED_AUTO_NEG_BIT)
  67549. +
  67550. +#define ETH_DTE_ADVERT_BIT 14
  67551. +#define ETH_DTE_ADVERT_MASK (1<<ETH_DTE_ADVERT_BIT)
  67552. +
  67553. +#define ETH_MII_PHY_MODE_BIT 15
  67554. +#define ETH_MII_PHY_MODE_MAC (0<<ETH_MII_PHY_MODE_BIT)
  67555. +#define ETH_MII_PHY_MODE_PHY (1<<ETH_MII_PHY_MODE_BIT)
  67556. +
  67557. +#define ETH_MII_SOURCE_SYNCH_BIT 16
  67558. +#define ETH_MII_STANDARD_SYNCH (0<<ETH_MII_SOURCE_SYNCH_BIT)
  67559. +#define ETH_MII_400Mbps_SYNCH (1<<ETH_MII_SOURCE_CLK_BIT)
  67560. +
  67561. +#define ETH_MAX_RX_PACKET_SIZE_OFFSET 17
  67562. +#define ETH_MAX_RX_PACKET_SIZE_MASK (7<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  67563. +#define ETH_MAX_RX_PACKET_1518BYTE (0<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  67564. +#define ETH_MAX_RX_PACKET_1522BYTE (1<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  67565. +#define ETH_MAX_RX_PACKET_1552BYTE (2<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  67566. +#define ETH_MAX_RX_PACKET_9022BYTE (3<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  67567. +#define ETH_MAX_RX_PACKET_9192BYTE (4<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  67568. +#define ETH_MAX_RX_PACKET_9700BYTE (5<<ETH_MAX_RX_PACKET_SIZE_OFFSET)
  67569. +
  67570. +#define ETH_SET_FULL_DUPLEX_BIT 21
  67571. +#define ETH_SET_FULL_DUPLEX_MASK (1<<ETH_SET_FULL_DUPLEX_BIT)
  67572. +
  67573. +#define ETH_SET_FLOW_CTRL_BIT 22
  67574. +#define ETH_SET_FLOW_CTRL_MASK (1<<ETH_SET_FLOW_CTRL_BIT)
  67575. +
  67576. +#define ETH_SET_GMII_SPEED_1000_BIT 23
  67577. +#define ETH_SET_GMII_SPEED_1000_MASK (1<<ETH_SET_GMII_SPEED_1000_BIT)
  67578. +
  67579. +#define ETH_SET_MII_SPEED_100_BIT 24
  67580. +#define ETH_SET_MII_SPEED_100_MASK (1<<ETH_SET_MII_SPEED_100_BIT)
  67581. +
  67582. +/* BITs of Port Serial Control 1 reg (PSC1R) */
  67583. +#define ETH_PSC_ENABLE_BIT 2
  67584. +#define ETH_PSC_ENABLE_MASK (1<<ETH_PSC_ENABLE_BIT)
  67585. +
  67586. +#define ETH_RGMII_ENABLE_BIT 3
  67587. +#define ETH_RGMII_ENABLE_MASK (1<<ETH_RGMII_ENABLE_BIT)
  67588. +
  67589. +#define ETH_PORT_RESET_BIT 4
  67590. +#define ETH_PORT_RESET_MASK (1<<ETH_PORT_RESET_BIT)
  67591. +
  67592. +#define ETH_INBAND_AUTO_NEG_ENABLE_BIT 6
  67593. +#define ETH_INBAND_AUTO_NEG_ENABLE_MASK (1<<ETH_INBAND_AUTO_NEG_ENABLE_BIT)
  67594. +
  67595. +#define ETH_INBAND_AUTO_NEG_BYPASS_BIT 7
  67596. +#define ETH_INBAND_AUTO_NEG_BYPASS_MASK (1<<ETH_INBAND_AUTO_NEG_BYPASS_BIT)
  67597. +
  67598. +#define ETH_INBAND_AUTO_NEG_START_BIT 8
  67599. +#define ETH_INBAND_AUTO_NEG_START_MASK (1<<ETH_INBAND_AUTO_NEG_START_BIT)
  67600. +
  67601. +#define ETH_PORT_TYPE_BIT 11
  67602. +#define ETH_PORT_TYPE_1000BasedX_MASK (1<<ETH_PORT_TYPE_BIT)
  67603. +
  67604. +#define ETH_SGMII_MODE_BIT 12
  67605. +#define ETH_1000BaseX_MODE_MASK (0<<ETH_SGMII_MODE_BIT)
  67606. +#define ETH_SGMII_MODE_MASK (1<<ETH_SGMII_MODE_BIT)
  67607. +
  67608. +#define ETH_MGMII_MODE_BIT 13
  67609. +
  67610. +#define ETH_EN_MII_ODD_PRE_BIT 22
  67611. +#define ETH_EN_MII_ODD_PRE_MASK (1<<ETH_EN_MII_ODD_PRE_BIT)
  67612. +
  67613. +/* BITs of SDMA Descriptor Command/Status field */
  67614. +#if defined(MV_CPU_BE)
  67615. +typedef struct _ethRxDesc
  67616. +{
  67617. + MV_U16 byteCnt ; /* Descriptor buffer byte count */
  67618. + MV_U16 bufSize ; /* Buffer size */
  67619. + MV_U32 cmdSts ; /* Descriptor command status */
  67620. + MV_U32 nextDescPtr; /* Next descriptor pointer */
  67621. + MV_U32 bufPtr ; /* Descriptor buffer pointer */
  67622. + MV_ULONG returnInfo ; /* User resource return information */
  67623. +} ETH_RX_DESC;
  67624. +
  67625. +typedef struct _ethTxDesc
  67626. +{
  67627. + MV_U16 byteCnt ; /* Descriptor buffer byte count */
  67628. + MV_U16 L4iChk ; /* CPU provided TCP Checksum */
  67629. + MV_U32 cmdSts ; /* Descriptor command status */
  67630. + MV_U32 nextDescPtr; /* Next descriptor pointer */
  67631. + MV_U32 bufPtr ; /* Descriptor buffer pointer */
  67632. + MV_ULONG returnInfo ; /* User resource return information */
  67633. + MV_U8* alignBufPtr; /* Pointer to 8 byte aligned buffer */
  67634. +} ETH_TX_DESC;
  67635. +
  67636. +#elif defined(MV_CPU_LE)
  67637. +
  67638. +typedef struct _ethRxDesc
  67639. +{
  67640. + MV_U32 cmdSts ; /* Descriptor command status */
  67641. + MV_U16 bufSize ; /* Buffer size */
  67642. + MV_U16 byteCnt ; /* Descriptor buffer byte count */
  67643. + MV_U32 bufPtr ; /* Descriptor buffer pointer */
  67644. + MV_U32 nextDescPtr; /* Next descriptor pointer */
  67645. + MV_ULONG returnInfo ; /* User resource return information */
  67646. +} ETH_RX_DESC;
  67647. +
  67648. +typedef struct _ethTxDesc
  67649. +{
  67650. + MV_U32 cmdSts ; /* Descriptor command status */
  67651. + MV_U16 L4iChk ; /* CPU provided TCP Checksum */
  67652. + MV_U16 byteCnt ; /* Descriptor buffer byte count */
  67653. + MV_U32 bufPtr ; /* Descriptor buffer pointer */
  67654. + MV_U32 nextDescPtr; /* Next descriptor pointer */
  67655. + MV_ULONG returnInfo ; /* User resource return information */
  67656. + MV_U8* alignBufPtr; /* Pointer to 32 byte aligned buffer */
  67657. +} ETH_TX_DESC;
  67658. +
  67659. +#else
  67660. +#error "MV_CPU_BE or MV_CPU_LE must be defined"
  67661. +#endif /* MV_CPU_BE || MV_CPU_LE */
  67662. +
  67663. +/* Buffer offset from buffer pointer */
  67664. +#define ETH_RX_BUF_OFFSET 0x2
  67665. +
  67666. +
  67667. +/* Tx & Rx descriptor bits */
  67668. +#define ETH_ERROR_SUMMARY_BIT 0
  67669. +#define ETH_ERROR_SUMMARY_MASK (1<<ETH_ERROR_SUMMARY_BIT)
  67670. +
  67671. +#define ETH_BUFFER_OWNER_BIT 31
  67672. +#define ETH_BUFFER_OWNED_BY_DMA (1<<ETH_BUFFER_OWNER_BIT)
  67673. +#define ETH_BUFFER_OWNED_BY_HOST (0<<ETH_BUFFER_OWNER_BIT)
  67674. +
  67675. +/* Tx descriptor bits */
  67676. +#define ETH_TX_ERROR_CODE_OFFSET 1
  67677. +#define ETH_TX_ERROR_CODE_MASK (3<<ETH_TX_ERROR_CODE_OFFSET)
  67678. +#define ETH_TX_LATE_COLLISION_ERROR (0<<ETH_TX_ERROR_CODE_OFFSET)
  67679. +#define ETH_TX_UNDERRUN_ERROR (1<<ETH_TX_ERROR_CODE_OFFSET)
  67680. +#define ETH_TX_EXCESSIVE_COLLISION_ERROR (2<<ETH_TX_ERROR_CODE_OFFSET)
  67681. +
  67682. +#define ETH_TX_LLC_SNAP_FORMAT_BIT 9
  67683. +#define ETH_TX_LLC_SNAP_FORMAT_MASK (1<<ETH_TX_LLC_SNAP_FORMAT_BIT)
  67684. +
  67685. +#define ETH_TX_IP_FRAG_BIT 10
  67686. +#define ETH_TX_IP_FRAG_MASK (1<<ETH_TX_IP_FRAG_BIT)
  67687. +#define ETH_TX_IP_FRAG (0<<ETH_TX_IP_FRAG_BIT)
  67688. +#define ETH_TX_IP_NO_FRAG (1<<ETH_TX_IP_FRAG_BIT)
  67689. +
  67690. +#define ETH_TX_IP_HEADER_LEN_OFFSET 11
  67691. +#define ETH_TX_IP_HEADER_LEN_ALL_MASK (0xF<<ETH_TX_IP_HEADER_LEN_OFFSET)
  67692. +#define ETH_TX_IP_HEADER_LEN_MASK(len) ((len)<<ETH_TX_IP_HEADER_LEN_OFFSET)
  67693. +
  67694. +#define ETH_TX_VLAN_TAGGED_FRAME_BIT 15
  67695. +#define ETH_TX_VLAN_TAGGED_FRAME_MASK (1<<ETH_TX_VLAN_TAGGED_FRAME_BIT)
  67696. +
  67697. +#define ETH_TX_L4_TYPE_BIT 16
  67698. +#define ETH_TX_L4_TCP_TYPE (0<<ETH_TX_L4_TYPE_BIT)
  67699. +#define ETH_TX_L4_UDP_TYPE (1<<ETH_TX_L4_TYPE_BIT)
  67700. +
  67701. +#define ETH_TX_GENERATE_L4_CHKSUM_BIT 17
  67702. +#define ETH_TX_GENERATE_L4_CHKSUM_MASK (1<<ETH_TX_GENERATE_L4_CHKSUM_BIT)
  67703. +
  67704. +#define ETH_TX_GENERATE_IP_CHKSUM_BIT 18
  67705. +#define ETH_TX_GENERATE_IP_CHKSUM_MASK (1<<ETH_TX_GENERATE_IP_CHKSUM_BIT)
  67706. +
  67707. +#define ETH_TX_ZERO_PADDING_BIT 19
  67708. +#define ETH_TX_ZERO_PADDING_MASK (1<<ETH_TX_ZERO_PADDING_BIT)
  67709. +
  67710. +#define ETH_TX_LAST_DESC_BIT 20
  67711. +#define ETH_TX_LAST_DESC_MASK (1<<ETH_TX_LAST_DESC_BIT)
  67712. +
  67713. +#define ETH_TX_FIRST_DESC_BIT 21
  67714. +#define ETH_TX_FIRST_DESC_MASK (1<<ETH_TX_FIRST_DESC_BIT)
  67715. +
  67716. +#define ETH_TX_GENERATE_CRC_BIT 22
  67717. +#define ETH_TX_GENERATE_CRC_MASK (1<<ETH_TX_GENERATE_CRC_BIT)
  67718. +
  67719. +#define ETH_TX_ENABLE_INTERRUPT_BIT 23
  67720. +#define ETH_TX_ENABLE_INTERRUPT_MASK (1<<ETH_TX_ENABLE_INTERRUPT_BIT)
  67721. +
  67722. +#define ETH_TX_AUTO_MODE_BIT 30
  67723. +#define ETH_TX_AUTO_MODE_MASK (1<<ETH_TX_AUTO_MODE_BIT)
  67724. +
  67725. +
  67726. +/* Rx descriptor bits */
  67727. +#define ETH_RX_ERROR_CODE_OFFSET 1
  67728. +#define ETH_RX_ERROR_CODE_MASK (3<<ETH_RX_ERROR_CODE_OFFSET)
  67729. +#define ETH_RX_CRC_ERROR (0<<ETH_RX_ERROR_CODE_OFFSET)
  67730. +#define ETH_RX_OVERRUN_ERROR (1<<ETH_RX_ERROR_CODE_OFFSET)
  67731. +#define ETH_RX_MAX_FRAME_LEN_ERROR (2<<ETH_RX_ERROR_CODE_OFFSET)
  67732. +#define ETH_RX_RESOURCE_ERROR (3<<ETH_RX_ERROR_CODE_OFFSET)
  67733. +
  67734. +#define ETH_RX_L4_CHECKSUM_OFFSET 3
  67735. +#define ETH_RX_L4_CHECKSUM_MASK (0xffff<<ETH_RX_L4_CHECKSUM_OFFSET)
  67736. +
  67737. +#define ETH_RX_VLAN_TAGGED_FRAME_BIT 19
  67738. +#define ETH_RX_VLAN_TAGGED_FRAME_MASK (1<<ETH_RX_VLAN_TAGGED_FRAME_BIT)
  67739. +
  67740. +#define ETH_RX_BPDU_FRAME_BIT 20
  67741. +#define ETH_RX_BPDU_FRAME_MASK (1<<ETH_RX_BPDU_FRAME_BIT)
  67742. +
  67743. +#define ETH_RX_L4_TYPE_OFFSET 21
  67744. +#define ETH_RX_L4_TYPE_MASK (3<<ETH_RX_L4_TYPE_OFFSET)
  67745. +#define ETH_RX_L4_TCP_TYPE (0<<ETH_RX_L4_TYPE_OFFSET)
  67746. +#define ETH_RX_L4_UDP_TYPE (1<<ETH_RX_L4_TYPE_OFFSET)
  67747. +#define ETH_RX_L4_OTHER_TYPE (2<<ETH_RX_L4_TYPE_OFFSET)
  67748. +
  67749. +#define ETH_RX_NOT_LLC_SNAP_FORMAT_BIT 23
  67750. +#define ETH_RX_NOT_LLC_SNAP_FORMAT_MASK (1<<ETH_RX_NOT_LLC_SNAP_FORMAT_BIT)
  67751. +
  67752. +#define ETH_RX_IP_FRAME_TYPE_BIT 24
  67753. +#define ETH_RX_IP_FRAME_TYPE_MASK (1<<ETH_RX_IP_FRAME_TYPE_BIT)
  67754. +
  67755. +#define ETH_RX_IP_HEADER_OK_BIT 25
  67756. +#define ETH_RX_IP_HEADER_OK_MASK (1<<ETH_RX_IP_HEADER_OK_BIT)
  67757. +
  67758. +#define ETH_RX_LAST_DESC_BIT 26
  67759. +#define ETH_RX_LAST_DESC_MASK (1<<ETH_RX_LAST_DESC_BIT)
  67760. +
  67761. +#define ETH_RX_FIRST_DESC_BIT 27
  67762. +#define ETH_RX_FIRST_DESC_MASK (1<<ETH_RX_FIRST_DESC_BIT)
  67763. +
  67764. +#define ETH_RX_UNKNOWN_DA_BIT 28
  67765. +#define ETH_RX_UNKNOWN_DA_MASK (1<<ETH_RX_UNKNOWN_DA_BIT)
  67766. +
  67767. +#define ETH_RX_ENABLE_INTERRUPT_BIT 29
  67768. +#define ETH_RX_ENABLE_INTERRUPT_MASK (1<<ETH_RX_ENABLE_INTERRUPT_BIT)
  67769. +
  67770. +#define ETH_RX_L4_CHECKSUM_OK_BIT 30
  67771. +#define ETH_RX_L4_CHECKSUM_OK_MASK (1<<ETH_RX_L4_CHECKSUM_OK_BIT)
  67772. +
  67773. +/* Rx descriptor bufSize field */
  67774. +#define ETH_RX_IP_FRAGMENTED_FRAME_BIT 2
  67775. +#define ETH_RX_IP_FRAGMENTED_FRAME_MASK (1<<ETH_RX_IP_FRAGMENTED_FRAME_BIT)
  67776. +
  67777. +#define ETH_RX_BUFFER_MASK 0xFFF8
  67778. +
  67779. +
  67780. +/* Ethernet Cause Register BITs */
  67781. +#define ETH_CAUSE_RX_READY_SUM_BIT 0
  67782. +#define ETH_CAUSE_EXTEND_BIT 1
  67783. +
  67784. +#define ETH_CAUSE_RX_READY_OFFSET 2
  67785. +#define ETH_CAUSE_RX_READY_BIT(queue) (ETH_CAUSE_RX_READY_OFFSET + (queue))
  67786. +#define ETH_CAUSE_RX_READY_MASK(queue) (1 << (ETH_CAUSE_RX_READY_BIT(queue)))
  67787. +
  67788. +#define ETH_CAUSE_RX_ERROR_SUM_BIT 10
  67789. +#define ETH_CAUSE_RX_ERROR_OFFSET 11
  67790. +#define ETH_CAUSE_RX_ERROR_BIT(queue) (ETH_CAUSE_RX_ERROR_OFFSET + (queue))
  67791. +#define ETH_CAUSE_RX_ERROR_MASK(queue) (1 << (ETH_CAUSE_RX_ERROR_BIT(queue)))
  67792. +
  67793. +#define ETH_CAUSE_TX_END_BIT 19
  67794. +#define ETH_CAUSE_SUM_BIT 31
  67795. +
  67796. +/* Ethernet Cause Extended Register BITs */
  67797. +#define ETH_CAUSE_TX_BUF_OFFSET 0
  67798. +#define ETH_CAUSE_TX_BUF_BIT(queue) (ETH_CAUSE_TX_BUF_OFFSET + (queue))
  67799. +#define ETH_CAUSE_TX_BUF_MASK(queue) (1 << (ETH_CAUSE_TX_BUF_BIT(queue)))
  67800. +
  67801. +#define ETH_CAUSE_TX_ERROR_OFFSET 8
  67802. +#define ETH_CAUSE_TX_ERROR_BIT(queue) (ETH_CAUSE_TX_ERROR_OFFSET + (queue))
  67803. +#define ETH_CAUSE_TX_ERROR_MASK(queue) (1 << (ETH_CAUSE_TX_ERROR_BIT(queue)))
  67804. +
  67805. +#define ETH_CAUSE_PHY_STATUS_CHANGE_BIT 16
  67806. +#define ETH_CAUSE_RX_OVERRUN_BIT 18
  67807. +#define ETH_CAUSE_TX_UNDERRUN_BIT 19
  67808. +#define ETH_CAUSE_LINK_STATE_CHANGE_BIT 20
  67809. +#define ETH_CAUSE_INTERNAL_ADDR_ERR_BIT 23
  67810. +#define ETH_CAUSE_EXTEND_SUM_BIT 31
  67811. +
  67812. +/* Marvell Header Register */
  67813. +/* Marvell Header register bits */
  67814. +#define ETH_MVHDR_EN_BIT 0
  67815. +#define ETH_MVHDR_EN_MASK (1 << ETH_MVHDR_EN_BIT)
  67816. +
  67817. +#define ETH_MVHDR_DAPREFIX_BIT 1
  67818. +#define ETH_MVHDR_DAPREFIX_MASK (0x3 << ETH_MVHDR_DAPREFIX_BIT)
  67819. +#define ETH_MVHDR_DAPREFIX_PRI_1_2 (0x1 << ETH_MVHDR_DAPREFIX_BIT)
  67820. +#define ETH_MVHDR_DAPREFIX_DBNUM_PRI (0x2 << ETH_MVHDR_DAPREFIX_BIT)
  67821. +#define ETH_MVHDR_DAPREFIX_SPID_PRI (0x3 << ETH_MVHDR_DAPREFIX_BIT)
  67822. +
  67823. +#define ETH_MVHDR_MHMASK_BIT 8
  67824. +#define ETH_MVHDR_MHMASK_MASK (0x3 << ETH_MVHDR_MHMASK_BIT)
  67825. +#define ETH_MVHDR_MHMASK_8_QUEUE (0x0 << ETH_MVHDR_MHMASK_BIT)
  67826. +#define ETH_MVHDR_MHMASK_4_QUEUE (0x1 << ETH_MVHDR_MHMASK_BIT)
  67827. +#define ETH_MVHDR_MHMASK_2_QUEUE (0x3 << ETH_MVHDR_MHMASK_BIT)
  67828. +
  67829. +
  67830. +/* Relevant for 6183 ONLY */
  67831. +#define ETH_UNIT_PORTS_PADS_CALIB_0_REG (MV_ETH_REG_BASE(0) + 0x0A0)
  67832. +#define ETH_UNIT_PORTS_PADS_CALIB_1_REG (MV_ETH_REG_BASE(0) + 0x0A4)
  67833. +#define ETH_UNIT_PORTS_PADS_CALIB_2_REG (MV_ETH_REG_BASE(0) + 0x0A8)
  67834. +/* Ethernet Unit Ports Pads Calibration_REG (ETH_UNIT_PORTS_PADS_CALIB_x_REG) */
  67835. +#define ETH_ETHERNET_PAD_CLIB_DRVN_OFFS 0
  67836. +#define ETH_ETHERNET_PAD_CLIB_DRVN_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_DRVN_OFFS)
  67837. +
  67838. +#define ETH_ETHERNET_PAD_CLIB_DRVP_OFFS 5
  67839. +#define ETH_ETHERNET_PAD_CLIB_DRVP_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_DRVP_OFFS)
  67840. +
  67841. +#define ETH_ETHERNET_PAD_CLIB_TUNEEN_OFFS 16
  67842. +#define ETH_ETHERNET_PAD_CLIB_TUNEEN_MASK (0x1 << ETH_ETHERNET_PAD_CLIB_TUNEEN_OFFS)
  67843. +
  67844. +#define ETH_ETHERNET_PAD_CLIB_LOCKN_OFFS 17
  67845. +#define ETH_ETHERNET_PAD_CLIB_LOCKN_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_LOCKN_OFFS)
  67846. +
  67847. +#define ETH_ETHERNET_PAD_CLIB_OFFST_OFFS 24
  67848. +#define ETH_ETHERNET_PAD_CLIB_OFFST_MASK (0x1F << ETH_ETHERNET_PAD_CLIB_OFFST_OFFS)
  67849. +
  67850. +#define ETH_ETHERNET_PAD_CLIB_WR_EN_OFFS 31
  67851. +#define ETH_ETHERNET_PAD_CLIB_WR_EN_MASK (0x1 << ETH_ETHERNET_PAD_CLIB_WR_EN_OFFS)
  67852. +
  67853. +
  67854. +#ifdef __cplusplus
  67855. +}
  67856. +#endif /* __cplusplus */
  67857. +
  67858. +#endif /* __INCmvEthRegsh */
  67859. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h
  67860. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h 1970-01-01 01:00:00.000000000 +0100
  67861. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/eth/mvEth.h 2011-08-01 14:38:19.000000000 +0200
  67862. @@ -0,0 +1,356 @@
  67863. +/*******************************************************************************
  67864. +Copyright (C) Marvell International Ltd. and its affiliates
  67865. +
  67866. +This software file (the "File") is owned and distributed by Marvell
  67867. +International Ltd. and/or its affiliates ("Marvell") under the following
  67868. +alternative licensing terms. Once you have made an election to distribute the
  67869. +File under one of the following license alternatives, please (i) delete this
  67870. +introductory statement regarding license alternatives, (ii) delete the two
  67871. +license alternatives that you have not elected to use and (iii) preserve the
  67872. +Marvell copyright notice above.
  67873. +
  67874. +********************************************************************************
  67875. +Marvell Commercial License Option
  67876. +
  67877. +If you received this File from Marvell and you have entered into a commercial
  67878. +license agreement (a "Commercial License") with Marvell, the File is licensed
  67879. +to you under the terms of the applicable Commercial License.
  67880. +
  67881. +********************************************************************************
  67882. +Marvell GPL License Option
  67883. +
  67884. +If you received this File from Marvell, you may opt to use, redistribute and/or
  67885. +modify this File in accordance with the terms and conditions of the General
  67886. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  67887. +available along with the File in the license.txt file or by writing to the Free
  67888. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  67889. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  67890. +
  67891. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  67892. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  67893. +DISCLAIMED. The GPL License provides additional details about this warranty
  67894. +disclaimer.
  67895. +********************************************************************************
  67896. +Marvell BSD License Option
  67897. +
  67898. +If you received this File from Marvell, you may opt to use, redistribute and/or
  67899. +modify this File under the following licensing terms.
  67900. +Redistribution and use in source and binary forms, with or without modification,
  67901. +are permitted provided that the following conditions are met:
  67902. +
  67903. + * Redistributions of source code must retain the above copyright notice,
  67904. + this list of conditions and the following disclaimer.
  67905. +
  67906. + * Redistributions in binary form must reproduce the above copyright
  67907. + notice, this list of conditions and the following disclaimer in the
  67908. + documentation and/or other materials provided with the distribution.
  67909. +
  67910. + * Neither the name of Marvell nor the names of its contributors may be
  67911. + used to endorse or promote products derived from this software without
  67912. + specific prior written permission.
  67913. +
  67914. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  67915. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  67916. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  67917. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  67918. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  67919. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  67920. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  67921. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  67922. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  67923. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  67924. +
  67925. +*******************************************************************************/
  67926. +
  67927. +/*******************************************************************************
  67928. +* mvEth.h - Header File for : Ethernet Controller
  67929. +*
  67930. +* DESCRIPTION:
  67931. +* This header file contains macros typedefs and function declaration for
  67932. +* Marvell Gigabit Ethernet Controllers.
  67933. +*
  67934. +* DEPENDENCIES:
  67935. +* None.
  67936. +*
  67937. +*******************************************************************************/
  67938. +
  67939. +#ifndef __mvEth_h__
  67940. +#define __mvEth_h__
  67941. +
  67942. +/* includes */
  67943. +#include "mvTypes.h"
  67944. +#include "mv802_3.h"
  67945. +#include "ctrlEnv/mvCtrlEnvLib.h"
  67946. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  67947. +#include "eth/gbe/mvEthRegs.h"
  67948. +#include "mvSysHwConfig.h"
  67949. +
  67950. +/* defines */
  67951. +
  67952. +#define MV_ETH_EXTRA_FRAGS_NUM 2
  67953. +
  67954. +
  67955. +typedef enum
  67956. +{
  67957. + MV_ETH_SPEED_AN,
  67958. + MV_ETH_SPEED_10,
  67959. + MV_ETH_SPEED_100,
  67960. + MV_ETH_SPEED_1000
  67961. +
  67962. +} MV_ETH_PORT_SPEED;
  67963. +
  67964. +typedef enum
  67965. +{
  67966. + MV_ETH_DUPLEX_AN,
  67967. + MV_ETH_DUPLEX_HALF,
  67968. + MV_ETH_DUPLEX_FULL
  67969. +
  67970. +} MV_ETH_PORT_DUPLEX;
  67971. +
  67972. +typedef enum
  67973. +{
  67974. + MV_ETH_FC_AN_ADV_DIS,
  67975. + MV_ETH_FC_AN_ADV_SYM,
  67976. + MV_ETH_FC_DISABLE,
  67977. + MV_ETH_FC_ENABLE
  67978. +
  67979. +} MV_ETH_PORT_FC;
  67980. +
  67981. +typedef enum
  67982. +{
  67983. + MV_ETH_PRIO_FIXED = 0, /* Fixed priority mode */
  67984. + MV_ETH_PRIO_WRR = 1 /* Weighted round robin priority mode */
  67985. +} MV_ETH_PRIO_MODE;
  67986. +
  67987. +/* Ethernet port specific infomation */
  67988. +typedef struct
  67989. +{
  67990. + int maxRxPktSize;
  67991. + int rxDefQ;
  67992. + int rxBpduQ;
  67993. + int rxArpQ;
  67994. + int rxTcpQ;
  67995. + int rxUdpQ;
  67996. + int ejpMode;
  67997. +} MV_ETH_PORT_CFG;
  67998. +
  67999. +typedef struct
  68000. +{
  68001. + int descrNum;
  68002. +} MV_ETH_RX_Q_CFG;
  68003. +
  68004. +typedef struct
  68005. +{
  68006. + int descrNum;
  68007. + MV_ETH_PRIO_MODE prioMode;
  68008. + int quota;
  68009. +} MV_ETH_TX_Q_CFG;
  68010. +
  68011. +typedef struct
  68012. +{
  68013. + int maxRxPktSize;
  68014. + int rxDefQ;
  68015. + int txDescrNum[MV_ETH_TX_Q_NUM];
  68016. + int rxDescrNum[MV_ETH_RX_Q_NUM];
  68017. + void *osHandle;
  68018. +} MV_ETH_PORT_INIT;
  68019. +
  68020. +typedef struct
  68021. +{
  68022. + MV_BOOL isLinkUp;
  68023. + MV_ETH_PORT_SPEED speed;
  68024. + MV_ETH_PORT_DUPLEX duplex;
  68025. + MV_ETH_PORT_FC flowControl;
  68026. +
  68027. +} MV_ETH_PORT_STATUS;
  68028. +
  68029. +typedef enum
  68030. +{
  68031. + MV_ETH_DISABLE_HEADER_MODE = 0,
  68032. + MV_ETH_ENABLE_HEADER_MODE_PRI_2_1 = 1,
  68033. + MV_ETH_ENABLE_HEADER_MODE_PRI_DBNUM = 2,
  68034. + MV_ETH_ENABLE_HEADER_MODE_PRI_SPID = 3
  68035. +} MV_ETH_HEADER_MODE;
  68036. +
  68037. +
  68038. +/* ethernet.h API list */
  68039. +void mvEthHalInit(void);
  68040. +void mvEthMemAttrGet(MV_BOOL* pIsSram, MV_BOOL* pIsSwCoher);
  68041. +
  68042. +/* Port Initalization routines */
  68043. +void* mvEthPortInit (int port, MV_ETH_PORT_INIT *pPortInit);
  68044. +void ethResetTxDescRing(void* pPortHndl, int queue);
  68045. +void ethResetRxDescRing(void* pPortHndl, int queue);
  68046. +
  68047. +void* mvEthPortHndlGet(int port);
  68048. +
  68049. +void mvEthPortFinish(void* pEthPortHndl);
  68050. +MV_STATUS mvEthPortDown(void* pEthPortHndl);
  68051. +MV_STATUS mvEthPortDisable(void* pEthPortHndl);
  68052. +MV_STATUS mvEthPortUp(void* pEthPortHndl);
  68053. +MV_STATUS mvEthPortEnable(void* pEthPortHndl);
  68054. +
  68055. +/* Port data flow routines */
  68056. +MV_PKT_INFO *mvEthPortForceTxDone(void* pEthPortHndl, int txQueue);
  68057. +MV_PKT_INFO *mvEthPortForceRx(void* pEthPortHndl, int rxQueue);
  68058. +
  68059. +/* Port Configuration routines */
  68060. +MV_STATUS mvEthDefaultsSet(void* pEthPortHndl);
  68061. +MV_STATUS mvEthMaxRxSizeSet(void* pPortHndl, int maxRxSize);
  68062. +
  68063. +/* Port RX MAC Filtering control routines */
  68064. +MV_U8 mvEthMcastCrc8Get(MV_U8* pAddr);
  68065. +MV_STATUS mvEthRxFilterModeSet(void* pPortHndl, MV_BOOL isPromisc);
  68066. +MV_STATUS mvEthMacAddrSet(void* pPortHandle, MV_U8* pMacAddr, int queue);
  68067. +MV_STATUS mvEthMcastAddrSet(void* pPortHandle, MV_U8 *pAddr, int queue);
  68068. +
  68069. +/* MIB Counters APIs */
  68070. +MV_U32 mvEthMibCounterRead(void* pPortHndl, unsigned int mibOffset,
  68071. + MV_U32* pHigh32);
  68072. +void mvEthMibCountersClear(void* pPortHandle);
  68073. +
  68074. +/* TX Scheduling configuration routines */
  68075. +MV_STATUS mvEthTxQueueConfig(void* pPortHandle, int txQueue,
  68076. + MV_ETH_PRIO_MODE txPrioMode, int txQuota);
  68077. +
  68078. +/* RX Dispatching configuration routines */
  68079. +MV_STATUS mvEthBpduRxQueue(void* pPortHandle, int bpduQueue);
  68080. +MV_STATUS mvEthVlanPrioRxQueue(void* pPortHandle, int vlanPrio, int vlanPrioQueue);
  68081. +MV_STATUS mvEthTosToRxqSet(void* pPortHandle, int tos, int rxq);
  68082. +int mvEthTosToRxqGet(void* pPortHandle, int tos);
  68083. +
  68084. +/* Speed, Duplex, FlowControl routines */
  68085. +MV_STATUS mvEthSpeedDuplexSet(void* pPortHandle, MV_ETH_PORT_SPEED speed,
  68086. + MV_ETH_PORT_DUPLEX duplex);
  68087. +
  68088. +MV_STATUS mvEthFlowCtrlSet(void* pPortHandle, MV_ETH_PORT_FC flowControl);
  68089. +
  68090. +#if (MV_ETH_VERSION >= 4)
  68091. +MV_STATUS mvEthEjpModeSet(void* pPortHandle, int mode);
  68092. +#endif /* (MV_ETH_VERSION >= 4) */
  68093. +
  68094. +void mvEthStatusGet(void* pPortHandle, MV_ETH_PORT_STATUS* pStatus);
  68095. +
  68096. +/* Marvell Header control */
  68097. +MV_STATUS mvEthHeaderModeSet(void* pPortHandle, MV_ETH_HEADER_MODE headerMode);
  68098. +
  68099. +/* PHY routines */
  68100. +void mvEthPhyAddrSet(void* pPortHandle, int phyAddr);
  68101. +int mvEthPhyAddrGet(void* pPortHandle);
  68102. +
  68103. +/* Power management routines */
  68104. +void mvEthPortPowerDown(int port);
  68105. +void mvEthPortPowerUp(int port);
  68106. +
  68107. +/******************** ETH PRIVATE ************************/
  68108. +
  68109. +/*#define UNCACHED_TX_BUFFERS*/
  68110. +/*#define UNCACHED_RX_BUFFERS*/
  68111. +
  68112. +
  68113. +/* Port attributes */
  68114. +/* Size of a Tx/Rx descriptor used in chain list data structure */
  68115. +#define ETH_RX_DESC_ALIGNED_SIZE 32
  68116. +#define ETH_TX_DESC_ALIGNED_SIZE 32
  68117. +
  68118. +#define TX_DISABLE_TIMEOUT_MSEC 1000
  68119. +#define RX_DISABLE_TIMEOUT_MSEC 1000
  68120. +#define TX_FIFO_EMPTY_TIMEOUT_MSEC 10000
  68121. +#define PORT_DISABLE_WAIT_TCLOCKS 5000
  68122. +
  68123. +/* Macros that save access to desc in order to find next desc pointer */
  68124. +#define RX_NEXT_DESC_PTR(pRxDescr, pQueueCtrl) \
  68125. + ((pRxDescr) == (pQueueCtrl)->pLastDescr) ? \
  68126. + (ETH_RX_DESC*)((pQueueCtrl)->pFirstDescr) : \
  68127. + (ETH_RX_DESC*)(((MV_ULONG)(pRxDescr)) + ETH_RX_DESC_ALIGNED_SIZE)
  68128. +
  68129. +#define TX_NEXT_DESC_PTR(pTxDescr, pQueueCtrl) \
  68130. + ((pTxDescr) == (pQueueCtrl)->pLastDescr) ? \
  68131. + (ETH_TX_DESC*)((pQueueCtrl)->pFirstDescr) : \
  68132. + (ETH_TX_DESC*)(((MV_ULONG)(pTxDescr)) + ETH_TX_DESC_ALIGNED_SIZE)
  68133. +
  68134. +#define RX_PREV_DESC_PTR(pRxDescr, pQueueCtrl) \
  68135. + ((pRxDescr) == (pQueueCtrl)->pFirstDescr) ? \
  68136. + (ETH_RX_DESC*)((pQueueCtrl)->pLastDescr) : \
  68137. + (ETH_RX_DESC*)(((MV_ULONG)(pRxDescr)) - ETH_RX_DESC_ALIGNED_SIZE)
  68138. +
  68139. +#define TX_PREV_DESC_PTR(pTxDescr, pQueueCtrl) \
  68140. + ((pTxDescr) == (pQueueCtrl)->pFirstDescr) ? \
  68141. + (ETH_TX_DESC*)((pQueueCtrl)->pLastDescr) : \
  68142. + (ETH_TX_DESC*)(((MV_ULONG)(pTxDescr)) - ETH_TX_DESC_ALIGNED_SIZE)
  68143. +
  68144. +
  68145. +/* Queue specific information */
  68146. +typedef struct
  68147. +{
  68148. + void* pFirstDescr;
  68149. + void* pLastDescr;
  68150. + void* pCurrentDescr;
  68151. + void* pUsedDescr;
  68152. + int resource;
  68153. + MV_BUF_INFO descBuf;
  68154. +} ETH_QUEUE_CTRL;
  68155. +
  68156. +
  68157. +/* Ethernet port specific infomation */
  68158. +typedef struct _ethPortCtrl
  68159. +{
  68160. + int portNo;
  68161. + ETH_QUEUE_CTRL rxQueue[MV_ETH_RX_Q_NUM]; /* Rx ring resource */
  68162. + ETH_QUEUE_CTRL txQueue[MV_ETH_TX_Q_NUM]; /* Tx ring resource */
  68163. +
  68164. + MV_ETH_PORT_CFG portConfig;
  68165. + MV_ETH_RX_Q_CFG rxQueueConfig[MV_ETH_RX_Q_NUM];
  68166. + MV_ETH_TX_Q_CFG txQueueConfig[MV_ETH_TX_Q_NUM];
  68167. +
  68168. + /* Register images - For DP */
  68169. + MV_U32 portTxQueueCmdReg; /* Port active Tx queues summary */
  68170. + MV_U32 portRxQueueCmdReg; /* Port active Rx queues summary */
  68171. +
  68172. + MV_STATE portState;
  68173. +
  68174. + MV_U8 mcastCount[256];
  68175. + MV_U32* hashPtr;
  68176. + void *osHandle;
  68177. +} ETH_PORT_CTRL;
  68178. +
  68179. +/************** MACROs ****************/
  68180. +
  68181. +/* MACROs to Flush / Invalidate TX / RX Buffers */
  68182. +#if (ETHER_DRAM_COHER == MV_CACHE_COHER_SW) && !defined(UNCACHED_TX_BUFFERS)
  68183. +# define ETH_PACKET_CACHE_FLUSH(pAddr, size) \
  68184. + mvOsCacheClear(NULL, (pAddr), (size)); \
  68185. + /*CPU_PIPE_FLUSH;*/
  68186. +#else
  68187. +# define ETH_PACKET_CACHE_FLUSH(pAddr, size) \
  68188. + mvOsIoVirtToPhy(NULL, (pAddr));
  68189. +#endif /* ETHER_DRAM_COHER == MV_CACHE_COHER_SW */
  68190. +
  68191. +#if ( (ETHER_DRAM_COHER == MV_CACHE_COHER_SW) && !defined(UNCACHED_RX_BUFFERS) )
  68192. +# define ETH_PACKET_CACHE_INVALIDATE(pAddr, size) \
  68193. + mvOsCacheInvalidate (NULL, (pAddr), (size)); \
  68194. + /*CPU_PIPE_FLUSH;*/
  68195. +#else
  68196. +# define ETH_PACKET_CACHE_INVALIDATE(pAddr, size)
  68197. +#endif /* ETHER_DRAM_COHER == MV_CACHE_COHER_SW && !UNCACHED_RX_BUFFERS */
  68198. +
  68199. +#ifdef ETH_DESCR_UNCACHED
  68200. +
  68201. +#define ETH_DESCR_FLUSH_INV(pPortCtrl, pDescr)
  68202. +#define ETH_DESCR_INV(pPortCtrl, pDescr)
  68203. +
  68204. +#else
  68205. +
  68206. +#define ETH_DESCR_FLUSH_INV(pPortCtrl, pDescr) \
  68207. + mvOsCacheLineFlushInv(pPortCtrl->osHandle, (MV_ULONG)(pDescr))
  68208. +
  68209. +#define ETH_DESCR_INV(pPortCtrl, pDescr) \
  68210. + mvOsCacheLineInv(pPortCtrl->osHandle, (MV_ULONG)(pDescr))
  68211. +
  68212. +#endif /* ETH_DESCR_UNCACHED */
  68213. +
  68214. +#include "eth/gbe/mvEthGbe.h"
  68215. +
  68216. +#endif /* __mvEth_h__ */
  68217. +
  68218. +
  68219. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c
  68220. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c 1970-01-01 01:00:00.000000000 +0100
  68221. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.c 2011-08-01 14:38:19.000000000 +0200
  68222. @@ -0,0 +1,362 @@
  68223. +/*******************************************************************************
  68224. +Copyright (C) Marvell International Ltd. and its affiliates
  68225. +
  68226. +This software file (the "File") is owned and distributed by Marvell
  68227. +International Ltd. and/or its affiliates ("Marvell") under the following
  68228. +alternative licensing terms. Once you have made an election to distribute the
  68229. +File under one of the following license alternatives, please (i) delete this
  68230. +introductory statement regarding license alternatives, (ii) delete the two
  68231. +license alternatives that you have not elected to use and (iii) preserve the
  68232. +Marvell copyright notice above.
  68233. +
  68234. +********************************************************************************
  68235. +Marvell Commercial License Option
  68236. +
  68237. +If you received this File from Marvell and you have entered into a commercial
  68238. +license agreement (a "Commercial License") with Marvell, the File is licensed
  68239. +to you under the terms of the applicable Commercial License.
  68240. +
  68241. +********************************************************************************
  68242. +Marvell GPL License Option
  68243. +
  68244. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68245. +modify this File in accordance with the terms and conditions of the General
  68246. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  68247. +available along with the File in the license.txt file or by writing to the Free
  68248. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  68249. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  68250. +
  68251. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  68252. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  68253. +DISCLAIMED. The GPL License provides additional details about this warranty
  68254. +disclaimer.
  68255. +********************************************************************************
  68256. +Marvell BSD License Option
  68257. +
  68258. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68259. +modify this File under the following licensing terms.
  68260. +Redistribution and use in source and binary forms, with or without modification,
  68261. +are permitted provided that the following conditions are met:
  68262. +
  68263. + * Redistributions of source code must retain the above copyright notice,
  68264. + this list of conditions and the following disclaimer.
  68265. +
  68266. + * Redistributions in binary form must reproduce the above copyright
  68267. + notice, this list of conditions and the following disclaimer in the
  68268. + documentation and/or other materials provided with the distribution.
  68269. +
  68270. + * Neither the name of Marvell nor the names of its contributors may be
  68271. + used to endorse or promote products derived from this software without
  68272. + specific prior written permission.
  68273. +
  68274. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  68275. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  68276. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  68277. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  68278. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  68279. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  68280. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  68281. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  68282. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  68283. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  68284. +
  68285. +*******************************************************************************/
  68286. +
  68287. +#include "gpp/mvGpp.h"
  68288. +#include "ctrlEnv/mvCtrlEnvLib.h"
  68289. +/* defines */
  68290. +#ifdef MV_DEBUG
  68291. + #define DB(x) x
  68292. +#else
  68293. + #define DB(x)
  68294. +#endif
  68295. +
  68296. +static MV_VOID gppRegSet(MV_U32 group, MV_U32 regOffs,MV_U32 mask,MV_U32 value);
  68297. +
  68298. +/*******************************************************************************
  68299. +* mvGppTypeSet - Enable a GPP (OUT) pin
  68300. +*
  68301. +* DESCRIPTION:
  68302. +*
  68303. +* INPUT:
  68304. +* group - GPP group number
  68305. +* mask - 32bit mask value. Each set bit in the mask means that the type
  68306. +* of corresponding GPP will be set. Other GPPs are ignored.
  68307. +* value - 32bit value that describes GPP type per pin.
  68308. +*
  68309. +* OUTPUT:
  68310. +* None.
  68311. +*
  68312. +* EXAMPLE:
  68313. +* Set GPP8 to input and GPP15 to output.
  68314. +* mvGppTypeSet(0, (GPP8 | GPP15),
  68315. +* ((MV_GPP_IN & GPP8) | (MV_GPP_OUT & GPP15)) );
  68316. +*
  68317. +* RETURN:
  68318. +* None.
  68319. +*
  68320. +*******************************************************************************/
  68321. +MV_STATUS mvGppTypeSet(MV_U32 group, MV_U32 mask, MV_U32 value)
  68322. +{
  68323. + if (group >= MV_GPP_MAX_GROUP)
  68324. + {
  68325. + DB(mvOsPrintf("mvGppTypeSet: ERR. invalid group number \n"));
  68326. + return MV_BAD_PARAM;
  68327. + }
  68328. +
  68329. + gppRegSet(group, GPP_DATA_OUT_EN_REG(group), mask, value);
  68330. +
  68331. + /* Workaround for Erratum FE-MISC-70*/
  68332. + if(mvCtrlRevGet()==MV_88F6XXX_A0_REV && (group == 1))
  68333. + {
  68334. + mask &= 0x2;
  68335. + gppRegSet(0, GPP_DATA_OUT_EN_REG(0), mask, value);
  68336. + } /*End of WA*/
  68337. +
  68338. + return MV_OK;
  68339. +
  68340. +}
  68341. +
  68342. +/*******************************************************************************
  68343. +* mvGppBlinkEn - Set a GPP (IN) Pin list to blink every ~100ms
  68344. +*
  68345. +* DESCRIPTION:
  68346. +*
  68347. +* INPUT:
  68348. +* group - GPP group number
  68349. +* mask - 32bit mask value. Each set bit in the mask means that the type
  68350. +* of corresponding GPP will be set. Other GPPs are ignored.
  68351. +* value - 32bit value that describes GPP blink per pin.
  68352. +*
  68353. +* OUTPUT:
  68354. +* None.
  68355. +*
  68356. +* EXAMPLE:
  68357. +* Set GPP8 to be static and GPP15 to be blinking.
  68358. +* mvGppBlinkEn(0, (GPP8 | GPP15),
  68359. +* ((MV_GPP_OUT_STATIC & GPP8) | (MV_GPP_OUT_BLINK & GPP15)) );
  68360. +*
  68361. +* RETURN:
  68362. +* None.
  68363. +*
  68364. +*******************************************************************************/
  68365. +MV_STATUS mvGppBlinkEn(MV_U32 group, MV_U32 mask, MV_U32 value)
  68366. +{
  68367. + if (group >= MV_GPP_MAX_GROUP)
  68368. + {
  68369. + DB(mvOsPrintf("mvGppBlinkEn: ERR. invalid group number \n"));
  68370. + return MV_BAD_PARAM;
  68371. + }
  68372. +
  68373. + gppRegSet(group, GPP_BLINK_EN_REG(group), mask, value);
  68374. +
  68375. + return MV_OK;
  68376. +
  68377. +}
  68378. +/*******************************************************************************
  68379. +* mvGppPolaritySet - Set a GPP (IN) Pin list Polarity mode
  68380. +*
  68381. +* DESCRIPTION:
  68382. +*
  68383. +* INPUT:
  68384. +* group - GPP group number
  68385. +* mask - 32bit mask value. Each set bit in the mask means that the type
  68386. +* of corresponding GPP will be set. Other GPPs are ignored.
  68387. +* value - 32bit value that describes GPP polarity per pin.
  68388. +*
  68389. +* OUTPUT:
  68390. +* None.
  68391. +*
  68392. +* EXAMPLE:
  68393. +* Set GPP8 to the actual pin value and GPP15 to be inverted.
  68394. +* mvGppPolaritySet(0, (GPP8 | GPP15),
  68395. +* ((MV_GPP_IN_ORIGIN & GPP8) | (MV_GPP_IN_INVERT & GPP15)) );
  68396. +*
  68397. +* RETURN:
  68398. +* None.
  68399. +*
  68400. +*******************************************************************************/
  68401. +MV_STATUS mvGppPolaritySet(MV_U32 group, MV_U32 mask, MV_U32 value)
  68402. +{
  68403. + if (group >= MV_GPP_MAX_GROUP)
  68404. + {
  68405. + DB(mvOsPrintf("mvGppPolaritySet: ERR. invalid group number \n"));
  68406. + return MV_BAD_PARAM;
  68407. + }
  68408. +
  68409. + gppRegSet(group, GPP_DATA_IN_POL_REG(group), mask, value);
  68410. +
  68411. + return MV_OK;
  68412. +
  68413. +}
  68414. +
  68415. +/*******************************************************************************
  68416. +* mvGppPolarityGet - Get a value of relevant bits from GPP Polarity register.
  68417. +*
  68418. +* DESCRIPTION:
  68419. +*
  68420. +* INPUT:
  68421. +* group - GPP group number
  68422. +* mask - 32bit mask value. Each set bit in the mask means that the
  68423. +* returned value is valid for it.
  68424. +*
  68425. +* OUTPUT:
  68426. +* None.
  68427. +*
  68428. +* EXAMPLE:
  68429. +* Get GPP8 and GPP15 value.
  68430. +* mvGppPolarityGet(0, (GPP8 | GPP15));
  68431. +*
  68432. +* RETURN:
  68433. +* 32bit value that describes GPP polatity mode per pin.
  68434. +*
  68435. +*******************************************************************************/
  68436. +MV_U32 mvGppPolarityGet(MV_U32 group, MV_U32 mask)
  68437. +{
  68438. + MV_U32 regVal;
  68439. +
  68440. + if (group >= MV_GPP_MAX_GROUP)
  68441. + {
  68442. + DB(mvOsPrintf("mvGppActiveSet: Error invalid group number \n"));
  68443. + return MV_ERROR;
  68444. + }
  68445. + regVal = MV_REG_READ(GPP_DATA_IN_POL_REG(group));
  68446. +
  68447. + return (regVal & mask);
  68448. +}
  68449. +
  68450. +/*******************************************************************************
  68451. +* mvGppValueGet - Get a GPP Pin list value.
  68452. +*
  68453. +* DESCRIPTION:
  68454. +* This function get GPP value.
  68455. +*
  68456. +* INPUT:
  68457. +* group - GPP group number
  68458. +* mask - 32bit mask value. Each set bit in the mask means that the
  68459. +* returned value is valid for it.
  68460. +*
  68461. +* OUTPUT:
  68462. +* None.
  68463. +*
  68464. +* EXAMPLE:
  68465. +* Get GPP8 and GPP15 value.
  68466. +* mvGppValueGet(0, (GPP8 | GPP15));
  68467. +*
  68468. +* RETURN:
  68469. +* 32bit value that describes GPP activity mode per pin.
  68470. +*
  68471. +*******************************************************************************/
  68472. +MV_U32 mvGppValueGet(MV_U32 group, MV_U32 mask)
  68473. +{
  68474. + MV_U32 gppData;
  68475. +
  68476. + gppData = MV_REG_READ(GPP_DATA_IN_REG(group));
  68477. +
  68478. + gppData &= mask;
  68479. +
  68480. + return gppData;
  68481. +
  68482. +}
  68483. +
  68484. +/*******************************************************************************
  68485. +* mvGppValueSet - Set a GPP Pin list value.
  68486. +*
  68487. +* DESCRIPTION:
  68488. +* This function set value for given GPP pin list.
  68489. +*
  68490. +* INPUT:
  68491. +* group - GPP group number
  68492. +* mask - 32bit mask value. Each set bit in the mask means that the
  68493. +* value of corresponding GPP will be set accordingly. Other GPP
  68494. +* are not affected.
  68495. +* value - 32bit value that describes GPP value per pin.
  68496. +*
  68497. +* OUTPUT:
  68498. +* None.
  68499. +*
  68500. +* EXAMPLE:
  68501. +* Set GPP8 value of '0' and GPP15 value of '1'.
  68502. +* mvGppActiveSet(0, (GPP8 | GPP15), ((0 & GPP8) | (GPP15)) );
  68503. +*
  68504. +* RETURN:
  68505. +* None.
  68506. +*
  68507. +*******************************************************************************/
  68508. +MV_STATUS mvGppValueSet (MV_U32 group, MV_U32 mask, MV_U32 value)
  68509. +{
  68510. + MV_U32 outEnable, tmp;
  68511. + MV_U32 i;
  68512. +
  68513. + if (group >= MV_GPP_MAX_GROUP)
  68514. + {
  68515. + DB(mvOsPrintf("mvGppValueSet: Error invalid group number \n"));
  68516. + return MV_BAD_PARAM;
  68517. + }
  68518. +
  68519. + /* verify that the gpp pin is configured as output */
  68520. + /* Note that in the register out enabled -> bit = '0'. */
  68521. + outEnable = ~MV_REG_READ(GPP_DATA_OUT_EN_REG(group));
  68522. +
  68523. + /* Workaround for Erratum FE-MISC-70*/
  68524. + if(mvCtrlRevGet()==MV_88F6XXX_A0_REV && (group == 1))
  68525. + {
  68526. + tmp = ~MV_REG_READ(GPP_DATA_OUT_EN_REG(0));
  68527. + outEnable &= 0xfffffffd;
  68528. + outEnable |= (tmp & 0x2);
  68529. + } /*End of WA*/
  68530. +
  68531. + for (i = 0 ; i < 32 ;i++)
  68532. + {
  68533. + if (((mask & (1 << i)) & (outEnable & (1 << i))) != (mask & (1 << i)))
  68534. + {
  68535. + mvOsPrintf("mvGppValueSet: Err. An attempt to set output "\
  68536. + "value to GPP %d in input mode.\n", i);
  68537. + return MV_ERROR;
  68538. + }
  68539. + }
  68540. +
  68541. + gppRegSet(group, GPP_DATA_OUT_REG(group), mask, value);
  68542. +
  68543. + return MV_OK;
  68544. +
  68545. +}
  68546. +/*******************************************************************************
  68547. +* gppRegSet - Set a specific GPP pin on a specific GPP register
  68548. +*
  68549. +* DESCRIPTION:
  68550. +* This function set a specific GPP pin on a specific GPP register
  68551. +*
  68552. +* INPUT:
  68553. +* regOffs - GPP Register offset
  68554. +* group - GPP group number
  68555. +* mask - 32bit mask value. Each set bit in the mask means that the
  68556. +* value of corresponding GPP will be set accordingly. Other GPP
  68557. +* are not affected.
  68558. +* value - 32bit value that describes GPP value per pin.
  68559. +*
  68560. +* OUTPUT:
  68561. +* None.
  68562. +*
  68563. +* EXAMPLE:
  68564. +* Set GPP8 value of '0' and GPP15 value of '1'.
  68565. +* mvGppActiveSet(0, (GPP8 | GPP15), ((0 & GPP8) | (1 & GPP15)) );
  68566. +*
  68567. +* RETURN:
  68568. +* None.
  68569. +*
  68570. +*******************************************************************************/
  68571. +static MV_VOID gppRegSet (MV_U32 group, MV_U32 regOffs,MV_U32 mask,MV_U32 value)
  68572. +{
  68573. + MV_U32 gppData;
  68574. +
  68575. + gppData = MV_REG_READ(regOffs);
  68576. +
  68577. + gppData &= ~mask;
  68578. +
  68579. + gppData |= (value & mask);
  68580. +
  68581. + MV_REG_WRITE(regOffs, gppData);
  68582. +}
  68583. +
  68584. +
  68585. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h
  68586. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h 1970-01-01 01:00:00.000000000 +0100
  68587. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGpp.h 2011-08-01 14:38:19.000000000 +0200
  68588. @@ -0,0 +1,118 @@
  68589. +/*******************************************************************************
  68590. +Copyright (C) Marvell International Ltd. and its affiliates
  68591. +
  68592. +This software file (the "File") is owned and distributed by Marvell
  68593. +International Ltd. and/or its affiliates ("Marvell") under the following
  68594. +alternative licensing terms. Once you have made an election to distribute the
  68595. +File under one of the following license alternatives, please (i) delete this
  68596. +introductory statement regarding license alternatives, (ii) delete the two
  68597. +license alternatives that you have not elected to use and (iii) preserve the
  68598. +Marvell copyright notice above.
  68599. +
  68600. +********************************************************************************
  68601. +Marvell Commercial License Option
  68602. +
  68603. +If you received this File from Marvell and you have entered into a commercial
  68604. +license agreement (a "Commercial License") with Marvell, the File is licensed
  68605. +to you under the terms of the applicable Commercial License.
  68606. +
  68607. +********************************************************************************
  68608. +Marvell GPL License Option
  68609. +
  68610. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68611. +modify this File in accordance with the terms and conditions of the General
  68612. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  68613. +available along with the File in the license.txt file or by writing to the Free
  68614. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  68615. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  68616. +
  68617. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  68618. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  68619. +DISCLAIMED. The GPL License provides additional details about this warranty
  68620. +disclaimer.
  68621. +********************************************************************************
  68622. +Marvell BSD License Option
  68623. +
  68624. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68625. +modify this File under the following licensing terms.
  68626. +Redistribution and use in source and binary forms, with or without modification,
  68627. +are permitted provided that the following conditions are met:
  68628. +
  68629. + * Redistributions of source code must retain the above copyright notice,
  68630. + this list of conditions and the following disclaimer.
  68631. +
  68632. + * Redistributions in binary form must reproduce the above copyright
  68633. + notice, this list of conditions and the following disclaimer in the
  68634. + documentation and/or other materials provided with the distribution.
  68635. +
  68636. + * Neither the name of Marvell nor the names of its contributors may be
  68637. + used to endorse or promote products derived from this software without
  68638. + specific prior written permission.
  68639. +
  68640. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  68641. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  68642. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  68643. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  68644. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  68645. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  68646. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  68647. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  68648. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  68649. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  68650. +
  68651. +*******************************************************************************/
  68652. +
  68653. +#ifndef __INCmvGppH
  68654. +#define __INCmvGppH
  68655. +
  68656. +#include "mvCommon.h"
  68657. +#include "mvOs.h"
  68658. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  68659. +#include "gpp/mvGppRegs.h"
  68660. +
  68661. +/* These macros describes the GPP type. Each of the GPPs pins can */
  68662. +/* be assigned to act as a general purpose input or output pin. */
  68663. +#define MV_GPP_IN 0xFFFFFFFF /* GPP input */
  68664. +#define MV_GPP_OUT 0 /* GPP output */
  68665. +
  68666. +
  68667. +/* These macros describes the GPP Out Enable. */
  68668. +#define MV_GPP_OUT_DIS 0xFFFFFFFF /* Out pin disabled*/
  68669. +#define MV_GPP_OUT_EN 0 /* Out pin enabled*/
  68670. +
  68671. +/* These macros describes the GPP Out Blinking. */
  68672. +/* When set and the corresponding bit in GPIO Data Out Enable Control */
  68673. +/* Register is enabled, the GPIO pin blinks every ~100 ms (a period of */
  68674. +/* 2^24 TCLK clocks). */
  68675. +#define MV_GPP_OUT_BLINK 0xFFFFFFFF /* Out pin blinking*/
  68676. +#define MV_GPP_OUT_STATIC 0 /* Out pin static*/
  68677. +
  68678. +
  68679. +/* These macros describes the GPP Polarity. */
  68680. +/* When set to 1 GPIO Data In Register reflects the inverted value of the */
  68681. +/* corresponding pin. */
  68682. +
  68683. +#define MV_GPP_IN_INVERT 0xFFFFFFFF /* Inverted value is got*/
  68684. +#define MV_GPP_IN_ORIGIN 0 /* original value is got*/
  68685. +
  68686. +/* mvGppTypeSet - Set PP pin mode (IN or OUT) */
  68687. +MV_STATUS mvGppTypeSet(MV_U32 group, MV_U32 mask, MV_U32 value);
  68688. +
  68689. +/* mvGppBlinkEn - Set a GPP (IN) Pin list to blink every ~100ms */
  68690. +MV_STATUS mvGppBlinkEn(MV_U32 group, MV_U32 mask, MV_U32 value);
  68691. +
  68692. +/* mvGppPolaritySet - Set a GPP (IN) Pin list Polarity mode. */
  68693. +MV_STATUS mvGppPolaritySet(MV_U32 group, MV_U32 mask, MV_U32 value);
  68694. +
  68695. +/* mvGppPolarityGet - Get the Polarity of a GPP Pin */
  68696. +MV_U32 mvGppPolarityGet(MV_U32 group, MV_U32 mask);
  68697. +
  68698. +/* mvGppValueGet - Get a GPP Pin list value.*/
  68699. +MV_U32 mvGppValueGet(MV_U32 group, MV_U32 mask);
  68700. +
  68701. +
  68702. +/* mvGppValueSet - Set a GPP Pin list value. */
  68703. +MV_STATUS mvGppValueSet (MV_U32 group, MV_U32 mask, MV_U32 value);
  68704. +
  68705. +#endif /* #ifndef __INCmvGppH */
  68706. +
  68707. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h
  68708. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h 1970-01-01 01:00:00.000000000 +0100
  68709. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/gpp/mvGppRegs.h 2011-08-01 14:38:19.000000000 +0200
  68710. @@ -0,0 +1,116 @@
  68711. +/*******************************************************************************
  68712. +Copyright (C) Marvell International Ltd. and its affiliates
  68713. +
  68714. +This software file (the "File") is owned and distributed by Marvell
  68715. +International Ltd. and/or its affiliates ("Marvell") under the following
  68716. +alternative licensing terms. Once you have made an election to distribute the
  68717. +File under one of the following license alternatives, please (i) delete this
  68718. +introductory statement regarding license alternatives, (ii) delete the two
  68719. +license alternatives that you have not elected to use and (iii) preserve the
  68720. +Marvell copyright notice above.
  68721. +
  68722. +********************************************************************************
  68723. +Marvell Commercial License Option
  68724. +
  68725. +If you received this File from Marvell and you have entered into a commercial
  68726. +license agreement (a "Commercial License") with Marvell, the File is licensed
  68727. +to you under the terms of the applicable Commercial License.
  68728. +
  68729. +********************************************************************************
  68730. +Marvell GPL License Option
  68731. +
  68732. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68733. +modify this File in accordance with the terms and conditions of the General
  68734. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  68735. +available along with the File in the license.txt file or by writing to the Free
  68736. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  68737. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  68738. +
  68739. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  68740. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  68741. +DISCLAIMED. The GPL License provides additional details about this warranty
  68742. +disclaimer.
  68743. +********************************************************************************
  68744. +Marvell BSD License Option
  68745. +
  68746. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68747. +modify this File under the following licensing terms.
  68748. +Redistribution and use in source and binary forms, with or without modification,
  68749. +are permitted provided that the following conditions are met:
  68750. +
  68751. + * Redistributions of source code must retain the above copyright notice,
  68752. + this list of conditions and the following disclaimer.
  68753. +
  68754. + * Redistributions in binary form must reproduce the above copyright
  68755. + notice, this list of conditions and the following disclaimer in the
  68756. + documentation and/or other materials provided with the distribution.
  68757. +
  68758. + * Neither the name of Marvell nor the names of its contributors may be
  68759. + used to endorse or promote products derived from this software without
  68760. + specific prior written permission.
  68761. +
  68762. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  68763. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  68764. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  68765. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  68766. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  68767. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  68768. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  68769. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  68770. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  68771. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  68772. +
  68773. +*******************************************************************************/
  68774. +
  68775. +#ifndef __INCmvGppRegsH
  68776. +#define __INCmvGppRegsH
  68777. +
  68778. +#define MV_GPP0 BIT0
  68779. +#define MV_GPP1 BIT1
  68780. +#define MV_GPP2 BIT2
  68781. +#define MV_GPP3 BIT3
  68782. +#define MV_GPP4 BIT4
  68783. +#define MV_GPP5 BIT5
  68784. +#define MV_GPP6 BIT6
  68785. +#define MV_GPP7 BIT7
  68786. +#define MV_GPP8 BIT8
  68787. +#define MV_GPP9 BIT9
  68788. +#define MV_GPP10 BIT10
  68789. +#define MV_GPP11 BIT11
  68790. +#define MV_GPP12 BIT12
  68791. +#define MV_GPP13 BIT13
  68792. +#define MV_GPP14 BIT14
  68793. +#define MV_GPP15 BIT15
  68794. +#define MV_GPP16 BIT16
  68795. +#define MV_GPP17 BIT17
  68796. +#define MV_GPP18 BIT18
  68797. +#define MV_GPP19 BIT19
  68798. +#define MV_GPP20 BIT20
  68799. +#define MV_GPP21 BIT21
  68800. +#define MV_GPP22 BIT22
  68801. +#define MV_GPP23 BIT23
  68802. +#define MV_GPP24 BIT24
  68803. +#define MV_GPP25 BIT25
  68804. +#define MV_GPP26 BIT26
  68805. +#define MV_GPP27 BIT27
  68806. +#define MV_GPP28 BIT28
  68807. +#define MV_GPP29 BIT29
  68808. +#define MV_GPP30 BIT30
  68809. +#define MV_GPP31 BIT31
  68810. +
  68811. +
  68812. +/* registers offsets */
  68813. +
  68814. +#define GPP_DATA_OUT_REG(grp) ((grp == 0) ? 0x10100 : 0x10140)
  68815. +#define GPP_DATA_OUT_EN_REG(grp) ((grp == 0) ? 0x10104 : 0x10144)
  68816. +#define GPP_BLINK_EN_REG(grp) ((grp == 0) ? 0x10108 : 0x10148)
  68817. +#define GPP_DATA_IN_POL_REG(grp) ((grp == 0) ? 0x1010C : 0x1014c)
  68818. +#define GPP_DATA_IN_REG(grp) ((grp == 0) ? 0x10110 : 0x10150)
  68819. +#define GPP_INT_CAUSE_REG(grp) ((grp == 0) ? 0x10114 : 0x10154)
  68820. +#define GPP_INT_MASK_REG(grp) ((grp == 0) ? 0x10118 : 0x10158)
  68821. +#define GPP_INT_LVL_REG(grp) ((grp == 0) ? 0x1011c : 0x1015c)
  68822. +
  68823. +#define GPP_DATA_OUT_SET_REG 0x10120
  68824. +#define GPP_DATA_OUT_CLEAR_REG 0x10124
  68825. +
  68826. +#endif /* #ifndef __INCmvGppRegsH */
  68827. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c
  68828. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c 1970-01-01 01:00:00.000000000 +0100
  68829. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.c 2011-08-01 14:38:19.000000000 +0200
  68830. @@ -0,0 +1,1047 @@
  68831. +/*******************************************************************************
  68832. +Copyright (C) Marvell International Ltd. and its affiliates
  68833. +
  68834. +This software file (the "File") is owned and distributed by Marvell
  68835. +International Ltd. and/or its affiliates ("Marvell") under the following
  68836. +alternative licensing terms. Once you have made an election to distribute the
  68837. +File under one of the following license alternatives, please (i) delete this
  68838. +introductory statement regarding license alternatives, (ii) delete the two
  68839. +license alternatives that you have not elected to use and (iii) preserve the
  68840. +Marvell copyright notice above.
  68841. +
  68842. +********************************************************************************
  68843. +Marvell Commercial License Option
  68844. +
  68845. +If you received this File from Marvell and you have entered into a commercial
  68846. +license agreement (a "Commercial License") with Marvell, the File is licensed
  68847. +to you under the terms of the applicable Commercial License.
  68848. +
  68849. +********************************************************************************
  68850. +Marvell GPL License Option
  68851. +
  68852. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68853. +modify this File in accordance with the terms and conditions of the General
  68854. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  68855. +available along with the File in the license.txt file or by writing to the Free
  68856. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  68857. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  68858. +
  68859. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  68860. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  68861. +DISCLAIMED. The GPL License provides additional details about this warranty
  68862. +disclaimer.
  68863. +********************************************************************************
  68864. +Marvell BSD License Option
  68865. +
  68866. +If you received this File from Marvell, you may opt to use, redistribute and/or
  68867. +modify this File under the following licensing terms.
  68868. +Redistribution and use in source and binary forms, with or without modification,
  68869. +are permitted provided that the following conditions are met:
  68870. +
  68871. + * Redistributions of source code must retain the above copyright notice,
  68872. + this list of conditions and the following disclaimer.
  68873. +
  68874. + * Redistributions in binary form must reproduce the above copyright
  68875. + notice, this list of conditions and the following disclaimer in the
  68876. + documentation and/or other materials provided with the distribution.
  68877. +
  68878. + * Neither the name of Marvell nor the names of its contributors may be
  68879. + used to endorse or promote products derived from this software without
  68880. + specific prior written permission.
  68881. +
  68882. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  68883. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  68884. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  68885. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  68886. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  68887. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  68888. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  68889. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  68890. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  68891. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  68892. +
  68893. +*******************************************************************************/
  68894. +#include "pci/mvPci.h"
  68895. +
  68896. +#include "ctrlEnv/mvCtrlEnvLib.h"
  68897. +
  68898. +/* defines */
  68899. +#ifdef MV_DEBUG
  68900. + #define DB(x) x
  68901. +#else
  68902. + #define DB(x)
  68903. +#endif
  68904. +
  68905. +
  68906. +
  68907. +MV_VOID mvPciHalInit(MV_U32 pciIf, MV_PCI_MOD pciIfmod)
  68908. +{
  68909. + if (MV_PCI_MOD_HOST == pciIfmod)
  68910. + {
  68911. +
  68912. + mvPciLocalBusNumSet(pciIf, PCI_HOST_BUS_NUM(pciIf));
  68913. + mvPciLocalDevNumSet(pciIf, PCI_HOST_DEV_NUM(pciIf));
  68914. +
  68915. + /* Local device master Enable */
  68916. + mvPciMasterEnable(pciIf, MV_TRUE);
  68917. +
  68918. + /* Local device slave Enable */
  68919. + mvPciSlaveEnable(pciIf, mvPciLocalBusNumGet(pciIf),
  68920. + mvPciLocalDevNumGet(pciIf), MV_TRUE);
  68921. + }
  68922. + /* enable CPU-2-PCI ordering */
  68923. + MV_REG_BIT_SET(PCI_CMD_REG(0), PCR_CPU_TO_PCI_ORDER_EN);
  68924. +}
  68925. +
  68926. +/*******************************************************************************
  68927. +* mvPciCommandSet - Set PCI comman register value.
  68928. +*
  68929. +* DESCRIPTION:
  68930. +* This function sets a given PCI interface with its command register
  68931. +* value.
  68932. +*
  68933. +* INPUT:
  68934. +* pciIf - PCI interface number.
  68935. +* command - 32bit value to be written to comamnd register.
  68936. +*
  68937. +* OUTPUT:
  68938. +* None.
  68939. +*
  68940. +* RETURN:
  68941. +* MV_BAD_PARAM if pciIf is not in range otherwise MV_OK
  68942. +*
  68943. +*******************************************************************************/
  68944. +MV_STATUS mvPciCommandSet(MV_U32 pciIf, MV_U32 command)
  68945. +{
  68946. + MV_U32 locBusNum, locDevNum, regVal;
  68947. +
  68948. + locBusNum = mvPciLocalBusNumGet(pciIf);
  68949. + locDevNum = mvPciLocalDevNumGet(pciIf);
  68950. +
  68951. + /* Parameter checking */
  68952. + if (pciIf >= mvCtrlPciMaxIfGet())
  68953. + {
  68954. + mvOsPrintf("mvPciCommandSet: ERR. Invalid PCI IF num %d\n", pciIf);
  68955. + return MV_BAD_PARAM;
  68956. + }
  68957. +
  68958. + /* Set command register */
  68959. + MV_REG_WRITE(PCI_CMD_REG(pciIf), command);
  68960. +
  68961. + /* Upodate device max outstanding split tarnsaction */
  68962. + if ((command & PCR_CPU_TO_PCI_ORDER_EN) &&
  68963. + (command & PCR_PCI_TO_CPU_ORDER_EN))
  68964. + {
  68965. + /* Read PCI-X command register */
  68966. + regVal = mvPciConfigRead (pciIf, locBusNum, locDevNum, 0, PCIX_COMMAND);
  68967. +
  68968. + /* clear bits 22:20 */
  68969. + regVal &= 0xff8fffff;
  68970. +
  68971. + /* set reset value */
  68972. + regVal |= (0x3 << 20);
  68973. +
  68974. + /* Write back the value */
  68975. + mvPciConfigWrite (pciIf, locBusNum, locDevNum, 0, PCIX_COMMAND, regVal);
  68976. + }
  68977. +
  68978. + return MV_OK;
  68979. +
  68980. +
  68981. +}
  68982. +
  68983. +
  68984. +/*******************************************************************************
  68985. +* mvPciModeGet - Get PCI interface mode.
  68986. +*
  68987. +* DESCRIPTION:
  68988. +* This function returns the given PCI interface mode.
  68989. +*
  68990. +* INPUT:
  68991. +* pciIf - PCI interface number.
  68992. +*
  68993. +* OUTPUT:
  68994. +* pPciMode - Pointer to PCI mode structure.
  68995. +*
  68996. +* RETURN:
  68997. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  68998. +*
  68999. +*******************************************************************************/
  69000. +MV_STATUS mvPciModeGet(MV_U32 pciIf, MV_PCI_MODE *pPciMode)
  69001. +{
  69002. + MV_U32 pciMode;
  69003. +
  69004. + /* Parameter checking */
  69005. + if (pciIf >= mvCtrlPciMaxIfGet())
  69006. + {
  69007. + mvOsPrintf("mvPciModeGet: ERR. Invalid PCI interface %d\n", pciIf);
  69008. + return MV_BAD_PARAM;
  69009. + }
  69010. + if (NULL == pPciMode)
  69011. + {
  69012. + mvOsPrintf("mvPciModeGet: ERR. pPciMode = NULL \n");
  69013. + return MV_BAD_PARAM;
  69014. + }
  69015. +
  69016. + /* Read pci mode register */
  69017. + pciMode = MV_REG_READ(PCI_MODE_REG(pciIf));
  69018. +
  69019. + switch (pciMode & PMR_PCI_MODE_MASK)
  69020. + {
  69021. + case PMR_PCI_MODE_CONV:
  69022. + pPciMode->pciType = MV_PCI_CONV;
  69023. +
  69024. + if (MV_REG_READ(PCI_DLL_CTRL_REG(pciIf)) & PDC_DLL_EN)
  69025. + {
  69026. + pPciMode->pciSpeed = 66000000; /* 66MHZ */
  69027. + }
  69028. + else
  69029. + {
  69030. + pPciMode->pciSpeed = 33000000; /* 33MHZ */
  69031. + }
  69032. +
  69033. + break;
  69034. +
  69035. + case PMR_PCI_MODE_PCIX_66MHZ:
  69036. + pPciMode->pciType = MV_PCIX;
  69037. + pPciMode->pciSpeed = 66000000; /* 66MHZ */
  69038. + break;
  69039. +
  69040. + case PMR_PCI_MODE_PCIX_100MHZ:
  69041. + pPciMode->pciType = MV_PCIX;
  69042. + pPciMode->pciSpeed = 100000000; /* 100MHZ */
  69043. + break;
  69044. +
  69045. + case PMR_PCI_MODE_PCIX_133MHZ:
  69046. + pPciMode->pciType = MV_PCIX;
  69047. + pPciMode->pciSpeed = 133000000; /* 133MHZ */
  69048. + break;
  69049. +
  69050. + default:
  69051. + {
  69052. + mvOsPrintf("mvPciModeGet: ERR. Non existing mode !!\n");
  69053. + return MV_ERROR;
  69054. + }
  69055. + }
  69056. +
  69057. + switch (pciMode & PMR_PCI_64_MASK)
  69058. + {
  69059. + case PMR_PCI_64_64BIT:
  69060. + pPciMode->pciWidth = MV_PCI_64;
  69061. + break;
  69062. +
  69063. + case PMR_PCI_64_32BIT:
  69064. + pPciMode->pciWidth = MV_PCI_32;
  69065. + break;
  69066. +
  69067. + default:
  69068. + {
  69069. + mvOsPrintf("mvPciModeGet: ERR. Non existing mode !!\n");
  69070. + return MV_ERROR;
  69071. + }
  69072. + }
  69073. +
  69074. + return MV_OK;
  69075. +}
  69076. +
  69077. +/*******************************************************************************
  69078. +* mvPciRetrySet - Set PCI retry counters
  69079. +*
  69080. +* DESCRIPTION:
  69081. +* This function specifies the number of times the PCI controller
  69082. +* retries a transaction before it quits.
  69083. +* Applies to the PCI Master when acting as a requester.
  69084. +* Applies to the PCI slave when acting as a completer (PCI-X mode).
  69085. +* A 0x00 value means a "retry forever".
  69086. +*
  69087. +* INPUT:
  69088. +* pciIf - PCI interface number.
  69089. +* counter - Number of times PCI controller retry. Use counter value
  69090. +* up to PRR_RETRY_CNTR_MAX.
  69091. +*
  69092. +* OUTPUT:
  69093. +* None.
  69094. +*
  69095. +* RETURN:
  69096. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  69097. +*
  69098. +*******************************************************************************/
  69099. +MV_STATUS mvPciRetrySet(MV_U32 pciIf, MV_U32 counter)
  69100. +{
  69101. + MV_U32 pciRetry;
  69102. +
  69103. + /* Parameter checking */
  69104. + if (pciIf >= mvCtrlPciMaxIfGet())
  69105. + {
  69106. + mvOsPrintf("mvPciRetrySet: ERR. Invalid PCI interface %d\n", pciIf);
  69107. + return MV_BAD_PARAM;
  69108. + }
  69109. +
  69110. + if (counter >= PRR_RETRY_CNTR_MAX)
  69111. + {
  69112. + mvOsPrintf("mvPciRetrySet: ERR. Invalid counter: %d\n", counter);
  69113. + return MV_BAD_PARAM;
  69114. +
  69115. + }
  69116. +
  69117. + /* Reading PCI retry register */
  69118. + pciRetry = MV_REG_READ(PCI_RETRY_REG(pciIf));
  69119. +
  69120. + pciRetry &= ~PRR_RETRY_CNTR_MASK;
  69121. +
  69122. + pciRetry |= (counter << PRR_RETRY_CNTR_OFFS);
  69123. +
  69124. + /* write new value */
  69125. + MV_REG_WRITE(PCI_RETRY_REG(pciIf), pciRetry);
  69126. +
  69127. + return MV_OK;
  69128. +}
  69129. +
  69130. +
  69131. +/*******************************************************************************
  69132. +* mvPciDiscardTimerSet - Set PCI discard timer
  69133. +*
  69134. +* DESCRIPTION:
  69135. +* This function set PCI discard timer.
  69136. +* In conventional PCI mode:
  69137. +* Specifies the number of PCLK cycles the PCI slave keeps a non-accessed
  69138. +* read buffers (non-completed delayed read) before invalidate the buffer.
  69139. +* Set to '0' to disable the timer. The PCI slave waits for delayed
  69140. +* read completion forever.
  69141. +* In PCI-X mode:
  69142. +* Specifies the number of PCLK cycles the PCI master waits for split
  69143. +* completion transaction, before it invalidates the pre-allocated read
  69144. +* buffer.
  69145. +* Set to '0' to disable the timer. The PCI master waits for split
  69146. +* completion forever.
  69147. +* NOTE: Must be set to a number greater than MV_PCI_MAX_DISCARD_CLK,
  69148. +* unless using the "wait for ever" setting 0x0.
  69149. +* NOTE: Must not be updated while there are pending read requests.
  69150. +*
  69151. +* INPUT:
  69152. +* pciIf - PCI interface number.
  69153. +* pClkCycles - Number of PCI clock cycles.
  69154. +*
  69155. +* OUTPUT:
  69156. +* None.
  69157. +*
  69158. +* RETURN:
  69159. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  69160. +*
  69161. +*******************************************************************************/
  69162. +MV_STATUS mvPciDiscardTimerSet(MV_U32 pciIf, MV_U32 pClkCycles)
  69163. +{
  69164. + MV_U32 pciDiscardTimer;
  69165. +
  69166. + /* Parameter checking */
  69167. + if (pciIf >= mvCtrlPciMaxIfGet())
  69168. + {
  69169. + mvOsPrintf("mvPciDiscardTimerSet: ERR. Invalid PCI interface %d\n",
  69170. + pciIf);
  69171. + return MV_BAD_PARAM;
  69172. + }
  69173. +
  69174. + if (pClkCycles >= PDTR_TIMER_MIN)
  69175. + {
  69176. + mvOsPrintf("mvPciDiscardTimerSet: ERR. Invalid Clk value: %d\n",
  69177. + pClkCycles);
  69178. + return MV_BAD_PARAM;
  69179. +
  69180. + }
  69181. +
  69182. + /* Read PCI Discard Timer */
  69183. + pciDiscardTimer = MV_REG_READ(PCI_DISCARD_TIMER_REG(pciIf));
  69184. +
  69185. + pciDiscardTimer &= ~PDTR_TIMER_MASK;
  69186. +
  69187. + pciDiscardTimer |= (pClkCycles << PDTR_TIMER_OFFS);
  69188. +
  69189. + /* Write new value */
  69190. + MV_REG_WRITE(PCI_DISCARD_TIMER_REG(pciIf), pciDiscardTimer);
  69191. +
  69192. + return MV_OK;
  69193. +
  69194. +}
  69195. +
  69196. +/* PCI Arbiter routines */
  69197. +
  69198. +/*******************************************************************************
  69199. +* mvPciArbEnable - PCI arbiter enable/disable
  69200. +*
  69201. +* DESCRIPTION:
  69202. +* This fuction enable/disables a given PCI interface arbiter.
  69203. +* NOTE: Arbiter setting can not be changed while in work. It should only
  69204. +* be set once.
  69205. +* INPUT:
  69206. +* pciIf - PCI interface number.
  69207. +* enable - Enable/disable parameter. If enable = MV_TRUE then enable.
  69208. +*
  69209. +* OUTPUT:
  69210. +* None.
  69211. +*
  69212. +* RETURN:
  69213. +* None.
  69214. +*
  69215. +*******************************************************************************/
  69216. +MV_STATUS mvPciArbEnable(MV_U32 pciIf, MV_BOOL enable)
  69217. +{
  69218. + MV_U32 regVal;
  69219. +
  69220. + /* Parameter checking */
  69221. + if (pciIf >= mvCtrlPciMaxIfGet())
  69222. + {
  69223. + mvOsPrintf("mvPciArbEnable: ERR. Invalid PCI interface %d\n", pciIf);
  69224. + return MV_ERROR;
  69225. + }
  69226. +
  69227. + /* Set PCI Arbiter Control register according to default configuration */
  69228. + regVal = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
  69229. +
  69230. + /* Make sure arbiter disabled before changing its values */
  69231. + MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE);
  69232. +
  69233. + regVal &= ~PCI_ARBITER_CTRL_DEFAULT_MASK;
  69234. +
  69235. + regVal |= PCI_ARBITER_CTRL_DEFAULT; /* Set default configuration */
  69236. +
  69237. + if (MV_TRUE == enable)
  69238. + {
  69239. + regVal |= PACR_ARB_ENABLE;
  69240. + }
  69241. + else
  69242. + {
  69243. + regVal &= ~PACR_ARB_ENABLE;
  69244. + }
  69245. +
  69246. + /* Write to register */
  69247. + MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), regVal);
  69248. +
  69249. + return MV_OK;
  69250. +}
  69251. +
  69252. +
  69253. +/*******************************************************************************
  69254. +* mvPciArbParkDis - Disable arbiter parking on agent
  69255. +*
  69256. +* DESCRIPTION:
  69257. +* This function disables the PCI arbiter from parking on the given agent
  69258. +* list.
  69259. +*
  69260. +* INPUT:
  69261. +* pciIf - PCI interface number.
  69262. +* pciAgentMask - When a bit in the mask is set to '1', parking on
  69263. +* the associated PCI master is disabled. Mask bit
  69264. +* refers to bit 0 - 6. For example disable parking on PCI
  69265. +* agent 3 set pciAgentMask 0x4 (bit 3 is set).
  69266. +*
  69267. +* OUTPUT:
  69268. +* None.
  69269. +*
  69270. +* RETURN:
  69271. +* None.
  69272. +*
  69273. +*******************************************************************************/
  69274. +MV_STATUS mvPciArbParkDis(MV_U32 pciIf, MV_U32 pciAgentMask)
  69275. +{
  69276. + MV_U32 pciArbiterCtrl;
  69277. +
  69278. + /* Parameter checking */
  69279. + if (pciIf >= mvCtrlPciMaxIfGet())
  69280. + {
  69281. + mvOsPrintf("mvPciArbParkDis: ERR. Invalid PCI interface %d\n", pciIf);
  69282. + return MV_ERROR;
  69283. + }
  69284. +
  69285. + /* Reading Arbiter Control register */
  69286. + pciArbiterCtrl = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
  69287. +
  69288. + /* Arbiter must be disabled before changing parking */
  69289. + MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE);
  69290. +
  69291. + /* do the change */
  69292. + pciArbiterCtrl &= ~PACR_PARK_DIS_MASK;
  69293. + pciArbiterCtrl |= (pciAgentMask << PACR_PARK_DIS_OFFS);
  69294. +
  69295. + /* writing new value ( if th earbiter was enabled before the change */
  69296. + /* here it will be reenabled */
  69297. + MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), pciArbiterCtrl);
  69298. +
  69299. + return MV_OK;
  69300. +}
  69301. +
  69302. +
  69303. +/*******************************************************************************
  69304. +* mvPciArbBrokDetectSet - Set PCI arbiter broken detection
  69305. +*
  69306. +* DESCRIPTION:
  69307. +* This function sets the maximum number of cycles that the arbiter
  69308. +* waits for a PCI master to respond to its grant assertion. If a
  69309. +* PCI agent fails to respond within this time, the PCI arbiter aborts
  69310. +* the transaction and performs a new arbitration cycle.
  69311. +* NOTE: Value must be greater than '1' for conventional PCI and
  69312. +* greater than '5' for PCI-X.
  69313. +*
  69314. +* INPUT:
  69315. +* pciIf - PCI interface number.
  69316. +* pClkCycles - Number of PCI clock cycles. If equal to '0' the broken
  69317. +* master detection is disabled.
  69318. +*
  69319. +* OUTPUT:
  69320. +* None.
  69321. +*
  69322. +* RETURN:
  69323. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  69324. +*
  69325. +*******************************************************************************/
  69326. +MV_STATUS mvPciArbBrokDetectSet(MV_U32 pciIf, MV_U32 pClkCycles)
  69327. +{
  69328. + MV_U32 pciArbiterCtrl;
  69329. + MV_U32 pciMode;
  69330. +
  69331. + /* Parameter checking */
  69332. + if (pciIf >= mvCtrlPciMaxIfGet())
  69333. + {
  69334. + mvOsPrintf("mvPciArbBrokDetectSet: ERR. Invalid PCI interface %d\n",
  69335. + pciIf);
  69336. + return MV_BAD_PARAM;
  69337. + }
  69338. +
  69339. + /* Checking PCI mode and if pClkCycles is legal value */
  69340. + pciMode = MV_REG_READ(PCI_MODE_REG(pciIf));
  69341. + pciMode &= PMR_PCI_MODE_MASK;
  69342. +
  69343. + if (PMR_PCI_MODE_CONV == pciMode)
  69344. + {
  69345. + if (pClkCycles < PACR_BROKEN_VAL_CONV_MIN)
  69346. + return MV_ERROR;
  69347. + }
  69348. + else
  69349. + {
  69350. + if (pClkCycles < PACR_BROKEN_VAL_PCIX_MIN)
  69351. + return MV_ERROR;
  69352. + }
  69353. +
  69354. + pClkCycles <<= PACR_BROKEN_VAL_OFFS;
  69355. +
  69356. + /* Reading Arbiter Control register */
  69357. + pciArbiterCtrl = MV_REG_READ(PCI_ARBITER_CTRL_REG(pciIf));
  69358. + pciArbiterCtrl &= ~PACR_BROKEN_VAL_MASK;
  69359. + pciArbiterCtrl |= pClkCycles;
  69360. +
  69361. + /* Arbiter must be disabled before changing broken detection */
  69362. + MV_REG_BIT_RESET(PCI_ARBITER_CTRL_REG(pciIf), PACR_ARB_ENABLE);
  69363. +
  69364. + /* writing new value ( if th earbiter was enabled before the change */
  69365. + /* here it will be reenabled */
  69366. +
  69367. + MV_REG_WRITE(PCI_ARBITER_CTRL_REG(pciIf), pciArbiterCtrl);
  69368. +
  69369. + return MV_OK;
  69370. +}
  69371. +
  69372. +/* PCI configuration space read write */
  69373. +
  69374. +/*******************************************************************************
  69375. +* mvPciConfigRead - Read from configuration space
  69376. +*
  69377. +* DESCRIPTION:
  69378. +* This function performs a 32 bit read from PCI configuration space.
  69379. +* It supports both type 0 and type 1 of Configuration Transactions
  69380. +* (local and over bridge). In order to read from local bus segment, use
  69381. +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
  69382. +* will result configuration transaction of type 1 (over bridge).
  69383. +*
  69384. +* INPUT:
  69385. +* pciIf - PCI interface number.
  69386. +* bus - PCI segment bus number.
  69387. +* dev - PCI device number.
  69388. +* func - Function number.
  69389. +* regOffs - Register offset.
  69390. +*
  69391. +* OUTPUT:
  69392. +* None.
  69393. +*
  69394. +* RETURN:
  69395. +* 32bit register data, 0xffffffff on error
  69396. +*
  69397. +*******************************************************************************/
  69398. +MV_U32 mvPciConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  69399. + MV_U32 regOff)
  69400. +{
  69401. + MV_U32 pciData = 0;
  69402. +
  69403. + /* Parameter checking */
  69404. + if (PCI_DEFAULT_IF != pciIf)
  69405. + {
  69406. + if (pciIf >= mvCtrlPciMaxIfGet())
  69407. + {
  69408. + mvOsPrintf("mvPciConfigRead: ERR. Invalid PCI interface %d\n",pciIf);
  69409. + return 0xFFFFFFFF;
  69410. + }
  69411. + }
  69412. +
  69413. + if (dev >= MAX_PCI_DEVICES)
  69414. + {
  69415. + DB(mvOsPrintf("mvPciConfigRead: ERR. device number illigal %d\n", dev));
  69416. + return 0xFFFFFFFF;
  69417. + }
  69418. +
  69419. + if (func >= MAX_PCI_FUNCS)
  69420. + {
  69421. + DB(mvOsPrintf("mvPciConfigRead: ERR. function number illigal %d\n", func));
  69422. + return 0xFFFFFFFF;
  69423. + }
  69424. +
  69425. + if (bus >= MAX_PCI_BUSSES)
  69426. + {
  69427. + DB(mvOsPrintf("mvPciConfigRead: ERR. bus number illigal %d\n", bus));
  69428. + return MV_ERROR;
  69429. + }
  69430. +
  69431. +
  69432. + /* Creating PCI address to be passed */
  69433. + pciData |= (bus << PCAR_BUS_NUM_OFFS);
  69434. + pciData |= (dev << PCAR_DEVICE_NUM_OFFS);
  69435. + pciData |= (func << PCAR_FUNC_NUM_OFFS);
  69436. + pciData |= (regOff & PCAR_REG_NUM_MASK);
  69437. +
  69438. + pciData |= PCAR_CONFIG_EN;
  69439. +
  69440. + /* Write the address to the PCI configuration address register */
  69441. + MV_REG_WRITE(PCI_CONFIG_ADDR_REG(pciIf), pciData);
  69442. +
  69443. + /* In order to let the PCI controller absorbed the address of the read */
  69444. + /* transaction we perform a validity check that the address was written */
  69445. + if(pciData != MV_REG_READ(PCI_CONFIG_ADDR_REG(pciIf)))
  69446. + {
  69447. + return MV_ERROR;
  69448. + }
  69449. + /* Read the Data returned in the PCI Data register */
  69450. + pciData = MV_REG_READ(PCI_CONFIG_DATA_REG(pciIf));
  69451. +
  69452. + return pciData;
  69453. +}
  69454. +
  69455. +/*******************************************************************************
  69456. +* mvPciConfigWrite - Write to configuration space
  69457. +*
  69458. +* DESCRIPTION:
  69459. +* This function performs a 32 bit write to PCI configuration space.
  69460. +* It supports both type 0 and type 1 of Configuration Transactions
  69461. +* (local and over bridge). In order to write to local bus segment, use
  69462. +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
  69463. +* will result configuration transaction of type 1 (over bridge).
  69464. +*
  69465. +* INPUT:
  69466. +* pciIf - PCI interface number.
  69467. +* bus - PCI segment bus number.
  69468. +* dev - PCI device number.
  69469. +* func - Function number.
  69470. +* regOffs - Register offset.
  69471. +* data - 32bit data.
  69472. +*
  69473. +* OUTPUT:
  69474. +* None.
  69475. +*
  69476. +* RETURN:
  69477. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  69478. +*
  69479. +*******************************************************************************/
  69480. +MV_STATUS mvPciConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  69481. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  69482. +{
  69483. + MV_U32 pciData = 0;
  69484. +
  69485. + /* Parameter checking */
  69486. + if (PCI_DEFAULT_IF != pciIf)
  69487. + {
  69488. + if (pciIf >= mvCtrlPciMaxIfGet())
  69489. + {
  69490. + mvOsPrintf("mvPciConfigWrite: ERR. Invalid PCI interface %d\n",
  69491. + pciIf);
  69492. + return 0xFFFFFFFF;
  69493. + }
  69494. + }
  69495. +
  69496. + if (dev >= MAX_PCI_DEVICES)
  69497. + {
  69498. + mvOsPrintf("mvPciConfigWrite: ERR. device number illigal %d\n",dev);
  69499. + return MV_BAD_PARAM;
  69500. + }
  69501. +
  69502. + if (func >= MAX_PCI_FUNCS)
  69503. + {
  69504. + mvOsPrintf("mvPciConfigWrite: ERR. function number illigal %d\n", func);
  69505. + return MV_ERROR;
  69506. + }
  69507. +
  69508. + if (bus >= MAX_PCI_BUSSES)
  69509. + {
  69510. + mvOsPrintf("mvPciConfigWrite: ERR. bus number illigal %d\n", bus);
  69511. + return MV_ERROR;
  69512. + }
  69513. +
  69514. + /* Creating PCI address to be passed */
  69515. + pciData |= (bus << PCAR_BUS_NUM_OFFS);
  69516. + pciData |= (dev << PCAR_DEVICE_NUM_OFFS);
  69517. + pciData |= (func << PCAR_FUNC_NUM_OFFS);
  69518. + pciData |= (regOff & PCAR_REG_NUM_MASK);
  69519. +
  69520. + pciData |= PCAR_CONFIG_EN;
  69521. +
  69522. + /* Write the address to the PCI configuration address register */
  69523. + MV_REG_WRITE(PCI_CONFIG_ADDR_REG(pciIf), pciData);
  69524. +
  69525. + /* In order to let the PCI controller absorbed the address of the read */
  69526. + /* transaction we perform a validity check that the address was written */
  69527. + if(pciData != MV_REG_READ(PCI_CONFIG_ADDR_REG(pciIf)))
  69528. + {
  69529. + return MV_ERROR;
  69530. + }
  69531. +
  69532. + /* Write the Data passed to the PCI Data register */
  69533. + MV_REG_WRITE(PCI_CONFIG_DATA_REG(pciIf), data);
  69534. +
  69535. + return MV_OK;
  69536. +}
  69537. +
  69538. +/*******************************************************************************
  69539. +* mvPciMasterEnable - Enable/disale PCI interface master transactions.
  69540. +*
  69541. +* DESCRIPTION:
  69542. +* This function performs read modified write to PCI command status
  69543. +* (offset 0x4) to set/reset bit 2. After this bit is set, the PCI
  69544. +* master is allowed to gain ownership on the bus, otherwise it is
  69545. +* incapable to do so.
  69546. +*
  69547. +* INPUT:
  69548. +* pciIf - PCI interface number.
  69549. +* enable - Enable/disable parameter.
  69550. +*
  69551. +* OUTPUT:
  69552. +* None.
  69553. +*
  69554. +* RETURN:
  69555. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  69556. +*
  69557. +*******************************************************************************/
  69558. +MV_STATUS mvPciMasterEnable(MV_U32 pciIf, MV_BOOL enable)
  69559. +{
  69560. + MV_U32 pciCommandStatus;
  69561. + MV_U32 RegOffs;
  69562. + MV_U32 localBus;
  69563. + MV_U32 localDev;
  69564. +
  69565. + /* Parameter checking */
  69566. + if (pciIf >= mvCtrlPciMaxIfGet())
  69567. + {
  69568. + mvOsPrintf("mvPciMasterEnable: ERR. Invalid PCI interface %d\n", pciIf);
  69569. + return MV_ERROR;
  69570. + }
  69571. +
  69572. + localBus = mvPciLocalBusNumGet(pciIf);
  69573. + localDev = mvPciLocalDevNumGet(pciIf);
  69574. +
  69575. + RegOffs = PCI_STATUS_AND_COMMAND;
  69576. +
  69577. + pciCommandStatus = mvPciConfigRead(pciIf, localBus, localDev, 0, RegOffs);
  69578. +
  69579. + if (MV_TRUE == enable)
  69580. + {
  69581. + pciCommandStatus |= PSCR_MASTER_EN;
  69582. + }
  69583. + else
  69584. + {
  69585. + pciCommandStatus &= ~PSCR_MASTER_EN;
  69586. + }
  69587. +
  69588. + mvPciConfigWrite(pciIf, localBus, localDev, 0, RegOffs, pciCommandStatus);
  69589. +
  69590. + return MV_OK;
  69591. +}
  69592. +
  69593. +
  69594. +/*******************************************************************************
  69595. +* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.
  69596. +*
  69597. +* DESCRIPTION:
  69598. +* This function performs read modified write to PCI command status
  69599. +* (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
  69600. +* the PCI slave is allowed to respond to PCI IO space access (bit 0)
  69601. +* and PCI memory space access (bit 1).
  69602. +*
  69603. +* INPUT:
  69604. +* pciIf - PCI interface number.
  69605. +* dev - PCI device number.
  69606. +* enable - Enable/disable parameter.
  69607. +*
  69608. +* OUTPUT:
  69609. +* None.
  69610. +*
  69611. +* RETURN:
  69612. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  69613. +*
  69614. +*******************************************************************************/
  69615. +MV_STATUS mvPciSlaveEnable(MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_BOOL enable)
  69616. +{
  69617. + MV_U32 pciCommandStatus;
  69618. + MV_U32 RegOffs;
  69619. +
  69620. + /* Parameter checking */
  69621. + if (pciIf >= mvCtrlPciMaxIfGet())
  69622. + {
  69623. + mvOsPrintf("mvPciSlaveEnable: ERR. Invalid PCI interface %d\n", pciIf);
  69624. + return MV_BAD_PARAM;
  69625. + }
  69626. + if (dev >= MAX_PCI_DEVICES)
  69627. + {
  69628. + mvOsPrintf("mvPciLocalDevNumSet: ERR. device number illigal %d\n", dev);
  69629. + return MV_BAD_PARAM;
  69630. +
  69631. + }
  69632. +
  69633. + RegOffs = PCI_STATUS_AND_COMMAND;
  69634. +
  69635. + pciCommandStatus=mvPciConfigRead(pciIf, bus, dev, 0, RegOffs);
  69636. +
  69637. + if (MV_TRUE == enable)
  69638. + {
  69639. + pciCommandStatus |= (PSCR_IO_EN | PSCR_MEM_EN);
  69640. + }
  69641. + else
  69642. + {
  69643. + pciCommandStatus &= ~(PSCR_IO_EN | PSCR_MEM_EN);
  69644. + }
  69645. +
  69646. + mvPciConfigWrite(pciIf, bus, dev, 0, RegOffs, pciCommandStatus);
  69647. +
  69648. + return MV_OK;
  69649. +}
  69650. +
  69651. +/*******************************************************************************
  69652. +* mvPciLocalBusNumSet - Set PCI interface local bus number.
  69653. +*
  69654. +* DESCRIPTION:
  69655. +* This function sets given PCI interface its local bus number.
  69656. +* Note: In case the PCI interface is PCI-X, the information is read-only.
  69657. +*
  69658. +* INPUT:
  69659. +* pciIf - PCI interface number.
  69660. +* busNum - Bus number.
  69661. +*
  69662. +* OUTPUT:
  69663. +* None.
  69664. +*
  69665. +* RETURN:
  69666. +* MV_NOT_ALLOWED in case PCI interface is PCI-X.
  69667. +* MV_BAD_PARAM on bad parameters ,
  69668. +* otherwise MV_OK
  69669. +*
  69670. +*******************************************************************************/
  69671. +MV_STATUS mvPciLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum)
  69672. +{
  69673. + MV_U32 pciP2PConfig;
  69674. + MV_PCI_MODE pciMode;
  69675. + MV_U32 localBus;
  69676. + MV_U32 localDev;
  69677. +
  69678. +
  69679. + /* Parameter checking */
  69680. + if (pciIf >= mvCtrlPciMaxIfGet())
  69681. + {
  69682. + mvOsPrintf("mvPciLocalBusNumSet: ERR. Invalid PCI interface %d\n",pciIf);
  69683. + return MV_BAD_PARAM;
  69684. + }
  69685. + if (busNum >= MAX_PCI_BUSSES)
  69686. + {
  69687. + mvOsPrintf("mvPciLocalBusNumSet: ERR. bus number illigal %d\n", busNum);
  69688. + return MV_ERROR;
  69689. +
  69690. + }
  69691. +
  69692. + localBus = mvPciLocalBusNumGet(pciIf);
  69693. + localDev = mvPciLocalDevNumGet(pciIf);
  69694. +
  69695. +
  69696. + /* PCI interface mode */
  69697. + mvPciModeGet(pciIf, &pciMode);
  69698. +
  69699. + /* if PCI type is PCI-X then it is not allowed to change the dev number */
  69700. + if (MV_PCIX == pciMode.pciType)
  69701. + {
  69702. + pciP2PConfig = mvPciConfigRead(pciIf, localBus, localDev, 0, PCIX_STATUS );
  69703. +
  69704. + pciP2PConfig &= ~PXS_BN_MASK;
  69705. +
  69706. + pciP2PConfig |= (busNum << PXS_BN_OFFS) & PXS_BN_MASK;
  69707. +
  69708. + mvPciConfigWrite(pciIf, localBus, localDev, 0, PCIX_STATUS,pciP2PConfig );
  69709. +
  69710. + }
  69711. + else
  69712. + {
  69713. + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
  69714. +
  69715. + pciP2PConfig &= ~PPCR_BUS_NUM_MASK;
  69716. +
  69717. + pciP2PConfig |= (busNum << PPCR_BUS_NUM_OFFS) & PPCR_BUS_NUM_MASK;
  69718. +
  69719. + MV_REG_WRITE(PCI_P2P_CONFIG_REG(pciIf), pciP2PConfig);
  69720. +
  69721. + }
  69722. +
  69723. +
  69724. + return MV_OK;
  69725. +}
  69726. +
  69727. +
  69728. +/*******************************************************************************
  69729. +* mvPciLocalBusNumGet - Get PCI interface local bus number.
  69730. +*
  69731. +* DESCRIPTION:
  69732. +* This function gets the local bus number of a given PCI interface.
  69733. +*
  69734. +* INPUT:
  69735. +* pciIf - PCI interface number.
  69736. +*
  69737. +* OUTPUT:
  69738. +* None.
  69739. +*
  69740. +* RETURN:
  69741. +* Local bus number.0xffffffff on Error
  69742. +*
  69743. +*******************************************************************************/
  69744. +MV_U32 mvPciLocalBusNumGet(MV_U32 pciIf)
  69745. +{
  69746. + MV_U32 pciP2PConfig;
  69747. +
  69748. + /* Parameter checking */
  69749. + if (PCI_DEFAULT_IF != pciIf)
  69750. + {
  69751. + if (pciIf >= mvCtrlPciMaxIfGet())
  69752. + {
  69753. + mvOsPrintf("mvPciLocalBusNumGet: ERR. Invalid PCI interface %d\n",
  69754. + pciIf);
  69755. + return 0xFFFFFFFF;
  69756. + }
  69757. + }
  69758. +
  69759. + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
  69760. + pciP2PConfig &= PPCR_BUS_NUM_MASK;
  69761. + return (pciP2PConfig >> PPCR_BUS_NUM_OFFS);
  69762. +}
  69763. +
  69764. +
  69765. +/*******************************************************************************
  69766. +* mvPciLocalDevNumSet - Set PCI interface local device number.
  69767. +*
  69768. +* DESCRIPTION:
  69769. +* This function sets given PCI interface its local device number.
  69770. +* Note: In case the PCI interface is PCI-X, the information is read-only.
  69771. +*
  69772. +* INPUT:
  69773. +* pciIf - PCI interface number.
  69774. +* devNum - Device number.
  69775. +*
  69776. +* OUTPUT:
  69777. +* None.
  69778. +*
  69779. +* RETURN:
  69780. +* MV_NOT_ALLOWED in case PCI interface is PCI-X. MV_BAD_PARAM on bad parameters ,
  69781. +* otherwise MV_OK
  69782. +*
  69783. +*******************************************************************************/
  69784. +MV_STATUS mvPciLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum)
  69785. +{
  69786. + MV_U32 pciP2PConfig;
  69787. + MV_PCI_MODE pciMode;
  69788. + MV_U32 localBus;
  69789. + MV_U32 localDev;
  69790. +
  69791. + /* Parameter checking */
  69792. + if (pciIf >= mvCtrlPciMaxIfGet())
  69793. + {
  69794. + mvOsPrintf("mvPciLocalDevNumSet: ERR. Invalid PCI interface %d\n",pciIf);
  69795. + return MV_BAD_PARAM;
  69796. + }
  69797. + if (devNum >= MAX_PCI_DEVICES)
  69798. + {
  69799. + mvOsPrintf("mvPciLocalDevNumSet: ERR. device number illigal %d\n",
  69800. + devNum);
  69801. + return MV_BAD_PARAM;
  69802. +
  69803. + }
  69804. +
  69805. + localBus = mvPciLocalBusNumGet(pciIf);
  69806. + localDev = mvPciLocalDevNumGet(pciIf);
  69807. +
  69808. + /* PCI interface mode */
  69809. + mvPciModeGet(pciIf, &pciMode);
  69810. +
  69811. + /* if PCI type is PCIX then it is not allowed to change the dev number */
  69812. + if (MV_PCIX == pciMode.pciType)
  69813. + {
  69814. + pciP2PConfig = mvPciConfigRead(pciIf, localBus, localDev, 0, PCIX_STATUS );
  69815. +
  69816. + pciP2PConfig &= ~PXS_DN_MASK;
  69817. +
  69818. + pciP2PConfig |= (devNum << PXS_DN_OFFS) & PXS_DN_MASK;
  69819. +
  69820. + mvPciConfigWrite(pciIf,localBus, localDev, 0, PCIX_STATUS,pciP2PConfig );
  69821. + }
  69822. + else
  69823. + {
  69824. + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
  69825. +
  69826. + pciP2PConfig &= ~PPCR_DEV_NUM_MASK;
  69827. +
  69828. + pciP2PConfig |= (devNum << PPCR_DEV_NUM_OFFS) & PPCR_DEV_NUM_MASK;
  69829. +
  69830. + MV_REG_WRITE(PCI_P2P_CONFIG_REG(pciIf), pciP2PConfig);
  69831. + }
  69832. +
  69833. + return MV_OK;
  69834. +}
  69835. +
  69836. +/*******************************************************************************
  69837. +* mvPciLocalDevNumGet - Get PCI interface local device number.
  69838. +*
  69839. +* DESCRIPTION:
  69840. +* This function gets the local device number of a given PCI interface.
  69841. +*
  69842. +* INPUT:
  69843. +* pciIf - PCI interface number.
  69844. +*
  69845. +* OUTPUT:
  69846. +* None.
  69847. +*
  69848. +* RETURN:
  69849. +* Local device number. 0xffffffff on Error
  69850. +*
  69851. +*******************************************************************************/
  69852. +MV_U32 mvPciLocalDevNumGet(MV_U32 pciIf)
  69853. +{
  69854. + MV_U32 pciP2PConfig;
  69855. +
  69856. + /* Parameter checking */
  69857. +
  69858. + if (PCI_DEFAULT_IF != pciIf)
  69859. + {
  69860. + if (pciIf >= mvCtrlPciMaxIfGet())
  69861. + {
  69862. + mvOsPrintf("mvPciLocalDevNumGet: ERR. Invalid PCI interface %d\n",
  69863. + pciIf);
  69864. + return 0xFFFFFFFF;
  69865. + }
  69866. + }
  69867. +
  69868. + pciP2PConfig = MV_REG_READ(PCI_P2P_CONFIG_REG(pciIf));
  69869. +
  69870. + pciP2PConfig &= PPCR_DEV_NUM_MASK;
  69871. +
  69872. + return (pciP2PConfig >> PPCR_DEV_NUM_OFFS);
  69873. +}
  69874. +
  69875. +
  69876. +
  69877. +
  69878. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h
  69879. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h 1970-01-01 01:00:00.000000000 +0100
  69880. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPci.h 2011-08-01 14:38:19.000000000 +0200
  69881. @@ -0,0 +1,185 @@
  69882. +/*******************************************************************************
  69883. +Copyright (C) Marvell International Ltd. and its affiliates
  69884. +
  69885. +This software file (the "File") is owned and distributed by Marvell
  69886. +International Ltd. and/or its affiliates ("Marvell") under the following
  69887. +alternative licensing terms. Once you have made an election to distribute the
  69888. +File under one of the following license alternatives, please (i) delete this
  69889. +introductory statement regarding license alternatives, (ii) delete the two
  69890. +license alternatives that you have not elected to use and (iii) preserve the
  69891. +Marvell copyright notice above.
  69892. +
  69893. +********************************************************************************
  69894. +Marvell Commercial License Option
  69895. +
  69896. +If you received this File from Marvell and you have entered into a commercial
  69897. +license agreement (a "Commercial License") with Marvell, the File is licensed
  69898. +to you under the terms of the applicable Commercial License.
  69899. +
  69900. +********************************************************************************
  69901. +Marvell GPL License Option
  69902. +
  69903. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69904. +modify this File in accordance with the terms and conditions of the General
  69905. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  69906. +available along with the File in the license.txt file or by writing to the Free
  69907. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  69908. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  69909. +
  69910. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  69911. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  69912. +DISCLAIMED. The GPL License provides additional details about this warranty
  69913. +disclaimer.
  69914. +********************************************************************************
  69915. +Marvell BSD License Option
  69916. +
  69917. +If you received this File from Marvell, you may opt to use, redistribute and/or
  69918. +modify this File under the following licensing terms.
  69919. +Redistribution and use in source and binary forms, with or without modification,
  69920. +are permitted provided that the following conditions are met:
  69921. +
  69922. + * Redistributions of source code must retain the above copyright notice,
  69923. + this list of conditions and the following disclaimer.
  69924. +
  69925. + * Redistributions in binary form must reproduce the above copyright
  69926. + notice, this list of conditions and the following disclaimer in the
  69927. + documentation and/or other materials provided with the distribution.
  69928. +
  69929. + * Neither the name of Marvell nor the names of its contributors may be
  69930. + used to endorse or promote products derived from this software without
  69931. + specific prior written permission.
  69932. +
  69933. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  69934. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  69935. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  69936. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  69937. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  69938. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  69939. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  69940. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  69941. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  69942. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  69943. +
  69944. +*******************************************************************************/
  69945. +
  69946. +
  69947. +#ifndef __INCPCIH
  69948. +#define __INCPCIH
  69949. +
  69950. +#include "mvCommon.h"
  69951. +#include "mvOs.h"
  69952. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  69953. +#include "pci/mvPciRegs.h"
  69954. +
  69955. +
  69956. +/* NOTE not supported in this driver:
  69957. +
  69958. + Built In Self Test (BIST)
  69959. + Vital Product Data (VPD)
  69960. + Message Signaled Interrupt (MSI)
  69961. + Power Management
  69962. + Compact PCI Hot Swap
  69963. + Header retarget
  69964. +
  69965. +Registers not supported:
  69966. +1) PCI DLL Status and Control (PCI0 0x1D20, PCI1 0x1DA0)
  69967. +2) PCI/MPP Pads Calibration (CI0/MPP[31:16] 0x1D1C, PCI1/MPP[15:0] 0X1D9C)
  69968. +*/
  69969. +
  69970. +/* defines */
  69971. +/* The number of supported PCI interfaces depend on Marvell controller */
  69972. +/* device number. This device number ID is located on the PCI unit */
  69973. +/* configuration header. This creates a loop where calling PCI */
  69974. +/* configuration read/write routine results a call to get PCI configuration */
  69975. +/* information etc. This macro defines a default PCI interface. This PCI */
  69976. +/* interface is sure to exist. */
  69977. +#define PCI_DEFAULT_IF 0
  69978. +
  69979. +
  69980. +/* typedefs */
  69981. +/* The Marvell controller supports both conventional PCI and PCI-X. */
  69982. +/* This enumeration describes the PCI type. */
  69983. +typedef enum _mvPciType
  69984. +{
  69985. + MV_PCI_CONV, /* Conventional PCI */
  69986. + MV_PCIX /* PCI-X */
  69987. +}MV_PCI_TYPE;
  69988. +
  69989. +typedef enum _mvPciMod
  69990. +{
  69991. + MV_PCI_MOD_HOST,
  69992. + MV_PCI_MOD_DEVICE
  69993. +}MV_PCI_MOD;
  69994. +
  69995. +
  69996. +/* The Marvell controller supports both PCI width of 32 and 64 bit. */
  69997. +/* This enumerator describes PCI width */
  69998. +typedef enum _mvPciWidth
  69999. +{
  70000. + MV_PCI_32, /* PCI width 32bit */
  70001. + MV_PCI_64 /* PCI width 64bit */
  70002. +}MV_PCI_WIDTH;
  70003. +
  70004. +/* This structure describes the PCI unit configured type, speed and width. */
  70005. +typedef struct _mvPciMode
  70006. +{
  70007. + MV_PCI_TYPE pciType; /* PCI type */
  70008. + MV_U32 pciSpeed; /* Assuming PCI base clock on board is 33MHz */
  70009. + MV_PCI_WIDTH pciWidth; /* PCI bus width */
  70010. +}MV_PCI_MODE;
  70011. +
  70012. +/* mvPciInit - Initialize PCI interfaces*/
  70013. +MV_VOID mvPciHalInit(MV_U32 pciIf, MV_PCI_MOD pciIfmod);
  70014. +
  70015. +/* mvPciCommandSet - Set PCI comman register value.*/
  70016. +MV_STATUS mvPciCommandSet(MV_U32 pciIf, MV_U32 command);
  70017. +
  70018. +/* mvPciModeGet - Get PCI interface mode.*/
  70019. +MV_STATUS mvPciModeGet(MV_U32 pciIf, MV_PCI_MODE *pPciMode);
  70020. +
  70021. +/* mvPciRetrySet - Set PCI retry counters*/
  70022. +MV_STATUS mvPciRetrySet(MV_U32 pciIf, MV_U32 counter);
  70023. +
  70024. +/* mvPciDiscardTimerSet - Set PCI discard timer*/
  70025. +MV_STATUS mvPciDiscardTimerSet(MV_U32 pciIf, MV_U32 pClkCycles);
  70026. +
  70027. +/* mvPciArbEnable - PCI arbiter enable/disable*/
  70028. +MV_STATUS mvPciArbEnable(MV_U32 pciIf, MV_BOOL enable);
  70029. +
  70030. +/* mvPciArbParkDis - Disable arbiter parking on agent */
  70031. +MV_STATUS mvPciArbParkDis(MV_U32 pciIf, MV_U32 pciAgentMask);
  70032. +
  70033. +/* mvPciArbBrokDetectSet - Set PCI arbiter broken detection */
  70034. +MV_STATUS mvPciArbBrokDetectSet(MV_U32 pciIf, MV_U32 pClkCycles);
  70035. +
  70036. +/* mvPciConfigRead - Read from configuration space */
  70037. +MV_U32 mvPciConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  70038. + MV_U32 func,MV_U32 regOff);
  70039. +
  70040. +/* mvPciConfigWrite - Write to configuration space */
  70041. +MV_STATUS mvPciConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  70042. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  70043. +
  70044. +/* mvPciMasterEnable - Enable/disale PCI interface master transactions.*/
  70045. +MV_STATUS mvPciMasterEnable(MV_U32 pciIf, MV_BOOL enable);
  70046. +
  70047. +/* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.*/
  70048. +MV_STATUS mvPciSlaveEnable(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,MV_BOOL enable);
  70049. +
  70050. +/* mvPciLocalBusNumSet - Set PCI interface local bus number.*/
  70051. +MV_STATUS mvPciLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum);
  70052. +
  70053. +/* mvPciLocalBusNumGet - Get PCI interface local bus number.*/
  70054. +MV_U32 mvPciLocalBusNumGet(MV_U32 pciIf);
  70055. +
  70056. +/* mvPciLocalDevNumSet - Set PCI interface local device number.*/
  70057. +MV_STATUS mvPciLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum);
  70058. +
  70059. +/* mvPciLocalDevNumGet - Get PCI interface local device number.*/
  70060. +MV_U32 mvPciLocalDevNumGet(MV_U32 pciIf);
  70061. +
  70062. +
  70063. +#endif /* #ifndef __INCPCIH */
  70064. +
  70065. +
  70066. +
  70067. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h
  70068. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h 1970-01-01 01:00:00.000000000 +0100
  70069. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci/mvPciRegs.h 2011-08-01 14:38:19.000000000 +0200
  70070. @@ -0,0 +1,411 @@
  70071. +/*******************************************************************************
  70072. +Copyright (C) Marvell International Ltd. and its affiliates
  70073. +
  70074. +This software file (the "File") is owned and distributed by Marvell
  70075. +International Ltd. and/or its affiliates ("Marvell") under the following
  70076. +alternative licensing terms. Once you have made an election to distribute the
  70077. +File under one of the following license alternatives, please (i) delete this
  70078. +introductory statement regarding license alternatives, (ii) delete the two
  70079. +license alternatives that you have not elected to use and (iii) preserve the
  70080. +Marvell copyright notice above.
  70081. +
  70082. +********************************************************************************
  70083. +Marvell Commercial License Option
  70084. +
  70085. +If you received this File from Marvell and you have entered into a commercial
  70086. +license agreement (a "Commercial License") with Marvell, the File is licensed
  70087. +to you under the terms of the applicable Commercial License.
  70088. +
  70089. +********************************************************************************
  70090. +Marvell GPL License Option
  70091. +
  70092. +If you received this File from Marvell, you may opt to use, redistribute and/or
  70093. +modify this File in accordance with the terms and conditions of the General
  70094. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  70095. +available along with the File in the license.txt file or by writing to the Free
  70096. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  70097. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  70098. +
  70099. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  70100. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  70101. +DISCLAIMED. The GPL License provides additional details about this warranty
  70102. +disclaimer.
  70103. +********************************************************************************
  70104. +Marvell BSD License Option
  70105. +
  70106. +If you received this File from Marvell, you may opt to use, redistribute and/or
  70107. +modify this File under the following licensing terms.
  70108. +Redistribution and use in source and binary forms, with or without modification,
  70109. +are permitted provided that the following conditions are met:
  70110. +
  70111. + * Redistributions of source code must retain the above copyright notice,
  70112. + this list of conditions and the following disclaimer.
  70113. +
  70114. + * Redistributions in binary form must reproduce the above copyright
  70115. + notice, this list of conditions and the following disclaimer in the
  70116. + documentation and/or other materials provided with the distribution.
  70117. +
  70118. + * Neither the name of Marvell nor the names of its contributors may be
  70119. + used to endorse or promote products derived from this software without
  70120. + specific prior written permission.
  70121. +
  70122. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  70123. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  70124. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  70125. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  70126. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  70127. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  70128. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  70129. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  70130. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  70131. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  70132. +
  70133. +*******************************************************************************/
  70134. +
  70135. +#ifndef __INCPCIREGSH
  70136. +#define __INCPCIREGSH
  70137. +
  70138. +
  70139. +#include "pci-if/mvPciIfRegs.h"
  70140. +/* defines */
  70141. +#define MAX_PCI_DEVICES 32
  70142. +#define MAX_PCI_FUNCS 8
  70143. +#define MAX_PCI_BUSSES 128
  70144. +
  70145. +/* enumerators */
  70146. +
  70147. +/* This enumerator described the possible PCI slave targets. */
  70148. +/* PCI slave targets are designated memory/IO address spaces that the */
  70149. +/* PCI slave targets can access. They are also refered as "targets" */
  70150. +/* this enumeratoe order is determined by the content of :
  70151. + PCI_BASE_ADDR_ENABLE_REG */
  70152. +
  70153. +
  70154. +/* registers offsetes defines */
  70155. +
  70156. +
  70157. +
  70158. +/*************************/
  70159. +/* PCI control registers */
  70160. +/*************************/
  70161. +/* maen : should add new registers */
  70162. +#define PCI_CMD_REG(pciIf) (0x30c00 + ((pciIf) * 0x80))
  70163. +#define PCI_MODE_REG(pciIf) (0x30d00 + ((pciIf) * 0x80))
  70164. +#define PCI_RETRY_REG(pciIf) (0x30c04 + ((pciIf) * 0x80))
  70165. +#define PCI_DISCARD_TIMER_REG(pciIf) (0x30d04 + ((pciIf) * 0x80))
  70166. +#define PCI_ARBITER_CTRL_REG(pciIf) (0x31d00 + ((pciIf) * 0x80))
  70167. +#define PCI_P2P_CONFIG_REG(pciIf) (0x31d14 + ((pciIf) * 0x80))
  70168. +#define PCI_ACCESS_CTRL_BASEL_REG(pciIf, targetWin) \
  70169. + (0x31e00 + ((pciIf) * 0x80) + ((targetWin) * 0x10))
  70170. +#define PCI_ACCESS_CTRL_BASEH_REG(pciIf, targetWin) \
  70171. + (0x31e04 + ((pciIf) * 0x80) + ((targetWin) * 0x10))
  70172. +#define PCI_ACCESS_CTRL_SIZE_REG(pciIf, targetWin) \
  70173. + (0x31e08 + ((pciIf) * 0x80) + ((targetWin) * 0x10))
  70174. +
  70175. +#define PCI_DLL_CTRL_REG(pciIf) (0x31d20 + ((pciIf) * 0x80))
  70176. +
  70177. +/* PCI Dll Control (PDC)*/
  70178. +#define PDC_DLL_EN BIT0
  70179. +
  70180. +
  70181. +/* PCI Command Register (PCR) */
  70182. +#define PCR_MASTER_BYTE_SWAP_EN BIT0
  70183. +#define PCR_MASTER_WR_COMBINE_EN BIT4
  70184. +#define PCR_MASTER_RD_COMBINE_EN BIT5
  70185. +#define PCR_MASTER_WR_TRIG_WHOLE BIT6
  70186. +#define PCR_MASTER_RD_TRIG_WHOLE BIT7
  70187. +#define PCR_MASTER_MEM_RD_LINE_EN BIT8
  70188. +#define PCR_MASTER_MEM_RD_MULT_EN BIT9
  70189. +#define PCR_MASTER_WORD_SWAP_EN BIT10
  70190. +#define PCR_SLAVE_WORD_SWAP_EN BIT11
  70191. +#define PCR_NS_ACCORDING_RCV_TRANS BIT14
  70192. +#define PCR_MASTER_PCIX_REQ64N_EN BIT15
  70193. +#define PCR_SLAVE_BYTE_SWAP_EN BIT16
  70194. +#define PCR_MASTER_DAC_EN BIT17
  70195. +#define PCR_MASTER_M64_ALLIGN BIT18
  70196. +#define PCR_ERRORS_PROPAGATION_EN BIT19
  70197. +#define PCR_SLAVE_SWAP_ENABLE BIT20
  70198. +#define PCR_MASTER_SWAP_ENABLE BIT21
  70199. +#define PCR_MASTER_INT_SWAP_EN BIT22
  70200. +#define PCR_LOOP_BACK_ENABLE BIT23
  70201. +#define PCR_SLAVE_INTREG_SWAP_OFFS 24
  70202. +#define PCR_SLAVE_INTREG_SWAP_MASK 0x3
  70203. +#define PCR_SLAVE_INTREG_BYTE_SWAP \
  70204. + (MV_BYTE_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
  70205. +#define PCR_SLAVE_INTREG_NO_SWAP \
  70206. + (MV_NO_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
  70207. +#define PCR_SLAVE_INTREG_BYTE_WORD \
  70208. + (MV_BYTE_WORD_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
  70209. +#define PCR_SLAVE_INTREG_WORD_SWAP \
  70210. + (MV_WORD_SWAP << PCR_SLAVE_INT_REG_SWAP_MASK)
  70211. +#define PCR_RESET_REASSERTION_EN BIT26
  70212. +#define PCR_PCI_TO_CPU_REG_ORDER_EN BIT28
  70213. +#define PCR_CPU_TO_PCI_ORDER_EN BIT29
  70214. +#define PCR_PCI_TO_CPU_ORDER_EN BIT30
  70215. +
  70216. +/* PCI Mode Register (PMR) */
  70217. +#define PMR_PCI_ID_OFFS 0 /* PCI Interface ID */
  70218. +#define PMR_PCI_ID_MASK (0x1 << PMR_PCI_ID_OFFS)
  70219. +#define PMR_PCI_ID_PCI(pciNum) ((pciNum) << PCI_MODE_PCIID_OFFS)
  70220. +
  70221. +#define PMR_PCI_64_OFFS 2 /* 64-bit PCI Interface */
  70222. +#define PMR_PCI_64_MASK (0x1 << PMR_PCI_64_OFFS)
  70223. +#define PMR_PCI_64_64BIT (0x1 << PMR_PCI_64_OFFS)
  70224. +#define PMR_PCI_64_32BIT (0x0 << PMR_PCI_64_OFFS)
  70225. +
  70226. +#define PMR_PCI_MODE_OFFS 4 /* PCI interface mode of operation */
  70227. +#define PMR_PCI_MODE_MASK (0x3 << PMR_PCI_MODE_OFFS)
  70228. +#define PMR_PCI_MODE_CONV (0x0 << PMR_PCI_MODE_OFFS)
  70229. +#define PMR_PCI_MODE_PCIX_66MHZ (0x1 << PMR_PCI_MODE_OFFS)
  70230. +#define PMR_PCI_MODE_PCIX_100MHZ (0x2 << PMR_PCI_MODE_OFFS)
  70231. +#define PMR_PCI_MODE_PCIX_133MHZ (0x3 << PMR_PCI_MODE_OFFS)
  70232. +
  70233. +#define PMR_EXP_ROM_SUPPORT BIT8 /* Expansion ROM Active */
  70234. +
  70235. +#define PMR_PCI_RESET_OFFS 31 /* PCI Interface Reset Indication */
  70236. +#define PMR_PCI_RESET_MASK (0x1 << PMR_PCI_RESET_OFFS)
  70237. +#define PMR_PCI_RESET_PCIXRST (0x0 << PMR_PCI_RESET_OFFS)
  70238. +
  70239. +
  70240. +/* PCI Retry Register (PRR) */
  70241. +#define PRR_RETRY_CNTR_OFFS 16 /* Retry Counter */
  70242. +#define PRR_RETRY_CNTR_MAX 0xff
  70243. +#define PRR_RETRY_CNTR_MASK (PRR_RETRY_CNTR_MAX << PRR_RETRY_CNTR_OFFS)
  70244. +
  70245. +
  70246. +/* PCI Discard Timer Register (PDTR) */
  70247. +#define PDTR_TIMER_OFFS 0 /* Timer */
  70248. +#define PDTR_TIMER_MAX 0xffff
  70249. +#define PDTR_TIMER_MIN 0x7F
  70250. +#define PDTR_TIMER_MASK (PDTR_TIMER_MAX << PDTR_TIMER_OFFS)
  70251. +
  70252. +
  70253. +/* PCI Arbiter Control Register (PACR) */
  70254. +#define PACR_BROKEN_DETECT_EN BIT1 /* Broken Detection Enable */
  70255. +
  70256. +#define PACR_BROKEN_VAL_OFFS 3 /* Broken Value */
  70257. +#define PACR_BROKEN_VAL_MASK (0xf << PACR_BROKEN_VAL_OFFS)
  70258. +#define PACR_BROKEN_VAL_CONV_MIN 0x2
  70259. +#define PACR_BROKEN_VAL_PCIX_MIN 0x6
  70260. +
  70261. +#define PACR_PARK_DIS_OFFS 14 /* Parking Disable */
  70262. +#define PACR_PARK_DIS_MAX_AGENT 0x3f
  70263. +#define PACR_PARK_DIS_MASK (PACR_PARK_DIS_MAX_AGENT<<PACR_PARK_DIS_OFFS)
  70264. +#define PACR_PARK_DIS(agent) ((1 << (agent)) << PACR_PARK_DIS_OFFS)
  70265. +
  70266. +#define PACR_ARB_ENABLE BIT31 /* Enable Internal Arbiter */
  70267. +
  70268. +
  70269. +/* PCI P2P Configuration Register (PPCR) */
  70270. +#define PPCR_2ND_BUS_L_OFFS 0 /* 2nd PCI Interface Bus Range Lower */
  70271. +#define PPCR_2ND_BUS_L_MASK (0xff << PPCR_2ND_BUS_L_OFFS)
  70272. +
  70273. +#define PPCR_2ND_BUS_H_OFFS 8 /* 2nd PCI Interface Bus Range Upper */
  70274. +#define PPCR_2ND_BUS_H_MASK (0xff << PPCR_2ND_BUS_H_OFFS)
  70275. +
  70276. +#define PPCR_BUS_NUM_OFFS 16 /* The PCI interface's Bus number */
  70277. +#define PPCR_BUS_NUM_MASK (0xff << PPCR_BUS_NUM_OFFS)
  70278. +
  70279. +#define PPCR_DEV_NUM_OFFS 24 /* The PCI interface’s Device number */
  70280. +#define PPCR_DEV_NUM_MASK (0xff << PPCR_DEV_NUM_OFFS)
  70281. +
  70282. +
  70283. +/* PCI Access Control Base Low Register (PACBLR) */
  70284. +#define PACBLR_EN BIT0 /* Access control window enable */
  70285. +
  70286. +#define PACBLR_ACCPROT BIT4 /* Access Protect */
  70287. +#define PACBLR_WRPROT BIT5 /* Write Protect */
  70288. +
  70289. +#define PACBLR_PCISWAP_OFFS 6 /* PCI slave Data Swap Control */
  70290. +#define PACBLR_PCISWAP_MASK (0x3 << PACBLR_PCISWAP_OFFS)
  70291. +#define PACBLR_PCISWAP_BYTE (0x0 << PACBLR_PCISWAP_OFFS)
  70292. +#define PACBLR_PCISWAP_NO_SWAP (0x1 << PACBLR_PCISWAP_OFFS)
  70293. +#define PACBLR_PCISWAP_BYTE_WORD (0x2 << PACBLR_PCISWAP_OFFS)
  70294. +#define PACBLR_PCISWAP_WORD (0x3 << PACBLR_PCISWAP_OFFS)
  70295. +
  70296. +#define PACBLR_RDMBURST_OFFS 8 /* Read Max Burst */
  70297. +#define PACBLR_RDMBURST_MASK (0x3 << PACBLR_RDMBURST_OFFS)
  70298. +#define PACBLR_RDMBURST_32BYTE (0x0 << PACBLR_RDMBURST_OFFS)
  70299. +#define PACBLR_RDMBURST_64BYTE (0x1 << PACBLR_RDMBURST_OFFS)
  70300. +#define PACBLR_RDMBURST_128BYTE (0x2 << PACBLR_RDMBURST_OFFS)
  70301. +
  70302. +#define PACBLR_RDSIZE_OFFS 10 /* Typical PCI read transaction Size. */
  70303. +#define PACBLR_RDSIZE_MASK (0x3 << PACBLR_RDSIZE_OFFS)
  70304. +#define PACBLR_RDSIZE_32BYTE (0x0 << PACBLR_RDSIZE_OFFS)
  70305. +#define PACBLR_RDSIZE_64BYTE (0x1 << PACBLR_RDSIZE_OFFS)
  70306. +#define PACBLR_RDSIZE_128BYTE (0x2 << PACBLR_RDSIZE_OFFS)
  70307. +#define PACBLR_RDSIZE_256BYTE (0x3 << PACBLR_RDSIZE_OFFS)
  70308. +
  70309. +#define PACBLR_BASE_L_OFFS 12 /* Corresponds to address bits [31:12] */
  70310. +#define PACBLR_BASE_L_MASK (0xfffff << PACBLR_BASE_L_OFFS)
  70311. +#define PACBLR_BASE_L_ALIGNMENT (1 << PACBLR_BASE_L_OFFS)
  70312. +#define PACBLR_BASE_ALIGN_UP(base) \
  70313. + ((base+PACBLR_BASE_L_ALIGNMENT)&PACBLR_BASE_L_MASK)
  70314. +#define PACBLR_BASE_ALIGN_DOWN(base) (base & PACBLR_BASE_L_MASK)
  70315. +
  70316. +
  70317. +/* PCI Access Control Base High Register (PACBHR) */
  70318. +#define PACBHR_BASE_H_OFFS 0 /* Corresponds to address bits [63:32] */
  70319. +#define PACBHR_CTRL_BASE_H_MASK (0xffffffff << PACBHR_BASE_H_OFFS)
  70320. +
  70321. +/* PCI Access Control Size Register (PACSR) */
  70322. +#define PACSR_WRMBURST_OFFS 8 /* Write Max Burst */
  70323. +#define PACSR_WRMBURST_MASK (0x3 << PACSR_WRMBURST_OFFS)
  70324. +#define PACSR_WRMBURST_32BYTE (0x0 << PACSR_WRMBURST_OFFS)
  70325. +#define PACSR_WRMBURST_64BYTE (0x1 << PACSR_WRMBURST_OFFS)
  70326. +#define PACSR_WRMBURST_128BYTE (0x2 << PACSR_WRMBURST_OFFS)
  70327. +
  70328. +#define PACSR_PCI_ORDERING BIT11 /* PCI Ordering required */
  70329. +
  70330. +#define PACSR_SIZE_OFFS 12 /* PCI access window size */
  70331. +#define PACSR_SIZE_MASK (0xfffff << PACSR_SIZE_OFFS)
  70332. +#define PACSR_SIZE_ALIGNMENT (1 << PACSR_SIZE_OFFS)
  70333. +#define PACSR_SIZE_ALIGN_UP(size) \
  70334. + ((size+PACSR_SIZE_ALIGNMENT)&PACSR_SIZE_MASK)
  70335. +#define PACSR_SIZE_ALIGN_DOWN(size) (size & PACSR_SIZE_MASK)
  70336. +
  70337. +
  70338. +/***************************************/
  70339. +/* PCI Configuration Access Registers */
  70340. +/***************************************/
  70341. +
  70342. +#define PCI_CONFIG_ADDR_REG(pciIf) (0x30C78 - ((pciIf) * 0x80) )
  70343. +#define PCI_CONFIG_DATA_REG(pciIf) (0x30C7C - ((pciIf) * 0x80) )
  70344. +#define PCI_INT_ACK_REG(pciIf) (0x30C34 + ((pciIf) * 0x80) )
  70345. +
  70346. +/* PCI Configuration Address Register (PCAR) */
  70347. +#define PCAR_REG_NUM_OFFS 2
  70348. +#define PCAR_REG_NUM_MASK (0x3F << PCAR_REG_NUM_OFFS)
  70349. +
  70350. +#define PCAR_FUNC_NUM_OFFS 8
  70351. +#define PCAR_FUNC_NUM_MASK (0x7 << PCAR_FUNC_NUM_OFFS)
  70352. +
  70353. +#define PCAR_DEVICE_NUM_OFFS 11
  70354. +#define PCAR_DEVICE_NUM_MASK (0x1F << PCAR_DEVICE_NUM_OFFS)
  70355. +
  70356. +#define PCAR_BUS_NUM_OFFS 16
  70357. +#define PCAR_BUS_NUM_MASK (0xFF << PCAR_BUS_NUM_OFFS)
  70358. +
  70359. +#define PCAR_CONFIG_EN BIT31
  70360. +
  70361. +
  70362. +/***************************************/
  70363. +/* PCI Configuration registers */
  70364. +/***************************************/
  70365. +
  70366. +/*********************************************/
  70367. +/* PCI Configuration, Function 0, Registers */
  70368. +/*********************************************/
  70369. +
  70370. +/* Marvell Specific */
  70371. +#define PCI_SCS0_BASE_ADDR_LOW 0x010
  70372. +#define PCI_SCS0_BASE_ADDR_HIGH 0x014
  70373. +#define PCI_SCS1_BASE_ADDR_LOW 0x018
  70374. +#define PCI_SCS1_BASE_ADDR_HIGH 0x01C
  70375. +#define PCI_INTER_REG_MEM_MAPPED_BASE_ADDR_L 0x020
  70376. +#define PCI_INTER_REG_MEM_MAPPED_BASE_ADDR_H 0x024
  70377. +
  70378. +/* capability list */
  70379. +#define PCI_POWER_MNG_CAPABILITY 0x040
  70380. +#define PCI_POWER_MNG_STATUS_CONTROL 0x044
  70381. +#define PCI_VPD_ADDRESS_REG 0x048
  70382. +#define PCI_VPD_DATA_REG 0x04c
  70383. +#define PCI_MSI_MESSAGE_CONTROL 0x050
  70384. +#define PCI_MSI_MESSAGE_ADDR 0x054
  70385. +#define PCI_MSI_MESSAGE_UPPER_ADDR 0x058
  70386. +#define PCI_MSI_MESSAGE_DATA 0x05c
  70387. +#define PCIX_COMMAND 0x060
  70388. +#define PCIX_STATUS 0x064
  70389. +#define PCI_COMPACT_PCI_HOT_SWAP 0x068
  70390. +
  70391. +
  70392. +/*********************************************/
  70393. +/* PCI Configuration, Function 1, Registers */
  70394. +/*********************************************/
  70395. +
  70396. +#define PCI_SCS2_BASE_ADDR_LOW 0x10
  70397. +#define PCI_SCS2_BASE_ADDR_HIGH 0x14
  70398. +#define PCI_SCS3_BASE_ADDR_LOW 0x18
  70399. +#define PCI_SCS3_BASE_ADDR_HIGH 0x1c
  70400. +
  70401. +
  70402. +/***********************************************/
  70403. +/* PCI Configuration, Function 2, Registers */
  70404. +/***********************************************/
  70405. +
  70406. +#define PCI_DEVCS0_BASE_ADDR_LOW 0x10
  70407. +#define PCI_DEVCS0_BASE_ADDR_HIGH 0x14
  70408. +#define PCI_DEVCS1_BASE_ADDR_LOW 0x18
  70409. +#define PCI_DEVCS1_BASE_ADDR_HIGH 0x1c
  70410. +#define PCI_DEVCS2_BASE_ADDR_LOW 0x20
  70411. +#define PCI_DEVCS2_BASE_ADDR_HIGH 0x24
  70412. +
  70413. +/***********************************************/
  70414. +/* PCI Configuration, Function 3, Registers */
  70415. +/***********************************************/
  70416. +
  70417. +#define PCI_BOOTCS_BASE_ADDR_LOW 0x18
  70418. +#define PCI_BOOTCS_BASE_ADDR_HIGH 0x1c
  70419. +
  70420. +/***********************************************/
  70421. +/* PCI Configuration, Function 4, Registers */
  70422. +/***********************************************/
  70423. +
  70424. +#define PCI_P2P_MEM0_BASE_ADDR_LOW 0x10
  70425. +#define PCI_P2P_MEM0_BASE_ADDR_HIGH 0x14
  70426. +#define PCI_P2P_IO_BASE_ADDR 0x20
  70427. +#define PCI_INTER_REGS_IO_MAPPED_BASE_ADDR 0x24
  70428. +
  70429. +/* PCIX_STATUS register fields (PXS) */
  70430. +
  70431. +#define PXS_FN_OFFS 0 /* Description Number */
  70432. +#define PXS_FN_MASK (0x7 << PXS_FN_OFFS)
  70433. +
  70434. +#define PXS_DN_OFFS 3 /* Device Number */
  70435. +#define PXS_DN_MASK (0x1f << PXS_DN_OFFS)
  70436. +
  70437. +#define PXS_BN_OFFS 8 /* Bus Number */
  70438. +#define PXS_BN_MASK (0xff << PXS_BN_OFFS)
  70439. +
  70440. +
  70441. +/* PCI Error Report Register Map */
  70442. +#define PCI_SERRN_MASK_REG(pciIf) (0x30c28 + (pciIf * 0x80))
  70443. +#define PCI_CAUSE_REG(pciIf) (0x31d58 + (pciIf * 0x80))
  70444. +#define PCI_MASK_REG(pciIf) (0x31d5C + (pciIf * 0x80))
  70445. +#define PCI_ERROR_ADDR_LOW_REG(pciIf) (0x31d40 + (pciIf * 0x80))
  70446. +#define PCI_ERROR_ADDR_HIGH_REG(pciIf) (0x31d44 + (pciIf * 0x80))
  70447. +#define PCI_ERROR_ATTRIBUTE_REG(pciIf) (0x31d48 + (pciIf * 0x80))
  70448. +#define PCI_ERROR_COMMAND_REG(pciIf) (0x31d50 + (pciIf * 0x80))
  70449. +
  70450. +/* PCI Interrupt Cause Register (PICR) */
  70451. +#define PICR_ERR_SEL_OFFS 27
  70452. +#define PICR_ERR_SEL_MASK (0x1f << PICR_ERR_SEL_OFFS)
  70453. +
  70454. +/* PCI Error Command Register (PECR) */
  70455. +#define PECR_ERR_CMD_OFFS 0
  70456. +#define PECR_ERR_CMD_MASK (0xf << PECR_ERR_CMD_OFFS)
  70457. +#define PECR_DAC BIT4
  70458. +
  70459. +
  70460. +/* defaults */
  70461. +/* Set bits means value is about to change according to new value */
  70462. +#define PCI_COMMAND_DEFAULT_MASK 0xffffdff1
  70463. +#define PCI_COMMAND_DEFAULT \
  70464. + (PCR_MASTER_WR_TRIG_WHOLE | \
  70465. + PCR_MASTER_RD_TRIG_WHOLE | \
  70466. + PCR_MASTER_MEM_RD_LINE_EN | \
  70467. + PCR_MASTER_MEM_RD_MULT_EN | \
  70468. + PCR_NS_ACCORDING_RCV_TRANS | \
  70469. + PCR_MASTER_PCIX_REQ64N_EN | \
  70470. + PCR_MASTER_DAC_EN | \
  70471. + PCR_MASTER_M64_ALLIGN | \
  70472. + PCR_ERRORS_PROPAGATION_EN)
  70473. +
  70474. +
  70475. +#define PCI_ARBITER_CTRL_DEFAULT_MASK 0x801fc07a
  70476. +#define PCI_ARBITER_CTRL_DEFAULT \
  70477. + (PACR_BROKEN_VAL_PCIX_MIN << PACR_BROKEN_VAL_OFFS)
  70478. +
  70479. +
  70480. +#endif /* #ifndef __INCPCIREGSH */
  70481. +
  70482. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c
  70483. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c 1970-01-01 01:00:00.000000000 +0100
  70484. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.c 2011-08-01 14:38:19.000000000 +0200
  70485. @@ -0,0 +1,669 @@
  70486. +/*******************************************************************************
  70487. +Copyright (C) Marvell International Ltd. and its affiliates
  70488. +
  70489. +This software file (the "File") is owned and distributed by Marvell
  70490. +International Ltd. and/or its affiliates ("Marvell") under the following
  70491. +alternative licensing terms. Once you have made an election to distribute the
  70492. +File under one of the following license alternatives, please (i) delete this
  70493. +introductory statement regarding license alternatives, (ii) delete the two
  70494. +license alternatives that you have not elected to use and (iii) preserve the
  70495. +Marvell copyright notice above.
  70496. +
  70497. +********************************************************************************
  70498. +Marvell Commercial License Option
  70499. +
  70500. +If you received this File from Marvell and you have entered into a commercial
  70501. +license agreement (a "Commercial License") with Marvell, the File is licensed
  70502. +to you under the terms of the applicable Commercial License.
  70503. +
  70504. +********************************************************************************
  70505. +Marvell GPL License Option
  70506. +
  70507. +If you received this File from Marvell, you may opt to use, redistribute and/or
  70508. +modify this File in accordance with the terms and conditions of the General
  70509. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  70510. +available along with the File in the license.txt file or by writing to the Free
  70511. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  70512. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  70513. +
  70514. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  70515. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  70516. +DISCLAIMED. The GPL License provides additional details about this warranty
  70517. +disclaimer.
  70518. +********************************************************************************
  70519. +Marvell BSD License Option
  70520. +
  70521. +If you received this File from Marvell, you may opt to use, redistribute and/or
  70522. +modify this File under the following licensing terms.
  70523. +Redistribution and use in source and binary forms, with or without modification,
  70524. +are permitted provided that the following conditions are met:
  70525. +
  70526. + * Redistributions of source code must retain the above copyright notice,
  70527. + this list of conditions and the following disclaimer.
  70528. +
  70529. + * Redistributions in binary form must reproduce the above copyright
  70530. + notice, this list of conditions and the following disclaimer in the
  70531. + documentation and/or other materials provided with the distribution.
  70532. +
  70533. + * Neither the name of Marvell nor the names of its contributors may be
  70534. + used to endorse or promote products derived from this software without
  70535. + specific prior written permission.
  70536. +
  70537. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  70538. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  70539. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  70540. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  70541. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  70542. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  70543. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  70544. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  70545. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  70546. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  70547. +
  70548. +*******************************************************************************/
  70549. +
  70550. +#include "mvPciIf.h"
  70551. +#include "ctrlEnv/sys/mvSysPex.h"
  70552. +
  70553. +#if defined(MV_INCLUDE_PCI)
  70554. +#include "ctrlEnv/sys/mvSysPci.h"
  70555. +#endif
  70556. +
  70557. +
  70558. +/* defines */
  70559. +#ifdef MV_DEBUG
  70560. + #define DB(x) x
  70561. +#else
  70562. + #define DB(x)
  70563. +#endif
  70564. +
  70565. +
  70566. +/*******************************************************************************
  70567. +* mvPciInit - Initialize PCI interfaces
  70568. +*
  70569. +* DESCRIPTION:
  70570. +*
  70571. +* INPUT:
  70572. +*
  70573. +*
  70574. +* OUTPUT:
  70575. +* None.
  70576. +*
  70577. +* RETURN:
  70578. +* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
  70579. +*
  70580. +*******************************************************************************/
  70581. +
  70582. +
  70583. +MV_STATUS mvPciIfInit(MV_U32 pciIf, PCI_IF_MODE pciIfmode)
  70584. +{
  70585. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  70586. +
  70587. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  70588. + {
  70589. + #if defined(MV_INCLUDE_PCI)
  70590. +
  70591. + MV_PCI_MOD pciMod;
  70592. +
  70593. + if (PCI_IF_MODE_HOST == pciIfmode)
  70594. + {
  70595. + pciMod = MV_PCI_MOD_HOST;
  70596. + }
  70597. + else if (PCI_IF_MODE_DEVICE == pciIfmode)
  70598. + {
  70599. + pciMod = MV_PCI_MOD_DEVICE;
  70600. + }
  70601. + else
  70602. + {
  70603. + mvOsPrintf("%s: ERROR!!! Bus %d mode %d neither host nor device!\n",
  70604. + __FUNCTION__, pciIf, pciIfmode);
  70605. + return MV_FAIL;
  70606. + }
  70607. +
  70608. + return mvPciInit(pciIf - MV_PCI_START_IF, pciMod);
  70609. + #else
  70610. + return MV_OK;
  70611. + #endif
  70612. + }
  70613. + else if (PCI_IF_TYPE_PEX == pciIfType)
  70614. + {
  70615. + #if defined(MV_INCLUDE_PEX)
  70616. +
  70617. + MV_PEX_TYPE pexType;
  70618. +
  70619. + if (PCI_IF_MODE_HOST == pciIfmode)
  70620. + {
  70621. + pexType = MV_PEX_ROOT_COMPLEX;
  70622. + }
  70623. + else if (PCI_IF_MODE_DEVICE == pciIfmode)
  70624. + {
  70625. + pexType = MV_PEX_END_POINT;
  70626. + }
  70627. + else
  70628. + {
  70629. + mvOsPrintf("%s: ERROR!!! Bus %d type %d neither root complex nor" \
  70630. + " end point\n", __FUNCTION__, pciIf, pciIfmode);
  70631. + return MV_FAIL;
  70632. + }
  70633. + return mvPexInit(pciIf - MV_PEX_START_IF, pexType);
  70634. +
  70635. + #else
  70636. + return MV_OK;
  70637. + #endif
  70638. +
  70639. + }
  70640. + else
  70641. + {
  70642. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  70643. + }
  70644. +
  70645. + return MV_FAIL;
  70646. +
  70647. +}
  70648. +
  70649. +/* PCI configuration space read write */
  70650. +
  70651. +/*******************************************************************************
  70652. +* mvPciConfigRead - Read from configuration space
  70653. +*
  70654. +* DESCRIPTION:
  70655. +* This function performs a 32 bit read from PCI configuration space.
  70656. +* It supports both type 0 and type 1 of Configuration Transactions
  70657. +* (local and over bridge). In order to read from local bus segment, use
  70658. +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
  70659. +* will result configuration transaction of type 1 (over bridge).
  70660. +*
  70661. +* INPUT:
  70662. +* pciIf - PCI interface number.
  70663. +* bus - PCI segment bus number.
  70664. +* dev - PCI device number.
  70665. +* func - Function number.
  70666. +* regOffs - Register offset.
  70667. +*
  70668. +* OUTPUT:
  70669. +* None.
  70670. +*
  70671. +* RETURN:
  70672. +* 32bit register data, 0xffffffff on error
  70673. +*
  70674. +*******************************************************************************/
  70675. +MV_U32 mvPciIfConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  70676. + MV_U32 regOff)
  70677. +{
  70678. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  70679. +
  70680. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  70681. + {
  70682. + #if defined(MV_INCLUDE_PCI)
  70683. + return mvPciConfigRead(pciIf - MV_PCI_START_IF,
  70684. + bus,
  70685. + dev,
  70686. + func,
  70687. + regOff);
  70688. + #else
  70689. + return 0xffffffff;
  70690. + #endif
  70691. + }
  70692. + else if (PCI_IF_TYPE_PEX == pciIfType)
  70693. + {
  70694. + #if defined(MV_INCLUDE_PEX)
  70695. + return mvPexConfigRead(pciIf - MV_PEX_START_IF,
  70696. + bus,
  70697. + dev,
  70698. + func,
  70699. + regOff);
  70700. + #else
  70701. + return 0xffffffff;
  70702. + #endif
  70703. +
  70704. + }
  70705. + else
  70706. + {
  70707. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  70708. + }
  70709. +
  70710. + return 0;
  70711. +
  70712. +}
  70713. +
  70714. +/*******************************************************************************
  70715. +* mvPciConfigWrite - Write to configuration space
  70716. +*
  70717. +* DESCRIPTION:
  70718. +* This function performs a 32 bit write to PCI configuration space.
  70719. +* It supports both type 0 and type 1 of Configuration Transactions
  70720. +* (local and over bridge). In order to write to local bus segment, use
  70721. +* bus number retrieved from mvPciLocalBusNumGet(). Other bus numbers
  70722. +* will result configuration transaction of type 1 (over bridge).
  70723. +*
  70724. +* INPUT:
  70725. +* pciIf - PCI interface number.
  70726. +* bus - PCI segment bus number.
  70727. +* dev - PCI device number.
  70728. +* func - Function number.
  70729. +* regOffs - Register offset.
  70730. +* data - 32bit data.
  70731. +*
  70732. +* OUTPUT:
  70733. +* None.
  70734. +*
  70735. +* RETURN:
  70736. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  70737. +*
  70738. +*******************************************************************************/
  70739. +MV_STATUS mvPciIfConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  70740. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  70741. +{
  70742. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  70743. +
  70744. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  70745. + {
  70746. + #if defined(MV_INCLUDE_PCI)
  70747. + return mvPciConfigWrite(pciIf - MV_PCI_START_IF,
  70748. + bus,
  70749. + dev,
  70750. + func,
  70751. + regOff,
  70752. + data);
  70753. + #else
  70754. + return MV_OK;
  70755. + #endif
  70756. + }
  70757. + else if (PCI_IF_TYPE_PEX == pciIfType)
  70758. + {
  70759. + #if defined(MV_INCLUDE_PEX)
  70760. + return mvPexConfigWrite(pciIf - MV_PEX_START_IF,
  70761. + bus,
  70762. + dev,
  70763. + func,
  70764. + regOff,
  70765. + data);
  70766. + #else
  70767. + return MV_OK;
  70768. + #endif
  70769. +
  70770. + }
  70771. + else
  70772. + {
  70773. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  70774. + }
  70775. +
  70776. + return MV_FAIL;
  70777. +
  70778. +}
  70779. +
  70780. +/*******************************************************************************
  70781. +* mvPciMasterEnable - Enable/disale PCI interface master transactions.
  70782. +*
  70783. +* DESCRIPTION:
  70784. +* This function performs read modified write to PCI command status
  70785. +* (offset 0x4) to set/reset bit 2. After this bit is set, the PCI
  70786. +* master is allowed to gain ownership on the bus, otherwise it is
  70787. +* incapable to do so.
  70788. +*
  70789. +* INPUT:
  70790. +* pciIf - PCI interface number.
  70791. +* enable - Enable/disable parameter.
  70792. +*
  70793. +* OUTPUT:
  70794. +* None.
  70795. +*
  70796. +* RETURN:
  70797. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  70798. +*
  70799. +*******************************************************************************/
  70800. +MV_STATUS mvPciIfMasterEnable(MV_U32 pciIf, MV_BOOL enable)
  70801. +{
  70802. +
  70803. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  70804. +
  70805. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  70806. + {
  70807. + #if defined(MV_INCLUDE_PCI)
  70808. + return mvPciMasterEnable(pciIf - MV_PCI_START_IF,
  70809. + enable);
  70810. + #else
  70811. + return MV_OK;
  70812. + #endif
  70813. + }
  70814. + else if (PCI_IF_TYPE_PEX == pciIfType)
  70815. + {
  70816. + #if defined(MV_INCLUDE_PEX)
  70817. + return mvPexMasterEnable(pciIf - MV_PEX_START_IF,
  70818. + enable);
  70819. + #else
  70820. + return MV_OK;
  70821. + #endif
  70822. + }
  70823. + else
  70824. + {
  70825. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  70826. + }
  70827. +
  70828. + return MV_FAIL;
  70829. +
  70830. +}
  70831. +
  70832. +
  70833. +/*******************************************************************************
  70834. +* mvPciSlaveEnable - Enable/disale PCI interface slave transactions.
  70835. +*
  70836. +* DESCRIPTION:
  70837. +* This function performs read modified write to PCI command status
  70838. +* (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
  70839. +* the PCI slave is allowed to respond to PCI IO space access (bit 0)
  70840. +* and PCI memory space access (bit 1).
  70841. +*
  70842. +* INPUT:
  70843. +* pciIf - PCI interface number.
  70844. +* dev - PCI device number.
  70845. +* enable - Enable/disable parameter.
  70846. +*
  70847. +* OUTPUT:
  70848. +* None.
  70849. +*
  70850. +* RETURN:
  70851. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  70852. +*
  70853. +*******************************************************************************/
  70854. +MV_STATUS mvPciIfSlaveEnable(MV_U32 pciIf,MV_U32 bus, MV_U32 dev, MV_BOOL enable)
  70855. +{
  70856. +
  70857. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  70858. +
  70859. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  70860. + {
  70861. + #if defined(MV_INCLUDE_PCI)
  70862. + return mvPciSlaveEnable(pciIf - MV_PCI_START_IF,bus,dev,
  70863. + enable);
  70864. + #else
  70865. + return MV_OK;
  70866. + #endif
  70867. + }
  70868. + else if (PCI_IF_TYPE_PEX == pciIfType)
  70869. + {
  70870. + #if defined(MV_INCLUDE_PEX)
  70871. + return mvPexSlaveEnable(pciIf - MV_PEX_START_IF,bus,dev,
  70872. + enable);
  70873. + #else
  70874. + return MV_OK;
  70875. + #endif
  70876. + }
  70877. + else
  70878. + {
  70879. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  70880. + }
  70881. +
  70882. + return MV_FAIL;
  70883. +
  70884. +}
  70885. +
  70886. +/*******************************************************************************
  70887. +* mvPciLocalBusNumSet - Set PCI interface local bus number.
  70888. +*
  70889. +* DESCRIPTION:
  70890. +* This function sets given PCI interface its local bus number.
  70891. +* Note: In case the PCI interface is PCI-X, the information is read-only.
  70892. +*
  70893. +* INPUT:
  70894. +* pciIf - PCI interface number.
  70895. +* busNum - Bus number.
  70896. +*
  70897. +* OUTPUT:
  70898. +* None.
  70899. +*
  70900. +* RETURN:
  70901. +* MV_NOT_ALLOWED in case PCI interface is PCI-X.
  70902. +* MV_BAD_PARAM on bad parameters ,
  70903. +* otherwise MV_OK
  70904. +*
  70905. +*******************************************************************************/
  70906. +MV_STATUS mvPciIfLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum)
  70907. +{
  70908. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  70909. +
  70910. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  70911. + {
  70912. + #if defined(MV_INCLUDE_PCI)
  70913. + return mvPciLocalBusNumSet(pciIf - MV_PCI_START_IF,
  70914. + busNum);
  70915. + #else
  70916. + return MV_OK;
  70917. + #endif
  70918. + }
  70919. + else if (PCI_IF_TYPE_PEX == pciIfType)
  70920. + {
  70921. + #if defined(MV_INCLUDE_PEX)
  70922. + return mvPexLocalBusNumSet(pciIf - MV_PEX_START_IF,
  70923. + busNum);
  70924. + #else
  70925. + return MV_OK;
  70926. + #endif
  70927. + }
  70928. + else
  70929. + {
  70930. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  70931. + }
  70932. +
  70933. + return MV_FAIL;
  70934. +
  70935. +}
  70936. +
  70937. +/*******************************************************************************
  70938. +* mvPciLocalBusNumGet - Get PCI interface local bus number.
  70939. +*
  70940. +* DESCRIPTION:
  70941. +* This function gets the local bus number of a given PCI interface.
  70942. +*
  70943. +* INPUT:
  70944. +* pciIf - PCI interface number.
  70945. +*
  70946. +* OUTPUT:
  70947. +* None.
  70948. +*
  70949. +* RETURN:
  70950. +* Local bus number.0xffffffff on Error
  70951. +*
  70952. +*******************************************************************************/
  70953. +MV_U32 mvPciIfLocalBusNumGet(MV_U32 pciIf)
  70954. +{
  70955. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  70956. +
  70957. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  70958. + {
  70959. + #if defined(MV_INCLUDE_PCI)
  70960. + return mvPciLocalBusNumGet(pciIf - MV_PCI_START_IF);
  70961. + #else
  70962. + return 0xFFFFFFFF;
  70963. + #endif
  70964. + }
  70965. + else if (PCI_IF_TYPE_PEX == pciIfType)
  70966. + {
  70967. + #if defined(MV_INCLUDE_PEX)
  70968. + return mvPexLocalBusNumGet(pciIf - MV_PEX_START_IF);
  70969. + #else
  70970. + return 0xFFFFFFFF;
  70971. + #endif
  70972. +
  70973. + }
  70974. + else
  70975. + {
  70976. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n",__FUNCTION__, pciIf);
  70977. + }
  70978. +
  70979. + return 0;
  70980. +
  70981. +}
  70982. +
  70983. +
  70984. +/*******************************************************************************
  70985. +* mvPciLocalDevNumSet - Set PCI interface local device number.
  70986. +*
  70987. +* DESCRIPTION:
  70988. +* This function sets given PCI interface its local device number.
  70989. +* Note: In case the PCI interface is PCI-X, the information is read-only.
  70990. +*
  70991. +* INPUT:
  70992. +* pciIf - PCI interface number.
  70993. +* devNum - Device number.
  70994. +*
  70995. +* OUTPUT:
  70996. +* None.
  70997. +*
  70998. +* RETURN:
  70999. +* MV_NOT_ALLOWED in case PCI interface is PCI-X. MV_BAD_PARAM on bad parameters ,
  71000. +* otherwise MV_OK
  71001. +*
  71002. +*******************************************************************************/
  71003. +MV_STATUS mvPciIfLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum)
  71004. +{
  71005. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  71006. +
  71007. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  71008. + {
  71009. + #if defined(MV_INCLUDE_PCI)
  71010. + return mvPciLocalDevNumSet(pciIf - MV_PCI_START_IF,
  71011. + devNum);
  71012. + #else
  71013. + return MV_OK;
  71014. + #endif
  71015. + }
  71016. + else if (PCI_IF_TYPE_PEX == pciIfType)
  71017. + {
  71018. + #if defined(MV_INCLUDE_PEX)
  71019. + return mvPexLocalDevNumSet(pciIf - MV_PEX_START_IF,
  71020. + devNum);
  71021. + #else
  71022. + return MV_OK;
  71023. + #endif
  71024. + }
  71025. + else
  71026. + {
  71027. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  71028. + }
  71029. +
  71030. + return MV_FAIL;
  71031. +
  71032. +}
  71033. +
  71034. +/*******************************************************************************
  71035. +* mvPciLocalDevNumGet - Get PCI interface local device number.
  71036. +*
  71037. +* DESCRIPTION:
  71038. +* This function gets the local device number of a given PCI interface.
  71039. +*
  71040. +* INPUT:
  71041. +* pciIf - PCI interface number.
  71042. +*
  71043. +* OUTPUT:
  71044. +* None.
  71045. +*
  71046. +* RETURN:
  71047. +* Local device number. 0xffffffff on Error
  71048. +*
  71049. +*******************************************************************************/
  71050. +MV_U32 mvPciIfLocalDevNumGet(MV_U32 pciIf)
  71051. +{
  71052. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  71053. +
  71054. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  71055. + {
  71056. + #if defined(MV_INCLUDE_PCI)
  71057. + return mvPciLocalDevNumGet(pciIf - MV_PCI_START_IF);
  71058. + #else
  71059. + return 0xFFFFFFFF;
  71060. + #endif
  71061. + }
  71062. + else if (PCI_IF_TYPE_PEX == pciIfType)
  71063. + {
  71064. + #if defined(MV_INCLUDE_PEX)
  71065. + return mvPexLocalDevNumGet(pciIf - MV_PEX_START_IF);
  71066. + #else
  71067. + return 0xFFFFFFFF;
  71068. + #endif
  71069. +
  71070. + }
  71071. + else
  71072. + {
  71073. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  71074. + }
  71075. +
  71076. + return 0;
  71077. +
  71078. +}
  71079. +
  71080. +/*******************************************************************************
  71081. +* mvPciIfTypeGet -
  71082. +*
  71083. +* DESCRIPTION:
  71084. +*
  71085. +* INPUT:
  71086. +*
  71087. +* OUTPUT:
  71088. +* None.
  71089. +*
  71090. +* RETURN:
  71091. +*
  71092. +*******************************************************************************/
  71093. +
  71094. +PCI_IF_TYPE mvPciIfTypeGet(MV_U32 pciIf)
  71095. +{
  71096. +
  71097. + if ((pciIf >= MV_PCI_START_IF)&&(pciIf < MV_PCI_MAX_IF + MV_PCI_START_IF))
  71098. + {
  71099. + return PCI_IF_TYPE_CONVEN_PCIX;
  71100. + }
  71101. + else if ((pciIf >= MV_PEX_START_IF) &&
  71102. + (pciIf < MV_PEX_MAX_IF + MV_PEX_START_IF))
  71103. + {
  71104. + return PCI_IF_TYPE_PEX;
  71105. +
  71106. + }
  71107. + else
  71108. + {
  71109. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  71110. + }
  71111. +
  71112. + return 0xffffffff;
  71113. +
  71114. +}
  71115. +
  71116. +/*******************************************************************************
  71117. +* mvPciIfTypeGet -
  71118. +*
  71119. +* DESCRIPTION:
  71120. +*
  71121. +* INPUT:
  71122. +*
  71123. +* OUTPUT:
  71124. +* None.
  71125. +*
  71126. +* RETURN:
  71127. +*
  71128. +*******************************************************************************/
  71129. +
  71130. +MV_U32 mvPciRealIfNumGet(MV_U32 pciIf)
  71131. +{
  71132. +
  71133. + PCI_IF_TYPE pciIfType = mvPciIfTypeGet(pciIf);
  71134. +
  71135. + if (PCI_IF_TYPE_CONVEN_PCIX == pciIfType)
  71136. + {
  71137. + return (pciIf - MV_PCI_START_IF);
  71138. + }
  71139. + else if (PCI_IF_TYPE_PEX == pciIfType)
  71140. + {
  71141. + return (pciIf - MV_PEX_START_IF);
  71142. +
  71143. + }
  71144. + else
  71145. + {
  71146. + mvOsPrintf("%s: ERROR!!! Invalid pciIf %d\n", __FUNCTION__, pciIf);
  71147. + }
  71148. +
  71149. + return 0xffffffff;
  71150. +
  71151. +}
  71152. +
  71153. +
  71154. +
  71155. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h
  71156. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h 1970-01-01 01:00:00.000000000 +0100
  71157. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIf.h 2011-08-01 14:38:19.000000000 +0200
  71158. @@ -0,0 +1,134 @@
  71159. +/*******************************************************************************
  71160. +Copyright (C) Marvell International Ltd. and its affiliates
  71161. +
  71162. +This software file (the "File") is owned and distributed by Marvell
  71163. +International Ltd. and/or its affiliates ("Marvell") under the following
  71164. +alternative licensing terms. Once you have made an election to distribute the
  71165. +File under one of the following license alternatives, please (i) delete this
  71166. +introductory statement regarding license alternatives, (ii) delete the two
  71167. +license alternatives that you have not elected to use and (iii) preserve the
  71168. +Marvell copyright notice above.
  71169. +
  71170. +********************************************************************************
  71171. +Marvell Commercial License Option
  71172. +
  71173. +If you received this File from Marvell and you have entered into a commercial
  71174. +license agreement (a "Commercial License") with Marvell, the File is licensed
  71175. +to you under the terms of the applicable Commercial License.
  71176. +
  71177. +********************************************************************************
  71178. +Marvell GPL License Option
  71179. +
  71180. +If you received this File from Marvell, you may opt to use, redistribute and/or
  71181. +modify this File in accordance with the terms and conditions of the General
  71182. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  71183. +available along with the File in the license.txt file or by writing to the Free
  71184. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  71185. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  71186. +
  71187. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  71188. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  71189. +DISCLAIMED. The GPL License provides additional details about this warranty
  71190. +disclaimer.
  71191. +********************************************************************************
  71192. +Marvell BSD License Option
  71193. +
  71194. +If you received this File from Marvell, you may opt to use, redistribute and/or
  71195. +modify this File under the following licensing terms.
  71196. +Redistribution and use in source and binary forms, with or without modification,
  71197. +are permitted provided that the following conditions are met:
  71198. +
  71199. + * Redistributions of source code must retain the above copyright notice,
  71200. + this list of conditions and the following disclaimer.
  71201. +
  71202. + * Redistributions in binary form must reproduce the above copyright
  71203. + notice, this list of conditions and the following disclaimer in the
  71204. + documentation and/or other materials provided with the distribution.
  71205. +
  71206. + * Neither the name of Marvell nor the names of its contributors may be
  71207. + used to endorse or promote products derived from this software without
  71208. + specific prior written permission.
  71209. +
  71210. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  71211. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  71212. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  71213. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  71214. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  71215. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  71216. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  71217. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  71218. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  71219. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  71220. +
  71221. +*******************************************************************************/
  71222. +
  71223. +#ifndef __INCPCIIFH
  71224. +#define __INCPCIIFH
  71225. +
  71226. +#include "mvSysHwConfig.h"
  71227. +#include "pci-if/mvPciIfRegs.h"
  71228. +#if defined(MV_INCLUDE_PEX)
  71229. +#include "pex/mvPex.h"
  71230. +#endif
  71231. +#if defined(MV_INCLUDE_PCI)
  71232. +#include "pci/mvPci.h"
  71233. +#endif
  71234. +#include "ctrlEnv/mvCtrlEnvLib.h"
  71235. +#include "ctrlEnv/mvCtrlEnvAddrDec.h"
  71236. +
  71237. +typedef enum _mvPCIIfType
  71238. +{
  71239. + PCI_IF_TYPE_CONVEN_PCIX,
  71240. + PCI_IF_TYPE_PEX
  71241. +
  71242. +}PCI_IF_TYPE;
  71243. +
  71244. +typedef enum _mvPCIIfMode
  71245. +{
  71246. + PCI_IF_MODE_HOST,
  71247. + PCI_IF_MODE_DEVICE
  71248. +}PCI_IF_MODE;
  71249. +
  71250. +
  71251. +/* Global Functions prototypes */
  71252. +
  71253. +/* mvPciIfInit - Initialize PCI interfaces*/
  71254. +MV_STATUS mvPciIfInit(MV_U32 pciIf, PCI_IF_MODE pciIfmode);
  71255. +
  71256. +/* mvPciIfConfigRead - Read from configuration space */
  71257. +MV_U32 mvPciIfConfigRead (MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  71258. + MV_U32 func,MV_U32 regOff);
  71259. +
  71260. +/* mvPciIfConfigWrite - Write to configuration space */
  71261. +MV_STATUS mvPciIfConfigWrite(MV_U32 pciIf, MV_U32 bus, MV_U32 dev,
  71262. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  71263. +
  71264. +/* mvPciIfMasterEnable - Enable/disale PCI interface master transactions.*/
  71265. +MV_STATUS mvPciIfMasterEnable(MV_U32 pciIf, MV_BOOL enable);
  71266. +
  71267. +/* mvPciIfSlaveEnable - Enable/disale PCI interface slave transactions.*/
  71268. +MV_STATUS mvPciIfSlaveEnable(MV_U32 pciIf,MV_U32 bus, MV_U32 dev,
  71269. + MV_BOOL enable);
  71270. +
  71271. +/* mvPciIfLocalBusNumSet - Set PCI interface local bus number.*/
  71272. +MV_STATUS mvPciIfLocalBusNumSet(MV_U32 pciIf, MV_U32 busNum);
  71273. +
  71274. +/* mvPciIfLocalBusNumGet - Get PCI interface local bus number.*/
  71275. +MV_U32 mvPciIfLocalBusNumGet(MV_U32 pciIf);
  71276. +
  71277. +/* mvPciIfLocalDevNumSet - Set PCI interface local device number.*/
  71278. +MV_STATUS mvPciIfLocalDevNumSet(MV_U32 pciIf, MV_U32 devNum);
  71279. +
  71280. +/* mvPciIfLocalDevNumGet - Get PCI interface local device number.*/
  71281. +MV_U32 mvPciIfLocalDevNumGet(MV_U32 pciIf);
  71282. +
  71283. +/* mvPciIfTypeGet - Get PCI If type*/
  71284. +PCI_IF_TYPE mvPciIfTypeGet(MV_U32 pciIf);
  71285. +
  71286. +MV_U32 mvPciRealIfNumGet(MV_U32 pciIf);
  71287. +
  71288. +/* mvPciIfAddrDecShow - Display address decode windows attributes */
  71289. +MV_VOID mvPciIfAddrDecShow(MV_VOID);
  71290. +
  71291. +#endif /* #ifndef __INCPCIIFH */
  71292. +
  71293. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h
  71294. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h 1970-01-01 01:00:00.000000000 +0100
  71295. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/mvPciIfRegs.h 2011-08-01 14:38:19.000000000 +0200
  71296. @@ -0,0 +1,245 @@
  71297. +/*******************************************************************************
  71298. +Copyright (C) Marvell International Ltd. and its affiliates
  71299. +
  71300. +This software file (the "File") is owned and distributed by Marvell
  71301. +International Ltd. and/or its affiliates ("Marvell") under the following
  71302. +alternative licensing terms. Once you have made an election to distribute the
  71303. +File under one of the following license alternatives, please (i) delete this
  71304. +introductory statement regarding license alternatives, (ii) delete the two
  71305. +license alternatives that you have not elected to use and (iii) preserve the
  71306. +Marvell copyright notice above.
  71307. +
  71308. +********************************************************************************
  71309. +Marvell Commercial License Option
  71310. +
  71311. +If you received this File from Marvell and you have entered into a commercial
  71312. +license agreement (a "Commercial License") with Marvell, the File is licensed
  71313. +to you under the terms of the applicable Commercial License.
  71314. +
  71315. +********************************************************************************
  71316. +Marvell GPL License Option
  71317. +
  71318. +If you received this File from Marvell, you may opt to use, redistribute and/or
  71319. +modify this File in accordance with the terms and conditions of the General
  71320. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  71321. +available along with the File in the license.txt file or by writing to the Free
  71322. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  71323. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  71324. +
  71325. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  71326. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  71327. +DISCLAIMED. The GPL License provides additional details about this warranty
  71328. +disclaimer.
  71329. +********************************************************************************
  71330. +Marvell BSD License Option
  71331. +
  71332. +If you received this File from Marvell, you may opt to use, redistribute and/or
  71333. +modify this File under the following licensing terms.
  71334. +Redistribution and use in source and binary forms, with or without modification,
  71335. +are permitted provided that the following conditions are met:
  71336. +
  71337. + * Redistributions of source code must retain the above copyright notice,
  71338. + this list of conditions and the following disclaimer.
  71339. +
  71340. + * Redistributions in binary form must reproduce the above copyright
  71341. + notice, this list of conditions and the following disclaimer in the
  71342. + documentation and/or other materials provided with the distribution.
  71343. +
  71344. + * Neither the name of Marvell nor the names of its contributors may be
  71345. + used to endorse or promote products derived from this software without
  71346. + specific prior written permission.
  71347. +
  71348. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  71349. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  71350. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  71351. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  71352. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  71353. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  71354. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  71355. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  71356. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  71357. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  71358. +
  71359. +*******************************************************************************/
  71360. +
  71361. +#ifndef __INCPCIIFREGSH
  71362. +#define __INCPCIIFREGSH
  71363. +
  71364. +
  71365. +/* defines */
  71366. +#define MAX_PCI_DEVICES 32
  71367. +#define MAX_PCI_FUNCS 8
  71368. +#define MAX_PCI_BUSSES 128
  71369. +
  71370. +/***************************************/
  71371. +/* PCI Configuration registers */
  71372. +/***************************************/
  71373. +
  71374. +/*********************************************/
  71375. +/* PCI Configuration, Function 0, Registers */
  71376. +/*********************************************/
  71377. +
  71378. +
  71379. +/* Standard registers */
  71380. +#define PCI_DEVICE_AND_VENDOR_ID 0x000
  71381. +#define PCI_STATUS_AND_COMMAND 0x004
  71382. +#define PCI_CLASS_CODE_AND_REVISION_ID 0x008
  71383. +#define PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE 0x00C
  71384. +#define PCI_MEMORY_BAR_BASE_ADDR(barNum) (0x010 + ((barNum) << 2))
  71385. +#define PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID 0x02C
  71386. +#define PCI_EXPANSION_ROM_BASE_ADDR_REG 0x030
  71387. +#define PCI_CAPABILTY_LIST_POINTER 0x034
  71388. +#define PCI_INTERRUPT_PIN_AND_LINE 0x03C
  71389. +
  71390. +
  71391. +/* PCI Device and Vendor ID Register (PDVIR) */
  71392. +#define PDVIR_VEN_ID_OFFS 0 /* Vendor ID */
  71393. +#define PDVIR_VEN_ID_MASK (0xffff << PDVIR_VEN_ID_OFFS)
  71394. +
  71395. +#define PDVIR_DEV_ID_OFFS 16 /* Device ID */
  71396. +#define PDVIR_DEV_ID_MASK (0xffff << PDVIR_DEV_ID_OFFS)
  71397. +
  71398. +/* PCI Status and Command Register (PSCR) */
  71399. +#define PSCR_IO_EN BIT0 /* IO Enable */
  71400. +#define PSCR_MEM_EN BIT1 /* Memory Enable */
  71401. +#define PSCR_MASTER_EN BIT2 /* Master Enable */
  71402. +#define PSCR_SPECIAL_EN BIT3 /* Special Cycle Enable */
  71403. +#define PSCR_MEM_WRI_INV BIT4 /* Memory Write and Invalidate Enable */
  71404. +#define PSCR_VGA BIT5 /* VGA Palette Snoops */
  71405. +#define PSCR_PERR_EN BIT6 /* Parity Errors Respond Enable */
  71406. +#define PSCR_ADDR_STEP BIT7 /* Address Stepping Enable (Wait Cycle En)*/
  71407. +#define PSCR_SERR_EN BIT8 /* Ability to assert SERR# line */
  71408. +#define PSCR_FAST_BTB_EN BIT9 /* generate fast back-to-back transactions*/
  71409. +#define PSCR_CAP_LIST BIT20 /* Capability List Support */
  71410. +#define PSCR_66MHZ_EN BIT21 /* 66 MHz Capable */
  71411. +#define PSCR_UDF_EN BIT22 /* User definable features */
  71412. +#define PSCR_TAR_FAST_BB BIT23 /* fast back-to-back transactions capable */
  71413. +#define PSCR_DATA_PERR BIT24 /* Data Parity reported */
  71414. +
  71415. +#define PSCR_DEVSEL_TIM_OFFS 25 /* DEVSEL timing */
  71416. +#define PSCR_DEVSEL_TIM_MASK (0x3 << PSCR_DEVSEL_TIM_OFFS)
  71417. +#define PSCR_DEVSEL_TIM_FAST (0x0 << PSCR_DEVSEL_TIM_OFFS)
  71418. +#define PSCR_DEVSEL_TIM_MED (0x1 << PSCR_DEVSEL_TIM_OFFS)
  71419. +#define PSCR_DEVSEL_TIM_SLOW (0x2 << PSCR_DEVSEL_TIM_OFFS)
  71420. +
  71421. +#define PSCR_SLAVE_TABORT BIT27 /* Signalled Target Abort */
  71422. +#define PSCR_MASTER_TABORT BIT28 /* Recieved Target Abort */
  71423. +#define PSCR_MABORT BIT29 /* Recieved Master Abort */
  71424. +#define PSCR_SYSERR BIT30 /* Signalled system error */
  71425. +#define PSCR_DET_PARERR BIT31 /* Detect Parity Error */
  71426. +
  71427. +/* PCI configuration register offset=0x08 fields
  71428. + (PCI_CLASS_CODE_AND_REVISION_ID)(PCCRI) */
  71429. +
  71430. +#define PCCRIR_REVID_OFFS 0 /* Revision ID */
  71431. +#define PCCRIR_REVID_MASK (0xff << PCCRIR_REVID_OFFS)
  71432. +
  71433. +#define PCCRIR_FULL_CLASS_OFFS 8 /* Full Class Code */
  71434. +#define PCCRIR_FULL_CLASS_MASK (0xffffff << PCCRIR_FULL_CLASS_OFFS)
  71435. +
  71436. +#define PCCRIR_PROGIF_OFFS 8 /* Prog .I/F*/
  71437. +#define PCCRIR_PROGIF_MASK (0xff << PCCRIR_PROGIF_OFFS)
  71438. +
  71439. +#define PCCRIR_SUB_CLASS_OFFS 16 /* Sub Class*/
  71440. +#define PCCRIR_SUB_CLASS_MASK (0xff << PCCRIR_SUB_CLASS_OFFS)
  71441. +
  71442. +#define PCCRIR_BASE_CLASS_OFFS 24 /* Base Class*/
  71443. +#define PCCRIR_BASE_CLASS_MASK (0xff << PCCRIR_BASE_CLASS_OFFS)
  71444. +
  71445. +/* PCI configuration register offset=0x0C fields
  71446. + (PCI_BIST_HEADER_TYPE_LATENCY_TIMER_CACHE_LINE)(PBHTLTCL) */
  71447. +
  71448. +#define PBHTLTCLR_CACHELINE_OFFS 0 /* Specifies the cache line size */
  71449. +#define PBHTLTCLR_CACHELINE_MASK (0xff << PBHTLTCLR_CACHELINE_OFFS)
  71450. +
  71451. +#define PBHTLTCLR_LATTIMER_OFFS 8 /* latency timer */
  71452. +#define PBHTLTCLR_LATTIMER_MASK (0xff << PBHTLTCLR_LATTIMER_OFFS)
  71453. +
  71454. +#define PBHTLTCLR_HEADTYPE_FULL_OFFS 16 /* Full Header Type */
  71455. +#define PBHTLTCLR_HEADTYPE_FULL_MASK (0xff << PBHTLTCLR_HEADTYPE_FULL_OFFS)
  71456. +
  71457. +#define PBHTLTCLR_MULTI_FUNC BIT23 /* Multi/Single function */
  71458. +
  71459. +#define PBHTLTCLR_HEADER_OFFS 16 /* Header type */
  71460. +#define PBHTLTCLR_HEADER_MASK (0x7f << PBHTLTCLR_HEADER_OFFS)
  71461. +#define PBHTLTCLR_HEADER_STANDARD (0x0 << PBHTLTCLR_HEADER_OFFS)
  71462. +#define PBHTLTCLR_HEADER_PCI2PCI_BRIDGE (0x1 << PBHTLTCLR_HEADER_OFFS)
  71463. +
  71464. +
  71465. +#define PBHTLTCLR_BISTCOMP_OFFS 24 /* BIST Completion Code */
  71466. +#define PBHTLTCLR_BISTCOMP_MASK (0xf << PBHTLTCLR_BISTCOMP_OFFS)
  71467. +
  71468. +#define PBHTLTCLR_BISTACT BIT30 /* BIST Activate bit */
  71469. +#define PBHTLTCLR_BISTCAP BIT31 /* BIST Capable Bit */
  71470. +
  71471. +
  71472. +/* PCI Bar Base Low Register (PBBLR) */
  71473. +#define PBBLR_IOSPACE BIT0 /* Memory Space Indicator */
  71474. +
  71475. +#define PBBLR_TYPE_OFFS 1 /* BAR Type/Init Val. */
  71476. +#define PBBLR_TYPE_MASK (0x3 << PBBLR_TYPE_OFFS)
  71477. +#define PBBLR_TYPE_32BIT_ADDR (0x0 << PBBLR_TYPE_OFFS)
  71478. +#define PBBLR_TYPE_64BIT_ADDR (0x2 << PBBLR_TYPE_OFFS)
  71479. +
  71480. +#define PBBLR_PREFETCH_EN BIT3 /* Prefetch Enable */
  71481. +
  71482. +
  71483. +#define PBBLR_MEM_BASE_OFFS 4 /* Memory Bar Base address. Corresponds to
  71484. + address bits [31:4] */
  71485. +#define PBBLR_MEM_BASE_MASK (0xfffffff << PBBLR_MEM_BASE_OFFS)
  71486. +
  71487. +#define PBBLR_IO_BASE_OFFS 2 /* IO Bar Base address. Corresponds to
  71488. + address bits [31:2] */
  71489. +#define PBBLR_IO_BASE_MASK (0x3fffffff << PBBLR_IO_BASE_OFFS)
  71490. +
  71491. +
  71492. +#define PBBLR_BASE_OFFS 12 /* Base address. Address bits [31:12] */
  71493. +#define PBBLR_BASE_MASK (0xfffff << PBBLR_BASE_OFFS)
  71494. +#define PBBLR_BASE_ALIGNMET (1 << PBBLR_BASE_OFFS)
  71495. +
  71496. +
  71497. +/* PCI Bar Base High Fegister (PBBHR) */
  71498. +#define PBBHR_BASE_OFFS 0 /* Base address. Address bits [31:12] */
  71499. +#define PBBHR_BASE_MASK (0xffffffff << PBBHR_BASE_OFFS)
  71500. +
  71501. +
  71502. +/* PCI configuration register offset=0x2C fields
  71503. + (PCI_SUBSYSTEM_ID_AND_SUBSYSTEM_VENDOR_ID)(PSISVI) */
  71504. +
  71505. +#define PSISVIR_VENID_OFFS 0 /* Subsystem Manufacturer Vendor ID Number */
  71506. +#define PSISVIR_VENID_MASK (0xffff << PSISVIR_VENID_OFFS)
  71507. +
  71508. +#define PSISVIR_DEVID_OFFS 16 /* Subsystem Device ID Number */
  71509. +#define PSISVIR_DEVID_MASK (0xffff << PSISVIR_DEVID_OFFS)
  71510. +
  71511. +/* PCI configuration register offset=0x30 fields
  71512. + (PCI_EXPANSION_ROM_BASE_ADDR_REG)(PERBA) */
  71513. +
  71514. +#define PERBAR_EXPROMEN BIT0 /* Expansion ROM Enable */
  71515. +
  71516. +#define PERBAR_BASE_OFFS 12 /* Expansion ROM Base Address */
  71517. +#define PERBAR_BASE_MASK (0xfffff << PERBAR_BASE_OFFS)
  71518. +
  71519. +/* PCI configuration register offset=0x34 fields
  71520. + (PCI_CAPABILTY_LIST_POINTER)(PCLP) */
  71521. +
  71522. +#define PCLPR_CAPPTR_OFFS 0 /* Capability List Pointer */
  71523. +#define PCLPR_CAPPTR_MASK (0xff << PCLPR_CAPPTR_OFFS)
  71524. +
  71525. +/* PCI configuration register offset=0x3C fields
  71526. + (PCI_INTERRUPT_PIN_AND_LINE)(PIPL) */
  71527. +
  71528. +#define PIPLR_INTLINE_OFFS 0 /* Interrupt line (IRQ) */
  71529. +#define PIPLR_INTLINE_MASK (0xff << PIPLR_INTLINE_OFFS)
  71530. +
  71531. +#define PIPLR_INTPIN_OFFS 8 /* interrupt pin (A,B,C,D) */
  71532. +#define PIPLR_INTPIN_MASK (0xff << PIPLR_INTPIN_OFFS)
  71533. +
  71534. +#define PIPLR_MINGRANT_OFFS 16 /* Minimum Grant on 250 nano seconds units */
  71535. +#define PIPLR_MINGRANT_MASK (0xff << PIPLR_MINGRANT_OFFS)
  71536. +
  71537. +#define PIPLR_MAXLATEN_OFFS 24 /* Maximum latency on 250 nano seconds units */
  71538. +#define PIPLR_MAXLATEN_MASK (0xff << PIPLR_MAXLATEN_OFFS)
  71539. +
  71540. +#endif /* #ifndef __INCPCIIFREGSH */
  71541. +
  71542. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c
  71543. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c 1970-01-01 01:00:00.000000000 +0100
  71544. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.c 2011-08-01 14:38:19.000000000 +0200
  71545. @@ -0,0 +1,1006 @@
  71546. +/*******************************************************************************
  71547. +Copyright (C) Marvell International Ltd. and its affiliates
  71548. +
  71549. +This software file (the "File") is owned and distributed by Marvell
  71550. +International Ltd. and/or its affiliates ("Marvell") under the following
  71551. +alternative licensing terms. Once you have made an election to distribute the
  71552. +File under one of the following license alternatives, please (i) delete this
  71553. +introductory statement regarding license alternatives, (ii) delete the two
  71554. +license alternatives that you have not elected to use and (iii) preserve the
  71555. +Marvell copyright notice above.
  71556. +
  71557. +********************************************************************************
  71558. +Marvell Commercial License Option
  71559. +
  71560. +If you received this File from Marvell and you have entered into a commercial
  71561. +license agreement (a "Commercial License") with Marvell, the File is licensed
  71562. +to you under the terms of the applicable Commercial License.
  71563. +
  71564. +********************************************************************************
  71565. +Marvell GPL License Option
  71566. +
  71567. +If you received this File from Marvell, you may opt to use, redistribute and/or
  71568. +modify this File in accordance with the terms and conditions of the General
  71569. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  71570. +available along with the File in the license.txt file or by writing to the Free
  71571. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  71572. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  71573. +
  71574. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  71575. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  71576. +DISCLAIMED. The GPL License provides additional details about this warranty
  71577. +disclaimer.
  71578. +********************************************************************************
  71579. +Marvell BSD License Option
  71580. +
  71581. +If you received this File from Marvell, you may opt to use, redistribute and/or
  71582. +modify this File under the following licensing terms.
  71583. +Redistribution and use in source and binary forms, with or without modification,
  71584. +are permitted provided that the following conditions are met:
  71585. +
  71586. + * Redistributions of source code must retain the above copyright notice,
  71587. + this list of conditions and the following disclaimer.
  71588. +
  71589. + * Redistributions in binary form must reproduce the above copyright
  71590. + notice, this list of conditions and the following disclaimer in the
  71591. + documentation and/or other materials provided with the distribution.
  71592. +
  71593. + * Neither the name of Marvell nor the names of its contributors may be
  71594. + used to endorse or promote products derived from this software without
  71595. + specific prior written permission.
  71596. +
  71597. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  71598. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  71599. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  71600. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  71601. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  71602. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  71603. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  71604. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  71605. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  71606. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  71607. +
  71608. +*******************************************************************************/
  71609. +
  71610. +/* includes */
  71611. +#include "mvPciUtils.h"
  71612. +
  71613. +#include "ctrlEnv/mvCtrlEnvLib.h"
  71614. +
  71615. +/* #define MV_DEBUG */
  71616. +/* defines */
  71617. +#ifdef MV_DEBUG
  71618. + #define DB(x) x
  71619. + #define mvOsPrintf printf
  71620. +#else
  71621. + #define DB(x)
  71622. +#endif
  71623. +
  71624. +/*
  71625. +This module only support scanning of Header type 00h of pci devices
  71626. +There is no suppotr for Header type 01h of pci devices ( PCI bridges )
  71627. +*/
  71628. +
  71629. +
  71630. +static MV_STATUS pciDetectDevice(MV_U32 pciIf,
  71631. + MV_U32 bus,
  71632. + MV_U32 dev,
  71633. + MV_U32 func,
  71634. + MV_PCI_DEVICE *pPciAgent);
  71635. +
  71636. +static MV_U32 pciDetectDeviceBars(MV_U32 pciIf,
  71637. + MV_U32 bus,
  71638. + MV_U32 dev,
  71639. + MV_U32 func,
  71640. + MV_PCI_DEVICE *pPciAgent);
  71641. +
  71642. +
  71643. +
  71644. +
  71645. +
  71646. +
  71647. +/*******************************************************************************
  71648. +* mvPciScan - Scan a PCI interface bus
  71649. +*
  71650. +* DESCRIPTION:
  71651. +* Performs a full scan on a PCI interface and returns all possible details
  71652. +* on the agents found on the bus.
  71653. +*
  71654. +* INPUT:
  71655. +* pciIf - PCI Interface
  71656. +* pPciAgents - Pointer to an Array of the pci agents to be detected
  71657. +* pPciAgentsNum - pPciAgents array maximum number of elements
  71658. +*
  71659. +* OUTPUT:
  71660. +* pPciAgents - Array of the pci agents detected on the bus
  71661. +* pPciAgentsNum - Number of pci agents detected on the bus
  71662. +*
  71663. +* RETURN:
  71664. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  71665. +*
  71666. +*******************************************************************************/
  71667. +
  71668. +MV_STATUS mvPciScan(MV_U32 pciIf,
  71669. + MV_PCI_DEVICE *pPciAgents,
  71670. + MV_U32 *pPciAgentsNum)
  71671. +{
  71672. +
  71673. + MV_U32 devIndex,funcIndex=0,busIndex=0,detectedDevNum=0;
  71674. + MV_U32 localBus=mvPciIfLocalBusNumGet(pciIf);
  71675. + MV_PCI_DEVICE *pPciDevice;
  71676. + MV_PCI_DEVICE *pMainDevice;
  71677. +
  71678. + DB(mvOsPrintf("mvPciScan: PCI interface num %d\n", pciIf));
  71679. + /* Parameter checking */
  71680. + if (pciIf >= mvCtrlPexMaxIfGet())
  71681. + {
  71682. + DB(mvOsPrintf("mvPciScan: ERR. Invalid PCI interface num %d\n", pciIf));
  71683. + return MV_BAD_PARAM;
  71684. + }
  71685. + if (NULL == pPciAgents)
  71686. + {
  71687. + DB(mvOsPrintf("mvPciScan: ERR. pPciAgents=NULL \n"));
  71688. + return MV_BAD_PARAM;
  71689. + }
  71690. + if (NULL == pPciAgentsNum)
  71691. + {
  71692. + DB(mvOsPrintf("mvPciScan: ERR. pPciAgentsNum=NULL \n"));
  71693. + return MV_BAD_PARAM;
  71694. + }
  71695. +
  71696. +
  71697. + DB(mvOsPrintf("mvPciScan: PCI interface num %d mvPciMasterEnable\n", pciIf));
  71698. + /* Master enable the MV PCI master */
  71699. + if (MV_OK != mvPciIfMasterEnable(pciIf,MV_TRUE))
  71700. + {
  71701. + DB(mvOsPrintf("mvPciScan: ERR. mvPciMasterEnable failed \n"));
  71702. + return MV_ERROR;
  71703. +
  71704. + }
  71705. +
  71706. + DB(mvOsPrintf("mvPciScan: PCI interface num scan%d\n", pciIf));
  71707. +
  71708. + /* go through all busses */
  71709. + for (busIndex=localBus ; busIndex < MAX_PCI_BUSSES ; busIndex++)
  71710. + {
  71711. + /* go through all possible devices on the local bus */
  71712. + for (devIndex=0 ; devIndex < MAX_PCI_DEVICES ; devIndex++)
  71713. + {
  71714. + /* always start with function equal to zero */
  71715. + funcIndex=0;
  71716. +
  71717. + pPciDevice=&pPciAgents[detectedDevNum];
  71718. + DB(mvOsPrintf("mvPciScan: PCI interface num scan%d:%d\n", busIndex, devIndex));
  71719. +
  71720. + if (MV_ERROR == pciDetectDevice(pciIf,
  71721. + busIndex,
  71722. + devIndex,
  71723. + funcIndex,
  71724. + pPciDevice))
  71725. + {
  71726. + /* no device detected , try the next address */
  71727. + continue;
  71728. + }
  71729. +
  71730. + /* We are here ! means we have detected a device*/
  71731. + /* always we start with only one function per device */
  71732. + pMainDevice = pPciDevice;
  71733. + pPciDevice->funtionsNum = 1;
  71734. +
  71735. +
  71736. + /* move on */
  71737. + detectedDevNum++;
  71738. +
  71739. +
  71740. + /* check if we have no more room for a new device */
  71741. + if (detectedDevNum == *pPciAgentsNum)
  71742. + {
  71743. + DB(mvOsPrintf("mvPciScan: ERR. array passed too small \n"));
  71744. + return MV_ERROR;
  71745. + }
  71746. +
  71747. + /* check the detected device if it is a multi functional device then
  71748. + scan all device functions*/
  71749. + if (pPciDevice->isMultiFunction == MV_TRUE)
  71750. + {
  71751. + /* start with function number 1 because we have already detected
  71752. + function 0 */
  71753. + for (funcIndex=1; funcIndex<MAX_PCI_FUNCS ; funcIndex++)
  71754. + {
  71755. + pPciDevice=&pPciAgents[detectedDevNum];
  71756. +
  71757. + if (MV_ERROR == pciDetectDevice(pciIf,
  71758. + busIndex,
  71759. + devIndex,
  71760. + funcIndex,
  71761. + pPciDevice))
  71762. + {
  71763. + /* no device detected means no more functions !*/
  71764. + continue;
  71765. + }
  71766. + /* We are here ! means we have detected a device */
  71767. +
  71768. + /* move on */
  71769. + pMainDevice->funtionsNum++;
  71770. + detectedDevNum++;
  71771. +
  71772. + /* check if we have no more room for a new device */
  71773. + if (detectedDevNum == *pPciAgentsNum)
  71774. + {
  71775. + DB(mvOsPrintf("mvPciScan: ERR. Array too small\n"));
  71776. + return MV_ERROR;
  71777. + }
  71778. +
  71779. +
  71780. + }
  71781. + }
  71782. +
  71783. + }
  71784. +
  71785. + }
  71786. +
  71787. + /* return the number of devices actually detected on the bus ! */
  71788. + *pPciAgentsNum = detectedDevNum;
  71789. +
  71790. + return MV_OK;
  71791. +
  71792. +}
  71793. +
  71794. +
  71795. +/*******************************************************************************
  71796. +* pciDetectDevice - Detect a pci device parameters
  71797. +*
  71798. +* DESCRIPTION:
  71799. +* This function detect if a pci agent exist on certain address !
  71800. +* and if exists then it fills all possible information on the
  71801. +* agent
  71802. +*
  71803. +* INPUT:
  71804. +* pciIf - PCI Interface
  71805. +* bus - Bus number
  71806. +* dev - Device number
  71807. +* func - Function number
  71808. +*
  71809. +*
  71810. +*
  71811. +* OUTPUT:
  71812. +* pPciAgent - pointer to the pci agent filled with its information
  71813. +*
  71814. +* RETURN:
  71815. +* MV_ERROR if no device , MV_OK otherwise
  71816. +*
  71817. +*******************************************************************************/
  71818. +
  71819. +static MV_STATUS pciDetectDevice(MV_U32 pciIf,
  71820. + MV_U32 bus,
  71821. + MV_U32 dev,
  71822. + MV_U32 func,
  71823. + MV_PCI_DEVICE *pPciAgent)
  71824. +{
  71825. + MV_U32 pciData;
  71826. +
  71827. + /* no Parameters checking ! because it is static function and it is assumed
  71828. + that all parameters were checked in the calling function */
  71829. +
  71830. +
  71831. + /* Try read the PCI Vendor ID and Device ID */
  71832. +
  71833. + /* We will scan only ourselves and the PCI slots that exist on the
  71834. + board, because we may have a case that we have one slot that has
  71835. + a Cardbus connector, and because CardBus answers all IDsels we want
  71836. + to scan only this slot and ourseleves.
  71837. +
  71838. + */
  71839. + #if defined(MV_INCLUDE_PCI)
  71840. + if ((PCI_IF_TYPE_CONVEN_PCIX == mvPciIfTypeGet(pciIf)) &&
  71841. + (DB_88F5181_DDR1_PRPMC != mvBoardIdGet()) &&
  71842. + (DB_88F5181_DDR1_PEXPCI != mvBoardIdGet()) &&
  71843. + (DB_88F5181_DDR1_MNG != mvBoardIdGet()))
  71844. + {
  71845. +
  71846. + if (mvBoardIsOurPciSlot(bus, dev) == MV_FALSE)
  71847. + {
  71848. + return MV_ERROR;
  71849. + }
  71850. + }
  71851. + #endif /* defined(MV_INCLUDE_PCI) */
  71852. +
  71853. + pciData = mvPciIfConfigRead(pciIf, bus,dev,func, PCI_DEVICE_AND_VENDOR_ID);
  71854. +
  71855. + if (PCI_ERROR_CODE == pciData)
  71856. + {
  71857. + /* no device exist */
  71858. + return MV_ERROR;
  71859. + }
  71860. +
  71861. + /* we are here ! means a device is detected */
  71862. +
  71863. + /* fill basic information */
  71864. + pPciAgent->busNumber=bus;
  71865. + pPciAgent->deviceNum=dev;
  71866. + pPciAgent->function=func;
  71867. +
  71868. + /* Fill the PCI Vendor ID and Device ID */
  71869. +
  71870. + pPciAgent->venID = (pciData & PDVIR_VEN_ID_MASK) >> PDVIR_VEN_ID_OFFS;
  71871. + pPciAgent->deviceID = (pciData & PDVIR_DEV_ID_MASK) >> PDVIR_DEV_ID_OFFS;
  71872. +
  71873. + /* Read Status and command */
  71874. + pciData = mvPciIfConfigRead(pciIf,
  71875. + bus,dev,func,
  71876. + PCI_STATUS_AND_COMMAND);
  71877. +
  71878. +
  71879. + /* Fill related Status and Command information*/
  71880. +
  71881. + if (pciData & PSCR_TAR_FAST_BB)
  71882. + {
  71883. + pPciAgent->isFastB2BCapable = MV_TRUE;
  71884. + }
  71885. + else
  71886. + {
  71887. + pPciAgent->isFastB2BCapable = MV_FALSE;
  71888. + }
  71889. +
  71890. + if (pciData & PSCR_CAP_LIST)
  71891. + {
  71892. + pPciAgent->isCapListSupport=MV_TRUE;
  71893. + }
  71894. + else
  71895. + {
  71896. + pPciAgent->isCapListSupport=MV_FALSE;
  71897. + }
  71898. +
  71899. + if (pciData & PSCR_66MHZ_EN)
  71900. + {
  71901. + pPciAgent->is66MHZCapable=MV_TRUE;
  71902. + }
  71903. + else
  71904. + {
  71905. + pPciAgent->is66MHZCapable=MV_FALSE;
  71906. + }
  71907. +
  71908. + /* Read Class Code and Revision */
  71909. + pciData = mvPciIfConfigRead(pciIf,
  71910. + bus,dev,func,
  71911. + PCI_CLASS_CODE_AND_REVISION_ID);
  71912. +
  71913. +
  71914. + pPciAgent->baseClassCode =
  71915. + (pciData & PCCRIR_BASE_CLASS_MASK) >> PCCRIR_BASE_CLASS_OFFS;
  71916. +
  71917. + pPciAgent->subClassCode =
  71918. + (pciData & PCCRIR_SUB_CLASS_MASK) >> PCCRIR_SUB_CLASS_OFFS;
  71919. +
  71920. + pPciAgent->progIf =
  71921. + (pciData & PCCRIR_PROGIF_MASK) >> PCCRIR_PROGIF_OFFS;
  71922. +
  71923. + pPciAgent->revisionID =
  71924. + (pciData & PCCRIR_REVID_MASK) >> PCCRIR_REVID_OFFS;
  71925. +
  71926. + /* Read PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE */
  71927. + pciData = mvPciIfConfigRead(pciIf,
  71928. + bus,dev,func,
  71929. + PCI_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE);
  71930. +
  71931. +
  71932. +
  71933. + pPciAgent->pciCacheLine=
  71934. + (pciData & PBHTLTCLR_CACHELINE_MASK ) >> PBHTLTCLR_CACHELINE_OFFS;
  71935. + pPciAgent->pciLatencyTimer=
  71936. + (pciData & PBHTLTCLR_LATTIMER_MASK) >> PBHTLTCLR_LATTIMER_OFFS;
  71937. +
  71938. + switch (pciData & PBHTLTCLR_HEADER_MASK)
  71939. + {
  71940. + case PBHTLTCLR_HEADER_STANDARD:
  71941. +
  71942. + pPciAgent->pciHeader=MV_PCI_STANDARD;
  71943. + break;
  71944. + case PBHTLTCLR_HEADER_PCI2PCI_BRIDGE:
  71945. +
  71946. + pPciAgent->pciHeader=MV_PCI_PCI2PCI_BRIDGE;
  71947. + break;
  71948. +
  71949. + }
  71950. +
  71951. + if (pciData & PBHTLTCLR_MULTI_FUNC)
  71952. + {
  71953. + pPciAgent->isMultiFunction=MV_TRUE;
  71954. + }
  71955. + else
  71956. + {
  71957. + pPciAgent->isMultiFunction=MV_FALSE;
  71958. + }
  71959. +
  71960. + if (pciData & PBHTLTCLR_BISTCAP)
  71961. + {
  71962. + pPciAgent->isBISTCapable=MV_TRUE;
  71963. + }
  71964. + else
  71965. + {
  71966. + pPciAgent->isBISTCapable=MV_FALSE;
  71967. + }
  71968. +
  71969. +
  71970. + /* read this device pci bars */
  71971. +
  71972. + pciDetectDeviceBars(pciIf,
  71973. + bus,dev,func,
  71974. + pPciAgent);
  71975. +
  71976. +
  71977. + /* check if we are bridge*/
  71978. + if ((pPciAgent->baseClassCode == PCI_BRIDGE_CLASS)&&
  71979. + (pPciAgent->subClassCode == P2P_BRIDGE_SUB_CLASS_CODE))
  71980. + {
  71981. +
  71982. + /* Read P2P_BUSSES_NUM */
  71983. + pciData = mvPciIfConfigRead(pciIf,
  71984. + bus,dev,func,
  71985. + P2P_BUSSES_NUM);
  71986. +
  71987. + pPciAgent->p2pPrimBusNum =
  71988. + (pciData & PBM_PRIME_BUS_NUM_MASK) >> PBM_PRIME_BUS_NUM_OFFS;
  71989. +
  71990. + pPciAgent->p2pSecBusNum =
  71991. + (pciData & PBM_SEC_BUS_NUM_MASK) >> PBM_SEC_BUS_NUM_OFFS;
  71992. +
  71993. + pPciAgent->p2pSubBusNum =
  71994. + (pciData & PBM_SUB_BUS_NUM_MASK) >> PBM_SUB_BUS_NUM_OFFS;
  71995. +
  71996. + pPciAgent->p2pSecLatencyTimer =
  71997. + (pciData & PBM_SEC_LAT_TMR_MASK) >> PBM_SEC_LAT_TMR_OFFS;
  71998. +
  71999. + /* Read P2P_IO_BASE_LIMIT_SEC_STATUS */
  72000. + pciData = mvPciIfConfigRead(pciIf,
  72001. + bus,dev,func,
  72002. + P2P_IO_BASE_LIMIT_SEC_STATUS);
  72003. +
  72004. + pPciAgent->p2pSecStatus =
  72005. + (pciData & PIBLSS_SEC_STATUS_MASK) >> PIBLSS_SEC_STATUS_OFFS;
  72006. +
  72007. +
  72008. + pPciAgent->p2pIObase =
  72009. + (pciData & PIBLSS_IO_BASE_MASK) << PIBLSS_IO_LIMIT_OFFS;
  72010. +
  72011. + /* clear low address (should be zero)*/
  72012. + pPciAgent->p2pIObase &= PIBLSS_HIGH_ADDR_MASK;
  72013. +
  72014. + pPciAgent->p2pIOLimit =
  72015. + (pciData & PIBLSS_IO_LIMIT_MASK);
  72016. +
  72017. + /* fill low address with 0xfff */
  72018. + pPciAgent->p2pIOLimit |= PIBLSS_LOW_ADDR_MASK;
  72019. +
  72020. +
  72021. + switch ((pciData & PIBLSS_ADD_CAP_MASK) >> PIBLSS_ADD_CAP_OFFS)
  72022. + {
  72023. + case PIBLSS_ADD_CAP_16BIT:
  72024. +
  72025. + pPciAgent->bIO32 = MV_FALSE;
  72026. +
  72027. + break;
  72028. + case PIBLSS_ADD_CAP_32BIT:
  72029. +
  72030. + pPciAgent->bIO32 = MV_TRUE;
  72031. +
  72032. + /* Read P2P_IO_BASE_LIMIT_UPPER_16 */
  72033. + pciData = mvPciIfConfigRead(pciIf,
  72034. + bus,dev,func,
  72035. + P2P_IO_BASE_LIMIT_UPPER_16);
  72036. +
  72037. + pPciAgent->p2pIObase |=
  72038. + (pciData & PRBU_IO_UPP_BASE_MASK) << PRBU_IO_UPP_LIMIT_OFFS;
  72039. +
  72040. +
  72041. + pPciAgent->p2pIOLimit |=
  72042. + (pciData & PRBU_IO_UPP_LIMIT_MASK);
  72043. +
  72044. + break;
  72045. +
  72046. + }
  72047. +
  72048. +
  72049. + /* Read P2P_MEM_BASE_LIMIT */
  72050. + pciData = mvPciIfConfigRead(pciIf,
  72051. + bus,dev,func,
  72052. + P2P_MEM_BASE_LIMIT);
  72053. +
  72054. + pPciAgent->p2pMemBase =
  72055. + (pciData & PMBL_MEM_BASE_MASK) << PMBL_MEM_LIMIT_OFFS;
  72056. +
  72057. + /* clear low address */
  72058. + pPciAgent->p2pMemBase &= PMBL_HIGH_ADDR_MASK;
  72059. +
  72060. + pPciAgent->p2pMemLimit =
  72061. + (pciData & PMBL_MEM_LIMIT_MASK);
  72062. +
  72063. + /* add 0xfffff */
  72064. + pPciAgent->p2pMemLimit |= PMBL_LOW_ADDR_MASK;
  72065. +
  72066. +
  72067. + /* Read P2P_PREF_MEM_BASE_LIMIT */
  72068. + pciData = mvPciIfConfigRead(pciIf,
  72069. + bus,dev,func,
  72070. + P2P_PREF_MEM_BASE_LIMIT);
  72071. +
  72072. +
  72073. + pPciAgent->p2pPrefMemBase =
  72074. + (pciData & PRMBL_PREF_MEM_BASE_MASK) << PRMBL_PREF_MEM_LIMIT_OFFS;
  72075. +
  72076. + /* get high address only */
  72077. + pPciAgent->p2pPrefMemBase &= PRMBL_HIGH_ADDR_MASK;
  72078. +
  72079. +
  72080. +
  72081. + pPciAgent->p2pPrefMemLimit =
  72082. + (pciData & PRMBL_PREF_MEM_LIMIT_MASK);
  72083. +
  72084. + /* add 0xfffff */
  72085. + pPciAgent->p2pPrefMemLimit |= PRMBL_LOW_ADDR_MASK;
  72086. +
  72087. + switch (pciData & PRMBL_ADD_CAP_MASK)
  72088. + {
  72089. + case PRMBL_ADD_CAP_32BIT:
  72090. +
  72091. + pPciAgent->bPrefMem64 = MV_FALSE;
  72092. +
  72093. + /* Read P2P_PREF_BASE_UPPER_32 */
  72094. + pPciAgent->p2pPrefBaseUpper32Bits = 0;
  72095. +
  72096. + /* Read P2P_PREF_LIMIT_UPPER_32 */
  72097. + pPciAgent->p2pPrefLimitUpper32Bits = 0;
  72098. +
  72099. + break;
  72100. + case PRMBL_ADD_CAP_64BIT:
  72101. +
  72102. + pPciAgent->bPrefMem64 = MV_TRUE;
  72103. +
  72104. + /* Read P2P_PREF_BASE_UPPER_32 */
  72105. + pPciAgent->p2pPrefBaseUpper32Bits = mvPciIfConfigRead(pciIf,
  72106. + bus,dev,func,
  72107. + P2P_PREF_BASE_UPPER_32);
  72108. +
  72109. + /* Read P2P_PREF_LIMIT_UPPER_32 */
  72110. + pPciAgent->p2pPrefLimitUpper32Bits = mvPciIfConfigRead(pciIf,
  72111. + bus,dev,func,
  72112. + P2P_PREF_LIMIT_UPPER_32);
  72113. +
  72114. + break;
  72115. +
  72116. + }
  72117. +
  72118. + }
  72119. + else /* no bridge */
  72120. + {
  72121. + /* Read PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID */
  72122. + pciData = mvPciIfConfigRead(pciIf,
  72123. + bus,dev,func,
  72124. + PCI_SUBSYS_ID_AND_SUBSYS_VENDOR_ID);
  72125. +
  72126. +
  72127. + pPciAgent->subSysVenID =
  72128. + (pciData & PSISVIR_VENID_MASK) >> PSISVIR_VENID_OFFS;
  72129. + pPciAgent->subSysID =
  72130. + (pciData & PSISVIR_DEVID_MASK) >> PSISVIR_DEVID_OFFS;
  72131. +
  72132. +
  72133. + /* Read PCI_EXPANSION_ROM_BASE_ADDR_REG */
  72134. + pciData = mvPciIfConfigRead(pciIf,
  72135. + bus,dev,func,
  72136. + PCI_EXPANSION_ROM_BASE_ADDR_REG);
  72137. +
  72138. +
  72139. + if (pciData & PERBAR_EXPROMEN)
  72140. + {
  72141. + pPciAgent->isExpRom = MV_TRUE;
  72142. + }
  72143. + else
  72144. + {
  72145. + pPciAgent->isExpRom = MV_FALSE;
  72146. + }
  72147. +
  72148. + pPciAgent->expRomAddr =
  72149. + (pciData & PERBAR_BASE_MASK) >> PERBAR_BASE_OFFS;
  72150. +
  72151. + }
  72152. +
  72153. +
  72154. + if (MV_TRUE == pPciAgent->isCapListSupport)
  72155. + {
  72156. + /* Read PCI_CAPABILTY_LIST_POINTER */
  72157. + pciData = mvPciIfConfigRead(pciIf,
  72158. + bus,dev,func,
  72159. + PCI_CAPABILTY_LIST_POINTER);
  72160. +
  72161. + pPciAgent->capListPointer =
  72162. + (pciData & PCLPR_CAPPTR_MASK) >> PCLPR_CAPPTR_OFFS;
  72163. +
  72164. + }
  72165. +
  72166. + /* Read PCI_INTERRUPT_PIN_AND_LINE */
  72167. + pciData = mvPciIfConfigRead(pciIf,
  72168. + bus,dev,func,
  72169. + PCI_INTERRUPT_PIN_AND_LINE);
  72170. +
  72171. +
  72172. + pPciAgent->irqLine=
  72173. + (pciData & PIPLR_INTLINE_MASK) >> PIPLR_INTLINE_OFFS;
  72174. +
  72175. + pPciAgent->intPin=
  72176. + (MV_PCI_INT_PIN)(pciData & PIPLR_INTPIN_MASK) >> PIPLR_INTPIN_OFFS;
  72177. +
  72178. + pPciAgent->minGrant=
  72179. + (pciData & PIPLR_MINGRANT_MASK) >> PIPLR_MINGRANT_OFFS;
  72180. + pPciAgent->maxLatency=
  72181. + (pciData & PIPLR_MAXLATEN_MASK) >> PIPLR_MAXLATEN_OFFS;
  72182. +
  72183. + mvPciClassNameGet(pPciAgent->baseClassCode,
  72184. + (MV_8 *)pPciAgent->type);
  72185. +
  72186. + return MV_OK;
  72187. +
  72188. +
  72189. +}
  72190. +
  72191. +/*******************************************************************************
  72192. +* pciDetectDeviceBars - Detect a pci device bars
  72193. +*
  72194. +* DESCRIPTION:
  72195. +* This function detects all pci agent bars
  72196. +*
  72197. +* INPUT:
  72198. +* pciIf - PCI Interface
  72199. +* bus - Bus number
  72200. +* dev - Device number
  72201. +* func - Function number
  72202. +*
  72203. +*
  72204. +*
  72205. +* OUTPUT:
  72206. +* pPciAgent - pointer to the pci agent filled with its information
  72207. +*
  72208. +* RETURN:
  72209. +* detected bars number
  72210. +*
  72211. +*******************************************************************************/
  72212. +static MV_U32 pciDetectDeviceBars(MV_U32 pciIf,
  72213. + MV_U32 bus,
  72214. + MV_U32 dev,
  72215. + MV_U32 func,
  72216. + MV_PCI_DEVICE *pPciAgent)
  72217. +{
  72218. + MV_U32 pciData,barIndex,detectedBar=0;
  72219. + MV_U32 tmpBaseHigh=0,tmpBaseLow=0;
  72220. + MV_U32 pciMaxBars=0;
  72221. +
  72222. + pPciAgent->barsNum=0;
  72223. +
  72224. + /* check if we are bridge*/
  72225. + if ((pPciAgent->baseClassCode == PCI_BRIDGE_CLASS)&&
  72226. + (pPciAgent->subClassCode == P2P_BRIDGE_SUB_CLASS_CODE))
  72227. + {
  72228. + pciMaxBars = 2;
  72229. + }
  72230. + else /* no bridge */
  72231. + {
  72232. + pciMaxBars = 6;
  72233. + }
  72234. +
  72235. + /* read this device pci bars */
  72236. + for (barIndex = 0 ; barIndex < pciMaxBars ; barIndex++ )
  72237. + {
  72238. + /* Read PCI_MEMORY_BAR_BASE_ADDR */
  72239. + tmpBaseLow = pciData = mvPciIfConfigRead(pciIf,
  72240. + bus,dev,func,
  72241. + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
  72242. +
  72243. + pPciAgent->pciBar[detectedBar].barOffset =
  72244. + PCI_MEMORY_BAR_BASE_ADDR(barIndex);
  72245. +
  72246. + /* check if the bar is 32bit or 64bit bar */
  72247. + switch (pciData & PBBLR_TYPE_MASK)
  72248. + {
  72249. + case PBBLR_TYPE_32BIT_ADDR:
  72250. + pPciAgent->pciBar[detectedBar].barType = PCI_32BIT_BAR;
  72251. + break;
  72252. + case PBBLR_TYPE_64BIT_ADDR:
  72253. + pPciAgent->pciBar[detectedBar].barType = PCI_64BIT_BAR;
  72254. + break;
  72255. +
  72256. + }
  72257. +
  72258. + /* check if it is memory or IO bar */
  72259. + if (pciData & PBBLR_IOSPACE)
  72260. + {
  72261. + pPciAgent->pciBar[detectedBar].barMapping=PCI_IO_BAR;
  72262. + }
  72263. + else
  72264. + {
  72265. + pPciAgent->pciBar[detectedBar].barMapping=PCI_MEMORY_BAR;
  72266. + }
  72267. +
  72268. + /* if it is memory bar then check if it is prefetchable */
  72269. + if (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping)
  72270. + {
  72271. + if (pciData & PBBLR_PREFETCH_EN)
  72272. + {
  72273. + pPciAgent->pciBar[detectedBar].isPrefetchable = MV_TRUE;
  72274. + }
  72275. + else
  72276. + {
  72277. + pPciAgent->pciBar[detectedBar].isPrefetchable = MV_FALSE;
  72278. + }
  72279. +
  72280. + pPciAgent->pciBar[detectedBar].barBaseLow =
  72281. + pciData & PBBLR_MEM_BASE_MASK;
  72282. +
  72283. +
  72284. + }
  72285. + else /* IO Bar */
  72286. + {
  72287. + pPciAgent->pciBar[detectedBar].barBaseLow =
  72288. + pciData & PBBLR_IO_BASE_MASK;
  72289. +
  72290. + }
  72291. +
  72292. + pPciAgent->pciBar[detectedBar].barBaseHigh=0;
  72293. +
  72294. + if (PCI_64BIT_BAR == pPciAgent->pciBar[detectedBar].barType)
  72295. + {
  72296. + barIndex++;
  72297. +
  72298. + tmpBaseHigh = pPciAgent->pciBar[detectedBar].barBaseHigh =
  72299. + mvPciIfConfigRead(pciIf,
  72300. + bus,dev,func,
  72301. + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
  72302. +
  72303. +
  72304. + }
  72305. +
  72306. + /* calculating full base address (64bit) */
  72307. + pPciAgent->pciBar[detectedBar].barBaseAddr =
  72308. + (MV_U64)pPciAgent->pciBar[detectedBar].barBaseHigh;
  72309. +
  72310. + pPciAgent->pciBar[detectedBar].barBaseAddr <<= 32;
  72311. +
  72312. + pPciAgent->pciBar[detectedBar].barBaseAddr |=
  72313. + (MV_U64)pPciAgent->pciBar[detectedBar].barBaseLow;
  72314. +
  72315. +
  72316. +
  72317. + /* get the sizes of the the bar */
  72318. +
  72319. + pPciAgent->pciBar[detectedBar].barSizeHigh=0;
  72320. +
  72321. + if ((PCI_64BIT_BAR == pPciAgent->pciBar[detectedBar].barType) &&
  72322. + (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping))
  72323. +
  72324. + {
  72325. + /* write oxffffffff to the bar to get the size */
  72326. + /* start with sizelow ( original value was saved in tmpBaseLow ) */
  72327. + mvPciIfConfigWrite(pciIf,
  72328. + bus,dev,func,
  72329. + PCI_MEMORY_BAR_BASE_ADDR(barIndex-1),
  72330. + 0xffffffff);
  72331. +
  72332. + /* read size */
  72333. + pPciAgent->pciBar[detectedBar].barSizeLow =
  72334. + mvPciIfConfigRead(pciIf,
  72335. + bus,dev,func,
  72336. + PCI_MEMORY_BAR_BASE_ADDR(barIndex-1));
  72337. +
  72338. +
  72339. +
  72340. + /* restore original value */
  72341. + mvPciIfConfigWrite(pciIf,
  72342. + bus,dev,func,
  72343. + PCI_MEMORY_BAR_BASE_ADDR(barIndex-1),
  72344. + tmpBaseLow);
  72345. +
  72346. +
  72347. + /* now do the same for BaseHigh */
  72348. +
  72349. + /* write oxffffffff to the bar to get the size */
  72350. + mvPciIfConfigWrite(pciIf,
  72351. + bus,dev,func,
  72352. + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
  72353. + 0xffffffff);
  72354. +
  72355. + /* read size */
  72356. + pPciAgent->pciBar[detectedBar].barSizeHigh =
  72357. + mvPciIfConfigRead(pciIf,
  72358. + bus,dev,func,
  72359. + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
  72360. +
  72361. + /* restore original value */
  72362. + mvPciIfConfigWrite(pciIf,
  72363. + bus,dev,func,
  72364. + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
  72365. + tmpBaseHigh);
  72366. +
  72367. + if ((0 == pPciAgent->pciBar[detectedBar].barSizeLow)&&
  72368. + (0 == pPciAgent->pciBar[detectedBar].barSizeHigh))
  72369. + {
  72370. + /* this bar is not applicable for this device,
  72371. + ignore all previous settings and check the next bar*/
  72372. +
  72373. + /* we though this was a 64bit bar , and it seems this
  72374. + was wrong ! so decrement barIndex */
  72375. + barIndex--;
  72376. + continue;
  72377. + }
  72378. +
  72379. + /* calculate the full 64 bit size */
  72380. +
  72381. + if (0 != pPciAgent->pciBar[detectedBar].barSizeHigh)
  72382. + {
  72383. + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
  72384. +
  72385. + pPciAgent->pciBar[detectedBar].barSizeLow =
  72386. + ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
  72387. +
  72388. + pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
  72389. +
  72390. + }
  72391. + else
  72392. + {
  72393. +
  72394. + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
  72395. +
  72396. + pPciAgent->pciBar[detectedBar].barSizeLow =
  72397. + ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
  72398. +
  72399. + pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
  72400. +
  72401. + }
  72402. +
  72403. +
  72404. +
  72405. + }
  72406. + else /* 32bit bar */
  72407. + {
  72408. + /* write oxffffffff to the bar to get the size */
  72409. + mvPciIfConfigWrite(pciIf,
  72410. + bus,dev,func,
  72411. + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
  72412. + 0xffffffff);
  72413. +
  72414. + /* read size */
  72415. + pPciAgent->pciBar[detectedBar].barSizeLow =
  72416. + mvPciIfConfigRead(pciIf,
  72417. + bus,dev,func,
  72418. + PCI_MEMORY_BAR_BASE_ADDR(barIndex));
  72419. +
  72420. + if (0 == pPciAgent->pciBar[detectedBar].barSizeLow)
  72421. + {
  72422. + /* this bar is not applicable for this device,
  72423. + ignore all previous settings and check the next bar*/
  72424. + continue;
  72425. + }
  72426. +
  72427. +
  72428. + /* restore original value */
  72429. + mvPciIfConfigWrite(pciIf,
  72430. + bus,dev,func,
  72431. + PCI_MEMORY_BAR_BASE_ADDR(barIndex),
  72432. + tmpBaseLow);
  72433. +
  72434. + /* calculate size low */
  72435. +
  72436. + if (PCI_MEMORY_BAR == pPciAgent->pciBar[detectedBar].barMapping)
  72437. + {
  72438. + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_MEM_BASE_MASK;
  72439. + }
  72440. + else
  72441. + {
  72442. + pPciAgent->pciBar[detectedBar].barSizeLow &= PBBLR_IO_BASE_MASK;
  72443. + }
  72444. +
  72445. + pPciAgent->pciBar[detectedBar].barSizeLow =
  72446. + ~pPciAgent->pciBar[detectedBar].barSizeLow + 1;
  72447. +
  72448. + pPciAgent->pciBar[detectedBar].barSizeHigh = 0;
  72449. + pPciAgent->pciBar[detectedBar].barSize =
  72450. + (MV_U64)pPciAgent->pciBar[detectedBar].barSizeLow;
  72451. +
  72452. +
  72453. + }
  72454. +
  72455. + /* we are here ! this means we have already detected a bar for
  72456. + this device , now move on */
  72457. +
  72458. + detectedBar++;
  72459. + pPciAgent->barsNum++;
  72460. + }
  72461. +
  72462. + return detectedBar;
  72463. +}
  72464. +
  72465. +
  72466. +/*******************************************************************************
  72467. +* mvPciClassNameGet - get PCI class name
  72468. +*
  72469. +* DESCRIPTION:
  72470. +* This function returns the PCI class name
  72471. +*
  72472. +* INPUT:
  72473. +* baseClassCode - Base Class Code.
  72474. +*
  72475. +* OUTPUT:
  72476. +* pType - the class name
  72477. +*
  72478. +* RETURN:
  72479. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  72480. +*
  72481. +*******************************************************************************/
  72482. +MV_STATUS mvPciClassNameGet(MV_U32 baseClassCode, MV_8 *pType)
  72483. +{
  72484. +
  72485. + switch(baseClassCode)
  72486. + {
  72487. + case 0x0:
  72488. + strcpy(pType,"Old generation device");
  72489. + break;
  72490. + case 0x1:
  72491. + strcpy(pType,"Mass storage controller");
  72492. + break;
  72493. + case 0x2:
  72494. + strcpy(pType,"Network controller");
  72495. + break;
  72496. + case 0x3:
  72497. + strcpy(pType,"Display controller");
  72498. + break;
  72499. + case 0x4:
  72500. + strcpy(pType,"Multimedia device");
  72501. + break;
  72502. + case 0x5:
  72503. + strcpy(pType,"Memory controller");
  72504. + break;
  72505. + case 0x6:
  72506. + strcpy(pType,"Bridge Device");
  72507. + break;
  72508. + case 0x7:
  72509. + strcpy(pType,"Simple Communication controllers");
  72510. + break;
  72511. + case 0x8:
  72512. + strcpy(pType,"Base system peripherals");
  72513. + break;
  72514. + case 0x9:
  72515. + strcpy(pType,"Input Devices");
  72516. + break;
  72517. + case 0xa:
  72518. + strcpy(pType,"Docking stations");
  72519. + break;
  72520. + case 0xb:
  72521. + strcpy(pType,"Processors");
  72522. + break;
  72523. + case 0xc:
  72524. + strcpy(pType,"Serial bus controllers");
  72525. + break;
  72526. + case 0xd:
  72527. + strcpy(pType,"Wireless controllers");
  72528. + break;
  72529. + case 0xe:
  72530. + strcpy(pType,"Intelligent I/O controllers");
  72531. + break;
  72532. + case 0xf:
  72533. + strcpy(pType,"Satellite communication controllers");
  72534. + break;
  72535. + case 0x10:
  72536. + strcpy(pType,"Encryption/Decryption controllers");
  72537. + break;
  72538. + case 0x11:
  72539. + strcpy(pType,"Data acquisition and signal processing controllers");
  72540. + break;
  72541. + default:
  72542. + strcpy(pType,"Unknown device");
  72543. + break;
  72544. + }
  72545. +
  72546. + return MV_OK;
  72547. +
  72548. +}
  72549. +
  72550. +
  72551. +
  72552. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h
  72553. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h 1970-01-01 01:00:00.000000000 +0100
  72554. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pci-if/pci_util/mvPciUtils.h 2011-08-01 14:38:19.000000000 +0200
  72555. @@ -0,0 +1,323 @@
  72556. +/*******************************************************************************
  72557. +Copyright (C) Marvell International Ltd. and its affiliates
  72558. +
  72559. +This software file (the "File") is owned and distributed by Marvell
  72560. +International Ltd. and/or its affiliates ("Marvell") under the following
  72561. +alternative licensing terms. Once you have made an election to distribute the
  72562. +File under one of the following license alternatives, please (i) delete this
  72563. +introductory statement regarding license alternatives, (ii) delete the two
  72564. +license alternatives that you have not elected to use and (iii) preserve the
  72565. +Marvell copyright notice above.
  72566. +
  72567. +********************************************************************************
  72568. +Marvell Commercial License Option
  72569. +
  72570. +If you received this File from Marvell and you have entered into a commercial
  72571. +license agreement (a "Commercial License") with Marvell, the File is licensed
  72572. +to you under the terms of the applicable Commercial License.
  72573. +
  72574. +********************************************************************************
  72575. +Marvell GPL License Option
  72576. +
  72577. +If you received this File from Marvell, you may opt to use, redistribute and/or
  72578. +modify this File in accordance with the terms and conditions of the General
  72579. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  72580. +available along with the File in the license.txt file or by writing to the Free
  72581. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  72582. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  72583. +
  72584. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  72585. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  72586. +DISCLAIMED. The GPL License provides additional details about this warranty
  72587. +disclaimer.
  72588. +********************************************************************************
  72589. +Marvell BSD License Option
  72590. +
  72591. +If you received this File from Marvell, you may opt to use, redistribute and/or
  72592. +modify this File under the following licensing terms.
  72593. +Redistribution and use in source and binary forms, with or without modification,
  72594. +are permitted provided that the following conditions are met:
  72595. +
  72596. + * Redistributions of source code must retain the above copyright notice,
  72597. + this list of conditions and the following disclaimer.
  72598. +
  72599. + * Redistributions in binary form must reproduce the above copyright
  72600. + notice, this list of conditions and the following disclaimer in the
  72601. + documentation and/or other materials provided with the distribution.
  72602. +
  72603. + * Neither the name of Marvell nor the names of its contributors may be
  72604. + used to endorse or promote products derived from this software without
  72605. + specific prior written permission.
  72606. +
  72607. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  72608. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  72609. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  72610. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  72611. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  72612. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  72613. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  72614. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  72615. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  72616. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  72617. +
  72618. +*******************************************************************************/
  72619. +
  72620. +#ifndef __INCmvPciUtilsh
  72621. +#define __INCmvPciUtilsh
  72622. +
  72623. +/*
  72624. +This module only support scanning of Header type 00h of pci devices
  72625. +There is no suppotr for Header type 01h of pci devices ( PCI bridges )
  72626. +*/
  72627. +
  72628. +/* includes */
  72629. +#include "mvSysHwConfig.h"
  72630. +#include "pci-if/mvPciIf.h"
  72631. +#include "pci/mvPciRegs.h"
  72632. +
  72633. +
  72634. +
  72635. +/* PCI base address low bar mask */
  72636. +#define PCI_ERROR_CODE 0xffffffff
  72637. +
  72638. +#define PCI_BRIDGE_CLASS 0x6
  72639. +#define P2P_BRIDGE_SUB_CLASS_CODE 0x4
  72640. +
  72641. +
  72642. +#define P2P_BUSSES_NUM 0x18
  72643. +#define P2P_IO_BASE_LIMIT_SEC_STATUS 0x1C
  72644. +#define P2P_MEM_BASE_LIMIT 0x20
  72645. +#define P2P_PREF_MEM_BASE_LIMIT 0x24
  72646. +#define P2P_PREF_BASE_UPPER_32 0x28
  72647. +#define P2P_PREF_LIMIT_UPPER_32 0x2C
  72648. +#define P2P_IO_BASE_LIMIT_UPPER_16 0x30
  72649. +#define P2P_EXP_ROM 0x38
  72650. +
  72651. +/* P2P_BUSSES_NUM (PBM) */
  72652. +
  72653. +#define PBM_PRIME_BUS_NUM_OFFS 0
  72654. +#define PBM_PRIME_BUS_NUM_MASK (0xff << PBM_PRIME_BUS_NUM_OFFS)
  72655. +
  72656. +#define PBM_SEC_BUS_NUM_OFFS 8
  72657. +#define PBM_SEC_BUS_NUM_MASK (0xff << PBM_SEC_BUS_NUM_OFFS)
  72658. +
  72659. +#define PBM_SUB_BUS_NUM_OFFS 16
  72660. +#define PBM_SUB_BUS_NUM_MASK (0xff << PBM_SUB_BUS_NUM_OFFS)
  72661. +
  72662. +#define PBM_SEC_LAT_TMR_OFFS 24
  72663. +#define PBM_SEC_LAT_TMR_MASK (0xff << PBM_SEC_LAT_TMR_OFFS)
  72664. +
  72665. +/* P2P_IO_BASE_LIMIT_SEC_STATUS (PIBLSS) */
  72666. +
  72667. +#define PIBLSS_IO_BASE_OFFS 0
  72668. +#define PIBLSS_IO_BASE_MASK (0xff << PIBLSS_IO_BASE_OFFS)
  72669. +
  72670. +#define PIBLSS_ADD_CAP_OFFS 0
  72671. +#define PIBLSS_ADD_CAP_MASK (0x3 << PIBLSS_ADD_CAP_OFFS)
  72672. +#define PIBLSS_ADD_CAP_16BIT (0x0 << PIBLSS_ADD_CAP_OFFS)
  72673. +#define PIBLSS_ADD_CAP_32BIT (0x1 << PIBLSS_ADD_CAP_OFFS)
  72674. +
  72675. +#define PIBLSS_LOW_ADDR_OFFS 0
  72676. +#define PIBLSS_LOW_ADDR_MASK (0xFFF << PIBLSS_LOW_ADDR_OFFS)
  72677. +
  72678. +#define PIBLSS_HIGH_ADDR_OFFS 12
  72679. +#define PIBLSS_HIGH_ADDR_MASK (0xF << PIBLSS_HIGH_ADDR_OFFS)
  72680. +
  72681. +#define PIBLSS_IO_LIMIT_OFFS 8
  72682. +#define PIBLSS_IO_LIMIT_MASK (0xff << PIBLSS_IO_LIMIT_OFFS)
  72683. +
  72684. +#define PIBLSS_SEC_STATUS_OFFS 16
  72685. +#define PIBLSS_SEC_STATUS_MASK (0xffff << PIBLSS_SEC_STATUS_OFFS)
  72686. +
  72687. +
  72688. +/* P2P_MEM_BASE_LIMIT (PMBL)*/
  72689. +
  72690. +#define PMBL_MEM_BASE_OFFS 0
  72691. +#define PMBL_MEM_BASE_MASK (0xffff << PMBL_MEM_BASE_OFFS)
  72692. +
  72693. +#define PMBL_MEM_LIMIT_OFFS 16
  72694. +#define PMBL_MEM_LIMIT_MASK (0xffff << PMBL_MEM_LIMIT_OFFS)
  72695. +
  72696. +
  72697. +#define PMBL_LOW_ADDR_OFFS 0
  72698. +#define PMBL_LOW_ADDR_MASK (0xFFFFF << PMBL_LOW_ADDR_OFFS)
  72699. +
  72700. +#define PMBL_HIGH_ADDR_OFFS 20
  72701. +#define PMBL_HIGH_ADDR_MASK (0xFFF << PMBL_HIGH_ADDR_OFFS)
  72702. +
  72703. +
  72704. +/* P2P_PREF_MEM_BASE_LIMIT (PRMBL) */
  72705. +
  72706. +#define PRMBL_PREF_MEM_BASE_OFFS 0
  72707. +#define PRMBL_PREF_MEM_BASE_MASK (0xffff << PRMBL_PREF_MEM_BASE_OFFS)
  72708. +
  72709. +#define PRMBL_PREF_MEM_LIMIT_OFFS 16
  72710. +#define PRMBL_PREF_MEM_LIMIT_MASK (0xffff<<PRMBL_PREF_MEM_LIMIT_OFFS)
  72711. +
  72712. +#define PRMBL_LOW_ADDR_OFFS 0
  72713. +#define PRMBL_LOW_ADDR_MASK (0xFFFFF << PRMBL_LOW_ADDR_OFFS)
  72714. +
  72715. +#define PRMBL_HIGH_ADDR_OFFS 20
  72716. +#define PRMBL_HIGH_ADDR_MASK (0xFFF << PRMBL_HIGH_ADDR_OFFS)
  72717. +
  72718. +#define PRMBL_ADD_CAP_OFFS 0
  72719. +#define PRMBL_ADD_CAP_MASK (0xf << PRMBL_ADD_CAP_OFFS)
  72720. +#define PRMBL_ADD_CAP_32BIT (0x0 << PRMBL_ADD_CAP_OFFS)
  72721. +#define PRMBL_ADD_CAP_64BIT (0x1 << PRMBL_ADD_CAP_OFFS)
  72722. +
  72723. +/* P2P_IO_BASE_LIMIT_UPPER_16 (PIBLU) */
  72724. +
  72725. +#define PRBU_IO_UPP_BASE_OFFS 0
  72726. +#define PRBU_IO_UPP_BASE_MASK (0xffff << PRBU_IO_UPP_BASE_OFFS)
  72727. +
  72728. +#define PRBU_IO_UPP_LIMIT_OFFS 16
  72729. +#define PRBU_IO_UPP_LIMIT_MASK (0xffff << PRBU_IO_UPP_LIMIT_OFFS)
  72730. +
  72731. +
  72732. +/* typedefs */
  72733. +
  72734. +typedef enum _mvPciBarMapping
  72735. +{
  72736. + PCI_MEMORY_BAR,
  72737. + PCI_IO_BAR,
  72738. + PCI_NO_MAPPING
  72739. +}MV_PCI_BAR_MAPPING;
  72740. +
  72741. +typedef enum _mvPciBarType
  72742. +{
  72743. + PCI_32BIT_BAR,
  72744. + PCI_64BIT_BAR
  72745. +}MV_PCI_BAR_TYPE;
  72746. +
  72747. +typedef enum _mvPciIntPin
  72748. +{
  72749. + MV_PCI_INTA = 1,
  72750. + MV_PCI_INTB = 2,
  72751. + MV_PCI_INTC = 3,
  72752. + MV_PCI_INTD = 4
  72753. +}MV_PCI_INT_PIN;
  72754. +
  72755. +typedef enum _mvPciHeader
  72756. +{
  72757. + MV_PCI_STANDARD,
  72758. + MV_PCI_PCI2PCI_BRIDGE
  72759. +
  72760. +}MV_PCI_HEADER;
  72761. +
  72762. +
  72763. +/* BAR structure */
  72764. +typedef struct _pciBar
  72765. +{
  72766. + MV_U32 barOffset;
  72767. + MV_U32 barBaseLow;
  72768. + MV_U32 barBaseHigh;
  72769. + MV_U32 barSizeLow;
  72770. + MV_U32 barSizeHigh;
  72771. + /* The 'barBaseAddr' is a 64-bit variable
  72772. + that will contain the TOTAL base address
  72773. + value achived by combining both the 'barBaseLow'
  72774. + and the 'barBaseHigh' parameters as follows:
  72775. +
  72776. + BIT: 63 31 0
  72777. + | | |
  72778. + barBaseHigh barBaseLow */
  72779. + MV_U64 barBaseAddr;
  72780. + /* The 'barSize' is a 64-bit variable
  72781. + that will contain the TOTAL size achived
  72782. + by combining both the 'barSizeLow' and
  72783. + the 'barSizeHigh' parameters as follows:
  72784. +
  72785. + BIT: 63 31 0
  72786. + | | |
  72787. + barSizeHigh barSizeLow
  72788. +
  72789. + NOTE: The total size described above
  72790. + is AFTER the size calculation as
  72791. + described in PCI spec rev2.2 */
  72792. + MV_U64 barSize;
  72793. + MV_BOOL isPrefetchable;
  72794. + MV_PCI_BAR_TYPE barType;
  72795. + MV_PCI_BAR_MAPPING barMapping;
  72796. +
  72797. +
  72798. +} PCI_BAR;
  72799. +
  72800. +/* Device information structure */
  72801. +typedef struct _mvPciDevice
  72802. +{
  72803. + /* Device specific information */
  72804. + MV_U32 busNumber; /* Pci agent bus number */
  72805. + MV_U32 deviceNum; /* Pci agent device number */
  72806. + MV_U32 function; /* Pci agent function number */
  72807. +
  72808. + MV_U32 venID; /* Pci agent Vendor ID */
  72809. + MV_U32 deviceID; /* Pci agent Device ID */
  72810. +
  72811. + MV_BOOL isFastB2BCapable; /* Capability of Fast Back to Back
  72812. + transactions */
  72813. + MV_BOOL isCapListSupport; /* Support of Capability list */
  72814. + MV_BOOL is66MHZCapable; /* 66MHZ support */
  72815. +
  72816. + MV_U32 baseClassCode; /* Pci agent base Class Code */
  72817. + MV_U32 subClassCode; /* Pci agent sub Class Code */
  72818. + MV_U32 progIf; /* Pci agent Programing interface */
  72819. + MV_U32 revisionID;
  72820. +
  72821. + PCI_BAR pciBar[6]; /* Pci agent bar list */
  72822. +
  72823. + MV_U32 p2pPrimBusNum; /* P2P Primary Bus number*/
  72824. + MV_U32 p2pSecBusNum; /* P2P Secondary Bus Number*/
  72825. + MV_U32 p2pSubBusNum; /* P2P Subordinate bus Number */
  72826. + MV_U32 p2pSecLatencyTimer; /* P2P Econdary Latency Timer*/
  72827. + MV_U32 p2pIObase; /* P2P IO Base */
  72828. + MV_U32 p2pIOLimit; /* P2P IO Linit */
  72829. + MV_BOOL bIO32;
  72830. + MV_U32 p2pSecStatus; /* P2P Secondary Status */
  72831. + MV_U32 p2pMemBase; /* P2P Memory Space */
  72832. + MV_U32 p2pMemLimit; /* P2P Memory Limit*/
  72833. + MV_U32 p2pPrefMemBase; /* P2P Prefetchable Mem Base*/
  72834. + MV_U32 p2pPrefMemLimit; /* P2P Prefetchable Memory Limit*/
  72835. + MV_BOOL bPrefMem64;
  72836. + MV_U32 p2pPrefBaseUpper32Bits;/* P2P Prefetchable upper 32 bits*/
  72837. + MV_U32 p2pPrefLimitUpper32Bits;/* P2P prefetchable limit upper 32*/
  72838. +
  72839. +
  72840. + MV_U32 pciCacheLine; /* Pci agent cache line */
  72841. + MV_U32 pciLatencyTimer; /* Pci agent Latency timer */
  72842. + MV_PCI_HEADER pciHeader; /* Pci agent header type*/
  72843. + MV_BOOL isMultiFunction; /* Multi function support */
  72844. + MV_BOOL isBISTCapable; /* Self test capable */
  72845. +
  72846. + MV_U32 subSysID; /* Sub System ID */
  72847. + MV_U32 subSysVenID; /* Sub System Vendor ID */
  72848. +
  72849. + MV_BOOL isExpRom; /* Expantion Rom support */
  72850. + MV_U32 expRomAddr; /* Expantion Rom pointer */
  72851. +
  72852. + MV_U32 capListPointer; /* Capability list pointer */
  72853. +
  72854. + MV_U32 irqLine; /* IRQ line */
  72855. + MV_PCI_INT_PIN intPin; /* Interrupt pin */
  72856. + MV_U32 minGrant; /* Minimum grant*/
  72857. + MV_U32 maxLatency; /* Maximum latency*/
  72858. +
  72859. + MV_U32 funtionsNum; /* pci agent total functions number */
  72860. +
  72861. + MV_U32 barsNum;
  72862. + MV_U8 type[60]; /* class name of the pci agent */
  72863. +
  72864. +
  72865. +} MV_PCI_DEVICE;
  72866. +
  72867. +/* PCI gloabl functions */
  72868. +MV_STATUS mvPciClassNameGet(MV_U32 classCode, MV_8 *pType);
  72869. +
  72870. +
  72871. +/* Performs a full scan on both PCIs and returns all possible details on the
  72872. + agents found on the bus. */
  72873. +MV_STATUS mvPciScan(MV_U32 pciIf,
  72874. + MV_PCI_DEVICE *pPciAgents,
  72875. + MV_U32 *pPciAgentsNum);
  72876. +
  72877. +
  72878. +#endif /* #ifndef __INCmvPciUtilsh */
  72879. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c
  72880. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c 1970-01-01 01:00:00.000000000 +0100
  72881. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.c 2011-08-01 14:38:19.000000000 +0200
  72882. @@ -0,0 +1,1143 @@
  72883. +/*******************************************************************************
  72884. +Copyright (C) Marvell International Ltd. and its affiliates
  72885. +
  72886. +This software file (the "File") is owned and distributed by Marvell
  72887. +International Ltd. and/or its affiliates ("Marvell") under the following
  72888. +alternative licensing terms. Once you have made an election to distribute the
  72889. +File under one of the following license alternatives, please (i) delete this
  72890. +introductory statement regarding license alternatives, (ii) delete the two
  72891. +license alternatives that you have not elected to use and (iii) preserve the
  72892. +Marvell copyright notice above.
  72893. +
  72894. +********************************************************************************
  72895. +Marvell Commercial License Option
  72896. +
  72897. +If you received this File from Marvell and you have entered into a commercial
  72898. +license agreement (a "Commercial License") with Marvell, the File is licensed
  72899. +to you under the terms of the applicable Commercial License.
  72900. +
  72901. +********************************************************************************
  72902. +Marvell GPL License Option
  72903. +
  72904. +If you received this File from Marvell, you may opt to use, redistribute and/or
  72905. +modify this File in accordance with the terms and conditions of the General
  72906. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  72907. +available along with the File in the license.txt file or by writing to the Free
  72908. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  72909. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  72910. +
  72911. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  72912. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  72913. +DISCLAIMED. The GPL License provides additional details about this warranty
  72914. +disclaimer.
  72915. +********************************************************************************
  72916. +Marvell BSD License Option
  72917. +
  72918. +If you received this File from Marvell, you may opt to use, redistribute and/or
  72919. +modify this File under the following licensing terms.
  72920. +Redistribution and use in source and binary forms, with or without modification,
  72921. +are permitted provided that the following conditions are met:
  72922. +
  72923. + * Redistributions of source code must retain the above copyright notice,
  72924. + this list of conditions and the following disclaimer.
  72925. +
  72926. + * Redistributions in binary form must reproduce the above copyright
  72927. + notice, this list of conditions and the following disclaimer in the
  72928. + documentation and/or other materials provided with the distribution.
  72929. +
  72930. + * Neither the name of Marvell nor the names of its contributors may be
  72931. + used to endorse or promote products derived from this software without
  72932. + specific prior written permission.
  72933. +
  72934. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  72935. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  72936. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  72937. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  72938. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  72939. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  72940. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  72941. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  72942. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  72943. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  72944. +
  72945. +*******************************************************************************/
  72946. +
  72947. +#include "pex/mvPex.h"
  72948. +
  72949. +#include "ctrlEnv/mvCtrlEnvLib.h"
  72950. +
  72951. +/* defines */
  72952. +#ifdef MV_DEBUG
  72953. +#define DB(x) x
  72954. +#else
  72955. +#define DB(x)
  72956. +#endif
  72957. +
  72958. +MV_STATUS mvPexHalInit(MV_U32 pexIf, MV_PEX_TYPE pexType)
  72959. +{
  72960. + MV_PEX_MODE pexMode;
  72961. + MV_U32 regVal;
  72962. + MV_U32 status;
  72963. +
  72964. + /* First implement Guideline (GL# PCI Express-2) Wrong Default Value */
  72965. + /* to Transmitter Output Current (TXAMP) Relevant for: 88F5181-A1/B0/B1 */
  72966. + /* and 88F5281-B0 and above, 88F5182, 88F5082, 88F5181L, 88F6082/L */
  72967. +
  72968. + if ((mvCtrlModelGet() != MV_1281_DEV_ID) &&
  72969. + (mvCtrlModelGet() != MV_6281_DEV_ID) &&
  72970. + (mvCtrlModelGet() != MV_6192_DEV_ID) &&
  72971. + (mvCtrlModelGet() != MV_6190_DEV_ID) &&
  72972. + (mvCtrlModelGet() != MV_6180_DEV_ID) &&
  72973. + (mvCtrlModelGet() != MV_6183_DEV_ID) &&
  72974. + (mvCtrlModelGet() != MV_6183L_DEV_ID) &&
  72975. + (mvCtrlModelGet() != MV_78100_DEV_ID) &&
  72976. + (mvCtrlModelGet() != MV_78200_DEV_ID) &&
  72977. + (mvCtrlModelGet() != MV_76100_DEV_ID) &&
  72978. + (mvCtrlModelGet() != MV_78XX0_DEV_ID))
  72979. + {
  72980. +
  72981. + /* Read current value of TXAMP */
  72982. + MV_REG_WRITE(0x41b00, 0x80820000); /* Write the read command */
  72983. +
  72984. + regVal = MV_REG_READ(0x41b00); /* Extract the data */
  72985. +
  72986. + /* Prepare new data for write */
  72987. + regVal &= ~0x7; /* Clear bits [2:0] */
  72988. + regVal |= 0x4; /* Set the new value */
  72989. + regVal &= ~0x80000000; /* Set "write" command */
  72990. + MV_REG_WRITE(0x41b00, regVal); /* Write the write command */
  72991. +
  72992. + }
  72993. + else
  72994. + {
  72995. + /* Implement 1.0V termination GL for 88F1281 device only */
  72996. + /* BIT0 - Common mode feedback */
  72997. + /* BIT3 - TxBuf, extra drive for 1.0V termination */
  72998. + if (mvCtrlModelGet() == MV_1281_DEV_ID)
  72999. + {
  73000. + MV_REG_WRITE(0x41b00, 0x80860000); /* Write the read command */
  73001. + regVal = MV_REG_READ(0x41b00); /* Extract the data */
  73002. + regVal |= (BIT0 | BIT3);
  73003. + regVal &= ~0x80000000; /* Set "write" command */
  73004. + MV_REG_WRITE(0x41b00, regVal); /* Write the write command */
  73005. +
  73006. + MV_REG_WRITE(0x31b00, 0x80860000); /* Write the read command */
  73007. + regVal = MV_REG_READ(0x31b00); /* Extract the data */
  73008. + regVal |= (BIT0 | BIT3);
  73009. + regVal &= ~0x80000000; /* Set "write" command */
  73010. + MV_REG_WRITE(0x31b00, regVal); /* Write the write command */
  73011. + }
  73012. + }
  73013. +
  73014. + if( mvPexModeGet(pexIf, &pexMode) != MV_OK)
  73015. + {
  73016. + mvOsPrintf("PEX init ERR. mvPexModeGet failed (pexType=%d)\n",pexMode.pexType);
  73017. + return MV_ERROR;
  73018. + }
  73019. +
  73020. + /* Check that required PEX type is the one set in reset time */
  73021. + if (pexType != pexMode.pexType)
  73022. + {
  73023. + /* No Link. Shut down the Phy */
  73024. + mvPexPowerDown(pexIf);
  73025. + mvOsPrintf("PEX init ERR. PEX type sampled mismatch (%d,%d)\n",pexType,pexMode.pexType);
  73026. + return MV_ERROR;
  73027. + }
  73028. +
  73029. + if (MV_PEX_ROOT_COMPLEX == pexType)
  73030. + {
  73031. + mvPexLocalBusNumSet(pexIf, PEX_HOST_BUS_NUM(pexIf));
  73032. + mvPexLocalDevNumSet(pexIf, PEX_HOST_DEV_NUM(pexIf));
  73033. +
  73034. + /* Local device master Enable */
  73035. + mvPexMasterEnable(pexIf, MV_TRUE);
  73036. +
  73037. + /* Local device slave Enable */
  73038. + mvPexSlaveEnable(pexIf, mvPexLocalBusNumGet(pexIf),
  73039. + mvPexLocalDevNumGet(pexIf), MV_TRUE);
  73040. + /* Interrupt disable */
  73041. + status = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND));
  73042. + status |= PXSAC_INT_DIS;
  73043. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_STATUS_AND_COMMAND), status);
  73044. + }
  73045. +
  73046. + /* now wait 500 ms to be sure the link is valid (spec compliant) */
  73047. + mvOsDelay(500);
  73048. + /* Check if we have link */
  73049. + if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)
  73050. + {
  73051. + mvOsPrintf("PEX%d interface detected no Link.\n",pexIf);
  73052. + return MV_NO_SUCH;
  73053. + }
  73054. +
  73055. + if (MV_PEX_WITDH_X1 == pexMode.pexWidth)
  73056. + {
  73057. + mvOsPrintf("PEX%d interface detected Link X1\n",pexIf);
  73058. + }
  73059. + else
  73060. + {
  73061. + mvOsPrintf("PEX%d interface detected Link X4\n",pexIf);
  73062. + }
  73063. +
  73064. +#ifdef PCIE_VIRTUAL_BRIDGE_SUPPORT
  73065. + mvPexVrtBrgInit(pexIf);
  73066. +#endif
  73067. + return MV_OK;
  73068. +}
  73069. +
  73070. +/*******************************************************************************
  73071. +* mvPexModeGet - Get Pex Mode
  73072. +*
  73073. +* DESCRIPTION:
  73074. +*
  73075. +* INPUT:
  73076. +* pexIf - PEX interface number.
  73077. +*
  73078. +* OUTPUT:
  73079. +* pexMode - Pex mode structure
  73080. +*
  73081. +* RETURN:
  73082. +* MV_OK on success , MV_ERROR otherwise
  73083. +*
  73084. +*******************************************************************************/
  73085. +MV_U32 mvPexModeGet(MV_U32 pexIf,MV_PEX_MODE *pexMode)
  73086. +{
  73087. + MV_U32 pexData;
  73088. +
  73089. + /* Parameter checking */
  73090. + if (PEX_DEFAULT_IF != pexIf)
  73091. + {
  73092. + if (pexIf >= mvCtrlPexMaxIfGet())
  73093. + {
  73094. + mvOsPrintf("mvPexModeGet: ERR. Invalid PEX interface %d\n",pexIf);
  73095. + return MV_ERROR;
  73096. + }
  73097. + }
  73098. +
  73099. + pexData = MV_REG_READ(PEX_CTRL_REG(pexIf));
  73100. +
  73101. + switch (pexData & PXCR_DEV_TYPE_CTRL_MASK)
  73102. + {
  73103. + case PXCR_DEV_TYPE_CTRL_CMPLX:
  73104. + pexMode->pexType = MV_PEX_ROOT_COMPLEX;
  73105. + break;
  73106. + case PXCR_DEV_TYPE_CTRL_POINT:
  73107. + pexMode->pexType = MV_PEX_END_POINT;
  73108. + break;
  73109. +
  73110. + }
  73111. +
  73112. + /* Check if we have link */
  73113. + if (MV_REG_READ(PEX_STATUS_REG(pexIf)) & PXSR_DL_DOWN)
  73114. + {
  73115. + pexMode->pexLinkUp = MV_FALSE;
  73116. +
  73117. + /* If there is no link, the auto negotiation data is worthless */
  73118. + pexMode->pexWidth = MV_PEX_WITDH_INVALID;
  73119. + }
  73120. + else
  73121. + {
  73122. + pexMode->pexLinkUp = MV_TRUE;
  73123. +
  73124. + /* We have link. The link width is now valid */
  73125. + pexData = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG));
  73126. + pexMode->pexWidth = ((pexData & PXLCSR_NEG_LNK_WDTH_MASK) >>
  73127. + PXLCSR_NEG_LNK_WDTH_OFFS);
  73128. + }
  73129. +
  73130. + return MV_OK;
  73131. +}
  73132. +
  73133. +
  73134. +/* PEX configuration space read write */
  73135. +
  73136. +/*******************************************************************************
  73137. +* mvPexConfigRead - Read from configuration space
  73138. +*
  73139. +* DESCRIPTION:
  73140. +* This function performs a 32 bit read from PEX configuration space.
  73141. +* It supports both type 0 and type 1 of Configuration Transactions
  73142. +* (local and over bridge). In order to read from local bus segment, use
  73143. +* bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers
  73144. +* will result configuration transaction of type 1 (over bridge).
  73145. +*
  73146. +* INPUT:
  73147. +* pexIf - PEX interface number.
  73148. +* bus - PEX segment bus number.
  73149. +* dev - PEX device number.
  73150. +* func - Function number.
  73151. +* regOffs - Register offset.
  73152. +*
  73153. +* OUTPUT:
  73154. +* None.
  73155. +*
  73156. +* RETURN:
  73157. +* 32bit register data, 0xffffffff on error
  73158. +*
  73159. +*******************************************************************************/
  73160. +MV_U32 mvPexConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  73161. + MV_U32 regOff)
  73162. +{
  73163. +#if defined(PCIE_VIRTUAL_BRIDGE_SUPPORT)
  73164. + return mvPexVrtBrgConfigRead (pexIf, bus, dev, func, regOff);
  73165. +}
  73166. +
  73167. +MV_U32 mvPexHwConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  73168. + MV_U32 regOff)
  73169. +{
  73170. +#endif
  73171. + MV_U32 pexData = 0;
  73172. + MV_U32 localDev,localBus;
  73173. +
  73174. + /* Parameter checking */
  73175. + if (PEX_DEFAULT_IF != pexIf)
  73176. + {
  73177. + if (pexIf >= mvCtrlPexMaxIfGet())
  73178. + {
  73179. + mvOsPrintf("mvPexConfigRead: ERR. Invalid PEX interface %d\n",pexIf);
  73180. + return 0xFFFFFFFF;
  73181. + }
  73182. + }
  73183. +
  73184. + if (dev >= MAX_PEX_DEVICES)
  73185. + {
  73186. + DB(mvOsPrintf("mvPexConfigRead: ERR. device number illigal %d\n", dev));
  73187. + return 0xFFFFFFFF;
  73188. + }
  73189. +
  73190. + if (func >= MAX_PEX_FUNCS)
  73191. + {
  73192. + DB(mvOsPrintf("mvPexConfigRead: ERR. function num illigal %d\n", func));
  73193. + return 0xFFFFFFFF;
  73194. + }
  73195. +
  73196. + if (bus >= MAX_PEX_BUSSES)
  73197. + {
  73198. + DB(mvOsPrintf("mvPexConfigRead: ERR. bus number illigal %d\n", bus));
  73199. + return MV_ERROR;
  73200. + }
  73201. +
  73202. + DB(mvOsPrintf("mvPexConfigRead: pexIf %d, bus %d, dev %d, func %d, regOff 0x%x\n",
  73203. + pexIf, bus, dev, func, regOff));
  73204. +
  73205. + localDev = mvPexLocalDevNumGet(pexIf);
  73206. + localBus = mvPexLocalBusNumGet(pexIf);
  73207. +
  73208. + /* Speed up the process. In case on no link, return MV_ERROR */
  73209. + if ((dev != localDev) || (bus != localBus))
  73210. + {
  73211. + pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));
  73212. +
  73213. + if ((pexData & PXSR_DL_DOWN))
  73214. + {
  73215. + return MV_ERROR;
  73216. + }
  73217. + }
  73218. +
  73219. + /* in PCI Express we have only one device number */
  73220. + /* and this number is the first number we encounter
  73221. + else that the localDev*/
  73222. + /* spec pex define return on config read/write on any device */
  73223. + if (bus == localBus)
  73224. + {
  73225. + if (localDev == 0)
  73226. + {
  73227. + /* if local dev is 0 then the first number we encounter
  73228. + after 0 is 1 */
  73229. + if ((dev != 1)&&(dev != localDev))
  73230. + {
  73231. + return MV_ERROR;
  73232. + }
  73233. + }
  73234. + else
  73235. + {
  73236. + /* if local dev is not 0 then the first number we encounter
  73237. + is 0 */
  73238. +
  73239. + if ((dev != 0)&&(dev != localDev))
  73240. + {
  73241. + return MV_ERROR;
  73242. + }
  73243. + }
  73244. + if(func != 0 ) /* i.e bridge */
  73245. + {
  73246. + return MV_ERROR;
  73247. + }
  73248. + }
  73249. +
  73250. +
  73251. + /* Creating PEX address to be passed */
  73252. + pexData = (bus << PXCAR_BUS_NUM_OFFS);
  73253. + pexData |= (dev << PXCAR_DEVICE_NUM_OFFS);
  73254. + pexData |= (func << PXCAR_FUNC_NUM_OFFS);
  73255. + pexData |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
  73256. + /* extended register space */
  73257. + pexData |=(((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >>
  73258. + PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
  73259. +
  73260. + pexData |= PXCAR_CONFIG_EN;
  73261. +
  73262. + /* Write the address to the PEX configuration address register */
  73263. + MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);
  73264. +
  73265. + DB(mvOsPrintf("mvPexConfigRead:address pexData=%x ",pexData));
  73266. +
  73267. +
  73268. + /* In order to let the PEX controller absorbed the address of the read */
  73269. + /* transaction we perform a validity check that the address was written */
  73270. + if(pexData != MV_REG_READ(PEX_CFG_ADDR_REG(pexIf)))
  73271. + {
  73272. + return MV_ERROR;
  73273. + }
  73274. +
  73275. + /* cleaning Master Abort */
  73276. + MV_REG_BIT_SET(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND),
  73277. + PXSAC_MABORT);
  73278. +#if 0
  73279. + /* Guideline (GL# PCI Express-1) Erroneous Read Data on Configuration */
  73280. + /* This guideline is relevant for all devices except of the following devices:
  73281. + 88F5281-BO and above, 88F5181L-A0 and above, 88F1281 A0 and above
  73282. + 88F6183 A0 and above, 88F6183L */
  73283. + if ( ( (dev != localDev) || (bus != localBus) ) &&
  73284. + (
  73285. + !(MV_5281_DEV_ID == mvCtrlModelGet())&&
  73286. + !((MV_5181_DEV_ID == mvCtrlModelGet())&& (mvCtrlRevGet() >= MV_5181L_A0_REV))&&
  73287. + !(MV_1281_DEV_ID == mvCtrlModelGet())&&
  73288. + !(MV_6183_DEV_ID == mvCtrlModelGet())&&
  73289. + !(MV_6183L_DEV_ID == mvCtrlModelGet())&&
  73290. + !(MV_6281_DEV_ID == mvCtrlModelGet())&&
  73291. + !(MV_6192_DEV_ID == mvCtrlModelGet())&&
  73292. + !(MV_6190_DEV_ID == mvCtrlModelGet())&&
  73293. + !(MV_6180_DEV_ID == mvCtrlModelGet())&&
  73294. + !(MV_78XX0_DEV_ID == mvCtrlModelGet())
  73295. + ))
  73296. + {
  73297. +
  73298. + /* PCI-Express configuration read work-around */
  73299. +
  73300. + /* we will use one of the Punit (AHBToMbus) windows to access the xbar
  73301. + and read the data from there */
  73302. + /*
  73303. + Need to configure the 2 free Punit (AHB to MBus bridge)
  73304. + address decoding windows:
  73305. + Configure the flash Window to handle Configuration space requests
  73306. + for PEX0/1:
  73307. + 1. write 0x7931/0x7941 to the flash window and the size,
  73308. + 79-xbar attr (pci cfg), 3/4-xbar target (pex0/1), 1-WinEn
  73309. + 2. write base to flash window
  73310. +
  73311. + Configuration transactions from the CPU should write/read the data
  73312. + to/from address of the form:
  73313. + addr[31:28] = 0x5 (for PEX0) or 0x6 (for PEX1)
  73314. + addr[27:24] = extended register number
  73315. + addr[23:16] = bus number
  73316. + addr[15:11] = device number
  73317. + addr[10:8] = function number
  73318. + addr[7:0] = register number
  73319. + */
  73320. +
  73321. + #include "ctrlEnv/sys/mvAhbToMbus.h"
  73322. + {
  73323. + MV_U32 winNum;
  73324. + MV_AHB_TO_MBUS_DEC_WIN originWin;
  73325. + MV_U32 pciAddr=0;
  73326. + MV_U32 remapLow=0,remapHigh=0;
  73327. +
  73328. + /*
  73329. + We will use DEV_CS2\Flash window for this workarround
  73330. + */
  73331. +
  73332. + winNum = mvAhbToMbusWinTargetGet(PEX_CONFIG_RW_WA_TARGET);
  73333. +
  73334. + /* save remap values if exist */
  73335. + if ((1 == winNum)||(0 == winNum))
  73336. + {
  73337. + remapLow = MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum));
  73338. + remapHigh = MV_REG_READ(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum));
  73339. +
  73340. + }
  73341. +
  73342. +
  73343. + /* save the original window values */
  73344. + mvAhbToMbusWinGet(winNum,&originWin);
  73345. +
  73346. + if (PEX_CONFIG_RW_WA_USE_ORIGINAL_WIN_VALUES)
  73347. + {
  73348. + /* set the window as xbar window */
  73349. + if (pexIf)
  73350. + {
  73351. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
  73352. + (0x7931 | (((originWin.addrWin.size >> 16)-1) ) << 16));
  73353. + }
  73354. + else
  73355. + {
  73356. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
  73357. + (0x7941 | (((originWin.addrWin.size >> 16)-1) ) << 16));
  73358. + }
  73359. +
  73360. + MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),
  73361. + originWin.addrWin.baseLow);
  73362. +
  73363. + /*pciAddr = originWin.addrWin.baseLow;*/
  73364. + pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(
  73365. + (MV_U32)originWin.addrWin.baseLow);
  73366. +
  73367. + }
  73368. + else
  73369. + {
  73370. + /* set the window as xbar window */
  73371. + if (pexIf)
  73372. + {
  73373. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
  73374. + (0x7931 | (((PEX_CONFIG_RW_WA_SIZE >> 16)-1) ) << 16));
  73375. + }
  73376. + else
  73377. + {
  73378. + MV_REG_WRITE(AHB_TO_MBUS_WIN_CTRL_REG(winNum),
  73379. + (0x7941 | (((PEX_CONFIG_RW_WA_SIZE >> 16)-1) ) << 16));
  73380. + }
  73381. +
  73382. + MV_REG_WRITE(AHB_TO_MBUS_WIN_BASE_REG(winNum),
  73383. + PEX_CONFIG_RW_WA_BASE);
  73384. +
  73385. + pciAddr = (MV_U32)CPU_MEMIO_UNCACHED_ADDR(PEX_CONFIG_RW_WA_BASE);
  73386. + }
  73387. +
  73388. +
  73389. + /* remap should be as base */
  73390. + if ((1 == winNum)||(0 == winNum))
  73391. + {
  73392. + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum),pciAddr);
  73393. + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum),0);
  73394. +
  73395. + }
  73396. +
  73397. + /* extended register space */
  73398. + pciAddr |= (bus << 16);
  73399. + pciAddr |= (dev << 11);
  73400. + pciAddr |= (func << 8);
  73401. + pciAddr |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
  73402. +
  73403. + pexData = *(MV_U32*)pciAddr;
  73404. + pexData = MV_32BIT_LE(pexData); /* Data always in LE */
  73405. +
  73406. + /* restore the original window values */
  73407. + mvAhbToMbusWinSet(winNum,&originWin);
  73408. +
  73409. + /* restore original remap values*/
  73410. + if ((1 == winNum)||(0 == winNum))
  73411. + {
  73412. + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_LOW_REG(winNum),remapLow);
  73413. + MV_REG_WRITE(AHB_TO_MBUS_WIN_REMAP_HIGH_REG(winNum),remapHigh);
  73414. +
  73415. + }
  73416. + }
  73417. + }
  73418. + else
  73419. +#endif
  73420. + {
  73421. + /* Read the Data returned in the PEX Data register */
  73422. + pexData = MV_REG_READ(PEX_CFG_DATA_REG(pexIf));
  73423. +
  73424. + }
  73425. +
  73426. + DB(mvOsPrintf("mvPexConfigRead: got : %x \n",pexData));
  73427. +
  73428. + return pexData;
  73429. +
  73430. +}
  73431. +
  73432. +/*******************************************************************************
  73433. +* mvPexConfigWrite - Write to configuration space
  73434. +*
  73435. +* DESCRIPTION:
  73436. +* This function performs a 32 bit write to PEX configuration space.
  73437. +* It supports both type 0 and type 1 of Configuration Transactions
  73438. +* (local and over bridge). In order to write to local bus segment, use
  73439. +* bus number retrieved from mvPexLocalBusNumGet(). Other bus numbers
  73440. +* will result configuration transaction of type 1 (over bridge).
  73441. +*
  73442. +* INPUT:
  73443. +* pexIf - PEX interface number.
  73444. +* bus - PEX segment bus number.
  73445. +* dev - PEX device number.
  73446. +* func - Function number.
  73447. +* regOffs - Register offset.
  73448. +* data - 32bit data.
  73449. +*
  73450. +* OUTPUT:
  73451. +* None.
  73452. +*
  73453. +* RETURN:
  73454. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  73455. +*
  73456. +*******************************************************************************/
  73457. +MV_STATUS mvPexConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  73458. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  73459. +{
  73460. +#if defined(PCIE_VIRTUAL_BRIDGE_SUPPORT)
  73461. + return mvPexVrtBrgConfigWrite (pexIf, bus, dev, func, regOff, data);
  73462. +}
  73463. +
  73464. +MV_STATUS mvPexHwConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  73465. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  73466. +{
  73467. +#endif
  73468. + MV_U32 pexData = 0;
  73469. + MV_U32 localDev,localBus;
  73470. +
  73471. + /* Parameter checking */
  73472. + if (PEX_DEFAULT_IF != pexIf)
  73473. + {
  73474. + if (pexIf >= mvCtrlPexMaxIfGet())
  73475. + {
  73476. + mvOsPrintf("mvPexConfigWrite: ERR. Invalid PEX interface %d\n",
  73477. + pexIf);
  73478. + return MV_ERROR;
  73479. + }
  73480. + }
  73481. +
  73482. + if (dev >= MAX_PEX_DEVICES)
  73483. + {
  73484. + mvOsPrintf("mvPexConfigWrite: ERR. device number illigal %d\n",dev);
  73485. + return MV_BAD_PARAM;
  73486. + }
  73487. +
  73488. + if (func >= MAX_PEX_FUNCS)
  73489. + {
  73490. + mvOsPrintf("mvPexConfigWrite: ERR. function number illigal %d\n", func);
  73491. + return MV_ERROR;
  73492. + }
  73493. +
  73494. + if (bus >= MAX_PEX_BUSSES)
  73495. + {
  73496. + mvOsPrintf("mvPexConfigWrite: ERR. bus number illigal %d\n", bus);
  73497. + return MV_ERROR;
  73498. + }
  73499. +
  73500. +
  73501. +
  73502. + localDev = mvPexLocalDevNumGet(pexIf);
  73503. + localBus = mvPexLocalBusNumGet(pexIf);
  73504. +
  73505. +
  73506. + /* in PCI Express we have only one device number other than ourselves*/
  73507. + /* and this number is the first number we encounter
  73508. + else than the localDev that can be any valid dev number*/
  73509. + /* pex spec define return on config read/write on any device */
  73510. + if (bus == localBus)
  73511. + {
  73512. +
  73513. + if (localDev == 0)
  73514. + {
  73515. + /* if local dev is 0 then the first number we encounter
  73516. + after 0 is 1 */
  73517. + if ((dev != 1)&&(dev != localDev))
  73518. + {
  73519. + return MV_ERROR;
  73520. + }
  73521. +
  73522. + }
  73523. + else
  73524. + {
  73525. + /* if local dev is not 0 then the first number we encounter
  73526. + is 0 */
  73527. +
  73528. + if ((dev != 0)&&(dev != localDev))
  73529. + {
  73530. + return MV_ERROR;
  73531. + }
  73532. + }
  73533. +
  73534. +
  73535. + }
  73536. +
  73537. + /* if we are not accessing ourselves , then check the link */
  73538. + if ((dev != localDev) || (bus != localBus) )
  73539. + {
  73540. + /* workarround */
  73541. + /* when no link return MV_ERROR */
  73542. +
  73543. + pexData = MV_REG_READ(PEX_STATUS_REG(pexIf));
  73544. +
  73545. + if ((pexData & PXSR_DL_DOWN))
  73546. + {
  73547. + return MV_ERROR;
  73548. + }
  73549. +
  73550. + }
  73551. +
  73552. + pexData =0;
  73553. +
  73554. + /* Creating PEX address to be passed */
  73555. + pexData |= (bus << PXCAR_BUS_NUM_OFFS);
  73556. + pexData |= (dev << PXCAR_DEVICE_NUM_OFFS);
  73557. + pexData |= (func << PXCAR_FUNC_NUM_OFFS);
  73558. + pexData |= (regOff & PXCAR_REG_NUM_MASK); /* lgacy register space */
  73559. + /* extended register space */
  73560. + pexData |=(((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >>
  73561. + PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS);
  73562. + pexData |= PXCAR_CONFIG_EN;
  73563. +
  73564. + DB(mvOsPrintf("mvPexConfigWrite: If=%x bus=%x func=%x dev=%x regOff=%x data=%x \n",
  73565. + pexIf,bus,func,dev,regOff,data,pexData) );
  73566. +
  73567. + /* Write the address to the PEX configuration address register */
  73568. + MV_REG_WRITE(PEX_CFG_ADDR_REG(pexIf), pexData);
  73569. +
  73570. + /* Clear CPU pipe. Important where CPU can perform OOO execution */
  73571. + CPU_PIPE_FLUSH;
  73572. +
  73573. + /* In order to let the PEX controller absorbed the address of the read */
  73574. + /* transaction we perform a validity check that the address was written */
  73575. + if(pexData != MV_REG_READ(PEX_CFG_ADDR_REG(pexIf)))
  73576. + {
  73577. + return MV_ERROR;
  73578. + }
  73579. +
  73580. + /* Write the Data passed to the PEX Data register */
  73581. + MV_REG_WRITE(PEX_CFG_DATA_REG(pexIf), data);
  73582. +
  73583. + return MV_OK;
  73584. +
  73585. +}
  73586. +
  73587. +/*******************************************************************************
  73588. +* mvPexMasterEnable - Enable/disale PEX interface master transactions.
  73589. +*
  73590. +* DESCRIPTION:
  73591. +* This function performs read modified write to PEX command status
  73592. +* (offset 0x4) to set/reset bit 2. After this bit is set, the PEX
  73593. +* master is allowed to gain ownership on the bus, otherwise it is
  73594. +* incapable to do so.
  73595. +*
  73596. +* INPUT:
  73597. +* pexIf - PEX interface number.
  73598. +* enable - Enable/disable parameter.
  73599. +*
  73600. +* OUTPUT:
  73601. +* None.
  73602. +*
  73603. +* RETURN:
  73604. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  73605. +*
  73606. +*******************************************************************************/
  73607. +MV_STATUS mvPexMasterEnable(MV_U32 pexIf, MV_BOOL enable)
  73608. +{
  73609. + MV_U32 pexCommandStatus;
  73610. + MV_U32 localBus;
  73611. + MV_U32 localDev;
  73612. +
  73613. + /* Parameter checking */
  73614. + if (pexIf >= mvCtrlPexMaxIfGet())
  73615. + {
  73616. + mvOsPrintf("mvPexMasterEnable: ERR. Invalid PEX interface %d\n", pexIf);
  73617. + return MV_ERROR;
  73618. + }
  73619. +
  73620. + localBus = mvPexLocalBusNumGet(pexIf);
  73621. + localDev = mvPexLocalDevNumGet(pexIf);
  73622. +
  73623. + pexCommandStatus = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf,
  73624. + PEX_STATUS_AND_COMMAND));
  73625. +
  73626. +
  73627. + if (MV_TRUE == enable)
  73628. + {
  73629. + pexCommandStatus |= PXSAC_MASTER_EN;
  73630. + }
  73631. + else
  73632. + {
  73633. + pexCommandStatus &= ~PXSAC_MASTER_EN;
  73634. + }
  73635. +
  73636. +
  73637. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf,PEX_STATUS_AND_COMMAND),
  73638. + pexCommandStatus);
  73639. +
  73640. + return MV_OK;
  73641. +}
  73642. +
  73643. +
  73644. +/*******************************************************************************
  73645. +* mvPexSlaveEnable - Enable/disale PEX interface slave transactions.
  73646. +*
  73647. +* DESCRIPTION:
  73648. +* This function performs read modified write to PEX command status
  73649. +* (offset 0x4) to set/reset bit 0 and 1. After those bits are set,
  73650. +* the PEX slave is allowed to respond to PEX IO space access (bit 0)
  73651. +* and PEX memory space access (bit 1).
  73652. +*
  73653. +* INPUT:
  73654. +* pexIf - PEX interface number.
  73655. +* dev - PEX device number.
  73656. +* enable - Enable/disable parameter.
  73657. +*
  73658. +* OUTPUT:
  73659. +* None.
  73660. +*
  73661. +* RETURN:
  73662. +* MV_BAD_PARAM for bad parameters ,MV_ERROR on error ! otherwise MV_OK
  73663. +*
  73664. +*******************************************************************************/
  73665. +MV_STATUS mvPexSlaveEnable(MV_U32 pexIf, MV_U32 bus,MV_U32 dev, MV_BOOL enable)
  73666. +{
  73667. + MV_U32 pexCommandStatus;
  73668. + MV_U32 RegOffs;
  73669. +
  73670. + /* Parameter checking */
  73671. + if (pexIf >= mvCtrlPexMaxIfGet())
  73672. + {
  73673. + mvOsPrintf("mvPexSlaveEnable: ERR. Invalid PEX interface %d\n", pexIf);
  73674. + return MV_BAD_PARAM;
  73675. + }
  73676. + if (dev >= MAX_PEX_DEVICES)
  73677. + {
  73678. + mvOsPrintf("mvPexLocalDevNumSet: ERR. device number illigal %d\n", dev);
  73679. + return MV_BAD_PARAM;
  73680. +
  73681. + }
  73682. +
  73683. +
  73684. + RegOffs = PEX_STATUS_AND_COMMAND;
  73685. +
  73686. + pexCommandStatus = mvPexConfigRead(pexIf, bus, dev, 0, RegOffs);
  73687. +
  73688. + if (MV_TRUE == enable)
  73689. + {
  73690. + pexCommandStatus |= (PXSAC_IO_EN | PXSAC_MEM_EN);
  73691. + }
  73692. + else
  73693. + {
  73694. + pexCommandStatus &= ~(PXSAC_IO_EN | PXSAC_MEM_EN);
  73695. + }
  73696. +
  73697. + mvPexConfigWrite(pexIf, bus, dev, 0, RegOffs, pexCommandStatus);
  73698. +
  73699. + return MV_OK;
  73700. +
  73701. +}
  73702. +
  73703. +/*******************************************************************************
  73704. +* mvPexLocalBusNumSet - Set PEX interface local bus number.
  73705. +*
  73706. +* DESCRIPTION:
  73707. +* This function sets given PEX interface its local bus number.
  73708. +* Note: In case the PEX interface is PEX-X, the information is read-only.
  73709. +*
  73710. +* INPUT:
  73711. +* pexIf - PEX interface number.
  73712. +* busNum - Bus number.
  73713. +*
  73714. +* OUTPUT:
  73715. +* None.
  73716. +*
  73717. +* RETURN:
  73718. +* MV_NOT_ALLOWED in case PEX interface is PEX-X.
  73719. +* MV_BAD_PARAM on bad parameters ,
  73720. +* otherwise MV_OK
  73721. +*
  73722. +*******************************************************************************/
  73723. +MV_STATUS mvPexLocalBusNumSet(MV_U32 pexIf, MV_U32 busNum)
  73724. +{
  73725. + MV_U32 pexStatus;
  73726. + MV_U32 localBus;
  73727. + MV_U32 localDev;
  73728. +
  73729. +
  73730. + /* Parameter checking */
  73731. + if (pexIf >= mvCtrlPexMaxIfGet())
  73732. + {
  73733. + mvOsPrintf("mvPexLocalBusNumSet: ERR. Invalid PEX interface %d\n",pexIf);
  73734. + return MV_BAD_PARAM;
  73735. + }
  73736. + if (busNum >= MAX_PEX_BUSSES)
  73737. + {
  73738. + mvOsPrintf("mvPexLocalBusNumSet: ERR. bus number illigal %d\n", busNum);
  73739. + return MV_ERROR;
  73740. +
  73741. + }
  73742. +
  73743. + localBus = mvPexLocalBusNumGet(pexIf);
  73744. + localDev = mvPexLocalDevNumGet(pexIf);
  73745. +
  73746. +
  73747. +
  73748. + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
  73749. +
  73750. + pexStatus &= ~PXSR_PEX_BUS_NUM_MASK;
  73751. +
  73752. + pexStatus |= (busNum << PXSR_PEX_BUS_NUM_OFFS) & PXSR_PEX_BUS_NUM_MASK;
  73753. +
  73754. + MV_REG_WRITE(PEX_STATUS_REG(pexIf), pexStatus);
  73755. +
  73756. +
  73757. + return MV_OK;
  73758. +}
  73759. +
  73760. +
  73761. +/*******************************************************************************
  73762. +* mvPexLocalBusNumGet - Get PEX interface local bus number.
  73763. +*
  73764. +* DESCRIPTION:
  73765. +* This function gets the local bus number of a given PEX interface.
  73766. +*
  73767. +* INPUT:
  73768. +* pexIf - PEX interface number.
  73769. +*
  73770. +* OUTPUT:
  73771. +* None.
  73772. +*
  73773. +* RETURN:
  73774. +* Local bus number.0xffffffff on Error
  73775. +*
  73776. +*******************************************************************************/
  73777. +MV_U32 mvPexLocalBusNumGet(MV_U32 pexIf)
  73778. +{
  73779. + MV_U32 pexStatus;
  73780. +
  73781. + /* Parameter checking */
  73782. + if (PEX_DEFAULT_IF != pexIf)
  73783. + {
  73784. + if (pexIf >= mvCtrlPexMaxIfGet())
  73785. + {
  73786. + mvOsPrintf("mvPexLocalBusNumGet: ERR. Invalid PEX interface %d\n",pexIf);
  73787. + return 0xFFFFFFFF;
  73788. + }
  73789. + }
  73790. +
  73791. +
  73792. + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
  73793. +
  73794. + pexStatus &= PXSR_PEX_BUS_NUM_MASK;
  73795. +
  73796. + return (pexStatus >> PXSR_PEX_BUS_NUM_OFFS);
  73797. +
  73798. +}
  73799. +
  73800. +
  73801. +/*******************************************************************************
  73802. +* mvPexLocalDevNumSet - Set PEX interface local device number.
  73803. +*
  73804. +* DESCRIPTION:
  73805. +* This function sets given PEX interface its local device number.
  73806. +* Note: In case the PEX interface is PEX-X, the information is read-only.
  73807. +*
  73808. +* INPUT:
  73809. +* pexIf - PEX interface number.
  73810. +* devNum - Device number.
  73811. +*
  73812. +* OUTPUT:
  73813. +* None.
  73814. +*
  73815. +* RETURN:
  73816. +* MV_NOT_ALLOWED in case PEX interface is PEX-X.
  73817. +* MV_BAD_PARAM on bad parameters ,
  73818. +* otherwise MV_OK
  73819. +*
  73820. +*******************************************************************************/
  73821. +MV_STATUS mvPexLocalDevNumSet(MV_U32 pexIf, MV_U32 devNum)
  73822. +{
  73823. + MV_U32 pexStatus;
  73824. + MV_U32 localBus;
  73825. + MV_U32 localDev;
  73826. +
  73827. + /* Parameter checking */
  73828. + if (pexIf >= mvCtrlPexMaxIfGet())
  73829. + {
  73830. + mvOsPrintf("mvPexLocalDevNumSet: ERR. Invalid PEX interface %d\n",pexIf);
  73831. + return MV_BAD_PARAM;
  73832. + }
  73833. + if (devNum >= MAX_PEX_DEVICES)
  73834. + {
  73835. + mvOsPrintf("mvPexLocalDevNumSet: ERR. device number illigal %d\n",
  73836. + devNum);
  73837. + return MV_BAD_PARAM;
  73838. +
  73839. + }
  73840. +
  73841. + localBus = mvPexLocalBusNumGet(pexIf);
  73842. + localDev = mvPexLocalDevNumGet(pexIf);
  73843. +
  73844. +
  73845. + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
  73846. +
  73847. + pexStatus &= ~PXSR_PEX_DEV_NUM_MASK;
  73848. +
  73849. + pexStatus |= (devNum << PXSR_PEX_DEV_NUM_OFFS) & PXSR_PEX_DEV_NUM_MASK;
  73850. +
  73851. + MV_REG_WRITE(PEX_STATUS_REG(pexIf), pexStatus);
  73852. +
  73853. +
  73854. + return MV_OK;
  73855. +}
  73856. +
  73857. +/*******************************************************************************
  73858. +* mvPexLocalDevNumGet - Get PEX interface local device number.
  73859. +*
  73860. +* DESCRIPTION:
  73861. +* This function gets the local device number of a given PEX interface.
  73862. +*
  73863. +* INPUT:
  73864. +* pexIf - PEX interface number.
  73865. +*
  73866. +* OUTPUT:
  73867. +* None.
  73868. +*
  73869. +* RETURN:
  73870. +* Local device number. 0xffffffff on Error
  73871. +*
  73872. +*******************************************************************************/
  73873. +MV_U32 mvPexLocalDevNumGet(MV_U32 pexIf)
  73874. +{
  73875. + MV_U32 pexStatus;
  73876. +
  73877. + /* Parameter checking */
  73878. +
  73879. + if (PEX_DEFAULT_IF != pexIf)
  73880. + {
  73881. + if (pexIf >= mvCtrlPexMaxIfGet())
  73882. + {
  73883. + mvOsPrintf("mvPexLocalDevNumGet: ERR. Invalid PEX interface %d\n",
  73884. + pexIf);
  73885. + return 0xFFFFFFFF;
  73886. + }
  73887. + }
  73888. +
  73889. + pexStatus = MV_REG_READ(PEX_STATUS_REG(pexIf));
  73890. +
  73891. + pexStatus &= PXSR_PEX_DEV_NUM_MASK;
  73892. +
  73893. + return (pexStatus >> PXSR_PEX_DEV_NUM_OFFS);
  73894. +}
  73895. +
  73896. +MV_VOID mvPexPhyRegRead(MV_U32 pexIf, MV_U32 regOffset, MV_U16 *value)
  73897. +{
  73898. +
  73899. + MV_U32 regAddr;
  73900. + if (pexIf >= mvCtrlPexMaxIfGet())
  73901. + {
  73902. + mvOsPrintf("mvPexPhyRegRead: ERR. Invalid PEX interface %d\n", pexIf);
  73903. + return;
  73904. + }
  73905. + regAddr = (BIT31 | ((regOffset & 0x3fff) << 16));
  73906. + MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regAddr);
  73907. + *value = MV_REG_READ(PEX_PHY_ACCESS_REG(pexIf));
  73908. +}
  73909. +
  73910. +
  73911. +MV_VOID mvPexPhyRegWrite(MV_U32 pexIf, MV_U32 regOffset, MV_U16 value)
  73912. +{
  73913. +
  73914. + MV_U32 regAddr;
  73915. + if(pexIf >= mvCtrlPexMaxIfGet())
  73916. + {
  73917. + mvOsPrintf("mvPexPhyRegWrite: ERR. Invalid PEX interface %d\n", pexIf);
  73918. + return;
  73919. + }
  73920. + regAddr = (((regOffset & 0x3fff) << 16) | value);
  73921. + MV_REG_WRITE(PEX_PHY_ACCESS_REG(pexIf), regAddr);
  73922. +}
  73923. +
  73924. +/*******************************************************************************
  73925. +* mvPexActiveStateLinkPMEnable
  73926. +*
  73927. +* DESCRIPTION:
  73928. +* Enable Active Link State Power Management
  73929. +*
  73930. +* INPUT:
  73931. +* pexIf - PEX interface number.
  73932. +* enable - MV_TRUE to enable ASPM, MV_FALSE to disable.
  73933. +*
  73934. +* OUTPUT:
  73935. +* None
  73936. +*
  73937. +* RETURN:
  73938. +* MV_OK on success , MV_ERROR otherwise
  73939. +*
  73940. +*******************************************************************************/
  73941. +MV_STATUS mvPexActiveStateLinkPMEnable(MV_U32 pexIf, MV_BOOL enable)
  73942. +{
  73943. + MV_U32 reg;
  73944. +
  73945. + if(pexIf >= mvCtrlPexMaxIfGet())
  73946. + {
  73947. + mvOsPrintf("mvPexActiveStateLinkPMEnable: ERR. Invalid PEX interface %d\n", pexIf);
  73948. + return MV_ERROR;
  73949. + }
  73950. +
  73951. + reg = MV_REG_READ(PEX_PWR_MNG_EXT_REG(pexIf)) & ~PXPMER_L1_ASPM_EN_MASK;
  73952. + if(enable == MV_TRUE)
  73953. + reg |= PXPMER_L1_ASPM_EN_MASK;
  73954. + MV_REG_WRITE(PEX_PWR_MNG_EXT_REG(pexIf), reg);
  73955. +
  73956. + /* Enable / Disable L0/1 entry */
  73957. + reg = MV_REG_READ(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG))
  73958. + & ~PXLCSR_ASPM_CNT_MASK;
  73959. + if(enable == MV_TRUE)
  73960. + reg |= PXLCSR_ASPM_CNT_L0S_L1S_ENT_SUPP;
  73961. + MV_REG_WRITE(PEX_CFG_DIRECT_ACCESS(pexIf, PEX_LINK_CTRL_STAT_REG), reg);
  73962. +
  73963. + return MV_OK;
  73964. +}
  73965. +
  73966. +
  73967. +/*******************************************************************************
  73968. +* mvPexForceX1
  73969. +*
  73970. +* DESCRIPTION:
  73971. +* shut down lanes 1-3 if recognize that attached to an x1 end-point
  73972. +* INPUT:
  73973. +* pexIf - PEX interface number.
  73974. +*
  73975. +* OUTPUT:
  73976. +* None
  73977. +*
  73978. +* RETURN:
  73979. +* MV_OK on success , MV_ERROR otherwise
  73980. +*
  73981. +*******************************************************************************/
  73982. +MV_U32 mvPexForceX1(MV_U32 pexIf)
  73983. +{
  73984. + MV_U32 regData = 0;
  73985. + if(pexIf >= mvCtrlPexMaxIfGet())
  73986. + {
  73987. + mvOsPrintf("mvPexForceX1: ERR. Invalid PEX interface %d\n", pexIf);
  73988. + return MV_BAD_PARAM;
  73989. + }
  73990. +
  73991. + regData = MV_REG_READ(PEX_CTRL_REG(pexIf)) & ~(PXCR_CONF_LINK_MASK) ;
  73992. + regData |= PXCR_CONF_LINK_X1;
  73993. +
  73994. + MV_REG_WRITE(PEX_CTRL_REG(pexIf), regData);
  73995. + return MV_OK;
  73996. +}
  73997. +
  73998. +MV_BOOL mvPexIsPowerUp(MV_U32 pexIf)
  73999. +{
  74000. + if(pexIf >= mvCtrlPexMaxIfGet())
  74001. + {
  74002. + mvOsPrintf("mvPexIsPowerUp: ERR. Invalid PEX interface %d\n", pexIf);
  74003. + return MV_FALSE;
  74004. + }
  74005. + return mvCtrlPwrClckGet(PEX_UNIT_ID, pexIf);
  74006. +}
  74007. +
  74008. +
  74009. +MV_VOID mvPexPowerDown(MV_U32 pexIf)
  74010. +{
  74011. + if ( (mvCtrlModelGet() == MV_78XX0_DEV_ID) ||
  74012. + (mvCtrlModelGet() == MV_76100_DEV_ID) ||
  74013. + (mvCtrlModelGet() == MV_78100_DEV_ID) ||
  74014. + (mvCtrlModelGet() == MV_78200_DEV_ID) )
  74015. + {
  74016. + mvCtrlPwrClckSet(PEX_UNIT_ID, pexIf, MV_FALSE);
  74017. + }
  74018. + else
  74019. + {
  74020. + MV_REG_WRITE((0x41B00 -(pexIf)*0x10000), 0x20800087);
  74021. + }
  74022. +}
  74023. +
  74024. +
  74025. +
  74026. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h
  74027. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h 1970-01-01 01:00:00.000000000 +0100
  74028. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPex.h 2011-08-01 14:38:19.000000000 +0200
  74029. @@ -0,0 +1,168 @@
  74030. +/*******************************************************************************
  74031. +Copyright (C) Marvell International Ltd. and its affiliates
  74032. +
  74033. +This software file (the "File") is owned and distributed by Marvell
  74034. +International Ltd. and/or its affiliates ("Marvell") under the following
  74035. +alternative licensing terms. Once you have made an election to distribute the
  74036. +File under one of the following license alternatives, please (i) delete this
  74037. +introductory statement regarding license alternatives, (ii) delete the two
  74038. +license alternatives that you have not elected to use and (iii) preserve the
  74039. +Marvell copyright notice above.
  74040. +
  74041. +********************************************************************************
  74042. +Marvell Commercial License Option
  74043. +
  74044. +If you received this File from Marvell and you have entered into a commercial
  74045. +license agreement (a "Commercial License") with Marvell, the File is licensed
  74046. +to you under the terms of the applicable Commercial License.
  74047. +
  74048. +********************************************************************************
  74049. +Marvell GPL License Option
  74050. +
  74051. +If you received this File from Marvell, you may opt to use, redistribute and/or
  74052. +modify this File in accordance with the terms and conditions of the General
  74053. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  74054. +available along with the File in the license.txt file or by writing to the Free
  74055. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  74056. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  74057. +
  74058. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  74059. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  74060. +DISCLAIMED. The GPL License provides additional details about this warranty
  74061. +disclaimer.
  74062. +********************************************************************************
  74063. +Marvell BSD License Option
  74064. +
  74065. +If you received this File from Marvell, you may opt to use, redistribute and/or
  74066. +modify this File under the following licensing terms.
  74067. +Redistribution and use in source and binary forms, with or without modification,
  74068. +are permitted provided that the following conditions are met:
  74069. +
  74070. + * Redistributions of source code must retain the above copyright notice,
  74071. + this list of conditions and the following disclaimer.
  74072. +
  74073. + * Redistributions in binary form must reproduce the above copyright
  74074. + notice, this list of conditions and the following disclaimer in the
  74075. + documentation and/or other materials provided with the distribution.
  74076. +
  74077. + * Neither the name of Marvell nor the names of its contributors may be
  74078. + used to endorse or promote products derived from this software without
  74079. + specific prior written permission.
  74080. +
  74081. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  74082. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  74083. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  74084. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  74085. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  74086. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  74087. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  74088. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  74089. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  74090. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  74091. +
  74092. +*******************************************************************************/
  74093. +
  74094. +#ifndef __INCPEXH
  74095. +#define __INCPEXH
  74096. +
  74097. +#include "mvCommon.h"
  74098. +#include "mvOs.h"
  74099. +#include "pex/mvPexRegs.h"
  74100. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  74101. +
  74102. +
  74103. +
  74104. +/* NOTE not supported in this driver:*/
  74105. +
  74106. +
  74107. +/* defines */
  74108. +/* The number of supported PEX interfaces depend on Marvell controller */
  74109. +/* device number. This device number ID is located on the PEX unit */
  74110. +/* configuration header. This creates a loop where calling PEX */
  74111. +/* configuration read/write routine results a call to get PEX configuration */
  74112. +/* information etc. This macro defines a default PEX interface. This PEX */
  74113. +/* interface is sure to exist. */
  74114. +#define PEX_DEFAULT_IF 0
  74115. +
  74116. +
  74117. +/* typedefs */
  74118. +/* The Marvell controller supports both root complex and end point devices */
  74119. +/* This enumeration describes the PEX type. */
  74120. +typedef enum _mvPexType
  74121. +{
  74122. + MV_PEX_ROOT_COMPLEX, /* root complex device */
  74123. + MV_PEX_END_POINT /* end point device */
  74124. +}MV_PEX_TYPE;
  74125. +
  74126. +typedef enum _mvPexWidth
  74127. +{
  74128. + MV_PEX_WITDH_X1 = 1,
  74129. + MV_PEX_WITDH_X2,
  74130. + MV_PEX_WITDH_X3,
  74131. + MV_PEX_WITDH_X4,
  74132. + MV_PEX_WITDH_INVALID
  74133. +}MV_PEX_WIDTH;
  74134. +
  74135. +/* PEX Bar attributes */
  74136. +typedef struct _mvPexMode
  74137. +{
  74138. + MV_PEX_TYPE pexType;
  74139. + MV_PEX_WIDTH pexWidth;
  74140. + MV_BOOL pexLinkUp;
  74141. +}MV_PEX_MODE;
  74142. +
  74143. +
  74144. +
  74145. +/* Global Functions prototypes */
  74146. +/* mvPexInit - Initialize PEX interfaces*/
  74147. +MV_STATUS mvPexHalInit(MV_U32 pexIf, MV_PEX_TYPE pexType);
  74148. +
  74149. +/* mvPexModeGet - Get Pex If mode */
  74150. +MV_U32 mvPexModeGet(MV_U32 pexIf,MV_PEX_MODE *pexMode);
  74151. +
  74152. +/* mvPexConfigRead - Read from configuration space */
  74153. +MV_U32 mvPexConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  74154. + MV_U32 func,MV_U32 regOff);
  74155. +
  74156. +/* mvPexConfigWrite - Write to configuration space */
  74157. +MV_STATUS mvPexConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  74158. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  74159. +
  74160. +/* mvPexMasterEnable - Enable/disale PEX interface master transactions.*/
  74161. +MV_STATUS mvPexMasterEnable(MV_U32 pexIf, MV_BOOL enable);
  74162. +
  74163. +/* mvPexSlaveEnable - Enable/disale PEX interface slave transactions.*/
  74164. +MV_STATUS mvPexSlaveEnable(MV_U32 pexIf, MV_U32 bus,MV_U32 dev, MV_BOOL enable);
  74165. +
  74166. +/* mvPexLocalBusNumSet - Set PEX interface local bus number.*/
  74167. +MV_STATUS mvPexLocalBusNumSet(MV_U32 pexIf, MV_U32 busNum);
  74168. +
  74169. +/* mvPexLocalBusNumGet - Get PEX interface local bus number.*/
  74170. +MV_U32 mvPexLocalBusNumGet(MV_U32 pexIf);
  74171. +
  74172. +/* mvPexLocalDevNumSet - Set PEX interface local device number.*/
  74173. +MV_STATUS mvPexLocalDevNumSet(MV_U32 pexIf, MV_U32 devNum);
  74174. +
  74175. +/* mvPexLocalDevNumGet - Get PEX interface local device number.*/
  74176. +MV_U32 mvPexLocalDevNumGet(MV_U32 pexIf);
  74177. +/* mvPexForceX1 - Force PEX interface to X1 mode. */
  74178. +MV_U32 mvPexForceX1(MV_U32 pexIf);
  74179. +
  74180. +/* mvPexIsPowerUp - Is PEX interface Power up? */
  74181. +MV_BOOL mvPexIsPowerUp(MV_U32 pexIf);
  74182. +
  74183. +/* mvPexPowerDown - Power Down */
  74184. +MV_VOID mvPexPowerDown(MV_U32 pexIf);
  74185. +
  74186. +/* mvPexPowerUp - Power Up */
  74187. +MV_VOID mvPexPowerUp(MV_U32 pexIf);
  74188. +
  74189. +/* mvPexPhyRegRead - Pex phy read */
  74190. +MV_VOID mvPexPhyRegRead(MV_U32 pexIf, MV_U32 regOffset, MV_U16 *value);
  74191. +
  74192. +/* mvPexPhyRegWrite - Pex phy write */
  74193. +MV_VOID mvPexPhyRegWrite(MV_U32 pexIf, MV_U32 regOffset, MV_U16 value);
  74194. +
  74195. +MV_STATUS mvPexActiveStateLinkPMEnable(MV_U32 pexIf, MV_BOOL enable);
  74196. +
  74197. +#endif /* #ifndef __INCPEXH */
  74198. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h
  74199. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h 1970-01-01 01:00:00.000000000 +0100
  74200. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvPexRegs.h 2011-08-01 14:38:19.000000000 +0200
  74201. @@ -0,0 +1,751 @@
  74202. +/*******************************************************************************
  74203. +Copyright (C) Marvell International Ltd. and its affiliates
  74204. +
  74205. +This software file (the "File") is owned and distributed by Marvell
  74206. +International Ltd. and/or its affiliates ("Marvell") under the following
  74207. +alternative licensing terms. Once you have made an election to distribute the
  74208. +File under one of the following license alternatives, please (i) delete this
  74209. +introductory statement regarding license alternatives, (ii) delete the two
  74210. +license alternatives that you have not elected to use and (iii) preserve the
  74211. +Marvell copyright notice above.
  74212. +
  74213. +********************************************************************************
  74214. +Marvell Commercial License Option
  74215. +
  74216. +If you received this File from Marvell and you have entered into a commercial
  74217. +license agreement (a "Commercial License") with Marvell, the File is licensed
  74218. +to you under the terms of the applicable Commercial License.
  74219. +
  74220. +********************************************************************************
  74221. +Marvell GPL License Option
  74222. +
  74223. +If you received this File from Marvell, you may opt to use, redistribute and/or
  74224. +modify this File in accordance with the terms and conditions of the General
  74225. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  74226. +available along with the File in the license.txt file or by writing to the Free
  74227. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  74228. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  74229. +
  74230. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  74231. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  74232. +DISCLAIMED. The GPL License provides additional details about this warranty
  74233. +disclaimer.
  74234. +********************************************************************************
  74235. +Marvell BSD License Option
  74236. +
  74237. +If you received this File from Marvell, you may opt to use, redistribute and/or
  74238. +modify this File under the following licensing terms.
  74239. +Redistribution and use in source and binary forms, with or without modification,
  74240. +are permitted provided that the following conditions are met:
  74241. +
  74242. + * Redistributions of source code must retain the above copyright notice,
  74243. + this list of conditions and the following disclaimer.
  74244. +
  74245. + * Redistributions in binary form must reproduce the above copyright
  74246. + notice, this list of conditions and the following disclaimer in the
  74247. + documentation and/or other materials provided with the distribution.
  74248. +
  74249. + * Neither the name of Marvell nor the names of its contributors may be
  74250. + used to endorse or promote products derived from this software without
  74251. + specific prior written permission.
  74252. +
  74253. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  74254. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  74255. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  74256. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  74257. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  74258. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  74259. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  74260. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  74261. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  74262. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  74263. +
  74264. +*******************************************************************************/
  74265. +
  74266. +#ifndef __INCPEXREGSH
  74267. +#define __INCPEXREGSH
  74268. +
  74269. +#ifdef __cplusplus
  74270. +extern "C" {
  74271. +#endif /* __cplusplus */
  74272. +
  74273. +/* defines */
  74274. +#define MAX_PEX_DEVICES 32
  74275. +#define MAX_PEX_FUNCS 8
  74276. +#define MAX_PEX_BUSSES 256
  74277. +
  74278. +
  74279. +
  74280. +/*********************************************************/
  74281. +/* PCI Express Configuration Cycles Generation Registers */
  74282. +/*********************************************************/
  74283. +
  74284. +#define PEX_CFG_ADDR_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x18F8)
  74285. +#define PEX_CFG_DATA_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x18FC)
  74286. +#define PEX_PHY_ACCESS_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1B00)
  74287. +/* PCI Express Configuration Address Register */
  74288. +/* PEX_CFG_ADDR_REG (PXCAR)*/
  74289. +
  74290. +#define PXCAR_REG_NUM_OFFS 2
  74291. +#define PXCAR_REG_NUM_MAX 0x3F
  74292. +#define PXCAR_REG_NUM_MASK (PXCAR_REG_NUM_MAX << PXCAR_REG_NUM_OFFS)
  74293. +#define PXCAR_FUNC_NUM_OFFS 8
  74294. +#define PXCAR_FUNC_NUM_MAX 0x7
  74295. +#define PXCAR_FUNC_NUM_MASK (PXCAR_FUNC_NUM_MAX << PXCAR_FUNC_NUM_OFFS)
  74296. +#define PXCAR_DEVICE_NUM_OFFS 11
  74297. +#define PXCAR_DEVICE_NUM_MAX 0x1F
  74298. +#define PXCAR_DEVICE_NUM_MASK (PXCAR_DEVICE_NUM_MAX << PXCAR_DEVICE_NUM_OFFS)
  74299. +#define PXCAR_BUS_NUM_OFFS 16
  74300. +#define PXCAR_BUS_NUM_MAX 0xFF
  74301. +#define PXCAR_BUS_NUM_MASK (PXCAR_BUS_NUM_MAX << PXCAR_BUS_NUM_OFFS)
  74302. +#define PXCAR_EXT_REG_NUM_OFFS 24
  74303. +#define PXCAR_EXT_REG_NUM_MAX 0xF
  74304. +
  74305. +/* in pci express register address is now the legacy register address (8 bits)
  74306. +with the new extended register address (more 4 bits) , below is the mask of
  74307. +the upper 4 bits of the full register address */
  74308. +
  74309. +#define PXCAR_REAL_EXT_REG_NUM_OFFS 8
  74310. +#define PXCAR_EXT_REG_NUM_MASK (PXCAR_EXT_REG_NUM_MAX << PXCAR_EXT_REG_NUM_OFFS)
  74311. +#define PXCAR_CONFIG_EN BIT31
  74312. +
  74313. +#define PXCAR_REAL_EXT_REG_NUM_OFFS 8
  74314. +#define PXCAR_REAL_EXT_REG_NUM_MASK (0xF << PXCAR_REAL_EXT_REG_NUM_OFFS)
  74315. +
  74316. +/* The traditional PCI spec defined 6-bit field to describe register offset.*/
  74317. +/* The new PCI Express extend the register offset by an extra 4-bits. */
  74318. +/* The below macro assign 10-bit register offset into the apprpreate */
  74319. +/* fields in the CFG_ADDR_REG */
  74320. +#define PXCAR_REG_OFFS_SET(regOffs) \
  74321. + ( (regOff & PXCAR_REG_NUM_MASK) | \
  74322. + ( ((regOff & PXCAR_REAL_EXT_REG_NUM_MASK) >> PXCAR_REAL_EXT_REG_NUM_OFFS) << PXCAR_EXT_REG_NUM_OFFS) )
  74323. +
  74324. +/***********************************/
  74325. +/* PCI Express Interrupt registers */
  74326. +/***********************************/
  74327. +#define PEX_CAUSE_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1900)
  74328. +#define PEX_MASK_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1910)
  74329. +
  74330. +#define PXICR_TX_REQ_IN_DLDOWN_ERR BIT0 /* Transmit request while field */
  74331. + /* <DLDown> of the PCI Express */
  74332. +/* PCI Express Interrupt Cause */
  74333. +/* PEX_INT_CAUSE_REG (PXICR)*/
  74334. +/* PEX_INT_MASK_REG*/
  74335. +/*
  74336. +NOTE:All bits except bits[27:24] are Read/Write Clear only. A cause bit sets
  74337. +upon an error event occurrence. A write of 0 clears the bit. A write of 1 has
  74338. +no affect. Bits[24:27} are set and cleared upon reception of interrupt
  74339. +emulation messages.
  74340. +
  74341. +Mask bit per cause bit. If a bit is set to 1, the corresponding event is
  74342. +enabled. Mask does not affect setting of the Interrupt Cause register bits;
  74343. +it only affects the assertion of the interrupt .*/
  74344. +
  74345. +
  74346. +#define PXICR_MDIS_CAUSE BIT1 /* Attempt to generate PCI transaction
  74347. + while master is disabled */
  74348. +#define PXICR_ERR_WRTO_REG_CAUSE BIT3 /* Erroneous write attempt to
  74349. + PCI Express internal register*/
  74350. +#define PXICR_HIT_DFLT_WIN_ERR BIT4 /* Hit Default Window Error */
  74351. +#define PXICR_RX_RAM_PAR_ERR BIT6 /* Rx RAM Parity Error */
  74352. +#define PXICR_TX_RAM_PAR_ERR BIT7 /* Tx RAM Parity Error */
  74353. +#define PXICR_COR_ERR_DET BIT8 /* Correctable Error Detected*/
  74354. +#define PXICR_NF_ERR_DET BIT9 /* Non-Fatal Error Detected*/
  74355. +#define PXICR_FERR_DET BIT10 /* Fatal Error Detected*/
  74356. +#define PXICR_DSTATE_CHANGE BIT11 /* Dstate Change Indication*/
  74357. +#define PXICR_BIST BIT12 /* PCI-Express BIST activated*/
  74358. +#define PXICR_FLW_CTRL_PROT BIT14 /* Flow Control Protocol Error */
  74359. +
  74360. +#define PXICR_RCV_UR_CA_ERR BIT15 /* Received UR or CA status. */
  74361. +#define PXICR_RCV_ERR_FATAL BIT16 /* Received ERR_FATAL message.*/
  74362. +#define PXICR_RCV_ERR_NON_FATAL BIT17 /* Received ERR_NONFATAL message*/
  74363. +#define PXICR_RCV_ERR_COR BIT18 /* Received ERR_COR message.*/
  74364. +#define PXICR_RCV_CRS BIT19 /* Received CRS completion status*/
  74365. +#define PXICR_SLV_HOT_RESET BIT20 /* Received Hot Reset Indication*/
  74366. +#define PXICR_SLV_DIS_LINK BIT21 /* Slave Disable Link Indication*/
  74367. +#define PXICR_SLV_LB BIT22 /* Slave Loopback Indication*/
  74368. +#define PXICR_LINK_FAIL BIT23 /* Link Failure indication.*/
  74369. +#define PXICR_RCV_INTA BIT24 /* IntA status.*/
  74370. +#define PXICR_RCV_INTB BIT25 /* IntB status.*/
  74371. +#define PXICR_RCV_INTC BIT26 /* IntC status.*/
  74372. +#define PXICR_RCV_INTD BIT27 /* IntD status.*/
  74373. +#define PXICR_RCV_PM_PME BIT28 /* Received PM_PME message. */
  74374. +
  74375. +
  74376. +/********************************************/
  74377. +/* PCI Express Control and Status Registers */
  74378. +/********************************************/
  74379. +#define PEX_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A00)
  74380. +#define PEX_STATUS_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A04)
  74381. +#define PEX_COMPLT_TMEOUT_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A10)
  74382. +#define PEX_PWR_MNG_EXT_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A18)
  74383. +#define PEX_FLOW_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A20)
  74384. +#define PEX_ACK_TMR_4X_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A30)
  74385. +#define PEX_ACK_TMR_1X_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A40)
  74386. +#define PEX_TL_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1AB0)
  74387. +
  74388. +
  74389. +#define PEX_RAM_PARITY_CTRL_REG(pexIf) ((PEX_IF_BASE(pexIf)) + 0x1A50)
  74390. +/* PCI Express Control Register */
  74391. +/* PEX_CTRL_REG (PXCR) */
  74392. +
  74393. +#define PXCR_CONF_LINK_OFFS 0
  74394. +#define PXCR_CONF_LINK_MASK (1 << PXCR_CONF_LINK_OFFS)
  74395. +#define PXCR_CONF_LINK_X4 (0 << PXCR_CONF_LINK_OFFS)
  74396. +#define PXCR_CONF_LINK_X1 (1 << PXCR_CONF_LINK_OFFS)
  74397. +#define PXCR_DEV_TYPE_CTRL_OFFS 1 /*PCI ExpressDevice Type Control*/
  74398. +#define PXCR_DEV_TYPE_CTRL_MASK BIT1
  74399. +#define PXCR_DEV_TYPE_CTRL_CMPLX (1 << PXCR_DEV_TYPE_CTRL_OFFS)
  74400. +#define PXCR_DEV_TYPE_CTRL_POINT (0 << PXCR_DEV_TYPE_CTRL_OFFS)
  74401. +#define PXCR_CFG_MAP_TO_MEM_EN BIT2 /* Configuration Header Mapping
  74402. + to Memory Space Enable */
  74403. +
  74404. +#define PXCR_CFG_MAP_TO_MEM_EN BIT2 /* Configuration Header Mapping
  74405. + to Memory Space Enable*/
  74406. +
  74407. +#define PXCR_RSRV1_OFFS 5
  74408. +#define PXCR_RSRV1_MASK (0x7 << PXCR_RSRV1_OFFS)
  74409. +#define PXCR_RSRV1_VAL (0x0 << PXCR_RSRV1_OFFS)
  74410. +
  74411. +#define PXCR_CONF_MAX_OUTSTND_OFFS 8 /*Maximum outstanding NP requests as a master*/
  74412. +#define PXCR_CONF_MAX_OUTSTND_MASK (0x3 << PXCR_CONF_MAX_OUTSTND_OFFS)
  74413. +
  74414. +
  74415. +#define PXCR_CONF_NFTS_OFFS 16 /*number of FTS Ordered-Sets*/
  74416. +#define PXCR_CONF_NFTS_MASK (0xff << PXCR_CONF_NFTS_OFFS)
  74417. +
  74418. +#define PXCR_CONF_MSTR_HOT_RESET BIT24 /*Master Hot-Reset.*/
  74419. +#define PXCR_CONF_MSTR_LB BIT26 /* Master Loopback */
  74420. +#define PXCR_CONF_MSTR_DIS_SCRMB BIT27 /* Master Disable Scrambling*/
  74421. +#define PXCR_CONF_DIRECT_DIS_SCRMB BIT28 /* Direct Disable Scrambling*/
  74422. +
  74423. +/* PCI Express Status Register */
  74424. +/* PEX_STATUS_REG (PXSR) */
  74425. +
  74426. +#define PXSR_DL_DOWN BIT0 /* DL_Down indication.*/
  74427. +
  74428. +#define PXSR_PEX_BUS_NUM_OFFS 8 /* Bus Number Indication */
  74429. +#define PXSR_PEX_BUS_NUM_MASK (0xff << PXSR_PEX_BUS_NUM_OFFS)
  74430. +
  74431. +#define PXSR_PEX_DEV_NUM_OFFS 16 /* Device Number Indication */
  74432. +#define PXSR_PEX_DEV_NUM_MASK (0x1f << PXSR_PEX_DEV_NUM_OFFS)
  74433. +
  74434. +#define PXSR_PEX_SLV_HOT_RESET BIT24 /* Slave Hot Reset Indication*/
  74435. +#define PXSR_PEX_SLV_DIS_LINK BIT25 /* Slave Disable Link Indication*/
  74436. +#define PXSR_PEX_SLV_LB BIT26 /* Slave Loopback Indication*/
  74437. +#define PXSR_PEX_SLV_DIS_SCRMB BIT27 /* Slave Disable Scrambling Indication*/
  74438. +
  74439. +
  74440. +/* PCI Express Completion Timeout Register */
  74441. +/* PEX_COMPLT_TMEOUT_REG (PXCTR)*/
  74442. +
  74443. +#define PXCTR_CMP_TO_THRSHLD_OFFS 0 /* Completion Timeout Threshold */
  74444. +#define PXCTR_CMP_TO_THRSHLD_MASK (0xffff << PXCTR_CMP_TO_THRSHLD_OFFS)
  74445. +
  74446. +/* PCI Express Power Management Extended Register */
  74447. +/* PEX_PWR_MNG_EXT_REG (PXPMER) */
  74448. +
  74449. +#define PXPMER_L1_ASPM_EN_OFFS 1
  74450. +#define PXPMER_L1_ASPM_EN_MASK (0x1 << PXPMER_L1_ASPM_EN_OFFS)
  74451. +
  74452. +/* PCI Express Flow Control Register */
  74453. +/* PEX_FLOW_CTRL_REG (PXFCR)*/
  74454. +
  74455. +#define PXFCR_PH_INIT_FC_OFFS 0 /*Posted Headers Flow Control Credit
  74456. + Initial Value.*/
  74457. +#define PXFCR_PH_INIT_FC_MASK (0xff << PXFCR_PH_INIT_FC_OFFS)
  74458. +
  74459. +
  74460. +#define PXFCR_NPH_INIT_FC_OFFS 8 /* Classified Non-Posted Headers
  74461. + Flow Control Credit Initial Value*/
  74462. +#define PXFCR_NPH_INIT_FC_MASK (0xff << PXFCR_NPH_INIT_FC_OFFS)
  74463. +
  74464. +#define PXFCR_CH_INIT_FC_OFFS 16 /* Completion Headers Flow Control
  74465. + Credit Initial Value Infinite*/
  74466. +
  74467. +#define PXFCR_CH_INIT_FC_MASK (0xff << PXFCR_CH_INIT_FC_OFFS)
  74468. +
  74469. +#define PXFCR_FC_UPDATE_TO_OFFS 24 /* Flow Control Update Timeout */
  74470. +#define PXFCR_FC_UPDATE_TO_MASK (0xff << PXFCR_FC_UPDATE_TO_OFFS)
  74471. +
  74472. +/* PCI Express Acknowledge Timers (4X) Register */
  74473. +/* PEX_ACK_TMR_4X_REG (PXAT4R) */
  74474. +#define PXAT1R_ACK_LAT_TOX4_OFFS 0 /* Ack Latency Timer Timeout Value */
  74475. +#define PXAT1R_ACK_LAT_TOX4_MASK (0xffff << PXAT4R_ACK_LAT_TOX1_OFFS)
  74476. +#define PXAT1R_ACK_RPLY_TOX4_OFFS 16 /* Ack Replay Timer Timeout Value */
  74477. +#define PXAT1R_ACK_RPLY_TOX4_MASK (0xffff << PXAT1R_ACK_RPLY_TOX1_OFFS)
  74478. +
  74479. +/* PCI Express Acknowledge Timers (1X) Register */
  74480. +/* PEX_ACK_TMR_1X_REG (PXAT1R) */
  74481. +
  74482. +#define PXAT1R_ACK_LAT_TOX1_OFFS 0 /* Acknowledge Latency Timer Timeout
  74483. + Value for 1X Link*/
  74484. +#define PXAT1R_ACK_LAT_TOX1_MASK (0xffff << PXAT1R_ACK_LAT_TOX1_OFFS)
  74485. +
  74486. +#define PXAT1R_ACK_RPLY_TOX1_OFFS 16 /* Acknowledge Replay Timer Timeout
  74487. + Value for 1X*/
  74488. +#define PXAT1R_ACK_RPLY_TOX1_MASK (0xffff << PXAT1R_ACK_RPLY_TOX1_OFFS)
  74489. +
  74490. +
  74491. +/* PCI Express TL Control Register */
  74492. +/* PEX_TL_CTRL_REG (PXTCR) */
  74493. +
  74494. +#define PXTCR_TX_CMP_BUFF_NO_OFFS 8 /*Number of completion buffers in Tx*/
  74495. +#define PXTCR_TX_CMP_BUFF_NO_MASK (0xf << PXTCR_TX_CMP_BUFF_NO_OFFS)
  74496. +
  74497. +/* PCI Express Debug MAC Control Register */
  74498. +/* PEX_DEBUG_MAC_CTRL_REG (PXDMCR) */
  74499. +
  74500. +#define PXDMCR_LINKUP BIT4
  74501. +
  74502. +
  74503. +
  74504. +/**********************************************/
  74505. +/* PCI Express Configuration Header Registers */
  74506. +/**********************************************/
  74507. +#define PEX_CFG_DIRECT_ACCESS(pexIf,cfgReg) ((PEX_IF_BASE(pexIf)) + (cfgReg))
  74508. +
  74509. +#define PEX_DEVICE_AND_VENDOR_ID 0x000
  74510. +#define PEX_STATUS_AND_COMMAND 0x004
  74511. +#define PEX_CLASS_CODE_AND_REVISION_ID 0x008
  74512. +#define PEX_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE 0x00C
  74513. +#define PEX_MEMORY_BAR_BASE_ADDR(barNum) (0x010 + ((barNum) << 2))
  74514. +#define PEX_MV_BAR_BASE(barNum) (0x010 + (barNum) * 8)
  74515. +#define PEX_MV_BAR_BASE_HIGH(barNum) (0x014 + (barNum) * 8)
  74516. +#define PEX_BAR0_INTER_REG 0x010
  74517. +#define PEX_BAR0_INTER_REG_HIGH 0x014
  74518. +#define PEX_BAR1_REG 0x018
  74519. +#define PEX_BAR1_REG_HIGH 0x01C
  74520. +#define PEX_BAR2_REG 0x020
  74521. +#define PEX_BAR2_REG_HIGH 0x024
  74522. +
  74523. +#define PEX_SUBSYS_ID_AND_SUBSYS_VENDOR_ID 0x02C
  74524. +#define PEX_EXPANSION_ROM_BASE_ADDR_REG 0x030
  74525. +#define PEX_CAPABILTY_LIST_POINTER 0x034
  74526. +#define PEX_INTERRUPT_PIN_AND_LINE 0x03C
  74527. +
  74528. +/* capability list */
  74529. +#define PEX_POWER_MNG_CAPABILITY 0x040
  74530. +#define PEX_POWER_MNG_STATUS_CONTROL 0x044
  74531. +
  74532. +#define PEX_MSI_MESSAGE_CONTROL 0x050
  74533. +#define PEX_MSI_MESSAGE_ADDR 0x054
  74534. +#define PEX_MSI_MESSAGE_HIGH_ADDR 0x058
  74535. +#define PEX_MSI_MESSAGE_DATA 0x05C
  74536. +
  74537. +#define PEX_CAPABILITY_REG 0x60
  74538. +#define PEX_DEV_CAPABILITY_REG 0x64
  74539. +#define PEX_DEV_CTRL_STAT_REG 0x68
  74540. +#define PEX_LINK_CAPABILITY_REG 0x6C
  74541. +#define PEX_LINK_CTRL_STAT_REG 0x70
  74542. +
  74543. +#define PEX_ADV_ERR_RPRT_HDR_TRGT_REG 0x100
  74544. +#define PEX_UNCORRECT_ERR_STAT_REG 0x104
  74545. +#define PEX_UNCORRECT_ERR_MASK_REG 0x108
  74546. +#define PEX_UNCORRECT_ERR_SERVITY_REG 0x10C
  74547. +#define PEX_CORRECT_ERR_STAT_REG 0x110
  74548. +#define PEX_CORRECT_ERR_MASK_REG 0x114
  74549. +#define PEX_ADV_ERR_CAPABILITY_CTRL_REG 0x118
  74550. +#define PEX_HDR_LOG_FIRST_DWORD_REG 0x11C
  74551. +#define PEX_HDR_LOG_SECOND_DWORD_REG 0x120
  74552. +#define PEX_HDR_LOG_THIRD_DWORD_REG 0x124
  74553. +#define PEX_HDR_LOG_FOURTH_DWORD_REG 0x128
  74554. +
  74555. +
  74556. +
  74557. +/* PCI Express Device and Vendor ID Register*/
  74558. +/*PEX_DEVICE_AND_VENDOR_ID (PXDAVI)*/
  74559. +
  74560. +#define PXDAVI_VEN_ID_OFFS 0 /* Vendor ID */
  74561. +#define PXDAVI_VEN_ID_MASK (0xffff << PXDAVI_VEN_ID_OFFS)
  74562. +
  74563. +#define PXDAVI_DEV_ID_OFFS 16 /* Device ID */
  74564. +#define PXDAVI_DEV_ID_MASK (0xffff << PXDAVI_DEV_ID_OFFS)
  74565. +
  74566. +
  74567. +/* PCI Express Command and Status Register*/
  74568. +/*PEX_STATUS_AND_COMMAND (PXSAC)*/
  74569. +
  74570. +#define PXSAC_IO_EN BIT0 /* IO Enable */
  74571. +#define PXSAC_MEM_EN BIT1 /* Memory Enable */
  74572. +#define PXSAC_MASTER_EN BIT2 /* Master Enable */
  74573. +#define PXSAC_PERR_EN BIT6 /* Parity Errors Respond Enable */
  74574. +#define PXSAC_SERR_EN BIT8 /* Ability to assert SERR# line */
  74575. +#define PXSAC_INT_DIS BIT10 /* Interrupt Disable */
  74576. +#define PXSAC_INT_STAT BIT19 /* Interrupt Status */
  74577. +#define PXSAC_CAP_LIST BIT20 /* Capability List Support */
  74578. +#define PXSAC_MAS_DATA_PERR BIT24 /* Master Data Parity Error */
  74579. +#define PXSAC_SLAVE_TABORT BIT27 /* Signalled Target Abort */
  74580. +#define PXSAC_RT_ABORT BIT28 /* Recieved Target Abort */
  74581. +#define PXSAC_MABORT BIT29 /* Recieved Master Abort */
  74582. +#define PXSAC_SYSERR BIT30 /* Signalled system error */
  74583. +#define PXSAC_DET_PARERR BIT31 /* Detect Parity Error */
  74584. +
  74585. +
  74586. +/* PCI Express Class Code and Revision ID Register*/
  74587. +/*PEX_CLASS_CODE_AND_REVISION_ID (PXCCARI)*/
  74588. +
  74589. +#define PXCCARI_REVID_OFFS 0 /* Revision ID */
  74590. +#define PXCCARI_REVID_MASK (0xff << PXCCARI_REVID_OFFS)
  74591. +
  74592. +#define PXCCARI_FULL_CLASS_OFFS 8 /* Full Class Code */
  74593. +#define PXCCARI_FULL_CLASS_MASK (0xffffff << PXCCARI_FULL_CLASS_OFFS)
  74594. +
  74595. +#define PXCCARI_PROGIF_OFFS 8 /* Prog .I/F*/
  74596. +#define PXCCARI_PROGIF_MASK (0xff << PXCCARI_PROGIF_OFFS)
  74597. +
  74598. +#define PXCCARI_SUB_CLASS_OFFS 16 /* Sub Class*/
  74599. +#define PXCCARI_SUB_CLASS_MASK (0xff << PXCCARI_SUB_CLASS_OFFS)
  74600. +
  74601. +#define PXCCARI_BASE_CLASS_OFFS 24 /* Base Class*/
  74602. +#define PXCCARI_BASE_CLASS_MASK (0xff << PXCCARI_BASE_CLASS_OFFS)
  74603. +
  74604. +
  74605. +/* PCI Express BIST, Header Type and Cache Line Size Register*/
  74606. +/*PEX_BIST_HDR_TYPE_LAT_TMR_CACHE_LINE (PXBHTLTCL)*/
  74607. +
  74608. +#define PXBHTLTCL_CACHELINE_OFFS 0 /* Specifies the cache line size */
  74609. +#define PXBHTLTCL_CACHELINE_MASK (0xff << PXBHTLTCL_CACHELINE_OFFS)
  74610. +
  74611. +#define PXBHTLTCL_HEADTYPE_FULL_OFFS 16 /* Full Header Type */
  74612. +#define PXBHTLTCL_HEADTYPE_FULL_MASK (0xff << PXBHTLTCL_HEADTYPE_FULL_OFFS)
  74613. +
  74614. +#define PXBHTLTCL_MULTI_FUNC BIT23 /* Multi/Single function */
  74615. +
  74616. +#define PXBHTLTCL_HEADER_OFFS 16 /* Header type */
  74617. +#define PXBHTLTCL_HEADER_MASK (0x7f << PXBHTLTCL_HEADER_OFFS)
  74618. +#define PXBHTLTCL_HEADER_STANDARD (0x0 << PXBHTLTCL_HEADER_OFFS)
  74619. +#define PXBHTLTCL_HEADER_PCI2PCI_BRIDGE (0x1 << PXBHTLTCL_HEADER_OFFS)
  74620. +
  74621. +
  74622. +#define PXBHTLTCL_BISTCOMP_OFFS 24 /* BIST Completion Code */
  74623. +#define PXBHTLTCL_BISTCOMP_MASK (0xf << PXBHTLTCL_BISTCOMP_OFFS)
  74624. +
  74625. +#define PXBHTLTCL_BISTACT BIT30 /* BIST Activate bit */
  74626. +#define PXBHTLTCL_BISTCAP BIT31 /* BIST Capable Bit */
  74627. +#define PXBHTLTCL_BISTCAP_OFFS 31
  74628. +#define PXBHTLTCL_BISTCAP_MASK BIT31
  74629. +#define PXBHTLTCL_BISTCAP_VAL 0
  74630. +
  74631. +
  74632. +/* PCI Express Subsystem Device and Vendor ID */
  74633. +/*PEX_SUBSYS_ID_AND_SUBSYS_VENDOR_ID (PXSIASVI)*/
  74634. +
  74635. +#define PXSIASVI_VENID_OFFS 0 /* Subsystem Manufacturer Vendor ID Number */
  74636. +#define PXSIASVI_VENID_MASK (0xffff << PXSIASVI_VENID_OFFS)
  74637. +
  74638. +#define PXSIASVI_DEVID_OFFS 16 /* Subsystem Device ID Number */
  74639. +#define PXSIASVI_DEVID_MASK (0xffff << PXSIASVI_DEVID_OFFS)
  74640. +
  74641. +
  74642. +/* PCI Express Capability List Pointer Register*/
  74643. +/*PEX_CAPABILTY_LIST_POINTER (PXCLP)*/
  74644. +
  74645. +#define PXCLP_CAPPTR_OFFS 0 /* Capability List Pointer */
  74646. +#define PXCLP_CAPPTR_MASK (0xff << PXCLP_CAPPTR_OFFS)
  74647. +
  74648. +/* PCI Express Interrupt Pin and Line Register */
  74649. +/*PEX_INTERRUPT_PIN_AND_LINE (PXIPAL)*/
  74650. +
  74651. +#define PXIPAL_INTLINE_OFFS 0 /* Interrupt line (IRQ) */
  74652. +#define PXIPAL_INTLINE_MASK (0xff << PXIPAL_INTLINE_OFFS)
  74653. +
  74654. +#define PXIPAL_INTPIN_OFFS 8 /* interrupt pin (A,B,C,D) */
  74655. +#define PXIPAL_INTPIN_MASK (0xff << PXIPAL_INTPIN_OFFS)
  74656. +
  74657. +
  74658. +/* PCI Express Power Management Capability Header Register*/
  74659. +/*PEX_POWER_MNG_CAPABILITY (PXPMC)*/
  74660. +
  74661. +#define PXPMC_CAP_ID_OFFS 0 /* Capability ID */
  74662. +#define PXPMC_CAP_ID_MASK (0xff << PXPMC_CAP_ID_OFFS)
  74663. +
  74664. +#define PXPMC_NEXT_PTR_OFFS 8 /* Next Item Pointer */
  74665. +#define PXPMC_NEXT_PTR_MASK (0xff << PXPMC_NEXT_PTR_OFFS)
  74666. +
  74667. +#define PXPMC_PMC_VER_OFFS 16 /* PCI Power Management Capability Version*/
  74668. +#define PXPMC_PMC_VER_MASK (0x7 << PXPMC_PMC_VER_OFFS)
  74669. +
  74670. +#define PXPMC_DSI BIT21/* Device Specific Initialization */
  74671. +
  74672. +#define PXPMC_AUX_CUR_OFFS 22 /* Auxiliary Current Requirements */
  74673. +#define PXPMC_AUX_CUR_MASK (0x7 << PXPMC_AUX_CUR_OFFS)
  74674. +
  74675. +#define PXPMC_D1_SUP BIT25 /* D1 Power Management support*/
  74676. +
  74677. +#define PXPMC_D2_SUP BIT26 /* D2 Power Management support*/
  74678. +
  74679. +#define PXPMC_PME_SUP_OFFS 27 /* PM Event generation support*/
  74680. +#define PXPMC_PME_SUP_MASK (0x1f << PXPMC_PME_SUP_OFFS)
  74681. +
  74682. +/* PCI Express Power Management Control and Status Register*/
  74683. +/*PEX_POWER_MNG_STATUS_CONTROL (PXPMSC)*/
  74684. +
  74685. +#define PXPMSC_PM_STATE_OFFS 0 /* Power State */
  74686. +#define PXPMSC_PM_STATE_MASK (0x3 << PXPMSC_PM_STATE_OFFS)
  74687. +#define PXPMSC_PM_STATE_D0 (0x0 << PXPMSC_PM_STATE_OFFS)
  74688. +#define PXPMSC_PM_STATE_D1 (0x1 << PXPMSC_PM_STATE_OFFS)
  74689. +#define PXPMSC_PM_STATE_D2 (0x2 << PXPMSC_PM_STATE_OFFS)
  74690. +#define PXPMSC_PM_STATE_D3 (0x3 << PXPMSC_PM_STATE_OFFS)
  74691. +
  74692. +#define PXPMSC_PME_EN BIT8/* PM_PME Message Generation Enable */
  74693. +
  74694. +#define PXPMSC_PM_DATA_SEL_OFFS 9 /* Data Select*/
  74695. +#define PXPMSC_PM_DATA_SEL_MASK (0xf << PXPMSC_PM_DATA_SEL_OFFS)
  74696. +
  74697. +#define PXPMSC_PM_DATA_SCALE_OFFS 13 /* Data Scale */
  74698. +#define PXPMSC_PM_DATA_SCALE_MASK (0x3 << PXPMSC_PM_DATA_SCALE_OFFS)
  74699. +
  74700. +#define PXPMSC_PME_STAT BIT15/* PME Status */
  74701. +
  74702. +#define PXPMSC_PM_DATA_OFFS 24 /* State Data */
  74703. +#define PXPMSC_PM_DATA_MASK (0xff << PXPMSC_PM_DATA_OFFS)
  74704. +
  74705. +
  74706. +/* PCI Express MSI Message Control Register*/
  74707. +/*PEX_MSI_MESSAGE_CONTROL (PXMMC)*/
  74708. +
  74709. +#define PXMMC_CAP_ID_OFFS 0 /* Capability ID */
  74710. +#define PXMMC_CAP_ID_MASK (0xff << PXMMC_CAP_ID_OFFS)
  74711. +
  74712. +#define PXMMC_NEXT_PTR_OFFS 8 /* Next Item Pointer */
  74713. +#define PXMMC_NEXT_PTR_MASK (0xff << PXMMC_NEXT_PTR_OFFS)
  74714. +
  74715. +#define PXMMC_MSI_EN BIT18 /* MSI Enable */
  74716. +
  74717. +#define PXMMC_MULTI_CAP_OFFS 17 /* Multiple Message Capable */
  74718. +#define PXMMC_MULTI_CAP_MASK (0x7 << PXMMC_MULTI_CAP_OFFS)
  74719. +
  74720. +#define PXMMC_MULTI_EN_OFFS 20 /* Multiple Messages Enable */
  74721. +#define PXMMC_MULTI_EN_MASK (0x7 << PXMMC_MULTI_EN_OFFS)
  74722. +
  74723. +#define PXMMC_ADDR64 BIT23 /* 64-bit Addressing Capable */
  74724. +
  74725. +
  74726. +/* PCI Express MSI Message Address Register*/
  74727. +/*PEX_MSI_MESSAGE_ADDR (PXMMA)*/
  74728. +
  74729. +#define PXMMA_MSI_ADDR_OFFS 2 /* Message Address corresponds to
  74730. + Address[31:2] of the MSI MWr TLP*/
  74731. +#define PXMMA_MSI_ADDR_MASK (0x3fffffff << PXMMA_MSI_ADDR_OFFS)
  74732. +
  74733. +
  74734. +/* PCI Express MSI Message Address (High) Register */
  74735. +/*PEX_MSI_MESSAGE_HIGH_ADDR (PXMMHA)*/
  74736. +
  74737. +#define PXMMA_MSI_ADDR_H_OFFS 0 /* Message Upper Address corresponds to
  74738. + Address[63:32] of the MSI MWr TLP*/
  74739. +#define PXMMA_MSI_ADDR_H_MASK (0xffffffff << PXMMA_MSI_ADDR_H_OFFS )
  74740. +
  74741. +
  74742. +/* PCI Express MSI Message Data Register*/
  74743. +/*PEX_MSI_MESSAGE_DATA (PXMMD)*/
  74744. +
  74745. +#define PXMMD_MSI_DATA_OFFS 0 /* Message Data */
  74746. +#define PXMMD_MSI_DATA_MASK (0xffff << PXMMD_MSI_DATA_OFFS )
  74747. +
  74748. +
  74749. +/* PCI Express Capability Register*/
  74750. +/*PEX_CAPABILITY_REG (PXCR)*/
  74751. +
  74752. +#define PXCR_CAP_ID_OFFS 0 /* Capability ID*/
  74753. +#define PXCR_CAP_ID_MASK (0xff << PXCR_CAP_ID_OFFS)
  74754. +
  74755. +#define PXCR_NEXT_PTR_OFFS 8 /* Next Item Pointer*/
  74756. +#define PXCR_NEXT_PTR_MASK (0xff << PXCR_NEXT_PTR_OFFS)
  74757. +
  74758. +#define PXCR_CAP_VER_OFFS 16 /* Capability Version*/
  74759. +#define PXCR_CAP_VER_MASK (0xf << PXCR_CAP_VER_OFFS)
  74760. +
  74761. +#define PXCR_DEV_TYPE_OFFS 20 /* Device/Port Type*/
  74762. +#define PXCR_DEV_TYPE_MASK (0xf << PXCR_DEV_TYPE_OFFS)
  74763. +
  74764. +#define PXCR_SLOT_IMP BIT24 /* Slot Implemented*/
  74765. +
  74766. +#define PXCR_INT_MSG_NUM_OFFS 25 /* Interrupt Message Number*/
  74767. +#define PXCR_INT_MSG_NUM_MASK (0x1f << PXCR_INT_MSG_NUM_OFFS)
  74768. +
  74769. +
  74770. +/* PCI Express Device Capabilities Register */
  74771. +/*PEX_DEV_CAPABILITY_REG (PXDCR)*/
  74772. +
  74773. +#define PXDCR_MAX_PLD_SIZE_SUP_OFFS 0 /* Maximum Payload Size Supported*/
  74774. +#define PXDCR_MAX_PLD_SIZE_SUP_MASK (0x7 << PXDCR_MAX_PLD_SIZE_SUP_OFFS)
  74775. +
  74776. +#define PXDCR_EP_L0S_ACC_LAT_OFFS 6/* Endpoint L0s Acceptable Latency*/
  74777. +#define PXDCR_EP_L0S_ACC_LAT_MASK (0x7 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  74778. +#define PXDCR_EP_L0S_ACC_LAT_64NS_LESS (0x0 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  74779. +#define PXDCR_EP_L0S_ACC_LAT_64NS_128NS (0x1 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  74780. +#define PXDCR_EP_L0S_ACC_LAT_128NS_256NS (0x2 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  74781. +#define PXDCR_EP_L0S_ACC_LAT_256NS_512NS (0x3 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  74782. +#define PXDCR_EP_L0S_ACC_LAT_512NS_1US (0x4 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  74783. +#define PXDCR_EP_L0S_ACC_LAT_1US_2US (0x5 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  74784. +#define PXDCR_EP_L0S_ACC_LAT_2US_4US (0x6 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  74785. +#define PXDCR_EP_L0S_ACC_LAT_4US_MORE (0x7 << PXDCR_EP_L0S_ACC_LAT_OFFS)
  74786. +
  74787. +#define PXDCR_EP_L1_ACC_LAT_OFFS 9 /* Endpoint L1 Acceptable Latency*/
  74788. +#define PXDCR_EP_L1_ACC_LAT_MASK (0x7 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74789. +#define PXDCR_EP_L1_ACC_LAT_64NS_LESS (0x0 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74790. +#define PXDCR_EP_L1_ACC_LAT_64NS_128NS (0x1 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74791. +#define PXDCR_EP_L1_ACC_LAT_128NS_256NS (0x2 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74792. +#define PXDCR_EP_L1_ACC_LAT_256NS_512NS (0x3 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74793. +#define PXDCR_EP_L1_ACC_LAT_512NS_1US (0x4 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74794. +#define PXDCR_EP_L1_ACC_LAT_1US_2US (0x5 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74795. +#define PXDCR_EP_L1_ACC_LAT_2US_4US (0x6 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74796. +#define PXDCR_EP_L1_ACC_LAT_4US_MORE (0x7 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74797. +
  74798. +
  74799. +#define PXDCR_ATT_BUT_PRS_OFFS 12 /* Attention Button Present*/
  74800. +#define PXDCR_ATT_BUT_PRS_MASK BIT12
  74801. +#define PXDCR_ATT_BUT_PRS_IMPLEMENTED BIT12
  74802. +
  74803. +#define PXDCR_ATT_IND_PRS_OFFS 13 /* Attention Indicator Present*/
  74804. +#define PXDCR_ATT_IND_PRS_MASK BIT13
  74805. +#define PXDCR_ATT_IND_PRS_IMPLEMENTED BIT13
  74806. +
  74807. +#define PXDCR_PWR_IND_PRS_OFFS 14/* Power Indicator Present*/
  74808. +#define PXDCR_PWR_IND_PRS_MASK BIT14
  74809. +#define PXDCR_PWR_IND_PRS_IMPLEMENTED BIT14
  74810. +
  74811. +#define PXDCR_CAP_SPL_VAL_OFFS 18 /*Captured Slot Power Limit
  74812. + Value*/
  74813. +#define PXDCR_CAP_SPL_VAL_MASK (0xff << PXDCR_CAP_SPL_VAL_OFFS)
  74814. +
  74815. +#define PXDCR_CAP_SP_LSCL_OFFS 26 /* Captured Slot Power Limit
  74816. + Scale */
  74817. +#define PXDCR_CAP_SP_LSCL_MASK (0x3 << PXDCR_CAP_SP_LSCL_OFFS)
  74818. +
  74819. +/* PCI Express Device Control Status Register */
  74820. +/*PEX_DEV_CTRL_STAT_REG (PXDCSR)*/
  74821. +
  74822. +#define PXDCSR_COR_ERR_REP_EN BIT0 /* Correctable Error Reporting Enable*/
  74823. +#define PXDCSR_NF_ERR_REP_EN BIT1 /* Non-Fatal Error Reporting Enable*/
  74824. +#define PXDCSR_F_ERR_REP_EN BIT2 /* Fatal Error Reporting Enable*/
  74825. +#define PXDCSR_UR_REP_EN BIT3 /* Unsupported Request (UR)
  74826. + Reporting Enable*/
  74827. +#define PXDCSR_EN_RO BIT4 /* Enable Relaxed Ordering*/
  74828. +
  74829. +#define PXDCSR_MAX_PLD_SZ_OFFS 5 /* Maximum Payload Size*/
  74830. +#define PXDCSR_MAX_PLD_SZ_MASK (0x7 << PXDCSR_MAX_PLD_SZ_OFFS)
  74831. +#define PXDCSR_MAX_PLD_SZ_128B (0x0 << PXDCSR_MAX_PLD_SZ_OFFS)
  74832. +#define PXDCSR_EN_NS BIT11 /* Enable No Snoop*/
  74833. +
  74834. +#define PXDCSR_MAX_RD_RQ_SZ_OFFS 12 /* Maximum Read Request Size*/
  74835. +#define PXDCSR_MAX_RD_RQ_SZ_MASK (0x7 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  74836. +#define PXDCSR_MAX_RD_RQ_SZ_128B (0x0 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  74837. +#define PXDCSR_MAX_RD_RQ_SZ_256B (0x1 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  74838. +#define PXDCSR_MAX_RD_RQ_SZ_512B (0x2 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  74839. +#define PXDCSR_MAX_RD_RQ_SZ_1KB (0x3 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  74840. +#define PXDCSR_MAX_RD_RQ_SZ_2KB (0x4 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  74841. +#define PXDCSR_MAX_RD_RQ_SZ_4KB (0x5 << PXDCSR_MAX_RD_RQ_SZ_OFFS)
  74842. +
  74843. +#define PXDCSR_COR_ERR_DET BIT16 /* Correctable Error Detected*/
  74844. +#define PXDCSR_NF_ERR_DET BIT17 /* Non-Fatal Error Detected.*/
  74845. +#define PXDCSR_F_ERR_DET BIT18 /* Fatal Error Detected.*/
  74846. +#define PXDCSR_UR_DET BIT19 /* Unsupported Request Detected */
  74847. +#define PXDCSR_AUX_PWR_DET BIT20 /* Reserved*/
  74848. +
  74849. +#define PXDCSR_TRANS_PEND_OFFS 21 /* Transactions Pending*/
  74850. +#define PXDCSR_TRANS_PEND_MASK BIT21
  74851. +#define PXDCSR_TRANS_PEND_NOT_COMPLETED (0x1 << PXDCSR_TRANS_PEND_OFFS)
  74852. +
  74853. +
  74854. +/* PCI Express Link Capabilities Register*/
  74855. +/*PEX_LINK_CAPABILITY_REG (PXLCR)*/
  74856. +
  74857. +#define PXLCR_MAX_LINK_SPD_OFFS 0 /* Maximum Link Speed*/
  74858. +#define PXLCR_MAX_LINK_SPD_MASK (0xf << PXLCR_MAX_LINK_SPD_OFFS)
  74859. +
  74860. +#define PXLCR_MAX_LNK_WDTH_OFFS 3 /* Maximum Link Width*/
  74861. +#define PXLCR_MAX_LNK_WDTH_MASK (0x3f << PXLCR_MAX_LNK_WDTH_OFFS)
  74862. +
  74863. +#define PXLCR_ASPM_SUP_OFFS 10 /* Active State Link PM Support*/
  74864. +#define PXLCR_ASPM_SUP_MASK (0x3 << PXLCR_ASPM_SUP_OFFS)
  74865. +
  74866. +#define PXLCR_L0S_EXT_LAT_OFFS 12 /* L0s Exit Latency*/
  74867. +#define PXLCR_L0S_EXT_LAT_MASK (0x7 << PXLCR_L0S_EXT_LAT_OFFS)
  74868. +#define PXLCR_L0S_EXT_LAT_64NS_LESS (0x0 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74869. +#define PXLCR_L0S_EXT_LAT_64NS_128NS (0x1 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74870. +#define PXLCR_L0S_EXT_LAT_128NS_256NS (0x2 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74871. +#define PXLCR_L0S_EXT_LAT_256NS_512NS (0x3 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74872. +#define PXLCR_L0S_EXT_LAT_512NS_1US (0x4 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74873. +#define PXLCR_L0S_EXT_LAT_1US_2US (0x5 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74874. +#define PXLCR_L0S_EXT_LAT_2US_4US (0x6 << PXDCR_EP_L1_ACC_LAT_OFFS)
  74875. +
  74876. +#define PXLCR_POR_TNUM_OFFS 24 /* Port Number */
  74877. +#define PXLCR_POR_TNUM_MASK (0xff << PXLCR_POR_TNUM_OFFS)
  74878. +
  74879. +/* PCI Express Link Control Status Register */
  74880. +/*PEX_LINK_CTRL_STAT_REG (PXLCSR)*/
  74881. +
  74882. +#define PXLCSR_ASPM_CNT_OFFS 0 /* Active State Link PM Control */
  74883. +#define PXLCSR_ASPM_CNT_MASK (0x3 << PXLCSR_ASPM_CNT_OFFS)
  74884. +#define PXLCSR_ASPM_CNT_DISABLED (0x0 << PXLCSR_ASPM_CNT_OFFS)
  74885. +#define PXLCSR_ASPM_CNT_L0S_ENT_SUPP (0x1 << PXLCSR_ASPM_CNT_OFFS)
  74886. +#define PXLCSR_ASPM_CNT_L1S_ENT_SUPP (0x2 << PXLCSR_ASPM_CNT_OFFS)
  74887. +#define PXLCSR_ASPM_CNT_L0S_L1S_ENT_SUPP (0x3 << PXLCSR_ASPM_CNT_OFFS)
  74888. +
  74889. +#define PXLCSR_RCB_OFFS 3 /* Read Completion Boundary */
  74890. +#define PXLCSR_RCB_MASK BIT3
  74891. +#define PXLCSR_RCB_64B (0 << PXLCSR_RCB_OFFS)
  74892. +#define PXLCSR_RCB_128B (1 << PXLCSR_RCB_OFFS)
  74893. +
  74894. +#define PXLCSR_LNK_DIS BIT4 /* Link Disable */
  74895. +#define PXLCSR_RETRN_LNK BIT5 /* Retrain Link */
  74896. +#define PXLCSR_CMN_CLK_CFG BIT6 /* Common Clock Configuration */
  74897. +#define PXLCSR_EXTD_SNC BIT7 /* Extended Sync */
  74898. +
  74899. +#define PXLCSR_LNK_SPD_OFFS 16 /* Link Speed */
  74900. +#define PXLCSR_LNK_SPD_MASK (0xf << PXLCSR_LNK_SPD_OFFS)
  74901. +
  74902. +#define PXLCSR_NEG_LNK_WDTH_OFFS 20 /* Negotiated Link Width */
  74903. +#define PXLCSR_NEG_LNK_WDTH_MASK (0x3f << PXLCSR_NEG_LNK_WDTH_OFFS)
  74904. +#define PXLCSR_NEG_LNK_WDTH_X1 (0x1 << PXLCSR_NEG_LNK_WDTH_OFFS)
  74905. +
  74906. +#define PXLCSR_LNK_TRN BIT27 /* Link Training */
  74907. +
  74908. +#define PXLCSR_SLT_CLK_CFG_OFFS 28 /* Slot Clock Configuration */
  74909. +#define PXLCSR_SLT_CLK_CFG_MASK BIT28
  74910. +#define PXLCSR_SLT_CLK_CFG_INDPNT (0x0 << PXLCSR_SLT_CLK_CFG_OFFS)
  74911. +#define PXLCSR_SLT_CLK_CFG_REF (0x1 << PXLCSR_SLT_CLK_CFG_OFFS)
  74912. +
  74913. +/* PCI Express Advanced Error Report Header Register */
  74914. +/*PEX_ADV_ERR_RPRT_HDR_TRGT_REG (PXAERHTR)*/
  74915. +
  74916. +/* PCI Express Uncorrectable Error Status Register*/
  74917. +/*PEX_UNCORRECT_ERR_STAT_REG (PXUESR)*/
  74918. +
  74919. +/* PCI Express Uncorrectable Error Mask Register */
  74920. +/*PEX_UNCORRECT_ERR_MASK_REG (PXUEMR)*/
  74921. +
  74922. +/* PCI Express Uncorrectable Error Severity Register */
  74923. +/*PEX_UNCORRECT_ERR_SERVITY_REG (PXUESR)*/
  74924. +
  74925. +/* PCI Express Correctable Error Status Register */
  74926. +/*PEX_CORRECT_ERR_STAT_REG (PXCESR)*/
  74927. +
  74928. +/* PCI Express Correctable Error Mask Register */
  74929. +/*PEX_CORRECT_ERR_MASK_REG (PXCEMR)*/
  74930. +
  74931. +/* PCI Express Advanced Error Capability and Control Register*/
  74932. +/*PEX_ADV_ERR_CAPABILITY_CTRL_REG (PXAECCR)*/
  74933. +
  74934. +/* PCI Express Header Log First DWORD Register*/
  74935. +/*PEX_HDR_LOG_FIRST_DWORD_REG (PXHLFDR)*/
  74936. +
  74937. +/* PCI Express Header Log Second DWORD Register*/
  74938. +/*PEX_HDR_LOG_SECOND_DWORD_REG (PXHLSDR)*/
  74939. +
  74940. +/* PCI Express Header Log Third DWORD Register*/
  74941. +/*PEX_HDR_LOG_THIRD_DWORD_REG (PXHLTDR)*/
  74942. +
  74943. +/* PCI Express Header Log Fourth DWORD Register*/
  74944. +/*PEX_HDR_LOG_FOURTH_DWORD_REG (PXHLFDR)*/
  74945. +
  74946. +#ifdef __cplusplus
  74947. +}
  74948. +#endif /* __cplusplus */
  74949. +
  74950. +#endif /* #ifndef __INCPEXREGSH */
  74951. +
  74952. +
  74953. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c
  74954. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c 1970-01-01 01:00:00.000000000 +0100
  74955. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.c 2011-08-01 14:38:19.000000000 +0200
  74956. @@ -0,0 +1,313 @@
  74957. +/*******************************************************************************
  74958. +Copyright (C) Marvell International Ltd. and its affiliates
  74959. +
  74960. +This software file (the "File") is owned and distributed by Marvell
  74961. +International Ltd. and/or its affiliates ("Marvell") under the following
  74962. +alternative licensing terms. Once you have made an election to distribute the
  74963. +File under one of the following license alternatives, please (i) delete this
  74964. +introductory statement regarding license alternatives, (ii) delete the two
  74965. +license alternatives that you have not elected to use and (iii) preserve the
  74966. +Marvell copyright notice above.
  74967. +
  74968. +********************************************************************************
  74969. +Marvell Commercial License Option
  74970. +
  74971. +If you received this File from Marvell and you have entered into a commercial
  74972. +license agreement (a "Commercial License") with Marvell, the File is licensed
  74973. +to you under the terms of the applicable Commercial License.
  74974. +
  74975. +********************************************************************************
  74976. +Marvell GPL License Option
  74977. +
  74978. +If you received this File from Marvell, you may opt to use, redistribute and/or
  74979. +modify this File in accordance with the terms and conditions of the General
  74980. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  74981. +available along with the File in the license.txt file or by writing to the Free
  74982. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  74983. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  74984. +
  74985. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  74986. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  74987. +DISCLAIMED. The GPL License provides additional details about this warranty
  74988. +disclaimer.
  74989. +********************************************************************************
  74990. +Marvell BSD License Option
  74991. +
  74992. +If you received this File from Marvell, you may opt to use, redistribute and/or
  74993. +modify this File under the following licensing terms.
  74994. +Redistribution and use in source and binary forms, with or without modification,
  74995. +are permitted provided that the following conditions are met:
  74996. +
  74997. + * Redistributions of source code must retain the above copyright notice,
  74998. + this list of conditions and the following disclaimer.
  74999. +
  75000. + * Redistributions in binary form must reproduce the above copyright
  75001. + notice, this list of conditions and the following disclaimer in the
  75002. + documentation and/or other materials provided with the distribution.
  75003. +
  75004. + * Neither the name of Marvell nor the names of its contributors may be
  75005. + used to endorse or promote products derived from this software without
  75006. + specific prior written permission.
  75007. +
  75008. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  75009. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  75010. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  75011. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  75012. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  75013. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  75014. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  75015. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  75016. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  75017. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  75018. +
  75019. +*******************************************************************************/
  75020. +
  75021. +#include "mvPex.h"
  75022. +
  75023. +//#define MV_DEBUG
  75024. +/* defines */
  75025. +#ifdef MV_DEBUG
  75026. + #define DB(x) x
  75027. +#else
  75028. + #define DB(x)
  75029. +#endif
  75030. +
  75031. +/* locals */
  75032. +typedef struct
  75033. +{
  75034. + MV_U32 data;
  75035. + MV_U32 mask;
  75036. +}PEX_HEADER_DATA;
  75037. +
  75038. +/* local function forwad decleration */
  75039. +MV_U32 mvPexHwConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  75040. + MV_U32 regOff);
  75041. +MV_STATUS mvPexHwConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  75042. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  75043. +void resetPexConfig(MV_U32 pexIf, MV_U32 bus, MV_U32 dev);
  75044. +
  75045. +
  75046. +PEX_HEADER_DATA configHdr[16] =
  75047. +{
  75048. +{0x888811ab, 0x00000000}, /*[device ID, vendor ID] */
  75049. +{0x00100007, 0x0000ffff}, /*[status register, command register] */
  75050. +{0x0604000e, 0x00000000}, /*[programming interface, sub class code, class code, revision ID] */
  75051. +{0x00010008, 0x00000000}, /*[BIST, header type, latency time, cache line] */
  75052. +{0x00000000, 0x00000000}, /*[base address 0] */
  75053. +{0x00000000, 0x00000000}, /*[base address 1] */
  75054. +{0x00000000, 0x00ffffff}, /*[secondary latency timersubordinate bus number, secondary bus number, primary bus number] */
  75055. +{0x0000f101, 0x00000000}, /*[secondary status ,IO limit, IO base] */
  75056. +{0x9ff0a000, 0x00000000}, /*[memory limit, memory base] */
  75057. +{0x0001fff1, 0x00000000}, /*[prefetch memory limit, prefetch memory base] */
  75058. +{0xffffffff, 0x00000000}, /*[prefetch memory base upper] */
  75059. +{0x00000000, 0x00000000}, /*[prefetch memory limit upper] */
  75060. +{0xeffff000, 0x00000000}, /*[IO limit upper 16 bits, IO base upper 16 bits] */
  75061. +{0x00000000, 0x00000000}, /*[reserved, capability pointer] */
  75062. +{0x00000000, 0x00000000}, /*[expansion ROM base address] */
  75063. +{0x00000000, 0x000000FF}, /*[bridge control, interrupt pin, interrupt line] */
  75064. +};
  75065. +
  75066. +
  75067. +#define HEADER_WRITE(data, offset) configHdr[offset/4].data = ((configHdr[offset/4].data & ~configHdr[offset/4].mask) | \
  75068. + (data & configHdr[offset/4].mask))
  75069. +#define HEADER_READ(offset) configHdr[offset/4].data
  75070. +
  75071. +/*******************************************************************************
  75072. +* mvVrtBrgPexInit - Initialize PEX interfaces
  75073. +*
  75074. +* DESCRIPTION:
  75075. +*
  75076. +* This function is responsible of intialization of the Pex Interface , It
  75077. +* configure the Pex Bars and Windows in the following manner:
  75078. +*
  75079. +* Assumptions :
  75080. +* Bar0 is always internal registers bar
  75081. +* Bar1 is always the DRAM bar
  75082. +* Bar2 is always the Device bar
  75083. +*
  75084. +* 1) Sets the Internal registers bar base by obtaining the base from
  75085. +* the CPU Interface
  75086. +* 2) Sets the DRAM bar base and size by getting the base and size from
  75087. +* the CPU Interface when the size is the sum of all enabled DRAM
  75088. +* chip selects and the base is the base of CS0 .
  75089. +* 3) Sets the Device bar base and size by getting these values from the
  75090. +* CPU Interface when the base is the base of the lowest base of the
  75091. +* Device chip selects, and the
  75092. +*
  75093. +*
  75094. +* INPUT:
  75095. +*
  75096. +* pexIf - PEX interface number.
  75097. +*
  75098. +*
  75099. +* OUTPUT:
  75100. +* None.
  75101. +*
  75102. +* RETURN:
  75103. +* MV_OK if function success otherwise MV_ERROR or MV_BAD_PARAM
  75104. +*
  75105. +*******************************************************************************/
  75106. +MV_STATUS mvPexVrtBrgInit(MV_U32 pexIf)
  75107. +{
  75108. + /* reset PEX tree to recover previous U-boot/Boot configurations */
  75109. + MV_U32 localBus = mvPexLocalBusNumGet(pexIf);
  75110. +
  75111. +
  75112. + resetPexConfig(pexIf, localBus, 1);
  75113. + return MV_OK;
  75114. +}
  75115. +
  75116. +
  75117. +MV_U32 mvPexVrtBrgConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev, MV_U32 func,
  75118. + MV_U32 regOff)
  75119. +{
  75120. +
  75121. + MV_U32 localBus = mvPexLocalBusNumGet(pexIf);
  75122. + MV_U32 localDev = mvPexLocalDevNumGet(pexIf);
  75123. + MV_U32 val;
  75124. + if(bus == localBus)
  75125. + {
  75126. + if(dev > 1)
  75127. + {
  75128. +/* on the local device allow only device #0 & #1 */
  75129. + return 0xffffffff;
  75130. + }
  75131. + else
  75132. + if (dev == localDev)
  75133. + {
  75134. + /* read the memory controller registers */
  75135. + return mvPexHwConfigRead (pexIf, bus, dev, func, regOff);
  75136. + }
  75137. + else
  75138. + {
  75139. + /* access the virtual brg header */
  75140. + return HEADER_READ(regOff);
  75141. + }
  75142. + }
  75143. + else
  75144. + if(bus == (localBus + 1))
  75145. + {
  75146. + /* access the device behind the virtual bridge */
  75147. + if((dev == localDev) || (dev > 1))
  75148. + {
  75149. + return 0xffffffff;
  75150. + }
  75151. + else
  75152. + {
  75153. + /* access the device behind the virtual bridge, in this case
  75154. + * change the bus number to the local bus number in order to
  75155. + * generate type 0 config cycle
  75156. + */
  75157. + mvPexLocalBusNumSet(pexIf, bus);
  75158. + mvPexLocalDevNumSet(pexIf, 1);
  75159. + val = mvPexHwConfigRead (pexIf, bus, 0, func, regOff);
  75160. + mvPexLocalBusNumSet(pexIf, localBus);
  75161. + mvPexLocalDevNumSet(pexIf, localDev);
  75162. + return val;
  75163. + }
  75164. + }
  75165. + /* for all other devices use the HW function to get the
  75166. + * requested registers
  75167. + */
  75168. + mvPexLocalDevNumSet(pexIf, 1);
  75169. + val = mvPexHwConfigRead (pexIf, bus, dev, func, regOff);
  75170. + mvPexLocalDevNumSet(pexIf, localDev);
  75171. + return val;
  75172. +}
  75173. +
  75174. +
  75175. +MV_STATUS mvPexVrtBrgConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  75176. + MV_U32 func, MV_U32 regOff, MV_U32 data)
  75177. +{
  75178. + MV_U32 localBus = mvPexLocalBusNumGet(pexIf);
  75179. + MV_U32 localDev = mvPexLocalDevNumGet(pexIf);
  75180. + MV_STATUS status;
  75181. +
  75182. + if(bus == localBus)
  75183. + {
  75184. + if(dev > 1)
  75185. + {
  75186. + /* on the local device allow only device #0 & #1 */
  75187. + return MV_ERROR;
  75188. + }
  75189. + else
  75190. + if (dev == localDev)
  75191. + {
  75192. + /* read the memory controller registers */
  75193. + return mvPexHwConfigWrite (pexIf, bus, dev, func, regOff, data);
  75194. + }
  75195. + else
  75196. + {
  75197. + /* access the virtual brg header */
  75198. + HEADER_WRITE(data, regOff);
  75199. + return MV_OK;
  75200. + }
  75201. + }
  75202. + else
  75203. + if(bus == (localBus + 1))
  75204. + {
  75205. + /* access the device behind the virtual bridge */
  75206. + if((dev == localDev) || (dev > 1))
  75207. + {
  75208. + return MV_ERROR;
  75209. + }
  75210. + else
  75211. + {
  75212. + /* access the device behind the virtual bridge, in this case
  75213. + * change the bus number to the local bus number in order to
  75214. + * generate type 0 config cycle
  75215. + */
  75216. + //return mvPexHwConfigWrite (pexIf, localBus, dev, func, regOff, data);
  75217. + mvPexLocalBusNumSet(pexIf, bus);
  75218. + mvPexLocalDevNumSet(pexIf, 1);
  75219. + status = mvPexHwConfigWrite (pexIf, bus, 0, func, regOff, data);
  75220. + mvPexLocalBusNumSet(pexIf, localBus);
  75221. + mvPexLocalDevNumSet(pexIf, localDev);
  75222. + return status;
  75223. +
  75224. + }
  75225. + }
  75226. + /* for all other devices use the HW function to get the
  75227. + * requested registers
  75228. + */
  75229. + mvPexLocalDevNumSet(pexIf, 1);
  75230. + status = mvPexHwConfigWrite (pexIf, bus, dev, func, regOff, data);
  75231. + mvPexLocalDevNumSet(pexIf, localDev);
  75232. + return status;
  75233. +}
  75234. +
  75235. +
  75236. +
  75237. +
  75238. +void resetPexConfig(MV_U32 pexIf, MV_U32 bus, MV_U32 dev)
  75239. +{
  75240. + MV_U32 tData;
  75241. + MV_U32 i;
  75242. +
  75243. + /* restore the PEX configuration to initialization state */
  75244. + /* in case PEX P2P call recursive and reset config */
  75245. + tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x0);
  75246. + if(tData != 0xffffffff)
  75247. + {
  75248. + /* agent had been found - check whether P2P */
  75249. + tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x8);
  75250. + if((tData & 0xffff0000) == 0x06040000)
  75251. + {/* P2P */
  75252. + /* get the sec bus and the subordinate */
  75253. + MV_U32 secBus;
  75254. + tData = mvPexHwConfigRead (pexIf, bus, dev, 0x0, 0x18);
  75255. + secBus = ((tData >> 8) & 0xff);
  75256. + /* now scan on sec bus */
  75257. + for(i = 0;i < 0xff;i++)
  75258. + {
  75259. + resetPexConfig(pexIf, secBus, i);
  75260. + }
  75261. + /* now reset this device */
  75262. + DB(mvOsPrintf("Reset bus %d dev %d\n", bus, dev));
  75263. + mvPexHwConfigWrite(pexIf, bus, dev, 0x0, 0x18, 0x0);
  75264. + DB(mvOsPrintf("Reset bus %d dev %d\n", bus, dev));
  75265. + }
  75266. + }
  75267. +}
  75268. +
  75269. +
  75270. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h
  75271. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h 1970-01-01 01:00:00.000000000 +0100
  75272. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/pex/mvVrtBrgPex.h 2011-08-01 14:38:19.000000000 +0200
  75273. @@ -0,0 +1,82 @@
  75274. +/*******************************************************************************
  75275. +Copyright (C) Marvell International Ltd. and its affiliates
  75276. +
  75277. +This software file (the "File") is owned and distributed by Marvell
  75278. +International Ltd. and/or its affiliates ("Marvell") under the following
  75279. +alternative licensing terms. Once you have made an election to distribute the
  75280. +File under one of the following license alternatives, please (i) delete this
  75281. +introductory statement regarding license alternatives, (ii) delete the two
  75282. +license alternatives that you have not elected to use and (iii) preserve the
  75283. +Marvell copyright notice above.
  75284. +
  75285. +********************************************************************************
  75286. +Marvell Commercial License Option
  75287. +
  75288. +If you received this File from Marvell and you have entered into a commercial
  75289. +license agreement (a "Commercial License") with Marvell, the File is licensed
  75290. +to you under the terms of the applicable Commercial License.
  75291. +
  75292. +********************************************************************************
  75293. +Marvell GPL License Option
  75294. +
  75295. +If you received this File from Marvell, you may opt to use, redistribute and/or
  75296. +modify this File in accordance with the terms and conditions of the General
  75297. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  75298. +available along with the File in the license.txt file or by writing to the Free
  75299. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  75300. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  75301. +
  75302. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  75303. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  75304. +DISCLAIMED. The GPL License provides additional details about this warranty
  75305. +disclaimer.
  75306. +********************************************************************************
  75307. +Marvell BSD License Option
  75308. +
  75309. +If you received this File from Marvell, you may opt to use, redistribute and/or
  75310. +modify this File under the following licensing terms.
  75311. +Redistribution and use in source and binary forms, with or without modification,
  75312. +are permitted provided that the following conditions are met:
  75313. +
  75314. + * Redistributions of source code must retain the above copyright notice,
  75315. + this list of conditions and the following disclaimer.
  75316. +
  75317. + * Redistributions in binary form must reproduce the above copyright
  75318. + notice, this list of conditions and the following disclaimer in the
  75319. + documentation and/or other materials provided with the distribution.
  75320. +
  75321. + * Neither the name of Marvell nor the names of its contributors may be
  75322. + used to endorse or promote products derived from this software without
  75323. + specific prior written permission.
  75324. +
  75325. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  75326. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  75327. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  75328. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  75329. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  75330. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  75331. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  75332. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  75333. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  75334. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  75335. +
  75336. +*******************************************************************************/
  75337. +
  75338. +#ifndef __INCVRTBRGPEXH
  75339. +#define __INCVRTBRGPEXH
  75340. +
  75341. +
  75342. +/* Global Functions prototypes */
  75343. +/* mvPexInit - Initialize PEX interfaces*/
  75344. +MV_STATUS mvPexVrtBrgInit(MV_U32 pexIf);
  75345. +
  75346. +/* mvPexConfigRead - Read from configuration space */
  75347. +MV_U32 mvPexVrtBrgConfigRead (MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  75348. + MV_U32 func,MV_U32 regOff);
  75349. +
  75350. +/* mvPexConfigWrite - Write to configuration space */
  75351. +MV_STATUS mvPexVrtBrgConfigWrite(MV_U32 pexIf, MV_U32 bus, MV_U32 dev,
  75352. + MV_U32 func, MV_U32 regOff, MV_U32 data);
  75353. +
  75354. +
  75355. +#endif /* #ifndef __INCPEXH */
  75356. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c
  75357. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c 1970-01-01 01:00:00.000000000 +0100
  75358. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.c 2011-08-01 14:38:19.000000000 +0200
  75359. @@ -0,0 +1,1522 @@
  75360. +/*******************************************************************************
  75361. +Copyright (C) Marvell International Ltd. and its affiliates
  75362. +
  75363. +This software file (the "File") is owned and distributed by Marvell
  75364. +International Ltd. and/or its affiliates ("Marvell") under the following
  75365. +alternative licensing terms. Once you have made an election to distribute the
  75366. +File under one of the following license alternatives, please (i) delete this
  75367. +introductory statement regarding license alternatives, (ii) delete the two
  75368. +license alternatives that you have not elected to use and (iii) preserve the
  75369. +Marvell copyright notice above.
  75370. +
  75371. +********************************************************************************
  75372. +Marvell Commercial License Option
  75373. +
  75374. +If you received this File from Marvell and you have entered into a commercial
  75375. +license agreement (a "Commercial License") with Marvell, the File is licensed
  75376. +to you under the terms of the applicable Commercial License.
  75377. +
  75378. +********************************************************************************
  75379. +Marvell GPL License Option
  75380. +
  75381. +If you received this File from Marvell, you may opt to use, redistribute and/or
  75382. +modify this File in accordance with the terms and conditions of the General
  75383. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  75384. +available along with the File in the license.txt file or by writing to the Free
  75385. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  75386. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  75387. +
  75388. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  75389. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  75390. +DISCLAIMED. The GPL License provides additional details about this warranty
  75391. +disclaimer.
  75392. +********************************************************************************
  75393. +Marvell BSD License Option
  75394. +
  75395. +If you received this File from Marvell, you may opt to use, redistribute and/or
  75396. +modify this File under the following licensing terms.
  75397. +Redistribution and use in source and binary forms, with or without modification,
  75398. +are permitted provided that the following conditions are met:
  75399. +
  75400. + * Redistributions of source code must retain the above copyright notice,
  75401. + this list of conditions and the following disclaimer.
  75402. +
  75403. + * Redistributions in binary form must reproduce the above copyright
  75404. + notice, this list of conditions and the following disclaimer in the
  75405. + documentation and/or other materials provided with the distribution.
  75406. +
  75407. + * Neither the name of Marvell nor the names of its contributors may be
  75408. + used to endorse or promote products derived from this software without
  75409. + specific prior written permission.
  75410. +
  75411. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  75412. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  75413. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  75414. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  75415. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  75416. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  75417. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  75418. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  75419. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  75420. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  75421. +
  75422. +*******************************************************************************/
  75423. +#include "mvOs.h"
  75424. +#include "sflash/mvSFlash.h"
  75425. +#include "sflash/mvSFlashSpec.h"
  75426. +#include "spi/mvSpi.h"
  75427. +#include "spi/mvSpiCmnd.h"
  75428. +#include "ctrlEnv/mvCtrlEnvLib.h"
  75429. +
  75430. +/*#define MV_DEBUG*/
  75431. +#ifdef MV_DEBUG
  75432. +#define DB(x) x
  75433. +#else
  75434. +#define DB(x)
  75435. +#endif
  75436. +
  75437. +/* Globals */
  75438. +static MV_SFLASH_DEVICE_PARAMS sflash[] = {
  75439. + /* ST M25P32 SPI flash, 4MB, 64 sectors of 64K each */
  75440. + {
  75441. + MV_M25P_WREN_CMND_OPCD,
  75442. + MV_M25P_WRDI_CMND_OPCD,
  75443. + MV_M25P_RDID_CMND_OPCD,
  75444. + MV_M25P_RDSR_CMND_OPCD,
  75445. + MV_M25P_WRSR_CMND_OPCD,
  75446. + MV_M25P_READ_CMND_OPCD,
  75447. + MV_M25P_FAST_RD_CMND_OPCD,
  75448. + MV_M25P_PP_CMND_OPCD,
  75449. + MV_M25P_SE_CMND_OPCD,
  75450. + MV_M25P_BE_CMND_OPCD,
  75451. + MV_M25P_RES_CMND_OPCD,
  75452. + MV_SFLASH_NO_SPECIFIC_OPCD, /* power save not supported */
  75453. + MV_M25P32_SECTOR_SIZE,
  75454. + MV_M25P32_SECTOR_NUMBER,
  75455. + MV_M25P_PAGE_SIZE,
  75456. + "ST M25P32",
  75457. + MV_M25PXXX_ST_MANF_ID,
  75458. + MV_M25P32_DEVICE_ID,
  75459. + MV_M25P32_MAX_SPI_FREQ,
  75460. + MV_M25P32_MAX_FAST_SPI_FREQ,
  75461. + MV_M25P32_FAST_READ_DUMMY_BYTES
  75462. + },
  75463. + /* ST M25P64 SPI flash, 8MB, 128 sectors of 64K each */
  75464. + {
  75465. + MV_M25P_WREN_CMND_OPCD,
  75466. + MV_M25P_WRDI_CMND_OPCD,
  75467. + MV_M25P_RDID_CMND_OPCD,
  75468. + MV_M25P_RDSR_CMND_OPCD,
  75469. + MV_M25P_WRSR_CMND_OPCD,
  75470. + MV_M25P_READ_CMND_OPCD,
  75471. + MV_M25P_FAST_RD_CMND_OPCD,
  75472. + MV_M25P_PP_CMND_OPCD,
  75473. + MV_M25P_SE_CMND_OPCD,
  75474. + MV_M25P_BE_CMND_OPCD,
  75475. + MV_M25P_RES_CMND_OPCD,
  75476. + MV_SFLASH_NO_SPECIFIC_OPCD, /* power save not supported */
  75477. + MV_M25P64_SECTOR_SIZE,
  75478. + MV_M25P64_SECTOR_NUMBER,
  75479. + MV_M25P_PAGE_SIZE,
  75480. + "ST M25P64",
  75481. + MV_M25PXXX_ST_MANF_ID,
  75482. + MV_M25P64_DEVICE_ID,
  75483. + MV_M25P64_MAX_SPI_FREQ,
  75484. + MV_M25P64_MAX_FAST_SPI_FREQ,
  75485. + MV_M25P64_FAST_READ_DUMMY_BYTES
  75486. + },
  75487. + /* ST M25P128 SPI flash, 16MB, 64 sectors of 256K each */
  75488. + {
  75489. + MV_M25P_WREN_CMND_OPCD,
  75490. + MV_M25P_WRDI_CMND_OPCD,
  75491. + MV_M25P_RDID_CMND_OPCD,
  75492. + MV_M25P_RDSR_CMND_OPCD,
  75493. + MV_M25P_WRSR_CMND_OPCD,
  75494. + MV_M25P_READ_CMND_OPCD,
  75495. + MV_M25P_FAST_RD_CMND_OPCD,
  75496. + MV_M25P_PP_CMND_OPCD,
  75497. + MV_M25P_SE_CMND_OPCD,
  75498. + MV_M25P_BE_CMND_OPCD,
  75499. + MV_M25P_RES_CMND_OPCD,
  75500. + MV_SFLASH_NO_SPECIFIC_OPCD, /* power save not supported */
  75501. + MV_M25P128_SECTOR_SIZE,
  75502. + MV_M25P128_SECTOR_NUMBER,
  75503. + MV_M25P_PAGE_SIZE,
  75504. + "ST M25P128",
  75505. + MV_M25PXXX_ST_MANF_ID,
  75506. + MV_M25P128_DEVICE_ID,
  75507. + MV_M25P128_MAX_SPI_FREQ,
  75508. + MV_M25P128_MAX_FAST_SPI_FREQ,
  75509. + MV_M25P128_FAST_READ_DUMMY_BYTES
  75510. + },
  75511. + /* Macronix MXIC MX25L6405 SPI flash, 8MB, 128 sectors of 64K each */
  75512. + {
  75513. + MV_MX25L_WREN_CMND_OPCD,
  75514. + MV_MX25L_WRDI_CMND_OPCD,
  75515. + MV_MX25L_RDID_CMND_OPCD,
  75516. + MV_MX25L_RDSR_CMND_OPCD,
  75517. + MV_MX25L_WRSR_CMND_OPCD,
  75518. + MV_MX25L_READ_CMND_OPCD,
  75519. + MV_MX25L_FAST_RD_CMND_OPCD,
  75520. + MV_MX25L_PP_CMND_OPCD,
  75521. + MV_MX25L_SE_CMND_OPCD,
  75522. + MV_MX25L_BE_CMND_OPCD,
  75523. + MV_MX25L_RES_CMND_OPCD,
  75524. + MV_MX25L_DP_CMND_OPCD,
  75525. + MV_MX25L6405_SECTOR_SIZE,
  75526. + MV_MX25L6405_SECTOR_NUMBER,
  75527. + MV_MXIC_PAGE_SIZE,
  75528. + "MXIC MX25L6405",
  75529. + MV_MXIC_MANF_ID,
  75530. + MV_MX25L6405_DEVICE_ID,
  75531. + MV_MX25L6405_MAX_SPI_FREQ,
  75532. + MV_MX25L6405_MAX_FAST_SPI_FREQ,
  75533. + MV_MX25L6405_FAST_READ_DUMMY_BYTES
  75534. + },
  75535. + /* SPANSION S25FL128P SPI flash, 16MB, 64 sectors of 256K each */
  75536. + {
  75537. + MV_S25FL_WREN_CMND_OPCD,
  75538. + MV_S25FL_WRDI_CMND_OPCD,
  75539. + MV_S25FL_RDID_CMND_OPCD,
  75540. + MV_S25FL_RDSR_CMND_OPCD,
  75541. + MV_S25FL_WRSR_CMND_OPCD,
  75542. + MV_S25FL_READ_CMND_OPCD,
  75543. + MV_S25FL_FAST_RD_CMND_OPCD,
  75544. + MV_S25FL_PP_CMND_OPCD,
  75545. + MV_S25FL_SE_CMND_OPCD,
  75546. + MV_S25FL_BE_CMND_OPCD,
  75547. + MV_S25FL_RES_CMND_OPCD,
  75548. + MV_S25FL_DP_CMND_OPCD,
  75549. + MV_S25FL128_SECTOR_SIZE,
  75550. + MV_S25FL128_SECTOR_NUMBER,
  75551. + MV_S25FL_PAGE_SIZE,
  75552. + "SPANSION S25FL128",
  75553. + MV_SPANSION_MANF_ID,
  75554. + MV_S25FL128_DEVICE_ID,
  75555. + MV_S25FL128_MAX_SPI_FREQ,
  75556. + MV_M25P128_MAX_FAST_SPI_FREQ,
  75557. + MV_M25P128_FAST_READ_DUMMY_BYTES
  75558. + }
  75559. +};
  75560. +
  75561. +/* Static Functions */
  75562. +static MV_STATUS mvWriteEnable (MV_SFLASH_INFO * pFlinfo);
  75563. +static MV_STATUS mvStatusRegGet (MV_SFLASH_INFO * pFlinfo, MV_U8 * pStatReg);
  75564. +static MV_STATUS mvStatusRegSet (MV_SFLASH_INFO * pFlinfo, MV_U8 sr);
  75565. +static MV_STATUS mvWaitOnWipClear(MV_SFLASH_INFO * pFlinfo);
  75566. +static MV_STATUS mvSFlashPageWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset, \
  75567. + MV_U8* pPageBuff, MV_U32 buffSize);
  75568. +static MV_STATUS mvSFlashWithDefaultsIdGet (MV_SFLASH_INFO * pFlinfo, \
  75569. + MV_U8* manId, MV_U16* devId);
  75570. +
  75571. +/*******************************************************************************
  75572. +* mvWriteEnable - serialize the write enable sequence
  75573. +*
  75574. +* DESCRIPTION:
  75575. +* transmit the sequence for write enable
  75576. +*
  75577. +********************************************************************************/
  75578. +static MV_STATUS mvWriteEnable(MV_SFLASH_INFO * pFlinfo)
  75579. +{
  75580. + MV_U8 cmd[MV_SFLASH_WREN_CMND_LENGTH];
  75581. +
  75582. +
  75583. + cmd[0] = sflash[pFlinfo->index].opcdWREN;
  75584. +
  75585. + return mvSpiWriteThenRead(cmd, MV_SFLASH_WREN_CMND_LENGTH, NULL, 0, 0);
  75586. +}
  75587. +
  75588. +/*******************************************************************************
  75589. +* mvStatusRegGet - Retrieve the value of the status register
  75590. +*
  75591. +* DESCRIPTION:
  75592. +* perform the RDSR sequence to get the 8bit status register
  75593. +*
  75594. +********************************************************************************/
  75595. +static MV_STATUS mvStatusRegGet(MV_SFLASH_INFO * pFlinfo, MV_U8 * pStatReg)
  75596. +{
  75597. + MV_STATUS ret;
  75598. + MV_U8 cmd[MV_SFLASH_RDSR_CMND_LENGTH];
  75599. + MV_U8 sr[MV_SFLASH_RDSR_REPLY_LENGTH];
  75600. +
  75601. +
  75602. +
  75603. +
  75604. + cmd[0] = sflash[pFlinfo->index].opcdRDSR;
  75605. +
  75606. + if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_RDSR_CMND_LENGTH, sr,
  75607. + MV_SFLASH_RDSR_REPLY_LENGTH,0)) != MV_OK)
  75608. + return ret;
  75609. +
  75610. + *pStatReg = sr[0];
  75611. +
  75612. + return MV_OK;
  75613. +}
  75614. +
  75615. +/*******************************************************************************
  75616. +* mvWaitOnWipClear - Block waiting for the WIP (write in progress) to be cleared
  75617. +*
  75618. +* DESCRIPTION:
  75619. +* Block waiting for the WIP (write in progress) to be cleared
  75620. +*
  75621. +********************************************************************************/
  75622. +static MV_STATUS mvWaitOnWipClear(MV_SFLASH_INFO * pFlinfo)
  75623. +{
  75624. + MV_STATUS ret;
  75625. + MV_U32 i;
  75626. + MV_U8 stat;
  75627. +
  75628. + for (i=0; i<MV_SFLASH_MAX_WAIT_LOOP; i++)
  75629. + {
  75630. + if ((ret = mvStatusRegGet(pFlinfo, &stat)) != MV_OK)
  75631. + return ret;
  75632. +
  75633. + if ((stat & MV_SFLASH_STATUS_REG_WIP_MASK) == 0)
  75634. + return MV_OK;
  75635. + }
  75636. +
  75637. + DB(mvOsPrintf("%s WARNING: Write Timeout!\n", __FUNCTION__);)
  75638. + return MV_TIMEOUT;
  75639. +}
  75640. +
  75641. +/*******************************************************************************
  75642. +* mvWaitOnChipEraseDone - Block waiting for the WIP (write in progress) to be
  75643. +* cleared after a chip erase command which is supposed
  75644. +* to take about 2:30 minutes
  75645. +*
  75646. +* DESCRIPTION:
  75647. +* Block waiting for the WIP (write in progress) to be cleared
  75648. +*
  75649. +********************************************************************************/
  75650. +static MV_STATUS mvWaitOnChipEraseDone(MV_SFLASH_INFO * pFlinfo)
  75651. +{
  75652. + MV_STATUS ret;
  75653. + MV_U32 i;
  75654. + MV_U8 stat;
  75655. +
  75656. + for (i=0; i<MV_SFLASH_CHIP_ERASE_MAX_WAIT_LOOP; i++)
  75657. + {
  75658. + if ((ret = mvStatusRegGet(pFlinfo, &stat)) != MV_OK)
  75659. + return ret;
  75660. +
  75661. + if ((stat & MV_SFLASH_STATUS_REG_WIP_MASK) == 0)
  75662. + return MV_OK;
  75663. + }
  75664. +
  75665. + DB(mvOsPrintf("%s WARNING: Write Timeout!\n", __FUNCTION__);)
  75666. + return MV_TIMEOUT;
  75667. +}
  75668. +
  75669. +/*******************************************************************************
  75670. +* mvStatusRegSet - Set the value of the 8bit status register
  75671. +*
  75672. +* DESCRIPTION:
  75673. +* Set the value of the 8bit status register
  75674. +*
  75675. +********************************************************************************/
  75676. +static MV_STATUS mvStatusRegSet(MV_SFLASH_INFO * pFlinfo, MV_U8 sr)
  75677. +{
  75678. + MV_STATUS ret;
  75679. + MV_U8 cmd[MV_SFLASH_WRSR_CMND_LENGTH];
  75680. +
  75681. +
  75682. + /* Issue the Write enable command prior the WRSR command */
  75683. + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
  75684. + return ret;
  75685. +
  75686. + /* Write the SR with the new values */
  75687. + cmd[0] = sflash[pFlinfo->index].opcdWRSR;
  75688. + cmd[1] = sr;
  75689. +
  75690. + if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_WRSR_CMND_LENGTH, NULL, 0, 0)) != MV_OK)
  75691. + return ret;
  75692. +
  75693. + if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)
  75694. + return ret;
  75695. +
  75696. + mvOsDelay(1);
  75697. +
  75698. + return MV_OK;
  75699. +}
  75700. +
  75701. +/*******************************************************************************
  75702. +* mvSFlashPageWr - Write up to 256 Bytes in the same page
  75703. +*
  75704. +* DESCRIPTION:
  75705. +* Write a buffer up to the page size in length provided that the whole address
  75706. +* range is within the same page (alligned to page bounderies)
  75707. +*
  75708. +*******************************************************************************/
  75709. +static MV_STATUS mvSFlashPageWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  75710. + MV_U8* pPageBuff, MV_U32 buffSize)
  75711. +{
  75712. + MV_STATUS ret;
  75713. + MV_U8 cmd[MV_SFLASH_PP_CMND_LENGTH];
  75714. +
  75715. +
  75716. + /* Protection - check if the model was detected */
  75717. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75718. + {
  75719. + DB(mvOsPrintf("%s WARNING: Invalid parameter device index!\n", __FUNCTION__);)
  75720. + return MV_BAD_PARAM;
  75721. + }
  75722. +
  75723. + /* check that we do not cross the page bounderies */
  75724. + if (((offset & (sflash[pFlinfo->index].pageSize - 1)) + buffSize) >
  75725. + sflash[pFlinfo->index].pageSize)
  75726. + {
  75727. + DB(mvOsPrintf("%s WARNING: Page allignment problem!\n", __FUNCTION__);)
  75728. + return MV_OUT_OF_RANGE;
  75729. + }
  75730. +
  75731. + /* Issue the Write enable command prior the page program command */
  75732. + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
  75733. + return ret;
  75734. +
  75735. + cmd[0] = sflash[pFlinfo->index].opcdPP;
  75736. + cmd[1] = ((offset >> 16) & 0xFF);
  75737. + cmd[2] = ((offset >> 8) & 0xFF);
  75738. + cmd[3] = (offset & 0xFF);
  75739. +
  75740. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_PP_CMND_LENGTH, pPageBuff, buffSize)) != MV_OK)
  75741. + return ret;
  75742. +
  75743. + if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)
  75744. + return ret;
  75745. +
  75746. + return MV_OK;
  75747. +}
  75748. +
  75749. +/*******************************************************************************
  75750. +* mvSFlashWithDefaultsIdGet - Try to read the manufacturer and Device IDs from
  75751. +* the device using the default RDID opcode and the default WREN opcode.
  75752. +*
  75753. +* DESCRIPTION:
  75754. +* This is used to detect a generic device that uses the default opcodes
  75755. +* for the WREN and RDID.
  75756. +*
  75757. +********************************************************************************/
  75758. +static MV_STATUS mvSFlashWithDefaultsIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* manId, MV_U16* devId)
  75759. +{
  75760. + MV_STATUS ret;
  75761. + MV_U8 cmdRDID[MV_SFLASH_RDID_CMND_LENGTH];
  75762. + MV_U8 id[MV_SFLASH_RDID_REPLY_LENGTH];
  75763. +
  75764. +
  75765. +
  75766. + /* Use the default RDID opcode to read the IDs */
  75767. + cmdRDID[0] = MV_SFLASH_DEFAULT_RDID_OPCD; /* unknown model try default */
  75768. + if ((ret = mvSpiWriteThenRead(cmdRDID, MV_SFLASH_RDID_CMND_LENGTH, id, MV_SFLASH_RDID_REPLY_LENGTH, 0)) != MV_OK)
  75769. + return ret;
  75770. +
  75771. + *manId = id[0];
  75772. + *devId = 0;
  75773. + *devId |= (id[1] << 8);
  75774. + *devId |= id[2];
  75775. +
  75776. + return MV_OK;
  75777. +}
  75778. +
  75779. +/*
  75780. +#####################################################################################
  75781. +#####################################################################################
  75782. +*/
  75783. +
  75784. +/*******************************************************************************
  75785. +* mvSFlashInit - Initialize the serial flash device
  75786. +*
  75787. +* DESCRIPTION:
  75788. +* Perform the neccessary initialization and configuration
  75789. +*
  75790. +* INPUT:
  75791. +* pFlinfo: pointer to the Flash information structure
  75792. +* pFlinfo->baseAddr: base address in fast mode.
  75793. +* pFlinfo->index: Index of the flash in the sflash tabel. If the SPI
  75794. +* flash device does not support read Id command with
  75795. +* the standard opcode, then the user should supply this
  75796. +* as an input to skip the autodetection process!!!!
  75797. +*
  75798. +* OUTPUT:
  75799. +* pFlinfo: pointer to the Flash information structure after detection
  75800. +* pFlinfo->manufacturerId: Manufacturer ID
  75801. +* pFlinfo->deviceId: Device ID
  75802. +* pFlinfo->sectorSize: size of the sector (all sectors are the same).
  75803. +* pFlinfo->sectorNumber: number of sectors.
  75804. +* pFlinfo->pageSize: size of the page.
  75805. +* pFlinfo->index: Index of the detected flash in the sflash tabel
  75806. +*
  75807. +* RETURN:
  75808. +* Success or Error code.
  75809. +*
  75810. +*
  75811. +*******************************************************************************/
  75812. +MV_STATUS mvSFlashInit (MV_SFLASH_INFO * pFlinfo)
  75813. +{
  75814. + MV_STATUS ret;
  75815. + MV_U8 manf;
  75816. + MV_U16 dev;
  75817. + MV_U32 indx;
  75818. + MV_BOOL detectFlag = MV_FALSE;
  75819. +
  75820. + /* check for NULL pointer */
  75821. + if (pFlinfo == NULL)
  75822. + {
  75823. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75824. + return MV_BAD_PARAM;
  75825. + }
  75826. +
  75827. + /* Initialize the SPI interface with low frequency to make sure that the read ID succeeds */
  75828. + if ((ret = mvSpiInit(MV_SFLASH_BASIC_SPI_FREQ)) != MV_OK)
  75829. + {
  75830. + mvOsPrintf("%s ERROR: Failed to initialize the SPI interface!\n", __FUNCTION__);
  75831. + return ret;
  75832. + }
  75833. +
  75834. + /* First try to read the Manufacturer and Device IDs */
  75835. + if ((ret = mvSFlashIdGet(pFlinfo, &manf, &dev)) != MV_OK)
  75836. + {
  75837. + mvOsPrintf("%s ERROR: Failed to get the SFlash ID!\n", __FUNCTION__);
  75838. + return ret;
  75839. + }
  75840. +
  75841. + /* loop over the whole table and look for the appropriate SFLASH */
  75842. + for (indx=0; indx<MV_ARRAY_SIZE(sflash); indx++)
  75843. + {
  75844. + if ((manf == sflash[indx].manufacturerId) && (dev == sflash[indx].deviceId))
  75845. + {
  75846. + pFlinfo->manufacturerId = manf;
  75847. + pFlinfo->deviceId = dev;
  75848. + pFlinfo->index = indx;
  75849. + detectFlag = MV_TRUE;
  75850. + }
  75851. + }
  75852. +
  75853. + if(!detectFlag)
  75854. + {
  75855. + mvOsPrintf("%s ERROR: Unknown SPI flash device!\n", __FUNCTION__);
  75856. + return MV_FAIL;
  75857. + }
  75858. +
  75859. + /* fill the info based on the model detected */
  75860. + pFlinfo->sectorSize = sflash[pFlinfo->index].sectorSize;
  75861. + pFlinfo->sectorNumber = sflash[pFlinfo->index].sectorNumber;
  75862. + pFlinfo->pageSize = sflash[pFlinfo->index].pageSize;
  75863. +
  75864. + /* Set the SPI frequency to the MAX allowed for the device for best performance */
  75865. + if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFreq)) != MV_OK)
  75866. + {
  75867. + mvOsPrintf("%s ERROR: Failed to set the SPI frequency!\n", __FUNCTION__);
  75868. + return ret;
  75869. + }
  75870. +
  75871. + /* As default lock the SR */
  75872. + if ((ret = mvSFlashStatRegLock(pFlinfo, MV_TRUE)) != MV_OK)
  75873. + return ret;
  75874. +
  75875. + return MV_OK;
  75876. +}
  75877. +
  75878. +/*******************************************************************************
  75879. +* mvSFlashSectorErase - Erasse a single sector of the serial flash
  75880. +*
  75881. +* DESCRIPTION:
  75882. +* Issue the erase sector command and address
  75883. +*
  75884. +* INPUT:
  75885. +* pFlinfo: pointer to the Flash information structure
  75886. +* secNumber: sector Number to erase (0 -> (sectorNumber-1))
  75887. +*
  75888. +* OUTPUT:
  75889. +* None
  75890. +*
  75891. +* RETURN:
  75892. +* Success or Error code.
  75893. +*
  75894. +*
  75895. +*******************************************************************************/
  75896. +MV_STATUS mvSFlashSectorErase (MV_SFLASH_INFO * pFlinfo, MV_U32 secNumber)
  75897. +{
  75898. + MV_STATUS ret;
  75899. + MV_U8 cmd[MV_SFLASH_SE_CMND_LENGTH];
  75900. +
  75901. + MV_U32 secAddr = (secNumber * pFlinfo->sectorSize);
  75902. +#if 0
  75903. + MV_U32 i;
  75904. + MV_U32 * pW = (MV_U32*) (secAddr + pFlinfo->baseAddr);
  75905. + MV_U32 erasedWord = 0xFFFFFFFF;
  75906. + MV_U32 wordsPerSector = (pFlinfo->sectorSize / sizeof(MV_U32));
  75907. + MV_BOOL eraseNeeded = MV_FALSE;
  75908. +#endif
  75909. + /* check for NULL pointer */
  75910. + if (pFlinfo == NULL)
  75911. + {
  75912. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75913. + return MV_BAD_PARAM;
  75914. + }
  75915. +
  75916. + /* Protection - check if the model was detected */
  75917. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75918. + {
  75919. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  75920. + return MV_BAD_PARAM;
  75921. + }
  75922. +
  75923. + /* check that the sector number is valid */
  75924. + if (secNumber >= pFlinfo->sectorNumber)
  75925. + {
  75926. + DB(mvOsPrintf("%s WARNING: Invaild parameter sector number!\n", __FUNCTION__);)
  75927. + return MV_BAD_PARAM;
  75928. + }
  75929. +
  75930. + /* we don't want to access SPI in direct mode from in-direct API,
  75931. + becasue of timing issue between CS asserts. */
  75932. +#if 0
  75933. + /* First compare to FF and check if erase is needed */
  75934. + for (i=0; i<wordsPerSector; i++)
  75935. + {
  75936. + if (memcmp(pW, &erasedWord, sizeof(MV_U32)) != 0)
  75937. + {
  75938. + eraseNeeded = MV_TRUE;
  75939. + break;
  75940. + }
  75941. +
  75942. + ++pW;
  75943. + }
  75944. + if (!eraseNeeded)
  75945. + return MV_OK;
  75946. +#endif
  75947. +
  75948. + cmd[0] = sflash[pFlinfo->index].opcdSE;
  75949. + cmd[1] = ((secAddr >> 16) & 0xFF);
  75950. + cmd[2] = ((secAddr >> 8) & 0xFF);
  75951. + cmd[3] = (secAddr & 0xFF);
  75952. +
  75953. + /* Issue the Write enable command prior the sector erase command */
  75954. + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
  75955. + return ret;
  75956. +
  75957. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_SE_CMND_LENGTH, NULL, 0)) != MV_OK)
  75958. + return ret;
  75959. +
  75960. + if ((ret = mvWaitOnWipClear(pFlinfo)) != MV_OK)
  75961. + return ret;
  75962. +
  75963. + return MV_OK;
  75964. +}
  75965. +
  75966. +/*******************************************************************************
  75967. +* mvSFlashChipErase - Erasse the whole serial flash
  75968. +*
  75969. +* DESCRIPTION:
  75970. +* Issue the bulk (chip) erase command
  75971. +*
  75972. +* INPUT:
  75973. +* pFlinfo: pointer to the Flash information structure
  75974. +*
  75975. +* OUTPUT:
  75976. +* None
  75977. +*
  75978. +* RETURN:
  75979. +* Success or Error code.
  75980. +*
  75981. +*
  75982. +*******************************************************************************/
  75983. +MV_STATUS mvSFlashChipErase (MV_SFLASH_INFO * pFlinfo)
  75984. +{
  75985. + MV_STATUS ret;
  75986. + MV_U8 cmd[MV_SFLASH_BE_CMND_LENGTH];
  75987. +
  75988. +
  75989. + /* check for NULL pointer */
  75990. + if (pFlinfo == NULL)
  75991. + {
  75992. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  75993. + return MV_BAD_PARAM;
  75994. + }
  75995. +
  75996. + /* Protection - check if the model was detected */
  75997. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  75998. + {
  75999. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  76000. + return MV_BAD_PARAM;
  76001. + }
  76002. +
  76003. + cmd[0] = sflash[pFlinfo->index].opcdBE;
  76004. +
  76005. + /* Issue the Write enable command prior the Bulk erase command */
  76006. + if ((ret = mvWriteEnable(pFlinfo)) != MV_OK)
  76007. + return ret;
  76008. +
  76009. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_BE_CMND_LENGTH, NULL, 0)) != MV_OK)
  76010. + return ret;
  76011. +
  76012. + if ((ret = mvWaitOnChipEraseDone(pFlinfo)) != MV_OK)
  76013. + return ret;
  76014. +
  76015. + return MV_OK;
  76016. +}
  76017. +
  76018. +/*******************************************************************************
  76019. +* mvSFlashBlockRd - Read from the serial flash
  76020. +*
  76021. +* DESCRIPTION:
  76022. +* Issue the read command and address then perfom the needed read
  76023. +*
  76024. +* INPUT:
  76025. +* pFlinfo: pointer to the Flash information structure
  76026. +* offset: byte offset with the flash to start reading from
  76027. +* pReadBuff: pointer to the buffer to read the data in
  76028. +* buffSize: size of the buffer to read.
  76029. +*
  76030. +* OUTPUT:
  76031. +* pReadBuff: pointer to the buffer containing the read data
  76032. +*
  76033. +* RETURN:
  76034. +* Success or Error code.
  76035. +*
  76036. +*
  76037. +*******************************************************************************/
  76038. +MV_STATUS mvSFlashBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  76039. + MV_U8* pReadBuff, MV_U32 buffSize)
  76040. +{
  76041. + MV_U8 cmd[MV_SFLASH_READ_CMND_LENGTH];
  76042. +
  76043. +
  76044. + /* check for NULL pointer */
  76045. + if ((pFlinfo == NULL) || (pReadBuff == NULL))
  76046. + {
  76047. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76048. + return MV_BAD_PARAM;
  76049. + }
  76050. +
  76051. + /* Protection - check if the model was detected */
  76052. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  76053. + {
  76054. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  76055. + return MV_BAD_PARAM;
  76056. + }
  76057. +
  76058. + cmd[0] = sflash[pFlinfo->index].opcdREAD;
  76059. + cmd[1] = ((offset >> 16) & 0xFF);
  76060. + cmd[2] = ((offset >> 8) & 0xFF);
  76061. + cmd[3] = (offset & 0xFF);
  76062. +
  76063. + return mvSpiWriteThenRead(cmd, MV_SFLASH_READ_CMND_LENGTH, pReadBuff, buffSize, 0);
  76064. +}
  76065. +
  76066. +/*******************************************************************************
  76067. +* mvSFlashFastBlockRd - Fast read from the serial flash
  76068. +*
  76069. +* DESCRIPTION:
  76070. +* Issue the fast read command and address then perfom the needed read
  76071. +*
  76072. +* INPUT:
  76073. +* pFlinfo: pointer to the Flash information structure
  76074. +* offset: byte offset with the flash to start reading from
  76075. +* pReadBuff: pointer to the buffer to read the data in
  76076. +* buffSize: size of the buffer to read.
  76077. +*
  76078. +* OUTPUT:
  76079. +* pReadBuff: pointer to the buffer containing the read data
  76080. +*
  76081. +* RETURN:
  76082. +* Success or Error code.
  76083. +*
  76084. +*
  76085. +*******************************************************************************/
  76086. +MV_STATUS mvSFlashFastBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  76087. + MV_U8* pReadBuff, MV_U32 buffSize)
  76088. +{
  76089. + MV_U8 cmd[MV_SFLASH_READ_CMND_LENGTH];
  76090. + MV_STATUS ret;
  76091. +
  76092. + /* check for NULL pointer */
  76093. + if ((pFlinfo == NULL) || (pReadBuff == NULL))
  76094. + {
  76095. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76096. + return MV_BAD_PARAM;
  76097. + }
  76098. +
  76099. + /* Protection - check if the model was detected */
  76100. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  76101. + {
  76102. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  76103. + return MV_BAD_PARAM;
  76104. + }
  76105. +
  76106. + /* Set the SPI frequency to the MAX allowed for fast-read operations */
  76107. + mvOsPrintf("Setting freq to %d.\n",sflash[pFlinfo->index].spiMaxFastFreq);
  76108. + if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFastFreq)) != MV_OK)
  76109. + {
  76110. + mvOsPrintf("%s ERROR: Failed to set the SPI fast frequency!\n", __FUNCTION__);
  76111. + return ret;
  76112. + }
  76113. +
  76114. + cmd[0] = sflash[pFlinfo->index].opcdFSTRD;
  76115. + cmd[1] = ((offset >> 16) & 0xFF);
  76116. + cmd[2] = ((offset >> 8) & 0xFF);
  76117. + cmd[3] = (offset & 0xFF);
  76118. +
  76119. +
  76120. + ret = mvSpiWriteThenRead(cmd, MV_SFLASH_READ_CMND_LENGTH, pReadBuff, buffSize,
  76121. + sflash[pFlinfo->index].spiFastRdDummyBytes);
  76122. +
  76123. + /* Reset the SPI frequency to the MAX allowed for the device for best performance */
  76124. + if ((ret = mvSpiBaudRateSet(sflash[pFlinfo->index].spiMaxFreq)) != MV_OK)
  76125. + {
  76126. + mvOsPrintf("%s ERROR: Failed to set the SPI frequency!\n", __FUNCTION__);
  76127. + return ret;
  76128. + }
  76129. +
  76130. + return ret;
  76131. +}
  76132. +
  76133. +
  76134. +/*******************************************************************************
  76135. +* mvSFlashBlockWr - Write a buffer with any size
  76136. +*
  76137. +* DESCRIPTION:
  76138. +* write regardless of the page boundaries and size limit per Page
  76139. +* program command
  76140. +*
  76141. +* INPUT:
  76142. +* pFlinfo: pointer to the Flash information structure
  76143. +* offset: byte offset within the flash region
  76144. +* pWriteBuff: pointer to the buffer holding the data to program
  76145. +* buffSize: size of the buffer to write
  76146. +*
  76147. +* OUTPUT:
  76148. +* None
  76149. +*
  76150. +* RETURN:
  76151. +* Success or Error code.
  76152. +*
  76153. +*
  76154. +*******************************************************************************/
  76155. +MV_STATUS mvSFlashBlockWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  76156. + MV_U8* pWriteBuff, MV_U32 buffSize)
  76157. +{
  76158. + MV_STATUS ret;
  76159. + MV_U32 data2write = buffSize;
  76160. + MV_U32 preAllOffset = (offset & MV_SFLASH_PAGE_ALLIGN_MASK(MV_M25P_PAGE_SIZE));
  76161. + MV_U32 preAllSz = (preAllOffset ? (MV_M25P_PAGE_SIZE - preAllOffset) : 0);
  76162. + MV_U32 writeOffset = offset;
  76163. +
  76164. + /* check for NULL pointer */
  76165. +#ifndef CONFIG_MARVELL
  76166. + if(NULL == pWriteBuff)
  76167. + {
  76168. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76169. + return MV_BAD_PARAM;
  76170. + }
  76171. +#endif
  76172. +
  76173. + if (pFlinfo == NULL)
  76174. + {
  76175. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76176. + return MV_BAD_PARAM;
  76177. + }
  76178. +
  76179. + /* Protection - check if the model was detected */
  76180. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  76181. + {
  76182. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  76183. + return MV_BAD_PARAM;
  76184. + }
  76185. +
  76186. + /* check that the buffer size does not exceed the flash size */
  76187. + if ((offset + buffSize) > mvSFlashSizeGet(pFlinfo))
  76188. + {
  76189. + DB(mvOsPrintf("%s WARNING: Write exceeds flash size!\n", __FUNCTION__);)
  76190. + return MV_OUT_OF_RANGE;
  76191. + }
  76192. +
  76193. + /* check if the total block size is less than the first chunk remainder */
  76194. + if (data2write < preAllSz)
  76195. + preAllSz = data2write;
  76196. +
  76197. + /* check if programing does not start at a 64byte alligned offset */
  76198. + if (preAllSz)
  76199. + {
  76200. + if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, preAllSz)) != MV_OK)
  76201. + return ret;
  76202. +
  76203. + /* increment pointers and counters */
  76204. + writeOffset += preAllSz;
  76205. + data2write -= preAllSz;
  76206. + pWriteBuff += preAllSz;
  76207. + }
  76208. +
  76209. + /* program the data that fits in complete page chunks */
  76210. + while (data2write >= sflash[pFlinfo->index].pageSize)
  76211. + {
  76212. + if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, sflash[pFlinfo->index].pageSize)) != MV_OK)
  76213. + return ret;
  76214. +
  76215. + /* increment pointers and counters */
  76216. + writeOffset += sflash[pFlinfo->index].pageSize;
  76217. + data2write -= sflash[pFlinfo->index].pageSize;
  76218. + pWriteBuff += sflash[pFlinfo->index].pageSize;
  76219. + }
  76220. +
  76221. + /* program the last partial chunk */
  76222. + if (data2write)
  76223. + {
  76224. + if ((ret = mvSFlashPageWr(pFlinfo, writeOffset, pWriteBuff, data2write)) != MV_OK)
  76225. + return ret;
  76226. + }
  76227. +
  76228. + return MV_OK;
  76229. +}
  76230. +
  76231. +/*******************************************************************************
  76232. +* mvSFlashIdGet - Get the manufacturer and device IDs.
  76233. +*
  76234. +* DESCRIPTION:
  76235. +* Get the Manufacturer and device IDs from the serial flash through
  76236. +* writing the RDID command then reading 3 bytes of data. In case that
  76237. +* this command was called for the first time in order to detect the
  76238. +* manufacturer and device IDs, then the default RDID opcode will be used
  76239. +* unless the device index is indicated by the user (in case the SPI flash
  76240. +* does not use the default RDID opcode).
  76241. +*
  76242. +* INPUT:
  76243. +* pFlinfo: pointer to the Flash information structure
  76244. +* pManId: pointer to the 8bit variable to hold the manufacturing ID
  76245. +* pDevId: pointer to the 16bit variable to hold the device ID
  76246. +*
  76247. +* OUTPUT:
  76248. +* pManId: pointer to the 8bit variable holding the manufacturing ID
  76249. +* pDevId: pointer to the 16bit variable holding the device ID
  76250. +*
  76251. +* RETURN:
  76252. +* Success or Error code.
  76253. +*
  76254. +*
  76255. +*******************************************************************************/
  76256. +MV_STATUS mvSFlashIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* pManId, MV_U16* pDevId)
  76257. +{
  76258. + MV_STATUS ret;
  76259. + MV_U8 cmd[MV_SFLASH_RDID_CMND_LENGTH];
  76260. + MV_U8 id[MV_SFLASH_RDID_REPLY_LENGTH];
  76261. +
  76262. +
  76263. +
  76264. + /* check for NULL pointer */
  76265. + if ((pFlinfo == NULL) || (pManId == NULL) || (pDevId == NULL))
  76266. + {
  76267. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76268. + return MV_BAD_PARAM;
  76269. + }
  76270. +
  76271. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  76272. + return mvSFlashWithDefaultsIdGet(pFlinfo, pManId, pDevId);
  76273. + else
  76274. + cmd[0] = sflash[pFlinfo->index].opcdRDID;
  76275. +
  76276. + if ((ret = mvSpiWriteThenRead(cmd, MV_SFLASH_RDID_CMND_LENGTH, id, MV_SFLASH_RDID_REPLY_LENGTH, 0)) != MV_OK)
  76277. + return ret;
  76278. +
  76279. + *pManId = id[0];
  76280. + *pDevId = 0;
  76281. + *pDevId |= (id[1] << 8);
  76282. + *pDevId |= id[2];
  76283. +
  76284. + return MV_OK;
  76285. +}
  76286. +
  76287. +/*******************************************************************************
  76288. +* mvSFlashWpRegionSet - Set the Write-Protected region
  76289. +*
  76290. +* DESCRIPTION:
  76291. +* Set the Write-Protected region
  76292. +*
  76293. +* INPUT:
  76294. +* pFlinfo: pointer to the Flash information structure
  76295. +* wpRegion: which region will be protected
  76296. +*
  76297. +* OUTPUT:
  76298. +* None
  76299. +*
  76300. +* RETURN:
  76301. +* Success or Error code.
  76302. +*
  76303. +*
  76304. +*******************************************************************************/
  76305. +MV_STATUS mvSFlashWpRegionSet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION wpRegion)
  76306. +{
  76307. + MV_U8 wpMask;
  76308. +
  76309. + /* check for NULL pointer */
  76310. + if (pFlinfo == NULL)
  76311. + {
  76312. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76313. + return MV_BAD_PARAM;
  76314. + }
  76315. +
  76316. + /* Protection - check if the model was detected */
  76317. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  76318. + {
  76319. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  76320. + return MV_BAD_PARAM;
  76321. + }
  76322. +
  76323. + /* Check if the chip is an ST flash; then WP supports only 3 bits */
  76324. + if (pFlinfo->manufacturerId == MV_M25PXXX_ST_MANF_ID)
  76325. + {
  76326. + switch (wpRegion)
  76327. + {
  76328. + case MV_WP_NONE:
  76329. + wpMask = MV_M25P_STATUS_BP_NONE;
  76330. + break;
  76331. +
  76332. + case MV_WP_UPR_1OF128:
  76333. + DB(mvOsPrintf("%s WARNING: Invaild option for this flash chip!\n", __FUNCTION__);)
  76334. + return MV_NOT_SUPPORTED;
  76335. +
  76336. + case MV_WP_UPR_1OF64:
  76337. + wpMask = MV_M25P_STATUS_BP_1_OF_64;
  76338. + break;
  76339. +
  76340. + case MV_WP_UPR_1OF32:
  76341. + wpMask = MV_M25P_STATUS_BP_1_OF_32;
  76342. + break;
  76343. +
  76344. + case MV_WP_UPR_1OF16:
  76345. + wpMask = MV_M25P_STATUS_BP_1_OF_16;
  76346. + break;
  76347. +
  76348. + case MV_WP_UPR_1OF8:
  76349. + wpMask = MV_M25P_STATUS_BP_1_OF_8;
  76350. + break;
  76351. +
  76352. + case MV_WP_UPR_1OF4:
  76353. + wpMask = MV_M25P_STATUS_BP_1_OF_4;
  76354. + break;
  76355. +
  76356. + case MV_WP_UPR_1OF2:
  76357. + wpMask = MV_M25P_STATUS_BP_1_OF_2;
  76358. + break;
  76359. +
  76360. + case MV_WP_ALL:
  76361. + wpMask = MV_M25P_STATUS_BP_ALL;
  76362. + break;
  76363. +
  76364. + default:
  76365. + DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)
  76366. + return MV_BAD_PARAM;
  76367. + }
  76368. + }
  76369. + /* check if the manufacturer is MXIC then the WP is 4bits */
  76370. + else if (pFlinfo->manufacturerId == MV_MXIC_MANF_ID)
  76371. + {
  76372. + switch (wpRegion)
  76373. + {
  76374. + case MV_WP_NONE:
  76375. + wpMask = MV_MX25L_STATUS_BP_NONE;
  76376. + break;
  76377. +
  76378. + case MV_WP_UPR_1OF128:
  76379. + wpMask = MV_MX25L_STATUS_BP_1_OF_128;
  76380. + break;
  76381. +
  76382. + case MV_WP_UPR_1OF64:
  76383. + wpMask = MV_MX25L_STATUS_BP_1_OF_64;
  76384. + break;
  76385. +
  76386. + case MV_WP_UPR_1OF32:
  76387. + wpMask = MV_MX25L_STATUS_BP_1_OF_32;
  76388. + break;
  76389. +
  76390. + case MV_WP_UPR_1OF16:
  76391. + wpMask = MV_MX25L_STATUS_BP_1_OF_16;
  76392. + break;
  76393. +
  76394. + case MV_WP_UPR_1OF8:
  76395. + wpMask = MV_MX25L_STATUS_BP_1_OF_8;
  76396. + break;
  76397. +
  76398. + case MV_WP_UPR_1OF4:
  76399. + wpMask = MV_MX25L_STATUS_BP_1_OF_4;
  76400. + break;
  76401. +
  76402. + case MV_WP_UPR_1OF2:
  76403. + wpMask = MV_MX25L_STATUS_BP_1_OF_2;
  76404. + break;
  76405. +
  76406. + case MV_WP_ALL:
  76407. + wpMask = MV_MX25L_STATUS_BP_ALL;
  76408. + break;
  76409. +
  76410. + default:
  76411. + DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)
  76412. + return MV_BAD_PARAM;
  76413. + }
  76414. + }
  76415. + /* check if the manufacturer is SPANSION then the WP is 4bits */
  76416. + else if (pFlinfo->manufacturerId == MV_SPANSION_MANF_ID)
  76417. + {
  76418. + switch (wpRegion)
  76419. + {
  76420. + case MV_WP_NONE:
  76421. + wpMask = MV_S25FL_STATUS_BP_NONE;
  76422. + break;
  76423. +
  76424. + case MV_WP_UPR_1OF128:
  76425. + DB(mvOsPrintf("%s WARNING: Invaild option for this flash chip!\n", __FUNCTION__);)
  76426. + return MV_NOT_SUPPORTED;
  76427. +
  76428. + case MV_WP_UPR_1OF64:
  76429. + wpMask = MV_S25FL_STATUS_BP_1_OF_64;
  76430. + break;
  76431. +
  76432. + case MV_WP_UPR_1OF32:
  76433. + wpMask = MV_S25FL_STATUS_BP_1_OF_32;
  76434. + break;
  76435. +
  76436. + case MV_WP_UPR_1OF16:
  76437. + wpMask = MV_S25FL_STATUS_BP_1_OF_16;
  76438. + break;
  76439. +
  76440. + case MV_WP_UPR_1OF8:
  76441. + wpMask = MV_S25FL_STATUS_BP_1_OF_8;
  76442. + break;
  76443. +
  76444. + case MV_WP_UPR_1OF4:
  76445. + wpMask = MV_S25FL_STATUS_BP_1_OF_4;
  76446. + break;
  76447. +
  76448. + case MV_WP_UPR_1OF2:
  76449. + wpMask = MV_S25FL_STATUS_BP_1_OF_2;
  76450. + break;
  76451. +
  76452. + case MV_WP_ALL:
  76453. + wpMask = MV_S25FL_STATUS_BP_ALL;
  76454. + break;
  76455. +
  76456. +
  76457. + default:
  76458. + DB(mvOsPrintf("%s WARNING: Invaild parameter WP region!\n", __FUNCTION__);)
  76459. + return MV_BAD_PARAM;
  76460. + }
  76461. + }
  76462. + else
  76463. + {
  76464. + DB(mvOsPrintf("%s WARNING: Invaild parameter Manufacturer ID!\n", __FUNCTION__);)
  76465. + return MV_BAD_PARAM;
  76466. + }
  76467. +
  76468. + /* Verify that the SRWD bit is always set - register is s/w locked */
  76469. + wpMask |= MV_SFLASH_STATUS_REG_SRWD_MASK;
  76470. +
  76471. + return mvStatusRegSet(pFlinfo, wpMask);
  76472. +}
  76473. +
  76474. +/*******************************************************************************
  76475. +* mvSFlashWpRegionGet - Get the Write-Protected region configured
  76476. +*
  76477. +* DESCRIPTION:
  76478. +* Get from the chip the Write-Protected region configured
  76479. +*
  76480. +* INPUT:
  76481. +* pFlinfo: pointer to the Flash information structure
  76482. +* pWpRegion: pointer to the variable to return the WP region in
  76483. +*
  76484. +* OUTPUT:
  76485. +* wpRegion: pointer to the variable holding the WP region configured
  76486. +*
  76487. +* RETURN:
  76488. +* Success or Error code.
  76489. +*
  76490. +*
  76491. +*******************************************************************************/
  76492. +MV_STATUS mvSFlashWpRegionGet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION * pWpRegion)
  76493. +{
  76494. + MV_STATUS ret;
  76495. + MV_U8 reg;
  76496. +
  76497. + /* check for NULL pointer */
  76498. + if ((pFlinfo == NULL) || (pWpRegion == NULL))
  76499. + {
  76500. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76501. + return MV_BAD_PARAM;
  76502. + }
  76503. +
  76504. + /* Protection - check if the model was detected */
  76505. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  76506. + {
  76507. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  76508. + return MV_BAD_PARAM;
  76509. + }
  76510. +
  76511. + if ((ret = mvStatusRegGet(pFlinfo, &reg)) != MV_OK)
  76512. + return ret;
  76513. +
  76514. + /* Check if the chip is an ST flash; then WP supports only 3 bits */
  76515. + if (pFlinfo->manufacturerId == MV_M25PXXX_ST_MANF_ID)
  76516. + {
  76517. + switch ((reg & MV_M25P_STATUS_REG_WP_MASK))
  76518. + {
  76519. + case MV_M25P_STATUS_BP_NONE:
  76520. + *pWpRegion = MV_WP_NONE;
  76521. + break;
  76522. +
  76523. + case MV_M25P_STATUS_BP_1_OF_64:
  76524. + *pWpRegion = MV_WP_UPR_1OF64;
  76525. + break;
  76526. +
  76527. + case MV_M25P_STATUS_BP_1_OF_32:
  76528. + *pWpRegion = MV_WP_UPR_1OF32;
  76529. + break;
  76530. +
  76531. + case MV_M25P_STATUS_BP_1_OF_16:
  76532. + *pWpRegion = MV_WP_UPR_1OF16;
  76533. + break;
  76534. +
  76535. + case MV_M25P_STATUS_BP_1_OF_8:
  76536. + *pWpRegion = MV_WP_UPR_1OF8;
  76537. + break;
  76538. +
  76539. + case MV_M25P_STATUS_BP_1_OF_4:
  76540. + *pWpRegion = MV_WP_UPR_1OF4;
  76541. + break;
  76542. +
  76543. + case MV_M25P_STATUS_BP_1_OF_2:
  76544. + *pWpRegion = MV_WP_UPR_1OF2;
  76545. + break;
  76546. +
  76547. + case MV_M25P_STATUS_BP_ALL:
  76548. + *pWpRegion = MV_WP_ALL;
  76549. + break;
  76550. +
  76551. + default:
  76552. + DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)
  76553. + return MV_BAD_VALUE;
  76554. + }
  76555. + }
  76556. + /* check if the manufacturer is MXIC then the WP is 4bits */
  76557. + else if (pFlinfo->manufacturerId == MV_MXIC_MANF_ID)
  76558. + {
  76559. + switch ((reg & MV_MX25L_STATUS_REG_WP_MASK))
  76560. + {
  76561. + case MV_MX25L_STATUS_BP_NONE:
  76562. + *pWpRegion = MV_WP_NONE;
  76563. + break;
  76564. +
  76565. + case MV_MX25L_STATUS_BP_1_OF_128:
  76566. + *pWpRegion = MV_WP_UPR_1OF128;
  76567. + break;
  76568. +
  76569. + case MV_MX25L_STATUS_BP_1_OF_64:
  76570. + *pWpRegion = MV_WP_UPR_1OF64;
  76571. + break;
  76572. +
  76573. + case MV_MX25L_STATUS_BP_1_OF_32:
  76574. + *pWpRegion = MV_WP_UPR_1OF32;
  76575. + break;
  76576. +
  76577. + case MV_MX25L_STATUS_BP_1_OF_16:
  76578. + *pWpRegion = MV_WP_UPR_1OF16;
  76579. + break;
  76580. +
  76581. + case MV_MX25L_STATUS_BP_1_OF_8:
  76582. + *pWpRegion = MV_WP_UPR_1OF8;
  76583. + break;
  76584. +
  76585. + case MV_MX25L_STATUS_BP_1_OF_4:
  76586. + *pWpRegion = MV_WP_UPR_1OF4;
  76587. + break;
  76588. +
  76589. + case MV_MX25L_STATUS_BP_1_OF_2:
  76590. + *pWpRegion = MV_WP_UPR_1OF2;
  76591. + break;
  76592. +
  76593. + case MV_MX25L_STATUS_BP_ALL:
  76594. + *pWpRegion = MV_WP_ALL;
  76595. + break;
  76596. +
  76597. + default:
  76598. + DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)
  76599. + return MV_BAD_VALUE;
  76600. + }
  76601. + }
  76602. + /* Check if the chip is an SPANSION flash; then WP supports only 3 bits */
  76603. + else if (pFlinfo->manufacturerId == MV_SPANSION_MANF_ID)
  76604. + {
  76605. + switch ((reg & MV_S25FL_STATUS_REG_WP_MASK))
  76606. + {
  76607. + case MV_S25FL_STATUS_BP_NONE:
  76608. + *pWpRegion = MV_WP_NONE;
  76609. + break;
  76610. +
  76611. + case MV_S25FL_STATUS_BP_1_OF_64:
  76612. + *pWpRegion = MV_WP_UPR_1OF64;
  76613. + break;
  76614. +
  76615. + case MV_S25FL_STATUS_BP_1_OF_32:
  76616. + *pWpRegion = MV_WP_UPR_1OF32;
  76617. + break;
  76618. +
  76619. + case MV_S25FL_STATUS_BP_1_OF_16:
  76620. + *pWpRegion = MV_WP_UPR_1OF16;
  76621. + break;
  76622. +
  76623. + case MV_S25FL_STATUS_BP_1_OF_8:
  76624. + *pWpRegion = MV_WP_UPR_1OF8;
  76625. + break;
  76626. +
  76627. + case MV_S25FL_STATUS_BP_1_OF_4:
  76628. + *pWpRegion = MV_WP_UPR_1OF4;
  76629. + break;
  76630. +
  76631. + case MV_S25FL_STATUS_BP_1_OF_2:
  76632. + *pWpRegion = MV_WP_UPR_1OF2;
  76633. + break;
  76634. +
  76635. + case MV_S25FL_STATUS_BP_ALL:
  76636. + *pWpRegion = MV_WP_ALL;
  76637. + break;
  76638. +
  76639. + default:
  76640. + DB(mvOsPrintf("%s WARNING: Unidentified WP region in h/w!\n", __FUNCTION__);)
  76641. + return MV_BAD_VALUE;
  76642. + }
  76643. + }
  76644. + else
  76645. + {
  76646. + DB(mvOsPrintf("%s WARNING: Invaild parameter Manufacturer ID!\n", __FUNCTION__);)
  76647. + return MV_BAD_PARAM;
  76648. + }
  76649. +
  76650. + return MV_OK;
  76651. +}
  76652. +
  76653. +/*******************************************************************************
  76654. +* mvSFlashStatRegLock - Lock the status register for writing - W/Vpp
  76655. +* pin should be low to take effect
  76656. +*
  76657. +* DESCRIPTION:
  76658. +* Lock the access to the Status Register for writing. This will
  76659. +* cause the flash to enter the hardware protection mode if the W/Vpp
  76660. +* is low. If the W/Vpp is hi, the chip will be in soft protection mode, but
  76661. +* the register will continue to be writable if WREN sequence was used.
  76662. +*
  76663. +* INPUT:
  76664. +* pFlinfo: pointer to the Flash information structure
  76665. +* srLock: enable/disable (MV_TRUE/MV_FALSE) status registor lock mechanism
  76666. +*
  76667. +* OUTPUT:
  76668. +* None
  76669. +*
  76670. +* RETURN:
  76671. +* Success or Error code.
  76672. +*
  76673. +*
  76674. +*******************************************************************************/
  76675. +MV_STATUS mvSFlashStatRegLock (MV_SFLASH_INFO * pFlinfo, MV_BOOL srLock)
  76676. +{
  76677. + MV_STATUS ret;
  76678. + MV_U8 reg;
  76679. +
  76680. + /* check for NULL pointer */
  76681. + if (pFlinfo == NULL)
  76682. + {
  76683. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76684. + return MV_BAD_PARAM;
  76685. + }
  76686. +
  76687. + /* Protection - check if the model was detected */
  76688. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  76689. + {
  76690. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  76691. + return MV_BAD_PARAM;
  76692. + }
  76693. +
  76694. + if ((ret = mvStatusRegGet(pFlinfo, &reg)) != MV_OK)
  76695. + return ret;
  76696. +
  76697. + if (srLock)
  76698. + reg |= MV_SFLASH_STATUS_REG_SRWD_MASK;
  76699. + else
  76700. + reg &= ~MV_SFLASH_STATUS_REG_SRWD_MASK;
  76701. +
  76702. + return mvStatusRegSet(pFlinfo, reg);
  76703. +}
  76704. +
  76705. +/*******************************************************************************
  76706. +* mvSFlashSizeGet - Get the size of the SPI flash
  76707. +*
  76708. +* DESCRIPTION:
  76709. +* based on the sector number and size of each sector calculate the total
  76710. +* size of the flash memory.
  76711. +*
  76712. +* INPUT:
  76713. +* pFlinfo: pointer to the Flash information structure
  76714. +*
  76715. +* OUTPUT:
  76716. +* None.
  76717. +*
  76718. +* RETURN:
  76719. +* Size of the flash in bytes.
  76720. +*
  76721. +*
  76722. +*******************************************************************************/
  76723. +MV_U32 mvSFlashSizeGet (MV_SFLASH_INFO * pFlinfo)
  76724. +{
  76725. + /* check for NULL pointer */
  76726. + if (pFlinfo == NULL)
  76727. + {
  76728. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76729. + return 0;
  76730. + }
  76731. +
  76732. + return (pFlinfo->sectorSize * pFlinfo->sectorNumber);
  76733. +}
  76734. +
  76735. +/*******************************************************************************
  76736. +* mvSFlashPowerSaveEnter - Cause the falsh device to go into power save mode
  76737. +*
  76738. +* DESCRIPTION:
  76739. +* Enter a special power save mode.
  76740. +*
  76741. +* INPUT:
  76742. +* pFlinfo: pointer to the Flash information structure
  76743. +*
  76744. +* OUTPUT:
  76745. +* None.
  76746. +*
  76747. +* RETURN:
  76748. +* Size of the flash in bytes.
  76749. +*
  76750. +*
  76751. +*******************************************************************************/
  76752. +MV_STATUS mvSFlashPowerSaveEnter(MV_SFLASH_INFO * pFlinfo)
  76753. +{
  76754. + MV_STATUS ret;
  76755. + MV_U8 cmd[MV_SFLASH_DP_CMND_LENGTH];
  76756. +
  76757. +
  76758. + /* check for NULL pointer */
  76759. + if (pFlinfo == NULL)
  76760. + {
  76761. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76762. + return 0;
  76763. + }
  76764. +
  76765. + /* Protection - check if the model was detected */
  76766. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  76767. + {
  76768. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  76769. + return MV_BAD_PARAM;
  76770. + }
  76771. +
  76772. + /* check that power save mode is supported in the specific device */
  76773. + if (sflash[pFlinfo->index].opcdPwrSave == MV_SFLASH_NO_SPECIFIC_OPCD)
  76774. + {
  76775. + DB(mvOsPrintf("%s WARNING: Power save not supported for this device!\n", __FUNCTION__);)
  76776. + return MV_NOT_SUPPORTED;
  76777. + }
  76778. +
  76779. + cmd[0] = sflash[pFlinfo->index].opcdPwrSave;
  76780. +
  76781. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_DP_CMND_LENGTH, NULL, 0)) != MV_OK)
  76782. + return ret;
  76783. +
  76784. + return MV_OK;
  76785. +
  76786. +}
  76787. +
  76788. +/*******************************************************************************
  76789. +* mvSFlashPowerSaveExit - Cause the falsh device to exit the power save mode
  76790. +*
  76791. +* DESCRIPTION:
  76792. +* Exit the deep power save mode.
  76793. +*
  76794. +* INPUT:
  76795. +* pFlinfo: pointer to the Flash information structure
  76796. +*
  76797. +* OUTPUT:
  76798. +* None.
  76799. +*
  76800. +* RETURN:
  76801. +* Size of the flash in bytes.
  76802. +*
  76803. +*
  76804. +*******************************************************************************/
  76805. +MV_STATUS mvSFlashPowerSaveExit (MV_SFLASH_INFO * pFlinfo)
  76806. +{
  76807. + MV_STATUS ret;
  76808. + MV_U8 cmd[MV_SFLASH_RES_CMND_LENGTH];
  76809. +
  76810. +
  76811. + /* check for NULL pointer */
  76812. + if (pFlinfo == NULL)
  76813. + {
  76814. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76815. + return 0;
  76816. + }
  76817. +
  76818. + /* Protection - check if the model was detected */
  76819. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  76820. + {
  76821. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  76822. + return MV_BAD_PARAM;
  76823. + }
  76824. +
  76825. + /* check that power save mode is supported in the specific device */
  76826. + if (sflash[pFlinfo->index].opcdRES == MV_SFLASH_NO_SPECIFIC_OPCD)
  76827. + {
  76828. + DB(mvOsPrintf("%s WARNING: Read Electronic Signature not supported for this device!\n", __FUNCTION__);)
  76829. + return MV_NOT_SUPPORTED;
  76830. + }
  76831. +
  76832. + cmd[0] = sflash[pFlinfo->index].opcdRES;
  76833. +
  76834. + if ((ret = mvSpiWriteThenWrite(cmd, MV_SFLASH_RES_CMND_LENGTH, NULL, 0)) != MV_OK)
  76835. + return ret;
  76836. +
  76837. + /* add the delay needed for the device to wake up */
  76838. + mvOsDelay(MV_MXIC_DP_EXIT_DELAY); /* 30 ms */
  76839. +
  76840. + return MV_OK;
  76841. +
  76842. +}
  76843. +
  76844. +/*******************************************************************************
  76845. +* mvSFlashModelGet - Retreive the string with the device manufacturer and model
  76846. +*
  76847. +* DESCRIPTION:
  76848. +* Retreive the string with the device manufacturer and model
  76849. +*
  76850. +* INPUT:
  76851. +* pFlinfo: pointer to the Flash information structure
  76852. +*
  76853. +* OUTPUT:
  76854. +* None.
  76855. +*
  76856. +* RETURN:
  76857. +* pointer to the string indicating the device manufacturer and model
  76858. +*
  76859. +*
  76860. +*******************************************************************************/
  76861. +const MV_8 * mvSFlashModelGet (MV_SFLASH_INFO * pFlinfo)
  76862. +{
  76863. + static const MV_8 * unknModel = (const MV_8 *)"Unknown";
  76864. +
  76865. + /* check for NULL pointer */
  76866. + if (pFlinfo == NULL)
  76867. + {
  76868. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  76869. + return 0;
  76870. + }
  76871. +
  76872. + /* Protection - check if the model was detected */
  76873. + if (pFlinfo->index >= MV_ARRAY_SIZE(sflash))
  76874. + {
  76875. + DB(mvOsPrintf("%s WARNING: Invaild parameter index!\n", __FUNCTION__);)
  76876. + return unknModel;
  76877. + }
  76878. +
  76879. + return sflash[pFlinfo->index].deviceModel;
  76880. +}
  76881. +
  76882. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h
  76883. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h 1970-01-01 01:00:00.000000000 +0100
  76884. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlash.h 2011-08-01 14:38:19.000000000 +0200
  76885. @@ -0,0 +1,166 @@
  76886. +/*******************************************************************************
  76887. +Copyright (C) Marvell International Ltd. and its affiliates
  76888. +
  76889. +This software file (the "File") is owned and distributed by Marvell
  76890. +International Ltd. and/or its affiliates ("Marvell") under the following
  76891. +alternative licensing terms. Once you have made an election to distribute the
  76892. +File under one of the following license alternatives, please (i) delete this
  76893. +introductory statement regarding license alternatives, (ii) delete the two
  76894. +license alternatives that you have not elected to use and (iii) preserve the
  76895. +Marvell copyright notice above.
  76896. +
  76897. +********************************************************************************
  76898. +Marvell Commercial License Option
  76899. +
  76900. +If you received this File from Marvell and you have entered into a commercial
  76901. +license agreement (a "Commercial License") with Marvell, the File is licensed
  76902. +to you under the terms of the applicable Commercial License.
  76903. +
  76904. +********************************************************************************
  76905. +Marvell GPL License Option
  76906. +
  76907. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76908. +modify this File in accordance with the terms and conditions of the General
  76909. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  76910. +available along with the File in the license.txt file or by writing to the Free
  76911. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  76912. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  76913. +
  76914. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  76915. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  76916. +DISCLAIMED. The GPL License provides additional details about this warranty
  76917. +disclaimer.
  76918. +********************************************************************************
  76919. +Marvell BSD License Option
  76920. +
  76921. +If you received this File from Marvell, you may opt to use, redistribute and/or
  76922. +modify this File under the following licensing terms.
  76923. +Redistribution and use in source and binary forms, with or without modification,
  76924. +are permitted provided that the following conditions are met:
  76925. +
  76926. + * Redistributions of source code must retain the above copyright notice,
  76927. + this list of conditions and the following disclaimer.
  76928. +
  76929. + * Redistributions in binary form must reproduce the above copyright
  76930. + notice, this list of conditions and the following disclaimer in the
  76931. + documentation and/or other materials provided with the distribution.
  76932. +
  76933. + * Neither the name of Marvell nor the names of its contributors may be
  76934. + used to endorse or promote products derived from this software without
  76935. + specific prior written permission.
  76936. +
  76937. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  76938. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  76939. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  76940. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  76941. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  76942. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  76943. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  76944. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  76945. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  76946. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  76947. +
  76948. +*******************************************************************************/
  76949. +
  76950. +#ifndef __INCmvSFlashH
  76951. +#define __INCmvSFlashH
  76952. +
  76953. +#include "mvTypes.h"
  76954. +
  76955. +/* MCAROS */
  76956. +#define MV_SFLASH_PAGE_ALLIGN_MASK(pgSz) (pgSz-1)
  76957. +#define MV_ARRAY_SIZE(a) ((sizeof(a)) / (sizeof(a[0])))
  76958. +
  76959. +/* Constants */
  76960. +#define MV_INVALID_DEVICE_NUMBER 0xFFFFFFFF
  76961. +/* 10 MHz is the minimum possible SPI frequency when tclk is set 200MHz*/
  76962. +#define MV_SFLASH_BASIC_SPI_FREQ 10000000
  76963. +/* enumerations */
  76964. +typedef enum
  76965. +{
  76966. + MV_WP_NONE, /* Unprotect the whole chip */
  76967. + MV_WP_UPR_1OF128, /* Write protect the upper 1/128 part */
  76968. + MV_WP_UPR_1OF64, /* Write protect the upper 1/64 part */
  76969. + MV_WP_UPR_1OF32, /* Write protect the upper 1/32 part */
  76970. + MV_WP_UPR_1OF16, /* Write protect the upper 1/16 part */
  76971. + MV_WP_UPR_1OF8, /* Write protect the upper 1/8 part */
  76972. + MV_WP_UPR_1OF4, /* Write protect the upper 1/4 part */
  76973. + MV_WP_UPR_1OF2, /* Write protect the upper 1/2 part */
  76974. + MV_WP_ALL /* Write protect the whole chip */
  76975. +} MV_SFLASH_WP_REGION;
  76976. +
  76977. +/* Type Definitions */
  76978. +typedef struct
  76979. +{
  76980. + MV_U8 opcdWREN; /* Write enable opcode */
  76981. + MV_U8 opcdWRDI; /* Write disable opcode */
  76982. + MV_U8 opcdRDID; /* Read ID opcode */
  76983. + MV_U8 opcdRDSR; /* Read Status Register opcode */
  76984. + MV_U8 opcdWRSR; /* Write Status register opcode */
  76985. + MV_U8 opcdREAD; /* Read opcode */
  76986. + MV_U8 opcdFSTRD; /* Fast Read opcode */
  76987. + MV_U8 opcdPP; /* Page program opcode */
  76988. + MV_U8 opcdSE; /* Sector erase opcode */
  76989. + MV_U8 opcdBE; /* Bulk erase opcode */
  76990. + MV_U8 opcdRES; /* Read electronic signature */
  76991. + MV_U8 opcdPwrSave; /* Go into power save mode */
  76992. + MV_U32 sectorSize; /* Size of each sector */
  76993. + MV_U32 sectorNumber; /* Number of sectors */
  76994. + MV_U32 pageSize; /* size of each page */
  76995. + const char * deviceModel; /* string with the device model */
  76996. + MV_U32 manufacturerId; /* The manufacturer ID */
  76997. + MV_U32 deviceId; /* Device ID */
  76998. + MV_U32 spiMaxFreq; /* The MAX frequency that can be used with the device */
  76999. + MV_U32 spiMaxFastFreq; /* The MAX frequency that can be used with the device for fast reads */
  77000. + MV_U32 spiFastRdDummyBytes; /* Number of dumy bytes to read before real data when working in fast read mode. */
  77001. +} MV_SFLASH_DEVICE_PARAMS;
  77002. +
  77003. +typedef struct
  77004. +{
  77005. + MV_U32 baseAddr; /* Flash Base Address used in fast mode */
  77006. + MV_U8 manufacturerId; /* Manufacturer ID */
  77007. + MV_U16 deviceId; /* Device ID */
  77008. + MV_U32 sectorSize; /* Size of each sector - all the same */
  77009. + MV_U32 sectorNumber; /* Number of sectors */
  77010. + MV_U32 pageSize; /* Page size - affect allignment */
  77011. + MV_U32 index; /* index of the device in the sflash table (internal parameter) */
  77012. +} MV_SFLASH_INFO;
  77013. +
  77014. +/* Function Prototypes */
  77015. +/* Init */
  77016. +MV_STATUS mvSFlashInit (MV_SFLASH_INFO * pFlinfo);
  77017. +
  77018. +/* erase */
  77019. +MV_STATUS mvSFlashSectorErase (MV_SFLASH_INFO * pFlinfo, MV_U32 secNumber);
  77020. +MV_STATUS mvSFlashChipErase (MV_SFLASH_INFO * pFlinfo);
  77021. +
  77022. +/* Read */
  77023. +MV_STATUS mvSFlashBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  77024. + MV_U8* pReadBuff, MV_U32 buffSize);
  77025. +MV_STATUS mvSFlashFastBlockRd (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  77026. + MV_U8* pReadBuff, MV_U32 buffSize);
  77027. +
  77028. +/* write regardless of the page boundaries and size limit per Page program command */
  77029. +MV_STATUS mvSFlashBlockWr (MV_SFLASH_INFO * pFlinfo, MV_U32 offset,
  77030. + MV_U8* pWriteBuff, MV_U32 buffSize);
  77031. +/* Get IDs */
  77032. +MV_STATUS mvSFlashIdGet (MV_SFLASH_INFO * pFlinfo, MV_U8* pManId, MV_U16* pDevId);
  77033. +
  77034. +/* Set and Get the Write Protection region - if the Status register is not locked */
  77035. +MV_STATUS mvSFlashWpRegionSet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION wpRegion);
  77036. +MV_STATUS mvSFlashWpRegionGet (MV_SFLASH_INFO * pFlinfo, MV_SFLASH_WP_REGION * pWpRegion);
  77037. +
  77038. +/* Lock the status register for writing - W/Vpp pin should be low to take effect */
  77039. +MV_STATUS mvSFlashStatRegLock (MV_SFLASH_INFO * pFlinfo, MV_BOOL srLock);
  77040. +
  77041. +/* Get the regions sizes */
  77042. +MV_U32 mvSFlashSizeGet (MV_SFLASH_INFO * pFlinfo);
  77043. +
  77044. +/* Cause the falsh device to go into power save mode */
  77045. +MV_STATUS mvSFlashPowerSaveEnter(MV_SFLASH_INFO * pFlinfo);
  77046. +MV_STATUS mvSFlashPowerSaveExit (MV_SFLASH_INFO * pFlinfo);
  77047. +
  77048. +/* Retreive the string with the device manufacturer and model */
  77049. +const MV_8 * mvSFlashModelGet (MV_SFLASH_INFO * pFlinfo);
  77050. +
  77051. +#endif /* __INCmvSFlashH */
  77052. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h
  77053. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h 1970-01-01 01:00:00.000000000 +0100
  77054. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/sflash/mvSFlashSpec.h 2011-08-01 14:38:19.000000000 +0200
  77055. @@ -0,0 +1,233 @@
  77056. +/*******************************************************************************
  77057. +Copyright (C) Marvell International Ltd. and its affiliates
  77058. +
  77059. +This software file (the "File") is owned and distributed by Marvell
  77060. +International Ltd. and/or its affiliates ("Marvell") under the following
  77061. +alternative licensing terms. Once you have made an election to distribute the
  77062. +File under one of the following license alternatives, please (i) delete this
  77063. +introductory statement regarding license alternatives, (ii) delete the two
  77064. +license alternatives that you have not elected to use and (iii) preserve the
  77065. +Marvell copyright notice above.
  77066. +
  77067. +********************************************************************************
  77068. +Marvell Commercial License Option
  77069. +
  77070. +If you received this File from Marvell and you have entered into a commercial
  77071. +license agreement (a "Commercial License") with Marvell, the File is licensed
  77072. +to you under the terms of the applicable Commercial License.
  77073. +
  77074. +********************************************************************************
  77075. +Marvell GPL License Option
  77076. +
  77077. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77078. +modify this File in accordance with the terms and conditions of the General
  77079. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  77080. +available along with the File in the license.txt file or by writing to the Free
  77081. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  77082. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  77083. +
  77084. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  77085. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  77086. +DISCLAIMED. The GPL License provides additional details about this warranty
  77087. +disclaimer.
  77088. +********************************************************************************
  77089. +Marvell BSD License Option
  77090. +
  77091. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77092. +modify this File under the following licensing terms.
  77093. +Redistribution and use in source and binary forms, with or without modification,
  77094. +are permitted provided that the following conditions are met:
  77095. +
  77096. + * Redistributions of source code must retain the above copyright notice,
  77097. + this list of conditions and the following disclaimer.
  77098. +
  77099. + * Redistributions in binary form must reproduce the above copyright
  77100. + notice, this list of conditions and the following disclaimer in the
  77101. + documentation and/or other materials provided with the distribution.
  77102. +
  77103. + * Neither the name of Marvell nor the names of its contributors may be
  77104. + used to endorse or promote products derived from this software without
  77105. + specific prior written permission.
  77106. +
  77107. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  77108. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  77109. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  77110. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  77111. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  77112. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  77113. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  77114. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  77115. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  77116. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  77117. +
  77118. +*******************************************************************************/
  77119. +
  77120. +#ifndef __INCmvSFlashSpecH
  77121. +#define __INCmvSFlashSpecH
  77122. +
  77123. +/* Constants */
  77124. +#define MV_SFLASH_READ_CMND_LENGTH 4 /* 1B opcode + 3B address */
  77125. +#define MV_SFLASH_SE_CMND_LENGTH 4 /* 1B opcode + 3B address */
  77126. +#define MV_SFLASH_BE_CMND_LENGTH 1 /* 1B opcode */
  77127. +#define MV_SFLASH_PP_CMND_LENGTH 4 /* 1B opcode + 3B address */
  77128. +#define MV_SFLASH_WREN_CMND_LENGTH 1 /* 1B opcode */
  77129. +#define MV_SFLASH_WRDI_CMND_LENGTH 1 /* 1B opcode */
  77130. +#define MV_SFLASH_RDID_CMND_LENGTH 1 /* 1B opcode */
  77131. +#define MV_SFLASH_RDID_REPLY_LENGTH 3 /* 1B manf ID and 2B device ID */
  77132. +#define MV_SFLASH_RDSR_CMND_LENGTH 1 /* 1B opcode */
  77133. +#define MV_SFLASH_RDSR_REPLY_LENGTH 1 /* 1B status */
  77134. +#define MV_SFLASH_WRSR_CMND_LENGTH 2 /* 1B opcode + 1B status value */
  77135. +#define MV_SFLASH_DP_CMND_LENGTH 1 /* 1B opcode */
  77136. +#define MV_SFLASH_RES_CMND_LENGTH 1 /* 1B opcode */
  77137. +
  77138. +/* Status Register Bit Masks */
  77139. +#define MV_SFLASH_STATUS_REG_WIP_OFFSET 0 /* bit 0; write in progress */
  77140. +#define MV_SFLASH_STATUS_REG_WP_OFFSET 2 /* bit 2-4; write protect option */
  77141. +#define MV_SFLASH_STATUS_REG_SRWD_OFFSET 7 /* bit 7; lock status register write */
  77142. +#define MV_SFLASH_STATUS_REG_WIP_MASK (0x1 << MV_SFLASH_STATUS_REG_WIP_OFFSET)
  77143. +#define MV_SFLASH_STATUS_REG_SRWD_MASK (0x1 << MV_SFLASH_STATUS_REG_SRWD_OFFSET)
  77144. +
  77145. +#define MV_SFLASH_MAX_WAIT_LOOP 1000000
  77146. +#define MV_SFLASH_CHIP_ERASE_MAX_WAIT_LOOP 0x50000000
  77147. +
  77148. +#define MV_SFLASH_DEFAULT_RDID_OPCD 0x9F /* Default Read ID */
  77149. +#define MV_SFLASH_DEFAULT_WREN_OPCD 0x06 /* Default Write Enable */
  77150. +#define MV_SFLASH_NO_SPECIFIC_OPCD 0x00
  77151. +
  77152. +/********************************/
  77153. +/* ST M25Pxxx Device Specific */
  77154. +/********************************/
  77155. +
  77156. +/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */
  77157. +#define MV_M25PXXX_ST_MANF_ID 0x20
  77158. +#define MV_M25P32_DEVICE_ID 0x2016
  77159. +#define MV_M25P32_MAX_SPI_FREQ 20000000 /* 20MHz */
  77160. +#define MV_M25P32_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
  77161. +#define MV_M25P32_FAST_READ_DUMMY_BYTES 1
  77162. +#define MV_M25P64_DEVICE_ID 0x2017
  77163. +#define MV_M25P64_MAX_SPI_FREQ 20000000 /* 20MHz */
  77164. +#define MV_M25P64_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
  77165. +#define MV_M25P64_FAST_READ_DUMMY_BYTES 1
  77166. +#define MV_M25P128_DEVICE_ID 0x2018
  77167. +#define MV_M25P128_MAX_SPI_FREQ 20000000 /* 20MHz */
  77168. +#define MV_M25P128_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
  77169. +#define MV_M25P128_FAST_READ_DUMMY_BYTES 1
  77170. +
  77171. +
  77172. +/* Sector Sizes and population per device model*/
  77173. +#define MV_M25P32_SECTOR_SIZE 0x10000 /* 64K */
  77174. +#define MV_M25P64_SECTOR_SIZE 0x10000 /* 64K */
  77175. +#define MV_M25P128_SECTOR_SIZE 0x40000 /* 256K */
  77176. +#define MV_M25P32_SECTOR_NUMBER 64
  77177. +#define MV_M25P64_SECTOR_NUMBER 128
  77178. +#define MV_M25P128_SECTOR_NUMBER 64
  77179. +#define MV_M25P_PAGE_SIZE 0x100 /* 256 byte */
  77180. +
  77181. +#define MV_M25P_WREN_CMND_OPCD 0x06 /* Write Enable */
  77182. +#define MV_M25P_WRDI_CMND_OPCD 0x04 /* Write Disable */
  77183. +#define MV_M25P_RDID_CMND_OPCD 0x9F /* Read ID */
  77184. +#define MV_M25P_RDSR_CMND_OPCD 0x05 /* Read Status Register */
  77185. +#define MV_M25P_WRSR_CMND_OPCD 0x01 /* Write Status Register */
  77186. +#define MV_M25P_READ_CMND_OPCD 0x03 /* Sequential Read */
  77187. +#define MV_M25P_FAST_RD_CMND_OPCD 0x0B /* Fast Read */
  77188. +#define MV_M25P_PP_CMND_OPCD 0x02 /* Page Program */
  77189. +#define MV_M25P_SE_CMND_OPCD 0xD8 /* Sector Erase */
  77190. +#define MV_M25P_BE_CMND_OPCD 0xC7 /* Bulk Erase */
  77191. +#define MV_M25P_RES_CMND_OPCD 0xAB /* Read Electronic Signature */
  77192. +
  77193. +/* Status Register Write Protect Bit Masks - 3bits */
  77194. +#define MV_M25P_STATUS_REG_WP_MASK (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77195. +#define MV_M25P_STATUS_BP_NONE (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77196. +#define MV_M25P_STATUS_BP_1_OF_64 (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77197. +#define MV_M25P_STATUS_BP_1_OF_32 (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77198. +#define MV_M25P_STATUS_BP_1_OF_16 (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77199. +#define MV_M25P_STATUS_BP_1_OF_8 (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77200. +#define MV_M25P_STATUS_BP_1_OF_4 (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77201. +#define MV_M25P_STATUS_BP_1_OF_2 (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77202. +#define MV_M25P_STATUS_BP_ALL (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77203. +
  77204. +/************************************/
  77205. +/* MXIC MX25L6405 Device Specific */
  77206. +/************************************/
  77207. +
  77208. +/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */
  77209. +#define MV_MXIC_MANF_ID 0xC2
  77210. +#define MV_MX25L6405_DEVICE_ID 0x2017
  77211. +#define MV_MX25L6405_MAX_SPI_FREQ 20000000 /* 20MHz */
  77212. +#define MV_MX25L6405_MAX_FAST_SPI_FREQ 50000000 /* 50MHz */
  77213. +#define MV_MX25L6405_FAST_READ_DUMMY_BYTES 1
  77214. +#define MV_MXIC_DP_EXIT_DELAY 30 /* 30 ms */
  77215. +
  77216. +/* Sector Sizes and population per device model*/
  77217. +#define MV_MX25L6405_SECTOR_SIZE 0x10000 /* 64K */
  77218. +#define MV_MX25L6405_SECTOR_NUMBER 128
  77219. +#define MV_MXIC_PAGE_SIZE 0x100 /* 256 byte */
  77220. +
  77221. +#define MV_MX25L_WREN_CMND_OPCD 0x06 /* Write Enable */
  77222. +#define MV_MX25L_WRDI_CMND_OPCD 0x04 /* Write Disable */
  77223. +#define MV_MX25L_RDID_CMND_OPCD 0x9F /* Read ID */
  77224. +#define MV_MX25L_RDSR_CMND_OPCD 0x05 /* Read Status Register */
  77225. +#define MV_MX25L_WRSR_CMND_OPCD 0x01 /* Write Status Register */
  77226. +#define MV_MX25L_READ_CMND_OPCD 0x03 /* Sequential Read */
  77227. +#define MV_MX25L_FAST_RD_CMND_OPCD 0x0B /* Fast Read */
  77228. +#define MV_MX25L_PP_CMND_OPCD 0x02 /* Page Program */
  77229. +#define MV_MX25L_SE_CMND_OPCD 0xD8 /* Sector Erase */
  77230. +#define MV_MX25L_BE_CMND_OPCD 0xC7 /* Bulk Erase */
  77231. +#define MV_MX25L_DP_CMND_OPCD 0xB9 /* Deep Power Down */
  77232. +#define MV_MX25L_RES_CMND_OPCD 0xAB /* Read Electronic Signature */
  77233. +
  77234. +/* Status Register Write Protect Bit Masks - 4bits */
  77235. +#define MV_MX25L_STATUS_REG_WP_MASK (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77236. +#define MV_MX25L_STATUS_BP_NONE (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77237. +#define MV_MX25L_STATUS_BP_1_OF_128 (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77238. +#define MV_MX25L_STATUS_BP_1_OF_64 (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77239. +#define MV_MX25L_STATUS_BP_1_OF_32 (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77240. +#define MV_MX25L_STATUS_BP_1_OF_16 (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77241. +#define MV_MX25L_STATUS_BP_1_OF_8 (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77242. +#define MV_MX25L_STATUS_BP_1_OF_4 (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77243. +#define MV_MX25L_STATUS_BP_1_OF_2 (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77244. +#define MV_MX25L_STATUS_BP_ALL (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77245. +
  77246. +/************************************/
  77247. +/* SPANSION S25FL128P Device Specific */
  77248. +/************************************/
  77249. +
  77250. +/* Manufacturer IDs and Device IDs for SFLASHs supported by the driver */
  77251. +#define MV_SPANSION_MANF_ID 0x01
  77252. +#define MV_S25FL128_DEVICE_ID 0x2018
  77253. +#define MV_S25FL128_MAX_SPI_FREQ 33000000 /* 33MHz */
  77254. +#define MV_S25FL128_MAX_FAST_SPI_FREQ 104000000 /* 104MHz */
  77255. +#define MV_S25FL128_FAST_READ_DUMMY_BYTES 1
  77256. +
  77257. +/* Sector Sizes and population per device model*/
  77258. +#define MV_S25FL128_SECTOR_SIZE 0x40000 /* 256K */
  77259. +#define MV_S25FL128_SECTOR_NUMBER 64
  77260. +#define MV_S25FL_PAGE_SIZE 0x100 /* 256 byte */
  77261. +
  77262. +#define MV_S25FL_WREN_CMND_OPCD 0x06 /* Write Enable */
  77263. +#define MV_S25FL_WRDI_CMND_OPCD 0x04 /* Write Disable */
  77264. +#define MV_S25FL_RDID_CMND_OPCD 0x9F /* Read ID */
  77265. +#define MV_S25FL_RDSR_CMND_OPCD 0x05 /* Read Status Register */
  77266. +#define MV_S25FL_WRSR_CMND_OPCD 0x01 /* Write Status Register */
  77267. +#define MV_S25FL_READ_CMND_OPCD 0x03 /* Sequential Read */
  77268. +#define MV_S25FL_FAST_RD_CMND_OPCD 0x0B /* Fast Read */
  77269. +#define MV_S25FL_PP_CMND_OPCD 0x02 /* Page Program */
  77270. +#define MV_S25FL_SE_CMND_OPCD 0xD8 /* Sector Erase */
  77271. +#define MV_S25FL_BE_CMND_OPCD 0xC7 /* Bulk Erase */
  77272. +#define MV_S25FL_DP_CMND_OPCD 0xB9 /* Deep Power Down */
  77273. +#define MV_S25FL_RES_CMND_OPCD 0xAB /* Read Electronic Signature */
  77274. +
  77275. +/* Status Register Write Protect Bit Masks - 4bits */
  77276. +#define MV_S25FL_STATUS_REG_WP_MASK (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77277. +#define MV_S25FL_STATUS_BP_NONE (0x00 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77278. +#define MV_S25FL_STATUS_BP_1_OF_128 (0x01 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77279. +#define MV_S25FL_STATUS_BP_1_OF_64 (0x02 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77280. +#define MV_S25FL_STATUS_BP_1_OF_32 (0x03 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77281. +#define MV_S25FL_STATUS_BP_1_OF_16 (0x04 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77282. +#define MV_S25FL_STATUS_BP_1_OF_8 (0x05 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77283. +#define MV_S25FL_STATUS_BP_1_OF_4 (0x06 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77284. +#define MV_S25FL_STATUS_BP_1_OF_2 (0x07 << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77285. +#define MV_S25FL_STATUS_BP_ALL (0x0F << MV_SFLASH_STATUS_REG_WP_OFFSET)
  77286. +
  77287. +#endif /* __INCmvSFlashSpecH */
  77288. +
  77289. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c
  77290. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c 1970-01-01 01:00:00.000000000 +0100
  77291. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.c 2011-08-01 14:38:19.000000000 +0200
  77292. @@ -0,0 +1,576 @@
  77293. +/*******************************************************************************
  77294. +Copyright (C) Marvell International Ltd. and its affiliates
  77295. +
  77296. +This software file (the "File") is owned and distributed by Marvell
  77297. +International Ltd. and/or its affiliates ("Marvell") under the following
  77298. +alternative licensing terms. Once you have made an election to distribute the
  77299. +File under one of the following license alternatives, please (i) delete this
  77300. +introductory statement regarding license alternatives, (ii) delete the two
  77301. +license alternatives that you have not elected to use and (iii) preserve the
  77302. +Marvell copyright notice above.
  77303. +
  77304. +********************************************************************************
  77305. +Marvell Commercial License Option
  77306. +
  77307. +If you received this File from Marvell and you have entered into a commercial
  77308. +license agreement (a "Commercial License") with Marvell, the File is licensed
  77309. +to you under the terms of the applicable Commercial License.
  77310. +
  77311. +********************************************************************************
  77312. +Marvell GPL License Option
  77313. +
  77314. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77315. +modify this File in accordance with the terms and conditions of the General
  77316. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  77317. +available along with the File in the license.txt file or by writing to the Free
  77318. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  77319. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  77320. +
  77321. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  77322. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  77323. +DISCLAIMED. The GPL License provides additional details about this warranty
  77324. +disclaimer.
  77325. +********************************************************************************
  77326. +Marvell BSD License Option
  77327. +
  77328. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77329. +modify this File under the following licensing terms.
  77330. +Redistribution and use in source and binary forms, with or without modification,
  77331. +are permitted provided that the following conditions are met:
  77332. +
  77333. + * Redistributions of source code must retain the above copyright notice,
  77334. + this list of conditions and the following disclaimer.
  77335. +
  77336. + * Redistributions in binary form must reproduce the above copyright
  77337. + notice, this list of conditions and the following disclaimer in the
  77338. + documentation and/or other materials provided with the distribution.
  77339. +
  77340. + * Neither the name of Marvell nor the names of its contributors may be
  77341. + used to endorse or promote products derived from this software without
  77342. + specific prior written permission.
  77343. +
  77344. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  77345. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  77346. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  77347. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  77348. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  77349. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  77350. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  77351. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  77352. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  77353. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  77354. +
  77355. +*******************************************************************************/
  77356. +
  77357. +#include "spi/mvSpi.h"
  77358. +#include "spi/mvSpiSpec.h"
  77359. +
  77360. +#include "ctrlEnv/mvCtrlEnvLib.h"
  77361. +
  77362. +/* #define MV_DEBUG */
  77363. +#ifdef MV_DEBUG
  77364. +#define DB(x) x
  77365. +#define mvOsPrintf printf
  77366. +#else
  77367. +#define DB(x)
  77368. +#endif
  77369. +
  77370. +
  77371. +/*******************************************************************************
  77372. +* mvSpi16bitDataTxRx - Transmt and receive data
  77373. +*
  77374. +* DESCRIPTION:
  77375. +* Tx data and block waiting for data to be transmitted
  77376. +*
  77377. +********************************************************************************/
  77378. +static MV_STATUS mvSpi16bitDataTxRx (MV_U16 txData, MV_U16 * pRxData)
  77379. +{
  77380. + MV_U32 i;
  77381. + MV_BOOL ready = MV_FALSE;
  77382. +
  77383. + /* First clear the bit in the interrupt cause register */
  77384. + MV_REG_WRITE(MV_SPI_INT_CAUSE_REG, 0x0);
  77385. +
  77386. + /* Transmit data */
  77387. + MV_REG_WRITE(MV_SPI_DATA_OUT_REG, MV_16BIT_LE(txData));
  77388. +
  77389. + /* wait with timeout for memory ready */
  77390. + for (i=0; i<MV_SPI_WAIT_RDY_MAX_LOOP; i++)
  77391. + {
  77392. + if (MV_REG_READ(MV_SPI_INT_CAUSE_REG))
  77393. + {
  77394. + ready = MV_TRUE;
  77395. + break;
  77396. + }
  77397. +#ifdef MV_SPI_SLEEP_ON_WAIT
  77398. + mvOsSleep(1);
  77399. +#endif /* MV_SPI_SLEEP_ON_WAIT */
  77400. + }
  77401. +
  77402. + if (!ready)
  77403. + return MV_TIMEOUT;
  77404. +
  77405. + /* check that the RX data is needed */
  77406. + if (pRxData)
  77407. + {
  77408. + if ((MV_U32)pRxData & 0x1) /* check if address is not alligned to 16bit */
  77409. + {
  77410. +#if defined(MV_CPU_LE)
  77411. + /* perform the data write to the buffer in two stages with 8bit each */
  77412. + MV_U8 * bptr = (MV_U8*)pRxData;
  77413. + MV_U16 data = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));
  77414. + *bptr = (data & 0xFF);
  77415. + ++bptr;
  77416. + *bptr = ((data >> 8) & 0xFF);
  77417. +
  77418. +#elif defined(MV_CPU_BE)
  77419. +
  77420. + /* perform the data write to the buffer in two stages with 8bit each */
  77421. + MV_U8 * bptr = (MV_U8 *)pRxData;
  77422. + MV_U16 data = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));
  77423. + *bptr = ((data >> 8) & 0xFF);
  77424. + ++bptr;
  77425. + *bptr = (data & 0xFF);
  77426. +
  77427. +#else
  77428. + #error "CPU endianess isn't defined!\n"
  77429. +#endif
  77430. +
  77431. + }
  77432. + else
  77433. + *pRxData = MV_16BIT_LE(MV_REG_READ(MV_SPI_DATA_IN_REG));
  77434. + }
  77435. +
  77436. + return MV_OK;
  77437. +}
  77438. +
  77439. +
  77440. +/*******************************************************************************
  77441. +* mvSpi8bitDataTxRx - Transmt and receive data (8bits)
  77442. +*
  77443. +* DESCRIPTION:
  77444. +* Tx data and block waiting for data to be transmitted
  77445. +*
  77446. +********************************************************************************/
  77447. +static MV_STATUS mvSpi8bitDataTxRx (MV_U8 txData, MV_U8 * pRxData)
  77448. +{
  77449. + MV_U32 i;
  77450. + MV_BOOL ready = MV_FALSE;
  77451. +
  77452. + /* First clear the bit in the interrupt cause register */
  77453. + MV_REG_WRITE(MV_SPI_INT_CAUSE_REG, 0x0);
  77454. +
  77455. + /* Transmit data */
  77456. + MV_REG_WRITE(MV_SPI_DATA_OUT_REG, txData);
  77457. +
  77458. + /* wait with timeout for memory ready */
  77459. + for (i=0; i<MV_SPI_WAIT_RDY_MAX_LOOP; i++)
  77460. + {
  77461. + if (MV_REG_READ(MV_SPI_INT_CAUSE_REG))
  77462. + {
  77463. + ready = MV_TRUE;
  77464. + break;
  77465. + }
  77466. +#ifdef MV_SPI_SLEEP_ON_WAIT
  77467. + mvOsSleep(1);
  77468. +#endif /* MV_SPI_SLEEP_ON_WAIT */
  77469. + }
  77470. +
  77471. + if (!ready)
  77472. + return MV_TIMEOUT;
  77473. +
  77474. + /* check that the RX data is needed */
  77475. + if (pRxData)
  77476. + *pRxData = MV_REG_READ(MV_SPI_DATA_IN_REG);
  77477. +
  77478. + return MV_OK;
  77479. +}
  77480. +
  77481. +/*
  77482. +#####################################################################################
  77483. +#####################################################################################
  77484. +*/
  77485. +
  77486. +/*******************************************************************************
  77487. +* mvSpiInit - Initialize the SPI controller
  77488. +*
  77489. +* DESCRIPTION:
  77490. +* Perform the neccessary initialization in order to be able to send an
  77491. +* receive over the SPI interface.
  77492. +*
  77493. +* INPUT:
  77494. +* serialBaudRate: Baud rate (SPI clock frequency)
  77495. +* use16BitMode: Whether to use 2bytes (MV_TRUE) or 1bytes (MV_FALSE)
  77496. +*
  77497. +* OUTPUT:
  77498. +* None.
  77499. +*
  77500. +* RETURN:
  77501. +* Success or Error code.
  77502. +*
  77503. +*
  77504. +*******************************************************************************/
  77505. +MV_STATUS mvSpiInit (MV_U32 serialBaudRate)
  77506. +{
  77507. + MV_STATUS ret;
  77508. +
  77509. + /* Set the serial clock */
  77510. + if ((ret = mvSpiBaudRateSet(serialBaudRate)) != MV_OK)
  77511. + return ret;
  77512. +
  77513. + /* For devices in which the SPI is muxed on the MPP with other interfaces*/
  77514. + mvMPPConfigToSPI();
  77515. +
  77516. + /* Configure the default SPI mode to be 16bit */
  77517. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  77518. +
  77519. + /* Fix ac timing on SPI in 6183, 6183L and 78x00 only */
  77520. + if ( (mvCtrlModelGet() == MV_6183_DEV_ID) ||
  77521. + (mvCtrlModelGet() == MV_6183L_DEV_ID) ||
  77522. + (mvCtrlModelGet() == MV_78100_DEV_ID) ||
  77523. + (mvCtrlModelGet() == MV_78200_DEV_ID) ||
  77524. + (mvCtrlModelGet() == MV_76100_DEV_ID))
  77525. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, BIT14);
  77526. +
  77527. + /* Verify that the CS is deasserted */
  77528. + mvSpiCsDeassert();
  77529. +
  77530. + return MV_OK;
  77531. +}
  77532. +
  77533. +/*******************************************************************************
  77534. +* mvSpiBaudRateSet - Set the Frequency of the SPI clock
  77535. +*
  77536. +* DESCRIPTION:
  77537. +* Set the Prescale bits to adapt to the requested baud rate (the clock
  77538. +* used for thr SPI).
  77539. +*
  77540. +* INPUT:
  77541. +* serialBaudRate: Baud rate (SPI clock frequency)
  77542. +*
  77543. +* OUTPUT:
  77544. +* None.
  77545. +*
  77546. +* RETURN:
  77547. +* Success or Error code.
  77548. +*
  77549. +*
  77550. +*******************************************************************************/
  77551. +MV_STATUS mvSpiBaudRateSet (MV_U32 serialBaudRate)
  77552. +{
  77553. + MV_U8 i;
  77554. + /* MV_U8 preScale[32] = {1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
  77555. + 2, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
  77556. + */
  77557. + MV_U8 preScale[14] = { 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30};
  77558. + MV_U8 bestPrescaleIndx = 100;
  77559. + MV_U32 minBaudOffset = 0xFFFFFFFF;
  77560. + MV_U32 cpuClk = mvBoardTclkGet(); /*mvCpuPclkGet();*/
  77561. + MV_U32 tempReg;
  77562. +
  77563. + /* Find the best prescale configuration - less or equal */
  77564. + for (i=0; i<14; i++)
  77565. + {
  77566. + /* check for higher - irrelevent */
  77567. + if ((cpuClk / preScale[i]) > serialBaudRate)
  77568. + continue;
  77569. +
  77570. + /* check for exact fit */
  77571. + if ((cpuClk / preScale[i]) == serialBaudRate)
  77572. + {
  77573. + bestPrescaleIndx = i;
  77574. + break;
  77575. + }
  77576. +
  77577. + /* check if this is better than the previous one */
  77578. + if ((serialBaudRate - (cpuClk / preScale[i])) < minBaudOffset)
  77579. + {
  77580. + minBaudOffset = (serialBaudRate - (cpuClk / preScale[i]));
  77581. + bestPrescaleIndx = i;
  77582. + }
  77583. + }
  77584. +
  77585. + if (bestPrescaleIndx > 14)
  77586. + {
  77587. + mvOsPrintf("%s ERROR: SPI baud rate prescale error!\n", __FUNCTION__);
  77588. + return MV_OUT_OF_RANGE;
  77589. + }
  77590. +
  77591. + /* configure the Prescale */
  77592. + tempReg = MV_REG_READ(MV_SPI_IF_CONFIG_REG);
  77593. + tempReg = ((tempReg & ~MV_SPI_CLK_PRESCALE_MASK) | (bestPrescaleIndx + 0x12));
  77594. + MV_REG_WRITE(MV_SPI_IF_CONFIG_REG, tempReg);
  77595. +
  77596. + return MV_OK;
  77597. +}
  77598. +
  77599. +/*******************************************************************************
  77600. +* mvSpiCsAssert - Assert the Chip Select pin indicating a new transfer
  77601. +*
  77602. +* DESCRIPTION:
  77603. +* Assert The chip select - used to select an external SPI device
  77604. +*
  77605. +* INPUT:
  77606. +* None.
  77607. +*
  77608. +* OUTPUT:
  77609. +* None.
  77610. +*
  77611. +* RETURN:
  77612. +* Success or Error code.
  77613. +*
  77614. +********************************************************************************/
  77615. +MV_VOID mvSpiCsAssert(MV_VOID)
  77616. +{
  77617. + /* For devices in which the SPI is muxed on the MPP with other interfaces*/
  77618. + mvMPPConfigToSPI();
  77619. + mvOsUDelay(1);
  77620. + MV_REG_BIT_SET(MV_SPI_IF_CTRL_REG, MV_SPI_CS_ENABLE_MASK);
  77621. +}
  77622. +
  77623. +/*******************************************************************************
  77624. +* mvSpiCsDeassert - DeAssert the Chip Select pin indicating the end of a
  77625. +* SPI transfer sequence
  77626. +*
  77627. +* DESCRIPTION:
  77628. +* DeAssert the chip select pin
  77629. +*
  77630. +* INPUT:
  77631. +* None.
  77632. +*
  77633. +* OUTPUT:
  77634. +* None.
  77635. +*
  77636. +* RETURN:
  77637. +* Success or Error code.
  77638. +*
  77639. +********************************************************************************/
  77640. +MV_VOID mvSpiCsDeassert(MV_VOID)
  77641. +{
  77642. + MV_REG_BIT_RESET(MV_SPI_IF_CTRL_REG, MV_SPI_CS_ENABLE_MASK);
  77643. +
  77644. + /* For devices in which the SPI is muxed on the MPP with other interfaces*/
  77645. + mvMPPConfigToDefault();
  77646. +}
  77647. +
  77648. +/*******************************************************************************
  77649. +* mvSpiRead - Read a buffer over the SPI interface
  77650. +*
  77651. +* DESCRIPTION:
  77652. +* Receive (read) a buffer over the SPI interface in 16bit chunks. If the
  77653. +* buffer size is odd, then the last chunk will be 8bits. Chip select is not
  77654. +* handled at this level.
  77655. +*
  77656. +* INPUT:
  77657. +* pRxBuff: Pointer to the buffer to hold the received data
  77658. +* buffSize: length of the pRxBuff
  77659. +*
  77660. +* OUTPUT:
  77661. +* pRxBuff: Pointer to the buffer with the received data
  77662. +*
  77663. +* RETURN:
  77664. +* Success or Error code.
  77665. +*
  77666. +*
  77667. +*******************************************************************************/
  77668. +MV_STATUS mvSpiRead (MV_U8* pRxBuff, MV_U32 buffSize)
  77669. +{
  77670. + MV_STATUS ret;
  77671. + MV_U32 bytesLeft = buffSize;
  77672. + MV_U16* rxPtr = (MV_U16*)pRxBuff;
  77673. +
  77674. + /* check for null parameters */
  77675. + if (pRxBuff == NULL)
  77676. + {
  77677. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  77678. + return MV_BAD_PARAM;
  77679. + }
  77680. +
  77681. + /* Check that the buffer pointer and the buffer size are 16bit aligned */
  77682. + if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pRxBuff & 1) == 0))
  77683. + {
  77684. + /* Verify that the SPI mode is in 16bit mode */
  77685. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  77686. +
  77687. + /* TX/RX as long we have complete 16bit chunks */
  77688. + while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)
  77689. + {
  77690. + /* Transmitted and wait for the transfer to be completed */
  77691. + if ((ret = mvSpi16bitDataTxRx(MV_SPI_DUMMY_WRITE_16BITS, rxPtr)) != MV_OK)
  77692. + return ret;
  77693. +
  77694. + /* increment the pointers */
  77695. + rxPtr++;
  77696. + bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;
  77697. + }
  77698. +
  77699. + }
  77700. + else
  77701. + {
  77702. + /* Verify that the SPI mode is in 8bit mode */
  77703. + MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  77704. +
  77705. + /* TX/RX in 8bit chanks */
  77706. + while (bytesLeft > 0)
  77707. + {
  77708. + /* Transmitted and wait for the transfer to be completed */
  77709. + if ((ret = mvSpi8bitDataTxRx(MV_SPI_DUMMY_WRITE_8BITS, pRxBuff)) != MV_OK)
  77710. + return ret;
  77711. + /* increment the pointers */
  77712. + pRxBuff++;
  77713. + bytesLeft--;
  77714. + }
  77715. + }
  77716. +
  77717. + return MV_OK;
  77718. +}
  77719. +
  77720. +/*******************************************************************************
  77721. +* mvSpiWrite - Transmit a buffer over the SPI interface
  77722. +*
  77723. +* DESCRIPTION:
  77724. +* Transmit a buffer over the SPI interface in 16bit chunks. If the
  77725. +* buffer size is odd, then the last chunk will be 8bits. No chip select
  77726. +* action is taken.
  77727. +*
  77728. +* INPUT:
  77729. +* pTxBuff: Pointer to the buffer holding the TX data
  77730. +* buffSize: length of the pTxBuff
  77731. +*
  77732. +* OUTPUT:
  77733. +* None.
  77734. +*
  77735. +* RETURN:
  77736. +* Success or Error code.
  77737. +*
  77738. +*
  77739. +*******************************************************************************/
  77740. +MV_STATUS mvSpiWrite(MV_U8* pTxBuff, MV_U32 buffSize)
  77741. +{
  77742. + MV_STATUS ret;
  77743. + MV_U32 bytesLeft = buffSize;
  77744. + MV_U16* txPtr = (MV_U16*)pTxBuff;
  77745. +
  77746. + /* check for null parameters */
  77747. + if (pTxBuff == NULL)
  77748. + {
  77749. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  77750. + return MV_BAD_PARAM;
  77751. + }
  77752. +
  77753. + /* Check that the buffer pointer and the buffer size are 16bit aligned */
  77754. + if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pTxBuff & 1) == 0))
  77755. + {
  77756. + /* Verify that the SPI mode is in 16bit mode */
  77757. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  77758. +
  77759. + /* TX/RX as long we have complete 16bit chunks */
  77760. + while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)
  77761. + {
  77762. + /* Transmitted and wait for the transfer to be completed */
  77763. + if ((ret = mvSpi16bitDataTxRx(*txPtr, NULL)) != MV_OK)
  77764. + return ret;
  77765. +
  77766. + /* increment the pointers */
  77767. + txPtr++;
  77768. + bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;
  77769. + }
  77770. + }
  77771. + else
  77772. + {
  77773. +
  77774. + /* Verify that the SPI mode is in 8bit mode */
  77775. + MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  77776. +
  77777. + /* TX/RX in 8bit chanks */
  77778. + while (bytesLeft > 0)
  77779. + {
  77780. + /* Transmitted and wait for the transfer to be completed */
  77781. + if ((ret = mvSpi8bitDataTxRx(*pTxBuff, NULL)) != MV_OK)
  77782. + return ret;
  77783. +
  77784. + /* increment the pointers */
  77785. + pTxBuff++;
  77786. + bytesLeft--;
  77787. + }
  77788. + }
  77789. +
  77790. + return MV_OK;
  77791. +}
  77792. +
  77793. +
  77794. +/*******************************************************************************
  77795. +* mvSpiReadWrite - Read and Write a buffer simultanuosely
  77796. +*
  77797. +* DESCRIPTION:
  77798. +* Transmit and receive a buffer over the SPI in 16bit chunks. If the
  77799. +* buffer size is odd, then the last chunk will be 8bits. The SPI chip
  77800. +* select is not handled implicitely.
  77801. +*
  77802. +* INPUT:
  77803. +* pRxBuff: Pointer to the buffer to write the RX info in
  77804. +* pTxBuff: Pointer to the buffer holding the TX info
  77805. +* buffSize: length of both the pTxBuff and pRxBuff
  77806. +*
  77807. +* OUTPUT:
  77808. +* pRxBuff: Pointer of the buffer holding the RX data
  77809. +*
  77810. +* RETURN:
  77811. +* Success or Error code.
  77812. +*
  77813. +*
  77814. +*******************************************************************************/
  77815. +MV_STATUS mvSpiReadWrite(MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize)
  77816. +{
  77817. + MV_STATUS ret;
  77818. + MV_U32 bytesLeft = buffSize;
  77819. + MV_U16* txPtr = (MV_U16*)pTxBuff;
  77820. + MV_U16* rxPtr = (MV_U16*)pRxBuff;
  77821. +
  77822. + /* check for null parameters */
  77823. + if ((pRxBuff == NULL) || (pTxBuff == NULL))
  77824. + {
  77825. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  77826. + return MV_BAD_PARAM;
  77827. + }
  77828. +
  77829. + /* Check that the buffer pointer and the buffer size are 16bit aligned */
  77830. + if ((((MV_U32)buffSize & 1) == 0) && (((MV_U32)pTxBuff & 1) == 0) && (((MV_U32)pRxBuff & 1) == 0))
  77831. + {
  77832. + /* Verify that the SPI mode is in 16bit mode */
  77833. + MV_REG_BIT_SET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  77834. +
  77835. + /* TX/RX as long we have complete 16bit chunks */
  77836. + while (bytesLeft >= MV_SPI_16_BIT_CHUNK_SIZE)
  77837. + {
  77838. + /* Transmitted and wait for the transfer to be completed */
  77839. + if ((ret = mvSpi16bitDataTxRx(*txPtr, rxPtr)) != MV_OK)
  77840. + return ret;
  77841. +
  77842. + /* increment the pointers */
  77843. + txPtr++;
  77844. + rxPtr++;
  77845. + bytesLeft -= MV_SPI_16_BIT_CHUNK_SIZE;
  77846. + }
  77847. + }
  77848. + else
  77849. + {
  77850. + /* Verify that the SPI mode is in 8bit mode */
  77851. + MV_REG_BIT_RESET(MV_SPI_IF_CONFIG_REG, MV_SPI_BYTE_LENGTH_MASK);
  77852. +
  77853. + /* TX/RX in 8bit chanks */
  77854. + while (bytesLeft > 0)
  77855. + {
  77856. + /* Transmitted and wait for the transfer to be completed */
  77857. + if ( (ret = mvSpi8bitDataTxRx(*pTxBuff, pRxBuff) ) != MV_OK)
  77858. + return ret;
  77859. + pRxBuff++;
  77860. + pTxBuff++;
  77861. + bytesLeft--;
  77862. + }
  77863. + }
  77864. +
  77865. + return MV_OK;
  77866. +}
  77867. +
  77868. +
  77869. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h
  77870. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h 1970-01-01 01:00:00.000000000 +0100
  77871. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpi.h 2011-08-01 14:38:19.000000000 +0200
  77872. @@ -0,0 +1,94 @@
  77873. +/*******************************************************************************
  77874. +Copyright (C) Marvell International Ltd. and its affiliates
  77875. +
  77876. +This software file (the "File") is owned and distributed by Marvell
  77877. +International Ltd. and/or its affiliates ("Marvell") under the following
  77878. +alternative licensing terms. Once you have made an election to distribute the
  77879. +File under one of the following license alternatives, please (i) delete this
  77880. +introductory statement regarding license alternatives, (ii) delete the two
  77881. +license alternatives that you have not elected to use and (iii) preserve the
  77882. +Marvell copyright notice above.
  77883. +
  77884. +********************************************************************************
  77885. +Marvell Commercial License Option
  77886. +
  77887. +If you received this File from Marvell and you have entered into a commercial
  77888. +license agreement (a "Commercial License") with Marvell, the File is licensed
  77889. +to you under the terms of the applicable Commercial License.
  77890. +
  77891. +********************************************************************************
  77892. +Marvell GPL License Option
  77893. +
  77894. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77895. +modify this File in accordance with the terms and conditions of the General
  77896. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  77897. +available along with the File in the license.txt file or by writing to the Free
  77898. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  77899. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  77900. +
  77901. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  77902. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  77903. +DISCLAIMED. The GPL License provides additional details about this warranty
  77904. +disclaimer.
  77905. +********************************************************************************
  77906. +Marvell BSD License Option
  77907. +
  77908. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77909. +modify this File under the following licensing terms.
  77910. +Redistribution and use in source and binary forms, with or without modification,
  77911. +are permitted provided that the following conditions are met:
  77912. +
  77913. + * Redistributions of source code must retain the above copyright notice,
  77914. + this list of conditions and the following disclaimer.
  77915. +
  77916. + * Redistributions in binary form must reproduce the above copyright
  77917. + notice, this list of conditions and the following disclaimer in the
  77918. + documentation and/or other materials provided with the distribution.
  77919. +
  77920. + * Neither the name of Marvell nor the names of its contributors may be
  77921. + used to endorse or promote products derived from this software without
  77922. + specific prior written permission.
  77923. +
  77924. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  77925. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  77926. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  77927. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  77928. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  77929. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  77930. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  77931. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  77932. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  77933. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  77934. +
  77935. +*******************************************************************************/
  77936. +
  77937. +#ifndef __INCmvSpihH
  77938. +#define __INCmvSpihH
  77939. +
  77940. +#include "mvCommon.h"
  77941. +#include "mvOs.h"
  77942. +#include "ctrlEnv/mvCtrlEnvSpec.h"
  77943. +
  77944. +/* Function Prototypes */
  77945. +/* Init */
  77946. +MV_STATUS mvSpiInit (MV_U32 serialBaudRate);
  77947. +
  77948. +/* Set the Frequency of the Spi clock */
  77949. +MV_STATUS mvSpiBaudRateSet(MV_U32 serialBaudRate);
  77950. +
  77951. +/* Assert the SPI chip select */
  77952. +MV_VOID mvSpiCsAssert (MV_VOID);
  77953. +
  77954. +/* De-assert the SPI chip select */
  77955. +MV_VOID mvSpiCsDeassert (MV_VOID);
  77956. +
  77957. +/* Simultanuous Read and write */
  77958. +MV_STATUS mvSpiReadWrite (MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize);
  77959. +
  77960. +/* serialize a buffer on the TX line - Rx is ignored */
  77961. +MV_STATUS mvSpiWrite (MV_U8* pTxBuff, MV_U32 buffSize);
  77962. +
  77963. +/* read from the RX line by writing dummy values to the TX line */
  77964. +MV_STATUS mvSpiRead (MV_U8* pRxBuff, MV_U32 buffSize);
  77965. +
  77966. +#endif /* __INCmvSpihH */
  77967. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c
  77968. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c 1970-01-01 01:00:00.000000000 +0100
  77969. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.c 2011-08-01 14:38:19.000000000 +0200
  77970. @@ -0,0 +1,249 @@
  77971. +/*******************************************************************************
  77972. +Copyright (C) Marvell International Ltd. and its affiliates
  77973. +
  77974. +This software file (the "File") is owned and distributed by Marvell
  77975. +International Ltd. and/or its affiliates ("Marvell") under the following
  77976. +alternative licensing terms. Once you have made an election to distribute the
  77977. +File under one of the following license alternatives, please (i) delete this
  77978. +introductory statement regarding license alternatives, (ii) delete the two
  77979. +license alternatives that you have not elected to use and (iii) preserve the
  77980. +Marvell copyright notice above.
  77981. +
  77982. +********************************************************************************
  77983. +Marvell Commercial License Option
  77984. +
  77985. +If you received this File from Marvell and you have entered into a commercial
  77986. +license agreement (a "Commercial License") with Marvell, the File is licensed
  77987. +to you under the terms of the applicable Commercial License.
  77988. +
  77989. +********************************************************************************
  77990. +Marvell GPL License Option
  77991. +
  77992. +If you received this File from Marvell, you may opt to use, redistribute and/or
  77993. +modify this File in accordance with the terms and conditions of the General
  77994. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  77995. +available along with the File in the license.txt file or by writing to the Free
  77996. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  77997. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  77998. +
  77999. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  78000. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  78001. +DISCLAIMED. The GPL License provides additional details about this warranty
  78002. +disclaimer.
  78003. +********************************************************************************
  78004. +Marvell BSD License Option
  78005. +
  78006. +If you received this File from Marvell, you may opt to use, redistribute and/or
  78007. +modify this File under the following licensing terms.
  78008. +Redistribution and use in source and binary forms, with or without modification,
  78009. +are permitted provided that the following conditions are met:
  78010. +
  78011. + * Redistributions of source code must retain the above copyright notice,
  78012. + this list of conditions and the following disclaimer.
  78013. +
  78014. + * Redistributions in binary form must reproduce the above copyright
  78015. + notice, this list of conditions and the following disclaimer in the
  78016. + documentation and/or other materials provided with the distribution.
  78017. +
  78018. + * Neither the name of Marvell nor the names of its contributors may be
  78019. + used to endorse or promote products derived from this software without
  78020. + specific prior written permission.
  78021. +
  78022. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  78023. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  78024. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  78025. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  78026. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  78027. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  78028. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  78029. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  78030. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  78031. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  78032. +
  78033. +*******************************************************************************/
  78034. +
  78035. +#include "spi/mvSpi.h"
  78036. +#include "spi/mvSpiSpec.h"
  78037. +
  78038. +/*#define MV_DEBUG*/
  78039. +#ifdef MV_DEBUG
  78040. +#define DB(x) x
  78041. +#else
  78042. +#define DB(x)
  78043. +#endif
  78044. +
  78045. +
  78046. +/*******************************************************************************
  78047. +* mvSpiReadAndWrite - Read and Write a buffer simultanuousely
  78048. +*
  78049. +* DESCRIPTION:
  78050. +* Transmit and receive a buffer over the SPI in 16bit chunks. If the
  78051. +* buffer size is odd, then the last chunk will be 8bits.
  78052. +*
  78053. +* INPUT:
  78054. +* pRxBuff: Pointer to the buffer to write the RX info in
  78055. +* pTxBuff: Pointer to the buffer holding the TX info
  78056. +* buffSize: length of both the pTxBuff and pRxBuff
  78057. +*
  78058. +* OUTPUT:
  78059. +* pRxBuff: Pointer of the buffer holding the RX data
  78060. +*
  78061. +* RETURN:
  78062. +* Success or Error code.
  78063. +*
  78064. +*
  78065. +*******************************************************************************/
  78066. +MV_STATUS mvSpiReadAndWrite(MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize)
  78067. +{
  78068. + MV_STATUS ret;
  78069. +
  78070. + /* check for null parameters */
  78071. + if ((pRxBuff == NULL) || (pTxBuff == NULL) || (buffSize == 0))
  78072. + {
  78073. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  78074. + return MV_BAD_PARAM;
  78075. + }
  78076. +
  78077. + /* First assert the chip select */
  78078. + mvSpiCsAssert();
  78079. +
  78080. + ret = mvSpiReadWrite(pRxBuff, pTxBuff, buffSize);
  78081. +
  78082. + /* Finally deassert the chip select */
  78083. + mvSpiCsDeassert();
  78084. +
  78085. + return ret;
  78086. +}
  78087. +
  78088. +/*******************************************************************************
  78089. +* mvSpiWriteThenWrite - Serialize a command followed by the data over the TX line
  78090. +*
  78091. +* DESCRIPTION:
  78092. +* Assert the chip select line. Transmit the command buffer followed by
  78093. +* the data buffer. Then deassert the CS line.
  78094. +*
  78095. +* INPUT:
  78096. +* pCmndBuff: Pointer to the command buffer to transmit
  78097. +* cmndSize: length of the command size
  78098. +* pTxDataBuff: Pointer to the data buffer to transmit
  78099. +* txDataSize: length of the data buffer
  78100. +*
  78101. +* OUTPUT:
  78102. +* None.
  78103. +*
  78104. +* RETURN:
  78105. +* Success or Error code.
  78106. +*
  78107. +*
  78108. +*******************************************************************************/
  78109. +MV_STATUS mvSpiWriteThenWrite (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pTxDataBuff,
  78110. + MV_U32 txDataSize)
  78111. +{
  78112. + MV_STATUS ret = MV_OK, tempRet;
  78113. +
  78114. + /* check for null parameters */
  78115. +#ifndef CONFIG_MARVELL
  78116. + if(NULL == pTxDataBuff)
  78117. + {
  78118. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  78119. + return MV_BAD_PARAM;
  78120. + }
  78121. +#endif
  78122. +
  78123. + if (pCmndBuff == NULL)
  78124. + {
  78125. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  78126. + return MV_BAD_PARAM;
  78127. + }
  78128. +
  78129. + /* First assert the chip select */
  78130. + mvSpiCsAssert();
  78131. +
  78132. + /* first write the command */
  78133. + if ((cmndSize) && (pCmndBuff != NULL))
  78134. + {
  78135. + if ((tempRet = mvSpiWrite(pCmndBuff, cmndSize)) != MV_OK)
  78136. + ret = tempRet;
  78137. + }
  78138. +
  78139. + /* Then write the data buffer */
  78140. +#ifndef CONFIG_MARVELL
  78141. + if (txDataSize)
  78142. +#else
  78143. + if ((txDataSize) && (pTxDataBuff != NULL))
  78144. +#endif
  78145. + {
  78146. + if ((tempRet = mvSpiWrite(pTxDataBuff, txDataSize)) != MV_OK)
  78147. + ret = tempRet;
  78148. + }
  78149. +
  78150. + /* Finally deassert the chip select */
  78151. + mvSpiCsDeassert();
  78152. +
  78153. + return ret;
  78154. +}
  78155. +
  78156. +/*******************************************************************************
  78157. +* mvSpiWriteThenRead - Serialize a command then read a data buffer
  78158. +*
  78159. +* DESCRIPTION:
  78160. +* Assert the chip select line. Transmit the command buffer then read
  78161. +* the data buffer. Then deassert the CS line.
  78162. +*
  78163. +* INPUT:
  78164. +* pCmndBuff: Pointer to the command buffer to transmit
  78165. +* cmndSize: length of the command size
  78166. +* pRxDataBuff: Pointer to the buffer to read the data in
  78167. +* txDataSize: length of the data buffer
  78168. +*
  78169. +* OUTPUT:
  78170. +* pRxDataBuff: Pointer to the buffer holding the data
  78171. +*
  78172. +* RETURN:
  78173. +* Success or Error code.
  78174. +*
  78175. +*
  78176. +*******************************************************************************/
  78177. +MV_STATUS mvSpiWriteThenRead (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pRxDataBuff,
  78178. + MV_U32 rxDataSize,MV_U32 dummyBytesToRead)
  78179. +{
  78180. + MV_STATUS ret = MV_OK, tempRet;
  78181. + MV_U8 dummyByte;
  78182. +
  78183. + /* check for null parameters */
  78184. + if ((pCmndBuff == NULL) && (pRxDataBuff == NULL))
  78185. + {
  78186. + mvOsPrintf("%s ERROR: Null pointer parameter!\n", __FUNCTION__);
  78187. + return MV_BAD_PARAM;
  78188. + }
  78189. +
  78190. + /* First assert the chip select */
  78191. + mvSpiCsAssert();
  78192. +
  78193. + /* first write the command */
  78194. + if ((cmndSize) && (pCmndBuff != NULL))
  78195. + {
  78196. + if ((tempRet = mvSpiWrite(pCmndBuff, cmndSize)) != MV_OK)
  78197. + ret = tempRet;
  78198. + }
  78199. +
  78200. + /* Read dummy bytes before real data. */
  78201. + while(dummyBytesToRead)
  78202. + {
  78203. + mvSpiRead(&dummyByte,1);
  78204. + dummyBytesToRead--;
  78205. + }
  78206. +
  78207. + /* Then write the data buffer */
  78208. + if ((rxDataSize) && (pRxDataBuff != NULL))
  78209. + {
  78210. + if ((tempRet = mvSpiRead(pRxDataBuff, rxDataSize)) != MV_OK)
  78211. + ret = tempRet;
  78212. + }
  78213. +
  78214. + /* Finally deassert the chip select */
  78215. + mvSpiCsDeassert();
  78216. +
  78217. + return ret;
  78218. +}
  78219. +
  78220. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h
  78221. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h 1970-01-01 01:00:00.000000000 +0100
  78222. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiCmnd.h 2011-08-01 14:38:19.000000000 +0200
  78223. @@ -0,0 +1,82 @@
  78224. +/*******************************************************************************
  78225. +Copyright (C) Marvell International Ltd. and its affiliates
  78226. +
  78227. +This software file (the "File") is owned and distributed by Marvell
  78228. +International Ltd. and/or its affiliates ("Marvell") under the following
  78229. +alternative licensing terms. Once you have made an election to distribute the
  78230. +File under one of the following license alternatives, please (i) delete this
  78231. +introductory statement regarding license alternatives, (ii) delete the two
  78232. +license alternatives that you have not elected to use and (iii) preserve the
  78233. +Marvell copyright notice above.
  78234. +
  78235. +********************************************************************************
  78236. +Marvell Commercial License Option
  78237. +
  78238. +If you received this File from Marvell and you have entered into a commercial
  78239. +license agreement (a "Commercial License") with Marvell, the File is licensed
  78240. +to you under the terms of the applicable Commercial License.
  78241. +
  78242. +********************************************************************************
  78243. +Marvell GPL License Option
  78244. +
  78245. +If you received this File from Marvell, you may opt to use, redistribute and/or
  78246. +modify this File in accordance with the terms and conditions of the General
  78247. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  78248. +available along with the File in the license.txt file or by writing to the Free
  78249. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  78250. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  78251. +
  78252. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  78253. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  78254. +DISCLAIMED. The GPL License provides additional details about this warranty
  78255. +disclaimer.
  78256. +********************************************************************************
  78257. +Marvell BSD License Option
  78258. +
  78259. +If you received this File from Marvell, you may opt to use, redistribute and/or
  78260. +modify this File under the following licensing terms.
  78261. +Redistribution and use in source and binary forms, with or without modification,
  78262. +are permitted provided that the following conditions are met:
  78263. +
  78264. + * Redistributions of source code must retain the above copyright notice,
  78265. + this list of conditions and the following disclaimer.
  78266. +
  78267. + * Redistributions in binary form must reproduce the above copyright
  78268. + notice, this list of conditions and the following disclaimer in the
  78269. + documentation and/or other materials provided with the distribution.
  78270. +
  78271. + * Neither the name of Marvell nor the names of its contributors may be
  78272. + used to endorse or promote products derived from this software without
  78273. + specific prior written permission.
  78274. +
  78275. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  78276. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  78277. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  78278. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  78279. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  78280. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  78281. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  78282. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  78283. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  78284. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  78285. +
  78286. +*******************************************************************************/
  78287. +
  78288. +#ifndef __INCmvSpiCmndhH
  78289. +#define __INCmvSpiCmndhH
  78290. +
  78291. +#include "mvTypes.h"
  78292. +
  78293. +/* Function Prototypes */
  78294. +
  78295. +/* Simultanuous Read and write */
  78296. +MV_STATUS mvSpiReadAndWrite (MV_U8* pRxBuff, MV_U8* pTxBuff, MV_U32 buffSize);
  78297. +
  78298. +/* write command - write a command and then write data */
  78299. +MV_STATUS mvSpiWriteThenWrite (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pTxDataBuff, MV_U32 txDataSize);
  78300. +
  78301. +/* read command - write a command and then read data by writing dummy data */
  78302. +MV_STATUS mvSpiWriteThenRead (MV_U8* pCmndBuff, MV_U32 cmndSize, MV_U8* pRxDataBuff,
  78303. + MV_U32 rxDataSize,MV_U32 dummyBytesToRead);
  78304. +
  78305. +#endif /* __INCmvSpiCmndhH */
  78306. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h
  78307. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h 1970-01-01 01:00:00.000000000 +0100
  78308. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/spi/mvSpiSpec.h 2011-08-01 14:38:19.000000000 +0200
  78309. @@ -0,0 +1,98 @@
  78310. +/*******************************************************************************
  78311. +Copyright (C) Marvell International Ltd. and its affiliates
  78312. +
  78313. +This software file (the "File") is owned and distributed by Marvell
  78314. +International Ltd. and/or its affiliates ("Marvell") under the following
  78315. +alternative licensing terms. Once you have made an election to distribute the
  78316. +File under one of the following license alternatives, please (i) delete this
  78317. +introductory statement regarding license alternatives, (ii) delete the two
  78318. +license alternatives that you have not elected to use and (iii) preserve the
  78319. +Marvell copyright notice above.
  78320. +
  78321. +********************************************************************************
  78322. +Marvell Commercial License Option
  78323. +
  78324. +If you received this File from Marvell and you have entered into a commercial
  78325. +license agreement (a "Commercial License") with Marvell, the File is licensed
  78326. +to you under the terms of the applicable Commercial License.
  78327. +
  78328. +********************************************************************************
  78329. +Marvell GPL License Option
  78330. +
  78331. +If you received this File from Marvell, you may opt to use, redistribute and/or
  78332. +modify this File in accordance with the terms and conditions of the General
  78333. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  78334. +available along with the File in the license.txt file or by writing to the Free
  78335. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  78336. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  78337. +
  78338. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  78339. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  78340. +DISCLAIMED. The GPL License provides additional details about this warranty
  78341. +disclaimer.
  78342. +********************************************************************************
  78343. +Marvell BSD License Option
  78344. +
  78345. +If you received this File from Marvell, you may opt to use, redistribute and/or
  78346. +modify this File under the following licensing terms.
  78347. +Redistribution and use in source and binary forms, with or without modification,
  78348. +are permitted provided that the following conditions are met:
  78349. +
  78350. + * Redistributions of source code must retain the above copyright notice,
  78351. + this list of conditions and the following disclaimer.
  78352. +
  78353. + * Redistributions in binary form must reproduce the above copyright
  78354. + notice, this list of conditions and the following disclaimer in the
  78355. + documentation and/or other materials provided with the distribution.
  78356. +
  78357. + * Neither the name of Marvell nor the names of its contributors may be
  78358. + used to endorse or promote products derived from this software without
  78359. + specific prior written permission.
  78360. +
  78361. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  78362. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  78363. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  78364. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  78365. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  78366. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  78367. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  78368. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  78369. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  78370. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  78371. +
  78372. +*******************************************************************************/
  78373. +
  78374. +#ifndef __INCmvSpiSpecH
  78375. +#define __INCmvSpiSpecH
  78376. +
  78377. +/* Constants */
  78378. +#define MV_SPI_WAIT_RDY_MAX_LOOP 100000
  78379. +#define MV_SPI_16_BIT_CHUNK_SIZE 2
  78380. +#define MV_SPI_DUMMY_WRITE_16BITS 0xFFFF
  78381. +#define MV_SPI_DUMMY_WRITE_8BITS 0xFF
  78382. +
  78383. +/* Marvell Flash Device Controller Registers */
  78384. +#define MV_SPI_CTRLR_OFST 0x10600
  78385. +#define MV_SPI_IF_CTRL_REG (MV_SPI_CTRLR_OFST + 0x00)
  78386. +#define MV_SPI_IF_CONFIG_REG (MV_SPI_CTRLR_OFST + 0x04)
  78387. +#define MV_SPI_DATA_OUT_REG (MV_SPI_CTRLR_OFST + 0x08)
  78388. +#define MV_SPI_DATA_IN_REG (MV_SPI_CTRLR_OFST + 0x0c)
  78389. +#define MV_SPI_INT_CAUSE_REG (MV_SPI_CTRLR_OFST + 0x10)
  78390. +#define MV_SPI_INT_CAUSE_MASK_REG (MV_SPI_CTRLR_OFST + 0x14)
  78391. +
  78392. +/* Serial Memory Interface Control Register Masks */
  78393. +#define MV_SPI_CS_ENABLE_OFFSET 0 /* bit 0 */
  78394. +#define MV_SPI_MEMORY_READY_OFFSET 1 /* bit 1 */
  78395. +#define MV_SPI_CS_ENABLE_MASK (0x1 << MV_SPI_CS_ENABLE_OFFSET)
  78396. +#define MV_SPI_MEMORY_READY_MASK (0x1 << MV_SPI_MEMORY_READY_OFFSET)
  78397. +
  78398. +/* Serial Memory Interface Configuration Register Masks */
  78399. +#define MV_SPI_CLK_PRESCALE_OFFSET 0 /* bit 0-4 */
  78400. +#define MV_SPI_BYTE_LENGTH_OFFSET 5 /* bit 5 */
  78401. +#define MV_SPI_ADDRESS_BURST_LENGTH_OFFSET 8 /* bit 8-9 */
  78402. +#define MV_SPI_CLK_PRESCALE_MASK (0x1F << MV_SPI_CLK_PRESCALE_OFFSET)
  78403. +#define MV_SPI_BYTE_LENGTH_MASK (0x1 << MV_SPI_BYTE_LENGTH_OFFSET)
  78404. +#define MV_SPI_ADDRESS_BURST_LENGTH_MASK (0x3 << MV_SPI_ADDRESS_BURST_LENGTH_OFFSET)
  78405. +
  78406. +#endif /* __INCmvSpiSpecH */
  78407. +
  78408. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c
  78409. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c 1970-01-01 01:00:00.000000000 +0100
  78410. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.c 2011-08-01 14:38:19.000000000 +0200
  78411. @@ -0,0 +1,1023 @@
  78412. +/*******************************************************************************
  78413. +Copyright (C) Marvell International Ltd. and its affiliates
  78414. +
  78415. +This software file (the "File") is owned and distributed by Marvell
  78416. +International Ltd. and/or its affiliates ("Marvell") under the following
  78417. +alternative licensing terms. Once you have made an election to distribute the
  78418. +File under one of the following license alternatives, please (i) delete this
  78419. +introductory statement regarding license alternatives, (ii) delete the two
  78420. +license alternatives that you have not elected to use and (iii) preserve the
  78421. +Marvell copyright notice above.
  78422. +
  78423. +********************************************************************************
  78424. +Marvell Commercial License Option
  78425. +
  78426. +If you received this File from Marvell and you have entered into a commercial
  78427. +license agreement (a "Commercial License") with Marvell, the File is licensed
  78428. +to you under the terms of the applicable Commercial License.
  78429. +
  78430. +********************************************************************************
  78431. +Marvell GPL License Option
  78432. +
  78433. +If you received this File from Marvell, you may opt to use, redistribute and/or
  78434. +modify this File in accordance with the terms and conditions of the General
  78435. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  78436. +available along with the File in the license.txt file or by writing to the Free
  78437. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  78438. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  78439. +
  78440. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  78441. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  78442. +DISCLAIMED. The GPL License provides additional details about this warranty
  78443. +disclaimer.
  78444. +********************************************************************************
  78445. +Marvell BSD License Option
  78446. +
  78447. +If you received this File from Marvell, you may opt to use, redistribute and/or
  78448. +modify this File under the following licensing terms.
  78449. +Redistribution and use in source and binary forms, with or without modification,
  78450. +are permitted provided that the following conditions are met:
  78451. +
  78452. + * Redistributions of source code must retain the above copyright notice,
  78453. + this list of conditions and the following disclaimer.
  78454. +
  78455. + * Redistributions in binary form must reproduce the above copyright
  78456. + notice, this list of conditions and the following disclaimer in the
  78457. + documentation and/or other materials provided with the distribution.
  78458. +
  78459. + * Neither the name of Marvell nor the names of its contributors may be
  78460. + used to endorse or promote products derived from this software without
  78461. + specific prior written permission.
  78462. +
  78463. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  78464. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  78465. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  78466. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  78467. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  78468. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  78469. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  78470. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  78471. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  78472. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  78473. +
  78474. +*******************************************************************************/
  78475. +
  78476. +
  78477. +#include "mvTwsi.h"
  78478. +#include "mvTwsiSpec.h"
  78479. +#include "cpu/mvCpu.h"
  78480. +
  78481. +
  78482. +/*#define MV_DEBUG*/
  78483. +#ifdef MV_DEBUG
  78484. +#define DB(x) x
  78485. +#else
  78486. +#define DB(x)
  78487. +#endif
  78488. +
  78489. +static MV_VOID twsiIntFlgClr(MV_U8 chanNum);
  78490. +static MV_BOOL twsiMainIntGet(MV_U8 chanNum);
  78491. +static MV_VOID twsiAckBitSet(MV_U8 chanNum);
  78492. +static MV_U32 twsiStsGet(MV_U8 chanNum);
  78493. +static MV_VOID twsiReset(MV_U8 chanNum);
  78494. +static MV_STATUS twsiAddr7BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command);
  78495. +static MV_STATUS twsiAddr10BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command);
  78496. +static MV_STATUS twsiDataTransmit(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize);
  78497. +static MV_STATUS twsiDataReceive(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize);
  78498. +static MV_STATUS twsiTargetOffsSet(MV_U8 chanNum, MV_U32 offset,MV_BOOL moreThen256);
  78499. +
  78500. +
  78501. +static MV_BOOL twsiTimeoutChk(MV_U32 timeout, const MV_8 *pString)
  78502. +{
  78503. + if(timeout >= TWSI_TIMEOUT_VALUE)
  78504. + {
  78505. + DB(mvOsPrintf("%s",pString));
  78506. + return MV_TRUE;
  78507. + }
  78508. + return MV_FALSE;
  78509. +
  78510. +}
  78511. +/*******************************************************************************
  78512. +* mvTwsiStartBitSet - Set start bit on the bus
  78513. +*
  78514. +* DESCRIPTION:
  78515. +* This routine sets the start bit on the TWSI bus.
  78516. +* The routine first checks for interrupt flag condition, then it sets
  78517. +* the start bit in the TWSI Control register.
  78518. +* If the interrupt flag condition check previously was set, the function
  78519. +* will clear it.
  78520. +* The function then wait for the start bit to be cleared by the HW.
  78521. +* Then it waits for the interrupt flag to be set and eventually, the
  78522. +* TWSI status is checked to be 0x8 or 0x10(repeated start bit).
  78523. +*
  78524. +* INPUT:
  78525. +* chanNum - TWSI channel.
  78526. +*
  78527. +* OUTPUT:
  78528. +* None.
  78529. +*
  78530. +* RETURN:
  78531. +* MV_OK is start bit was set successfuly on the bus.
  78532. +* MV_FAIL if interrupt flag was set before setting start bit.
  78533. +*
  78534. +*******************************************************************************/
  78535. +MV_STATUS mvTwsiStartBitSet(MV_U8 chanNum)
  78536. +{
  78537. + MV_BOOL isIntFlag = MV_FALSE;
  78538. + MV_U32 timeout, temp;
  78539. +
  78540. + DB(mvOsPrintf("TWSI: mvTwsiStartBitSet \n"));
  78541. + /* check Int flag */
  78542. + if(twsiMainIntGet(chanNum))
  78543. + isIntFlag = MV_TRUE;
  78544. + /* set start Bit */
  78545. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  78546. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_START_BIT);
  78547. +
  78548. + /* in case that the int flag was set before i.e. repeated start bit */
  78549. + if(isIntFlag){
  78550. + DB(mvOsPrintf("TWSI: mvTwsiStartBitSet repeated start Bit\n"));
  78551. + twsiIntFlgClr(chanNum);
  78552. + }
  78553. +
  78554. + /* wait for interrupt */
  78555. + timeout = 0;
  78556. + while(!twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  78557. +
  78558. + /* check for timeout */
  78559. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: mvTwsiStartBitSet ERROR - Start Clear bit TimeOut .\n"))
  78560. + return MV_TIMEOUT;
  78561. +
  78562. +
  78563. + /* check that start bit went down */
  78564. + if((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_START_BIT) != 0)
  78565. + {
  78566. + mvOsPrintf("TWSI: mvTwsiStartBitSet ERROR - start bit didn't went down\n");
  78567. + return MV_FAIL;
  78568. + }
  78569. +
  78570. + /* check the status */
  78571. + temp = twsiStsGet(chanNum);
  78572. + if(( temp != TWSI_START_CON_TRA ) && ( temp != TWSI_REPEATED_START_CON_TRA ))
  78573. + {
  78574. + mvOsPrintf("TWSI: mvTwsiStartBitSet ERROR - status %x after Set Start Bit. \n",temp);
  78575. + return MV_FAIL;
  78576. + }
  78577. +
  78578. + return MV_OK;
  78579. +
  78580. +}
  78581. +
  78582. +/*******************************************************************************
  78583. +* mvTwsiStopBitSet - Set stop bit on the bus
  78584. +*
  78585. +* DESCRIPTION:
  78586. +* This routine set the stop bit on the TWSI bus.
  78587. +* The function then wait for the stop bit to be cleared by the HW.
  78588. +* Finally the function checks for status of 0xF8.
  78589. +*
  78590. +* INPUT:
  78591. +* chanNum - TWSI channel
  78592. +*
  78593. +* OUTPUT:
  78594. +* None.
  78595. +*
  78596. +* RETURN:
  78597. +* MV_TRUE is stop bit was set successfuly on the bus.
  78598. +*
  78599. +*******************************************************************************/
  78600. +MV_STATUS mvTwsiStopBitSet(MV_U8 chanNum)
  78601. +{
  78602. + MV_U32 timeout, temp;
  78603. +
  78604. + /* Generate stop bit */
  78605. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  78606. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_STOP_BIT);
  78607. +
  78608. + twsiIntFlgClr(chanNum);
  78609. +
  78610. + /* wait for stop bit to come down */
  78611. + timeout = 0;
  78612. + while( ((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_STOP_BIT) != 0) && (timeout++ < TWSI_TIMEOUT_VALUE));
  78613. +
  78614. + /* check for timeout */
  78615. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: mvTwsiStopBitSet ERROR - Stop bit TimeOut .\n"))
  78616. + return MV_TIMEOUT;
  78617. +
  78618. + /* check that the stop bit went down */
  78619. + if((MV_REG_READ(TWSI_CONTROL_REG(chanNum)) & TWSI_CONTROL_STOP_BIT) != 0)
  78620. + {
  78621. + mvOsPrintf("TWSI: mvTwsiStopBitSet ERROR - stop bit didn't went down. \n");
  78622. + return MV_FAIL;
  78623. + }
  78624. +
  78625. + /* check the status */
  78626. + temp = twsiStsGet(chanNum);
  78627. + if( temp != TWSI_NO_REL_STS_INT_FLAG_IS_KEPT_0){
  78628. + mvOsPrintf("TWSI: mvTwsiStopBitSet ERROR - status %x after Stop Bit. \n", temp);
  78629. + return MV_FAIL;
  78630. + }
  78631. +
  78632. + return MV_OK;
  78633. +}
  78634. +
  78635. +/*******************************************************************************
  78636. +* twsiMainIntGet - Get twsi bit from main Interrupt cause.
  78637. +*
  78638. +* DESCRIPTION:
  78639. +* This routine returns the twsi interrupt flag value.
  78640. +*
  78641. +* INPUT:
  78642. +* None.
  78643. +*
  78644. +* OUTPUT:
  78645. +* None.
  78646. +*
  78647. +* RETURN:
  78648. +* MV_TRUE is interrupt flag is set, MV_FALSE otherwise.
  78649. +*
  78650. +*******************************************************************************/
  78651. +static MV_BOOL twsiMainIntGet(MV_U8 chanNum)
  78652. +{
  78653. + MV_U32 temp;
  78654. +
  78655. + /* get the int flag bit */
  78656. +
  78657. + temp = MV_REG_READ(TWSI_CPU_MAIN_INT_CAUSE_REG);
  78658. + if (temp & (TWSI0_CPU_MAIN_INT_BIT << chanNum))
  78659. + return MV_TRUE;
  78660. +
  78661. + return MV_FALSE;
  78662. +}
  78663. +/*******************************************************************************
  78664. +* twsiIntFlgClr - Clear Interrupt flag.
  78665. +*
  78666. +* DESCRIPTION:
  78667. +* This routine clears the interrupt flag. It does NOT poll the interrupt
  78668. +* to make sure the clear. After clearing the interrupt, it waits for at
  78669. +* least 1 miliseconds.
  78670. +*
  78671. +* INPUT:
  78672. +* chanNum - TWSI channel
  78673. +*
  78674. +* OUTPUT:
  78675. +* None.
  78676. +*
  78677. +* RETURN:
  78678. +* None.
  78679. +*
  78680. +*******************************************************************************/
  78681. +static MV_VOID twsiIntFlgClr(MV_U8 chanNum)
  78682. +{
  78683. + MV_U32 temp;
  78684. +
  78685. + /* wait for 1 mili to prevent TWSI register write after write problems */
  78686. + mvOsDelay(1);
  78687. + /* clear the int flag bit */
  78688. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  78689. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum),temp & ~(TWSI_CONTROL_INT_FLAG_SET));
  78690. +
  78691. + /* wait for 1 mili sec for the clear to take effect */
  78692. + mvOsDelay(1);
  78693. +
  78694. + return;
  78695. +}
  78696. +
  78697. +
  78698. +/*******************************************************************************
  78699. +* twsiAckBitSet - Set acknowledge bit on the bus
  78700. +*
  78701. +* DESCRIPTION:
  78702. +* This routine set the acknowledge bit on the TWSI bus.
  78703. +*
  78704. +* INPUT:
  78705. +* None.
  78706. +*
  78707. +* OUTPUT:
  78708. +* None.
  78709. +*
  78710. +* RETURN:
  78711. +* None.
  78712. +*
  78713. +*******************************************************************************/
  78714. +static MV_VOID twsiAckBitSet(MV_U8 chanNum)
  78715. +{
  78716. + MV_U32 temp;
  78717. +
  78718. + /*Set the Ack bit */
  78719. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  78720. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp | TWSI_CONTROL_ACK);
  78721. +
  78722. + /* Add delay of 1ms */
  78723. + mvOsDelay(1);
  78724. + return;
  78725. +}
  78726. +
  78727. +
  78728. +/*******************************************************************************
  78729. +* twsiInit - Initialize TWSI interface
  78730. +*
  78731. +* DESCRIPTION:
  78732. +* This routine:
  78733. +* -Reset the TWSI.
  78734. +* -Initialize the TWSI clock baud rate according to given frequancy
  78735. +* parameter based on Tclk frequancy and enables TWSI slave.
  78736. +* -Set the ack bit.
  78737. +* -Assign the TWSI slave address according to the TWSI address Type.
  78738. +*
  78739. +*
  78740. +* INPUT:
  78741. +* chanNum - TWSI channel
  78742. +* frequancy - TWSI frequancy in KHz. (up to 100KHZ)
  78743. +*
  78744. +* OUTPUT:
  78745. +* None.
  78746. +*
  78747. +* RETURN:
  78748. +* Actual frequancy.
  78749. +*
  78750. +*******************************************************************************/
  78751. +MV_U32 mvTwsiInit(MV_U8 chanNum, MV_HZ frequancy, MV_U32 Tclk, MV_TWSI_ADDR *pTwsiAddr, MV_BOOL generalCallEnable)
  78752. +{
  78753. + MV_U32 n,m,freq,margin,minMargin = 0xffffffff;
  78754. + MV_U32 power;
  78755. + MV_U32 actualFreq = 0,actualN = 0,actualM = 0,val;
  78756. +
  78757. + if(frequancy > 100000)
  78758. + {
  78759. + mvOsPrintf("Warning TWSI frequancy is too high, please use up tp 100Khz. \n");
  78760. + }
  78761. +
  78762. + DB(mvOsPrintf("TWSI: mvTwsiInit - Tclk = %d freq = %d\n",Tclk,frequancy));
  78763. + /* Calucalte N and M for the TWSI clock baud rate */
  78764. + for(n = 0 ; n < 8 ; n++)
  78765. + {
  78766. + for(m = 0 ; m < 16 ; m++)
  78767. + {
  78768. + power = 2 << n; /* power = 2^(n+1) */
  78769. + freq = Tclk/(10*(m+1)*power);
  78770. + margin = MV_ABS(frequancy - freq);
  78771. + if(margin < minMargin)
  78772. + {
  78773. + minMargin = margin;
  78774. + actualFreq = freq;
  78775. + actualN = n;
  78776. + actualM = m;
  78777. + }
  78778. + }
  78779. + }
  78780. + DB(mvOsPrintf("TWSI: mvTwsiInit - actN %d actM %d actFreq %d\n",actualN , actualM, actualFreq));
  78781. + /* Reset the TWSI logic */
  78782. + twsiReset(chanNum);
  78783. +
  78784. + /* Set the baud rate */
  78785. + val = ((actualM<< TWSI_BAUD_RATE_M_OFFS) | actualN << TWSI_BAUD_RATE_N_OFFS);
  78786. + MV_REG_WRITE(TWSI_STATUS_BAUDE_RATE_REG(chanNum),val);
  78787. +
  78788. + /* Enable the TWSI and slave */
  78789. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), TWSI_CONTROL_ENA | TWSI_CONTROL_ACK);
  78790. +
  78791. + /* set the TWSI slave address */
  78792. + if( pTwsiAddr->type == ADDR10_BIT )/* 10 Bit deviceAddress */
  78793. + {
  78794. + /* writing the 2 most significant bits of the 10 bit address*/
  78795. + val = ((pTwsiAddr->address & TWSI_SLAVE_ADDR_10BIT_MASK) >> TWSI_SLAVE_ADDR_10BIT_OFFS );
  78796. + /* bits 7:3 must be 0x11110 */
  78797. + val |= TWSI_SLAVE_ADDR_10BIT_CONST;
  78798. + /* set GCE bit */
  78799. + if(generalCallEnable)
  78800. + val |= TWSI_SLAVE_ADDR_GCE_ENA;
  78801. + /* write slave address */
  78802. + MV_REG_WRITE(TWSI_SLAVE_ADDR_REG(chanNum),val);
  78803. +
  78804. + /* writing the 8 least significant bits of the 10 bit address*/
  78805. + val = (pTwsiAddr->address << TWSI_EXTENDED_SLAVE_OFFS) & TWSI_EXTENDED_SLAVE_MASK;
  78806. + MV_REG_WRITE(TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum), val);
  78807. + }
  78808. + else /*7 bit address*/
  78809. + {
  78810. + /* set the 7 Bits address */
  78811. + MV_REG_WRITE(TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum),0x0);
  78812. + val = (pTwsiAddr->address << TWSI_SLAVE_ADDR_7BIT_OFFS) & TWSI_SLAVE_ADDR_7BIT_MASK;
  78813. + MV_REG_WRITE(TWSI_SLAVE_ADDR_REG(chanNum), val);
  78814. + }
  78815. +
  78816. + /* unmask twsi int */
  78817. + val = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  78818. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), val | TWSI_CONTROL_INT_ENA);
  78819. + /* Add delay of 1ms */
  78820. + mvOsDelay(1);
  78821. +
  78822. + return actualFreq;
  78823. +}
  78824. +
  78825. +
  78826. +/*******************************************************************************
  78827. +* twsiStsGet - Get the TWSI status value.
  78828. +*
  78829. +* DESCRIPTION:
  78830. +* This routine returns the TWSI status value.
  78831. +*
  78832. +* INPUT:
  78833. +* chanNum - TWSI channel
  78834. +*
  78835. +* OUTPUT:
  78836. +* None.
  78837. +*
  78838. +* RETURN:
  78839. +* MV_U32 - the TWSI status.
  78840. +*
  78841. +*******************************************************************************/
  78842. +static MV_U32 twsiStsGet(MV_U8 chanNum)
  78843. +{
  78844. + return MV_REG_READ(TWSI_STATUS_BAUDE_RATE_REG(chanNum));
  78845. +
  78846. +}
  78847. +
  78848. +/*******************************************************************************
  78849. +* twsiReset - Reset the TWSI.
  78850. +*
  78851. +* DESCRIPTION:
  78852. +* Resets the TWSI logic and sets all TWSI registers to their reset values.
  78853. +*
  78854. +* INPUT:
  78855. +* chanNum - TWSI channel
  78856. +*
  78857. +* OUTPUT:
  78858. +* None.
  78859. +*
  78860. +* RETURN:
  78861. +* None
  78862. +*
  78863. +*******************************************************************************/
  78864. +static MV_VOID twsiReset(MV_U8 chanNum)
  78865. +{
  78866. + /* Reset the TWSI logic */
  78867. + MV_REG_WRITE(TWSI_SOFT_RESET_REG(chanNum),0);
  78868. +
  78869. + /* wait for 2 mili sec */
  78870. + mvOsDelay(2);
  78871. +
  78872. + return;
  78873. +}
  78874. +
  78875. +
  78876. +
  78877. +
  78878. +/******************************* POLICY ****************************************/
  78879. +
  78880. +
  78881. +
  78882. +/*******************************************************************************
  78883. +* mvTwsiAddrSet - Set address on TWSI bus.
  78884. +*
  78885. +* DESCRIPTION:
  78886. +* This function Set address (7 or 10 Bit address) on the Twsi Bus.
  78887. +*
  78888. +* INPUT:
  78889. +* chanNum - TWSI channel
  78890. +* pTwsiAddr - twsi address.
  78891. +* command - read / write .
  78892. +*
  78893. +* OUTPUT:
  78894. +* None.
  78895. +*
  78896. +* RETURN:
  78897. +* MV_OK - if setting the address completed succesfully.
  78898. +* MV_FAIL otherwmise.
  78899. +*
  78900. +*******************************************************************************/
  78901. +MV_STATUS mvTwsiAddrSet(MV_U8 chanNum, MV_TWSI_ADDR *pTwsiAddr, MV_TWSI_CMD command)
  78902. +{
  78903. + DB(mvOsPrintf("TWSI: mvTwsiAddr7BitSet addr %x , type %d, cmd is %s\n",pTwsiAddr->address,\
  78904. + pTwsiAddr->type, ((command==MV_TWSI_WRITE)?"Write":"Read") ));
  78905. + /* 10 Bit address */
  78906. + if(pTwsiAddr->type == ADDR10_BIT)
  78907. + {
  78908. + return twsiAddr10BitSet(chanNum, pTwsiAddr->address,command);
  78909. + }
  78910. + /* 7 Bit address */
  78911. + else
  78912. + {
  78913. + return twsiAddr7BitSet(chanNum, pTwsiAddr->address,command);
  78914. + }
  78915. +
  78916. +}
  78917. +
  78918. +/*******************************************************************************
  78919. +* twsiAddr10BitSet - Set 10 Bit address on TWSI bus.
  78920. +*
  78921. +* DESCRIPTION:
  78922. +* There are two address phases:
  78923. +* 1) Write '11110' to data register bits [7:3] and 10-bit address MSB
  78924. +* (bits [9:8]) to data register bits [2:1] plus a write(0) or read(1) bit
  78925. +* to the Data register. Then it clears interrupt flag which drive
  78926. +* the address on the TWSI bus. The function then waits for interrupt
  78927. +* flag to be active and status 0x18 (write) or 0x40 (read) to be set.
  78928. +* 2) write the rest of 10-bit address to data register and clears
  78929. +* interrupt flag which drive the address on the TWSI bus. The
  78930. +* function then waits for interrupt flag to be active and status
  78931. +* 0xD0 (write) or 0xE0 (read) to be set.
  78932. +*
  78933. +* INPUT:
  78934. +* chanNum - TWSI channel
  78935. +* deviceAddress - twsi address.
  78936. +* command - read / write .
  78937. +*
  78938. +* OUTPUT:
  78939. +* None.
  78940. +*
  78941. +* RETURN:
  78942. +* MV_OK - if setting the address completed succesfully.
  78943. +* MV_FAIL otherwmise.
  78944. +*
  78945. +*******************************************************************************/
  78946. +static MV_STATUS twsiAddr10BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command)
  78947. +{
  78948. + MV_U32 val,timeout;
  78949. +
  78950. + /* writing the 2 most significant bits of the 10 bit address*/
  78951. + val = ((deviceAddress & TWSI_DATA_ADDR_10BIT_MASK) >> TWSI_DATA_ADDR_10BIT_OFFS );
  78952. + /* bits 7:3 must be 0x11110 */
  78953. + val |= TWSI_DATA_ADDR_10BIT_CONST;
  78954. + /* set command */
  78955. + val |= command;
  78956. + MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);
  78957. + /* WA add a delay */
  78958. + mvOsDelay(1);
  78959. +
  78960. + /* clear Int flag */
  78961. + twsiIntFlgClr(chanNum);
  78962. +
  78963. + /* wait for Int to be Set */
  78964. + timeout = 0;
  78965. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  78966. +
  78967. + /* check for timeout */
  78968. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr10BitSet ERROR - 1st addr (10Bit) Int TimeOut.\n"))
  78969. + return MV_TIMEOUT;
  78970. +
  78971. + /* check the status */
  78972. + val = twsiStsGet(chanNum);
  78973. + if(( (val != TWSI_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) ||
  78974. + ( (val != TWSI_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))
  78975. + {
  78976. + mvOsPrintf("TWSI: twsiAddr10BitSet ERROR - status %x 1st addr (10 Bit) in %s mode.\n"\
  78977. + ,val, ((command==MV_TWSI_WRITE)?"Write":"Read") );
  78978. + return MV_FAIL;
  78979. + }
  78980. +
  78981. + /* set 8 LSB of the address */
  78982. + val = (deviceAddress << TWSI_DATA_ADDR_7BIT_OFFS) & TWSI_DATA_ADDR_7BIT_MASK;
  78983. + MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);
  78984. +
  78985. + /* clear Int flag */
  78986. + twsiIntFlgClr(chanNum);
  78987. +
  78988. + /* wait for Int to be Set */
  78989. + timeout = 0;
  78990. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  78991. +
  78992. + /* check for timeout */
  78993. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr10BitSet ERROR - 2nd (10 Bit) Int TimOut.\n"))
  78994. + return MV_TIMEOUT;
  78995. +
  78996. + /* check the status */
  78997. + val = twsiStsGet(chanNum);
  78998. + if(( (val != TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) ||
  78999. + ( (val != TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))
  79000. + {
  79001. + mvOsPrintf("TWSI: twsiAddr10BitSet ERROR - status %x 2nd addr(10 Bit) in %s mode.\n"\
  79002. + ,val, ((command==MV_TWSI_WRITE)?"Write":"Read") );
  79003. + return MV_FAIL;
  79004. + }
  79005. +
  79006. + return MV_OK;
  79007. +}
  79008. +
  79009. +/*******************************************************************************
  79010. +* twsiAddr7BitSet - Set 7 Bit address on TWSI bus.
  79011. +*
  79012. +* DESCRIPTION:
  79013. +* This function writes 7 bit address plus a write or read bit to the
  79014. +* Data register. Then it clears interrupt flag which drive the address on
  79015. +* the TWSI bus. The function then waits for interrupt flag to be active
  79016. +* and status 0x18 (write) or 0x40 (read) to be set.
  79017. +*
  79018. +* INPUT:
  79019. +* chanNum - TWSI channel
  79020. +* deviceAddress - twsi address.
  79021. +* command - read / write .
  79022. +*
  79023. +* OUTPUT:
  79024. +* None.
  79025. +*
  79026. +* RETURN:
  79027. +* MV_OK - if setting the address completed succesfully.
  79028. +* MV_FAIL otherwmise.
  79029. +*
  79030. +*******************************************************************************/
  79031. +static MV_STATUS twsiAddr7BitSet(MV_U8 chanNum, MV_U32 deviceAddress,MV_TWSI_CMD command)
  79032. +{
  79033. + MV_U32 val,timeout;
  79034. +
  79035. + /* set the address */
  79036. + val = (deviceAddress << TWSI_DATA_ADDR_7BIT_OFFS) & TWSI_DATA_ADDR_7BIT_MASK;
  79037. + /* set command */
  79038. + val |= command;
  79039. + MV_REG_WRITE(TWSI_DATA_REG(chanNum), val);
  79040. + /* WA add a delay */
  79041. + mvOsDelay(1);
  79042. +
  79043. + /* clear Int flag */
  79044. + twsiIntFlgClr(chanNum);
  79045. +
  79046. + /* wait for Int to be Set */
  79047. + timeout = 0;
  79048. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  79049. +
  79050. + /* check for timeout */
  79051. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiAddr7BitSet ERROR - Addr (7 Bit) int TimeOut.\n"))
  79052. + return MV_TIMEOUT;
  79053. +
  79054. + /* check the status */
  79055. + val = twsiStsGet(chanNum);
  79056. + if(( (val != TWSI_AD_PLS_RD_BIT_TRA_ACK_REC) && (command == MV_TWSI_READ ) ) ||
  79057. + ( (val != TWSI_AD_PLS_WR_BIT_TRA_ACK_REC) && (command == MV_TWSI_WRITE) ))
  79058. + {
  79059. + /* only in debug, since in boot we try to read the SPD of both DRAM, and we don't
  79060. + want error messeges in case DIMM doesn't exist. */
  79061. + DB(mvOsPrintf("TWSI: twsiAddr7BitSet ERROR - status %x addr (7 Bit) in %s mode.\n"\
  79062. + ,val,((command==MV_TWSI_WRITE)?"Write":"Read") ));
  79063. + return MV_FAIL;
  79064. + }
  79065. +
  79066. + return MV_OK;
  79067. +}
  79068. +
  79069. +/*******************************************************************************
  79070. +* twsiDataWrite - Trnasmit a data block over TWSI bus.
  79071. +*
  79072. +* DESCRIPTION:
  79073. +* This function writes a given data block to TWSI bus in 8 bit granularity.
  79074. +* first The function waits for interrupt flag to be active then
  79075. +* For each 8-bit data:
  79076. +* The function writes data to data register. It then clears
  79077. +* interrupt flag which drives the data on the TWSI bus.
  79078. +* The function then waits for interrupt flag to be active and status
  79079. +* 0x28 to be set.
  79080. +*
  79081. +*
  79082. +* INPUT:
  79083. +* chanNum - TWSI channel
  79084. +* pBlock - Data block.
  79085. +* blockSize - number of chars in pBlock.
  79086. +*
  79087. +* OUTPUT:
  79088. +* None.
  79089. +*
  79090. +* RETURN:
  79091. +* MV_OK - if transmiting the block completed succesfully,
  79092. +* MV_BAD_PARAM - if pBlock is NULL,
  79093. +* MV_FAIL otherwmise.
  79094. +*
  79095. +*******************************************************************************/
  79096. +static MV_STATUS twsiDataTransmit(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize)
  79097. +{
  79098. + MV_U32 timeout, temp, blockSizeWr = blockSize;
  79099. +
  79100. + if(NULL == pBlock)
  79101. + return MV_BAD_PARAM;
  79102. +
  79103. + /* wait for Int to be Set */
  79104. + timeout = 0;
  79105. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  79106. +
  79107. + /* check for timeout */
  79108. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataTransmit ERROR - Read Data Int TimeOut.\n"))
  79109. + return MV_TIMEOUT;
  79110. +
  79111. + while(blockSizeWr)
  79112. + {
  79113. + /* write the data*/
  79114. + MV_REG_WRITE(TWSI_DATA_REG(chanNum),(MV_U32)*pBlock);
  79115. + DB(mvOsPrintf("TWSI: twsiDataTransmit place = %d write %x \n",\
  79116. + blockSize - blockSizeWr, *pBlock));
  79117. + pBlock++;
  79118. + blockSizeWr--;
  79119. +
  79120. + twsiIntFlgClr(chanNum);
  79121. +
  79122. + /* wait for Int to be Set */
  79123. + timeout = 0;
  79124. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  79125. +
  79126. + /* check for timeout */
  79127. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataTransmit ERROR - Read Data Int TimeOut.\n"))
  79128. + return MV_TIMEOUT;
  79129. +
  79130. + /* check the status */
  79131. + temp = twsiStsGet(chanNum);
  79132. + if(temp != TWSI_M_TRAN_DATA_BYTE_ACK_REC)
  79133. + {
  79134. + mvOsPrintf("TWSI: twsiDataTransmit ERROR - status %x in write trans\n",temp);
  79135. + return MV_FAIL;
  79136. + }
  79137. +
  79138. + }
  79139. +
  79140. + return MV_OK;
  79141. +}
  79142. +
  79143. +/*******************************************************************************
  79144. +* twsiDataReceive - Receive data block from TWSI bus.
  79145. +*
  79146. +* DESCRIPTION:
  79147. +* This function receive data block from TWSI bus in 8bit granularity
  79148. +* into pBlock buffer.
  79149. +* first The function waits for interrupt flag to be active then
  79150. +* For each 8-bit data:
  79151. +* It clears the interrupt flag which allows the next data to be
  79152. +* received from TWSI bus.
  79153. +* The function waits for interrupt flag to be active,
  79154. +* and status reg is 0x50.
  79155. +* Then the function reads data from data register, and copies it to
  79156. +* the given buffer.
  79157. +*
  79158. +* INPUT:
  79159. +* chanNum - TWSI channel
  79160. +* blockSize - number of bytes to read.
  79161. +*
  79162. +* OUTPUT:
  79163. +* pBlock - Data block.
  79164. +*
  79165. +* RETURN:
  79166. +* MV_OK - if receive transaction completed succesfully,
  79167. +* MV_BAD_PARAM - if pBlock is NULL,
  79168. +* MV_FAIL otherwmise.
  79169. +*
  79170. +*******************************************************************************/
  79171. +static MV_STATUS twsiDataReceive(MV_U8 chanNum, MV_U8 *pBlock, MV_U32 blockSize)
  79172. +{
  79173. + MV_U32 timeout, temp, blockSizeRd = blockSize;
  79174. + if(NULL == pBlock)
  79175. + return MV_BAD_PARAM;
  79176. +
  79177. + /* wait for Int to be Set */
  79178. + timeout = 0;
  79179. + while( !twsiMainIntGet(chanNum) && (timeout++ < TWSI_TIMEOUT_VALUE));
  79180. +
  79181. + /* check for timeout */
  79182. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataReceive ERROR - Read Data int Time out .\n"))
  79183. + return MV_TIMEOUT;
  79184. +
  79185. + while(blockSizeRd)
  79186. + {
  79187. + if(blockSizeRd == 1)
  79188. + {
  79189. + /* clear ack and Int flag */
  79190. + temp = MV_REG_READ(TWSI_CONTROL_REG(chanNum));
  79191. + temp &= ~(TWSI_CONTROL_ACK);
  79192. + MV_REG_WRITE(TWSI_CONTROL_REG(chanNum), temp);
  79193. + }
  79194. + twsiIntFlgClr(chanNum);
  79195. + /* wait for Int to be Set */
  79196. + timeout = 0;
  79197. + while( (!twsiMainIntGet(chanNum)) && (timeout++ < TWSI_TIMEOUT_VALUE));
  79198. +
  79199. + /* check for timeout */
  79200. + if(MV_TRUE == twsiTimeoutChk(timeout,"TWSI: twsiDataReceive ERROR - Read Data Int Time out .\n"))
  79201. + return MV_TIMEOUT;
  79202. +
  79203. + /* check the status */
  79204. + temp = twsiStsGet(chanNum);
  79205. + if((temp != TWSI_M_REC_RD_DATA_ACK_TRA) && (blockSizeRd !=1))
  79206. + {
  79207. + mvOsPrintf("TWSI: twsiDataReceive ERROR - status %x in read trans \n",temp);
  79208. + return MV_FAIL;
  79209. + }
  79210. + else if((temp != TWSI_M_REC_RD_DATA_ACK_NOT_TRA) && (blockSizeRd ==1))
  79211. + {
  79212. + mvOsPrintf("TWSI: twsiDataReceive ERROR - status %x in Rd Terminate\n",temp);
  79213. + return MV_FAIL;
  79214. + }
  79215. +
  79216. + /* read the data*/
  79217. + *pBlock = (MV_U8)MV_REG_READ(TWSI_DATA_REG(chanNum));
  79218. + DB(mvOsPrintf("TWSI: twsiDataReceive place %d read %x \n",\
  79219. + blockSize - blockSizeRd,*pBlock));
  79220. + pBlock++;
  79221. + blockSizeRd--;
  79222. + }
  79223. +
  79224. + return MV_OK;
  79225. +}
  79226. +
  79227. +
  79228. +
  79229. +/*******************************************************************************
  79230. +* twsiTargetOffsSet - Set TWST target offset on TWSI bus.
  79231. +*
  79232. +* DESCRIPTION:
  79233. +* The function support TWSI targets that have inside address space (for
  79234. +* example EEPROMs). The function:
  79235. +* 1) Convert the given offset into pBlock and size.
  79236. +* in case the offset should be set to a TWSI slave which support
  79237. +* more then 256 bytes offset, the offset setting will be done
  79238. +* in 2 transactions.
  79239. +* 2) Use twsiDataTransmit to place those on the bus.
  79240. +*
  79241. +* INPUT:
  79242. +* chanNum - TWSI channel
  79243. +* offset - offset to be set on the EEPROM device.
  79244. +* moreThen256 - whether the EEPROM device support more then 256 byte offset.
  79245. +*
  79246. +* OUTPUT:
  79247. +* None.
  79248. +*
  79249. +* RETURN:
  79250. +* MV_OK - if setting the offset completed succesfully.
  79251. +* MV_FAIL otherwmise.
  79252. +*
  79253. +*******************************************************************************/
  79254. +static MV_STATUS twsiTargetOffsSet(MV_U8 chanNum, MV_U32 offset, MV_BOOL moreThen256)
  79255. +{
  79256. + MV_U8 offBlock[2];
  79257. + MV_U32 offSize;
  79258. +
  79259. + if(moreThen256 == MV_TRUE)
  79260. + {
  79261. + offBlock[0] = (offset >> 8) & 0xff;
  79262. + offBlock[1] = offset & 0xff;
  79263. + offSize = 2;
  79264. + }
  79265. + else
  79266. + {
  79267. + offBlock[0] = offset & 0xff;
  79268. + offSize = 1;
  79269. + }
  79270. + DB(mvOsPrintf("TWSI: twsiTargetOffsSet offSize = %x addr1 = %x addr2 = %x\n",\
  79271. + offSize,offBlock[0],offBlock[1]));
  79272. + return twsiDataTransmit(chanNum, offBlock, offSize);
  79273. +
  79274. +}
  79275. +
  79276. +/*******************************************************************************
  79277. +* mvTwsiRead - Read data block from a TWSI Slave.
  79278. +*
  79279. +* DESCRIPTION:
  79280. +* The function calls the following functions:
  79281. +* -) mvTwsiStartBitSet();
  79282. +* if(EEPROM device)
  79283. +* -) mvTwsiAddrSet(w);
  79284. +* -) twsiTargetOffsSet();
  79285. +* -) mvTwsiStartBitSet();
  79286. +* -) mvTwsiAddrSet(r);
  79287. +* -) twsiDataReceive();
  79288. +* -) mvTwsiStopBitSet();
  79289. +*
  79290. +* INPUT:
  79291. +* chanNum - TWSI channel
  79292. +* pTwsiSlave - Twsi Slave structure.
  79293. +* blockSize - number of bytes to read.
  79294. +*
  79295. +* OUTPUT:
  79296. +* pBlock - Data block.
  79297. +*
  79298. +* RETURN:
  79299. +* MV_OK - if EEPROM read transaction completed succesfully,
  79300. +* MV_BAD_PARAM - if pBlock is NULL,
  79301. +* MV_FAIL otherwmise.
  79302. +*
  79303. +*******************************************************************************/
  79304. +MV_STATUS mvTwsiRead(MV_U8 chanNum, MV_TWSI_SLAVE *pTwsiSlave, MV_U8 *pBlock, MV_U32 blockSize)
  79305. +{
  79306. + if((NULL == pBlock) || (NULL == pTwsiSlave))
  79307. + return MV_BAD_PARAM;
  79308. + if(MV_OK != mvTwsiStartBitSet(chanNum))
  79309. + {
  79310. + mvTwsiStopBitSet(chanNum);
  79311. + return MV_FAIL;
  79312. + }
  79313. +
  79314. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStartBitSet\n"));
  79315. +
  79316. + /* in case offset exsist (i.e. eeprom ) */
  79317. + if(MV_TRUE == pTwsiSlave->validOffset)
  79318. + {
  79319. + if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_WRITE))
  79320. + {
  79321. + mvTwsiStopBitSet(chanNum);
  79322. + return MV_FAIL;
  79323. + }
  79324. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiAddrSet\n"));
  79325. + if(MV_OK != twsiTargetOffsSet(chanNum, pTwsiSlave->offset, pTwsiSlave->moreThen256))
  79326. + {
  79327. + mvTwsiStopBitSet(chanNum);
  79328. + return MV_FAIL;
  79329. + }
  79330. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after twsiTargetOffsSet\n"));
  79331. + if(MV_OK != mvTwsiStartBitSet(chanNum))
  79332. + {
  79333. + mvTwsiStopBitSet(chanNum);
  79334. + return MV_FAIL;
  79335. + }
  79336. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStartBitSet\n"));
  79337. + }
  79338. + if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_READ))
  79339. + {
  79340. + mvTwsiStopBitSet(chanNum);
  79341. + return MV_FAIL;
  79342. + }
  79343. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiAddrSet\n"));
  79344. + if(MV_OK != twsiDataReceive(chanNum, pBlock, blockSize))
  79345. + {
  79346. + mvTwsiStopBitSet(chanNum);
  79347. + return MV_FAIL;
  79348. + }
  79349. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after twsiDataReceive\n"));
  79350. +
  79351. + if(MV_OK != mvTwsiStopBitSet(chanNum))
  79352. + {
  79353. + return MV_FAIL;
  79354. + }
  79355. +
  79356. + twsiAckBitSet(chanNum);
  79357. +
  79358. + DB(mvOsPrintf("TWSI: mvTwsiEepromRead after mvTwsiStopBitSet\n"));
  79359. +
  79360. + return MV_OK;
  79361. +}
  79362. +
  79363. +/*******************************************************************************
  79364. +* mvTwsiWrite - Write data block to a TWSI Slave.
  79365. +*
  79366. +* DESCRIPTION:
  79367. +* The function calls the following functions:
  79368. +* -) mvTwsiStartBitSet();
  79369. +* -) mvTwsiAddrSet();
  79370. +* -)if(EEPROM device)
  79371. +* -) twsiTargetOffsSet();
  79372. +* -) twsiDataTransmit();
  79373. +* -) mvTwsiStopBitSet();
  79374. +*
  79375. +* INPUT:
  79376. +* chanNum - TWSI channel
  79377. +* eepromAddress - eeprom address.
  79378. +* blockSize - number of bytes to write.
  79379. +* pBlock - Data block.
  79380. +*
  79381. +* OUTPUT:
  79382. +* None
  79383. +*
  79384. +* RETURN:
  79385. +* MV_OK - if EEPROM read transaction completed succesfully.
  79386. +* MV_BAD_PARAM - if pBlock is NULL,
  79387. +* MV_FAIL otherwmise.
  79388. +*
  79389. +* NOTE: Part of the EEPROM, required that the offset will be aligned to the
  79390. +* max write burst supported.
  79391. +*******************************************************************************/
  79392. +MV_STATUS mvTwsiWrite(MV_U8 chanNum, MV_TWSI_SLAVE *pTwsiSlave, MV_U8 *pBlock, MV_U32 blockSize)
  79393. +{
  79394. + if((NULL == pBlock) || (NULL == pTwsiSlave))
  79395. + return MV_BAD_PARAM;
  79396. +
  79397. + if(MV_OK != mvTwsiStartBitSet(chanNum))
  79398. + {
  79399. + mvTwsiStopBitSet(chanNum);
  79400. + return MV_FAIL;
  79401. + }
  79402. +
  79403. + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after mvTwsiStartBitSet\n"));
  79404. + if(MV_OK != mvTwsiAddrSet(chanNum, &(pTwsiSlave->slaveAddr), MV_TWSI_WRITE))
  79405. + {
  79406. + mvTwsiStopBitSet(chanNum);
  79407. + return MV_FAIL;
  79408. + }
  79409. + DB(mvOsPrintf("TWSI :mvTwsiEepromWrite after mvTwsiAddrSet\n"));
  79410. +
  79411. + /* in case offset exsist (i.e. eeprom ) */
  79412. + if(MV_TRUE == pTwsiSlave->validOffset)
  79413. + {
  79414. + if(MV_OK != twsiTargetOffsSet(chanNum, pTwsiSlave->offset, pTwsiSlave->moreThen256))
  79415. + {
  79416. + mvTwsiStopBitSet(chanNum);
  79417. + return MV_FAIL;
  79418. + }
  79419. + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after twsiTargetOffsSet\n"));
  79420. + }
  79421. + if(MV_OK != twsiDataTransmit(chanNum, pBlock, blockSize))
  79422. + {
  79423. + mvTwsiStopBitSet(chanNum);
  79424. + return MV_FAIL;
  79425. + }
  79426. + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after twsiDataTransmit\n"));
  79427. + if(MV_OK != mvTwsiStopBitSet(chanNum))
  79428. + {
  79429. + return MV_FAIL;
  79430. + }
  79431. + DB(mvOsPrintf("TWSI: mvTwsiEepromWrite after mvTwsiStopBitSet\n"));
  79432. +
  79433. + return MV_OK;
  79434. +}
  79435. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h
  79436. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h 1970-01-01 01:00:00.000000000 +0100
  79437. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsi.h 2011-08-01 14:38:19.000000000 +0200
  79438. @@ -0,0 +1,121 @@
  79439. +/*******************************************************************************
  79440. +Copyright (C) Marvell International Ltd. and its affiliates
  79441. +
  79442. +This software file (the "File") is owned and distributed by Marvell
  79443. +International Ltd. and/or its affiliates ("Marvell") under the following
  79444. +alternative licensing terms. Once you have made an election to distribute the
  79445. +File under one of the following license alternatives, please (i) delete this
  79446. +introductory statement regarding license alternatives, (ii) delete the two
  79447. +license alternatives that you have not elected to use and (iii) preserve the
  79448. +Marvell copyright notice above.
  79449. +
  79450. +********************************************************************************
  79451. +Marvell Commercial License Option
  79452. +
  79453. +If you received this File from Marvell and you have entered into a commercial
  79454. +license agreement (a "Commercial License") with Marvell, the File is licensed
  79455. +to you under the terms of the applicable Commercial License.
  79456. +
  79457. +********************************************************************************
  79458. +Marvell GPL License Option
  79459. +
  79460. +If you received this File from Marvell, you may opt to use, redistribute and/or
  79461. +modify this File in accordance with the terms and conditions of the General
  79462. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  79463. +available along with the File in the license.txt file or by writing to the Free
  79464. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  79465. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  79466. +
  79467. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  79468. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  79469. +DISCLAIMED. The GPL License provides additional details about this warranty
  79470. +disclaimer.
  79471. +********************************************************************************
  79472. +Marvell BSD License Option
  79473. +
  79474. +If you received this File from Marvell, you may opt to use, redistribute and/or
  79475. +modify this File under the following licensing terms.
  79476. +Redistribution and use in source and binary forms, with or without modification,
  79477. +are permitted provided that the following conditions are met:
  79478. +
  79479. + * Redistributions of source code must retain the above copyright notice,
  79480. + this list of conditions and the following disclaimer.
  79481. +
  79482. + * Redistributions in binary form must reproduce the above copyright
  79483. + notice, this list of conditions and the following disclaimer in the
  79484. + documentation and/or other materials provided with the distribution.
  79485. +
  79486. + * Neither the name of Marvell nor the names of its contributors may be
  79487. + used to endorse or promote products derived from this software without
  79488. + specific prior written permission.
  79489. +
  79490. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  79491. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  79492. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  79493. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  79494. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  79495. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  79496. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  79497. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  79498. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  79499. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  79500. +
  79501. +*******************************************************************************/
  79502. +#ifndef __INCmvTwsiH
  79503. +#define __INCmvTwsiH
  79504. +
  79505. +#ifdef __cplusplus
  79506. +extern "C" {
  79507. +#endif /* __cplusplus */
  79508. +
  79509. +/* need to update this includes */
  79510. +#include "twsi/mvTwsiSpec.h"
  79511. +#include "ctrlEnv/mvCtrlEnvLib.h"
  79512. +
  79513. +
  79514. +/* The TWSI interface supports both 7-bit and 10-bit addressing. */
  79515. +/* This enumerator describes addressing type. */
  79516. +typedef enum _mvTwsiAddrType
  79517. +{
  79518. + ADDR7_BIT, /* 7 bit address */
  79519. + ADDR10_BIT /* 10 bit address */
  79520. +}MV_TWSI_ADDR_TYPE;
  79521. +
  79522. +/* This structure describes TWSI address. */
  79523. +typedef struct _mvTwsiAddr
  79524. +{
  79525. + MV_U32 address; /* address */
  79526. + MV_TWSI_ADDR_TYPE type; /* Address type */
  79527. +}MV_TWSI_ADDR;
  79528. +
  79529. +/* This structure describes a TWSI slave. */
  79530. +typedef struct _mvTwsiSlave
  79531. +{
  79532. + MV_TWSI_ADDR slaveAddr;
  79533. + MV_BOOL validOffset; /* whether the slave has offset (i.e. Eeprom etc.) */
  79534. + MV_U32 offset; /* offset in the slave. */
  79535. + MV_BOOL moreThen256; /* whether the ofset is bigger then 256 */
  79536. +}MV_TWSI_SLAVE;
  79537. +
  79538. +/* This enumerator describes TWSI protocol commands. */
  79539. +typedef enum _mvTwsiCmd
  79540. +{
  79541. + MV_TWSI_WRITE, /* TWSI write command - 0 according to spec */
  79542. + MV_TWSI_READ /* TWSI read command - 1 according to spec */
  79543. +}MV_TWSI_CMD;
  79544. +
  79545. +MV_STATUS mvTwsiStartBitSet(MV_U8 chanNum);
  79546. +MV_STATUS mvTwsiStopBitSet(MV_U8 chanNum);
  79547. +MV_STATUS mvTwsiAddrSet(MV_U8 chanNum, MV_TWSI_ADDR *twsiAddr, MV_TWSI_CMD command);
  79548. +
  79549. +MV_U32 mvTwsiInit(MV_U8 chanNum, MV_KHZ frequancy, MV_U32 Tclk, MV_TWSI_ADDR *twsiAddr, MV_BOOL generalCallEnable);
  79550. +MV_STATUS mvTwsiRead (MV_U8 chanNum, MV_TWSI_SLAVE *twsiSlave, MV_U8 *pBlock, MV_U32 blockSize);
  79551. +MV_STATUS mvTwsiWrite(MV_U8 chanNum, MV_TWSI_SLAVE *twsiSlave, MV_U8 *pBlock, MV_U32 blockSize);
  79552. +
  79553. +
  79554. +#ifdef __cplusplus
  79555. +}
  79556. +#endif /* __cplusplus */
  79557. +
  79558. +#endif /* __INCmvTwsiH */
  79559. +
  79560. diff -Nur linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h
  79561. --- linux-2.6.39.orig/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h 1970-01-01 01:00:00.000000000 +0100
  79562. +++ linux-2.6.39/crypto/ocf/kirkwood/mvHal/mv_hal/twsi/mvTwsiSpec.h 2011-08-01 14:38:19.000000000 +0200
  79563. @@ -0,0 +1,160 @@
  79564. +/*******************************************************************************
  79565. +Copyright (C) Marvell International Ltd. and its affiliates
  79566. +
  79567. +This software file (the "File") is owned and distributed by Marvell
  79568. +International Ltd. and/or its affiliates ("Marvell") under the following
  79569. +alternative licensing terms. Once you have made an election to distribute the
  79570. +File under one of the following license alternatives, please (i) delete this
  79571. +introductory statement regarding license alternatives, (ii) delete the two
  79572. +license alternatives that you have not elected to use and (iii) preserve the
  79573. +Marvell copyright notice above.
  79574. +
  79575. +********************************************************************************
  79576. +Marvell Commercial License Option
  79577. +
  79578. +If you received this File from Marvell and you have entered into a commercial
  79579. +license agreement (a "Commercial License") with Marvell, the File is licensed
  79580. +to you under the terms of the applicable Commercial License.
  79581. +
  79582. +********************************************************************************
  79583. +Marvell GPL License Option
  79584. +
  79585. +If you received this File from Marvell, you may opt to use, redistribute and/or
  79586. +modify this File in accordance with the terms and conditions of the General
  79587. +Public License Version 2, June 1991 (the "GPL License"), a copy of which is
  79588. +available along with the File in the license.txt file or by writing to the Free
  79589. +Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or
  79590. +on the worldwide web at http://www.gnu.org/licenses/gpl.txt.
  79591. +
  79592. +THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED
  79593. +WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY
  79594. +DISCLAIMED. The GPL License provides additional details about this warranty
  79595. +disclaimer.
  79596. +********************************************************************************
  79597. +Marvell BSD License Option
  79598. +
  79599. +If you received this File from Marvell, you may opt to use, redistribute and/or
  79600. +modify this File under the following licensing terms.
  79601. +Redistribution and use in source and binary forms, with or without modification,
  79602. +are permitted provided that the following conditions are met:
  79603. +
  79604. + * Redistributions of source code must retain the above copyright notice,
  79605. + this list of conditions and the following disclaimer.
  79606. +
  79607. + * Redistributions in binary form must reproduce the above copyright
  79608. + notice, this list of conditions and the following disclaimer in the
  79609. + documentation and/or other materials provided with the distribution.
  79610. +
  79611. + * Neither the name of Marvell nor the names of its contributors may be
  79612. + used to endorse or promote products derived from this software without
  79613. + specific prior written permission.
  79614. +
  79615. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  79616. +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  79617. +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  79618. +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  79619. +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  79620. +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  79621. +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  79622. +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  79623. +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  79624. +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  79625. +
  79626. +*******************************************************************************/
  79627. +/****************************************/
  79628. +/* TWSI Registers */
  79629. +/****************************************/
  79630. +#ifndef __INCmvTwsiSpech
  79631. +#define __INCmvTwsiSpech
  79632. +
  79633. +#ifdef __cplusplus
  79634. +extern "C" {
  79635. +#endif /* __cplusplus */
  79636. +
  79637. +/* defines */
  79638. +#define TWSI_SLAVE_ADDR_REG(chanNum) (TWSI_SLAVE_BASE(chanNum)+ 0x00)
  79639. +
  79640. +#define TWSI_SLAVE_ADDR_GCE_ENA BIT0
  79641. +#define TWSI_SLAVE_ADDR_7BIT_OFFS 0x1
  79642. +#define TWSI_SLAVE_ADDR_7BIT_MASK (0xFF << TWSI_SLAVE_ADDR_7BIT_OFFS)
  79643. +#define TWSI_SLAVE_ADDR_10BIT_OFFS 0x7
  79644. +#define TWSI_SLAVE_ADDR_10BIT_MASK 0x300
  79645. +#define TWSI_SLAVE_ADDR_10BIT_CONST 0xF0
  79646. +
  79647. +
  79648. +#define TWSI_EXTENDED_SLAVE_ADDR_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x10)
  79649. +#define TWSI_EXTENDED_SLAVE_OFFS 0
  79650. +#define TWSI_EXTENDED_SLAVE_MASK (0xFF << TWSI_EXTENDED_SLAVE_OFFS)
  79651. +
  79652. +
  79653. +#define TWSI_DATA_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x04)
  79654. +#define TWSI_DATA_COMMAND_OFFS 0x0
  79655. +#define TWSI_DATA_COMMAND_MASK (0x1 << TWSI_DATA_COMMAND_OFFS)
  79656. +#define TWSI_DATA_COMMAND_WR (0x1 << TWSI_DATA_COMMAND_OFFS)
  79657. +#define TWSI_DATA_COMMAND_RD (0x0 << TWSI_DATA_COMMAND_OFFS)
  79658. +#define TWSI_DATA_ADDR_7BIT_OFFS 0x1
  79659. +#define TWSI_DATA_ADDR_7BIT_MASK (0xFF << TWSI_DATA_ADDR_7BIT_OFFS)
  79660. +#define TWSI_DATA_ADDR_10BIT_OFFS 0x7
  79661. +#define TWSI_DATA_ADDR_10BIT_MASK 0x300
  79662. +#define TWSI_DATA_ADDR_10BIT_CONST 0xF0
  79663. +
  79664. +
  79665. +#define TWSI_CONTROL_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x08)
  79666. +#define TWSI_CONTROL_ACK BIT2
  79667. +#define TWSI_CONTROL_INT_FLAG_SET BIT3
  79668. +#define TWSI_CONTROL_STOP_BIT BIT4
  79669. +#define TWSI_CONTROL_START_BIT BIT5
  79670. +#define TWSI_CONTROL_ENA BIT6
  79671. +#define TWSI_CONTROL_INT_ENA BIT7
  79672. +
  79673. +
  79674. +#define TWSI_STATUS_BAUDE_RATE_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x0c)
  79675. +#define TWSI_BAUD_RATE_N_OFFS 0
  79676. +#define TWSI_BAUD_RATE_N_MASK (0x7 << TWSI_BAUD_RATE_N_OFFS)
  79677. +#define TWSI_BAUD_RATE_M_OFFS 3
  79678. +#define TWSI_BAUD_RATE_M_MASK (0xF << TWSI_BAUD_RATE_M_OFFS)
  79679. +
  79680. +#define TWSI_SOFT_RESET_REG(chanNum) (TWSI_SLAVE_BASE(chanNum) + 0x1c)
  79681. +
  79682. +/* defines */
  79683. +#define TWSI_TIMEOUT_VALUE 0x500
  79684. +
  79685. +/* TWSI status codes */
  79686. +#define TWSI_BUS_ERROR 0x00
  79687. +#define TWSI_START_CON_TRA 0x08
  79688. +#define TWSI_REPEATED_START_CON_TRA 0x10
  79689. +#define TWSI_AD_PLS_WR_BIT_TRA_ACK_REC 0x18
  79690. +#define TWSI_AD_PLS_WR_BIT_TRA_ACK_NOT_REC 0x20
  79691. +#define TWSI_M_TRAN_DATA_BYTE_ACK_REC 0x28
  79692. +#define TWSI_M_TRAN_DATA_BYTE_ACK_NOT_REC 0x30
  79693. +#define TWSI_M_LOST_ARB_DUR_AD_OR_DATA_TRA 0x38
  79694. +#define TWSI_AD_PLS_RD_BIT_TRA_ACK_REC 0x40
  79695. +#define TWSI_AD_PLS_RD_BIT_TRA_ACK_NOT_REC 0x48
  79696. +#define TWSI_M_REC_RD_DATA_ACK_TRA 0x50
  79697. +#define TWSI_M_REC_RD_DATA_ACK_NOT_TRA 0x58
  79698. +#define TWSI_SLA_REC_AD_PLS_WR_BIT_ACK_TRA 0x60
  79699. +#define TWSI_M_LOST_ARB_DUR_AD_TRA_AD_IS_TRGT_TO_SLA_ACK_TRA_W 0x68
  79700. +#define TWSI_GNL_CALL_REC_ACK_TRA 0x70
  79701. +#define TWSI_M_LOST_ARB_DUR_AD_TRA_GNL_CALL_AD_REC_ACK_TRA 0x78
  79702. +#define TWSI_SLA_REC_WR_DATA_AF_REC_SLA_AD_ACK_TRAN 0x80
  79703. +#define TWSI_SLA_REC_WR_DATA_AF_REC_SLA_AD_ACK_NOT_TRAN 0x88
  79704. +#define TWSI_SLA_REC_WR_DATA_AF_REC_GNL_CALL_ACK_TRAN 0x90
  79705. +#define TWSI_SLA_REC_WR_DATA_AF_REC_GNL_CALL_ACK_NOT_TRAN 0x98
  79706. +#define TWSI_SLA_REC_STOP_OR_REPEATED_STRT_CON 0xA0
  79707. +#define TWSI_SLA_REC_AD_PLS_RD_BIT_ACK_TRA 0xA8
  79708. +#define TWSI_M_LOST_ARB_DUR_AD_TRA_AD_IS_TRGT_TO_SLA_ACK_TRA_R 0xB0
  79709. +#define TWSI_SLA_TRA_RD_DATA_ACK_REC 0xB8
  79710. +#define TWSI_SLA_TRA_RD_DATA_ACK_NOT_REC 0xC0
  79711. +#define TWSI_SLA_TRA_LAST_RD_DATA_ACK_REC 0xC8
  79712. +#define TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_REC 0xD0
  79713. +#define TWSI_SEC_AD_PLS_WR_BIT_TRA_ACK_NOT_REC 0xD8
  79714. +#define TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_REC 0xE0
  79715. +#define TWSI_SEC_AD_PLS_RD_BIT_TRA_ACK_NOT_REC 0xE8
  79716. +#define TWSI_NO_REL_STS_INT_FLAG_IS_KEPT_0 0xF8
  79717. +
  79718. +
  79719. +#ifdef __cplusplus
  79720. +}
  79721. +#endif /* __cplusplus */
  79722. +
  79723. +#endif /* __INCmvTwsiSpech */
  79724. diff -Nur linux-2.6.39.orig/crypto/ocf/ocf-bench.c linux-2.6.39/crypto/ocf/ocf-bench.c
  79725. --- linux-2.6.39.orig/crypto/ocf/ocf-bench.c 1970-01-01 01:00:00.000000000 +0100
  79726. +++ linux-2.6.39/crypto/ocf/ocf-bench.c 2011-08-01 14:38:19.000000000 +0200
  79727. @@ -0,0 +1,436 @@
  79728. +/*
  79729. + * A loadable module that benchmarks the OCF crypto speed from kernel space.
  79730. + *
  79731. + * Copyright (C) 2004-2010 David McCullough <david_mccullough@mcafee.com>
  79732. + *
  79733. + * LICENSE TERMS
  79734. + *
  79735. + * The free distribution and use of this software in both source and binary
  79736. + * form is allowed (with or without changes) provided that:
  79737. + *
  79738. + * 1. distributions of this source code include the above copyright
  79739. + * notice, this list of conditions and the following disclaimer;
  79740. + *
  79741. + * 2. distributions in binary form include the above copyright
  79742. + * notice, this list of conditions and the following disclaimer
  79743. + * in the documentation and/or other associated materials;
  79744. + *
  79745. + * 3. the copyright holder's name is not used to endorse products
  79746. + * built using this software without specific written permission.
  79747. + *
  79748. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  79749. + * may be distributed under the terms of the GNU General Public License (GPL),
  79750. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  79751. + *
  79752. + * DISCLAIMER
  79753. + *
  79754. + * This software is provided 'as is' with no explicit or implied warranties
  79755. + * in respect of its properties, including, but not limited to, correctness
  79756. + * and/or fitness for purpose.
  79757. + */
  79758. +
  79759. +
  79760. +#ifndef AUTOCONF_INCLUDED
  79761. +#include <linux/config.h>
  79762. +#endif
  79763. +#include <linux/module.h>
  79764. +#include <linux/init.h>
  79765. +#include <linux/list.h>
  79766. +#include <linux/slab.h>
  79767. +#include <linux/wait.h>
  79768. +#include <linux/sched.h>
  79769. +#include <linux/spinlock.h>
  79770. +#include <linux/version.h>
  79771. +#include <linux/interrupt.h>
  79772. +#include <cryptodev.h>
  79773. +
  79774. +#ifdef I_HAVE_AN_XSCALE_WITH_INTEL_SDK
  79775. +#define BENCH_IXP_ACCESS_LIB 1
  79776. +#endif
  79777. +#ifdef BENCH_IXP_ACCESS_LIB
  79778. +#include <IxTypes.h>
  79779. +#include <IxOsBuffMgt.h>
  79780. +#include <IxNpeDl.h>
  79781. +#include <IxCryptoAcc.h>
  79782. +#include <IxQMgr.h>
  79783. +#include <IxOsServices.h>
  79784. +#include <IxOsCacheMMU.h>
  79785. +#endif
  79786. +
  79787. +/*
  79788. + * support for access lib version 1.4
  79789. + */
  79790. +#ifndef IX_MBUF_PRIV
  79791. +#define IX_MBUF_PRIV(x) ((x)->priv)
  79792. +#endif
  79793. +
  79794. +/*
  79795. + * the number of simultaneously active requests
  79796. + */
  79797. +static int request_q_len = 20;
  79798. +module_param(request_q_len, int, 0);
  79799. +MODULE_PARM_DESC(request_q_len, "Number of outstanding requests");
  79800. +/*
  79801. + * how many requests we want to have processed
  79802. + */
  79803. +static int request_num = 1024;
  79804. +module_param(request_num, int, 0);
  79805. +MODULE_PARM_DESC(request_num, "run for at least this many requests");
  79806. +/*
  79807. + * the size of each request
  79808. + */
  79809. +static int request_size = 1500;
  79810. +module_param(request_size, int, 0);
  79811. +MODULE_PARM_DESC(request_size, "size of each request");
  79812. +
  79813. +/*
  79814. + * a structure for each request
  79815. + */
  79816. +typedef struct {
  79817. + struct work_struct work;
  79818. +#ifdef BENCH_IXP_ACCESS_LIB
  79819. + IX_MBUF mbuf;
  79820. +#endif
  79821. + unsigned char *buffer;
  79822. +} request_t;
  79823. +
  79824. +static request_t *requests;
  79825. +
  79826. +static int outstanding;
  79827. +static int total;
  79828. +
  79829. +/*************************************************************************/
  79830. +/*
  79831. + * OCF benchmark routines
  79832. + */
  79833. +
  79834. +static uint64_t ocf_cryptoid;
  79835. +static int ocf_init(void);
  79836. +static int ocf_cb(struct cryptop *crp);
  79837. +static void ocf_request(void *arg);
  79838. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  79839. +static void ocf_request_wq(struct work_struct *work);
  79840. +#endif
  79841. +
  79842. +static int
  79843. +ocf_init(void)
  79844. +{
  79845. + int error;
  79846. + struct cryptoini crie, cria;
  79847. + struct cryptodesc crda, crde;
  79848. +
  79849. + memset(&crie, 0, sizeof(crie));
  79850. + memset(&cria, 0, sizeof(cria));
  79851. + memset(&crde, 0, sizeof(crde));
  79852. + memset(&crda, 0, sizeof(crda));
  79853. +
  79854. + cria.cri_alg = CRYPTO_SHA1_HMAC;
  79855. + cria.cri_klen = 20 * 8;
  79856. + cria.cri_key = "0123456789abcdefghij";
  79857. +
  79858. + crie.cri_alg = CRYPTO_3DES_CBC;
  79859. + crie.cri_klen = 24 * 8;
  79860. + crie.cri_key = "0123456789abcdefghijklmn";
  79861. +
  79862. + crie.cri_next = &cria;
  79863. +
  79864. + error = crypto_newsession(&ocf_cryptoid, &crie, 0);
  79865. + if (error) {
  79866. + printk("crypto_newsession failed %d\n", error);
  79867. + return -1;
  79868. + }
  79869. + return 0;
  79870. +}
  79871. +
  79872. +static int
  79873. +ocf_cb(struct cryptop *crp)
  79874. +{
  79875. + request_t *r = (request_t *) crp->crp_opaque;
  79876. +
  79877. + if (crp->crp_etype)
  79878. + printk("Error in OCF processing: %d\n", crp->crp_etype);
  79879. + total++;
  79880. + crypto_freereq(crp);
  79881. + crp = NULL;
  79882. +
  79883. + if (total > request_num) {
  79884. + outstanding--;
  79885. + return 0;
  79886. + }
  79887. +
  79888. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  79889. + INIT_WORK(&r->work, ocf_request_wq);
  79890. +#else
  79891. + INIT_WORK(&r->work, ocf_request, r);
  79892. +#endif
  79893. + schedule_work(&r->work);
  79894. + return 0;
  79895. +}
  79896. +
  79897. +
  79898. +static void
  79899. +ocf_request(void *arg)
  79900. +{
  79901. + request_t *r = arg;
  79902. + struct cryptop *crp = crypto_getreq(2);
  79903. + struct cryptodesc *crde, *crda;
  79904. +
  79905. + if (!crp) {
  79906. + outstanding--;
  79907. + return;
  79908. + }
  79909. +
  79910. + crde = crp->crp_desc;
  79911. + crda = crde->crd_next;
  79912. +
  79913. + crda->crd_skip = 0;
  79914. + crda->crd_flags = 0;
  79915. + crda->crd_len = request_size;
  79916. + crda->crd_inject = request_size;
  79917. + crda->crd_alg = CRYPTO_SHA1_HMAC;
  79918. + crda->crd_key = "0123456789abcdefghij";
  79919. + crda->crd_klen = 20 * 8;
  79920. +
  79921. + crde->crd_skip = 0;
  79922. + crde->crd_flags = CRD_F_IV_EXPLICIT | CRD_F_ENCRYPT;
  79923. + crde->crd_len = request_size;
  79924. + crde->crd_inject = request_size;
  79925. + crde->crd_alg = CRYPTO_3DES_CBC;
  79926. + crde->crd_key = "0123456789abcdefghijklmn";
  79927. + crde->crd_klen = 24 * 8;
  79928. +
  79929. + crp->crp_ilen = request_size + 64;
  79930. + crp->crp_flags = CRYPTO_F_CBIMM;
  79931. + crp->crp_buf = (caddr_t) r->buffer;
  79932. + crp->crp_callback = ocf_cb;
  79933. + crp->crp_sid = ocf_cryptoid;
  79934. + crp->crp_opaque = (caddr_t) r;
  79935. + crypto_dispatch(crp);
  79936. +}
  79937. +
  79938. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  79939. +static void
  79940. +ocf_request_wq(struct work_struct *work)
  79941. +{
  79942. + request_t *r = container_of(work, request_t, work);
  79943. + ocf_request(r);
  79944. +}
  79945. +#endif
  79946. +
  79947. +/*************************************************************************/
  79948. +#ifdef BENCH_IXP_ACCESS_LIB
  79949. +/*************************************************************************/
  79950. +/*
  79951. + * CryptoAcc benchmark routines
  79952. + */
  79953. +
  79954. +static IxCryptoAccCtx ixp_ctx;
  79955. +static UINT32 ixp_ctx_id;
  79956. +static IX_MBUF ixp_pri;
  79957. +static IX_MBUF ixp_sec;
  79958. +static int ixp_registered = 0;
  79959. +
  79960. +static void ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp,
  79961. + IxCryptoAccStatus status);
  79962. +static void ixp_perform_cb(UINT32 ctx_id, IX_MBUF *sbufp, IX_MBUF *dbufp,
  79963. + IxCryptoAccStatus status);
  79964. +static void ixp_request(void *arg);
  79965. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  79966. +static void ixp_request_wq(struct work_struct *work);
  79967. +#endif
  79968. +
  79969. +static int
  79970. +ixp_init(void)
  79971. +{
  79972. + IxCryptoAccStatus status;
  79973. +
  79974. + ixp_ctx.cipherCtx.cipherAlgo = IX_CRYPTO_ACC_CIPHER_3DES;
  79975. + ixp_ctx.cipherCtx.cipherMode = IX_CRYPTO_ACC_MODE_CBC;
  79976. + ixp_ctx.cipherCtx.cipherKeyLen = 24;
  79977. + ixp_ctx.cipherCtx.cipherBlockLen = IX_CRYPTO_ACC_DES_BLOCK_64;
  79978. + ixp_ctx.cipherCtx.cipherInitialVectorLen = IX_CRYPTO_ACC_DES_IV_64;
  79979. + memcpy(ixp_ctx.cipherCtx.key.cipherKey, "0123456789abcdefghijklmn", 24);
  79980. +
  79981. + ixp_ctx.authCtx.authAlgo = IX_CRYPTO_ACC_AUTH_SHA1;
  79982. + ixp_ctx.authCtx.authDigestLen = 12;
  79983. + ixp_ctx.authCtx.aadLen = 0;
  79984. + ixp_ctx.authCtx.authKeyLen = 20;
  79985. + memcpy(ixp_ctx.authCtx.key.authKey, "0123456789abcdefghij", 20);
  79986. +
  79987. + ixp_ctx.useDifferentSrcAndDestMbufs = 0;
  79988. + ixp_ctx.operation = IX_CRYPTO_ACC_OP_ENCRYPT_AUTH ;
  79989. +
  79990. + IX_MBUF_MLEN(&ixp_pri) = IX_MBUF_PKT_LEN(&ixp_pri) = 128;
  79991. + IX_MBUF_MDATA(&ixp_pri) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  79992. + IX_MBUF_MLEN(&ixp_sec) = IX_MBUF_PKT_LEN(&ixp_sec) = 128;
  79993. + IX_MBUF_MDATA(&ixp_sec) = (unsigned char *) kmalloc(128, SLAB_ATOMIC);
  79994. +
  79995. + status = ixCryptoAccCtxRegister(&ixp_ctx, &ixp_pri, &ixp_sec,
  79996. + ixp_register_cb, ixp_perform_cb, &ixp_ctx_id);
  79997. +
  79998. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status) {
  79999. + while (!ixp_registered)
  80000. + schedule();
  80001. + return ixp_registered < 0 ? -1 : 0;
  80002. + }
  80003. +
  80004. + printk("ixp: ixCryptoAccCtxRegister failed %d\n", status);
  80005. + return -1;
  80006. +}
  80007. +
  80008. +static void
  80009. +ixp_register_cb(UINT32 ctx_id, IX_MBUF *bufp, IxCryptoAccStatus status)
  80010. +{
  80011. + if (bufp) {
  80012. + IX_MBUF_MLEN(bufp) = IX_MBUF_PKT_LEN(bufp) = 0;
  80013. + kfree(IX_MBUF_MDATA(bufp));
  80014. + IX_MBUF_MDATA(bufp) = NULL;
  80015. + }
  80016. +
  80017. + if (IX_CRYPTO_ACC_STATUS_WAIT == status)
  80018. + return;
  80019. + if (IX_CRYPTO_ACC_STATUS_SUCCESS == status)
  80020. + ixp_registered = 1;
  80021. + else
  80022. + ixp_registered = -1;
  80023. +}
  80024. +
  80025. +static void
  80026. +ixp_perform_cb(
  80027. + UINT32 ctx_id,
  80028. + IX_MBUF *sbufp,
  80029. + IX_MBUF *dbufp,
  80030. + IxCryptoAccStatus status)
  80031. +{
  80032. + request_t *r = NULL;
  80033. +
  80034. + total++;
  80035. + if (total > request_num) {
  80036. + outstanding--;
  80037. + return;
  80038. + }
  80039. +
  80040. + if (!sbufp || !(r = IX_MBUF_PRIV(sbufp))) {
  80041. + printk("crappo %p %p\n", sbufp, r);
  80042. + outstanding--;
  80043. + return;
  80044. + }
  80045. +
  80046. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  80047. + INIT_WORK(&r->work, ixp_request_wq);
  80048. +#else
  80049. + INIT_WORK(&r->work, ixp_request, r);
  80050. +#endif
  80051. + schedule_work(&r->work);
  80052. +}
  80053. +
  80054. +static void
  80055. +ixp_request(void *arg)
  80056. +{
  80057. + request_t *r = arg;
  80058. + IxCryptoAccStatus status;
  80059. +
  80060. + memset(&r->mbuf, 0, sizeof(r->mbuf));
  80061. + IX_MBUF_MLEN(&r->mbuf) = IX_MBUF_PKT_LEN(&r->mbuf) = request_size + 64;
  80062. + IX_MBUF_MDATA(&r->mbuf) = r->buffer;
  80063. + IX_MBUF_PRIV(&r->mbuf) = r;
  80064. + status = ixCryptoAccAuthCryptPerform(ixp_ctx_id, &r->mbuf, NULL,
  80065. + 0, request_size, 0, request_size, request_size, r->buffer);
  80066. + if (IX_CRYPTO_ACC_STATUS_SUCCESS != status) {
  80067. + printk("status1 = %d\n", status);
  80068. + outstanding--;
  80069. + return;
  80070. + }
  80071. + return;
  80072. +}
  80073. +
  80074. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20)
  80075. +static void
  80076. +ixp_request_wq(struct work_struct *work)
  80077. +{
  80078. + request_t *r = container_of(work, request_t, work);
  80079. + ixp_request(r);
  80080. +}
  80081. +#endif
  80082. +
  80083. +/*************************************************************************/
  80084. +#endif /* BENCH_IXP_ACCESS_LIB */
  80085. +/*************************************************************************/
  80086. +
  80087. +int
  80088. +ocfbench_init(void)
  80089. +{
  80090. + int i, jstart, jstop;
  80091. +
  80092. + printk("Crypto Speed tests\n");
  80093. +
  80094. + requests = kmalloc(sizeof(request_t) * request_q_len, GFP_KERNEL);
  80095. + if (!requests) {
  80096. + printk("malloc failed\n");
  80097. + return -EINVAL;
  80098. + }
  80099. +
  80100. + for (i = 0; i < request_q_len; i++) {
  80101. + /* +64 for return data */
  80102. + requests[i].buffer = kmalloc(request_size + 128, GFP_DMA);
  80103. + if (!requests[i].buffer) {
  80104. + printk("malloc failed\n");
  80105. + return -EINVAL;
  80106. + }
  80107. + memset(requests[i].buffer, '0' + i, request_size + 128);
  80108. + }
  80109. +
  80110. + /*
  80111. + * OCF benchmark
  80112. + */
  80113. + printk("OCF: testing ...\n");
  80114. + ocf_init();
  80115. + total = outstanding = 0;
  80116. + jstart = jiffies;
  80117. + for (i = 0; i < request_q_len; i++) {
  80118. + outstanding++;
  80119. + ocf_request(&requests[i]);
  80120. + }
  80121. + while (outstanding > 0)
  80122. + schedule();
  80123. + jstop = jiffies;
  80124. +
  80125. + printk("OCF: %d requests of %d bytes in %d jiffies\n", total, request_size,
  80126. + jstop - jstart);
  80127. +
  80128. +#ifdef BENCH_IXP_ACCESS_LIB
  80129. + /*
  80130. + * IXP benchmark
  80131. + */
  80132. + printk("IXP: testing ...\n");
  80133. + ixp_init();
  80134. + total = outstanding = 0;
  80135. + jstart = jiffies;
  80136. + for (i = 0; i < request_q_len; i++) {
  80137. + outstanding++;
  80138. + ixp_request(&requests[i]);
  80139. + }
  80140. + while (outstanding > 0)
  80141. + schedule();
  80142. + jstop = jiffies;
  80143. +
  80144. + printk("IXP: %d requests of %d bytes in %d jiffies\n", total, request_size,
  80145. + jstop - jstart);
  80146. +#endif /* BENCH_IXP_ACCESS_LIB */
  80147. +
  80148. + for (i = 0; i < request_q_len; i++)
  80149. + kfree(requests[i].buffer);
  80150. + kfree(requests);
  80151. + return -EINVAL; /* always fail to load so it can be re-run quickly ;-) */
  80152. +}
  80153. +
  80154. +static void __exit ocfbench_exit(void)
  80155. +{
  80156. +}
  80157. +
  80158. +module_init(ocfbench_init);
  80159. +module_exit(ocfbench_exit);
  80160. +
  80161. +MODULE_LICENSE("BSD");
  80162. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  80163. +MODULE_DESCRIPTION("Benchmark various in-kernel crypto speeds");
  80164. diff -Nur linux-2.6.39.orig/crypto/ocf/ocf-compat.h linux-2.6.39/crypto/ocf/ocf-compat.h
  80165. --- linux-2.6.39.orig/crypto/ocf/ocf-compat.h 1970-01-01 01:00:00.000000000 +0100
  80166. +++ linux-2.6.39/crypto/ocf/ocf-compat.h 2011-08-01 14:38:19.000000000 +0200
  80167. @@ -0,0 +1,294 @@
  80168. +#ifndef _BSD_COMPAT_H_
  80169. +#define _BSD_COMPAT_H_ 1
  80170. +/****************************************************************************/
  80171. +/*
  80172. + * Provide compat routines for older linux kernels and BSD kernels
  80173. + *
  80174. + * Written by David McCullough <david_mccullough@mcafee.com>
  80175. + * Copyright (C) 2010 David McCullough <david_mccullough@mcafee.com>
  80176. + *
  80177. + * LICENSE TERMS
  80178. + *
  80179. + * The free distribution and use of this software in both source and binary
  80180. + * form is allowed (with or without changes) provided that:
  80181. + *
  80182. + * 1. distributions of this source code include the above copyright
  80183. + * notice, this list of conditions and the following disclaimer;
  80184. + *
  80185. + * 2. distributions in binary form include the above copyright
  80186. + * notice, this list of conditions and the following disclaimer
  80187. + * in the documentation and/or other associated materials;
  80188. + *
  80189. + * 3. the copyright holder's name is not used to endorse products
  80190. + * built using this software without specific written permission.
  80191. + *
  80192. + * ALTERNATIVELY, provided that this notice is retained in full, this file
  80193. + * may be distributed under the terms of the GNU General Public License (GPL),
  80194. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  80195. + *
  80196. + * DISCLAIMER
  80197. + *
  80198. + * This software is provided 'as is' with no explicit or implied warranties
  80199. + * in respect of its properties, including, but not limited to, correctness
  80200. + * and/or fitness for purpose.
  80201. + */
  80202. +/****************************************************************************/
  80203. +#ifdef __KERNEL__
  80204. +/*
  80205. + * fake some BSD driver interface stuff specifically for OCF use
  80206. + */
  80207. +
  80208. +typedef struct ocf_device *device_t;
  80209. +
  80210. +typedef struct {
  80211. + int (*cryptodev_newsession)(device_t dev, u_int32_t *sidp, struct cryptoini *cri);
  80212. + int (*cryptodev_freesession)(device_t dev, u_int64_t tid);
  80213. + int (*cryptodev_process)(device_t dev, struct cryptop *crp, int hint);
  80214. + int (*cryptodev_kprocess)(device_t dev, struct cryptkop *krp, int hint);
  80215. +} device_method_t;
  80216. +#define DEVMETHOD(id, func) id: func
  80217. +
  80218. +struct ocf_device {
  80219. + char name[32]; /* the driver name */
  80220. + char nameunit[32]; /* the driver name + HW instance */
  80221. + int unit;
  80222. + device_method_t methods;
  80223. + void *softc;
  80224. +};
  80225. +
  80226. +#define CRYPTODEV_NEWSESSION(dev, sid, cri) \
  80227. + ((*(dev)->methods.cryptodev_newsession)(dev,sid,cri))
  80228. +#define CRYPTODEV_FREESESSION(dev, sid) \
  80229. + ((*(dev)->methods.cryptodev_freesession)(dev, sid))
  80230. +#define CRYPTODEV_PROCESS(dev, crp, hint) \
  80231. + ((*(dev)->methods.cryptodev_process)(dev, crp, hint))
  80232. +#define CRYPTODEV_KPROCESS(dev, krp, hint) \
  80233. + ((*(dev)->methods.cryptodev_kprocess)(dev, krp, hint))
  80234. +
  80235. +#define device_get_name(dev) ((dev)->name)
  80236. +#define device_get_nameunit(dev) ((dev)->nameunit)
  80237. +#define device_get_unit(dev) ((dev)->unit)
  80238. +#define device_get_softc(dev) ((dev)->softc)
  80239. +
  80240. +#define softc_device_decl \
  80241. + struct ocf_device _device; \
  80242. + device_t
  80243. +
  80244. +#define softc_device_init(_sc, _name, _unit, _methods) \
  80245. + if (1) {\
  80246. + strncpy((_sc)->_device.name, _name, sizeof((_sc)->_device.name) - 1); \
  80247. + snprintf((_sc)->_device.nameunit, sizeof((_sc)->_device.name), "%s%d", _name, _unit); \
  80248. + (_sc)->_device.unit = _unit; \
  80249. + (_sc)->_device.methods = _methods; \
  80250. + (_sc)->_device.softc = (void *) _sc; \
  80251. + *(device_t *)((softc_get_device(_sc))+1) = &(_sc)->_device; \
  80252. + } else
  80253. +
  80254. +#define softc_get_device(_sc) (&(_sc)->_device)
  80255. +
  80256. +/*
  80257. + * iomem support for 2.4 and 2.6 kernels
  80258. + */
  80259. +#include <linux/version.h>
  80260. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  80261. +#define ocf_iomem_t unsigned long
  80262. +
  80263. +/*
  80264. + * implement simple workqueue like support for older kernels
  80265. + */
  80266. +
  80267. +#include <linux/tqueue.h>
  80268. +
  80269. +#define work_struct tq_struct
  80270. +
  80271. +#define INIT_WORK(wp, fp, ap) \
  80272. + do { \
  80273. + (wp)->sync = 0; \
  80274. + (wp)->routine = (fp); \
  80275. + (wp)->data = (ap); \
  80276. + } while (0)
  80277. +
  80278. +#define schedule_work(wp) \
  80279. + do { \
  80280. + queue_task((wp), &tq_immediate); \
  80281. + mark_bh(IMMEDIATE_BH); \
  80282. + } while (0)
  80283. +
  80284. +#define flush_scheduled_work() run_task_queue(&tq_immediate)
  80285. +
  80286. +#else
  80287. +#define ocf_iomem_t void __iomem *
  80288. +
  80289. +#include <linux/workqueue.h>
  80290. +
  80291. +#endif
  80292. +
  80293. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,26)
  80294. +#include <linux/fdtable.h>
  80295. +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
  80296. +#define files_fdtable(files) (files)
  80297. +#endif
  80298. +
  80299. +#ifdef MODULE_PARM
  80300. +#undef module_param /* just in case */
  80301. +#define module_param(a,b,c) MODULE_PARM(a,"i")
  80302. +#endif
  80303. +
  80304. +#define bzero(s,l) memset(s,0,l)
  80305. +#define bcopy(s,d,l) memcpy(d,s,l)
  80306. +#define bcmp(x, y, l) memcmp(x,y,l)
  80307. +
  80308. +#define MIN(x,y) ((x) < (y) ? (x) : (y))
  80309. +
  80310. +#define device_printf(dev, a...) ({ \
  80311. + printk("%s: ", device_get_nameunit(dev)); printk(a); \
  80312. + })
  80313. +
  80314. +#undef printf
  80315. +#define printf(fmt...) printk(fmt)
  80316. +
  80317. +#define KASSERT(c,p) if (!(c)) { printk p ; } else
  80318. +
  80319. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  80320. +#define ocf_daemonize(str) \
  80321. + daemonize(); \
  80322. + spin_lock_irq(&current->sigmask_lock); \
  80323. + sigemptyset(&current->blocked); \
  80324. + recalc_sigpending(current); \
  80325. + spin_unlock_irq(&current->sigmask_lock); \
  80326. + sprintf(current->comm, str);
  80327. +#else
  80328. +#define ocf_daemonize(str) daemonize(str);
  80329. +#endif
  80330. +
  80331. +#define TAILQ_INSERT_TAIL(q,d,m) list_add_tail(&(d)->m, (q))
  80332. +#define TAILQ_EMPTY(q) list_empty(q)
  80333. +#define TAILQ_FOREACH(v, q, m) list_for_each_entry(v, q, m)
  80334. +
  80335. +#define read_random(p,l) get_random_bytes(p,l)
  80336. +
  80337. +#define DELAY(x) ((x) > 2000 ? mdelay((x)/1000) : udelay(x))
  80338. +#define strtoul simple_strtoul
  80339. +
  80340. +#define pci_get_vendor(dev) ((dev)->vendor)
  80341. +#define pci_get_device(dev) ((dev)->device)
  80342. +
  80343. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  80344. +#define pci_set_consistent_dma_mask(dev, mask) (0)
  80345. +#endif
  80346. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
  80347. +#define pci_dma_sync_single_for_cpu pci_dma_sync_single
  80348. +#endif
  80349. +
  80350. +#ifndef DMA_32BIT_MASK
  80351. +#define DMA_32BIT_MASK 0x00000000ffffffffULL
  80352. +#endif
  80353. +
  80354. +#ifndef htole32
  80355. +#define htole32(x) cpu_to_le32(x)
  80356. +#endif
  80357. +#ifndef htobe32
  80358. +#define htobe32(x) cpu_to_be32(x)
  80359. +#endif
  80360. +#ifndef htole16
  80361. +#define htole16(x) cpu_to_le16(x)
  80362. +#endif
  80363. +#ifndef htobe16
  80364. +#define htobe16(x) cpu_to_be16(x)
  80365. +#endif
  80366. +
  80367. +/* older kernels don't have these */
  80368. +
  80369. +#include <asm/irq.h>
  80370. +#if !defined(IRQ_NONE) && !defined(IRQ_RETVAL)
  80371. +#define IRQ_NONE
  80372. +#define IRQ_HANDLED
  80373. +#define IRQ_WAKE_THREAD
  80374. +#define IRQ_RETVAL
  80375. +#define irqreturn_t void
  80376. +typedef irqreturn_t (*irq_handler_t)(int irq, void *arg, struct pt_regs *regs);
  80377. +#endif
  80378. +#ifndef IRQF_SHARED
  80379. +#define IRQF_SHARED SA_SHIRQ
  80380. +#endif
  80381. +
  80382. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
  80383. +# define strlcpy(dest,src,len) \
  80384. + ({strncpy(dest,src,(len)-1); ((char *)dest)[(len)-1] = '\0'; })
  80385. +#endif
  80386. +
  80387. +#ifndef MAX_ERRNO
  80388. +#define MAX_ERRNO 4095
  80389. +#endif
  80390. +#ifndef IS_ERR_VALUE
  80391. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,5)
  80392. +#include <linux/err.h>
  80393. +#endif
  80394. +#ifndef IS_ERR_VALUE
  80395. +#define IS_ERR_VALUE(x) ((unsigned long)(x) >= (unsigned long)-MAX_ERRNO)
  80396. +#endif
  80397. +#endif
  80398. +
  80399. +/*
  80400. + * common debug for all
  80401. + */
  80402. +#if 1
  80403. +#define dprintk(a...) do { if (debug) printk(a); } while(0)
  80404. +#else
  80405. +#define dprintk(a...)
  80406. +#endif
  80407. +
  80408. +#ifndef SLAB_ATOMIC
  80409. +/* Changed in 2.6.20, must use GFP_ATOMIC now */
  80410. +#define SLAB_ATOMIC GFP_ATOMIC
  80411. +#endif
  80412. +
  80413. +/*
  80414. + * need some additional support for older kernels */
  80415. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,2)
  80416. +#define pci_register_driver_compat(driver, rc) \
  80417. + do { \
  80418. + if ((rc) > 0) { \
  80419. + (rc) = 0; \
  80420. + } else if (rc == 0) { \
  80421. + (rc) = -ENODEV; \
  80422. + } else { \
  80423. + pci_unregister_driver(driver); \
  80424. + } \
  80425. + } while (0)
  80426. +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
  80427. +#define pci_register_driver_compat(driver,rc) ((rc) = (rc) < 0 ? (rc) : 0)
  80428. +#else
  80429. +#define pci_register_driver_compat(driver,rc)
  80430. +#endif
  80431. +
  80432. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
  80433. +
  80434. +#include <linux/mm.h>
  80435. +#include <asm/scatterlist.h>
  80436. +
  80437. +static inline void sg_set_page(struct scatterlist *sg, struct page *page,
  80438. + unsigned int len, unsigned int offset)
  80439. +{
  80440. + sg->page = page;
  80441. + sg->offset = offset;
  80442. + sg->length = len;
  80443. +}
  80444. +
  80445. +static inline void *sg_virt(struct scatterlist *sg)
  80446. +{
  80447. + return page_address(sg->page) + sg->offset;
  80448. +}
  80449. +
  80450. +#define sg_init_table(sg, n)
  80451. +
  80452. +#endif
  80453. +
  80454. +#ifndef late_initcall
  80455. +#define late_initcall(init) module_init(init)
  80456. +#endif
  80457. +
  80458. +#endif /* __KERNEL__ */
  80459. +
  80460. +/****************************************************************************/
  80461. +#endif /* _BSD_COMPAT_H_ */
  80462. diff -Nur linux-2.6.39.orig/crypto/ocf/ocfnull/Makefile linux-2.6.39/crypto/ocf/ocfnull/Makefile
  80463. --- linux-2.6.39.orig/crypto/ocf/ocfnull/Makefile 1970-01-01 01:00:00.000000000 +0100
  80464. +++ linux-2.6.39/crypto/ocf/ocfnull/Makefile 2011-08-01 14:38:19.000000000 +0200
  80465. @@ -0,0 +1,12 @@
  80466. +# for SGlinux builds
  80467. +-include $(ROOTDIR)/modules/.config
  80468. +
  80469. +obj-$(CONFIG_OCF_OCFNULL) += ocfnull.o
  80470. +
  80471. +obj ?= .
  80472. +EXTRA_CFLAGS += -I$(obj)/..
  80473. +
  80474. +ifdef TOPDIR
  80475. +-include $(TOPDIR)/Rules.make
  80476. +endif
  80477. +
  80478. diff -Nur linux-2.6.39.orig/crypto/ocf/ocfnull/ocfnull.c linux-2.6.39/crypto/ocf/ocfnull/ocfnull.c
  80479. --- linux-2.6.39.orig/crypto/ocf/ocfnull/ocfnull.c 1970-01-01 01:00:00.000000000 +0100
  80480. +++ linux-2.6.39/crypto/ocf/ocfnull/ocfnull.c 2011-08-01 14:38:19.000000000 +0200
  80481. @@ -0,0 +1,203 @@
  80482. +/*
  80483. + * An OCF module for determining the cost of crypto versus the cost of
  80484. + * IPSec processing outside of OCF. This modules gives us the effect of
  80485. + * zero cost encryption, of course you will need to run it at both ends
  80486. + * since it does no crypto at all.
  80487. + *
  80488. + * Written by David McCullough <david_mccullough@mcafee.com>
  80489. + * Copyright (C) 2006-2010 David McCullough
  80490. + *
  80491. + * LICENSE TERMS
  80492. + *
  80493. + * The free distribution and use of this software in both source and binary
  80494. + * form is allowed (with or without changes) provided that:
  80495. + *
  80496. + * 1. distributions of this source code include the above copyright
  80497. + * notice, this list of conditions and the following disclaimer;
  80498. + *
  80499. + * 2. distributions in binary form include the above copyright
  80500. + * notice, this list of conditions and the following disclaimer
  80501. + * in the documentation and/or other associated materials;
  80502. + *
  80503. + * 3. the copyright holder's name is not used to endorse products
  80504. + * built using this software without specific written permission.
  80505. + *
  80506. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  80507. + * may be distributed under the terms of the GNU General Public License (GPL),
  80508. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  80509. + *
  80510. + * DISCLAIMER
  80511. + *
  80512. + * This software is provided 'as is' with no explicit or implied warranties
  80513. + * in respect of its properties, including, but not limited to, correctness
  80514. + * and/or fitness for purpose.
  80515. + */
  80516. +
  80517. +#ifndef AUTOCONF_INCLUDED
  80518. +#include <linux/config.h>
  80519. +#endif
  80520. +#include <linux/module.h>
  80521. +#include <linux/init.h>
  80522. +#include <linux/list.h>
  80523. +#include <linux/slab.h>
  80524. +#include <linux/sched.h>
  80525. +#include <linux/wait.h>
  80526. +#include <linux/crypto.h>
  80527. +#include <linux/interrupt.h>
  80528. +
  80529. +#include <cryptodev.h>
  80530. +#include <uio.h>
  80531. +
  80532. +static int32_t null_id = -1;
  80533. +static u_int32_t null_sesnum = 0;
  80534. +
  80535. +static int null_process(device_t, struct cryptop *, int);
  80536. +static int null_newsession(device_t, u_int32_t *, struct cryptoini *);
  80537. +static int null_freesession(device_t, u_int64_t);
  80538. +
  80539. +#define debug ocfnull_debug
  80540. +int ocfnull_debug = 0;
  80541. +module_param(ocfnull_debug, int, 0644);
  80542. +MODULE_PARM_DESC(ocfnull_debug, "Enable debug");
  80543. +
  80544. +/*
  80545. + * dummy device structure
  80546. + */
  80547. +
  80548. +static struct {
  80549. + softc_device_decl sc_dev;
  80550. +} nulldev;
  80551. +
  80552. +static device_method_t null_methods = {
  80553. + /* crypto device methods */
  80554. + DEVMETHOD(cryptodev_newsession, null_newsession),
  80555. + DEVMETHOD(cryptodev_freesession,null_freesession),
  80556. + DEVMETHOD(cryptodev_process, null_process),
  80557. +};
  80558. +
  80559. +/*
  80560. + * Generate a new software session.
  80561. + */
  80562. +static int
  80563. +null_newsession(device_t arg, u_int32_t *sid, struct cryptoini *cri)
  80564. +{
  80565. + dprintk("%s()\n", __FUNCTION__);
  80566. + if (sid == NULL || cri == NULL) {
  80567. + dprintk("%s,%d - EINVAL\n", __FILE__, __LINE__);
  80568. + return EINVAL;
  80569. + }
  80570. +
  80571. + if (null_sesnum == 0)
  80572. + null_sesnum++;
  80573. + *sid = null_sesnum++;
  80574. + return 0;
  80575. +}
  80576. +
  80577. +
  80578. +/*
  80579. + * Free a session.
  80580. + */
  80581. +static int
  80582. +null_freesession(device_t arg, u_int64_t tid)
  80583. +{
  80584. + u_int32_t sid = CRYPTO_SESID2LID(tid);
  80585. +
  80586. + dprintk("%s()\n", __FUNCTION__);
  80587. + if (sid > null_sesnum) {
  80588. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  80589. + return EINVAL;
  80590. + }
  80591. +
  80592. + /* Silently accept and return */
  80593. + if (sid == 0)
  80594. + return 0;
  80595. + return 0;
  80596. +}
  80597. +
  80598. +
  80599. +/*
  80600. + * Process a request.
  80601. + */
  80602. +static int
  80603. +null_process(device_t arg, struct cryptop *crp, int hint)
  80604. +{
  80605. + unsigned int lid;
  80606. +
  80607. + dprintk("%s()\n", __FUNCTION__);
  80608. +
  80609. + /* Sanity check */
  80610. + if (crp == NULL) {
  80611. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  80612. + return EINVAL;
  80613. + }
  80614. +
  80615. + crp->crp_etype = 0;
  80616. +
  80617. + if (crp->crp_desc == NULL || crp->crp_buf == NULL) {
  80618. + dprintk("%s,%d: EINVAL\n", __FILE__, __LINE__);
  80619. + crp->crp_etype = EINVAL;
  80620. + goto done;
  80621. + }
  80622. +
  80623. + /*
  80624. + * find the session we are using
  80625. + */
  80626. +
  80627. + lid = crp->crp_sid & 0xffffffff;
  80628. + if (lid >= null_sesnum || lid == 0) {
  80629. + crp->crp_etype = ENOENT;
  80630. + dprintk("%s,%d: ENOENT\n", __FILE__, __LINE__);
  80631. + goto done;
  80632. + }
  80633. +
  80634. +done:
  80635. + crypto_done(crp);
  80636. + return 0;
  80637. +}
  80638. +
  80639. +
  80640. +/*
  80641. + * our driver startup and shutdown routines
  80642. + */
  80643. +
  80644. +static int
  80645. +null_init(void)
  80646. +{
  80647. + dprintk("%s(%p)\n", __FUNCTION__, null_init);
  80648. +
  80649. + memset(&nulldev, 0, sizeof(nulldev));
  80650. + softc_device_init(&nulldev, "ocfnull", 0, null_methods);
  80651. +
  80652. + null_id = crypto_get_driverid(softc_get_device(&nulldev),
  80653. + CRYPTOCAP_F_HARDWARE);
  80654. + if (null_id < 0)
  80655. + panic("ocfnull: crypto device cannot initialize!");
  80656. +
  80657. +#define REGISTER(alg) \
  80658. + crypto_register(null_id,alg,0,0)
  80659. + REGISTER(CRYPTO_DES_CBC);
  80660. + REGISTER(CRYPTO_3DES_CBC);
  80661. + REGISTER(CRYPTO_RIJNDAEL128_CBC);
  80662. + REGISTER(CRYPTO_MD5);
  80663. + REGISTER(CRYPTO_SHA1);
  80664. + REGISTER(CRYPTO_MD5_HMAC);
  80665. + REGISTER(CRYPTO_SHA1_HMAC);
  80666. +#undef REGISTER
  80667. +
  80668. + return 0;
  80669. +}
  80670. +
  80671. +static void
  80672. +null_exit(void)
  80673. +{
  80674. + dprintk("%s()\n", __FUNCTION__);
  80675. + crypto_unregister_all(null_id);
  80676. + null_id = -1;
  80677. +}
  80678. +
  80679. +module_init(null_init);
  80680. +module_exit(null_exit);
  80681. +
  80682. +MODULE_LICENSE("Dual BSD/GPL");
  80683. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  80684. +MODULE_DESCRIPTION("ocfnull - claims a lot but does nothing");
  80685. diff -Nur linux-2.6.39.orig/crypto/ocf/pasemi/Makefile linux-2.6.39/crypto/ocf/pasemi/Makefile
  80686. --- linux-2.6.39.orig/crypto/ocf/pasemi/Makefile 1970-01-01 01:00:00.000000000 +0100
  80687. +++ linux-2.6.39/crypto/ocf/pasemi/Makefile 2011-08-01 14:38:19.000000000 +0200
  80688. @@ -0,0 +1,12 @@
  80689. +# for SGlinux builds
  80690. +-include $(ROOTDIR)/modules/.config
  80691. +
  80692. +obj-$(CONFIG_OCF_PASEMI) += pasemi.o
  80693. +
  80694. +obj ?= .
  80695. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  80696. +
  80697. +ifdef TOPDIR
  80698. +-include $(TOPDIR)/Rules.make
  80699. +endif
  80700. +
  80701. diff -Nur linux-2.6.39.orig/crypto/ocf/pasemi/pasemi.c linux-2.6.39/crypto/ocf/pasemi/pasemi.c
  80702. --- linux-2.6.39.orig/crypto/ocf/pasemi/pasemi.c 1970-01-01 01:00:00.000000000 +0100
  80703. +++ linux-2.6.39/crypto/ocf/pasemi/pasemi.c 2011-08-01 14:38:19.000000000 +0200
  80704. @@ -0,0 +1,1009 @@
  80705. +/*
  80706. + * Copyright (C) 2007 PA Semi, Inc
  80707. + *
  80708. + * Driver for the PA Semi PWRficient DMA Crypto Engine
  80709. + *
  80710. + * This program is free software; you can redistribute it and/or modify
  80711. + * it under the terms of the GNU General Public License version 2 as
  80712. + * published by the Free Software Foundation.
  80713. + *
  80714. + * This program is distributed in the hope that it will be useful,
  80715. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  80716. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  80717. + * GNU General Public License for more details.
  80718. + *
  80719. + * You should have received a copy of the GNU General Public License
  80720. + * along with this program; if not, write to the Free Software
  80721. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  80722. + */
  80723. +
  80724. +#ifndef AUTOCONF_INCLUDED
  80725. +#include <linux/config.h>
  80726. +#endif
  80727. +#include <linux/module.h>
  80728. +#include <linux/init.h>
  80729. +#include <linux/interrupt.h>
  80730. +#include <linux/timer.h>
  80731. +#include <linux/random.h>
  80732. +#include <linux/skbuff.h>
  80733. +#include <asm/scatterlist.h>
  80734. +#include <linux/moduleparam.h>
  80735. +#include <linux/pci.h>
  80736. +#include <cryptodev.h>
  80737. +#include <uio.h>
  80738. +#include "pasemi_fnu.h"
  80739. +
  80740. +#define DRV_NAME "pasemi"
  80741. +
  80742. +#define TIMER_INTERVAL 1000
  80743. +
  80744. +static void __devexit pasemi_dma_remove(struct pci_dev *pdev);
  80745. +static struct pasdma_status volatile * dma_status;
  80746. +
  80747. +static int debug;
  80748. +module_param(debug, int, 0644);
  80749. +MODULE_PARM_DESC(debug, "Enable debug");
  80750. +
  80751. +static void pasemi_desc_start(struct pasemi_desc *desc, u64 hdr)
  80752. +{
  80753. + desc->postop = 0;
  80754. + desc->quad[0] = hdr;
  80755. + desc->quad_cnt = 1;
  80756. + desc->size = 1;
  80757. +}
  80758. +
  80759. +static void pasemi_desc_build(struct pasemi_desc *desc, u64 val)
  80760. +{
  80761. + desc->quad[desc->quad_cnt++] = val;
  80762. + desc->size = (desc->quad_cnt + 1) / 2;
  80763. +}
  80764. +
  80765. +static void pasemi_desc_hdr(struct pasemi_desc *desc, u64 hdr)
  80766. +{
  80767. + desc->quad[0] |= hdr;
  80768. +}
  80769. +
  80770. +static int pasemi_desc_size(struct pasemi_desc *desc)
  80771. +{
  80772. + return desc->size;
  80773. +}
  80774. +
  80775. +static void pasemi_ring_add_desc(
  80776. + struct pasemi_fnu_txring *ring,
  80777. + struct pasemi_desc *desc,
  80778. + struct cryptop *crp) {
  80779. + int i;
  80780. + int ring_index = 2 * (ring->next_to_fill & (TX_RING_SIZE-1));
  80781. +
  80782. + TX_DESC_INFO(ring, ring->next_to_fill).desc_size = desc->size;
  80783. + TX_DESC_INFO(ring, ring->next_to_fill).desc_postop = desc->postop;
  80784. + TX_DESC_INFO(ring, ring->next_to_fill).cf_crp = crp;
  80785. +
  80786. + for (i = 0; i < desc->quad_cnt; i += 2) {
  80787. + ring_index = 2 * (ring->next_to_fill & (TX_RING_SIZE-1));
  80788. + ring->desc[ring_index] = desc->quad[i];
  80789. + ring->desc[ring_index + 1] = desc->quad[i + 1];
  80790. + ring->next_to_fill++;
  80791. + }
  80792. +
  80793. + if (desc->quad_cnt & 1)
  80794. + ring->desc[ring_index + 1] = 0;
  80795. +}
  80796. +
  80797. +static void pasemi_ring_incr(struct pasemi_softc *sc, int chan_index, int incr)
  80798. +{
  80799. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_INCR(sc->base_chan + chan_index),
  80800. + incr);
  80801. +}
  80802. +
  80803. +/*
  80804. + * Generate a new software session.
  80805. + */
  80806. +static int
  80807. +pasemi_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  80808. +{
  80809. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  80810. + struct pasemi_softc *sc = device_get_softc(dev);
  80811. + struct pasemi_session *ses = NULL, **sespp;
  80812. + int sesn, blksz = 0;
  80813. + u64 ccmd = 0;
  80814. + unsigned long flags;
  80815. + struct pasemi_desc init_desc;
  80816. + struct pasemi_fnu_txring *txring;
  80817. +
  80818. + DPRINTF("%s()\n", __FUNCTION__);
  80819. + if (sidp == NULL || cri == NULL || sc == NULL) {
  80820. + DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);
  80821. + return -EINVAL;
  80822. + }
  80823. + for (c = cri; c != NULL; c = c->cri_next) {
  80824. + if (ALG_IS_SIG(c->cri_alg)) {
  80825. + if (macini)
  80826. + return -EINVAL;
  80827. + macini = c;
  80828. + } else if (ALG_IS_CIPHER(c->cri_alg)) {
  80829. + if (encini)
  80830. + return -EINVAL;
  80831. + encini = c;
  80832. + } else {
  80833. + DPRINTF("UNKNOWN c->cri_alg %d\n", c->cri_alg);
  80834. + return -EINVAL;
  80835. + }
  80836. + }
  80837. + if (encini == NULL && macini == NULL)
  80838. + return -EINVAL;
  80839. + if (encini) {
  80840. + /* validate key length */
  80841. + switch (encini->cri_alg) {
  80842. + case CRYPTO_DES_CBC:
  80843. + if (encini->cri_klen != 64)
  80844. + return -EINVAL;
  80845. + ccmd = DMA_CALGO_DES;
  80846. + break;
  80847. + case CRYPTO_3DES_CBC:
  80848. + if (encini->cri_klen != 192)
  80849. + return -EINVAL;
  80850. + ccmd = DMA_CALGO_3DES;
  80851. + break;
  80852. + case CRYPTO_AES_CBC:
  80853. + if (encini->cri_klen != 128 &&
  80854. + encini->cri_klen != 192 &&
  80855. + encini->cri_klen != 256)
  80856. + return -EINVAL;
  80857. + ccmd = DMA_CALGO_AES;
  80858. + break;
  80859. + case CRYPTO_ARC4:
  80860. + if (encini->cri_klen != 128)
  80861. + return -EINVAL;
  80862. + ccmd = DMA_CALGO_ARC;
  80863. + break;
  80864. + default:
  80865. + DPRINTF("UNKNOWN encini->cri_alg %d\n",
  80866. + encini->cri_alg);
  80867. + return -EINVAL;
  80868. + }
  80869. + }
  80870. +
  80871. + if (macini) {
  80872. + switch (macini->cri_alg) {
  80873. + case CRYPTO_MD5:
  80874. + case CRYPTO_MD5_HMAC:
  80875. + blksz = 16;
  80876. + break;
  80877. + case CRYPTO_SHA1:
  80878. + case CRYPTO_SHA1_HMAC:
  80879. + blksz = 20;
  80880. + break;
  80881. + default:
  80882. + DPRINTF("UNKNOWN macini->cri_alg %d\n",
  80883. + macini->cri_alg);
  80884. + return -EINVAL;
  80885. + }
  80886. + if (((macini->cri_klen + 7) / 8) > blksz) {
  80887. + DPRINTF("key length %d bigger than blksize %d not supported\n",
  80888. + ((macini->cri_klen + 7) / 8), blksz);
  80889. + return -EINVAL;
  80890. + }
  80891. + }
  80892. +
  80893. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  80894. + if (sc->sc_sessions[sesn] == NULL) {
  80895. + sc->sc_sessions[sesn] = (struct pasemi_session *)
  80896. + kzalloc(sizeof(struct pasemi_session), GFP_ATOMIC);
  80897. + ses = sc->sc_sessions[sesn];
  80898. + break;
  80899. + } else if (sc->sc_sessions[sesn]->used == 0) {
  80900. + ses = sc->sc_sessions[sesn];
  80901. + break;
  80902. + }
  80903. + }
  80904. +
  80905. + if (ses == NULL) {
  80906. + sespp = (struct pasemi_session **)
  80907. + kzalloc(sc->sc_nsessions * 2 *
  80908. + sizeof(struct pasemi_session *), GFP_ATOMIC);
  80909. + if (sespp == NULL)
  80910. + return -ENOMEM;
  80911. + memcpy(sespp, sc->sc_sessions,
  80912. + sc->sc_nsessions * sizeof(struct pasemi_session *));
  80913. + kfree(sc->sc_sessions);
  80914. + sc->sc_sessions = sespp;
  80915. + sesn = sc->sc_nsessions;
  80916. + ses = sc->sc_sessions[sesn] = (struct pasemi_session *)
  80917. + kzalloc(sizeof(struct pasemi_session), GFP_ATOMIC);
  80918. + if (ses == NULL)
  80919. + return -ENOMEM;
  80920. + sc->sc_nsessions *= 2;
  80921. + }
  80922. +
  80923. + ses->used = 1;
  80924. +
  80925. + ses->dma_addr = pci_map_single(sc->dma_pdev, (void *) ses->civ,
  80926. + sizeof(struct pasemi_session), DMA_TO_DEVICE);
  80927. +
  80928. + /* enter the channel scheduler */
  80929. + spin_lock_irqsave(&sc->sc_chnlock, flags);
  80930. +
  80931. + /* ARC4 has to be processed by the even channel */
  80932. + if (encini && (encini->cri_alg == CRYPTO_ARC4))
  80933. + ses->chan = sc->sc_lastchn & ~1;
  80934. + else
  80935. + ses->chan = sc->sc_lastchn;
  80936. + sc->sc_lastchn = (sc->sc_lastchn + 1) % sc->sc_num_channels;
  80937. +
  80938. + spin_unlock_irqrestore(&sc->sc_chnlock, flags);
  80939. +
  80940. + txring = &sc->tx[ses->chan];
  80941. +
  80942. + if (encini) {
  80943. + ses->ccmd = ccmd;
  80944. +
  80945. + /* get an IV */
  80946. + /* XXX may read fewer than requested */
  80947. + get_random_bytes(ses->civ, sizeof(ses->civ));
  80948. +
  80949. + ses->keysz = (encini->cri_klen - 63) / 64;
  80950. + memcpy(ses->key, encini->cri_key, (ses->keysz + 1) * 8);
  80951. +
  80952. + pasemi_desc_start(&init_desc,
  80953. + XCT_CTRL_HDR(ses->chan, (encini && macini) ? 0x68 : 0x40, DMA_FN_CIV0));
  80954. + pasemi_desc_build(&init_desc,
  80955. + XCT_FUN_SRC_PTR((encini && macini) ? 0x68 : 0x40, ses->dma_addr));
  80956. + }
  80957. + if (macini) {
  80958. + if (macini->cri_alg == CRYPTO_MD5_HMAC ||
  80959. + macini->cri_alg == CRYPTO_SHA1_HMAC)
  80960. + memcpy(ses->hkey, macini->cri_key, blksz);
  80961. + else {
  80962. + /* Load initialization constants(RFC 1321, 3174) */
  80963. + ses->hiv[0] = 0x67452301efcdab89ULL;
  80964. + ses->hiv[1] = 0x98badcfe10325476ULL;
  80965. + ses->hiv[2] = 0xc3d2e1f000000000ULL;
  80966. + }
  80967. + ses->hseq = 0ULL;
  80968. + }
  80969. +
  80970. + spin_lock_irqsave(&txring->fill_lock, flags);
  80971. +
  80972. + if (((txring->next_to_fill + pasemi_desc_size(&init_desc)) -
  80973. + txring->next_to_clean) > TX_RING_SIZE) {
  80974. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  80975. + return ERESTART;
  80976. + }
  80977. +
  80978. + if (encini) {
  80979. + pasemi_ring_add_desc(txring, &init_desc, NULL);
  80980. + pasemi_ring_incr(sc, ses->chan,
  80981. + pasemi_desc_size(&init_desc));
  80982. + }
  80983. +
  80984. + txring->sesn = sesn;
  80985. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  80986. +
  80987. + *sidp = PASEMI_SID(sesn);
  80988. + return 0;
  80989. +}
  80990. +
  80991. +/*
  80992. + * Deallocate a session.
  80993. + */
  80994. +static int
  80995. +pasemi_freesession(device_t dev, u_int64_t tid)
  80996. +{
  80997. + struct pasemi_softc *sc = device_get_softc(dev);
  80998. + int session;
  80999. + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
  81000. +
  81001. + DPRINTF("%s()\n", __FUNCTION__);
  81002. +
  81003. + if (sc == NULL)
  81004. + return -EINVAL;
  81005. + session = PASEMI_SESSION(sid);
  81006. + if (session >= sc->sc_nsessions || !sc->sc_sessions[session])
  81007. + return -EINVAL;
  81008. +
  81009. + pci_unmap_single(sc->dma_pdev,
  81010. + sc->sc_sessions[session]->dma_addr,
  81011. + sizeof(struct pasemi_session), DMA_TO_DEVICE);
  81012. + memset(sc->sc_sessions[session], 0,
  81013. + sizeof(struct pasemi_session));
  81014. +
  81015. + return 0;
  81016. +}
  81017. +
  81018. +static int
  81019. +pasemi_process(device_t dev, struct cryptop *crp, int hint)
  81020. +{
  81021. +
  81022. + int err = 0, ivsize, srclen = 0, reinit = 0, reinit_size = 0, chsel;
  81023. + struct pasemi_softc *sc = device_get_softc(dev);
  81024. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  81025. + caddr_t ivp;
  81026. + struct pasemi_desc init_desc, work_desc;
  81027. + struct pasemi_session *ses;
  81028. + struct sk_buff *skb;
  81029. + struct uio *uiop;
  81030. + unsigned long flags;
  81031. + struct pasemi_fnu_txring *txring;
  81032. +
  81033. + DPRINTF("%s()\n", __FUNCTION__);
  81034. +
  81035. + if (crp == NULL || crp->crp_callback == NULL || sc == NULL)
  81036. + return -EINVAL;
  81037. +
  81038. + crp->crp_etype = 0;
  81039. + if (PASEMI_SESSION(crp->crp_sid) >= sc->sc_nsessions)
  81040. + return -EINVAL;
  81041. +
  81042. + ses = sc->sc_sessions[PASEMI_SESSION(crp->crp_sid)];
  81043. +
  81044. + crd1 = crp->crp_desc;
  81045. + if (crd1 == NULL) {
  81046. + err = -EINVAL;
  81047. + goto errout;
  81048. + }
  81049. + crd2 = crd1->crd_next;
  81050. +
  81051. + if (ALG_IS_SIG(crd1->crd_alg)) {
  81052. + maccrd = crd1;
  81053. + if (crd2 == NULL)
  81054. + enccrd = NULL;
  81055. + else if (ALG_IS_CIPHER(crd2->crd_alg) &&
  81056. + (crd2->crd_flags & CRD_F_ENCRYPT) == 0)
  81057. + enccrd = crd2;
  81058. + else
  81059. + goto erralg;
  81060. + } else if (ALG_IS_CIPHER(crd1->crd_alg)) {
  81061. + enccrd = crd1;
  81062. + if (crd2 == NULL)
  81063. + maccrd = NULL;
  81064. + else if (ALG_IS_SIG(crd2->crd_alg) &&
  81065. + (crd1->crd_flags & CRD_F_ENCRYPT))
  81066. + maccrd = crd2;
  81067. + else
  81068. + goto erralg;
  81069. + } else
  81070. + goto erralg;
  81071. +
  81072. + chsel = ses->chan;
  81073. +
  81074. + txring = &sc->tx[chsel];
  81075. +
  81076. + if (enccrd && !maccrd) {
  81077. + if (enccrd->crd_alg == CRYPTO_ARC4)
  81078. + reinit = 1;
  81079. + reinit_size = 0x40;
  81080. + srclen = crp->crp_ilen;
  81081. +
  81082. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I
  81083. + | XCT_FUN_FUN(chsel));
  81084. + if (enccrd->crd_flags & CRD_F_ENCRYPT)
  81085. + pasemi_desc_hdr(&work_desc, XCT_FUN_CRM_ENC);
  81086. + else
  81087. + pasemi_desc_hdr(&work_desc, XCT_FUN_CRM_DEC);
  81088. + } else if (enccrd && maccrd) {
  81089. + if (enccrd->crd_alg == CRYPTO_ARC4)
  81090. + reinit = 1;
  81091. + reinit_size = 0x68;
  81092. +
  81093. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  81094. + /* Encrypt -> Authenticate */
  81095. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_ENC_SIG
  81096. + | XCT_FUN_A | XCT_FUN_FUN(chsel));
  81097. + srclen = maccrd->crd_skip + maccrd->crd_len;
  81098. + } else {
  81099. + /* Authenticate -> Decrypt */
  81100. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_SIG_DEC
  81101. + | XCT_FUN_24BRES | XCT_FUN_FUN(chsel));
  81102. + pasemi_desc_build(&work_desc, 0);
  81103. + pasemi_desc_build(&work_desc, 0);
  81104. + pasemi_desc_build(&work_desc, 0);
  81105. + work_desc.postop = PASEMI_CHECK_SIG;
  81106. + srclen = crp->crp_ilen;
  81107. + }
  81108. +
  81109. + pasemi_desc_hdr(&work_desc, XCT_FUN_SHL(maccrd->crd_skip / 4));
  81110. + pasemi_desc_hdr(&work_desc, XCT_FUN_CHL(enccrd->crd_skip - maccrd->crd_skip));
  81111. + } else if (!enccrd && maccrd) {
  81112. + srclen = maccrd->crd_len;
  81113. +
  81114. + pasemi_desc_start(&init_desc,
  81115. + XCT_CTRL_HDR(chsel, 0x58, DMA_FN_HKEY0));
  81116. + pasemi_desc_build(&init_desc,
  81117. + XCT_FUN_SRC_PTR(0x58, ((struct pasemi_session *)ses->dma_addr)->hkey));
  81118. +
  81119. + pasemi_desc_start(&work_desc, XCT_FUN_O | XCT_FUN_I | XCT_FUN_CRM_SIG
  81120. + | XCT_FUN_A | XCT_FUN_FUN(chsel));
  81121. + }
  81122. +
  81123. + if (enccrd) {
  81124. + switch (enccrd->crd_alg) {
  81125. + case CRYPTO_3DES_CBC:
  81126. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_3DES |
  81127. + XCT_FUN_BCM_CBC);
  81128. + ivsize = sizeof(u64);
  81129. + break;
  81130. + case CRYPTO_DES_CBC:
  81131. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_DES |
  81132. + XCT_FUN_BCM_CBC);
  81133. + ivsize = sizeof(u64);
  81134. + break;
  81135. + case CRYPTO_AES_CBC:
  81136. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_AES |
  81137. + XCT_FUN_BCM_CBC);
  81138. + ivsize = 2 * sizeof(u64);
  81139. + break;
  81140. + case CRYPTO_ARC4:
  81141. + pasemi_desc_hdr(&work_desc, XCT_FUN_ALG_ARC);
  81142. + ivsize = 0;
  81143. + break;
  81144. + default:
  81145. + printk(DRV_NAME ": unimplemented enccrd->crd_alg %d\n",
  81146. + enccrd->crd_alg);
  81147. + err = -EINVAL;
  81148. + goto errout;
  81149. + }
  81150. +
  81151. + ivp = (ivsize == sizeof(u64)) ? (caddr_t) &ses->civ[1] : (caddr_t) &ses->civ[0];
  81152. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  81153. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  81154. + memcpy(ivp, enccrd->crd_iv, ivsize);
  81155. + /* If IV is not present in the buffer already, it has to be copied there */
  81156. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0)
  81157. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  81158. + enccrd->crd_inject, ivsize, ivp);
  81159. + } else {
  81160. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  81161. + /* IV is provided expicitly in descriptor */
  81162. + memcpy(ivp, enccrd->crd_iv, ivsize);
  81163. + else
  81164. + /* IV is provided in the packet */
  81165. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  81166. + enccrd->crd_inject, ivsize,
  81167. + ivp);
  81168. + }
  81169. + }
  81170. +
  81171. + if (maccrd) {
  81172. + switch (maccrd->crd_alg) {
  81173. + case CRYPTO_MD5:
  81174. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_MD5 |
  81175. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  81176. + break;
  81177. + case CRYPTO_SHA1:
  81178. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_SHA1 |
  81179. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  81180. + break;
  81181. + case CRYPTO_MD5_HMAC:
  81182. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_HMAC_MD5 |
  81183. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  81184. + break;
  81185. + case CRYPTO_SHA1_HMAC:
  81186. + pasemi_desc_hdr(&work_desc, XCT_FUN_SIG_HMAC_SHA1 |
  81187. + XCT_FUN_HSZ((crp->crp_ilen - maccrd->crd_inject) / 4));
  81188. + break;
  81189. + default:
  81190. + printk(DRV_NAME ": unimplemented maccrd->crd_alg %d\n",
  81191. + maccrd->crd_alg);
  81192. + err = -EINVAL;
  81193. + goto errout;
  81194. + }
  81195. + }
  81196. +
  81197. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  81198. + /* using SKB buffers */
  81199. + skb = (struct sk_buff *)crp->crp_buf;
  81200. + if (skb_shinfo(skb)->nr_frags) {
  81201. + printk(DRV_NAME ": skb frags unimplemented\n");
  81202. + err = -EINVAL;
  81203. + goto errout;
  81204. + }
  81205. + pasemi_desc_build(
  81206. + &work_desc,
  81207. + XCT_FUN_DST_PTR(skb->len, pci_map_single(
  81208. + sc->dma_pdev, skb->data,
  81209. + skb->len, DMA_TO_DEVICE)));
  81210. + pasemi_desc_build(
  81211. + &work_desc,
  81212. + XCT_FUN_SRC_PTR(
  81213. + srclen, pci_map_single(
  81214. + sc->dma_pdev, skb->data,
  81215. + srclen, DMA_TO_DEVICE)));
  81216. + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
  81217. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  81218. + /* using IOV buffers */
  81219. + uiop = (struct uio *)crp->crp_buf;
  81220. + if (uiop->uio_iovcnt > 1) {
  81221. + printk(DRV_NAME ": iov frags unimplemented\n");
  81222. + err = -EINVAL;
  81223. + goto errout;
  81224. + }
  81225. +
  81226. + /* crp_olen is never set; always use crp_ilen */
  81227. + pasemi_desc_build(
  81228. + &work_desc,
  81229. + XCT_FUN_DST_PTR(crp->crp_ilen, pci_map_single(
  81230. + sc->dma_pdev,
  81231. + uiop->uio_iov->iov_base,
  81232. + crp->crp_ilen, DMA_TO_DEVICE)));
  81233. + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
  81234. +
  81235. + pasemi_desc_build(
  81236. + &work_desc,
  81237. + XCT_FUN_SRC_PTR(srclen, pci_map_single(
  81238. + sc->dma_pdev,
  81239. + uiop->uio_iov->iov_base,
  81240. + srclen, DMA_TO_DEVICE)));
  81241. + } else {
  81242. + /* using contig buffers */
  81243. + pasemi_desc_build(
  81244. + &work_desc,
  81245. + XCT_FUN_DST_PTR(crp->crp_ilen, pci_map_single(
  81246. + sc->dma_pdev,
  81247. + crp->crp_buf,
  81248. + crp->crp_ilen, DMA_TO_DEVICE)));
  81249. + pasemi_desc_build(
  81250. + &work_desc,
  81251. + XCT_FUN_SRC_PTR(srclen, pci_map_single(
  81252. + sc->dma_pdev,
  81253. + crp->crp_buf, srclen,
  81254. + DMA_TO_DEVICE)));
  81255. + pasemi_desc_hdr(&work_desc, XCT_FUN_LLEN(srclen));
  81256. + }
  81257. +
  81258. + spin_lock_irqsave(&txring->fill_lock, flags);
  81259. +
  81260. + if (txring->sesn != PASEMI_SESSION(crp->crp_sid)) {
  81261. + txring->sesn = PASEMI_SESSION(crp->crp_sid);
  81262. + reinit = 1;
  81263. + }
  81264. +
  81265. + if (enccrd) {
  81266. + pasemi_desc_start(&init_desc,
  81267. + XCT_CTRL_HDR(chsel, reinit ? reinit_size : 0x10, DMA_FN_CIV0));
  81268. + pasemi_desc_build(&init_desc,
  81269. + XCT_FUN_SRC_PTR(reinit ? reinit_size : 0x10, ses->dma_addr));
  81270. + }
  81271. +
  81272. + if (((txring->next_to_fill + pasemi_desc_size(&init_desc) +
  81273. + pasemi_desc_size(&work_desc)) -
  81274. + txring->next_to_clean) > TX_RING_SIZE) {
  81275. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  81276. + err = ERESTART;
  81277. + goto errout;
  81278. + }
  81279. +
  81280. + pasemi_ring_add_desc(txring, &init_desc, NULL);
  81281. + pasemi_ring_add_desc(txring, &work_desc, crp);
  81282. +
  81283. + pasemi_ring_incr(sc, chsel,
  81284. + pasemi_desc_size(&init_desc) +
  81285. + pasemi_desc_size(&work_desc));
  81286. +
  81287. + spin_unlock_irqrestore(&txring->fill_lock, flags);
  81288. +
  81289. + mod_timer(&txring->crypto_timer, jiffies + TIMER_INTERVAL);
  81290. +
  81291. + return 0;
  81292. +
  81293. +erralg:
  81294. + printk(DRV_NAME ": unsupported algorithm or algorithm order alg1 %d alg2 %d\n",
  81295. + crd1->crd_alg, crd2->crd_alg);
  81296. + err = -EINVAL;
  81297. +
  81298. +errout:
  81299. + if (err != ERESTART) {
  81300. + crp->crp_etype = err;
  81301. + crypto_done(crp);
  81302. + }
  81303. + return err;
  81304. +}
  81305. +
  81306. +static int pasemi_clean_tx(struct pasemi_softc *sc, int chan)
  81307. +{
  81308. + int i, j, ring_idx;
  81309. + struct pasemi_fnu_txring *ring = &sc->tx[chan];
  81310. + u16 delta_cnt;
  81311. + int flags, loops = 10;
  81312. + int desc_size;
  81313. + struct cryptop *crp;
  81314. +
  81315. + spin_lock_irqsave(&ring->clean_lock, flags);
  81316. +
  81317. + while ((delta_cnt = (dma_status->tx_sta[sc->base_chan + chan]
  81318. + & PAS_STATUS_PCNT_M) - ring->total_pktcnt)
  81319. + && loops--) {
  81320. +
  81321. + for (i = 0; i < delta_cnt; i++) {
  81322. + desc_size = TX_DESC_INFO(ring, ring->next_to_clean).desc_size;
  81323. + crp = TX_DESC_INFO(ring, ring->next_to_clean).cf_crp;
  81324. + if (crp) {
  81325. + ring_idx = 2 * (ring->next_to_clean & (TX_RING_SIZE-1));
  81326. + if (TX_DESC_INFO(ring, ring->next_to_clean).desc_postop & PASEMI_CHECK_SIG) {
  81327. + /* Need to make sure signature matched,
  81328. + * if not - return error */
  81329. + if (!(ring->desc[ring_idx + 1] & (1ULL << 63)))
  81330. + crp->crp_etype = -EINVAL;
  81331. + }
  81332. + crypto_done(TX_DESC_INFO(ring,
  81333. + ring->next_to_clean).cf_crp);
  81334. + TX_DESC_INFO(ring, ring->next_to_clean).cf_crp = NULL;
  81335. + pci_unmap_single(
  81336. + sc->dma_pdev,
  81337. + XCT_PTR_ADDR_LEN(ring->desc[ring_idx + 1]),
  81338. + PCI_DMA_TODEVICE);
  81339. +
  81340. + ring->desc[ring_idx] = ring->desc[ring_idx + 1] = 0;
  81341. +
  81342. + ring->next_to_clean++;
  81343. + for (j = 1; j < desc_size; j++) {
  81344. + ring_idx = 2 *
  81345. + (ring->next_to_clean &
  81346. + (TX_RING_SIZE-1));
  81347. + pci_unmap_single(
  81348. + sc->dma_pdev,
  81349. + XCT_PTR_ADDR_LEN(ring->desc[ring_idx]),
  81350. + PCI_DMA_TODEVICE);
  81351. + if (ring->desc[ring_idx + 1])
  81352. + pci_unmap_single(
  81353. + sc->dma_pdev,
  81354. + XCT_PTR_ADDR_LEN(
  81355. + ring->desc[
  81356. + ring_idx + 1]),
  81357. + PCI_DMA_TODEVICE);
  81358. + ring->desc[ring_idx] =
  81359. + ring->desc[ring_idx + 1] = 0;
  81360. + ring->next_to_clean++;
  81361. + }
  81362. + } else {
  81363. + for (j = 0; j < desc_size; j++) {
  81364. + ring_idx = 2 * (ring->next_to_clean & (TX_RING_SIZE-1));
  81365. + ring->desc[ring_idx] =
  81366. + ring->desc[ring_idx + 1] = 0;
  81367. + ring->next_to_clean++;
  81368. + }
  81369. + }
  81370. + }
  81371. +
  81372. + ring->total_pktcnt += delta_cnt;
  81373. + }
  81374. + spin_unlock_irqrestore(&ring->clean_lock, flags);
  81375. +
  81376. + return 0;
  81377. +}
  81378. +
  81379. +static void sweepup_tx(struct pasemi_softc *sc)
  81380. +{
  81381. + int i;
  81382. +
  81383. + for (i = 0; i < sc->sc_num_channels; i++)
  81384. + pasemi_clean_tx(sc, i);
  81385. +}
  81386. +
  81387. +static irqreturn_t pasemi_intr(int irq, void *arg, struct pt_regs *regs)
  81388. +{
  81389. + struct pasemi_softc *sc = arg;
  81390. + unsigned int reg;
  81391. + int chan = irq - sc->base_irq;
  81392. + int chan_index = sc->base_chan + chan;
  81393. + u64 stat = dma_status->tx_sta[chan_index];
  81394. +
  81395. + DPRINTF("%s()\n", __FUNCTION__);
  81396. +
  81397. + if (!(stat & PAS_STATUS_CAUSE_M))
  81398. + return IRQ_NONE;
  81399. +
  81400. + pasemi_clean_tx(sc, chan);
  81401. +
  81402. + stat = dma_status->tx_sta[chan_index];
  81403. +
  81404. + reg = PAS_IOB_DMA_TXCH_RESET_PINTC |
  81405. + PAS_IOB_DMA_TXCH_RESET_PCNT(sc->tx[chan].total_pktcnt);
  81406. +
  81407. + if (stat & PAS_STATUS_SOFT)
  81408. + reg |= PAS_IOB_DMA_RXCH_RESET_SINTC;
  81409. +
  81410. + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), reg);
  81411. +
  81412. +
  81413. + return IRQ_HANDLED;
  81414. +}
  81415. +
  81416. +static int pasemi_dma_setup_tx_resources(struct pasemi_softc *sc, int chan)
  81417. +{
  81418. + u32 val;
  81419. + int chan_index = chan + sc->base_chan;
  81420. + int ret;
  81421. + struct pasemi_fnu_txring *ring;
  81422. +
  81423. + ring = &sc->tx[chan];
  81424. +
  81425. + spin_lock_init(&ring->fill_lock);
  81426. + spin_lock_init(&ring->clean_lock);
  81427. +
  81428. + ring->desc_info = kzalloc(sizeof(struct pasemi_desc_info) *
  81429. + TX_RING_SIZE, GFP_KERNEL);
  81430. + if (!ring->desc_info)
  81431. + return -ENOMEM;
  81432. +
  81433. + /* Allocate descriptors */
  81434. + ring->desc = dma_alloc_coherent(&sc->dma_pdev->dev,
  81435. + TX_RING_SIZE *
  81436. + 2 * sizeof(u64),
  81437. + &ring->dma, GFP_KERNEL);
  81438. + if (!ring->desc)
  81439. + return -ENOMEM;
  81440. +
  81441. + memset((void *) ring->desc, 0, TX_RING_SIZE * 2 * sizeof(u64));
  81442. +
  81443. + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_RESET(chan_index), 0x30);
  81444. +
  81445. + ring->total_pktcnt = 0;
  81446. +
  81447. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEL(chan_index),
  81448. + PAS_DMA_TXCHAN_BASEL_BRBL(ring->dma));
  81449. +
  81450. + val = PAS_DMA_TXCHAN_BASEU_BRBH(ring->dma >> 32);
  81451. + val |= PAS_DMA_TXCHAN_BASEU_SIZ(TX_RING_SIZE >> 2);
  81452. +
  81453. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_BASEU(chan_index), val);
  81454. +
  81455. + out_le32(sc->dma_regs + PAS_DMA_TXCHAN_CFG(chan_index),
  81456. + PAS_DMA_TXCHAN_CFG_TY_FUNC |
  81457. + PAS_DMA_TXCHAN_CFG_TATTR(chan) |
  81458. + PAS_DMA_TXCHAN_CFG_WT(2));
  81459. +
  81460. + /* enable tx channel */
  81461. + out_le32(sc->dma_regs +
  81462. + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
  81463. + PAS_DMA_TXCHAN_TCMDSTA_EN);
  81464. +
  81465. + out_le32(sc->iob_regs + PAS_IOB_DMA_TXCH_CFG(chan_index),
  81466. + PAS_IOB_DMA_TXCH_CFG_CNTTH(1000));
  81467. +
  81468. + ring->next_to_fill = 0;
  81469. + ring->next_to_clean = 0;
  81470. +
  81471. + snprintf(ring->irq_name, sizeof(ring->irq_name),
  81472. + "%s%d", "crypto", chan);
  81473. +
  81474. + ring->irq = irq_create_mapping(NULL, sc->base_irq + chan);
  81475. + ret = request_irq(ring->irq, (irq_handler_t)
  81476. + pasemi_intr, IRQF_DISABLED, ring->irq_name, sc);
  81477. + if (ret) {
  81478. + printk(KERN_ERR DRV_NAME ": failed to hook irq %d ret %d\n",
  81479. + ring->irq, ret);
  81480. + ring->irq = -1;
  81481. + return ret;
  81482. + }
  81483. +
  81484. + setup_timer(&ring->crypto_timer, (void *) sweepup_tx, (unsigned long) sc);
  81485. +
  81486. + return 0;
  81487. +}
  81488. +
  81489. +static device_method_t pasemi_methods = {
  81490. + /* crypto device methods */
  81491. + DEVMETHOD(cryptodev_newsession, pasemi_newsession),
  81492. + DEVMETHOD(cryptodev_freesession, pasemi_freesession),
  81493. + DEVMETHOD(cryptodev_process, pasemi_process),
  81494. +};
  81495. +
  81496. +/* Set up the crypto device structure, private data,
  81497. + * and anything else we need before we start */
  81498. +
  81499. +static int __devinit
  81500. +pasemi_dma_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
  81501. +{
  81502. + struct pasemi_softc *sc;
  81503. + int ret, i;
  81504. +
  81505. + DPRINTF(KERN_ERR "%s()\n", __FUNCTION__);
  81506. +
  81507. + sc = kzalloc(sizeof(*sc), GFP_KERNEL);
  81508. + if (!sc)
  81509. + return -ENOMEM;
  81510. +
  81511. + softc_device_init(sc, DRV_NAME, 1, pasemi_methods);
  81512. +
  81513. + pci_set_drvdata(pdev, sc);
  81514. +
  81515. + spin_lock_init(&sc->sc_chnlock);
  81516. +
  81517. + sc->sc_sessions = (struct pasemi_session **)
  81518. + kzalloc(PASEMI_INITIAL_SESSIONS *
  81519. + sizeof(struct pasemi_session *), GFP_ATOMIC);
  81520. + if (sc->sc_sessions == NULL) {
  81521. + ret = -ENOMEM;
  81522. + goto out;
  81523. + }
  81524. +
  81525. + sc->sc_nsessions = PASEMI_INITIAL_SESSIONS;
  81526. + sc->sc_lastchn = 0;
  81527. + sc->base_irq = pdev->irq + 6;
  81528. + sc->base_chan = 6;
  81529. + sc->sc_cid = -1;
  81530. + sc->dma_pdev = pdev;
  81531. +
  81532. + sc->iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
  81533. + if (!sc->iob_pdev) {
  81534. + dev_err(&pdev->dev, "Can't find I/O Bridge\n");
  81535. + ret = -ENODEV;
  81536. + goto out;
  81537. + }
  81538. +
  81539. + /* This is hardcoded and ugly, but we have some firmware versions
  81540. + * who don't provide the register space in the device tree. Luckily
  81541. + * they are at well-known locations so we can just do the math here.
  81542. + */
  81543. + sc->dma_regs =
  81544. + ioremap(0xe0000000 + (sc->dma_pdev->devfn << 12), 0x2000);
  81545. + sc->iob_regs =
  81546. + ioremap(0xe0000000 + (sc->iob_pdev->devfn << 12), 0x2000);
  81547. + if (!sc->dma_regs || !sc->iob_regs) {
  81548. + dev_err(&pdev->dev, "Can't map registers\n");
  81549. + ret = -ENODEV;
  81550. + goto out;
  81551. + }
  81552. +
  81553. + dma_status = __ioremap(0xfd800000, 0x1000, 0);
  81554. + if (!dma_status) {
  81555. + ret = -ENODEV;
  81556. + dev_err(&pdev->dev, "Can't map dmastatus space\n");
  81557. + goto out;
  81558. + }
  81559. +
  81560. + sc->tx = (struct pasemi_fnu_txring *)
  81561. + kzalloc(sizeof(struct pasemi_fnu_txring)
  81562. + * 8, GFP_KERNEL);
  81563. + if (!sc->tx) {
  81564. + ret = -ENOMEM;
  81565. + goto out;
  81566. + }
  81567. +
  81568. + /* Initialize the h/w */
  81569. + out_le32(sc->dma_regs + PAS_DMA_COM_CFG,
  81570. + (in_le32(sc->dma_regs + PAS_DMA_COM_CFG) |
  81571. + PAS_DMA_COM_CFG_FWF));
  81572. + out_le32(sc->dma_regs + PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN);
  81573. +
  81574. + for (i = 0; i < PASEMI_FNU_CHANNELS; i++) {
  81575. + sc->sc_num_channels++;
  81576. + ret = pasemi_dma_setup_tx_resources(sc, i);
  81577. + if (ret)
  81578. + goto out;
  81579. + }
  81580. +
  81581. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),
  81582. + CRYPTOCAP_F_HARDWARE);
  81583. + if (sc->sc_cid < 0) {
  81584. + printk(KERN_ERR DRV_NAME ": could not get crypto driver id\n");
  81585. + ret = -ENXIO;
  81586. + goto out;
  81587. + }
  81588. +
  81589. + /* register algorithms with the framework */
  81590. + printk(DRV_NAME ":");
  81591. +
  81592. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  81593. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  81594. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  81595. + crypto_register(sc->sc_cid, CRYPTO_ARC4, 0, 0);
  81596. + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
  81597. + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
  81598. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  81599. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  81600. +
  81601. + return 0;
  81602. +
  81603. +out:
  81604. + pasemi_dma_remove(pdev);
  81605. + return ret;
  81606. +}
  81607. +
  81608. +#define MAX_RETRIES 5000
  81609. +
  81610. +static void pasemi_free_tx_resources(struct pasemi_softc *sc, int chan)
  81611. +{
  81612. + struct pasemi_fnu_txring *ring = &sc->tx[chan];
  81613. + int chan_index = chan + sc->base_chan;
  81614. + int retries;
  81615. + u32 stat;
  81616. +
  81617. + /* Stop the channel */
  81618. + out_le32(sc->dma_regs +
  81619. + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
  81620. + PAS_DMA_TXCHAN_TCMDSTA_ST);
  81621. +
  81622. + for (retries = 0; retries < MAX_RETRIES; retries++) {
  81623. + stat = in_le32(sc->dma_regs +
  81624. + PAS_DMA_TXCHAN_TCMDSTA(chan_index));
  81625. + if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT))
  81626. + break;
  81627. + cond_resched();
  81628. + }
  81629. +
  81630. + if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)
  81631. + dev_err(&sc->dma_pdev->dev, "Failed to stop tx channel %d\n",
  81632. + chan_index);
  81633. +
  81634. + /* Disable the channel */
  81635. + out_le32(sc->dma_regs +
  81636. + PAS_DMA_TXCHAN_TCMDSTA(chan_index),
  81637. + 0);
  81638. +
  81639. + if (ring->desc_info)
  81640. + kfree((void *) ring->desc_info);
  81641. + if (ring->desc)
  81642. + dma_free_coherent(&sc->dma_pdev->dev,
  81643. + TX_RING_SIZE *
  81644. + 2 * sizeof(u64),
  81645. + (void *) ring->desc, ring->dma);
  81646. + if (ring->irq != -1)
  81647. + free_irq(ring->irq, sc);
  81648. +
  81649. + del_timer(&ring->crypto_timer);
  81650. +}
  81651. +
  81652. +static void __devexit pasemi_dma_remove(struct pci_dev *pdev)
  81653. +{
  81654. + struct pasemi_softc *sc = pci_get_drvdata(pdev);
  81655. + int i;
  81656. +
  81657. + DPRINTF("%s()\n", __FUNCTION__);
  81658. +
  81659. + if (sc->sc_cid >= 0) {
  81660. + crypto_unregister_all(sc->sc_cid);
  81661. + }
  81662. +
  81663. + if (sc->tx) {
  81664. + for (i = 0; i < sc->sc_num_channels; i++)
  81665. + pasemi_free_tx_resources(sc, i);
  81666. +
  81667. + kfree(sc->tx);
  81668. + }
  81669. + if (sc->sc_sessions) {
  81670. + for (i = 0; i < sc->sc_nsessions; i++)
  81671. + kfree(sc->sc_sessions[i]);
  81672. + kfree(sc->sc_sessions);
  81673. + }
  81674. + if (sc->iob_pdev)
  81675. + pci_dev_put(sc->iob_pdev);
  81676. + if (sc->dma_regs)
  81677. + iounmap(sc->dma_regs);
  81678. + if (sc->iob_regs)
  81679. + iounmap(sc->iob_regs);
  81680. + kfree(sc);
  81681. +}
  81682. +
  81683. +static struct pci_device_id pasemi_dma_pci_tbl[] = {
  81684. + { PCI_DEVICE(PCI_VENDOR_ID_PASEMI, 0xa007) },
  81685. +};
  81686. +
  81687. +MODULE_DEVICE_TABLE(pci, pasemi_dma_pci_tbl);
  81688. +
  81689. +static struct pci_driver pasemi_dma_driver = {
  81690. + .name = "pasemi_dma",
  81691. + .id_table = pasemi_dma_pci_tbl,
  81692. + .probe = pasemi_dma_probe,
  81693. + .remove = __devexit_p(pasemi_dma_remove),
  81694. +};
  81695. +
  81696. +static void __exit pasemi_dma_cleanup_module(void)
  81697. +{
  81698. + pci_unregister_driver(&pasemi_dma_driver);
  81699. + __iounmap(dma_status);
  81700. + dma_status = NULL;
  81701. +}
  81702. +
  81703. +int pasemi_dma_init_module(void)
  81704. +{
  81705. + return pci_register_driver(&pasemi_dma_driver);
  81706. +}
  81707. +
  81708. +module_init(pasemi_dma_init_module);
  81709. +module_exit(pasemi_dma_cleanup_module);
  81710. +
  81711. +MODULE_LICENSE("Dual BSD/GPL");
  81712. +MODULE_AUTHOR("Egor Martovetsky egor@pasemi.com");
  81713. +MODULE_DESCRIPTION("OCF driver for PA Semi PWRficient DMA Crypto Engine");
  81714. diff -Nur linux-2.6.39.orig/crypto/ocf/pasemi/pasemi_fnu.h linux-2.6.39/crypto/ocf/pasemi/pasemi_fnu.h
  81715. --- linux-2.6.39.orig/crypto/ocf/pasemi/pasemi_fnu.h 1970-01-01 01:00:00.000000000 +0100
  81716. +++ linux-2.6.39/crypto/ocf/pasemi/pasemi_fnu.h 2011-08-01 14:38:19.000000000 +0200
  81717. @@ -0,0 +1,410 @@
  81718. +/*
  81719. + * Copyright (C) 2007 PA Semi, Inc
  81720. + *
  81721. + * Driver for the PA Semi PWRficient DMA Crypto Engine, soft state and
  81722. + * hardware register layouts.
  81723. + *
  81724. + * This program is free software; you can redistribute it and/or modify
  81725. + * it under the terms of the GNU General Public License version 2 as
  81726. + * published by the Free Software Foundation.
  81727. + *
  81728. + * This program is distributed in the hope that it will be useful,
  81729. + * but WITHOUT ANY WARRANTY; without even the implied warranty of
  81730. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  81731. + * GNU General Public License for more details.
  81732. + *
  81733. + * You should have received a copy of the GNU General Public License
  81734. + * along with this program; if not, write to the Free Software
  81735. + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  81736. + */
  81737. +
  81738. +#ifndef PASEMI_FNU_H
  81739. +#define PASEMI_FNU_H
  81740. +
  81741. +#include <linux/spinlock.h>
  81742. +
  81743. +#define PASEMI_SESSION(sid) ((sid) & 0xffffffff)
  81744. +#define PASEMI_SID(sesn) ((sesn) & 0xffffffff)
  81745. +#define DPRINTF(a...) if (debug) { printk(DRV_NAME ": " a); }
  81746. +
  81747. +/* Must be a power of two */
  81748. +#define RX_RING_SIZE 512
  81749. +#define TX_RING_SIZE 512
  81750. +#define TX_DESC(ring, num) ((ring)->desc[2 * (num & (TX_RING_SIZE-1))])
  81751. +#define TX_DESC_INFO(ring, num) ((ring)->desc_info[(num) & (TX_RING_SIZE-1)])
  81752. +#define MAX_DESC_SIZE 8
  81753. +#define PASEMI_INITIAL_SESSIONS 10
  81754. +#define PASEMI_FNU_CHANNELS 8
  81755. +
  81756. +/* DMA descriptor */
  81757. +struct pasemi_desc {
  81758. + u64 quad[2*MAX_DESC_SIZE];
  81759. + int quad_cnt;
  81760. + int size;
  81761. + int postop;
  81762. +};
  81763. +
  81764. +/*
  81765. + * Holds per descriptor data
  81766. + */
  81767. +struct pasemi_desc_info {
  81768. + int desc_size;
  81769. + int desc_postop;
  81770. +#define PASEMI_CHECK_SIG 0x1
  81771. +
  81772. + struct cryptop *cf_crp;
  81773. +};
  81774. +
  81775. +/*
  81776. + * Holds per channel data
  81777. + */
  81778. +struct pasemi_fnu_txring {
  81779. + volatile u64 *desc;
  81780. + volatile struct
  81781. + pasemi_desc_info *desc_info;
  81782. + dma_addr_t dma;
  81783. + struct timer_list crypto_timer;
  81784. + spinlock_t fill_lock;
  81785. + spinlock_t clean_lock;
  81786. + unsigned int next_to_fill;
  81787. + unsigned int next_to_clean;
  81788. + u16 total_pktcnt;
  81789. + int irq;
  81790. + int sesn;
  81791. + char irq_name[10];
  81792. +};
  81793. +
  81794. +/*
  81795. + * Holds data specific to a single pasemi device.
  81796. + */
  81797. +struct pasemi_softc {
  81798. + softc_device_decl sc_cdev;
  81799. + struct pci_dev *dma_pdev; /* device backpointer */
  81800. + struct pci_dev *iob_pdev; /* device backpointer */
  81801. + void __iomem *dma_regs;
  81802. + void __iomem *iob_regs;
  81803. + int base_irq;
  81804. + int base_chan;
  81805. + int32_t sc_cid; /* crypto tag */
  81806. + int sc_nsessions;
  81807. + struct pasemi_session **sc_sessions;
  81808. + int sc_num_channels;/* number of crypto channels */
  81809. +
  81810. + /* pointer to the array of txring datastructures, one txring per channel */
  81811. + struct pasemi_fnu_txring *tx;
  81812. +
  81813. + /*
  81814. + * mutual exclusion for the channel scheduler
  81815. + */
  81816. + spinlock_t sc_chnlock;
  81817. + /* last channel used, for now use round-robin to allocate channels */
  81818. + int sc_lastchn;
  81819. +};
  81820. +
  81821. +struct pasemi_session {
  81822. + u64 civ[2];
  81823. + u64 keysz;
  81824. + u64 key[4];
  81825. + u64 ccmd;
  81826. + u64 hkey[4];
  81827. + u64 hseq;
  81828. + u64 giv[2];
  81829. + u64 hiv[4];
  81830. +
  81831. + int used;
  81832. + dma_addr_t dma_addr;
  81833. + int chan;
  81834. +};
  81835. +
  81836. +/* status register layout in IOB region, at 0xfd800000 */
  81837. +struct pasdma_status {
  81838. + u64 rx_sta[64];
  81839. + u64 tx_sta[20];
  81840. +};
  81841. +
  81842. +#define ALG_IS_CIPHER(alg) ((alg == CRYPTO_DES_CBC) || \
  81843. + (alg == CRYPTO_3DES_CBC) || \
  81844. + (alg == CRYPTO_AES_CBC) || \
  81845. + (alg == CRYPTO_ARC4) || \
  81846. + (alg == CRYPTO_NULL_CBC))
  81847. +
  81848. +#define ALG_IS_SIG(alg) ((alg == CRYPTO_MD5) || \
  81849. + (alg == CRYPTO_MD5_HMAC) || \
  81850. + (alg == CRYPTO_SHA1) || \
  81851. + (alg == CRYPTO_SHA1_HMAC) || \
  81852. + (alg == CRYPTO_NULL_HMAC))
  81853. +
  81854. +enum {
  81855. + PAS_DMA_COM_TXCMD = 0x100, /* Transmit Command Register */
  81856. + PAS_DMA_COM_TXSTA = 0x104, /* Transmit Status Register */
  81857. + PAS_DMA_COM_RXCMD = 0x108, /* Receive Command Register */
  81858. + PAS_DMA_COM_RXSTA = 0x10c, /* Receive Status Register */
  81859. + PAS_DMA_COM_CFG = 0x114, /* DMA Configuration Register */
  81860. +};
  81861. +
  81862. +/* All these registers live in the PCI configuration space for the DMA PCI
  81863. + * device. Use the normal PCI config access functions for them.
  81864. + */
  81865. +
  81866. +#define PAS_DMA_COM_CFG_FWF 0x18000000
  81867. +
  81868. +#define PAS_DMA_COM_TXCMD_EN 0x00000001 /* enable */
  81869. +#define PAS_DMA_COM_TXSTA_ACT 0x00000001 /* active */
  81870. +#define PAS_DMA_COM_RXCMD_EN 0x00000001 /* enable */
  81871. +#define PAS_DMA_COM_RXSTA_ACT 0x00000001 /* active */
  81872. +
  81873. +#define _PAS_DMA_TXCHAN_STRIDE 0x20 /* Size per channel */
  81874. +#define _PAS_DMA_TXCHAN_TCMDSTA 0x300 /* Command / Status */
  81875. +#define _PAS_DMA_TXCHAN_CFG 0x304 /* Configuration */
  81876. +#define _PAS_DMA_TXCHAN_DSCRBU 0x308 /* Descriptor BU Allocation */
  81877. +#define _PAS_DMA_TXCHAN_INCR 0x310 /* Descriptor increment */
  81878. +#define _PAS_DMA_TXCHAN_CNT 0x314 /* Descriptor count/offset */
  81879. +#define _PAS_DMA_TXCHAN_BASEL 0x318 /* Descriptor ring base (low) */
  81880. +#define _PAS_DMA_TXCHAN_BASEU 0x31c /* (high) */
  81881. +#define PAS_DMA_TXCHAN_TCMDSTA(c) (0x300+(c)*_PAS_DMA_TXCHAN_STRIDE)
  81882. +#define PAS_DMA_TXCHAN_TCMDSTA_EN 0x00000001 /* Enabled */
  81883. +#define PAS_DMA_TXCHAN_TCMDSTA_ST 0x00000002 /* Stop interface */
  81884. +#define PAS_DMA_TXCHAN_TCMDSTA_ACT 0x00010000 /* Active */
  81885. +#define PAS_DMA_TXCHAN_CFG(c) (0x304+(c)*_PAS_DMA_TXCHAN_STRIDE)
  81886. +#define PAS_DMA_TXCHAN_CFG_TY_FUNC 0x00000002 /* Type = interface */
  81887. +#define PAS_DMA_TXCHAN_CFG_TY_IFACE 0x00000000 /* Type = interface */
  81888. +#define PAS_DMA_TXCHAN_CFG_TATTR_M 0x0000003c
  81889. +#define PAS_DMA_TXCHAN_CFG_TATTR_S 2
  81890. +#define PAS_DMA_TXCHAN_CFG_TATTR(x) (((x) << PAS_DMA_TXCHAN_CFG_TATTR_S) & \
  81891. + PAS_DMA_TXCHAN_CFG_TATTR_M)
  81892. +#define PAS_DMA_TXCHAN_CFG_WT_M 0x000001c0
  81893. +#define PAS_DMA_TXCHAN_CFG_WT_S 6
  81894. +#define PAS_DMA_TXCHAN_CFG_WT(x) (((x) << PAS_DMA_TXCHAN_CFG_WT_S) & \
  81895. + PAS_DMA_TXCHAN_CFG_WT_M)
  81896. +#define PAS_DMA_TXCHAN_CFG_LPSQ_FAST 0x00000400
  81897. +#define PAS_DMA_TXCHAN_CFG_LPDQ_FAST 0x00000800
  81898. +#define PAS_DMA_TXCHAN_CFG_CF 0x00001000 /* Clean first line */
  81899. +#define PAS_DMA_TXCHAN_CFG_CL 0x00002000 /* Clean last line */
  81900. +#define PAS_DMA_TXCHAN_CFG_UP 0x00004000 /* update tx descr when sent */
  81901. +#define PAS_DMA_TXCHAN_INCR(c) (0x310+(c)*_PAS_DMA_TXCHAN_STRIDE)
  81902. +#define PAS_DMA_TXCHAN_BASEL(c) (0x318+(c)*_PAS_DMA_TXCHAN_STRIDE)
  81903. +#define PAS_DMA_TXCHAN_BASEL_BRBL_M 0xffffffc0
  81904. +#define PAS_DMA_TXCHAN_BASEL_BRBL_S 0
  81905. +#define PAS_DMA_TXCHAN_BASEL_BRBL(x) (((x) << PAS_DMA_TXCHAN_BASEL_BRBL_S) & \
  81906. + PAS_DMA_TXCHAN_BASEL_BRBL_M)
  81907. +#define PAS_DMA_TXCHAN_BASEU(c) (0x31c+(c)*_PAS_DMA_TXCHAN_STRIDE)
  81908. +#define PAS_DMA_TXCHAN_BASEU_BRBH_M 0x00000fff
  81909. +#define PAS_DMA_TXCHAN_BASEU_BRBH_S 0
  81910. +#define PAS_DMA_TXCHAN_BASEU_BRBH(x) (((x) << PAS_DMA_TXCHAN_BASEU_BRBH_S) & \
  81911. + PAS_DMA_TXCHAN_BASEU_BRBH_M)
  81912. +/* # of cache lines worth of buffer ring */
  81913. +#define PAS_DMA_TXCHAN_BASEU_SIZ_M 0x3fff0000
  81914. +#define PAS_DMA_TXCHAN_BASEU_SIZ_S 16 /* 0 = 16K */
  81915. +#define PAS_DMA_TXCHAN_BASEU_SIZ(x) (((x) << PAS_DMA_TXCHAN_BASEU_SIZ_S) & \
  81916. + PAS_DMA_TXCHAN_BASEU_SIZ_M)
  81917. +
  81918. +#define PAS_STATUS_PCNT_M 0x000000000000ffffull
  81919. +#define PAS_STATUS_PCNT_S 0
  81920. +#define PAS_STATUS_DCNT_M 0x00000000ffff0000ull
  81921. +#define PAS_STATUS_DCNT_S 16
  81922. +#define PAS_STATUS_BPCNT_M 0x0000ffff00000000ull
  81923. +#define PAS_STATUS_BPCNT_S 32
  81924. +#define PAS_STATUS_CAUSE_M 0xf000000000000000ull
  81925. +#define PAS_STATUS_TIMER 0x1000000000000000ull
  81926. +#define PAS_STATUS_ERROR 0x2000000000000000ull
  81927. +#define PAS_STATUS_SOFT 0x4000000000000000ull
  81928. +#define PAS_STATUS_INT 0x8000000000000000ull
  81929. +
  81930. +#define PAS_IOB_DMA_RXCH_CFG(i) (0x1100 + (i)*4)
  81931. +#define PAS_IOB_DMA_RXCH_CFG_CNTTH_M 0x00000fff
  81932. +#define PAS_IOB_DMA_RXCH_CFG_CNTTH_S 0
  81933. +#define PAS_IOB_DMA_RXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_RXCH_CFG_CNTTH_S) & \
  81934. + PAS_IOB_DMA_RXCH_CFG_CNTTH_M)
  81935. +#define PAS_IOB_DMA_TXCH_CFG(i) (0x1200 + (i)*4)
  81936. +#define PAS_IOB_DMA_TXCH_CFG_CNTTH_M 0x00000fff
  81937. +#define PAS_IOB_DMA_TXCH_CFG_CNTTH_S 0
  81938. +#define PAS_IOB_DMA_TXCH_CFG_CNTTH(x) (((x) << PAS_IOB_DMA_TXCH_CFG_CNTTH_S) & \
  81939. + PAS_IOB_DMA_TXCH_CFG_CNTTH_M)
  81940. +#define PAS_IOB_DMA_RXCH_STAT(i) (0x1300 + (i)*4)
  81941. +#define PAS_IOB_DMA_RXCH_STAT_INTGEN 0x00001000
  81942. +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_M 0x00000fff
  81943. +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL_S 0
  81944. +#define PAS_IOB_DMA_RXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_RXCH_STAT_CNTDEL_S) &\
  81945. + PAS_IOB_DMA_RXCH_STAT_CNTDEL_M)
  81946. +#define PAS_IOB_DMA_TXCH_STAT(i) (0x1400 + (i)*4)
  81947. +#define PAS_IOB_DMA_TXCH_STAT_INTGEN 0x00001000
  81948. +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_M 0x00000fff
  81949. +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL_S 0
  81950. +#define PAS_IOB_DMA_TXCH_STAT_CNTDEL(x) (((x) << PAS_IOB_DMA_TXCH_STAT_CNTDEL_S) &\
  81951. + PAS_IOB_DMA_TXCH_STAT_CNTDEL_M)
  81952. +#define PAS_IOB_DMA_RXCH_RESET(i) (0x1500 + (i)*4)
  81953. +#define PAS_IOB_DMA_RXCH_RESET_PCNT_M 0xffff0000
  81954. +#define PAS_IOB_DMA_RXCH_RESET_PCNT_S 16
  81955. +#define PAS_IOB_DMA_RXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_RXCH_RESET_PCNT_S) & \
  81956. + PAS_IOB_DMA_RXCH_RESET_PCNT_M)
  81957. +#define PAS_IOB_DMA_RXCH_RESET_PCNTRST 0x00000020
  81958. +#define PAS_IOB_DMA_RXCH_RESET_DCNTRST 0x00000010
  81959. +#define PAS_IOB_DMA_RXCH_RESET_TINTC 0x00000008
  81960. +#define PAS_IOB_DMA_RXCH_RESET_DINTC 0x00000004
  81961. +#define PAS_IOB_DMA_RXCH_RESET_SINTC 0x00000002
  81962. +#define PAS_IOB_DMA_RXCH_RESET_PINTC 0x00000001
  81963. +#define PAS_IOB_DMA_TXCH_RESET(i) (0x1600 + (i)*4)
  81964. +#define PAS_IOB_DMA_TXCH_RESET_PCNT_M 0xffff0000
  81965. +#define PAS_IOB_DMA_TXCH_RESET_PCNT_S 16
  81966. +#define PAS_IOB_DMA_TXCH_RESET_PCNT(x) (((x) << PAS_IOB_DMA_TXCH_RESET_PCNT_S) & \
  81967. + PAS_IOB_DMA_TXCH_RESET_PCNT_M)
  81968. +#define PAS_IOB_DMA_TXCH_RESET_PCNTRST 0x00000020
  81969. +#define PAS_IOB_DMA_TXCH_RESET_DCNTRST 0x00000010
  81970. +#define PAS_IOB_DMA_TXCH_RESET_TINTC 0x00000008
  81971. +#define PAS_IOB_DMA_TXCH_RESET_DINTC 0x00000004
  81972. +#define PAS_IOB_DMA_TXCH_RESET_SINTC 0x00000002
  81973. +#define PAS_IOB_DMA_TXCH_RESET_PINTC 0x00000001
  81974. +
  81975. +#define PAS_IOB_DMA_COM_TIMEOUTCFG 0x1700
  81976. +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M 0x00ffffff
  81977. +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S 0
  81978. +#define PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(x) (((x) << PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_S) & \
  81979. + PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT_M)
  81980. +
  81981. +/* Transmit descriptor fields */
  81982. +#define XCT_MACTX_T 0x8000000000000000ull
  81983. +#define XCT_MACTX_ST 0x4000000000000000ull
  81984. +#define XCT_MACTX_NORES 0x0000000000000000ull
  81985. +#define XCT_MACTX_8BRES 0x1000000000000000ull
  81986. +#define XCT_MACTX_24BRES 0x2000000000000000ull
  81987. +#define XCT_MACTX_40BRES 0x3000000000000000ull
  81988. +#define XCT_MACTX_I 0x0800000000000000ull
  81989. +#define XCT_MACTX_O 0x0400000000000000ull
  81990. +#define XCT_MACTX_E 0x0200000000000000ull
  81991. +#define XCT_MACTX_VLAN_M 0x0180000000000000ull
  81992. +#define XCT_MACTX_VLAN_NOP 0x0000000000000000ull
  81993. +#define XCT_MACTX_VLAN_REMOVE 0x0080000000000000ull
  81994. +#define XCT_MACTX_VLAN_INSERT 0x0100000000000000ull
  81995. +#define XCT_MACTX_VLAN_REPLACE 0x0180000000000000ull
  81996. +#define XCT_MACTX_CRC_M 0x0060000000000000ull
  81997. +#define XCT_MACTX_CRC_NOP 0x0000000000000000ull
  81998. +#define XCT_MACTX_CRC_INSERT 0x0020000000000000ull
  81999. +#define XCT_MACTX_CRC_PAD 0x0040000000000000ull
  82000. +#define XCT_MACTX_CRC_REPLACE 0x0060000000000000ull
  82001. +#define XCT_MACTX_SS 0x0010000000000000ull
  82002. +#define XCT_MACTX_LLEN_M 0x00007fff00000000ull
  82003. +#define XCT_MACTX_LLEN_S 32ull
  82004. +#define XCT_MACTX_LLEN(x) ((((long)(x)) << XCT_MACTX_LLEN_S) & \
  82005. + XCT_MACTX_LLEN_M)
  82006. +#define XCT_MACTX_IPH_M 0x00000000f8000000ull
  82007. +#define XCT_MACTX_IPH_S 27ull
  82008. +#define XCT_MACTX_IPH(x) ((((long)(x)) << XCT_MACTX_IPH_S) & \
  82009. + XCT_MACTX_IPH_M)
  82010. +#define XCT_MACTX_IPO_M 0x0000000007c00000ull
  82011. +#define XCT_MACTX_IPO_S 22ull
  82012. +#define XCT_MACTX_IPO(x) ((((long)(x)) << XCT_MACTX_IPO_S) & \
  82013. + XCT_MACTX_IPO_M)
  82014. +#define XCT_MACTX_CSUM_M 0x0000000000000060ull
  82015. +#define XCT_MACTX_CSUM_NOP 0x0000000000000000ull
  82016. +#define XCT_MACTX_CSUM_TCP 0x0000000000000040ull
  82017. +#define XCT_MACTX_CSUM_UDP 0x0000000000000060ull
  82018. +#define XCT_MACTX_V6 0x0000000000000010ull
  82019. +#define XCT_MACTX_C 0x0000000000000004ull
  82020. +#define XCT_MACTX_AL2 0x0000000000000002ull
  82021. +
  82022. +#define XCT_PTR_T 0x8000000000000000ull
  82023. +#define XCT_PTR_LEN_M 0x7ffff00000000000ull
  82024. +#define XCT_PTR_LEN_S 44
  82025. +#define XCT_PTR_LEN(x) ((((long)(x)) << XCT_PTR_LEN_S) & \
  82026. + XCT_PTR_LEN_M)
  82027. +#define XCT_PTR_ADDR_M 0x00000fffffffffffull
  82028. +#define XCT_PTR_ADDR_S 0
  82029. +#define XCT_PTR_ADDR(x) ((((long)(x)) << XCT_PTR_ADDR_S) & \
  82030. + XCT_PTR_ADDR_M)
  82031. +
  82032. +/* Function descriptor fields */
  82033. +#define XCT_FUN_T 0x8000000000000000ull
  82034. +#define XCT_FUN_ST 0x4000000000000000ull
  82035. +#define XCT_FUN_NORES 0x0000000000000000ull
  82036. +#define XCT_FUN_8BRES 0x1000000000000000ull
  82037. +#define XCT_FUN_24BRES 0x2000000000000000ull
  82038. +#define XCT_FUN_40BRES 0x3000000000000000ull
  82039. +#define XCT_FUN_I 0x0800000000000000ull
  82040. +#define XCT_FUN_O 0x0400000000000000ull
  82041. +#define XCT_FUN_E 0x0200000000000000ull
  82042. +#define XCT_FUN_FUN_S 54
  82043. +#define XCT_FUN_FUN_M 0x01c0000000000000ull
  82044. +#define XCT_FUN_FUN(num) ((((long)(num)) << XCT_FUN_FUN_S) & \
  82045. + XCT_FUN_FUN_M)
  82046. +#define XCT_FUN_CRM_NOP 0x0000000000000000ull
  82047. +#define XCT_FUN_CRM_SIG 0x0008000000000000ull
  82048. +#define XCT_FUN_CRM_ENC 0x0010000000000000ull
  82049. +#define XCT_FUN_CRM_DEC 0x0018000000000000ull
  82050. +#define XCT_FUN_CRM_SIG_ENC 0x0020000000000000ull
  82051. +#define XCT_FUN_CRM_ENC_SIG 0x0028000000000000ull
  82052. +#define XCT_FUN_CRM_SIG_DEC 0x0030000000000000ull
  82053. +#define XCT_FUN_CRM_DEC_SIG 0x0038000000000000ull
  82054. +#define XCT_FUN_LLEN_M 0x0007ffff00000000ull
  82055. +#define XCT_FUN_LLEN_S 32ULL
  82056. +#define XCT_FUN_LLEN(x) ((((long)(x)) << XCT_FUN_LLEN_S) & \
  82057. + XCT_FUN_LLEN_M)
  82058. +#define XCT_FUN_SHL_M 0x00000000f8000000ull
  82059. +#define XCT_FUN_SHL_S 27ull
  82060. +#define XCT_FUN_SHL(x) ((((long)(x)) << XCT_FUN_SHL_S) & \
  82061. + XCT_FUN_SHL_M)
  82062. +#define XCT_FUN_CHL_M 0x0000000007c00000ull
  82063. +#define XCT_FUN_CHL_S 22ull
  82064. +#define XCT_FUN_CHL(x) ((((long)(x)) << XCT_FUN_CHL_S) & \
  82065. + XCT_FUN_CHL_M)
  82066. +#define XCT_FUN_HSZ_M 0x00000000003c0000ull
  82067. +#define XCT_FUN_HSZ_S 18ull
  82068. +#define XCT_FUN_HSZ(x) ((((long)(x)) << XCT_FUN_HSZ_S) & \
  82069. + XCT_FUN_HSZ_M)
  82070. +#define XCT_FUN_ALG_DES 0x0000000000000000ull
  82071. +#define XCT_FUN_ALG_3DES 0x0000000000008000ull
  82072. +#define XCT_FUN_ALG_AES 0x0000000000010000ull
  82073. +#define XCT_FUN_ALG_ARC 0x0000000000018000ull
  82074. +#define XCT_FUN_ALG_KASUMI 0x0000000000020000ull
  82075. +#define XCT_FUN_BCM_ECB 0x0000000000000000ull
  82076. +#define XCT_FUN_BCM_CBC 0x0000000000001000ull
  82077. +#define XCT_FUN_BCM_CFB 0x0000000000002000ull
  82078. +#define XCT_FUN_BCM_OFB 0x0000000000003000ull
  82079. +#define XCT_FUN_BCM_CNT 0x0000000000003800ull
  82080. +#define XCT_FUN_BCM_KAS_F8 0x0000000000002800ull
  82081. +#define XCT_FUN_BCM_KAS_F9 0x0000000000001800ull
  82082. +#define XCT_FUN_BCP_NO_PAD 0x0000000000000000ull
  82083. +#define XCT_FUN_BCP_ZRO 0x0000000000000200ull
  82084. +#define XCT_FUN_BCP_PL 0x0000000000000400ull
  82085. +#define XCT_FUN_BCP_INCR 0x0000000000000600ull
  82086. +#define XCT_FUN_SIG_MD5 (0ull << 4)
  82087. +#define XCT_FUN_SIG_SHA1 (2ull << 4)
  82088. +#define XCT_FUN_SIG_HMAC_MD5 (8ull << 4)
  82089. +#define XCT_FUN_SIG_HMAC_SHA1 (10ull << 4)
  82090. +#define XCT_FUN_A 0x0000000000000008ull
  82091. +#define XCT_FUN_C 0x0000000000000004ull
  82092. +#define XCT_FUN_AL2 0x0000000000000002ull
  82093. +#define XCT_FUN_SE 0x0000000000000001ull
  82094. +
  82095. +#define XCT_FUN_SRC_PTR(len, addr) (XCT_PTR_LEN(len) | XCT_PTR_ADDR(addr))
  82096. +#define XCT_FUN_DST_PTR(len, addr) (XCT_FUN_SRC_PTR(len, addr) | \
  82097. + 0x8000000000000000ull)
  82098. +
  82099. +#define XCT_CTRL_HDR_FUN_NUM_M 0x01c0000000000000ull
  82100. +#define XCT_CTRL_HDR_FUN_NUM_S 54
  82101. +#define XCT_CTRL_HDR_LEN_M 0x0007ffff00000000ull
  82102. +#define XCT_CTRL_HDR_LEN_S 32
  82103. +#define XCT_CTRL_HDR_REG_M 0x00000000000000ffull
  82104. +#define XCT_CTRL_HDR_REG_S 0
  82105. +
  82106. +#define XCT_CTRL_HDR(funcN,len,reg) (0x9400000000000000ull | \
  82107. + ((((long)(funcN)) << XCT_CTRL_HDR_FUN_NUM_S) \
  82108. + & XCT_CTRL_HDR_FUN_NUM_M) | \
  82109. + ((((long)(len)) << \
  82110. + XCT_CTRL_HDR_LEN_S) & XCT_CTRL_HDR_LEN_M) | \
  82111. + ((((long)(reg)) << \
  82112. + XCT_CTRL_HDR_REG_S) & XCT_CTRL_HDR_REG_M))
  82113. +
  82114. +/* Function config command options */
  82115. +#define DMA_CALGO_DES 0x00
  82116. +#define DMA_CALGO_3DES 0x01
  82117. +#define DMA_CALGO_AES 0x02
  82118. +#define DMA_CALGO_ARC 0x03
  82119. +
  82120. +#define DMA_FN_CIV0 0x02
  82121. +#define DMA_FN_CIV1 0x03
  82122. +#define DMA_FN_HKEY0 0x0a
  82123. +
  82124. +#define XCT_PTR_ADDR_LEN(ptr) ((ptr) & XCT_PTR_ADDR_M), \
  82125. + (((ptr) & XCT_PTR_LEN_M) >> XCT_PTR_LEN_S)
  82126. +
  82127. +#endif /* PASEMI_FNU_H */
  82128. diff -Nur linux-2.6.39.orig/crypto/ocf/random.c linux-2.6.39/crypto/ocf/random.c
  82129. --- linux-2.6.39.orig/crypto/ocf/random.c 1970-01-01 01:00:00.000000000 +0100
  82130. +++ linux-2.6.39/crypto/ocf/random.c 2011-08-01 14:38:19.000000000 +0200
  82131. @@ -0,0 +1,322 @@
  82132. +/*
  82133. + * A system independant way of adding entropy to the kernels pool
  82134. + * this way the drivers can focus on the real work and we can take
  82135. + * care of pushing it to the appropriate place in the kernel.
  82136. + *
  82137. + * This should be fast and callable from timers/interrupts
  82138. + *
  82139. + * Written by David McCullough <david_mccullough@mcafee.com>
  82140. + * Copyright (C) 2006-2010 David McCullough
  82141. + * Copyright (C) 2004-2005 Intel Corporation.
  82142. + *
  82143. + * LICENSE TERMS
  82144. + *
  82145. + * The free distribution and use of this software in both source and binary
  82146. + * form is allowed (with or without changes) provided that:
  82147. + *
  82148. + * 1. distributions of this source code include the above copyright
  82149. + * notice, this list of conditions and the following disclaimer;
  82150. + *
  82151. + * 2. distributions in binary form include the above copyright
  82152. + * notice, this list of conditions and the following disclaimer
  82153. + * in the documentation and/or other associated materials;
  82154. + *
  82155. + * 3. the copyright holder's name is not used to endorse products
  82156. + * built using this software without specific written permission.
  82157. + *
  82158. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  82159. + * may be distributed under the terms of the GNU General Public License (GPL),
  82160. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  82161. + *
  82162. + * DISCLAIMER
  82163. + *
  82164. + * This software is provided 'as is' with no explicit or implied warranties
  82165. + * in respect of its properties, including, but not limited to, correctness
  82166. + * and/or fitness for purpose.
  82167. + */
  82168. +
  82169. +#ifndef AUTOCONF_INCLUDED
  82170. +#include <linux/config.h>
  82171. +#endif
  82172. +#include <linux/module.h>
  82173. +#include <linux/init.h>
  82174. +#include <linux/list.h>
  82175. +#include <linux/slab.h>
  82176. +#include <linux/wait.h>
  82177. +#include <linux/sched.h>
  82178. +#include <linux/spinlock.h>
  82179. +#include <linux/version.h>
  82180. +#include <linux/unistd.h>
  82181. +#include <linux/poll.h>
  82182. +#include <linux/random.h>
  82183. +#include <cryptodev.h>
  82184. +
  82185. +#ifdef CONFIG_OCF_FIPS
  82186. +#include "rndtest.h"
  82187. +#endif
  82188. +
  82189. +#ifndef HAS_RANDOM_INPUT_WAIT
  82190. +#error "Please do not enable OCF_RANDOMHARVEST unless you have applied patches"
  82191. +#endif
  82192. +
  82193. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)
  82194. +#include <linux/sched.h>
  82195. +#define kill_proc(p,s,v) send_sig(s,find_task_by_vpid(p),0)
  82196. +#endif
  82197. +
  82198. +/*
  82199. + * a hack to access the debug levels from the crypto driver
  82200. + */
  82201. +extern int crypto_debug;
  82202. +#define debug crypto_debug
  82203. +
  82204. +/*
  82205. + * a list of all registered random providers
  82206. + */
  82207. +static LIST_HEAD(random_ops);
  82208. +static int started = 0;
  82209. +static int initted = 0;
  82210. +
  82211. +struct random_op {
  82212. + struct list_head random_list;
  82213. + u_int32_t driverid;
  82214. + int (*read_random)(void *arg, u_int32_t *buf, int len);
  82215. + void *arg;
  82216. +};
  82217. +
  82218. +static int random_proc(void *arg);
  82219. +
  82220. +static pid_t randomproc = (pid_t) -1;
  82221. +static spinlock_t random_lock;
  82222. +
  82223. +/*
  82224. + * just init the spin locks
  82225. + */
  82226. +static int
  82227. +crypto_random_init(void)
  82228. +{
  82229. + spin_lock_init(&random_lock);
  82230. + initted = 1;
  82231. + return(0);
  82232. +}
  82233. +
  82234. +/*
  82235. + * Add the given random reader to our list (if not present)
  82236. + * and start the thread (if not already started)
  82237. + *
  82238. + * we have to assume that driver id is ok for now
  82239. + */
  82240. +int
  82241. +crypto_rregister(
  82242. + u_int32_t driverid,
  82243. + int (*read_random)(void *arg, u_int32_t *buf, int len),
  82244. + void *arg)
  82245. +{
  82246. + unsigned long flags;
  82247. + int ret = 0;
  82248. + struct random_op *rops, *tmp;
  82249. +
  82250. + dprintk("%s,%d: %s(0x%x, %p, %p)\n", __FILE__, __LINE__,
  82251. + __FUNCTION__, driverid, read_random, arg);
  82252. +
  82253. + if (!initted)
  82254. + crypto_random_init();
  82255. +
  82256. +#if 0
  82257. + struct cryptocap *cap;
  82258. +
  82259. + cap = crypto_checkdriver(driverid);
  82260. + if (!cap)
  82261. + return EINVAL;
  82262. +#endif
  82263. +
  82264. + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
  82265. + if (rops->driverid == driverid && rops->read_random == read_random)
  82266. + return EEXIST;
  82267. + }
  82268. +
  82269. + rops = (struct random_op *) kmalloc(sizeof(*rops), GFP_KERNEL);
  82270. + if (!rops)
  82271. + return ENOMEM;
  82272. +
  82273. + rops->driverid = driverid;
  82274. + rops->read_random = read_random;
  82275. + rops->arg = arg;
  82276. +
  82277. + spin_lock_irqsave(&random_lock, flags);
  82278. + list_add_tail(&rops->random_list, &random_ops);
  82279. + if (!started) {
  82280. + randomproc = kernel_thread(random_proc, NULL, CLONE_FS|CLONE_FILES);
  82281. + if (randomproc < 0) {
  82282. + ret = randomproc;
  82283. + printk("crypto: crypto_rregister cannot start random thread; "
  82284. + "error %d", ret);
  82285. + } else
  82286. + started = 1;
  82287. + }
  82288. + spin_unlock_irqrestore(&random_lock, flags);
  82289. +
  82290. + return ret;
  82291. +}
  82292. +EXPORT_SYMBOL(crypto_rregister);
  82293. +
  82294. +int
  82295. +crypto_runregister_all(u_int32_t driverid)
  82296. +{
  82297. + struct random_op *rops, *tmp;
  82298. + unsigned long flags;
  82299. +
  82300. + dprintk("%s,%d: %s(0x%x)\n", __FILE__, __LINE__, __FUNCTION__, driverid);
  82301. +
  82302. + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
  82303. + if (rops->driverid == driverid) {
  82304. + list_del(&rops->random_list);
  82305. + kfree(rops);
  82306. + }
  82307. + }
  82308. +
  82309. + spin_lock_irqsave(&random_lock, flags);
  82310. + if (list_empty(&random_ops) && started)
  82311. + kill_proc(randomproc, SIGKILL, 1);
  82312. + spin_unlock_irqrestore(&random_lock, flags);
  82313. + return(0);
  82314. +}
  82315. +EXPORT_SYMBOL(crypto_runregister_all);
  82316. +
  82317. +/*
  82318. + * while we can add entropy to random.c continue to read random data from
  82319. + * the drivers and push it to random.
  82320. + */
  82321. +static int
  82322. +random_proc(void *arg)
  82323. +{
  82324. + int n;
  82325. + int wantcnt;
  82326. + int bufcnt = 0;
  82327. + int retval = 0;
  82328. + int *buf = NULL;
  82329. +
  82330. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  82331. + daemonize();
  82332. + spin_lock_irq(&current->sigmask_lock);
  82333. + sigemptyset(&current->blocked);
  82334. + recalc_sigpending(current);
  82335. + spin_unlock_irq(&current->sigmask_lock);
  82336. + sprintf(current->comm, "ocf-random");
  82337. +#else
  82338. + daemonize("ocf-random");
  82339. + allow_signal(SIGKILL);
  82340. +#endif
  82341. +
  82342. + (void) get_fs();
  82343. + set_fs(get_ds());
  82344. +
  82345. +#ifdef CONFIG_OCF_FIPS
  82346. +#define NUM_INT (RNDTEST_NBYTES/sizeof(int))
  82347. +#else
  82348. +#define NUM_INT 32
  82349. +#endif
  82350. +
  82351. + /*
  82352. + * some devices can transferr their RNG data direct into memory,
  82353. + * so make sure it is device friendly
  82354. + */
  82355. + buf = kmalloc(NUM_INT * sizeof(int), GFP_DMA);
  82356. + if (NULL == buf) {
  82357. + printk("crypto: RNG could not allocate memory\n");
  82358. + retval = -ENOMEM;
  82359. + goto bad_alloc;
  82360. + }
  82361. +
  82362. + wantcnt = NUM_INT; /* start by adding some entropy */
  82363. +
  82364. + /*
  82365. + * its possible due to errors or driver removal that we no longer
  82366. + * have anything to do, if so exit or we will consume all the CPU
  82367. + * doing nothing
  82368. + */
  82369. + while (!list_empty(&random_ops)) {
  82370. + struct random_op *rops, *tmp;
  82371. +
  82372. +#ifdef CONFIG_OCF_FIPS
  82373. + if (wantcnt)
  82374. + wantcnt = NUM_INT; /* FIPs mode can do 20000 bits or none */
  82375. +#endif
  82376. +
  82377. + /* see if we can get enough entropy to make the world
  82378. + * a better place.
  82379. + */
  82380. + while (bufcnt < wantcnt && bufcnt < NUM_INT) {
  82381. + list_for_each_entry_safe(rops, tmp, &random_ops, random_list) {
  82382. +
  82383. + n = (*rops->read_random)(rops->arg, &buf[bufcnt],
  82384. + NUM_INT - bufcnt);
  82385. +
  82386. + /* on failure remove the random number generator */
  82387. + if (n == -1) {
  82388. + list_del(&rops->random_list);
  82389. + printk("crypto: RNG (driverid=0x%x) failed, disabling\n",
  82390. + rops->driverid);
  82391. + kfree(rops);
  82392. + } else if (n > 0)
  82393. + bufcnt += n;
  82394. + }
  82395. + /* give up CPU for a bit, just in case as this is a loop */
  82396. + schedule();
  82397. + }
  82398. +
  82399. +
  82400. +#ifdef CONFIG_OCF_FIPS
  82401. + if (bufcnt > 0 && rndtest_buf((unsigned char *) &buf[0])) {
  82402. + dprintk("crypto: buffer had fips errors, discarding\n");
  82403. + bufcnt = 0;
  82404. + }
  82405. +#endif
  82406. +
  82407. + /*
  82408. + * if we have a certified buffer, we can send some data
  82409. + * to /dev/random and move along
  82410. + */
  82411. + if (bufcnt > 0) {
  82412. + /* add what we have */
  82413. + random_input_words(buf, bufcnt, bufcnt*sizeof(int)*8);
  82414. + bufcnt = 0;
  82415. + }
  82416. +
  82417. + /* give up CPU for a bit so we don't hog while filling */
  82418. + schedule();
  82419. +
  82420. + /* wait for needing more */
  82421. + wantcnt = random_input_wait();
  82422. +
  82423. + if (wantcnt <= 0)
  82424. + wantcnt = 0; /* try to get some info again */
  82425. + else
  82426. + /* round up to one word or we can loop forever */
  82427. + wantcnt = (wantcnt + (sizeof(int)*8)) / (sizeof(int)*8);
  82428. + if (wantcnt > NUM_INT) {
  82429. + wantcnt = NUM_INT;
  82430. + }
  82431. +
  82432. + if (signal_pending(current)) {
  82433. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  82434. + spin_lock_irq(&current->sigmask_lock);
  82435. +#endif
  82436. + flush_signals(current);
  82437. +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
  82438. + spin_unlock_irq(&current->sigmask_lock);
  82439. +#endif
  82440. + }
  82441. + }
  82442. +
  82443. + kfree(buf);
  82444. +
  82445. +bad_alloc:
  82446. + spin_lock_irq(&random_lock);
  82447. + randomproc = (pid_t) -1;
  82448. + started = 0;
  82449. + spin_unlock_irq(&random_lock);
  82450. +
  82451. + return retval;
  82452. +}
  82453. +
  82454. diff -Nur linux-2.6.39.orig/crypto/ocf/rndtest.c linux-2.6.39/crypto/ocf/rndtest.c
  82455. --- linux-2.6.39.orig/crypto/ocf/rndtest.c 1970-01-01 01:00:00.000000000 +0100
  82456. +++ linux-2.6.39/crypto/ocf/rndtest.c 2011-08-01 14:38:19.000000000 +0200
  82457. @@ -0,0 +1,300 @@
  82458. +/* $OpenBSD$ */
  82459. +
  82460. +/*
  82461. + * OCF/Linux port done by David McCullough <david_mccullough@mcafee.com>
  82462. + * Copyright (C) 2006-2010 David McCullough
  82463. + * Copyright (C) 2004-2005 Intel Corporation.
  82464. + * The license and original author are listed below.
  82465. + *
  82466. + * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
  82467. + * All rights reserved.
  82468. + *
  82469. + * Redistribution and use in source and binary forms, with or without
  82470. + * modification, are permitted provided that the following conditions
  82471. + * are met:
  82472. + * 1. Redistributions of source code must retain the above copyright
  82473. + * notice, this list of conditions and the following disclaimer.
  82474. + * 2. Redistributions in binary form must reproduce the above copyright
  82475. + * notice, this list of conditions and the following disclaimer in the
  82476. + * documentation and/or other materials provided with the distribution.
  82477. + * 3. All advertising materials mentioning features or use of this software
  82478. + * must display the following acknowledgement:
  82479. + * This product includes software developed by Jason L. Wright
  82480. + * 4. The name of the author may not be used to endorse or promote products
  82481. + * derived from this software without specific prior written permission.
  82482. + *
  82483. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  82484. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  82485. + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  82486. + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  82487. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  82488. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  82489. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  82490. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  82491. + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  82492. + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  82493. + * POSSIBILITY OF SUCH DAMAGE.
  82494. + */
  82495. +
  82496. +#ifndef AUTOCONF_INCLUDED
  82497. +#include <linux/config.h>
  82498. +#endif
  82499. +#include <linux/module.h>
  82500. +#include <linux/list.h>
  82501. +#include <linux/wait.h>
  82502. +#include <linux/time.h>
  82503. +#include <linux/version.h>
  82504. +#include <linux/unistd.h>
  82505. +#include <linux/kernel.h>
  82506. +#include <linux/string.h>
  82507. +#include <linux/time.h>
  82508. +#include <cryptodev.h>
  82509. +#include "rndtest.h"
  82510. +
  82511. +static struct rndtest_stats rndstats;
  82512. +
  82513. +static void rndtest_test(struct rndtest_state *);
  82514. +
  82515. +/* The tests themselves */
  82516. +static int rndtest_monobit(struct rndtest_state *);
  82517. +static int rndtest_runs(struct rndtest_state *);
  82518. +static int rndtest_longruns(struct rndtest_state *);
  82519. +static int rndtest_chi_4(struct rndtest_state *);
  82520. +
  82521. +static int rndtest_runs_check(struct rndtest_state *, int, int *);
  82522. +static void rndtest_runs_record(struct rndtest_state *, int, int *);
  82523. +
  82524. +static const struct rndtest_testfunc {
  82525. + int (*test)(struct rndtest_state *);
  82526. +} rndtest_funcs[] = {
  82527. + { rndtest_monobit },
  82528. + { rndtest_runs },
  82529. + { rndtest_chi_4 },
  82530. + { rndtest_longruns },
  82531. +};
  82532. +
  82533. +#define RNDTEST_NTESTS (sizeof(rndtest_funcs)/sizeof(rndtest_funcs[0]))
  82534. +
  82535. +static void
  82536. +rndtest_test(struct rndtest_state *rsp)
  82537. +{
  82538. + int i, rv = 0;
  82539. +
  82540. + rndstats.rst_tests++;
  82541. + for (i = 0; i < RNDTEST_NTESTS; i++)
  82542. + rv |= (*rndtest_funcs[i].test)(rsp);
  82543. + rsp->rs_discard = (rv != 0);
  82544. +}
  82545. +
  82546. +
  82547. +extern int crypto_debug;
  82548. +#define rndtest_verbose 2
  82549. +#define rndtest_report(rsp, failure, fmt, a...) \
  82550. + { if (failure || crypto_debug) { printk("rng_test: " fmt "\n", a); } else; }
  82551. +
  82552. +#define RNDTEST_MONOBIT_MINONES 9725
  82553. +#define RNDTEST_MONOBIT_MAXONES 10275
  82554. +
  82555. +static int
  82556. +rndtest_monobit(struct rndtest_state *rsp)
  82557. +{
  82558. + int i, ones = 0, j;
  82559. + u_int8_t r;
  82560. +
  82561. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  82562. + r = rsp->rs_buf[i];
  82563. + for (j = 0; j < 8; j++, r <<= 1)
  82564. + if (r & 0x80)
  82565. + ones++;
  82566. + }
  82567. + if (ones > RNDTEST_MONOBIT_MINONES &&
  82568. + ones < RNDTEST_MONOBIT_MAXONES) {
  82569. + if (rndtest_verbose > 1)
  82570. + rndtest_report(rsp, 0, "monobit pass (%d < %d < %d)",
  82571. + RNDTEST_MONOBIT_MINONES, ones,
  82572. + RNDTEST_MONOBIT_MAXONES);
  82573. + return (0);
  82574. + } else {
  82575. + if (rndtest_verbose)
  82576. + rndtest_report(rsp, 1,
  82577. + "monobit failed (%d ones)", ones);
  82578. + rndstats.rst_monobit++;
  82579. + return (-1);
  82580. + }
  82581. +}
  82582. +
  82583. +#define RNDTEST_RUNS_NINTERVAL 6
  82584. +
  82585. +static const struct rndtest_runs_tabs {
  82586. + u_int16_t min, max;
  82587. +} rndtest_runs_tab[] = {
  82588. + { 2343, 2657 },
  82589. + { 1135, 1365 },
  82590. + { 542, 708 },
  82591. + { 251, 373 },
  82592. + { 111, 201 },
  82593. + { 111, 201 },
  82594. +};
  82595. +
  82596. +static int
  82597. +rndtest_runs(struct rndtest_state *rsp)
  82598. +{
  82599. + int i, j, ones, zeros, rv = 0;
  82600. + int onei[RNDTEST_RUNS_NINTERVAL], zeroi[RNDTEST_RUNS_NINTERVAL];
  82601. + u_int8_t c;
  82602. +
  82603. + bzero(onei, sizeof(onei));
  82604. + bzero(zeroi, sizeof(zeroi));
  82605. + ones = zeros = 0;
  82606. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  82607. + c = rsp->rs_buf[i];
  82608. + for (j = 0; j < 8; j++, c <<= 1) {
  82609. + if (c & 0x80) {
  82610. + ones++;
  82611. + rndtest_runs_record(rsp, zeros, zeroi);
  82612. + zeros = 0;
  82613. + } else {
  82614. + zeros++;
  82615. + rndtest_runs_record(rsp, ones, onei);
  82616. + ones = 0;
  82617. + }
  82618. + }
  82619. + }
  82620. + rndtest_runs_record(rsp, ones, onei);
  82621. + rndtest_runs_record(rsp, zeros, zeroi);
  82622. +
  82623. + rv |= rndtest_runs_check(rsp, 0, zeroi);
  82624. + rv |= rndtest_runs_check(rsp, 1, onei);
  82625. +
  82626. + if (rv)
  82627. + rndstats.rst_runs++;
  82628. +
  82629. + return (rv);
  82630. +}
  82631. +
  82632. +static void
  82633. +rndtest_runs_record(struct rndtest_state *rsp, int len, int *intrv)
  82634. +{
  82635. + if (len == 0)
  82636. + return;
  82637. + if (len > RNDTEST_RUNS_NINTERVAL)
  82638. + len = RNDTEST_RUNS_NINTERVAL;
  82639. + len -= 1;
  82640. + intrv[len]++;
  82641. +}
  82642. +
  82643. +static int
  82644. +rndtest_runs_check(struct rndtest_state *rsp, int val, int *src)
  82645. +{
  82646. + int i, rv = 0;
  82647. +
  82648. + for (i = 0; i < RNDTEST_RUNS_NINTERVAL; i++) {
  82649. + if (src[i] < rndtest_runs_tab[i].min ||
  82650. + src[i] > rndtest_runs_tab[i].max) {
  82651. + rndtest_report(rsp, 1,
  82652. + "%s interval %d failed (%d, %d-%d)",
  82653. + val ? "ones" : "zeros",
  82654. + i + 1, src[i], rndtest_runs_tab[i].min,
  82655. + rndtest_runs_tab[i].max);
  82656. + rv = -1;
  82657. + } else {
  82658. + rndtest_report(rsp, 0,
  82659. + "runs pass %s interval %d (%d < %d < %d)",
  82660. + val ? "ones" : "zeros",
  82661. + i + 1, rndtest_runs_tab[i].min, src[i],
  82662. + rndtest_runs_tab[i].max);
  82663. + }
  82664. + }
  82665. + return (rv);
  82666. +}
  82667. +
  82668. +static int
  82669. +rndtest_longruns(struct rndtest_state *rsp)
  82670. +{
  82671. + int i, j, ones = 0, zeros = 0, maxones = 0, maxzeros = 0;
  82672. + u_int8_t c;
  82673. +
  82674. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  82675. + c = rsp->rs_buf[i];
  82676. + for (j = 0; j < 8; j++, c <<= 1) {
  82677. + if (c & 0x80) {
  82678. + zeros = 0;
  82679. + ones++;
  82680. + if (ones > maxones)
  82681. + maxones = ones;
  82682. + } else {
  82683. + ones = 0;
  82684. + zeros++;
  82685. + if (zeros > maxzeros)
  82686. + maxzeros = zeros;
  82687. + }
  82688. + }
  82689. + }
  82690. +
  82691. + if (maxones < 26 && maxzeros < 26) {
  82692. + rndtest_report(rsp, 0, "longruns pass (%d ones, %d zeros)",
  82693. + maxones, maxzeros);
  82694. + return (0);
  82695. + } else {
  82696. + rndtest_report(rsp, 1, "longruns fail (%d ones, %d zeros)",
  82697. + maxones, maxzeros);
  82698. + rndstats.rst_longruns++;
  82699. + return (-1);
  82700. + }
  82701. +}
  82702. +
  82703. +/*
  82704. + * chi^2 test over 4 bits: (this is called the poker test in FIPS 140-2,
  82705. + * but it is really the chi^2 test over 4 bits (the poker test as described
  82706. + * by Knuth vol 2 is something different, and I take him as authoritative
  82707. + * on nomenclature over NIST).
  82708. + */
  82709. +#define RNDTEST_CHI4_K 16
  82710. +#define RNDTEST_CHI4_K_MASK (RNDTEST_CHI4_K - 1)
  82711. +
  82712. +/*
  82713. + * The unnormalized values are used so that we don't have to worry about
  82714. + * fractional precision. The "real" value is found by:
  82715. + * (V - 1562500) * (16 / 5000) = Vn (where V is the unnormalized value)
  82716. + */
  82717. +#define RNDTEST_CHI4_VMIN 1563181 /* 2.1792 */
  82718. +#define RNDTEST_CHI4_VMAX 1576929 /* 46.1728 */
  82719. +
  82720. +static int
  82721. +rndtest_chi_4(struct rndtest_state *rsp)
  82722. +{
  82723. + unsigned int freq[RNDTEST_CHI4_K], i, sum;
  82724. +
  82725. + for (i = 0; i < RNDTEST_CHI4_K; i++)
  82726. + freq[i] = 0;
  82727. +
  82728. + /* Get number of occurances of each 4 bit pattern */
  82729. + for (i = 0; i < RNDTEST_NBYTES; i++) {
  82730. + freq[(rsp->rs_buf[i] >> 4) & RNDTEST_CHI4_K_MASK]++;
  82731. + freq[(rsp->rs_buf[i] >> 0) & RNDTEST_CHI4_K_MASK]++;
  82732. + }
  82733. +
  82734. + for (i = 0, sum = 0; i < RNDTEST_CHI4_K; i++)
  82735. + sum += freq[i] * freq[i];
  82736. +
  82737. + if (sum >= 1563181 && sum <= 1576929) {
  82738. + rndtest_report(rsp, 0, "chi^2(4): pass (sum %u)", sum);
  82739. + return (0);
  82740. + } else {
  82741. + rndtest_report(rsp, 1, "chi^2(4): failed (sum %u)", sum);
  82742. + rndstats.rst_chi++;
  82743. + return (-1);
  82744. + }
  82745. +}
  82746. +
  82747. +int
  82748. +rndtest_buf(unsigned char *buf)
  82749. +{
  82750. + struct rndtest_state rsp;
  82751. +
  82752. + memset(&rsp, 0, sizeof(rsp));
  82753. + rsp.rs_buf = buf;
  82754. + rndtest_test(&rsp);
  82755. + return(rsp.rs_discard);
  82756. +}
  82757. +
  82758. diff -Nur linux-2.6.39.orig/crypto/ocf/rndtest.h linux-2.6.39/crypto/ocf/rndtest.h
  82759. --- linux-2.6.39.orig/crypto/ocf/rndtest.h 1970-01-01 01:00:00.000000000 +0100
  82760. +++ linux-2.6.39/crypto/ocf/rndtest.h 2011-08-01 14:38:19.000000000 +0200
  82761. @@ -0,0 +1,54 @@
  82762. +/* $FreeBSD: src/sys/dev/rndtest/rndtest.h,v 1.1 2003/03/11 22:54:44 sam Exp $ */
  82763. +/* $OpenBSD$ */
  82764. +
  82765. +/*
  82766. + * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
  82767. + * All rights reserved.
  82768. + *
  82769. + * Redistribution and use in source and binary forms, with or without
  82770. + * modification, are permitted provided that the following conditions
  82771. + * are met:
  82772. + * 1. Redistributions of source code must retain the above copyright
  82773. + * notice, this list of conditions and the following disclaimer.
  82774. + * 2. Redistributions in binary form must reproduce the above copyright
  82775. + * notice, this list of conditions and the following disclaimer in the
  82776. + * documentation and/or other materials provided with the distribution.
  82777. + * 3. All advertising materials mentioning features or use of this software
  82778. + * must display the following acknowledgement:
  82779. + * This product includes software developed by Jason L. Wright
  82780. + * 4. The name of the author may not be used to endorse or promote products
  82781. + * derived from this software without specific prior written permission.
  82782. + *
  82783. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  82784. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  82785. + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  82786. + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
  82787. + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  82788. + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  82789. + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  82790. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  82791. + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  82792. + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  82793. + * POSSIBILITY OF SUCH DAMAGE.
  82794. + */
  82795. +
  82796. +
  82797. +/* Some of the tests depend on these values */
  82798. +#define RNDTEST_NBYTES 2500
  82799. +#define RNDTEST_NBITS (8 * RNDTEST_NBYTES)
  82800. +
  82801. +struct rndtest_state {
  82802. + int rs_discard; /* discard/accept random data */
  82803. + u_int8_t *rs_buf;
  82804. +};
  82805. +
  82806. +struct rndtest_stats {
  82807. + u_int32_t rst_discard; /* number of bytes discarded */
  82808. + u_int32_t rst_tests; /* number of test runs */
  82809. + u_int32_t rst_monobit; /* monobit test failures */
  82810. + u_int32_t rst_runs; /* 0/1 runs failures */
  82811. + u_int32_t rst_longruns; /* longruns failures */
  82812. + u_int32_t rst_chi; /* chi^2 failures */
  82813. +};
  82814. +
  82815. +extern int rndtest_buf(unsigned char *buf);
  82816. diff -Nur linux-2.6.39.orig/crypto/ocf/safe/Makefile linux-2.6.39/crypto/ocf/safe/Makefile
  82817. --- linux-2.6.39.orig/crypto/ocf/safe/Makefile 1970-01-01 01:00:00.000000000 +0100
  82818. +++ linux-2.6.39/crypto/ocf/safe/Makefile 2011-08-01 14:38:19.000000000 +0200
  82819. @@ -0,0 +1,12 @@
  82820. +# for SGlinux builds
  82821. +-include $(ROOTDIR)/modules/.config
  82822. +
  82823. +obj-$(CONFIG_OCF_SAFE) += safe.o
  82824. +
  82825. +obj ?= .
  82826. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  82827. +
  82828. +ifdef TOPDIR
  82829. +-include $(TOPDIR)/Rules.make
  82830. +endif
  82831. +
  82832. diff -Nur linux-2.6.39.orig/crypto/ocf/safe/md5.c linux-2.6.39/crypto/ocf/safe/md5.c
  82833. --- linux-2.6.39.orig/crypto/ocf/safe/md5.c 1970-01-01 01:00:00.000000000 +0100
  82834. +++ linux-2.6.39/crypto/ocf/safe/md5.c 2011-08-01 14:38:19.000000000 +0200
  82835. @@ -0,0 +1,308 @@
  82836. +/* $KAME: md5.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
  82837. +/*
  82838. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  82839. + * All rights reserved.
  82840. + *
  82841. + * Redistribution and use in source and binary forms, with or without
  82842. + * modification, are permitted provided that the following conditions
  82843. + * are met:
  82844. + * 1. Redistributions of source code must retain the above copyright
  82845. + * notice, this list of conditions and the following disclaimer.
  82846. + * 2. Redistributions in binary form must reproduce the above copyright
  82847. + * notice, this list of conditions and the following disclaimer in the
  82848. + * documentation and/or other materials provided with the distribution.
  82849. + * 3. Neither the name of the project nor the names of its contributors
  82850. + * may be used to endorse or promote products derived from this software
  82851. + * without specific prior written permission.
  82852. + *
  82853. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  82854. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  82855. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  82856. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  82857. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  82858. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  82859. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  82860. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  82861. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  82862. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  82863. + * SUCH DAMAGE.
  82864. + */
  82865. +
  82866. +#if 0
  82867. +#include <sys/cdefs.h>
  82868. +__FBSDID("$FreeBSD: src/sys/crypto/md5.c,v 1.9 2004/01/27 19:49:19 des Exp $");
  82869. +
  82870. +#include <sys/types.h>
  82871. +#include <sys/cdefs.h>
  82872. +#include <sys/time.h>
  82873. +#include <sys/systm.h>
  82874. +#include <crypto/md5.h>
  82875. +#endif
  82876. +
  82877. +#define SHIFT(X, s) (((X) << (s)) | ((X) >> (32 - (s))))
  82878. +
  82879. +#define F(X, Y, Z) (((X) & (Y)) | ((~X) & (Z)))
  82880. +#define G(X, Y, Z) (((X) & (Z)) | ((Y) & (~Z)))
  82881. +#define H(X, Y, Z) ((X) ^ (Y) ^ (Z))
  82882. +#define I(X, Y, Z) ((Y) ^ ((X) | (~Z)))
  82883. +
  82884. +#define ROUND1(a, b, c, d, k, s, i) { \
  82885. + (a) = (a) + F((b), (c), (d)) + X[(k)] + T[(i)]; \
  82886. + (a) = SHIFT((a), (s)); \
  82887. + (a) = (b) + (a); \
  82888. +}
  82889. +
  82890. +#define ROUND2(a, b, c, d, k, s, i) { \
  82891. + (a) = (a) + G((b), (c), (d)) + X[(k)] + T[(i)]; \
  82892. + (a) = SHIFT((a), (s)); \
  82893. + (a) = (b) + (a); \
  82894. +}
  82895. +
  82896. +#define ROUND3(a, b, c, d, k, s, i) { \
  82897. + (a) = (a) + H((b), (c), (d)) + X[(k)] + T[(i)]; \
  82898. + (a) = SHIFT((a), (s)); \
  82899. + (a) = (b) + (a); \
  82900. +}
  82901. +
  82902. +#define ROUND4(a, b, c, d, k, s, i) { \
  82903. + (a) = (a) + I((b), (c), (d)) + X[(k)] + T[(i)]; \
  82904. + (a) = SHIFT((a), (s)); \
  82905. + (a) = (b) + (a); \
  82906. +}
  82907. +
  82908. +#define Sa 7
  82909. +#define Sb 12
  82910. +#define Sc 17
  82911. +#define Sd 22
  82912. +
  82913. +#define Se 5
  82914. +#define Sf 9
  82915. +#define Sg 14
  82916. +#define Sh 20
  82917. +
  82918. +#define Si 4
  82919. +#define Sj 11
  82920. +#define Sk 16
  82921. +#define Sl 23
  82922. +
  82923. +#define Sm 6
  82924. +#define Sn 10
  82925. +#define So 15
  82926. +#define Sp 21
  82927. +
  82928. +#define MD5_A0 0x67452301
  82929. +#define MD5_B0 0xefcdab89
  82930. +#define MD5_C0 0x98badcfe
  82931. +#define MD5_D0 0x10325476
  82932. +
  82933. +/* Integer part of 4294967296 times abs(sin(i)), where i is in radians. */
  82934. +static const u_int32_t T[65] = {
  82935. + 0,
  82936. + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
  82937. + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
  82938. + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
  82939. + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
  82940. +
  82941. + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
  82942. + 0xd62f105d, 0x2441453, 0xd8a1e681, 0xe7d3fbc8,
  82943. + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
  82944. + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
  82945. +
  82946. + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
  82947. + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
  82948. + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x4881d05,
  82949. + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
  82950. +
  82951. + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
  82952. + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
  82953. + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
  82954. + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
  82955. +};
  82956. +
  82957. +static const u_int8_t md5_paddat[MD5_BUFLEN] = {
  82958. + 0x80, 0, 0, 0, 0, 0, 0, 0,
  82959. + 0, 0, 0, 0, 0, 0, 0, 0,
  82960. + 0, 0, 0, 0, 0, 0, 0, 0,
  82961. + 0, 0, 0, 0, 0, 0, 0, 0,
  82962. + 0, 0, 0, 0, 0, 0, 0, 0,
  82963. + 0, 0, 0, 0, 0, 0, 0, 0,
  82964. + 0, 0, 0, 0, 0, 0, 0, 0,
  82965. + 0, 0, 0, 0, 0, 0, 0, 0,
  82966. +};
  82967. +
  82968. +static void md5_calc(u_int8_t *, md5_ctxt *);
  82969. +
  82970. +void md5_init(ctxt)
  82971. + md5_ctxt *ctxt;
  82972. +{
  82973. + ctxt->md5_n = 0;
  82974. + ctxt->md5_i = 0;
  82975. + ctxt->md5_sta = MD5_A0;
  82976. + ctxt->md5_stb = MD5_B0;
  82977. + ctxt->md5_stc = MD5_C0;
  82978. + ctxt->md5_std = MD5_D0;
  82979. + bzero(ctxt->md5_buf, sizeof(ctxt->md5_buf));
  82980. +}
  82981. +
  82982. +void md5_loop(ctxt, input, len)
  82983. + md5_ctxt *ctxt;
  82984. + u_int8_t *input;
  82985. + u_int len; /* number of bytes */
  82986. +{
  82987. + u_int gap, i;
  82988. +
  82989. + ctxt->md5_n += len * 8; /* byte to bit */
  82990. + gap = MD5_BUFLEN - ctxt->md5_i;
  82991. +
  82992. + if (len >= gap) {
  82993. + bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
  82994. + gap);
  82995. + md5_calc(ctxt->md5_buf, ctxt);
  82996. +
  82997. + for (i = gap; i + MD5_BUFLEN <= len; i += MD5_BUFLEN) {
  82998. + md5_calc((u_int8_t *)(input + i), ctxt);
  82999. + }
  83000. +
  83001. + ctxt->md5_i = len - i;
  83002. + bcopy((void *)(input + i), (void *)ctxt->md5_buf, ctxt->md5_i);
  83003. + } else {
  83004. + bcopy((void *)input, (void *)(ctxt->md5_buf + ctxt->md5_i),
  83005. + len);
  83006. + ctxt->md5_i += len;
  83007. + }
  83008. +}
  83009. +
  83010. +void md5_pad(ctxt)
  83011. + md5_ctxt *ctxt;
  83012. +{
  83013. + u_int gap;
  83014. +
  83015. + /* Don't count up padding. Keep md5_n. */
  83016. + gap = MD5_BUFLEN - ctxt->md5_i;
  83017. + if (gap > 8) {
  83018. + bcopy(md5_paddat,
  83019. + (void *)(ctxt->md5_buf + ctxt->md5_i),
  83020. + gap - sizeof(ctxt->md5_n));
  83021. + } else {
  83022. + /* including gap == 8 */
  83023. + bcopy(md5_paddat, (void *)(ctxt->md5_buf + ctxt->md5_i),
  83024. + gap);
  83025. + md5_calc(ctxt->md5_buf, ctxt);
  83026. + bcopy((md5_paddat + gap),
  83027. + (void *)ctxt->md5_buf,
  83028. + MD5_BUFLEN - sizeof(ctxt->md5_n));
  83029. + }
  83030. +
  83031. + /* 8 byte word */
  83032. +#if BYTE_ORDER == LITTLE_ENDIAN
  83033. + bcopy(&ctxt->md5_n8[0], &ctxt->md5_buf[56], 8);
  83034. +#endif
  83035. +#if BYTE_ORDER == BIG_ENDIAN
  83036. + ctxt->md5_buf[56] = ctxt->md5_n8[7];
  83037. + ctxt->md5_buf[57] = ctxt->md5_n8[6];
  83038. + ctxt->md5_buf[58] = ctxt->md5_n8[5];
  83039. + ctxt->md5_buf[59] = ctxt->md5_n8[4];
  83040. + ctxt->md5_buf[60] = ctxt->md5_n8[3];
  83041. + ctxt->md5_buf[61] = ctxt->md5_n8[2];
  83042. + ctxt->md5_buf[62] = ctxt->md5_n8[1];
  83043. + ctxt->md5_buf[63] = ctxt->md5_n8[0];
  83044. +#endif
  83045. +
  83046. + md5_calc(ctxt->md5_buf, ctxt);
  83047. +}
  83048. +
  83049. +void md5_result(digest, ctxt)
  83050. + u_int8_t *digest;
  83051. + md5_ctxt *ctxt;
  83052. +{
  83053. + /* 4 byte words */
  83054. +#if BYTE_ORDER == LITTLE_ENDIAN
  83055. + bcopy(&ctxt->md5_st8[0], digest, 16);
  83056. +#endif
  83057. +#if BYTE_ORDER == BIG_ENDIAN
  83058. + digest[ 0] = ctxt->md5_st8[ 3]; digest[ 1] = ctxt->md5_st8[ 2];
  83059. + digest[ 2] = ctxt->md5_st8[ 1]; digest[ 3] = ctxt->md5_st8[ 0];
  83060. + digest[ 4] = ctxt->md5_st8[ 7]; digest[ 5] = ctxt->md5_st8[ 6];
  83061. + digest[ 6] = ctxt->md5_st8[ 5]; digest[ 7] = ctxt->md5_st8[ 4];
  83062. + digest[ 8] = ctxt->md5_st8[11]; digest[ 9] = ctxt->md5_st8[10];
  83063. + digest[10] = ctxt->md5_st8[ 9]; digest[11] = ctxt->md5_st8[ 8];
  83064. + digest[12] = ctxt->md5_st8[15]; digest[13] = ctxt->md5_st8[14];
  83065. + digest[14] = ctxt->md5_st8[13]; digest[15] = ctxt->md5_st8[12];
  83066. +#endif
  83067. +}
  83068. +
  83069. +static void md5_calc(b64, ctxt)
  83070. + u_int8_t *b64;
  83071. + md5_ctxt *ctxt;
  83072. +{
  83073. + u_int32_t A = ctxt->md5_sta;
  83074. + u_int32_t B = ctxt->md5_stb;
  83075. + u_int32_t C = ctxt->md5_stc;
  83076. + u_int32_t D = ctxt->md5_std;
  83077. +#if BYTE_ORDER == LITTLE_ENDIAN
  83078. + u_int32_t *X = (u_int32_t *)b64;
  83079. +#endif
  83080. +#if BYTE_ORDER == BIG_ENDIAN
  83081. + /* 4 byte words */
  83082. + /* what a brute force but fast! */
  83083. + u_int32_t X[16];
  83084. + u_int8_t *y = (u_int8_t *)X;
  83085. + y[ 0] = b64[ 3]; y[ 1] = b64[ 2]; y[ 2] = b64[ 1]; y[ 3] = b64[ 0];
  83086. + y[ 4] = b64[ 7]; y[ 5] = b64[ 6]; y[ 6] = b64[ 5]; y[ 7] = b64[ 4];
  83087. + y[ 8] = b64[11]; y[ 9] = b64[10]; y[10] = b64[ 9]; y[11] = b64[ 8];
  83088. + y[12] = b64[15]; y[13] = b64[14]; y[14] = b64[13]; y[15] = b64[12];
  83089. + y[16] = b64[19]; y[17] = b64[18]; y[18] = b64[17]; y[19] = b64[16];
  83090. + y[20] = b64[23]; y[21] = b64[22]; y[22] = b64[21]; y[23] = b64[20];
  83091. + y[24] = b64[27]; y[25] = b64[26]; y[26] = b64[25]; y[27] = b64[24];
  83092. + y[28] = b64[31]; y[29] = b64[30]; y[30] = b64[29]; y[31] = b64[28];
  83093. + y[32] = b64[35]; y[33] = b64[34]; y[34] = b64[33]; y[35] = b64[32];
  83094. + y[36] = b64[39]; y[37] = b64[38]; y[38] = b64[37]; y[39] = b64[36];
  83095. + y[40] = b64[43]; y[41] = b64[42]; y[42] = b64[41]; y[43] = b64[40];
  83096. + y[44] = b64[47]; y[45] = b64[46]; y[46] = b64[45]; y[47] = b64[44];
  83097. + y[48] = b64[51]; y[49] = b64[50]; y[50] = b64[49]; y[51] = b64[48];
  83098. + y[52] = b64[55]; y[53] = b64[54]; y[54] = b64[53]; y[55] = b64[52];
  83099. + y[56] = b64[59]; y[57] = b64[58]; y[58] = b64[57]; y[59] = b64[56];
  83100. + y[60] = b64[63]; y[61] = b64[62]; y[62] = b64[61]; y[63] = b64[60];
  83101. +#endif
  83102. +
  83103. + ROUND1(A, B, C, D, 0, Sa, 1); ROUND1(D, A, B, C, 1, Sb, 2);
  83104. + ROUND1(C, D, A, B, 2, Sc, 3); ROUND1(B, C, D, A, 3, Sd, 4);
  83105. + ROUND1(A, B, C, D, 4, Sa, 5); ROUND1(D, A, B, C, 5, Sb, 6);
  83106. + ROUND1(C, D, A, B, 6, Sc, 7); ROUND1(B, C, D, A, 7, Sd, 8);
  83107. + ROUND1(A, B, C, D, 8, Sa, 9); ROUND1(D, A, B, C, 9, Sb, 10);
  83108. + ROUND1(C, D, A, B, 10, Sc, 11); ROUND1(B, C, D, A, 11, Sd, 12);
  83109. + ROUND1(A, B, C, D, 12, Sa, 13); ROUND1(D, A, B, C, 13, Sb, 14);
  83110. + ROUND1(C, D, A, B, 14, Sc, 15); ROUND1(B, C, D, A, 15, Sd, 16);
  83111. +
  83112. + ROUND2(A, B, C, D, 1, Se, 17); ROUND2(D, A, B, C, 6, Sf, 18);
  83113. + ROUND2(C, D, A, B, 11, Sg, 19); ROUND2(B, C, D, A, 0, Sh, 20);
  83114. + ROUND2(A, B, C, D, 5, Se, 21); ROUND2(D, A, B, C, 10, Sf, 22);
  83115. + ROUND2(C, D, A, B, 15, Sg, 23); ROUND2(B, C, D, A, 4, Sh, 24);
  83116. + ROUND2(A, B, C, D, 9, Se, 25); ROUND2(D, A, B, C, 14, Sf, 26);
  83117. + ROUND2(C, D, A, B, 3, Sg, 27); ROUND2(B, C, D, A, 8, Sh, 28);
  83118. + ROUND2(A, B, C, D, 13, Se, 29); ROUND2(D, A, B, C, 2, Sf, 30);
  83119. + ROUND2(C, D, A, B, 7, Sg, 31); ROUND2(B, C, D, A, 12, Sh, 32);
  83120. +
  83121. + ROUND3(A, B, C, D, 5, Si, 33); ROUND3(D, A, B, C, 8, Sj, 34);
  83122. + ROUND3(C, D, A, B, 11, Sk, 35); ROUND3(B, C, D, A, 14, Sl, 36);
  83123. + ROUND3(A, B, C, D, 1, Si, 37); ROUND3(D, A, B, C, 4, Sj, 38);
  83124. + ROUND3(C, D, A, B, 7, Sk, 39); ROUND3(B, C, D, A, 10, Sl, 40);
  83125. + ROUND3(A, B, C, D, 13, Si, 41); ROUND3(D, A, B, C, 0, Sj, 42);
  83126. + ROUND3(C, D, A, B, 3, Sk, 43); ROUND3(B, C, D, A, 6, Sl, 44);
  83127. + ROUND3(A, B, C, D, 9, Si, 45); ROUND3(D, A, B, C, 12, Sj, 46);
  83128. + ROUND3(C, D, A, B, 15, Sk, 47); ROUND3(B, C, D, A, 2, Sl, 48);
  83129. +
  83130. + ROUND4(A, B, C, D, 0, Sm, 49); ROUND4(D, A, B, C, 7, Sn, 50);
  83131. + ROUND4(C, D, A, B, 14, So, 51); ROUND4(B, C, D, A, 5, Sp, 52);
  83132. + ROUND4(A, B, C, D, 12, Sm, 53); ROUND4(D, A, B, C, 3, Sn, 54);
  83133. + ROUND4(C, D, A, B, 10, So, 55); ROUND4(B, C, D, A, 1, Sp, 56);
  83134. + ROUND4(A, B, C, D, 8, Sm, 57); ROUND4(D, A, B, C, 15, Sn, 58);
  83135. + ROUND4(C, D, A, B, 6, So, 59); ROUND4(B, C, D, A, 13, Sp, 60);
  83136. + ROUND4(A, B, C, D, 4, Sm, 61); ROUND4(D, A, B, C, 11, Sn, 62);
  83137. + ROUND4(C, D, A, B, 2, So, 63); ROUND4(B, C, D, A, 9, Sp, 64);
  83138. +
  83139. + ctxt->md5_sta += A;
  83140. + ctxt->md5_stb += B;
  83141. + ctxt->md5_stc += C;
  83142. + ctxt->md5_std += D;
  83143. +}
  83144. diff -Nur linux-2.6.39.orig/crypto/ocf/safe/md5.h linux-2.6.39/crypto/ocf/safe/md5.h
  83145. --- linux-2.6.39.orig/crypto/ocf/safe/md5.h 1970-01-01 01:00:00.000000000 +0100
  83146. +++ linux-2.6.39/crypto/ocf/safe/md5.h 2011-08-01 14:38:19.000000000 +0200
  83147. @@ -0,0 +1,76 @@
  83148. +/* $FreeBSD: src/sys/crypto/md5.h,v 1.4 2002/03/20 05:13:50 alfred Exp $ */
  83149. +/* $KAME: md5.h,v 1.4 2000/03/27 04:36:22 sumikawa Exp $ */
  83150. +
  83151. +/*
  83152. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  83153. + * All rights reserved.
  83154. + *
  83155. + * Redistribution and use in source and binary forms, with or without
  83156. + * modification, are permitted provided that the following conditions
  83157. + * are met:
  83158. + * 1. Redistributions of source code must retain the above copyright
  83159. + * notice, this list of conditions and the following disclaimer.
  83160. + * 2. Redistributions in binary form must reproduce the above copyright
  83161. + * notice, this list of conditions and the following disclaimer in the
  83162. + * documentation and/or other materials provided with the distribution.
  83163. + * 3. Neither the name of the project nor the names of its contributors
  83164. + * may be used to endorse or promote products derived from this software
  83165. + * without specific prior written permission.
  83166. + *
  83167. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  83168. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  83169. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  83170. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  83171. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  83172. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  83173. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  83174. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  83175. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  83176. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  83177. + * SUCH DAMAGE.
  83178. + */
  83179. +
  83180. +#ifndef _NETINET6_MD5_H_
  83181. +#define _NETINET6_MD5_H_
  83182. +
  83183. +#define MD5_BUFLEN 64
  83184. +
  83185. +typedef struct {
  83186. + union {
  83187. + u_int32_t md5_state32[4];
  83188. + u_int8_t md5_state8[16];
  83189. + } md5_st;
  83190. +
  83191. +#define md5_sta md5_st.md5_state32[0]
  83192. +#define md5_stb md5_st.md5_state32[1]
  83193. +#define md5_stc md5_st.md5_state32[2]
  83194. +#define md5_std md5_st.md5_state32[3]
  83195. +#define md5_st8 md5_st.md5_state8
  83196. +
  83197. + union {
  83198. + u_int64_t md5_count64;
  83199. + u_int8_t md5_count8[8];
  83200. + } md5_count;
  83201. +#define md5_n md5_count.md5_count64
  83202. +#define md5_n8 md5_count.md5_count8
  83203. +
  83204. + u_int md5_i;
  83205. + u_int8_t md5_buf[MD5_BUFLEN];
  83206. +} md5_ctxt;
  83207. +
  83208. +extern void md5_init(md5_ctxt *);
  83209. +extern void md5_loop(md5_ctxt *, u_int8_t *, u_int);
  83210. +extern void md5_pad(md5_ctxt *);
  83211. +extern void md5_result(u_int8_t *, md5_ctxt *);
  83212. +
  83213. +/* compatibility */
  83214. +#define MD5_CTX md5_ctxt
  83215. +#define MD5Init(x) md5_init((x))
  83216. +#define MD5Update(x, y, z) md5_loop((x), (y), (z))
  83217. +#define MD5Final(x, y) \
  83218. +do { \
  83219. + md5_pad((y)); \
  83220. + md5_result((x), (y)); \
  83221. +} while (0)
  83222. +
  83223. +#endif /* ! _NETINET6_MD5_H_*/
  83224. diff -Nur linux-2.6.39.orig/crypto/ocf/safe/safe.c linux-2.6.39/crypto/ocf/safe/safe.c
  83225. --- linux-2.6.39.orig/crypto/ocf/safe/safe.c 1970-01-01 01:00:00.000000000 +0100
  83226. +++ linux-2.6.39/crypto/ocf/safe/safe.c 2011-08-01 14:38:19.000000000 +0200
  83227. @@ -0,0 +1,2288 @@
  83228. +/*-
  83229. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  83230. + * Copyright (C) 2004-2010 David McCullough
  83231. + * The license and original author are listed below.
  83232. + *
  83233. + * Copyright (c) 2003 Sam Leffler, Errno Consulting
  83234. + * Copyright (c) 2003 Global Technology Associates, Inc.
  83235. + * All rights reserved.
  83236. + *
  83237. + * Redistribution and use in source and binary forms, with or without
  83238. + * modification, are permitted provided that the following conditions
  83239. + * are met:
  83240. + * 1. Redistributions of source code must retain the above copyright
  83241. + * notice, this list of conditions and the following disclaimer.
  83242. + * 2. Redistributions in binary form must reproduce the above copyright
  83243. + * notice, this list of conditions and the following disclaimer in the
  83244. + * documentation and/or other materials provided with the distribution.
  83245. + *
  83246. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  83247. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  83248. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  83249. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  83250. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  83251. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  83252. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  83253. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  83254. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  83255. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  83256. + * SUCH DAMAGE.
  83257. + *
  83258. +__FBSDID("$FreeBSD: src/sys/dev/safe/safe.c,v 1.18 2007/03/21 03:42:50 sam Exp $");
  83259. + */
  83260. +
  83261. +#ifndef AUTOCONF_INCLUDED
  83262. +#include <linux/config.h>
  83263. +#endif
  83264. +#include <linux/module.h>
  83265. +#include <linux/kernel.h>
  83266. +#include <linux/init.h>
  83267. +#include <linux/list.h>
  83268. +#include <linux/slab.h>
  83269. +#include <linux/wait.h>
  83270. +#include <linux/sched.h>
  83271. +#include <linux/pci.h>
  83272. +#include <linux/delay.h>
  83273. +#include <linux/interrupt.h>
  83274. +#include <linux/spinlock.h>
  83275. +#include <linux/random.h>
  83276. +#include <linux/version.h>
  83277. +#include <linux/skbuff.h>
  83278. +#include <asm/io.h>
  83279. +
  83280. +/*
  83281. + * SafeNet SafeXcel-1141 hardware crypto accelerator
  83282. + */
  83283. +
  83284. +#include <cryptodev.h>
  83285. +#include <uio.h>
  83286. +#include <safe/safereg.h>
  83287. +#include <safe/safevar.h>
  83288. +
  83289. +#if 1
  83290. +#define DPRINTF(a) do { \
  83291. + if (debug) { \
  83292. + printk("%s: ", sc ? \
  83293. + device_get_nameunit(sc->sc_dev) : "safe"); \
  83294. + printk a; \
  83295. + } \
  83296. + } while (0)
  83297. +#else
  83298. +#define DPRINTF(a)
  83299. +#endif
  83300. +
  83301. +/*
  83302. + * until we find a cleaner way, include the BSD md5/sha1 code
  83303. + * here
  83304. + */
  83305. +#define HMAC_HACK 1
  83306. +#ifdef HMAC_HACK
  83307. +#define LITTLE_ENDIAN 1234
  83308. +#define BIG_ENDIAN 4321
  83309. +#ifdef __LITTLE_ENDIAN
  83310. +#define BYTE_ORDER LITTLE_ENDIAN
  83311. +#endif
  83312. +#ifdef __BIG_ENDIAN
  83313. +#define BYTE_ORDER BIG_ENDIAN
  83314. +#endif
  83315. +#include <safe/md5.h>
  83316. +#include <safe/md5.c>
  83317. +#include <safe/sha1.h>
  83318. +#include <safe/sha1.c>
  83319. +
  83320. +u_int8_t hmac_ipad_buffer[64] = {
  83321. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  83322. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  83323. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  83324. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  83325. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  83326. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  83327. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
  83328. + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36
  83329. +};
  83330. +
  83331. +u_int8_t hmac_opad_buffer[64] = {
  83332. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  83333. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  83334. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  83335. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  83336. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  83337. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  83338. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C,
  83339. + 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C, 0x5C
  83340. +};
  83341. +#endif /* HMAC_HACK */
  83342. +
  83343. +/* add proc entry for this */
  83344. +struct safe_stats safestats;
  83345. +
  83346. +#define debug safe_debug
  83347. +int safe_debug = 0;
  83348. +module_param(safe_debug, int, 0644);
  83349. +MODULE_PARM_DESC(safe_debug, "Enable debug");
  83350. +
  83351. +static void safe_callback(struct safe_softc *, struct safe_ringentry *);
  83352. +static void safe_feed(struct safe_softc *, struct safe_ringentry *);
  83353. +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
  83354. +static void safe_rng_init(struct safe_softc *);
  83355. +int safe_rngbufsize = 8; /* 32 bytes each read */
  83356. +module_param(safe_rngbufsize, int, 0644);
  83357. +MODULE_PARM_DESC(safe_rngbufsize, "RNG polling buffer size (32-bit words)");
  83358. +int safe_rngmaxalarm = 8; /* max alarms before reset */
  83359. +module_param(safe_rngmaxalarm, int, 0644);
  83360. +MODULE_PARM_DESC(safe_rngmaxalarm, "RNG max alarms before reset");
  83361. +#endif /* SAFE_NO_RNG */
  83362. +
  83363. +static void safe_totalreset(struct safe_softc *sc);
  83364. +static int safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op);
  83365. +static int safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op);
  83366. +static int safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re);
  83367. +static int safe_kprocess(device_t dev, struct cryptkop *krp, int hint);
  83368. +static int safe_kstart(struct safe_softc *sc);
  83369. +static int safe_ksigbits(struct safe_softc *sc, struct crparam *cr);
  83370. +static void safe_kfeed(struct safe_softc *sc);
  83371. +static void safe_kpoll(unsigned long arg);
  83372. +static void safe_kload_reg(struct safe_softc *sc, u_int32_t off,
  83373. + u_int32_t len, struct crparam *n);
  83374. +
  83375. +static int safe_newsession(device_t, u_int32_t *, struct cryptoini *);
  83376. +static int safe_freesession(device_t, u_int64_t);
  83377. +static int safe_process(device_t, struct cryptop *, int);
  83378. +
  83379. +static device_method_t safe_methods = {
  83380. + /* crypto device methods */
  83381. + DEVMETHOD(cryptodev_newsession, safe_newsession),
  83382. + DEVMETHOD(cryptodev_freesession,safe_freesession),
  83383. + DEVMETHOD(cryptodev_process, safe_process),
  83384. + DEVMETHOD(cryptodev_kprocess, safe_kprocess),
  83385. +};
  83386. +
  83387. +#define READ_REG(sc,r) readl((sc)->sc_base_addr + (r))
  83388. +#define WRITE_REG(sc,r,val) writel((val), (sc)->sc_base_addr + (r))
  83389. +
  83390. +#define SAFE_MAX_CHIPS 8
  83391. +static struct safe_softc *safe_chip_idx[SAFE_MAX_CHIPS];
  83392. +
  83393. +/*
  83394. + * split our buffers up into safe DMAable byte fragments to avoid lockup
  83395. + * bug in 1141 HW on rev 1.0.
  83396. + */
  83397. +
  83398. +static int
  83399. +pci_map_linear(
  83400. + struct safe_softc *sc,
  83401. + struct safe_operand *buf,
  83402. + void *addr,
  83403. + int len)
  83404. +{
  83405. + dma_addr_t tmp;
  83406. + int chunk, tlen = len;
  83407. +
  83408. + tmp = pci_map_single(sc->sc_pcidev, addr, len, PCI_DMA_BIDIRECTIONAL);
  83409. +
  83410. + buf->mapsize += len;
  83411. + while (len > 0) {
  83412. + chunk = (len > sc->sc_max_dsize) ? sc->sc_max_dsize : len;
  83413. + buf->segs[buf->nsegs].ds_addr = tmp;
  83414. + buf->segs[buf->nsegs].ds_len = chunk;
  83415. + buf->segs[buf->nsegs].ds_tlen = tlen;
  83416. + buf->nsegs++;
  83417. + tmp += chunk;
  83418. + len -= chunk;
  83419. + tlen = 0;
  83420. + }
  83421. + return 0;
  83422. +}
  83423. +
  83424. +/*
  83425. + * map in a given uio buffer (great on some arches :-)
  83426. + */
  83427. +
  83428. +static int
  83429. +pci_map_uio(struct safe_softc *sc, struct safe_operand *buf, struct uio *uio)
  83430. +{
  83431. + struct iovec *iov = uio->uio_iov;
  83432. + int n;
  83433. +
  83434. + DPRINTF(("%s()\n", __FUNCTION__));
  83435. +
  83436. + buf->mapsize = 0;
  83437. + buf->nsegs = 0;
  83438. +
  83439. + for (n = 0; n < uio->uio_iovcnt; n++) {
  83440. + pci_map_linear(sc, buf, iov->iov_base, iov->iov_len);
  83441. + iov++;
  83442. + }
  83443. +
  83444. + /* identify this buffer by the first segment */
  83445. + buf->map = (void *) buf->segs[0].ds_addr;
  83446. + return(0);
  83447. +}
  83448. +
  83449. +/*
  83450. + * map in a given sk_buff
  83451. + */
  83452. +
  83453. +static int
  83454. +pci_map_skb(struct safe_softc *sc,struct safe_operand *buf,struct sk_buff *skb)
  83455. +{
  83456. + int i;
  83457. +
  83458. + DPRINTF(("%s()\n", __FUNCTION__));
  83459. +
  83460. + buf->mapsize = 0;
  83461. + buf->nsegs = 0;
  83462. +
  83463. + pci_map_linear(sc, buf, skb->data, skb_headlen(skb));
  83464. +
  83465. + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
  83466. + pci_map_linear(sc, buf,
  83467. + page_address(skb_shinfo(skb)->frags[i].page) +
  83468. + skb_shinfo(skb)->frags[i].page_offset,
  83469. + skb_shinfo(skb)->frags[i].size);
  83470. + }
  83471. +
  83472. + /* identify this buffer by the first segment */
  83473. + buf->map = (void *) buf->segs[0].ds_addr;
  83474. + return(0);
  83475. +}
  83476. +
  83477. +
  83478. +#if 0 /* not needed at this time */
  83479. +static void
  83480. +pci_sync_operand(struct safe_softc *sc, struct safe_operand *buf)
  83481. +{
  83482. + int i;
  83483. +
  83484. + DPRINTF(("%s()\n", __FUNCTION__));
  83485. + for (i = 0; i < buf->nsegs; i++)
  83486. + pci_dma_sync_single_for_cpu(sc->sc_pcidev, buf->segs[i].ds_addr,
  83487. + buf->segs[i].ds_len, PCI_DMA_BIDIRECTIONAL);
  83488. +}
  83489. +#endif
  83490. +
  83491. +static void
  83492. +pci_unmap_operand(struct safe_softc *sc, struct safe_operand *buf)
  83493. +{
  83494. + int i;
  83495. + DPRINTF(("%s()\n", __FUNCTION__));
  83496. + for (i = 0; i < buf->nsegs; i++) {
  83497. + if (buf->segs[i].ds_tlen) {
  83498. + DPRINTF(("%s - unmap %d 0x%x %d\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));
  83499. + pci_unmap_single(sc->sc_pcidev, buf->segs[i].ds_addr,
  83500. + buf->segs[i].ds_tlen, PCI_DMA_BIDIRECTIONAL);
  83501. + DPRINTF(("%s - unmap %d 0x%x %d done\n", __FUNCTION__, i, buf->segs[i].ds_addr, buf->segs[i].ds_tlen));
  83502. + }
  83503. + buf->segs[i].ds_addr = 0;
  83504. + buf->segs[i].ds_len = 0;
  83505. + buf->segs[i].ds_tlen = 0;
  83506. + }
  83507. + buf->nsegs = 0;
  83508. + buf->mapsize = 0;
  83509. + buf->map = 0;
  83510. +}
  83511. +
  83512. +
  83513. +/*
  83514. + * SafeXcel Interrupt routine
  83515. + */
  83516. +static irqreturn_t
  83517. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  83518. +safe_intr(int irq, void *arg)
  83519. +#else
  83520. +safe_intr(int irq, void *arg, struct pt_regs *regs)
  83521. +#endif
  83522. +{
  83523. + struct safe_softc *sc = arg;
  83524. + int stat;
  83525. + unsigned long flags;
  83526. +
  83527. + stat = READ_REG(sc, SAFE_HM_STAT);
  83528. +
  83529. + DPRINTF(("%s(stat=0x%x)\n", __FUNCTION__, stat));
  83530. +
  83531. + if (stat == 0) /* shared irq, not for us */
  83532. + return IRQ_NONE;
  83533. +
  83534. + WRITE_REG(sc, SAFE_HI_CLR, stat); /* IACK */
  83535. +
  83536. + if ((stat & SAFE_INT_PE_DDONE)) {
  83537. + /*
  83538. + * Descriptor(s) done; scan the ring and
  83539. + * process completed operations.
  83540. + */
  83541. + spin_lock_irqsave(&sc->sc_ringmtx, flags);
  83542. + while (sc->sc_back != sc->sc_front) {
  83543. + struct safe_ringentry *re = sc->sc_back;
  83544. +
  83545. +#ifdef SAFE_DEBUG
  83546. + if (debug) {
  83547. + safe_dump_ringstate(sc, __func__);
  83548. + safe_dump_request(sc, __func__, re);
  83549. + }
  83550. +#endif
  83551. + /*
  83552. + * safe_process marks ring entries that were allocated
  83553. + * but not used with a csr of zero. This insures the
  83554. + * ring front pointer never needs to be set backwards
  83555. + * in the event that an entry is allocated but not used
  83556. + * because of a setup error.
  83557. + */
  83558. + DPRINTF(("%s re->re_desc.d_csr=0x%x\n", __FUNCTION__, re->re_desc.d_csr));
  83559. + if (re->re_desc.d_csr != 0) {
  83560. + if (!SAFE_PE_CSR_IS_DONE(re->re_desc.d_csr)) {
  83561. + DPRINTF(("%s !CSR_IS_DONE\n", __FUNCTION__));
  83562. + break;
  83563. + }
  83564. + if (!SAFE_PE_LEN_IS_DONE(re->re_desc.d_len)) {
  83565. + DPRINTF(("%s !LEN_IS_DONE\n", __FUNCTION__));
  83566. + break;
  83567. + }
  83568. + sc->sc_nqchip--;
  83569. + safe_callback(sc, re);
  83570. + }
  83571. + if (++(sc->sc_back) == sc->sc_ringtop)
  83572. + sc->sc_back = sc->sc_ring;
  83573. + }
  83574. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  83575. + }
  83576. +
  83577. + /*
  83578. + * Check to see if we got any DMA Error
  83579. + */
  83580. + if (stat & SAFE_INT_PE_ERROR) {
  83581. + printk("%s: dmaerr dmastat %08x\n", device_get_nameunit(sc->sc_dev),
  83582. + (int)READ_REG(sc, SAFE_PE_DMASTAT));
  83583. + safestats.st_dmaerr++;
  83584. + safe_totalreset(sc);
  83585. +#if 0
  83586. + safe_feed(sc);
  83587. +#endif
  83588. + }
  83589. +
  83590. + if (sc->sc_needwakeup) { /* XXX check high watermark */
  83591. + int wakeup = sc->sc_needwakeup & (CRYPTO_SYMQ|CRYPTO_ASYMQ);
  83592. + DPRINTF(("%s: wakeup crypto %x\n", __func__,
  83593. + sc->sc_needwakeup));
  83594. + sc->sc_needwakeup &= ~wakeup;
  83595. + crypto_unblock(sc->sc_cid, wakeup);
  83596. + }
  83597. +
  83598. + return IRQ_HANDLED;
  83599. +}
  83600. +
  83601. +/*
  83602. + * safe_feed() - post a request to chip
  83603. + */
  83604. +static void
  83605. +safe_feed(struct safe_softc *sc, struct safe_ringentry *re)
  83606. +{
  83607. + DPRINTF(("%s()\n", __FUNCTION__));
  83608. +#ifdef SAFE_DEBUG
  83609. + if (debug) {
  83610. + safe_dump_ringstate(sc, __func__);
  83611. + safe_dump_request(sc, __func__, re);
  83612. + }
  83613. +#endif
  83614. + sc->sc_nqchip++;
  83615. + if (sc->sc_nqchip > safestats.st_maxqchip)
  83616. + safestats.st_maxqchip = sc->sc_nqchip;
  83617. + /* poke h/w to check descriptor ring, any value can be written */
  83618. + WRITE_REG(sc, SAFE_HI_RD_DESCR, 0);
  83619. +}
  83620. +
  83621. +#define N(a) (sizeof(a) / sizeof (a[0]))
  83622. +static void
  83623. +safe_setup_enckey(struct safe_session *ses, caddr_t key)
  83624. +{
  83625. + int i;
  83626. +
  83627. + bcopy(key, ses->ses_key, ses->ses_klen / 8);
  83628. +
  83629. + /* PE is little-endian, insure proper byte order */
  83630. + for (i = 0; i < N(ses->ses_key); i++)
  83631. + ses->ses_key[i] = htole32(ses->ses_key[i]);
  83632. +}
  83633. +
  83634. +static void
  83635. +safe_setup_mackey(struct safe_session *ses, int algo, caddr_t key, int klen)
  83636. +{
  83637. +#ifdef HMAC_HACK
  83638. + MD5_CTX md5ctx;
  83639. + SHA1_CTX sha1ctx;
  83640. + int i;
  83641. +
  83642. +
  83643. + for (i = 0; i < klen; i++)
  83644. + key[i] ^= HMAC_IPAD_VAL;
  83645. +
  83646. + if (algo == CRYPTO_MD5_HMAC) {
  83647. + MD5Init(&md5ctx);
  83648. + MD5Update(&md5ctx, key, klen);
  83649. + MD5Update(&md5ctx, hmac_ipad_buffer, MD5_HMAC_BLOCK_LEN - klen);
  83650. + bcopy(md5ctx.md5_st8, ses->ses_hminner, sizeof(md5ctx.md5_st8));
  83651. + } else {
  83652. + SHA1Init(&sha1ctx);
  83653. + SHA1Update(&sha1ctx, key, klen);
  83654. + SHA1Update(&sha1ctx, hmac_ipad_buffer,
  83655. + SHA1_HMAC_BLOCK_LEN - klen);
  83656. + bcopy(sha1ctx.h.b32, ses->ses_hminner, sizeof(sha1ctx.h.b32));
  83657. + }
  83658. +
  83659. + for (i = 0; i < klen; i++)
  83660. + key[i] ^= (HMAC_IPAD_VAL ^ HMAC_OPAD_VAL);
  83661. +
  83662. + if (algo == CRYPTO_MD5_HMAC) {
  83663. + MD5Init(&md5ctx);
  83664. + MD5Update(&md5ctx, key, klen);
  83665. + MD5Update(&md5ctx, hmac_opad_buffer, MD5_HMAC_BLOCK_LEN - klen);
  83666. + bcopy(md5ctx.md5_st8, ses->ses_hmouter, sizeof(md5ctx.md5_st8));
  83667. + } else {
  83668. + SHA1Init(&sha1ctx);
  83669. + SHA1Update(&sha1ctx, key, klen);
  83670. + SHA1Update(&sha1ctx, hmac_opad_buffer,
  83671. + SHA1_HMAC_BLOCK_LEN - klen);
  83672. + bcopy(sha1ctx.h.b32, ses->ses_hmouter, sizeof(sha1ctx.h.b32));
  83673. + }
  83674. +
  83675. + for (i = 0; i < klen; i++)
  83676. + key[i] ^= HMAC_OPAD_VAL;
  83677. +
  83678. +#if 0
  83679. + /*
  83680. + * this code prevents SHA working on a BE host,
  83681. + * so it is obviously wrong. I think the byte
  83682. + * swap setup we do with the chip fixes this for us
  83683. + */
  83684. +
  83685. + /* PE is little-endian, insure proper byte order */
  83686. + for (i = 0; i < N(ses->ses_hminner); i++) {
  83687. + ses->ses_hminner[i] = htole32(ses->ses_hminner[i]);
  83688. + ses->ses_hmouter[i] = htole32(ses->ses_hmouter[i]);
  83689. + }
  83690. +#endif
  83691. +#else /* HMAC_HACK */
  83692. + printk("safe: md5/sha not implemented\n");
  83693. +#endif /* HMAC_HACK */
  83694. +}
  83695. +#undef N
  83696. +
  83697. +/*
  83698. + * Allocate a new 'session' and return an encoded session id. 'sidp'
  83699. + * contains our registration id, and should contain an encoded session
  83700. + * id on successful allocation.
  83701. + */
  83702. +static int
  83703. +safe_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  83704. +{
  83705. + struct safe_softc *sc = device_get_softc(dev);
  83706. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  83707. + struct safe_session *ses = NULL;
  83708. + int sesn;
  83709. +
  83710. + DPRINTF(("%s()\n", __FUNCTION__));
  83711. +
  83712. + if (sidp == NULL || cri == NULL || sc == NULL)
  83713. + return (EINVAL);
  83714. +
  83715. + for (c = cri; c != NULL; c = c->cri_next) {
  83716. + if (c->cri_alg == CRYPTO_MD5_HMAC ||
  83717. + c->cri_alg == CRYPTO_SHA1_HMAC ||
  83718. + c->cri_alg == CRYPTO_NULL_HMAC) {
  83719. + if (macini)
  83720. + return (EINVAL);
  83721. + macini = c;
  83722. + } else if (c->cri_alg == CRYPTO_DES_CBC ||
  83723. + c->cri_alg == CRYPTO_3DES_CBC ||
  83724. + c->cri_alg == CRYPTO_AES_CBC ||
  83725. + c->cri_alg == CRYPTO_NULL_CBC) {
  83726. + if (encini)
  83727. + return (EINVAL);
  83728. + encini = c;
  83729. + } else
  83730. + return (EINVAL);
  83731. + }
  83732. + if (encini == NULL && macini == NULL)
  83733. + return (EINVAL);
  83734. + if (encini) { /* validate key length */
  83735. + switch (encini->cri_alg) {
  83736. + case CRYPTO_DES_CBC:
  83737. + if (encini->cri_klen != 64)
  83738. + return (EINVAL);
  83739. + break;
  83740. + case CRYPTO_3DES_CBC:
  83741. + if (encini->cri_klen != 192)
  83742. + return (EINVAL);
  83743. + break;
  83744. + case CRYPTO_AES_CBC:
  83745. + if (encini->cri_klen != 128 &&
  83746. + encini->cri_klen != 192 &&
  83747. + encini->cri_klen != 256)
  83748. + return (EINVAL);
  83749. + break;
  83750. + }
  83751. + }
  83752. +
  83753. + if (sc->sc_sessions == NULL) {
  83754. + ses = sc->sc_sessions = (struct safe_session *)
  83755. + kmalloc(sizeof(struct safe_session), SLAB_ATOMIC);
  83756. + if (ses == NULL)
  83757. + return (ENOMEM);
  83758. + memset(ses, 0, sizeof(struct safe_session));
  83759. + sesn = 0;
  83760. + sc->sc_nsessions = 1;
  83761. + } else {
  83762. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  83763. + if (sc->sc_sessions[sesn].ses_used == 0) {
  83764. + ses = &sc->sc_sessions[sesn];
  83765. + break;
  83766. + }
  83767. + }
  83768. +
  83769. + if (ses == NULL) {
  83770. + sesn = sc->sc_nsessions;
  83771. + ses = (struct safe_session *)
  83772. + kmalloc((sesn + 1) * sizeof(struct safe_session), SLAB_ATOMIC);
  83773. + if (ses == NULL)
  83774. + return (ENOMEM);
  83775. + memset(ses, 0, (sesn + 1) * sizeof(struct safe_session));
  83776. + bcopy(sc->sc_sessions, ses, sesn *
  83777. + sizeof(struct safe_session));
  83778. + bzero(sc->sc_sessions, sesn *
  83779. + sizeof(struct safe_session));
  83780. + kfree(sc->sc_sessions);
  83781. + sc->sc_sessions = ses;
  83782. + ses = &sc->sc_sessions[sesn];
  83783. + sc->sc_nsessions++;
  83784. + }
  83785. + }
  83786. +
  83787. + bzero(ses, sizeof(struct safe_session));
  83788. + ses->ses_used = 1;
  83789. +
  83790. + if (encini) {
  83791. + /* get an IV */
  83792. + /* XXX may read fewer than requested */
  83793. + read_random(ses->ses_iv, sizeof(ses->ses_iv));
  83794. +
  83795. + ses->ses_klen = encini->cri_klen;
  83796. + if (encini->cri_key != NULL)
  83797. + safe_setup_enckey(ses, encini->cri_key);
  83798. + }
  83799. +
  83800. + if (macini) {
  83801. + ses->ses_mlen = macini->cri_mlen;
  83802. + if (ses->ses_mlen == 0) {
  83803. + if (macini->cri_alg == CRYPTO_MD5_HMAC)
  83804. + ses->ses_mlen = MD5_HASH_LEN;
  83805. + else
  83806. + ses->ses_mlen = SHA1_HASH_LEN;
  83807. + }
  83808. +
  83809. + if (macini->cri_key != NULL) {
  83810. + safe_setup_mackey(ses, macini->cri_alg, macini->cri_key,
  83811. + macini->cri_klen / 8);
  83812. + }
  83813. + }
  83814. +
  83815. + *sidp = SAFE_SID(device_get_unit(sc->sc_dev), sesn);
  83816. + return (0);
  83817. +}
  83818. +
  83819. +/*
  83820. + * Deallocate a session.
  83821. + */
  83822. +static int
  83823. +safe_freesession(device_t dev, u_int64_t tid)
  83824. +{
  83825. + struct safe_softc *sc = device_get_softc(dev);
  83826. + int session, ret;
  83827. + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
  83828. +
  83829. + DPRINTF(("%s()\n", __FUNCTION__));
  83830. +
  83831. + if (sc == NULL)
  83832. + return (EINVAL);
  83833. +
  83834. + session = SAFE_SESSION(sid);
  83835. + if (session < sc->sc_nsessions) {
  83836. + bzero(&sc->sc_sessions[session], sizeof(sc->sc_sessions[session]));
  83837. + ret = 0;
  83838. + } else
  83839. + ret = EINVAL;
  83840. + return (ret);
  83841. +}
  83842. +
  83843. +
  83844. +static int
  83845. +safe_process(device_t dev, struct cryptop *crp, int hint)
  83846. +{
  83847. + struct safe_softc *sc = device_get_softc(dev);
  83848. + int err = 0, i, nicealign, uniform;
  83849. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  83850. + int bypass, oplen, ivsize;
  83851. + caddr_t iv;
  83852. + int16_t coffset;
  83853. + struct safe_session *ses;
  83854. + struct safe_ringentry *re;
  83855. + struct safe_sarec *sa;
  83856. + struct safe_pdesc *pd;
  83857. + u_int32_t cmd0, cmd1, staterec;
  83858. + unsigned long flags;
  83859. +
  83860. + DPRINTF(("%s()\n", __FUNCTION__));
  83861. +
  83862. + if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
  83863. + safestats.st_invalid++;
  83864. + return (EINVAL);
  83865. + }
  83866. + if (SAFE_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
  83867. + safestats.st_badsession++;
  83868. + return (EINVAL);
  83869. + }
  83870. +
  83871. + spin_lock_irqsave(&sc->sc_ringmtx, flags);
  83872. + if (sc->sc_front == sc->sc_back && sc->sc_nqchip != 0) {
  83873. + safestats.st_ringfull++;
  83874. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  83875. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  83876. + return (ERESTART);
  83877. + }
  83878. + re = sc->sc_front;
  83879. +
  83880. + staterec = re->re_sa.sa_staterec; /* save */
  83881. + /* NB: zero everything but the PE descriptor */
  83882. + bzero(&re->re_sa, sizeof(struct safe_ringentry) - sizeof(re->re_desc));
  83883. + re->re_sa.sa_staterec = staterec; /* restore */
  83884. +
  83885. + re->re_crp = crp;
  83886. + re->re_sesn = SAFE_SESSION(crp->crp_sid);
  83887. +
  83888. + re->re_src.nsegs = 0;
  83889. + re->re_dst.nsegs = 0;
  83890. +
  83891. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  83892. + re->re_src_skb = (struct sk_buff *)crp->crp_buf;
  83893. + re->re_dst_skb = (struct sk_buff *)crp->crp_buf;
  83894. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  83895. + re->re_src_io = (struct uio *)crp->crp_buf;
  83896. + re->re_dst_io = (struct uio *)crp->crp_buf;
  83897. + } else {
  83898. + safestats.st_badflags++;
  83899. + err = EINVAL;
  83900. + goto errout; /* XXX we don't handle contiguous blocks! */
  83901. + }
  83902. +
  83903. + sa = &re->re_sa;
  83904. + ses = &sc->sc_sessions[re->re_sesn];
  83905. +
  83906. + crd1 = crp->crp_desc;
  83907. + if (crd1 == NULL) {
  83908. + safestats.st_nodesc++;
  83909. + err = EINVAL;
  83910. + goto errout;
  83911. + }
  83912. + crd2 = crd1->crd_next;
  83913. +
  83914. + cmd0 = SAFE_SA_CMD0_BASIC; /* basic group operation */
  83915. + cmd1 = 0;
  83916. + if (crd2 == NULL) {
  83917. + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
  83918. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  83919. + crd1->crd_alg == CRYPTO_NULL_HMAC) {
  83920. + maccrd = crd1;
  83921. + enccrd = NULL;
  83922. + cmd0 |= SAFE_SA_CMD0_OP_HASH;
  83923. + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
  83924. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  83925. + crd1->crd_alg == CRYPTO_AES_CBC ||
  83926. + crd1->crd_alg == CRYPTO_NULL_CBC) {
  83927. + maccrd = NULL;
  83928. + enccrd = crd1;
  83929. + cmd0 |= SAFE_SA_CMD0_OP_CRYPT;
  83930. + } else {
  83931. + safestats.st_badalg++;
  83932. + err = EINVAL;
  83933. + goto errout;
  83934. + }
  83935. + } else {
  83936. + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
  83937. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  83938. + crd1->crd_alg == CRYPTO_NULL_HMAC) &&
  83939. + (crd2->crd_alg == CRYPTO_DES_CBC ||
  83940. + crd2->crd_alg == CRYPTO_3DES_CBC ||
  83941. + crd2->crd_alg == CRYPTO_AES_CBC ||
  83942. + crd2->crd_alg == CRYPTO_NULL_CBC) &&
  83943. + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
  83944. + maccrd = crd1;
  83945. + enccrd = crd2;
  83946. + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
  83947. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  83948. + crd1->crd_alg == CRYPTO_AES_CBC ||
  83949. + crd1->crd_alg == CRYPTO_NULL_CBC) &&
  83950. + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
  83951. + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
  83952. + crd2->crd_alg == CRYPTO_NULL_HMAC) &&
  83953. + (crd1->crd_flags & CRD_F_ENCRYPT)) {
  83954. + enccrd = crd1;
  83955. + maccrd = crd2;
  83956. + } else {
  83957. + safestats.st_badalg++;
  83958. + err = EINVAL;
  83959. + goto errout;
  83960. + }
  83961. + cmd0 |= SAFE_SA_CMD0_OP_BOTH;
  83962. + }
  83963. +
  83964. + if (enccrd) {
  83965. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT)
  83966. + safe_setup_enckey(ses, enccrd->crd_key);
  83967. +
  83968. + if (enccrd->crd_alg == CRYPTO_DES_CBC) {
  83969. + cmd0 |= SAFE_SA_CMD0_DES;
  83970. + cmd1 |= SAFE_SA_CMD1_CBC;
  83971. + ivsize = 2*sizeof(u_int32_t);
  83972. + } else if (enccrd->crd_alg == CRYPTO_3DES_CBC) {
  83973. + cmd0 |= SAFE_SA_CMD0_3DES;
  83974. + cmd1 |= SAFE_SA_CMD1_CBC;
  83975. + ivsize = 2*sizeof(u_int32_t);
  83976. + } else if (enccrd->crd_alg == CRYPTO_AES_CBC) {
  83977. + cmd0 |= SAFE_SA_CMD0_AES;
  83978. + cmd1 |= SAFE_SA_CMD1_CBC;
  83979. + if (ses->ses_klen == 128)
  83980. + cmd1 |= SAFE_SA_CMD1_AES128;
  83981. + else if (ses->ses_klen == 192)
  83982. + cmd1 |= SAFE_SA_CMD1_AES192;
  83983. + else
  83984. + cmd1 |= SAFE_SA_CMD1_AES256;
  83985. + ivsize = 4*sizeof(u_int32_t);
  83986. + } else {
  83987. + cmd0 |= SAFE_SA_CMD0_CRYPT_NULL;
  83988. + ivsize = 0;
  83989. + }
  83990. +
  83991. + /*
  83992. + * Setup encrypt/decrypt state. When using basic ops
  83993. + * we can't use an inline IV because hash/crypt offset
  83994. + * must be from the end of the IV to the start of the
  83995. + * crypt data and this leaves out the preceding header
  83996. + * from the hash calculation. Instead we place the IV
  83997. + * in the state record and set the hash/crypt offset to
  83998. + * copy both the header+IV.
  83999. + */
  84000. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  84001. + cmd0 |= SAFE_SA_CMD0_OUTBOUND;
  84002. +
  84003. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  84004. + iv = enccrd->crd_iv;
  84005. + else
  84006. + iv = (caddr_t) ses->ses_iv;
  84007. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  84008. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  84009. + enccrd->crd_inject, ivsize, iv);
  84010. + }
  84011. + bcopy(iv, re->re_sastate.sa_saved_iv, ivsize);
  84012. + /* make iv LE */
  84013. + for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)
  84014. + re->re_sastate.sa_saved_iv[i] =
  84015. + cpu_to_le32(re->re_sastate.sa_saved_iv[i]);
  84016. + cmd0 |= SAFE_SA_CMD0_IVLD_STATE | SAFE_SA_CMD0_SAVEIV;
  84017. + re->re_flags |= SAFE_QFLAGS_COPYOUTIV;
  84018. + } else {
  84019. + cmd0 |= SAFE_SA_CMD0_INBOUND;
  84020. +
  84021. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  84022. + bcopy(enccrd->crd_iv,
  84023. + re->re_sastate.sa_saved_iv, ivsize);
  84024. + } else {
  84025. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  84026. + enccrd->crd_inject, ivsize,
  84027. + (caddr_t)re->re_sastate.sa_saved_iv);
  84028. + }
  84029. + /* make iv LE */
  84030. + for (i = 0; i < ivsize/sizeof(re->re_sastate.sa_saved_iv[0]); i++)
  84031. + re->re_sastate.sa_saved_iv[i] =
  84032. + cpu_to_le32(re->re_sastate.sa_saved_iv[i]);
  84033. + cmd0 |= SAFE_SA_CMD0_IVLD_STATE;
  84034. + }
  84035. + /*
  84036. + * For basic encryption use the zero pad algorithm.
  84037. + * This pads results to an 8-byte boundary and
  84038. + * suppresses padding verification for inbound (i.e.
  84039. + * decrypt) operations.
  84040. + *
  84041. + * NB: Not sure if the 8-byte pad boundary is a problem.
  84042. + */
  84043. + cmd0 |= SAFE_SA_CMD0_PAD_ZERO;
  84044. +
  84045. + /* XXX assert key bufs have the same size */
  84046. + bcopy(ses->ses_key, sa->sa_key, sizeof(sa->sa_key));
  84047. + }
  84048. +
  84049. + if (maccrd) {
  84050. + if (maccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
  84051. + safe_setup_mackey(ses, maccrd->crd_alg,
  84052. + maccrd->crd_key, maccrd->crd_klen / 8);
  84053. + }
  84054. +
  84055. + if (maccrd->crd_alg == CRYPTO_MD5_HMAC) {
  84056. + cmd0 |= SAFE_SA_CMD0_MD5;
  84057. + cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */
  84058. + } else if (maccrd->crd_alg == CRYPTO_SHA1_HMAC) {
  84059. + cmd0 |= SAFE_SA_CMD0_SHA1;
  84060. + cmd1 |= SAFE_SA_CMD1_HMAC; /* NB: enable HMAC */
  84061. + } else {
  84062. + cmd0 |= SAFE_SA_CMD0_HASH_NULL;
  84063. + }
  84064. + /*
  84065. + * Digest data is loaded from the SA and the hash
  84066. + * result is saved to the state block where we
  84067. + * retrieve it for return to the caller.
  84068. + */
  84069. + /* XXX assert digest bufs have the same size */
  84070. + bcopy(ses->ses_hminner, sa->sa_indigest,
  84071. + sizeof(sa->sa_indigest));
  84072. + bcopy(ses->ses_hmouter, sa->sa_outdigest,
  84073. + sizeof(sa->sa_outdigest));
  84074. +
  84075. + cmd0 |= SAFE_SA_CMD0_HSLD_SA | SAFE_SA_CMD0_SAVEHASH;
  84076. + re->re_flags |= SAFE_QFLAGS_COPYOUTICV;
  84077. + }
  84078. +
  84079. + if (enccrd && maccrd) {
  84080. + /*
  84081. + * The offset from hash data to the start of
  84082. + * crypt data is the difference in the skips.
  84083. + */
  84084. + bypass = maccrd->crd_skip;
  84085. + coffset = enccrd->crd_skip - maccrd->crd_skip;
  84086. + if (coffset < 0) {
  84087. + DPRINTF(("%s: hash does not precede crypt; "
  84088. + "mac skip %u enc skip %u\n",
  84089. + __func__, maccrd->crd_skip, enccrd->crd_skip));
  84090. + safestats.st_skipmismatch++;
  84091. + err = EINVAL;
  84092. + goto errout;
  84093. + }
  84094. + oplen = enccrd->crd_skip + enccrd->crd_len;
  84095. + if (maccrd->crd_skip + maccrd->crd_len != oplen) {
  84096. + DPRINTF(("%s: hash amount %u != crypt amount %u\n",
  84097. + __func__, maccrd->crd_skip + maccrd->crd_len,
  84098. + oplen));
  84099. + safestats.st_lenmismatch++;
  84100. + err = EINVAL;
  84101. + goto errout;
  84102. + }
  84103. +#ifdef SAFE_DEBUG
  84104. + if (debug) {
  84105. + printf("mac: skip %d, len %d, inject %d\n",
  84106. + maccrd->crd_skip, maccrd->crd_len,
  84107. + maccrd->crd_inject);
  84108. + printf("enc: skip %d, len %d, inject %d\n",
  84109. + enccrd->crd_skip, enccrd->crd_len,
  84110. + enccrd->crd_inject);
  84111. + printf("bypass %d coffset %d oplen %d\n",
  84112. + bypass, coffset, oplen);
  84113. + }
  84114. +#endif
  84115. + if (coffset & 3) { /* offset must be 32-bit aligned */
  84116. + DPRINTF(("%s: coffset %u misaligned\n",
  84117. + __func__, coffset));
  84118. + safestats.st_coffmisaligned++;
  84119. + err = EINVAL;
  84120. + goto errout;
  84121. + }
  84122. + coffset >>= 2;
  84123. + if (coffset > 255) { /* offset must be <256 dwords */
  84124. + DPRINTF(("%s: coffset %u too big\n",
  84125. + __func__, coffset));
  84126. + safestats.st_cofftoobig++;
  84127. + err = EINVAL;
  84128. + goto errout;
  84129. + }
  84130. + /*
  84131. + * Tell the hardware to copy the header to the output.
  84132. + * The header is defined as the data from the end of
  84133. + * the bypass to the start of data to be encrypted.
  84134. + * Typically this is the inline IV. Note that you need
  84135. + * to do this even if src+dst are the same; it appears
  84136. + * that w/o this bit the crypted data is written
  84137. + * immediately after the bypass data.
  84138. + */
  84139. + cmd1 |= SAFE_SA_CMD1_HDRCOPY;
  84140. + /*
  84141. + * Disable IP header mutable bit handling. This is
  84142. + * needed to get correct HMAC calculations.
  84143. + */
  84144. + cmd1 |= SAFE_SA_CMD1_MUTABLE;
  84145. + } else {
  84146. + if (enccrd) {
  84147. + bypass = enccrd->crd_skip;
  84148. + oplen = bypass + enccrd->crd_len;
  84149. + } else {
  84150. + bypass = maccrd->crd_skip;
  84151. + oplen = bypass + maccrd->crd_len;
  84152. + }
  84153. + coffset = 0;
  84154. + }
  84155. + /* XXX verify multiple of 4 when using s/g */
  84156. + if (bypass > 96) { /* bypass offset must be <= 96 bytes */
  84157. + DPRINTF(("%s: bypass %u too big\n", __func__, bypass));
  84158. + safestats.st_bypasstoobig++;
  84159. + err = EINVAL;
  84160. + goto errout;
  84161. + }
  84162. +
  84163. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  84164. + if (pci_map_skb(sc, &re->re_src, re->re_src_skb)) {
  84165. + safestats.st_noload++;
  84166. + err = ENOMEM;
  84167. + goto errout;
  84168. + }
  84169. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  84170. + if (pci_map_uio(sc, &re->re_src, re->re_src_io)) {
  84171. + safestats.st_noload++;
  84172. + err = ENOMEM;
  84173. + goto errout;
  84174. + }
  84175. + }
  84176. + nicealign = safe_dmamap_aligned(sc, &re->re_src);
  84177. + uniform = safe_dmamap_uniform(sc, &re->re_src);
  84178. +
  84179. + DPRINTF(("src nicealign %u uniform %u nsegs %u\n",
  84180. + nicealign, uniform, re->re_src.nsegs));
  84181. + if (re->re_src.nsegs > 1) {
  84182. + re->re_desc.d_src = sc->sc_spalloc.dma_paddr +
  84183. + ((caddr_t) sc->sc_spfree - (caddr_t) sc->sc_spring);
  84184. + for (i = 0; i < re->re_src_nsegs; i++) {
  84185. + /* NB: no need to check if there's space */
  84186. + pd = sc->sc_spfree;
  84187. + if (++(sc->sc_spfree) == sc->sc_springtop)
  84188. + sc->sc_spfree = sc->sc_spring;
  84189. +
  84190. + KASSERT((pd->pd_flags&3) == 0 ||
  84191. + (pd->pd_flags&3) == SAFE_PD_DONE,
  84192. + ("bogus source particle descriptor; flags %x",
  84193. + pd->pd_flags));
  84194. + pd->pd_addr = re->re_src_segs[i].ds_addr;
  84195. + pd->pd_size = re->re_src_segs[i].ds_len;
  84196. + pd->pd_flags = SAFE_PD_READY;
  84197. + }
  84198. + cmd0 |= SAFE_SA_CMD0_IGATHER;
  84199. + } else {
  84200. + /*
  84201. + * No need for gather, reference the operand directly.
  84202. + */
  84203. + re->re_desc.d_src = re->re_src_segs[0].ds_addr;
  84204. + }
  84205. +
  84206. + if (enccrd == NULL && maccrd != NULL) {
  84207. + /*
  84208. + * Hash op; no destination needed.
  84209. + */
  84210. + } else {
  84211. + if (crp->crp_flags & (CRYPTO_F_IOV|CRYPTO_F_SKBUF)) {
  84212. + if (!nicealign) {
  84213. + safestats.st_iovmisaligned++;
  84214. + err = EINVAL;
  84215. + goto errout;
  84216. + }
  84217. + if (uniform != 1) {
  84218. + device_printf(sc->sc_dev, "!uniform source\n");
  84219. + if (!uniform) {
  84220. + /*
  84221. + * There's no way to handle the DMA
  84222. + * requirements with this uio. We
  84223. + * could create a separate DMA area for
  84224. + * the result and then copy it back,
  84225. + * but for now we just bail and return
  84226. + * an error. Note that uio requests
  84227. + * > SAFE_MAX_DSIZE are handled because
  84228. + * the DMA map and segment list for the
  84229. + * destination wil result in a
  84230. + * destination particle list that does
  84231. + * the necessary scatter DMA.
  84232. + */
  84233. + safestats.st_iovnotuniform++;
  84234. + err = EINVAL;
  84235. + goto errout;
  84236. + }
  84237. + } else
  84238. + re->re_dst = re->re_src;
  84239. + } else {
  84240. + safestats.st_badflags++;
  84241. + err = EINVAL;
  84242. + goto errout;
  84243. + }
  84244. +
  84245. + if (re->re_dst.nsegs > 1) {
  84246. + re->re_desc.d_dst = sc->sc_dpalloc.dma_paddr +
  84247. + ((caddr_t) sc->sc_dpfree - (caddr_t) sc->sc_dpring);
  84248. + for (i = 0; i < re->re_dst_nsegs; i++) {
  84249. + pd = sc->sc_dpfree;
  84250. + KASSERT((pd->pd_flags&3) == 0 ||
  84251. + (pd->pd_flags&3) == SAFE_PD_DONE,
  84252. + ("bogus dest particle descriptor; flags %x",
  84253. + pd->pd_flags));
  84254. + if (++(sc->sc_dpfree) == sc->sc_dpringtop)
  84255. + sc->sc_dpfree = sc->sc_dpring;
  84256. + pd->pd_addr = re->re_dst_segs[i].ds_addr;
  84257. + pd->pd_flags = SAFE_PD_READY;
  84258. + }
  84259. + cmd0 |= SAFE_SA_CMD0_OSCATTER;
  84260. + } else {
  84261. + /*
  84262. + * No need for scatter, reference the operand directly.
  84263. + */
  84264. + re->re_desc.d_dst = re->re_dst_segs[0].ds_addr;
  84265. + }
  84266. + }
  84267. +
  84268. + /*
  84269. + * All done with setup; fillin the SA command words
  84270. + * and the packet engine descriptor. The operation
  84271. + * is now ready for submission to the hardware.
  84272. + */
  84273. + sa->sa_cmd0 = cmd0 | SAFE_SA_CMD0_IPCI | SAFE_SA_CMD0_OPCI;
  84274. + sa->sa_cmd1 = cmd1
  84275. + | (coffset << SAFE_SA_CMD1_OFFSET_S)
  84276. + | SAFE_SA_CMD1_SAREV1 /* Rev 1 SA data structure */
  84277. + | SAFE_SA_CMD1_SRPCI
  84278. + ;
  84279. + /*
  84280. + * NB: the order of writes is important here. In case the
  84281. + * chip is scanning the ring because of an outstanding request
  84282. + * it might nab this one too. In that case we need to make
  84283. + * sure the setup is complete before we write the length
  84284. + * field of the descriptor as it signals the descriptor is
  84285. + * ready for processing.
  84286. + */
  84287. + re->re_desc.d_csr = SAFE_PE_CSR_READY | SAFE_PE_CSR_SAPCI;
  84288. + if (maccrd)
  84289. + re->re_desc.d_csr |= SAFE_PE_CSR_LOADSA | SAFE_PE_CSR_HASHFINAL;
  84290. + wmb();
  84291. + re->re_desc.d_len = oplen
  84292. + | SAFE_PE_LEN_READY
  84293. + | (bypass << SAFE_PE_LEN_BYPASS_S)
  84294. + ;
  84295. +
  84296. + safestats.st_ipackets++;
  84297. + safestats.st_ibytes += oplen;
  84298. +
  84299. + if (++(sc->sc_front) == sc->sc_ringtop)
  84300. + sc->sc_front = sc->sc_ring;
  84301. +
  84302. + /* XXX honor batching */
  84303. + safe_feed(sc, re);
  84304. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  84305. + return (0);
  84306. +
  84307. +errout:
  84308. + if (re->re_src.map != re->re_dst.map)
  84309. + pci_unmap_operand(sc, &re->re_dst);
  84310. + if (re->re_src.map)
  84311. + pci_unmap_operand(sc, &re->re_src);
  84312. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  84313. + if (err != ERESTART) {
  84314. + crp->crp_etype = err;
  84315. + crypto_done(crp);
  84316. + } else {
  84317. + sc->sc_needwakeup |= CRYPTO_SYMQ;
  84318. + }
  84319. + return (err);
  84320. +}
  84321. +
  84322. +static void
  84323. +safe_callback(struct safe_softc *sc, struct safe_ringentry *re)
  84324. +{
  84325. + struct cryptop *crp = (struct cryptop *)re->re_crp;
  84326. + struct cryptodesc *crd;
  84327. +
  84328. + DPRINTF(("%s()\n", __FUNCTION__));
  84329. +
  84330. + safestats.st_opackets++;
  84331. + safestats.st_obytes += re->re_dst.mapsize;
  84332. +
  84333. + if (re->re_desc.d_csr & SAFE_PE_CSR_STATUS) {
  84334. + device_printf(sc->sc_dev, "csr 0x%x cmd0 0x%x cmd1 0x%x\n",
  84335. + re->re_desc.d_csr,
  84336. + re->re_sa.sa_cmd0, re->re_sa.sa_cmd1);
  84337. + safestats.st_peoperr++;
  84338. + crp->crp_etype = EIO; /* something more meaningful? */
  84339. + }
  84340. +
  84341. + if (re->re_dst.map != NULL && re->re_dst.map != re->re_src.map)
  84342. + pci_unmap_operand(sc, &re->re_dst);
  84343. + pci_unmap_operand(sc, &re->re_src);
  84344. +
  84345. + /*
  84346. + * If result was written to a differet mbuf chain, swap
  84347. + * it in as the return value and reclaim the original.
  84348. + */
  84349. + if ((crp->crp_flags & CRYPTO_F_SKBUF) && re->re_src_skb != re->re_dst_skb) {
  84350. + device_printf(sc->sc_dev, "no CRYPTO_F_SKBUF swapping support\n");
  84351. + /* kfree_skb(skb) */
  84352. + /* crp->crp_buf = (caddr_t)re->re_dst_skb */
  84353. + return;
  84354. + }
  84355. +
  84356. + if (re->re_flags & SAFE_QFLAGS_COPYOUTIV) {
  84357. + /* copy out IV for future use */
  84358. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  84359. + int i;
  84360. + int ivsize;
  84361. +
  84362. + if (crd->crd_alg == CRYPTO_DES_CBC ||
  84363. + crd->crd_alg == CRYPTO_3DES_CBC) {
  84364. + ivsize = 2*sizeof(u_int32_t);
  84365. + } else if (crd->crd_alg == CRYPTO_AES_CBC) {
  84366. + ivsize = 4*sizeof(u_int32_t);
  84367. + } else
  84368. + continue;
  84369. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  84370. + crd->crd_skip + crd->crd_len - ivsize, ivsize,
  84371. + (caddr_t)sc->sc_sessions[re->re_sesn].ses_iv);
  84372. + for (i = 0;
  84373. + i < ivsize/sizeof(sc->sc_sessions[re->re_sesn].ses_iv[0]);
  84374. + i++)
  84375. + sc->sc_sessions[re->re_sesn].ses_iv[i] =
  84376. + cpu_to_le32(sc->sc_sessions[re->re_sesn].ses_iv[i]);
  84377. + break;
  84378. + }
  84379. + }
  84380. +
  84381. + if (re->re_flags & SAFE_QFLAGS_COPYOUTICV) {
  84382. + /* copy out ICV result */
  84383. + for (crd = crp->crp_desc; crd; crd = crd->crd_next) {
  84384. + if (!(crd->crd_alg == CRYPTO_MD5_HMAC ||
  84385. + crd->crd_alg == CRYPTO_SHA1_HMAC ||
  84386. + crd->crd_alg == CRYPTO_NULL_HMAC))
  84387. + continue;
  84388. + if (crd->crd_alg == CRYPTO_SHA1_HMAC) {
  84389. + /*
  84390. + * SHA-1 ICV's are byte-swapped; fix 'em up
  84391. + * before copy them to their destination.
  84392. + */
  84393. + re->re_sastate.sa_saved_indigest[0] =
  84394. + cpu_to_be32(re->re_sastate.sa_saved_indigest[0]);
  84395. + re->re_sastate.sa_saved_indigest[1] =
  84396. + cpu_to_be32(re->re_sastate.sa_saved_indigest[1]);
  84397. + re->re_sastate.sa_saved_indigest[2] =
  84398. + cpu_to_be32(re->re_sastate.sa_saved_indigest[2]);
  84399. + } else {
  84400. + re->re_sastate.sa_saved_indigest[0] =
  84401. + cpu_to_le32(re->re_sastate.sa_saved_indigest[0]);
  84402. + re->re_sastate.sa_saved_indigest[1] =
  84403. + cpu_to_le32(re->re_sastate.sa_saved_indigest[1]);
  84404. + re->re_sastate.sa_saved_indigest[2] =
  84405. + cpu_to_le32(re->re_sastate.sa_saved_indigest[2]);
  84406. + }
  84407. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  84408. + crd->crd_inject,
  84409. + sc->sc_sessions[re->re_sesn].ses_mlen,
  84410. + (caddr_t)re->re_sastate.sa_saved_indigest);
  84411. + break;
  84412. + }
  84413. + }
  84414. + crypto_done(crp);
  84415. +}
  84416. +
  84417. +
  84418. +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
  84419. +#define SAFE_RNG_MAXWAIT 1000
  84420. +
  84421. +static void
  84422. +safe_rng_init(struct safe_softc *sc)
  84423. +{
  84424. + u_int32_t w, v;
  84425. + int i;
  84426. +
  84427. + DPRINTF(("%s()\n", __FUNCTION__));
  84428. +
  84429. + WRITE_REG(sc, SAFE_RNG_CTRL, 0);
  84430. + /* use default value according to the manual */
  84431. + WRITE_REG(sc, SAFE_RNG_CNFG, 0x834); /* magic from SafeNet */
  84432. + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
  84433. +
  84434. + /*
  84435. + * There is a bug in rev 1.0 of the 1140 that when the RNG
  84436. + * is brought out of reset the ready status flag does not
  84437. + * work until the RNG has finished its internal initialization.
  84438. + *
  84439. + * So in order to determine the device is through its
  84440. + * initialization we must read the data register, using the
  84441. + * status reg in the read in case it is initialized. Then read
  84442. + * the data register until it changes from the first read.
  84443. + * Once it changes read the data register until it changes
  84444. + * again. At this time the RNG is considered initialized.
  84445. + * This could take between 750ms - 1000ms in time.
  84446. + */
  84447. + i = 0;
  84448. + w = READ_REG(sc, SAFE_RNG_OUT);
  84449. + do {
  84450. + v = READ_REG(sc, SAFE_RNG_OUT);
  84451. + if (v != w) {
  84452. + w = v;
  84453. + break;
  84454. + }
  84455. + DELAY(10);
  84456. + } while (++i < SAFE_RNG_MAXWAIT);
  84457. +
  84458. + /* Wait Until data changes again */
  84459. + i = 0;
  84460. + do {
  84461. + v = READ_REG(sc, SAFE_RNG_OUT);
  84462. + if (v != w)
  84463. + break;
  84464. + DELAY(10);
  84465. + } while (++i < SAFE_RNG_MAXWAIT);
  84466. +}
  84467. +
  84468. +static __inline void
  84469. +safe_rng_disable_short_cycle(struct safe_softc *sc)
  84470. +{
  84471. + DPRINTF(("%s()\n", __FUNCTION__));
  84472. +
  84473. + WRITE_REG(sc, SAFE_RNG_CTRL,
  84474. + READ_REG(sc, SAFE_RNG_CTRL) &~ SAFE_RNG_CTRL_SHORTEN);
  84475. +}
  84476. +
  84477. +static __inline void
  84478. +safe_rng_enable_short_cycle(struct safe_softc *sc)
  84479. +{
  84480. + DPRINTF(("%s()\n", __FUNCTION__));
  84481. +
  84482. + WRITE_REG(sc, SAFE_RNG_CTRL,
  84483. + READ_REG(sc, SAFE_RNG_CTRL) | SAFE_RNG_CTRL_SHORTEN);
  84484. +}
  84485. +
  84486. +static __inline u_int32_t
  84487. +safe_rng_read(struct safe_softc *sc)
  84488. +{
  84489. + int i;
  84490. +
  84491. + i = 0;
  84492. + while (READ_REG(sc, SAFE_RNG_STAT) != 0 && ++i < SAFE_RNG_MAXWAIT)
  84493. + ;
  84494. + return READ_REG(sc, SAFE_RNG_OUT);
  84495. +}
  84496. +
  84497. +static int
  84498. +safe_read_random(void *arg, u_int32_t *buf, int maxwords)
  84499. +{
  84500. + struct safe_softc *sc = (struct safe_softc *) arg;
  84501. + int i, rc;
  84502. +
  84503. + DPRINTF(("%s()\n", __FUNCTION__));
  84504. +
  84505. + safestats.st_rng++;
  84506. + /*
  84507. + * Fetch the next block of data.
  84508. + */
  84509. + if (maxwords > safe_rngbufsize)
  84510. + maxwords = safe_rngbufsize;
  84511. + if (maxwords > SAFE_RNG_MAXBUFSIZ)
  84512. + maxwords = SAFE_RNG_MAXBUFSIZ;
  84513. +retry:
  84514. + /* read as much as we can */
  84515. + for (rc = 0; rc < maxwords; rc++) {
  84516. + if (READ_REG(sc, SAFE_RNG_STAT) != 0)
  84517. + break;
  84518. + buf[rc] = READ_REG(sc, SAFE_RNG_OUT);
  84519. + }
  84520. + if (rc == 0)
  84521. + return 0;
  84522. + /*
  84523. + * Check the comparator alarm count and reset the h/w if
  84524. + * it exceeds our threshold. This guards against the
  84525. + * hardware oscillators resonating with external signals.
  84526. + */
  84527. + if (READ_REG(sc, SAFE_RNG_ALM_CNT) > safe_rngmaxalarm) {
  84528. + u_int32_t freq_inc, w;
  84529. +
  84530. + DPRINTF(("%s: alarm count %u exceeds threshold %u\n", __func__,
  84531. + (unsigned)READ_REG(sc, SAFE_RNG_ALM_CNT), safe_rngmaxalarm));
  84532. + safestats.st_rngalarm++;
  84533. + safe_rng_enable_short_cycle(sc);
  84534. + freq_inc = 18;
  84535. + for (i = 0; i < 64; i++) {
  84536. + w = READ_REG(sc, SAFE_RNG_CNFG);
  84537. + freq_inc = ((w + freq_inc) & 0x3fL);
  84538. + w = ((w & ~0x3fL) | freq_inc);
  84539. + WRITE_REG(sc, SAFE_RNG_CNFG, w);
  84540. +
  84541. + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
  84542. +
  84543. + (void) safe_rng_read(sc);
  84544. + DELAY(25);
  84545. +
  84546. + if (READ_REG(sc, SAFE_RNG_ALM_CNT) == 0) {
  84547. + safe_rng_disable_short_cycle(sc);
  84548. + goto retry;
  84549. + }
  84550. + freq_inc = 1;
  84551. + }
  84552. + safe_rng_disable_short_cycle(sc);
  84553. + } else
  84554. + WRITE_REG(sc, SAFE_RNG_ALM_CNT, 0);
  84555. +
  84556. + return(rc);
  84557. +}
  84558. +#endif /* defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG) */
  84559. +
  84560. +
  84561. +/*
  84562. + * Resets the board. Values in the regesters are left as is
  84563. + * from the reset (i.e. initial values are assigned elsewhere).
  84564. + */
  84565. +static void
  84566. +safe_reset_board(struct safe_softc *sc)
  84567. +{
  84568. + u_int32_t v;
  84569. + /*
  84570. + * Reset the device. The manual says no delay
  84571. + * is needed between marking and clearing reset.
  84572. + */
  84573. + DPRINTF(("%s()\n", __FUNCTION__));
  84574. +
  84575. + v = READ_REG(sc, SAFE_PE_DMACFG) &~
  84576. + (SAFE_PE_DMACFG_PERESET | SAFE_PE_DMACFG_PDRRESET |
  84577. + SAFE_PE_DMACFG_SGRESET);
  84578. + WRITE_REG(sc, SAFE_PE_DMACFG, v
  84579. + | SAFE_PE_DMACFG_PERESET
  84580. + | SAFE_PE_DMACFG_PDRRESET
  84581. + | SAFE_PE_DMACFG_SGRESET);
  84582. + WRITE_REG(sc, SAFE_PE_DMACFG, v);
  84583. +}
  84584. +
  84585. +/*
  84586. + * Initialize registers we need to touch only once.
  84587. + */
  84588. +static void
  84589. +safe_init_board(struct safe_softc *sc)
  84590. +{
  84591. + u_int32_t v, dwords;
  84592. +
  84593. + DPRINTF(("%s()\n", __FUNCTION__));
  84594. +
  84595. + v = READ_REG(sc, SAFE_PE_DMACFG);
  84596. + v &=~ ( SAFE_PE_DMACFG_PEMODE
  84597. + | SAFE_PE_DMACFG_FSENA /* failsafe enable */
  84598. + | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */
  84599. + | SAFE_PE_DMACFG_SPRPCI /* scatter ring on PCI */
  84600. + | SAFE_PE_DMACFG_ESDESC /* endian-swap descriptors */
  84601. + | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */
  84602. + | SAFE_PE_DMACFG_ESSA /* endian-swap SA's */
  84603. + | SAFE_PE_DMACFG_ESPACKET /* swap the packet data */
  84604. + );
  84605. + v |= SAFE_PE_DMACFG_FSENA /* failsafe enable */
  84606. + | SAFE_PE_DMACFG_GPRPCI /* gather ring on PCI */
  84607. + | SAFE_PE_DMACFG_SPRPCI /* scatter ring on PCI */
  84608. + | SAFE_PE_DMACFG_ESDESC /* endian-swap descriptors */
  84609. + | SAFE_PE_DMACFG_ESPDESC /* endian-swap part. desc's */
  84610. + | SAFE_PE_DMACFG_ESSA /* endian-swap SA's */
  84611. +#if 0
  84612. + | SAFE_PE_DMACFG_ESPACKET /* swap the packet data */
  84613. +#endif
  84614. + ;
  84615. + WRITE_REG(sc, SAFE_PE_DMACFG, v);
  84616. +
  84617. +#ifdef __BIG_ENDIAN
  84618. + /* tell the safenet that we are 4321 and not 1234 */
  84619. + WRITE_REG(sc, SAFE_ENDIAN, 0xe4e41b1b);
  84620. +#endif
  84621. +
  84622. + if (sc->sc_chiprev == SAFE_REV(1,0)) {
  84623. + /*
  84624. + * Avoid large PCI DMA transfers. Rev 1.0 has a bug where
  84625. + * "target mode transfers" done while the chip is DMA'ing
  84626. + * >1020 bytes cause the hardware to lockup. To avoid this
  84627. + * we reduce the max PCI transfer size and use small source
  84628. + * particle descriptors (<= 256 bytes).
  84629. + */
  84630. + WRITE_REG(sc, SAFE_DMA_CFG, 256);
  84631. + device_printf(sc->sc_dev,
  84632. + "Reduce max DMA size to %u words for rev %u.%u WAR\n",
  84633. + (unsigned) ((READ_REG(sc, SAFE_DMA_CFG)>>2) & 0xff),
  84634. + (unsigned) SAFE_REV_MAJ(sc->sc_chiprev),
  84635. + (unsigned) SAFE_REV_MIN(sc->sc_chiprev));
  84636. + sc->sc_max_dsize = 256;
  84637. + } else {
  84638. + sc->sc_max_dsize = SAFE_MAX_DSIZE;
  84639. + }
  84640. +
  84641. + /* NB: operands+results are overlaid */
  84642. + WRITE_REG(sc, SAFE_PE_PDRBASE, sc->sc_ringalloc.dma_paddr);
  84643. + WRITE_REG(sc, SAFE_PE_RDRBASE, sc->sc_ringalloc.dma_paddr);
  84644. + /*
  84645. + * Configure ring entry size and number of items in the ring.
  84646. + */
  84647. + KASSERT((sizeof(struct safe_ringentry) % sizeof(u_int32_t)) == 0,
  84648. + ("PE ring entry not 32-bit aligned!"));
  84649. + dwords = sizeof(struct safe_ringentry) / sizeof(u_int32_t);
  84650. + WRITE_REG(sc, SAFE_PE_RINGCFG,
  84651. + (dwords << SAFE_PE_RINGCFG_OFFSET_S) | SAFE_MAX_NQUEUE);
  84652. + WRITE_REG(sc, SAFE_PE_RINGPOLL, 0); /* disable polling */
  84653. +
  84654. + WRITE_REG(sc, SAFE_PE_GRNGBASE, sc->sc_spalloc.dma_paddr);
  84655. + WRITE_REG(sc, SAFE_PE_SRNGBASE, sc->sc_dpalloc.dma_paddr);
  84656. + WRITE_REG(sc, SAFE_PE_PARTSIZE,
  84657. + (SAFE_TOTAL_DPART<<16) | SAFE_TOTAL_SPART);
  84658. + /*
  84659. + * NB: destination particles are fixed size. We use
  84660. + * an mbuf cluster and require all results go to
  84661. + * clusters or smaller.
  84662. + */
  84663. + WRITE_REG(sc, SAFE_PE_PARTCFG, sc->sc_max_dsize);
  84664. +
  84665. + /* it's now safe to enable PE mode, do it */
  84666. + WRITE_REG(sc, SAFE_PE_DMACFG, v | SAFE_PE_DMACFG_PEMODE);
  84667. +
  84668. + /*
  84669. + * Configure hardware to use level-triggered interrupts and
  84670. + * to interrupt after each descriptor is processed.
  84671. + */
  84672. + WRITE_REG(sc, SAFE_HI_CFG, SAFE_HI_CFG_LEVEL);
  84673. + WRITE_REG(sc, SAFE_HI_CLR, 0xffffffff);
  84674. + WRITE_REG(sc, SAFE_HI_DESC_CNT, 1);
  84675. + WRITE_REG(sc, SAFE_HI_MASK, SAFE_INT_PE_DDONE | SAFE_INT_PE_ERROR);
  84676. +}
  84677. +
  84678. +
  84679. +/*
  84680. + * Clean up after a chip crash.
  84681. + * It is assumed that the caller in splimp()
  84682. + */
  84683. +static void
  84684. +safe_cleanchip(struct safe_softc *sc)
  84685. +{
  84686. + DPRINTF(("%s()\n", __FUNCTION__));
  84687. +
  84688. + if (sc->sc_nqchip != 0) {
  84689. + struct safe_ringentry *re = sc->sc_back;
  84690. +
  84691. + while (re != sc->sc_front) {
  84692. + if (re->re_desc.d_csr != 0)
  84693. + safe_free_entry(sc, re);
  84694. + if (++re == sc->sc_ringtop)
  84695. + re = sc->sc_ring;
  84696. + }
  84697. + sc->sc_back = re;
  84698. + sc->sc_nqchip = 0;
  84699. + }
  84700. +}
  84701. +
  84702. +/*
  84703. + * free a safe_q
  84704. + * It is assumed that the caller is within splimp().
  84705. + */
  84706. +static int
  84707. +safe_free_entry(struct safe_softc *sc, struct safe_ringentry *re)
  84708. +{
  84709. + struct cryptop *crp;
  84710. +
  84711. + DPRINTF(("%s()\n", __FUNCTION__));
  84712. +
  84713. + /*
  84714. + * Free header MCR
  84715. + */
  84716. + if ((re->re_dst_skb != NULL) && (re->re_src_skb != re->re_dst_skb))
  84717. +#ifdef NOTYET
  84718. + m_freem(re->re_dst_m);
  84719. +#else
  84720. + printk("%s,%d: SKB not supported\n", __FILE__, __LINE__);
  84721. +#endif
  84722. +
  84723. + crp = (struct cryptop *)re->re_crp;
  84724. +
  84725. + re->re_desc.d_csr = 0;
  84726. +
  84727. + crp->crp_etype = EFAULT;
  84728. + crypto_done(crp);
  84729. + return(0);
  84730. +}
  84731. +
  84732. +/*
  84733. + * Routine to reset the chip and clean up.
  84734. + * It is assumed that the caller is in splimp()
  84735. + */
  84736. +static void
  84737. +safe_totalreset(struct safe_softc *sc)
  84738. +{
  84739. + DPRINTF(("%s()\n", __FUNCTION__));
  84740. +
  84741. + safe_reset_board(sc);
  84742. + safe_init_board(sc);
  84743. + safe_cleanchip(sc);
  84744. +}
  84745. +
  84746. +/*
  84747. + * Is the operand suitable aligned for direct DMA. Each
  84748. + * segment must be aligned on a 32-bit boundary and all
  84749. + * but the last segment must be a multiple of 4 bytes.
  84750. + */
  84751. +static int
  84752. +safe_dmamap_aligned(struct safe_softc *sc, const struct safe_operand *op)
  84753. +{
  84754. + int i;
  84755. +
  84756. + DPRINTF(("%s()\n", __FUNCTION__));
  84757. +
  84758. + for (i = 0; i < op->nsegs; i++) {
  84759. + if (op->segs[i].ds_addr & 3)
  84760. + return (0);
  84761. + if (i != (op->nsegs - 1) && (op->segs[i].ds_len & 3))
  84762. + return (0);
  84763. + }
  84764. + return (1);
  84765. +}
  84766. +
  84767. +/*
  84768. + * Is the operand suitable for direct DMA as the destination
  84769. + * of an operation. The hardware requires that each ``particle''
  84770. + * but the last in an operation result have the same size. We
  84771. + * fix that size at SAFE_MAX_DSIZE bytes. This routine returns
  84772. + * 0 if some segment is not a multiple of of this size, 1 if all
  84773. + * segments are exactly this size, or 2 if segments are at worst
  84774. + * a multple of this size.
  84775. + */
  84776. +static int
  84777. +safe_dmamap_uniform(struct safe_softc *sc, const struct safe_operand *op)
  84778. +{
  84779. + int result = 1;
  84780. +
  84781. + DPRINTF(("%s()\n", __FUNCTION__));
  84782. +
  84783. + if (op->nsegs > 0) {
  84784. + int i;
  84785. +
  84786. + for (i = 0; i < op->nsegs-1; i++) {
  84787. + if (op->segs[i].ds_len % sc->sc_max_dsize)
  84788. + return (0);
  84789. + if (op->segs[i].ds_len != sc->sc_max_dsize)
  84790. + result = 2;
  84791. + }
  84792. + }
  84793. + return (result);
  84794. +}
  84795. +
  84796. +static int
  84797. +safe_kprocess(device_t dev, struct cryptkop *krp, int hint)
  84798. +{
  84799. + struct safe_softc *sc = device_get_softc(dev);
  84800. + struct safe_pkq *q;
  84801. + unsigned long flags;
  84802. +
  84803. + DPRINTF(("%s()\n", __FUNCTION__));
  84804. +
  84805. + if (sc == NULL) {
  84806. + krp->krp_status = EINVAL;
  84807. + goto err;
  84808. + }
  84809. +
  84810. + if (krp->krp_op != CRK_MOD_EXP) {
  84811. + krp->krp_status = EOPNOTSUPP;
  84812. + goto err;
  84813. + }
  84814. +
  84815. + q = (struct safe_pkq *) kmalloc(sizeof(*q), GFP_KERNEL);
  84816. + if (q == NULL) {
  84817. + krp->krp_status = ENOMEM;
  84818. + goto err;
  84819. + }
  84820. + memset(q, 0, sizeof(*q));
  84821. + q->pkq_krp = krp;
  84822. + INIT_LIST_HEAD(&q->pkq_list);
  84823. +
  84824. + spin_lock_irqsave(&sc->sc_pkmtx, flags);
  84825. + list_add_tail(&q->pkq_list, &sc->sc_pkq);
  84826. + safe_kfeed(sc);
  84827. + spin_unlock_irqrestore(&sc->sc_pkmtx, flags);
  84828. + return (0);
  84829. +
  84830. +err:
  84831. + crypto_kdone(krp);
  84832. + return (0);
  84833. +}
  84834. +
  84835. +#define SAFE_CRK_PARAM_BASE 0
  84836. +#define SAFE_CRK_PARAM_EXP 1
  84837. +#define SAFE_CRK_PARAM_MOD 2
  84838. +
  84839. +static int
  84840. +safe_kstart(struct safe_softc *sc)
  84841. +{
  84842. + struct cryptkop *krp = sc->sc_pkq_cur->pkq_krp;
  84843. + int exp_bits, mod_bits, base_bits;
  84844. + u_int32_t op, a_off, b_off, c_off, d_off;
  84845. +
  84846. + DPRINTF(("%s()\n", __FUNCTION__));
  84847. +
  84848. + if (krp->krp_iparams < 3 || krp->krp_oparams != 1) {
  84849. + krp->krp_status = EINVAL;
  84850. + return (1);
  84851. + }
  84852. +
  84853. + base_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_BASE]);
  84854. + if (base_bits > 2048)
  84855. + goto too_big;
  84856. + if (base_bits <= 0) /* 5. base not zero */
  84857. + goto too_small;
  84858. +
  84859. + exp_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_EXP]);
  84860. + if (exp_bits > 2048)
  84861. + goto too_big;
  84862. + if (exp_bits <= 0) /* 1. exponent word length > 0 */
  84863. + goto too_small; /* 4. exponent not zero */
  84864. +
  84865. + mod_bits = safe_ksigbits(sc, &krp->krp_param[SAFE_CRK_PARAM_MOD]);
  84866. + if (mod_bits > 2048)
  84867. + goto too_big;
  84868. + if (mod_bits <= 32) /* 2. modulus word length > 1 */
  84869. + goto too_small; /* 8. MSW of modulus != zero */
  84870. + if (mod_bits < exp_bits) /* 3 modulus len >= exponent len */
  84871. + goto too_small;
  84872. + if ((krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p[0] & 1) == 0)
  84873. + goto bad_domain; /* 6. modulus is odd */
  84874. + if (mod_bits > krp->krp_param[krp->krp_iparams].crp_nbits)
  84875. + goto too_small; /* make sure result will fit */
  84876. +
  84877. + /* 7. modulus > base */
  84878. + if (mod_bits < base_bits)
  84879. + goto too_small;
  84880. + if (mod_bits == base_bits) {
  84881. + u_int8_t *basep, *modp;
  84882. + int i;
  84883. +
  84884. + basep = krp->krp_param[SAFE_CRK_PARAM_BASE].crp_p +
  84885. + ((base_bits + 7) / 8) - 1;
  84886. + modp = krp->krp_param[SAFE_CRK_PARAM_MOD].crp_p +
  84887. + ((mod_bits + 7) / 8) - 1;
  84888. +
  84889. + for (i = 0; i < (mod_bits + 7) / 8; i++, basep--, modp--) {
  84890. + if (*modp < *basep)
  84891. + goto too_small;
  84892. + if (*modp > *basep)
  84893. + break;
  84894. + }
  84895. + }
  84896. +
  84897. + /* And on the 9th step, he rested. */
  84898. +
  84899. + WRITE_REG(sc, SAFE_PK_A_LEN, (exp_bits + 31) / 32);
  84900. + WRITE_REG(sc, SAFE_PK_B_LEN, (mod_bits + 31) / 32);
  84901. + if (mod_bits > 1024) {
  84902. + op = SAFE_PK_FUNC_EXP4;
  84903. + a_off = 0x000;
  84904. + b_off = 0x100;
  84905. + c_off = 0x200;
  84906. + d_off = 0x300;
  84907. + } else {
  84908. + op = SAFE_PK_FUNC_EXP16;
  84909. + a_off = 0x000;
  84910. + b_off = 0x080;
  84911. + c_off = 0x100;
  84912. + d_off = 0x180;
  84913. + }
  84914. + sc->sc_pk_reslen = b_off - a_off;
  84915. + sc->sc_pk_resoff = d_off;
  84916. +
  84917. + /* A is exponent, B is modulus, C is base, D is result */
  84918. + safe_kload_reg(sc, a_off, b_off - a_off,
  84919. + &krp->krp_param[SAFE_CRK_PARAM_EXP]);
  84920. + WRITE_REG(sc, SAFE_PK_A_ADDR, a_off >> 2);
  84921. + safe_kload_reg(sc, b_off, b_off - a_off,
  84922. + &krp->krp_param[SAFE_CRK_PARAM_MOD]);
  84923. + WRITE_REG(sc, SAFE_PK_B_ADDR, b_off >> 2);
  84924. + safe_kload_reg(sc, c_off, b_off - a_off,
  84925. + &krp->krp_param[SAFE_CRK_PARAM_BASE]);
  84926. + WRITE_REG(sc, SAFE_PK_C_ADDR, c_off >> 2);
  84927. + WRITE_REG(sc, SAFE_PK_D_ADDR, d_off >> 2);
  84928. +
  84929. + WRITE_REG(sc, SAFE_PK_FUNC, op | SAFE_PK_FUNC_RUN);
  84930. +
  84931. + return (0);
  84932. +
  84933. +too_big:
  84934. + krp->krp_status = E2BIG;
  84935. + return (1);
  84936. +too_small:
  84937. + krp->krp_status = ERANGE;
  84938. + return (1);
  84939. +bad_domain:
  84940. + krp->krp_status = EDOM;
  84941. + return (1);
  84942. +}
  84943. +
  84944. +static int
  84945. +safe_ksigbits(struct safe_softc *sc, struct crparam *cr)
  84946. +{
  84947. + u_int plen = (cr->crp_nbits + 7) / 8;
  84948. + int i, sig = plen * 8;
  84949. + u_int8_t c, *p = cr->crp_p;
  84950. +
  84951. + DPRINTF(("%s()\n", __FUNCTION__));
  84952. +
  84953. + for (i = plen - 1; i >= 0; i--) {
  84954. + c = p[i];
  84955. + if (c != 0) {
  84956. + while ((c & 0x80) == 0) {
  84957. + sig--;
  84958. + c <<= 1;
  84959. + }
  84960. + break;
  84961. + }
  84962. + sig -= 8;
  84963. + }
  84964. + return (sig);
  84965. +}
  84966. +
  84967. +static void
  84968. +safe_kfeed(struct safe_softc *sc)
  84969. +{
  84970. + struct safe_pkq *q, *tmp;
  84971. +
  84972. + DPRINTF(("%s()\n", __FUNCTION__));
  84973. +
  84974. + if (list_empty(&sc->sc_pkq) && sc->sc_pkq_cur == NULL)
  84975. + return;
  84976. + if (sc->sc_pkq_cur != NULL)
  84977. + return;
  84978. + list_for_each_entry_safe(q, tmp, &sc->sc_pkq, pkq_list) {
  84979. + sc->sc_pkq_cur = q;
  84980. + list_del(&q->pkq_list);
  84981. + if (safe_kstart(sc) != 0) {
  84982. + crypto_kdone(q->pkq_krp);
  84983. + kfree(q);
  84984. + sc->sc_pkq_cur = NULL;
  84985. + } else {
  84986. + /* op started, start polling */
  84987. + mod_timer(&sc->sc_pkto, jiffies + 1);
  84988. + break;
  84989. + }
  84990. + }
  84991. +}
  84992. +
  84993. +static void
  84994. +safe_kpoll(unsigned long arg)
  84995. +{
  84996. + struct safe_softc *sc = NULL;
  84997. + struct safe_pkq *q;
  84998. + struct crparam *res;
  84999. + int i;
  85000. + u_int32_t buf[64];
  85001. + unsigned long flags;
  85002. +
  85003. + DPRINTF(("%s()\n", __FUNCTION__));
  85004. +
  85005. + if (arg >= SAFE_MAX_CHIPS)
  85006. + return;
  85007. + sc = safe_chip_idx[arg];
  85008. + if (!sc) {
  85009. + DPRINTF(("%s() - bad callback\n", __FUNCTION__));
  85010. + return;
  85011. + }
  85012. +
  85013. + spin_lock_irqsave(&sc->sc_pkmtx, flags);
  85014. + if (sc->sc_pkq_cur == NULL)
  85015. + goto out;
  85016. + if (READ_REG(sc, SAFE_PK_FUNC) & SAFE_PK_FUNC_RUN) {
  85017. + /* still running, check back later */
  85018. + mod_timer(&sc->sc_pkto, jiffies + 1);
  85019. + goto out;
  85020. + }
  85021. +
  85022. + q = sc->sc_pkq_cur;
  85023. + res = &q->pkq_krp->krp_param[q->pkq_krp->krp_iparams];
  85024. + bzero(buf, sizeof(buf));
  85025. + bzero(res->crp_p, (res->crp_nbits + 7) / 8);
  85026. + for (i = 0; i < sc->sc_pk_reslen >> 2; i++)
  85027. + buf[i] = le32_to_cpu(READ_REG(sc, SAFE_PK_RAM_START +
  85028. + sc->sc_pk_resoff + (i << 2)));
  85029. + bcopy(buf, res->crp_p, (res->crp_nbits + 7) / 8);
  85030. + /*
  85031. + * reduce the bits that need copying if possible
  85032. + */
  85033. + res->crp_nbits = min(res->crp_nbits,sc->sc_pk_reslen * 8);
  85034. + res->crp_nbits = safe_ksigbits(sc, res);
  85035. +
  85036. + for (i = SAFE_PK_RAM_START; i < SAFE_PK_RAM_END; i += 4)
  85037. + WRITE_REG(sc, i, 0);
  85038. +
  85039. + crypto_kdone(q->pkq_krp);
  85040. + kfree(q);
  85041. + sc->sc_pkq_cur = NULL;
  85042. +
  85043. + safe_kfeed(sc);
  85044. +out:
  85045. + spin_unlock_irqrestore(&sc->sc_pkmtx, flags);
  85046. +}
  85047. +
  85048. +static void
  85049. +safe_kload_reg(struct safe_softc *sc, u_int32_t off, u_int32_t len,
  85050. + struct crparam *n)
  85051. +{
  85052. + u_int32_t buf[64], i;
  85053. +
  85054. + DPRINTF(("%s()\n", __FUNCTION__));
  85055. +
  85056. + bzero(buf, sizeof(buf));
  85057. + bcopy(n->crp_p, buf, (n->crp_nbits + 7) / 8);
  85058. +
  85059. + for (i = 0; i < len >> 2; i++)
  85060. + WRITE_REG(sc, SAFE_PK_RAM_START + off + (i << 2),
  85061. + cpu_to_le32(buf[i]));
  85062. +}
  85063. +
  85064. +#ifdef SAFE_DEBUG
  85065. +static void
  85066. +safe_dump_dmastatus(struct safe_softc *sc, const char *tag)
  85067. +{
  85068. + printf("%s: ENDIAN 0x%x SRC 0x%x DST 0x%x STAT 0x%x\n"
  85069. + , tag
  85070. + , READ_REG(sc, SAFE_DMA_ENDIAN)
  85071. + , READ_REG(sc, SAFE_DMA_SRCADDR)
  85072. + , READ_REG(sc, SAFE_DMA_DSTADDR)
  85073. + , READ_REG(sc, SAFE_DMA_STAT)
  85074. + );
  85075. +}
  85076. +
  85077. +static void
  85078. +safe_dump_intrstate(struct safe_softc *sc, const char *tag)
  85079. +{
  85080. + printf("%s: HI_CFG 0x%x HI_MASK 0x%x HI_DESC_CNT 0x%x HU_STAT 0x%x HM_STAT 0x%x\n"
  85081. + , tag
  85082. + , READ_REG(sc, SAFE_HI_CFG)
  85083. + , READ_REG(sc, SAFE_HI_MASK)
  85084. + , READ_REG(sc, SAFE_HI_DESC_CNT)
  85085. + , READ_REG(sc, SAFE_HU_STAT)
  85086. + , READ_REG(sc, SAFE_HM_STAT)
  85087. + );
  85088. +}
  85089. +
  85090. +static void
  85091. +safe_dump_ringstate(struct safe_softc *sc, const char *tag)
  85092. +{
  85093. + u_int32_t estat = READ_REG(sc, SAFE_PE_ERNGSTAT);
  85094. +
  85095. + /* NB: assume caller has lock on ring */
  85096. + printf("%s: ERNGSTAT %x (next %u) back %lu front %lu\n",
  85097. + tag,
  85098. + estat, (estat >> SAFE_PE_ERNGSTAT_NEXT_S),
  85099. + (unsigned long)(sc->sc_back - sc->sc_ring),
  85100. + (unsigned long)(sc->sc_front - sc->sc_ring));
  85101. +}
  85102. +
  85103. +static void
  85104. +safe_dump_request(struct safe_softc *sc, const char* tag, struct safe_ringentry *re)
  85105. +{
  85106. + int ix, nsegs;
  85107. +
  85108. + ix = re - sc->sc_ring;
  85109. + printf("%s: %p (%u): csr %x src %x dst %x sa %x len %x\n"
  85110. + , tag
  85111. + , re, ix
  85112. + , re->re_desc.d_csr
  85113. + , re->re_desc.d_src
  85114. + , re->re_desc.d_dst
  85115. + , re->re_desc.d_sa
  85116. + , re->re_desc.d_len
  85117. + );
  85118. + if (re->re_src.nsegs > 1) {
  85119. + ix = (re->re_desc.d_src - sc->sc_spalloc.dma_paddr) /
  85120. + sizeof(struct safe_pdesc);
  85121. + for (nsegs = re->re_src.nsegs; nsegs; nsegs--) {
  85122. + printf(" spd[%u] %p: %p size %u flags %x"
  85123. + , ix, &sc->sc_spring[ix]
  85124. + , (caddr_t)(uintptr_t) sc->sc_spring[ix].pd_addr
  85125. + , sc->sc_spring[ix].pd_size
  85126. + , sc->sc_spring[ix].pd_flags
  85127. + );
  85128. + if (sc->sc_spring[ix].pd_size == 0)
  85129. + printf(" (zero!)");
  85130. + printf("\n");
  85131. + if (++ix == SAFE_TOTAL_SPART)
  85132. + ix = 0;
  85133. + }
  85134. + }
  85135. + if (re->re_dst.nsegs > 1) {
  85136. + ix = (re->re_desc.d_dst - sc->sc_dpalloc.dma_paddr) /
  85137. + sizeof(struct safe_pdesc);
  85138. + for (nsegs = re->re_dst.nsegs; nsegs; nsegs--) {
  85139. + printf(" dpd[%u] %p: %p flags %x\n"
  85140. + , ix, &sc->sc_dpring[ix]
  85141. + , (caddr_t)(uintptr_t) sc->sc_dpring[ix].pd_addr
  85142. + , sc->sc_dpring[ix].pd_flags
  85143. + );
  85144. + if (++ix == SAFE_TOTAL_DPART)
  85145. + ix = 0;
  85146. + }
  85147. + }
  85148. + printf("sa: cmd0 %08x cmd1 %08x staterec %x\n",
  85149. + re->re_sa.sa_cmd0, re->re_sa.sa_cmd1, re->re_sa.sa_staterec);
  85150. + printf("sa: key %x %x %x %x %x %x %x %x\n"
  85151. + , re->re_sa.sa_key[0]
  85152. + , re->re_sa.sa_key[1]
  85153. + , re->re_sa.sa_key[2]
  85154. + , re->re_sa.sa_key[3]
  85155. + , re->re_sa.sa_key[4]
  85156. + , re->re_sa.sa_key[5]
  85157. + , re->re_sa.sa_key[6]
  85158. + , re->re_sa.sa_key[7]
  85159. + );
  85160. + printf("sa: indigest %x %x %x %x %x\n"
  85161. + , re->re_sa.sa_indigest[0]
  85162. + , re->re_sa.sa_indigest[1]
  85163. + , re->re_sa.sa_indigest[2]
  85164. + , re->re_sa.sa_indigest[3]
  85165. + , re->re_sa.sa_indigest[4]
  85166. + );
  85167. + printf("sa: outdigest %x %x %x %x %x\n"
  85168. + , re->re_sa.sa_outdigest[0]
  85169. + , re->re_sa.sa_outdigest[1]
  85170. + , re->re_sa.sa_outdigest[2]
  85171. + , re->re_sa.sa_outdigest[3]
  85172. + , re->re_sa.sa_outdigest[4]
  85173. + );
  85174. + printf("sr: iv %x %x %x %x\n"
  85175. + , re->re_sastate.sa_saved_iv[0]
  85176. + , re->re_sastate.sa_saved_iv[1]
  85177. + , re->re_sastate.sa_saved_iv[2]
  85178. + , re->re_sastate.sa_saved_iv[3]
  85179. + );
  85180. + printf("sr: hashbc %u indigest %x %x %x %x %x\n"
  85181. + , re->re_sastate.sa_saved_hashbc
  85182. + , re->re_sastate.sa_saved_indigest[0]
  85183. + , re->re_sastate.sa_saved_indigest[1]
  85184. + , re->re_sastate.sa_saved_indigest[2]
  85185. + , re->re_sastate.sa_saved_indigest[3]
  85186. + , re->re_sastate.sa_saved_indigest[4]
  85187. + );
  85188. +}
  85189. +
  85190. +static void
  85191. +safe_dump_ring(struct safe_softc *sc, const char *tag)
  85192. +{
  85193. + unsigned long flags;
  85194. +
  85195. + spin_lock_irqsave(&sc->sc_ringmtx, flags);
  85196. + printf("\nSafeNet Ring State:\n");
  85197. + safe_dump_intrstate(sc, tag);
  85198. + safe_dump_dmastatus(sc, tag);
  85199. + safe_dump_ringstate(sc, tag);
  85200. + if (sc->sc_nqchip) {
  85201. + struct safe_ringentry *re = sc->sc_back;
  85202. + do {
  85203. + safe_dump_request(sc, tag, re);
  85204. + if (++re == sc->sc_ringtop)
  85205. + re = sc->sc_ring;
  85206. + } while (re != sc->sc_front);
  85207. + }
  85208. + spin_unlock_irqrestore(&sc->sc_ringmtx, flags);
  85209. +}
  85210. +#endif /* SAFE_DEBUG */
  85211. +
  85212. +
  85213. +static int safe_probe(struct pci_dev *dev, const struct pci_device_id *ent)
  85214. +{
  85215. + struct safe_softc *sc = NULL;
  85216. + u32 mem_start, mem_len, cmd;
  85217. + int i, rc, devinfo;
  85218. + dma_addr_t raddr;
  85219. + static int num_chips = 0;
  85220. +
  85221. + DPRINTF(("%s()\n", __FUNCTION__));
  85222. +
  85223. + if (pci_enable_device(dev) < 0)
  85224. + return(-ENODEV);
  85225. +
  85226. + if (!dev->irq) {
  85227. + printk("safe: found device with no IRQ assigned. check BIOS settings!");
  85228. + pci_disable_device(dev);
  85229. + return(-ENODEV);
  85230. + }
  85231. +
  85232. + if (pci_set_mwi(dev)) {
  85233. + printk("safe: pci_set_mwi failed!");
  85234. + return(-ENODEV);
  85235. + }
  85236. +
  85237. + sc = (struct safe_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  85238. + if (!sc)
  85239. + return(-ENOMEM);
  85240. + memset(sc, 0, sizeof(*sc));
  85241. +
  85242. + softc_device_init(sc, "safe", num_chips, safe_methods);
  85243. +
  85244. + sc->sc_irq = -1;
  85245. + sc->sc_cid = -1;
  85246. + sc->sc_pcidev = dev;
  85247. + if (num_chips < SAFE_MAX_CHIPS) {
  85248. + safe_chip_idx[device_get_unit(sc->sc_dev)] = sc;
  85249. + num_chips++;
  85250. + }
  85251. +
  85252. + INIT_LIST_HEAD(&sc->sc_pkq);
  85253. + spin_lock_init(&sc->sc_pkmtx);
  85254. +
  85255. + pci_set_drvdata(sc->sc_pcidev, sc);
  85256. +
  85257. + /* we read its hardware registers as memory */
  85258. + mem_start = pci_resource_start(sc->sc_pcidev, 0);
  85259. + mem_len = pci_resource_len(sc->sc_pcidev, 0);
  85260. +
  85261. + sc->sc_base_addr = (ocf_iomem_t) ioremap(mem_start, mem_len);
  85262. + if (!sc->sc_base_addr) {
  85263. + device_printf(sc->sc_dev, "failed to ioremap 0x%x-0x%x\n",
  85264. + mem_start, mem_start + mem_len - 1);
  85265. + goto out;
  85266. + }
  85267. +
  85268. + /* fix up the bus size */
  85269. + if (pci_set_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {
  85270. + device_printf(sc->sc_dev, "No usable DMA configuration, aborting.\n");
  85271. + goto out;
  85272. + }
  85273. + if (pci_set_consistent_dma_mask(sc->sc_pcidev, DMA_32BIT_MASK)) {
  85274. + device_printf(sc->sc_dev, "No usable consistent DMA configuration, aborting.\n");
  85275. + goto out;
  85276. + }
  85277. +
  85278. + pci_set_master(sc->sc_pcidev);
  85279. +
  85280. + pci_read_config_dword(sc->sc_pcidev, PCI_COMMAND, &cmd);
  85281. +
  85282. + if (!(cmd & PCI_COMMAND_MEMORY)) {
  85283. + device_printf(sc->sc_dev, "failed to enable memory mapping\n");
  85284. + goto out;
  85285. + }
  85286. +
  85287. + if (!(cmd & PCI_COMMAND_MASTER)) {
  85288. + device_printf(sc->sc_dev, "failed to enable bus mastering\n");
  85289. + goto out;
  85290. + }
  85291. +
  85292. + rc = request_irq(dev->irq, safe_intr, IRQF_SHARED, "safe", sc);
  85293. + if (rc) {
  85294. + device_printf(sc->sc_dev, "failed to hook irq %d\n", sc->sc_irq);
  85295. + goto out;
  85296. + }
  85297. + sc->sc_irq = dev->irq;
  85298. +
  85299. + sc->sc_chiprev = READ_REG(sc, SAFE_DEVINFO) &
  85300. + (SAFE_DEVINFO_REV_MAJ | SAFE_DEVINFO_REV_MIN);
  85301. +
  85302. + /*
  85303. + * Allocate packet engine descriptors.
  85304. + */
  85305. + sc->sc_ringalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
  85306. + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
  85307. + &sc->sc_ringalloc.dma_paddr);
  85308. + if (!sc->sc_ringalloc.dma_vaddr) {
  85309. + device_printf(sc->sc_dev, "cannot allocate PE descriptor ring\n");
  85310. + goto out;
  85311. + }
  85312. +
  85313. + /*
  85314. + * Hookup the static portion of all our data structures.
  85315. + */
  85316. + sc->sc_ring = (struct safe_ringentry *) sc->sc_ringalloc.dma_vaddr;
  85317. + sc->sc_ringtop = sc->sc_ring + SAFE_MAX_NQUEUE;
  85318. + sc->sc_front = sc->sc_ring;
  85319. + sc->sc_back = sc->sc_ring;
  85320. + raddr = sc->sc_ringalloc.dma_paddr;
  85321. + bzero(sc->sc_ring, SAFE_MAX_NQUEUE * sizeof(struct safe_ringentry));
  85322. + for (i = 0; i < SAFE_MAX_NQUEUE; i++) {
  85323. + struct safe_ringentry *re = &sc->sc_ring[i];
  85324. +
  85325. + re->re_desc.d_sa = raddr +
  85326. + offsetof(struct safe_ringentry, re_sa);
  85327. + re->re_sa.sa_staterec = raddr +
  85328. + offsetof(struct safe_ringentry, re_sastate);
  85329. +
  85330. + raddr += sizeof (struct safe_ringentry);
  85331. + }
  85332. + spin_lock_init(&sc->sc_ringmtx);
  85333. +
  85334. + /*
  85335. + * Allocate scatter and gather particle descriptors.
  85336. + */
  85337. + sc->sc_spalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
  85338. + SAFE_TOTAL_SPART * sizeof (struct safe_pdesc),
  85339. + &sc->sc_spalloc.dma_paddr);
  85340. + if (!sc->sc_spalloc.dma_vaddr) {
  85341. + device_printf(sc->sc_dev, "cannot allocate source particle descriptor ring\n");
  85342. + goto out;
  85343. + }
  85344. + sc->sc_spring = (struct safe_pdesc *) sc->sc_spalloc.dma_vaddr;
  85345. + sc->sc_springtop = sc->sc_spring + SAFE_TOTAL_SPART;
  85346. + sc->sc_spfree = sc->sc_spring;
  85347. + bzero(sc->sc_spring, SAFE_TOTAL_SPART * sizeof(struct safe_pdesc));
  85348. +
  85349. + sc->sc_dpalloc.dma_vaddr = pci_alloc_consistent(sc->sc_pcidev,
  85350. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  85351. + &sc->sc_dpalloc.dma_paddr);
  85352. + if (!sc->sc_dpalloc.dma_vaddr) {
  85353. + device_printf(sc->sc_dev, "cannot allocate destination particle descriptor ring\n");
  85354. + goto out;
  85355. + }
  85356. + sc->sc_dpring = (struct safe_pdesc *) sc->sc_dpalloc.dma_vaddr;
  85357. + sc->sc_dpringtop = sc->sc_dpring + SAFE_TOTAL_DPART;
  85358. + sc->sc_dpfree = sc->sc_dpring;
  85359. + bzero(sc->sc_dpring, SAFE_TOTAL_DPART * sizeof(struct safe_pdesc));
  85360. +
  85361. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc), CRYPTOCAP_F_HARDWARE);
  85362. + if (sc->sc_cid < 0) {
  85363. + device_printf(sc->sc_dev, "could not get crypto driver id\n");
  85364. + goto out;
  85365. + }
  85366. +
  85367. + printf("%s:", device_get_nameunit(sc->sc_dev));
  85368. +
  85369. + devinfo = READ_REG(sc, SAFE_DEVINFO);
  85370. + if (devinfo & SAFE_DEVINFO_RNG) {
  85371. + sc->sc_flags |= SAFE_FLAGS_RNG;
  85372. + printf(" rng");
  85373. + }
  85374. + if (devinfo & SAFE_DEVINFO_PKEY) {
  85375. + printf(" key");
  85376. + sc->sc_flags |= SAFE_FLAGS_KEY;
  85377. + crypto_kregister(sc->sc_cid, CRK_MOD_EXP, 0);
  85378. +#if 0
  85379. + crypto_kregister(sc->sc_cid, CRK_MOD_EXP_CRT, 0);
  85380. +#endif
  85381. + init_timer(&sc->sc_pkto);
  85382. + sc->sc_pkto.function = safe_kpoll;
  85383. + sc->sc_pkto.data = (unsigned long) device_get_unit(sc->sc_dev);
  85384. + }
  85385. + if (devinfo & SAFE_DEVINFO_DES) {
  85386. + printf(" des/3des");
  85387. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  85388. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  85389. + }
  85390. + if (devinfo & SAFE_DEVINFO_AES) {
  85391. + printf(" aes");
  85392. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  85393. + }
  85394. + if (devinfo & SAFE_DEVINFO_MD5) {
  85395. + printf(" md5");
  85396. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  85397. + }
  85398. + if (devinfo & SAFE_DEVINFO_SHA1) {
  85399. + printf(" sha1");
  85400. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  85401. + }
  85402. + printf(" null");
  85403. + crypto_register(sc->sc_cid, CRYPTO_NULL_CBC, 0, 0);
  85404. + crypto_register(sc->sc_cid, CRYPTO_NULL_HMAC, 0, 0);
  85405. + /* XXX other supported algorithms */
  85406. + printf("\n");
  85407. +
  85408. + safe_reset_board(sc); /* reset h/w */
  85409. + safe_init_board(sc); /* init h/w */
  85410. +
  85411. +#if defined(CONFIG_OCF_RANDOMHARVEST) && !defined(SAFE_NO_RNG)
  85412. + if (sc->sc_flags & SAFE_FLAGS_RNG) {
  85413. + safe_rng_init(sc);
  85414. + crypto_rregister(sc->sc_cid, safe_read_random, sc);
  85415. + }
  85416. +#endif /* SAFE_NO_RNG */
  85417. +
  85418. + return (0);
  85419. +
  85420. +out:
  85421. + if (sc->sc_cid >= 0)
  85422. + crypto_unregister_all(sc->sc_cid);
  85423. + if (sc->sc_irq != -1)
  85424. + free_irq(sc->sc_irq, sc);
  85425. + if (sc->sc_ringalloc.dma_vaddr)
  85426. + pci_free_consistent(sc->sc_pcidev,
  85427. + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
  85428. + sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);
  85429. + if (sc->sc_spalloc.dma_vaddr)
  85430. + pci_free_consistent(sc->sc_pcidev,
  85431. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  85432. + sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);
  85433. + if (sc->sc_dpalloc.dma_vaddr)
  85434. + pci_free_consistent(sc->sc_pcidev,
  85435. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  85436. + sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);
  85437. + kfree(sc);
  85438. + return(-ENODEV);
  85439. +}
  85440. +
  85441. +static void safe_remove(struct pci_dev *dev)
  85442. +{
  85443. + struct safe_softc *sc = pci_get_drvdata(dev);
  85444. +
  85445. + DPRINTF(("%s()\n", __FUNCTION__));
  85446. +
  85447. + /* XXX wait/abort active ops */
  85448. +
  85449. + WRITE_REG(sc, SAFE_HI_MASK, 0); /* disable interrupts */
  85450. +
  85451. + del_timer_sync(&sc->sc_pkto);
  85452. +
  85453. + crypto_unregister_all(sc->sc_cid);
  85454. +
  85455. + safe_cleanchip(sc);
  85456. +
  85457. + if (sc->sc_irq != -1)
  85458. + free_irq(sc->sc_irq, sc);
  85459. + if (sc->sc_ringalloc.dma_vaddr)
  85460. + pci_free_consistent(sc->sc_pcidev,
  85461. + SAFE_MAX_NQUEUE * sizeof (struct safe_ringentry),
  85462. + sc->sc_ringalloc.dma_vaddr, sc->sc_ringalloc.dma_paddr);
  85463. + if (sc->sc_spalloc.dma_vaddr)
  85464. + pci_free_consistent(sc->sc_pcidev,
  85465. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  85466. + sc->sc_spalloc.dma_vaddr, sc->sc_spalloc.dma_paddr);
  85467. + if (sc->sc_dpalloc.dma_vaddr)
  85468. + pci_free_consistent(sc->sc_pcidev,
  85469. + SAFE_TOTAL_DPART * sizeof (struct safe_pdesc),
  85470. + sc->sc_dpalloc.dma_vaddr, sc->sc_dpalloc.dma_paddr);
  85471. + sc->sc_irq = -1;
  85472. + sc->sc_ringalloc.dma_vaddr = NULL;
  85473. + sc->sc_spalloc.dma_vaddr = NULL;
  85474. + sc->sc_dpalloc.dma_vaddr = NULL;
  85475. +}
  85476. +
  85477. +static struct pci_device_id safe_pci_tbl[] = {
  85478. + { PCI_VENDOR_SAFENET, PCI_PRODUCT_SAFEXCEL,
  85479. + PCI_ANY_ID, PCI_ANY_ID, 0, 0, },
  85480. + { },
  85481. +};
  85482. +MODULE_DEVICE_TABLE(pci, safe_pci_tbl);
  85483. +
  85484. +static struct pci_driver safe_driver = {
  85485. + .name = "safe",
  85486. + .id_table = safe_pci_tbl,
  85487. + .probe = safe_probe,
  85488. + .remove = safe_remove,
  85489. + /* add PM stuff here one day */
  85490. +};
  85491. +
  85492. +static int __init safe_init (void)
  85493. +{
  85494. + struct safe_softc *sc = NULL;
  85495. + int rc;
  85496. +
  85497. + DPRINTF(("%s(%p)\n", __FUNCTION__, safe_init));
  85498. +
  85499. + rc = pci_register_driver(&safe_driver);
  85500. + pci_register_driver_compat(&safe_driver, rc);
  85501. +
  85502. + return rc;
  85503. +}
  85504. +
  85505. +static void __exit safe_exit (void)
  85506. +{
  85507. + pci_unregister_driver(&safe_driver);
  85508. +}
  85509. +
  85510. +module_init(safe_init);
  85511. +module_exit(safe_exit);
  85512. +
  85513. +MODULE_LICENSE("BSD");
  85514. +MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
  85515. +MODULE_DESCRIPTION("OCF driver for safenet PCI crypto devices");
  85516. diff -Nur linux-2.6.39.orig/crypto/ocf/safe/safereg.h linux-2.6.39/crypto/ocf/safe/safereg.h
  85517. --- linux-2.6.39.orig/crypto/ocf/safe/safereg.h 1970-01-01 01:00:00.000000000 +0100
  85518. +++ linux-2.6.39/crypto/ocf/safe/safereg.h 2011-08-01 14:38:19.000000000 +0200
  85519. @@ -0,0 +1,421 @@
  85520. +/*-
  85521. + * Copyright (c) 2003 Sam Leffler, Errno Consulting
  85522. + * Copyright (c) 2003 Global Technology Associates, Inc.
  85523. + * All rights reserved.
  85524. + *
  85525. + * Redistribution and use in source and binary forms, with or without
  85526. + * modification, are permitted provided that the following conditions
  85527. + * are met:
  85528. + * 1. Redistributions of source code must retain the above copyright
  85529. + * notice, this list of conditions and the following disclaimer.
  85530. + * 2. Redistributions in binary form must reproduce the above copyright
  85531. + * notice, this list of conditions and the following disclaimer in the
  85532. + * documentation and/or other materials provided with the distribution.
  85533. + *
  85534. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  85535. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  85536. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  85537. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  85538. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  85539. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  85540. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  85541. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  85542. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  85543. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  85544. + * SUCH DAMAGE.
  85545. + *
  85546. + * $FreeBSD: src/sys/dev/safe/safereg.h,v 1.1 2003/07/21 21:46:07 sam Exp $
  85547. + */
  85548. +#ifndef _SAFE_SAFEREG_H_
  85549. +#define _SAFE_SAFEREG_H_
  85550. +
  85551. +/*
  85552. + * Register definitions for SafeNet SafeXcel-1141 crypto device.
  85553. + * Definitions from revision 1.3 (Nov 6 2002) of the User's Manual.
  85554. + */
  85555. +
  85556. +#define BS_BAR 0x10 /* DMA base address register */
  85557. +#define BS_TRDY_TIMEOUT 0x40 /* TRDY timeout */
  85558. +#define BS_RETRY_TIMEOUT 0x41 /* DMA retry timeout */
  85559. +
  85560. +#define PCI_VENDOR_SAFENET 0x16ae /* SafeNet, Inc. */
  85561. +
  85562. +/* SafeNet */
  85563. +#define PCI_PRODUCT_SAFEXCEL 0x1141 /* 1141 */
  85564. +
  85565. +#define SAFE_PE_CSR 0x0000 /* Packet Enginge Ctrl/Status */
  85566. +#define SAFE_PE_SRC 0x0004 /* Packet Engine Source */
  85567. +#define SAFE_PE_DST 0x0008 /* Packet Engine Destination */
  85568. +#define SAFE_PE_SA 0x000c /* Packet Engine SA */
  85569. +#define SAFE_PE_LEN 0x0010 /* Packet Engine Length */
  85570. +#define SAFE_PE_DMACFG 0x0040 /* Packet Engine DMA Configuration */
  85571. +#define SAFE_PE_DMASTAT 0x0044 /* Packet Engine DMA Status */
  85572. +#define SAFE_PE_PDRBASE 0x0048 /* Packet Engine Descriptor Ring Base */
  85573. +#define SAFE_PE_RDRBASE 0x004c /* Packet Engine Result Ring Base */
  85574. +#define SAFE_PE_RINGCFG 0x0050 /* Packet Engine Ring Configuration */
  85575. +#define SAFE_PE_RINGPOLL 0x0054 /* Packet Engine Ring Poll */
  85576. +#define SAFE_PE_IRNGSTAT 0x0058 /* Packet Engine Internal Ring Status */
  85577. +#define SAFE_PE_ERNGSTAT 0x005c /* Packet Engine External Ring Status */
  85578. +#define SAFE_PE_IOTHRESH 0x0060 /* Packet Engine I/O Threshold */
  85579. +#define SAFE_PE_GRNGBASE 0x0064 /* Packet Engine Gather Ring Base */
  85580. +#define SAFE_PE_SRNGBASE 0x0068 /* Packet Engine Scatter Ring Base */
  85581. +#define SAFE_PE_PARTSIZE 0x006c /* Packet Engine Particlar Ring Size */
  85582. +#define SAFE_PE_PARTCFG 0x0070 /* Packet Engine Particle Ring Config */
  85583. +#define SAFE_CRYPTO_CTRL 0x0080 /* Crypto Control */
  85584. +#define SAFE_DEVID 0x0084 /* Device ID */
  85585. +#define SAFE_DEVINFO 0x0088 /* Device Info */
  85586. +#define SAFE_HU_STAT 0x00a0 /* Host Unmasked Status */
  85587. +#define SAFE_HM_STAT 0x00a4 /* Host Masked Status (read-only) */
  85588. +#define SAFE_HI_CLR 0x00a4 /* Host Clear Interrupt (write-only) */
  85589. +#define SAFE_HI_MASK 0x00a8 /* Host Mask Control */
  85590. +#define SAFE_HI_CFG 0x00ac /* Interrupt Configuration */
  85591. +#define SAFE_HI_RD_DESCR 0x00b4 /* Force Descriptor Read */
  85592. +#define SAFE_HI_DESC_CNT 0x00b8 /* Host Descriptor Done Count */
  85593. +#define SAFE_DMA_ENDIAN 0x00c0 /* Master Endian Status */
  85594. +#define SAFE_DMA_SRCADDR 0x00c4 /* DMA Source Address Status */
  85595. +#define SAFE_DMA_DSTADDR 0x00c8 /* DMA Destination Address Status */
  85596. +#define SAFE_DMA_STAT 0x00cc /* DMA Current Status */
  85597. +#define SAFE_DMA_CFG 0x00d4 /* DMA Configuration/Status */
  85598. +#define SAFE_ENDIAN 0x00e0 /* Endian Configuration */
  85599. +#define SAFE_PK_A_ADDR 0x0800 /* Public Key A Address */
  85600. +#define SAFE_PK_B_ADDR 0x0804 /* Public Key B Address */
  85601. +#define SAFE_PK_C_ADDR 0x0808 /* Public Key C Address */
  85602. +#define SAFE_PK_D_ADDR 0x080c /* Public Key D Address */
  85603. +#define SAFE_PK_A_LEN 0x0810 /* Public Key A Length */
  85604. +#define SAFE_PK_B_LEN 0x0814 /* Public Key B Length */
  85605. +#define SAFE_PK_SHIFT 0x0818 /* Public Key Shift */
  85606. +#define SAFE_PK_FUNC 0x081c /* Public Key Function */
  85607. +#define SAFE_PK_RAM_START 0x1000 /* Public Key RAM start address */
  85608. +#define SAFE_PK_RAM_END 0x1fff /* Public Key RAM end address */
  85609. +
  85610. +#define SAFE_RNG_OUT 0x0100 /* RNG Output */
  85611. +#define SAFE_RNG_STAT 0x0104 /* RNG Status */
  85612. +#define SAFE_RNG_CTRL 0x0108 /* RNG Control */
  85613. +#define SAFE_RNG_A 0x010c /* RNG A */
  85614. +#define SAFE_RNG_B 0x0110 /* RNG B */
  85615. +#define SAFE_RNG_X_LO 0x0114 /* RNG X [31:0] */
  85616. +#define SAFE_RNG_X_MID 0x0118 /* RNG X [63:32] */
  85617. +#define SAFE_RNG_X_HI 0x011c /* RNG X [80:64] */
  85618. +#define SAFE_RNG_X_CNTR 0x0120 /* RNG Counter */
  85619. +#define SAFE_RNG_ALM_CNT 0x0124 /* RNG Alarm Count */
  85620. +#define SAFE_RNG_CNFG 0x0128 /* RNG Configuration */
  85621. +#define SAFE_RNG_LFSR1_LO 0x012c /* RNG LFSR1 [31:0] */
  85622. +#define SAFE_RNG_LFSR1_HI 0x0130 /* RNG LFSR1 [47:32] */
  85623. +#define SAFE_RNG_LFSR2_LO 0x0134 /* RNG LFSR1 [31:0] */
  85624. +#define SAFE_RNG_LFSR2_HI 0x0138 /* RNG LFSR1 [47:32] */
  85625. +
  85626. +#define SAFE_PE_CSR_READY 0x00000001 /* ready for processing */
  85627. +#define SAFE_PE_CSR_DONE 0x00000002 /* h/w completed processing */
  85628. +#define SAFE_PE_CSR_LOADSA 0x00000004 /* load SA digests */
  85629. +#define SAFE_PE_CSR_HASHFINAL 0x00000010 /* do hash pad & write result */
  85630. +#define SAFE_PE_CSR_SABUSID 0x000000c0 /* bus id for SA */
  85631. +#define SAFE_PE_CSR_SAPCI 0x00000040 /* PCI bus id for SA */
  85632. +#define SAFE_PE_CSR_NXTHDR 0x0000ff00 /* next hdr value for IPsec */
  85633. +#define SAFE_PE_CSR_FPAD 0x0000ff00 /* fixed pad for basic ops */
  85634. +#define SAFE_PE_CSR_STATUS 0x00ff0000 /* operation result status */
  85635. +#define SAFE_PE_CSR_AUTH_FAIL 0x00010000 /* ICV mismatch (inbound) */
  85636. +#define SAFE_PE_CSR_PAD_FAIL 0x00020000 /* pad verify fail (inbound) */
  85637. +#define SAFE_PE_CSR_SEQ_FAIL 0x00040000 /* sequence number (inbound) */
  85638. +#define SAFE_PE_CSR_XERROR 0x00080000 /* extended error follows */
  85639. +#define SAFE_PE_CSR_XECODE 0x00f00000 /* extended error code */
  85640. +#define SAFE_PE_CSR_XECODE_S 20
  85641. +#define SAFE_PE_CSR_XECODE_BADCMD 0 /* invalid command */
  85642. +#define SAFE_PE_CSR_XECODE_BADALG 1 /* invalid algorithm */
  85643. +#define SAFE_PE_CSR_XECODE_ALGDIS 2 /* algorithm disabled */
  85644. +#define SAFE_PE_CSR_XECODE_ZEROLEN 3 /* zero packet length */
  85645. +#define SAFE_PE_CSR_XECODE_DMAERR 4 /* bus DMA error */
  85646. +#define SAFE_PE_CSR_XECODE_PIPEABORT 5 /* secondary bus DMA error */
  85647. +#define SAFE_PE_CSR_XECODE_BADSPI 6 /* IPsec SPI mismatch */
  85648. +#define SAFE_PE_CSR_XECODE_TIMEOUT 10 /* failsafe timeout */
  85649. +#define SAFE_PE_CSR_PAD 0xff000000 /* ESP padding control/status */
  85650. +#define SAFE_PE_CSR_PAD_MIN 0x00000000 /* minimum IPsec padding */
  85651. +#define SAFE_PE_CSR_PAD_16 0x08000000 /* pad to 16-byte boundary */
  85652. +#define SAFE_PE_CSR_PAD_32 0x10000000 /* pad to 32-byte boundary */
  85653. +#define SAFE_PE_CSR_PAD_64 0x20000000 /* pad to 64-byte boundary */
  85654. +#define SAFE_PE_CSR_PAD_128 0x40000000 /* pad to 128-byte boundary */
  85655. +#define SAFE_PE_CSR_PAD_256 0x80000000 /* pad to 256-byte boundary */
  85656. +
  85657. +/*
  85658. + * Check the CSR to see if the PE has returned ownership to
  85659. + * the host. Note that before processing a descriptor this
  85660. + * must be done followed by a check of the SAFE_PE_LEN register
  85661. + * status bits to avoid premature processing of a descriptor
  85662. + * on its way back to the host.
  85663. + */
  85664. +#define SAFE_PE_CSR_IS_DONE(_csr) \
  85665. + (((_csr) & (SAFE_PE_CSR_READY | SAFE_PE_CSR_DONE)) == SAFE_PE_CSR_DONE)
  85666. +
  85667. +#define SAFE_PE_LEN_LENGTH 0x000fffff /* total length (bytes) */
  85668. +#define SAFE_PE_LEN_READY 0x00400000 /* ready for processing */
  85669. +#define SAFE_PE_LEN_DONE 0x00800000 /* h/w completed processing */
  85670. +#define SAFE_PE_LEN_BYPASS 0xff000000 /* bypass offset (bytes) */
  85671. +#define SAFE_PE_LEN_BYPASS_S 24
  85672. +
  85673. +#define SAFE_PE_LEN_IS_DONE(_len) \
  85674. + (((_len) & (SAFE_PE_LEN_READY | SAFE_PE_LEN_DONE)) == SAFE_PE_LEN_DONE)
  85675. +
  85676. +/* NB: these apply to HU_STAT, HM_STAT, HI_CLR, and HI_MASK */
  85677. +#define SAFE_INT_PE_CDONE 0x00000002 /* PE context done */
  85678. +#define SAFE_INT_PE_DDONE 0x00000008 /* PE descriptor done */
  85679. +#define SAFE_INT_PE_ERROR 0x00000010 /* PE error */
  85680. +#define SAFE_INT_PE_ODONE 0x00000020 /* PE operation done */
  85681. +
  85682. +#define SAFE_HI_CFG_PULSE 0x00000001 /* use pulse interrupt */
  85683. +#define SAFE_HI_CFG_LEVEL 0x00000000 /* use level interrupt */
  85684. +#define SAFE_HI_CFG_AUTOCLR 0x00000002 /* auto-clear pulse interrupt */
  85685. +
  85686. +#define SAFE_ENDIAN_PASS 0x000000e4 /* straight pass-thru */
  85687. +#define SAFE_ENDIAN_SWAB 0x0000001b /* swap bytes in 32-bit word */
  85688. +
  85689. +#define SAFE_PE_DMACFG_PERESET 0x00000001 /* reset packet engine */
  85690. +#define SAFE_PE_DMACFG_PDRRESET 0x00000002 /* reset PDR counters/ptrs */
  85691. +#define SAFE_PE_DMACFG_SGRESET 0x00000004 /* reset scatter/gather cache */
  85692. +#define SAFE_PE_DMACFG_FSENA 0x00000008 /* enable failsafe reset */
  85693. +#define SAFE_PE_DMACFG_PEMODE 0x00000100 /* packet engine mode */
  85694. +#define SAFE_PE_DMACFG_SAPREC 0x00000200 /* SA precedes packet */
  85695. +#define SAFE_PE_DMACFG_PKFOLL 0x00000400 /* packet follows descriptor */
  85696. +#define SAFE_PE_DMACFG_GPRBID 0x00003000 /* gather particle ring busid */
  85697. +#define SAFE_PE_DMACFG_GPRPCI 0x00001000 /* PCI gather particle ring */
  85698. +#define SAFE_PE_DMACFG_SPRBID 0x0000c000 /* scatter part. ring busid */
  85699. +#define SAFE_PE_DMACFG_SPRPCI 0x00004000 /* PCI scatter part. ring */
  85700. +#define SAFE_PE_DMACFG_ESDESC 0x00010000 /* endian swap descriptors */
  85701. +#define SAFE_PE_DMACFG_ESSA 0x00020000 /* endian swap SA data */
  85702. +#define SAFE_PE_DMACFG_ESPACKET 0x00040000 /* endian swap packet data */
  85703. +#define SAFE_PE_DMACFG_ESPDESC 0x00080000 /* endian swap particle desc. */
  85704. +#define SAFE_PE_DMACFG_NOPDRUP 0x00100000 /* supp. PDR ownership update */
  85705. +#define SAFE_PD_EDMACFG_PCIMODE 0x01000000 /* PCI target mode */
  85706. +
  85707. +#define SAFE_PE_DMASTAT_PEIDONE 0x00000001 /* PE core input done */
  85708. +#define SAFE_PE_DMASTAT_PEODONE 0x00000002 /* PE core output done */
  85709. +#define SAFE_PE_DMASTAT_ENCDONE 0x00000004 /* encryption done */
  85710. +#define SAFE_PE_DMASTAT_IHDONE 0x00000008 /* inner hash done */
  85711. +#define SAFE_PE_DMASTAT_OHDONE 0x00000010 /* outer hash (HMAC) done */
  85712. +#define SAFE_PE_DMASTAT_PADFLT 0x00000020 /* crypto pad fault */
  85713. +#define SAFE_PE_DMASTAT_ICVFLT 0x00000040 /* ICV fault */
  85714. +#define SAFE_PE_DMASTAT_SPIMIS 0x00000080 /* SPI mismatch */
  85715. +#define SAFE_PE_DMASTAT_CRYPTO 0x00000100 /* crypto engine timeout */
  85716. +#define SAFE_PE_DMASTAT_CQACT 0x00000200 /* command queue active */
  85717. +#define SAFE_PE_DMASTAT_IRACT 0x00000400 /* input request active */
  85718. +#define SAFE_PE_DMASTAT_ORACT 0x00000800 /* output request active */
  85719. +#define SAFE_PE_DMASTAT_PEISIZE 0x003ff000 /* PE input size:32-bit words */
  85720. +#define SAFE_PE_DMASTAT_PEOSIZE 0xffc00000 /* PE out. size:32-bit words */
  85721. +
  85722. +#define SAFE_PE_RINGCFG_SIZE 0x000003ff /* ring size (descriptors) */
  85723. +#define SAFE_PE_RINGCFG_OFFSET 0xffff0000 /* offset btw desc's (dwords) */
  85724. +#define SAFE_PE_RINGCFG_OFFSET_S 16
  85725. +
  85726. +#define SAFE_PE_RINGPOLL_POLL 0x00000fff /* polling frequency/divisor */
  85727. +#define SAFE_PE_RINGPOLL_RETRY 0x03ff0000 /* polling frequency/divisor */
  85728. +#define SAFE_PE_RINGPOLL_CONT 0x80000000 /* continuously poll */
  85729. +
  85730. +#define SAFE_PE_IRNGSTAT_CQAVAIL 0x00000001 /* command queue available */
  85731. +
  85732. +#define SAFE_PE_ERNGSTAT_NEXT 0x03ff0000 /* index of next packet desc. */
  85733. +#define SAFE_PE_ERNGSTAT_NEXT_S 16
  85734. +
  85735. +#define SAFE_PE_IOTHRESH_INPUT 0x000003ff /* input threshold (dwords) */
  85736. +#define SAFE_PE_IOTHRESH_OUTPUT 0x03ff0000 /* output threshold (dwords) */
  85737. +
  85738. +#define SAFE_PE_PARTCFG_SIZE 0x0000ffff /* scatter particle size */
  85739. +#define SAFE_PE_PARTCFG_GBURST 0x00030000 /* gather particle burst */
  85740. +#define SAFE_PE_PARTCFG_GBURST_2 0x00000000
  85741. +#define SAFE_PE_PARTCFG_GBURST_4 0x00010000
  85742. +#define SAFE_PE_PARTCFG_GBURST_8 0x00020000
  85743. +#define SAFE_PE_PARTCFG_GBURST_16 0x00030000
  85744. +#define SAFE_PE_PARTCFG_SBURST 0x000c0000 /* scatter particle burst */
  85745. +#define SAFE_PE_PARTCFG_SBURST_2 0x00000000
  85746. +#define SAFE_PE_PARTCFG_SBURST_4 0x00040000
  85747. +#define SAFE_PE_PARTCFG_SBURST_8 0x00080000
  85748. +#define SAFE_PE_PARTCFG_SBURST_16 0x000c0000
  85749. +
  85750. +#define SAFE_PE_PARTSIZE_SCAT 0xffff0000 /* scatter particle ring size */
  85751. +#define SAFE_PE_PARTSIZE_GATH 0x0000ffff /* gather particle ring size */
  85752. +
  85753. +#define SAFE_CRYPTO_CTRL_3DES 0x00000001 /* enable 3DES support */
  85754. +#define SAFE_CRYPTO_CTRL_PKEY 0x00010000 /* enable public key support */
  85755. +#define SAFE_CRYPTO_CTRL_RNG 0x00020000 /* enable RNG support */
  85756. +
  85757. +#define SAFE_DEVINFO_REV_MIN 0x0000000f /* minor rev for chip */
  85758. +#define SAFE_DEVINFO_REV_MAJ 0x000000f0 /* major rev for chip */
  85759. +#define SAFE_DEVINFO_REV_MAJ_S 4
  85760. +#define SAFE_DEVINFO_DES 0x00000100 /* DES/3DES support present */
  85761. +#define SAFE_DEVINFO_ARC4 0x00000200 /* ARC4 support present */
  85762. +#define SAFE_DEVINFO_AES 0x00000400 /* AES support present */
  85763. +#define SAFE_DEVINFO_MD5 0x00001000 /* MD5 support present */
  85764. +#define SAFE_DEVINFO_SHA1 0x00002000 /* SHA-1 support present */
  85765. +#define SAFE_DEVINFO_RIPEMD 0x00004000 /* RIPEMD support present */
  85766. +#define SAFE_DEVINFO_DEFLATE 0x00010000 /* Deflate support present */
  85767. +#define SAFE_DEVINFO_SARAM 0x00100000 /* on-chip SA RAM present */
  85768. +#define SAFE_DEVINFO_EMIBUS 0x00200000 /* EMI bus present */
  85769. +#define SAFE_DEVINFO_PKEY 0x00400000 /* public key support present */
  85770. +#define SAFE_DEVINFO_RNG 0x00800000 /* RNG present */
  85771. +
  85772. +#define SAFE_REV(_maj, _min) (((_maj) << SAFE_DEVINFO_REV_MAJ_S) | (_min))
  85773. +#define SAFE_REV_MAJ(_chiprev) \
  85774. + (((_chiprev) & SAFE_DEVINFO_REV_MAJ) >> SAFE_DEVINFO_REV_MAJ_S)
  85775. +#define SAFE_REV_MIN(_chiprev) ((_chiprev) & SAFE_DEVINFO_REV_MIN)
  85776. +
  85777. +#define SAFE_PK_FUNC_MULT 0x00000001 /* Multiply function */
  85778. +#define SAFE_PK_FUNC_SQUARE 0x00000004 /* Square function */
  85779. +#define SAFE_PK_FUNC_ADD 0x00000010 /* Add function */
  85780. +#define SAFE_PK_FUNC_SUB 0x00000020 /* Subtract function */
  85781. +#define SAFE_PK_FUNC_LSHIFT 0x00000040 /* Left-shift function */
  85782. +#define SAFE_PK_FUNC_RSHIFT 0x00000080 /* Right-shift function */
  85783. +#define SAFE_PK_FUNC_DIV 0x00000100 /* Divide function */
  85784. +#define SAFE_PK_FUNC_CMP 0x00000400 /* Compare function */
  85785. +#define SAFE_PK_FUNC_COPY 0x00000800 /* Copy function */
  85786. +#define SAFE_PK_FUNC_EXP16 0x00002000 /* Exponentiate (4-bit ACT) */
  85787. +#define SAFE_PK_FUNC_EXP4 0x00004000 /* Exponentiate (2-bit ACT) */
  85788. +#define SAFE_PK_FUNC_RUN 0x00008000 /* start/status */
  85789. +
  85790. +#define SAFE_RNG_STAT_BUSY 0x00000001 /* busy, data not valid */
  85791. +
  85792. +#define SAFE_RNG_CTRL_PRE_LFSR 0x00000001 /* enable output pre-LFSR */
  85793. +#define SAFE_RNG_CTRL_TST_MODE 0x00000002 /* enable test mode */
  85794. +#define SAFE_RNG_CTRL_TST_RUN 0x00000004 /* start test state machine */
  85795. +#define SAFE_RNG_CTRL_ENA_RING1 0x00000008 /* test entropy oscillator #1 */
  85796. +#define SAFE_RNG_CTRL_ENA_RING2 0x00000010 /* test entropy oscillator #2 */
  85797. +#define SAFE_RNG_CTRL_DIS_ALARM 0x00000020 /* disable RNG alarm reports */
  85798. +#define SAFE_RNG_CTRL_TST_CLOCK 0x00000040 /* enable test clock */
  85799. +#define SAFE_RNG_CTRL_SHORTEN 0x00000080 /* shorten state timers */
  85800. +#define SAFE_RNG_CTRL_TST_ALARM 0x00000100 /* simulate alarm state */
  85801. +#define SAFE_RNG_CTRL_RST_LFSR 0x00000200 /* reset LFSR */
  85802. +
  85803. +/*
  85804. + * Packet engine descriptor. Note that d_csr is a copy of the
  85805. + * SAFE_PE_CSR register and all definitions apply, and d_len
  85806. + * is a copy of the SAFE_PE_LEN register and all definitions apply.
  85807. + * d_src and d_len may point directly to contiguous data or to a
  85808. + * list of ``particle descriptors'' when using scatter/gather i/o.
  85809. + */
  85810. +struct safe_desc {
  85811. + u_int32_t d_csr; /* per-packet control/status */
  85812. + u_int32_t d_src; /* source address */
  85813. + u_int32_t d_dst; /* destination address */
  85814. + u_int32_t d_sa; /* SA address */
  85815. + u_int32_t d_len; /* length, bypass, status */
  85816. +};
  85817. +
  85818. +/*
  85819. + * Scatter/Gather particle descriptor.
  85820. + *
  85821. + * NB: scatter descriptors do not specify a size; this is fixed
  85822. + * by the setting of the SAFE_PE_PARTCFG register.
  85823. + */
  85824. +struct safe_pdesc {
  85825. + u_int32_t pd_addr; /* particle address */
  85826. +#ifdef __BIG_ENDIAN
  85827. + u_int16_t pd_flags; /* control word */
  85828. + u_int16_t pd_size; /* particle size (bytes) */
  85829. +#else
  85830. + u_int16_t pd_flags; /* control word */
  85831. + u_int16_t pd_size; /* particle size (bytes) */
  85832. +#endif
  85833. +};
  85834. +
  85835. +#define SAFE_PD_READY 0x0001 /* ready for processing */
  85836. +#define SAFE_PD_DONE 0x0002 /* h/w completed processing */
  85837. +
  85838. +/*
  85839. + * Security Association (SA) Record (Rev 1). One of these is
  85840. + * required for each operation processed by the packet engine.
  85841. + */
  85842. +struct safe_sarec {
  85843. + u_int32_t sa_cmd0;
  85844. + u_int32_t sa_cmd1;
  85845. + u_int32_t sa_resv0;
  85846. + u_int32_t sa_resv1;
  85847. + u_int32_t sa_key[8]; /* DES/3DES/AES key */
  85848. + u_int32_t sa_indigest[5]; /* inner digest */
  85849. + u_int32_t sa_outdigest[5]; /* outer digest */
  85850. + u_int32_t sa_spi; /* SPI */
  85851. + u_int32_t sa_seqnum; /* sequence number */
  85852. + u_int32_t sa_seqmask[2]; /* sequence number mask */
  85853. + u_int32_t sa_resv2;
  85854. + u_int32_t sa_staterec; /* address of state record */
  85855. + u_int32_t sa_resv3[2];
  85856. + u_int32_t sa_samgmt0; /* SA management field 0 */
  85857. + u_int32_t sa_samgmt1; /* SA management field 0 */
  85858. +};
  85859. +
  85860. +#define SAFE_SA_CMD0_OP 0x00000007 /* operation code */
  85861. +#define SAFE_SA_CMD0_OP_CRYPT 0x00000000 /* encrypt/decrypt (basic) */
  85862. +#define SAFE_SA_CMD0_OP_BOTH 0x00000001 /* encrypt-hash/hash-decrypto */
  85863. +#define SAFE_SA_CMD0_OP_HASH 0x00000003 /* hash (outbound-only) */
  85864. +#define SAFE_SA_CMD0_OP_ESP 0x00000000 /* ESP in/out (proto) */
  85865. +#define SAFE_SA_CMD0_OP_AH 0x00000001 /* AH in/out (proto) */
  85866. +#define SAFE_SA_CMD0_INBOUND 0x00000008 /* inbound operation */
  85867. +#define SAFE_SA_CMD0_OUTBOUND 0x00000000 /* outbound operation */
  85868. +#define SAFE_SA_CMD0_GROUP 0x00000030 /* operation group */
  85869. +#define SAFE_SA_CMD0_BASIC 0x00000000 /* basic operation */
  85870. +#define SAFE_SA_CMD0_PROTO 0x00000010 /* protocol/packet operation */
  85871. +#define SAFE_SA_CMD0_BUNDLE 0x00000020 /* bundled operation (resvd) */
  85872. +#define SAFE_SA_CMD0_PAD 0x000000c0 /* crypto pad method */
  85873. +#define SAFE_SA_CMD0_PAD_IPSEC 0x00000000 /* IPsec padding */
  85874. +#define SAFE_SA_CMD0_PAD_PKCS7 0x00000040 /* PKCS#7 padding */
  85875. +#define SAFE_SA_CMD0_PAD_CONS 0x00000080 /* constant padding */
  85876. +#define SAFE_SA_CMD0_PAD_ZERO 0x000000c0 /* zero padding */
  85877. +#define SAFE_SA_CMD0_CRYPT_ALG 0x00000f00 /* symmetric crypto algorithm */
  85878. +#define SAFE_SA_CMD0_DES 0x00000000 /* DES crypto algorithm */
  85879. +#define SAFE_SA_CMD0_3DES 0x00000100 /* 3DES crypto algorithm */
  85880. +#define SAFE_SA_CMD0_AES 0x00000300 /* AES crypto algorithm */
  85881. +#define SAFE_SA_CMD0_CRYPT_NULL 0x00000f00 /* null crypto algorithm */
  85882. +#define SAFE_SA_CMD0_HASH_ALG 0x0000f000 /* hash algorithm */
  85883. +#define SAFE_SA_CMD0_MD5 0x00000000 /* MD5 hash algorithm */
  85884. +#define SAFE_SA_CMD0_SHA1 0x00001000 /* SHA-1 hash algorithm */
  85885. +#define SAFE_SA_CMD0_HASH_NULL 0x0000f000 /* null hash algorithm */
  85886. +#define SAFE_SA_CMD0_HDR_PROC 0x00080000 /* header processing */
  85887. +#define SAFE_SA_CMD0_IBUSID 0x00300000 /* input bus id */
  85888. +#define SAFE_SA_CMD0_IPCI 0x00100000 /* PCI input bus id */
  85889. +#define SAFE_SA_CMD0_OBUSID 0x00c00000 /* output bus id */
  85890. +#define SAFE_SA_CMD0_OPCI 0x00400000 /* PCI output bus id */
  85891. +#define SAFE_SA_CMD0_IVLD 0x03000000 /* IV loading */
  85892. +#define SAFE_SA_CMD0_IVLD_NONE 0x00000000 /* IV no load (reuse) */
  85893. +#define SAFE_SA_CMD0_IVLD_IBUF 0x01000000 /* IV load from input buffer */
  85894. +#define SAFE_SA_CMD0_IVLD_STATE 0x02000000 /* IV load from state */
  85895. +#define SAFE_SA_CMD0_HSLD 0x0c000000 /* hash state loading */
  85896. +#define SAFE_SA_CMD0_HSLD_SA 0x00000000 /* hash state load from SA */
  85897. +#define SAFE_SA_CMD0_HSLD_STATE 0x08000000 /* hash state load from state */
  85898. +#define SAFE_SA_CMD0_HSLD_NONE 0x0c000000 /* hash state no load */
  85899. +#define SAFE_SA_CMD0_SAVEIV 0x10000000 /* save IV */
  85900. +#define SAFE_SA_CMD0_SAVEHASH 0x20000000 /* save hash state */
  85901. +#define SAFE_SA_CMD0_IGATHER 0x40000000 /* input gather */
  85902. +#define SAFE_SA_CMD0_OSCATTER 0x80000000 /* output scatter */
  85903. +
  85904. +#define SAFE_SA_CMD1_HDRCOPY 0x00000002 /* copy header to output */
  85905. +#define SAFE_SA_CMD1_PAYCOPY 0x00000004 /* copy payload to output */
  85906. +#define SAFE_SA_CMD1_PADCOPY 0x00000008 /* copy pad to output */
  85907. +#define SAFE_SA_CMD1_IPV4 0x00000000 /* IPv4 protocol */
  85908. +#define SAFE_SA_CMD1_IPV6 0x00000010 /* IPv6 protocol */
  85909. +#define SAFE_SA_CMD1_MUTABLE 0x00000020 /* mutable bit processing */
  85910. +#define SAFE_SA_CMD1_SRBUSID 0x000000c0 /* state record bus id */
  85911. +#define SAFE_SA_CMD1_SRPCI 0x00000040 /* state record from PCI */
  85912. +#define SAFE_SA_CMD1_CRMODE 0x00000300 /* crypto mode */
  85913. +#define SAFE_SA_CMD1_ECB 0x00000000 /* ECB crypto mode */
  85914. +#define SAFE_SA_CMD1_CBC 0x00000100 /* CBC crypto mode */
  85915. +#define SAFE_SA_CMD1_OFB 0x00000200 /* OFB crypto mode */
  85916. +#define SAFE_SA_CMD1_CFB 0x00000300 /* CFB crypto mode */
  85917. +#define SAFE_SA_CMD1_CRFEEDBACK 0x00000c00 /* crypto feedback mode */
  85918. +#define SAFE_SA_CMD1_64BIT 0x00000000 /* 64-bit crypto feedback */
  85919. +#define SAFE_SA_CMD1_8BIT 0x00000400 /* 8-bit crypto feedback */
  85920. +#define SAFE_SA_CMD1_1BIT 0x00000800 /* 1-bit crypto feedback */
  85921. +#define SAFE_SA_CMD1_128BIT 0x00000c00 /* 128-bit crypto feedback */
  85922. +#define SAFE_SA_CMD1_OPTIONS 0x00001000 /* HMAC/options mutable bit */
  85923. +#define SAFE_SA_CMD1_HMAC SAFE_SA_CMD1_OPTIONS
  85924. +#define SAFE_SA_CMD1_SAREV1 0x00008000 /* SA Revision 1 */
  85925. +#define SAFE_SA_CMD1_OFFSET 0x00ff0000 /* hash/crypto offset(dwords) */
  85926. +#define SAFE_SA_CMD1_OFFSET_S 16
  85927. +#define SAFE_SA_CMD1_AESKEYLEN 0x0f000000 /* AES key length */
  85928. +#define SAFE_SA_CMD1_AES128 0x02000000 /* 128-bit AES key */
  85929. +#define SAFE_SA_CMD1_AES192 0x03000000 /* 192-bit AES key */
  85930. +#define SAFE_SA_CMD1_AES256 0x04000000 /* 256-bit AES key */
  85931. +
  85932. +/*
  85933. + * Security Associate State Record (Rev 1).
  85934. + */
  85935. +struct safe_sastate {
  85936. + u_int32_t sa_saved_iv[4]; /* saved IV (DES/3DES/AES) */
  85937. + u_int32_t sa_saved_hashbc; /* saved hash byte count */
  85938. + u_int32_t sa_saved_indigest[5]; /* saved inner digest */
  85939. +};
  85940. +#endif /* _SAFE_SAFEREG_H_ */
  85941. diff -Nur linux-2.6.39.orig/crypto/ocf/safe/safevar.h linux-2.6.39/crypto/ocf/safe/safevar.h
  85942. --- linux-2.6.39.orig/crypto/ocf/safe/safevar.h 1970-01-01 01:00:00.000000000 +0100
  85943. +++ linux-2.6.39/crypto/ocf/safe/safevar.h 2011-08-01 14:38:19.000000000 +0200
  85944. @@ -0,0 +1,230 @@
  85945. +/*-
  85946. + * The linux port of this code done by David McCullough
  85947. + * Copyright (C) 2004-2010 David McCullough <david_mccullough@mcafee.com>
  85948. + * The license and original author are listed below.
  85949. + *
  85950. + * Copyright (c) 2003 Sam Leffler, Errno Consulting
  85951. + * Copyright (c) 2003 Global Technology Associates, Inc.
  85952. + * All rights reserved.
  85953. + *
  85954. + * Redistribution and use in source and binary forms, with or without
  85955. + * modification, are permitted provided that the following conditions
  85956. + * are met:
  85957. + * 1. Redistributions of source code must retain the above copyright
  85958. + * notice, this list of conditions and the following disclaimer.
  85959. + * 2. Redistributions in binary form must reproduce the above copyright
  85960. + * notice, this list of conditions and the following disclaimer in the
  85961. + * documentation and/or other materials provided with the distribution.
  85962. + *
  85963. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  85964. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  85965. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  85966. + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  85967. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  85968. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  85969. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  85970. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  85971. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  85972. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  85973. + * SUCH DAMAGE.
  85974. + *
  85975. + * $FreeBSD: src/sys/dev/safe/safevar.h,v 1.2 2006/05/17 18:34:26 pjd Exp $
  85976. + */
  85977. +#ifndef _SAFE_SAFEVAR_H_
  85978. +#define _SAFE_SAFEVAR_H_
  85979. +
  85980. +/* Maximum queue length */
  85981. +#ifndef SAFE_MAX_NQUEUE
  85982. +#define SAFE_MAX_NQUEUE 60
  85983. +#endif
  85984. +
  85985. +#define SAFE_MAX_PART 64 /* Maximum scatter/gather depth */
  85986. +#define SAFE_DMA_BOUNDARY 0 /* No boundary for source DMA ops */
  85987. +#define SAFE_MAX_DSIZE 2048 /* MCLBYTES Fixed scatter particle size */
  85988. +#define SAFE_MAX_SSIZE 0x0ffff /* Maximum gather particle size */
  85989. +#define SAFE_MAX_DMA 0xfffff /* Maximum PE operand size (20 bits) */
  85990. +/* total src+dst particle descriptors */
  85991. +#define SAFE_TOTAL_DPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART)
  85992. +#define SAFE_TOTAL_SPART (SAFE_MAX_NQUEUE * SAFE_MAX_PART)
  85993. +
  85994. +#define SAFE_RNG_MAXBUFSIZ 128 /* 32-bit words */
  85995. +
  85996. +#define SAFE_CARD(sid) (((sid) & 0xf0000000) >> 28)
  85997. +#define SAFE_SESSION(sid) ( (sid) & 0x0fffffff)
  85998. +#define SAFE_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))
  85999. +
  86000. +#define SAFE_DEF_RTY 0xff /* PCI Retry Timeout */
  86001. +#define SAFE_DEF_TOUT 0xff /* PCI TRDY Timeout */
  86002. +#define SAFE_DEF_CACHELINE 0x01 /* Cache Line setting */
  86003. +
  86004. +#ifdef __KERNEL__
  86005. +/*
  86006. + * State associated with the allocation of each chunk
  86007. + * of memory setup for DMA.
  86008. + */
  86009. +struct safe_dma_alloc {
  86010. + dma_addr_t dma_paddr;
  86011. + void *dma_vaddr;
  86012. +};
  86013. +
  86014. +/*
  86015. + * Cryptographic operand state. One of these exists for each
  86016. + * source and destination operand passed in from the crypto
  86017. + * subsystem. When possible source and destination operands
  86018. + * refer to the same memory. More often they are distinct.
  86019. + * We track the virtual address of each operand as well as
  86020. + * where each is mapped for DMA.
  86021. + */
  86022. +struct safe_operand {
  86023. + union {
  86024. + struct sk_buff *skb;
  86025. + struct uio *io;
  86026. + } u;
  86027. + void *map;
  86028. + int mapsize; /* total number of bytes in segs */
  86029. + struct {
  86030. + dma_addr_t ds_addr;
  86031. + int ds_len;
  86032. + int ds_tlen;
  86033. + } segs[SAFE_MAX_PART];
  86034. + int nsegs;
  86035. +};
  86036. +
  86037. +/*
  86038. + * Packet engine ring entry and cryptographic operation state.
  86039. + * The packet engine requires a ring of descriptors that contain
  86040. + * pointers to various cryptographic state. However the ring
  86041. + * configuration register allows you to specify an arbitrary size
  86042. + * for ring entries. We use this feature to collect most of the
  86043. + * state for each cryptographic request into one spot. Other than
  86044. + * ring entries only the ``particle descriptors'' (scatter/gather
  86045. + * lists) and the actual operand data are kept separate. The
  86046. + * particle descriptors must also be organized in rings. The
  86047. + * operand data can be located aribtrarily (modulo alignment constraints).
  86048. + *
  86049. + * Note that the descriptor ring is mapped onto the PCI bus so
  86050. + * the hardware can DMA data. This means the entire ring must be
  86051. + * contiguous.
  86052. + */
  86053. +struct safe_ringentry {
  86054. + struct safe_desc re_desc; /* command descriptor */
  86055. + struct safe_sarec re_sa; /* SA record */
  86056. + struct safe_sastate re_sastate; /* SA state record */
  86057. +
  86058. + struct cryptop *re_crp; /* crypto operation */
  86059. +
  86060. + struct safe_operand re_src; /* source operand */
  86061. + struct safe_operand re_dst; /* destination operand */
  86062. +
  86063. + int re_sesn; /* crypto session ID */
  86064. + int re_flags;
  86065. +#define SAFE_QFLAGS_COPYOUTIV 0x1 /* copy back on completion */
  86066. +#define SAFE_QFLAGS_COPYOUTICV 0x2 /* copy back on completion */
  86067. +};
  86068. +
  86069. +#define re_src_skb re_src.u.skb
  86070. +#define re_src_io re_src.u.io
  86071. +#define re_src_map re_src.map
  86072. +#define re_src_nsegs re_src.nsegs
  86073. +#define re_src_segs re_src.segs
  86074. +#define re_src_mapsize re_src.mapsize
  86075. +
  86076. +#define re_dst_skb re_dst.u.skb
  86077. +#define re_dst_io re_dst.u.io
  86078. +#define re_dst_map re_dst.map
  86079. +#define re_dst_nsegs re_dst.nsegs
  86080. +#define re_dst_segs re_dst.segs
  86081. +#define re_dst_mapsize re_dst.mapsize
  86082. +
  86083. +struct rndstate_test;
  86084. +
  86085. +struct safe_session {
  86086. + u_int32_t ses_used;
  86087. + u_int32_t ses_klen; /* key length in bits */
  86088. + u_int32_t ses_key[8]; /* DES/3DES/AES key */
  86089. + u_int32_t ses_mlen; /* hmac length in bytes */
  86090. + u_int32_t ses_hminner[5]; /* hmac inner state */
  86091. + u_int32_t ses_hmouter[5]; /* hmac outer state */
  86092. + u_int32_t ses_iv[4]; /* DES/3DES/AES iv */
  86093. +};
  86094. +
  86095. +struct safe_pkq {
  86096. + struct list_head pkq_list;
  86097. + struct cryptkop *pkq_krp;
  86098. +};
  86099. +
  86100. +struct safe_softc {
  86101. + softc_device_decl sc_dev;
  86102. + u32 sc_irq;
  86103. +
  86104. + struct pci_dev *sc_pcidev;
  86105. + ocf_iomem_t sc_base_addr;
  86106. +
  86107. + u_int sc_chiprev; /* major/minor chip revision */
  86108. + int sc_flags; /* device specific flags */
  86109. +#define SAFE_FLAGS_KEY 0x01 /* has key accelerator */
  86110. +#define SAFE_FLAGS_RNG 0x02 /* hardware rng */
  86111. + int sc_suspended;
  86112. + int sc_needwakeup; /* notify crypto layer */
  86113. + int32_t sc_cid; /* crypto tag */
  86114. +
  86115. + struct safe_dma_alloc sc_ringalloc; /* PE ring allocation state */
  86116. + struct safe_ringentry *sc_ring; /* PE ring */
  86117. + struct safe_ringentry *sc_ringtop; /* PE ring top */
  86118. + struct safe_ringentry *sc_front; /* next free entry */
  86119. + struct safe_ringentry *sc_back; /* next pending entry */
  86120. + int sc_nqchip; /* # passed to chip */
  86121. + spinlock_t sc_ringmtx; /* PE ring lock */
  86122. + struct safe_pdesc *sc_spring; /* src particle ring */
  86123. + struct safe_pdesc *sc_springtop; /* src particle ring top */
  86124. + struct safe_pdesc *sc_spfree; /* next free src particle */
  86125. + struct safe_dma_alloc sc_spalloc; /* src particle ring state */
  86126. + struct safe_pdesc *sc_dpring; /* dest particle ring */
  86127. + struct safe_pdesc *sc_dpringtop; /* dest particle ring top */
  86128. + struct safe_pdesc *sc_dpfree; /* next free dest particle */
  86129. + struct safe_dma_alloc sc_dpalloc; /* dst particle ring state */
  86130. + int sc_nsessions; /* # of sessions */
  86131. + struct safe_session *sc_sessions; /* sessions */
  86132. +
  86133. + struct timer_list sc_pkto; /* PK polling */
  86134. + spinlock_t sc_pkmtx; /* PK lock */
  86135. + struct list_head sc_pkq; /* queue of PK requests */
  86136. + struct safe_pkq *sc_pkq_cur; /* current processing request */
  86137. + u_int32_t sc_pk_reslen, sc_pk_resoff;
  86138. +
  86139. + int sc_max_dsize; /* maximum safe DMA size */
  86140. +};
  86141. +#endif /* __KERNEL__ */
  86142. +
  86143. +struct safe_stats {
  86144. + u_int64_t st_ibytes;
  86145. + u_int64_t st_obytes;
  86146. + u_int32_t st_ipackets;
  86147. + u_int32_t st_opackets;
  86148. + u_int32_t st_invalid; /* invalid argument */
  86149. + u_int32_t st_badsession; /* invalid session id */
  86150. + u_int32_t st_badflags; /* flags indicate !(mbuf | uio) */
  86151. + u_int32_t st_nodesc; /* op submitted w/o descriptors */
  86152. + u_int32_t st_badalg; /* unsupported algorithm */
  86153. + u_int32_t st_ringfull; /* PE descriptor ring full */
  86154. + u_int32_t st_peoperr; /* PE marked error */
  86155. + u_int32_t st_dmaerr; /* PE DMA error */
  86156. + u_int32_t st_bypasstoobig; /* bypass > 96 bytes */
  86157. + u_int32_t st_skipmismatch; /* enc part begins before auth part */
  86158. + u_int32_t st_lenmismatch; /* enc length different auth length */
  86159. + u_int32_t st_coffmisaligned; /* crypto offset not 32-bit aligned */
  86160. + u_int32_t st_cofftoobig; /* crypto offset > 255 words */
  86161. + u_int32_t st_iovmisaligned; /* iov op not aligned */
  86162. + u_int32_t st_iovnotuniform; /* iov op not suitable */
  86163. + u_int32_t st_unaligned; /* unaligned src caused copy */
  86164. + u_int32_t st_notuniform; /* non-uniform src caused copy */
  86165. + u_int32_t st_nomap; /* bus_dmamap_create failed */
  86166. + u_int32_t st_noload; /* bus_dmamap_load_* failed */
  86167. + u_int32_t st_nombuf; /* MGET* failed */
  86168. + u_int32_t st_nomcl; /* MCLGET* failed */
  86169. + u_int32_t st_maxqchip; /* max mcr1 ops out for processing */
  86170. + u_int32_t st_rng; /* RNG requests */
  86171. + u_int32_t st_rngalarm; /* RNG alarm requests */
  86172. + u_int32_t st_noicvcopy; /* ICV data copies suppressed */
  86173. +};
  86174. +#endif /* _SAFE_SAFEVAR_H_ */
  86175. diff -Nur linux-2.6.39.orig/crypto/ocf/safe/sha1.c linux-2.6.39/crypto/ocf/safe/sha1.c
  86176. --- linux-2.6.39.orig/crypto/ocf/safe/sha1.c 1970-01-01 01:00:00.000000000 +0100
  86177. +++ linux-2.6.39/crypto/ocf/safe/sha1.c 2011-08-01 14:38:19.000000000 +0200
  86178. @@ -0,0 +1,279 @@
  86179. +/* $KAME: sha1.c,v 1.5 2000/11/08 06:13:08 itojun Exp $ */
  86180. +/*
  86181. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  86182. + * All rights reserved.
  86183. + *
  86184. + * Redistribution and use in source and binary forms, with or without
  86185. + * modification, are permitted provided that the following conditions
  86186. + * are met:
  86187. + * 1. Redistributions of source code must retain the above copyright
  86188. + * notice, this list of conditions and the following disclaimer.
  86189. + * 2. Redistributions in binary form must reproduce the above copyright
  86190. + * notice, this list of conditions and the following disclaimer in the
  86191. + * documentation and/or other materials provided with the distribution.
  86192. + * 3. Neither the name of the project nor the names of its contributors
  86193. + * may be used to endorse or promote products derived from this software
  86194. + * without specific prior written permission.
  86195. + *
  86196. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  86197. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  86198. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  86199. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  86200. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  86201. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  86202. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  86203. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  86204. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  86205. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  86206. + * SUCH DAMAGE.
  86207. + */
  86208. +
  86209. +/*
  86210. + * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
  86211. + * based on: http://csrc.nist.gov/fips/fip180-1.txt
  86212. + * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
  86213. + */
  86214. +
  86215. +#if 0
  86216. +#include <sys/cdefs.h>
  86217. +__FBSDID("$FreeBSD: src/sys/crypto/sha1.c,v 1.9 2003/06/10 21:36:57 obrien Exp $");
  86218. +
  86219. +#include <sys/types.h>
  86220. +#include <sys/cdefs.h>
  86221. +#include <sys/time.h>
  86222. +#include <sys/systm.h>
  86223. +
  86224. +#include <crypto/sha1.h>
  86225. +#endif
  86226. +
  86227. +/* sanity check */
  86228. +#if BYTE_ORDER != BIG_ENDIAN
  86229. +# if BYTE_ORDER != LITTLE_ENDIAN
  86230. +# define unsupported 1
  86231. +# endif
  86232. +#endif
  86233. +
  86234. +#ifndef unsupported
  86235. +
  86236. +/* constant table */
  86237. +static u_int32_t _K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 };
  86238. +#define K(t) _K[(t) / 20]
  86239. +
  86240. +#define F0(b, c, d) (((b) & (c)) | ((~(b)) & (d)))
  86241. +#define F1(b, c, d) (((b) ^ (c)) ^ (d))
  86242. +#define F2(b, c, d) (((b) & (c)) | ((b) & (d)) | ((c) & (d)))
  86243. +#define F3(b, c, d) (((b) ^ (c)) ^ (d))
  86244. +
  86245. +#define S(n, x) (((x) << (n)) | ((x) >> (32 - n)))
  86246. +
  86247. +#undef H
  86248. +#define H(n) (ctxt->h.b32[(n)])
  86249. +#define COUNT (ctxt->count)
  86250. +#define BCOUNT (ctxt->c.b64[0] / 8)
  86251. +#define W(n) (ctxt->m.b32[(n)])
  86252. +
  86253. +#define PUTBYTE(x) { \
  86254. + ctxt->m.b8[(COUNT % 64)] = (x); \
  86255. + COUNT++; \
  86256. + COUNT %= 64; \
  86257. + ctxt->c.b64[0] += 8; \
  86258. + if (COUNT % 64 == 0) \
  86259. + sha1_step(ctxt); \
  86260. + }
  86261. +
  86262. +#define PUTPAD(x) { \
  86263. + ctxt->m.b8[(COUNT % 64)] = (x); \
  86264. + COUNT++; \
  86265. + COUNT %= 64; \
  86266. + if (COUNT % 64 == 0) \
  86267. + sha1_step(ctxt); \
  86268. + }
  86269. +
  86270. +static void sha1_step(struct sha1_ctxt *);
  86271. +
  86272. +static void
  86273. +sha1_step(ctxt)
  86274. + struct sha1_ctxt *ctxt;
  86275. +{
  86276. + u_int32_t a, b, c, d, e;
  86277. + size_t t, s;
  86278. + u_int32_t tmp;
  86279. +
  86280. +#if BYTE_ORDER == LITTLE_ENDIAN
  86281. + struct sha1_ctxt tctxt;
  86282. + bcopy(&ctxt->m.b8[0], &tctxt.m.b8[0], 64);
  86283. + ctxt->m.b8[0] = tctxt.m.b8[3]; ctxt->m.b8[1] = tctxt.m.b8[2];
  86284. + ctxt->m.b8[2] = tctxt.m.b8[1]; ctxt->m.b8[3] = tctxt.m.b8[0];
  86285. + ctxt->m.b8[4] = tctxt.m.b8[7]; ctxt->m.b8[5] = tctxt.m.b8[6];
  86286. + ctxt->m.b8[6] = tctxt.m.b8[5]; ctxt->m.b8[7] = tctxt.m.b8[4];
  86287. + ctxt->m.b8[8] = tctxt.m.b8[11]; ctxt->m.b8[9] = tctxt.m.b8[10];
  86288. + ctxt->m.b8[10] = tctxt.m.b8[9]; ctxt->m.b8[11] = tctxt.m.b8[8];
  86289. + ctxt->m.b8[12] = tctxt.m.b8[15]; ctxt->m.b8[13] = tctxt.m.b8[14];
  86290. + ctxt->m.b8[14] = tctxt.m.b8[13]; ctxt->m.b8[15] = tctxt.m.b8[12];
  86291. + ctxt->m.b8[16] = tctxt.m.b8[19]; ctxt->m.b8[17] = tctxt.m.b8[18];
  86292. + ctxt->m.b8[18] = tctxt.m.b8[17]; ctxt->m.b8[19] = tctxt.m.b8[16];
  86293. + ctxt->m.b8[20] = tctxt.m.b8[23]; ctxt->m.b8[21] = tctxt.m.b8[22];
  86294. + ctxt->m.b8[22] = tctxt.m.b8[21]; ctxt->m.b8[23] = tctxt.m.b8[20];
  86295. + ctxt->m.b8[24] = tctxt.m.b8[27]; ctxt->m.b8[25] = tctxt.m.b8[26];
  86296. + ctxt->m.b8[26] = tctxt.m.b8[25]; ctxt->m.b8[27] = tctxt.m.b8[24];
  86297. + ctxt->m.b8[28] = tctxt.m.b8[31]; ctxt->m.b8[29] = tctxt.m.b8[30];
  86298. + ctxt->m.b8[30] = tctxt.m.b8[29]; ctxt->m.b8[31] = tctxt.m.b8[28];
  86299. + ctxt->m.b8[32] = tctxt.m.b8[35]; ctxt->m.b8[33] = tctxt.m.b8[34];
  86300. + ctxt->m.b8[34] = tctxt.m.b8[33]; ctxt->m.b8[35] = tctxt.m.b8[32];
  86301. + ctxt->m.b8[36] = tctxt.m.b8[39]; ctxt->m.b8[37] = tctxt.m.b8[38];
  86302. + ctxt->m.b8[38] = tctxt.m.b8[37]; ctxt->m.b8[39] = tctxt.m.b8[36];
  86303. + ctxt->m.b8[40] = tctxt.m.b8[43]; ctxt->m.b8[41] = tctxt.m.b8[42];
  86304. + ctxt->m.b8[42] = tctxt.m.b8[41]; ctxt->m.b8[43] = tctxt.m.b8[40];
  86305. + ctxt->m.b8[44] = tctxt.m.b8[47]; ctxt->m.b8[45] = tctxt.m.b8[46];
  86306. + ctxt->m.b8[46] = tctxt.m.b8[45]; ctxt->m.b8[47] = tctxt.m.b8[44];
  86307. + ctxt->m.b8[48] = tctxt.m.b8[51]; ctxt->m.b8[49] = tctxt.m.b8[50];
  86308. + ctxt->m.b8[50] = tctxt.m.b8[49]; ctxt->m.b8[51] = tctxt.m.b8[48];
  86309. + ctxt->m.b8[52] = tctxt.m.b8[55]; ctxt->m.b8[53] = tctxt.m.b8[54];
  86310. + ctxt->m.b8[54] = tctxt.m.b8[53]; ctxt->m.b8[55] = tctxt.m.b8[52];
  86311. + ctxt->m.b8[56] = tctxt.m.b8[59]; ctxt->m.b8[57] = tctxt.m.b8[58];
  86312. + ctxt->m.b8[58] = tctxt.m.b8[57]; ctxt->m.b8[59] = tctxt.m.b8[56];
  86313. + ctxt->m.b8[60] = tctxt.m.b8[63]; ctxt->m.b8[61] = tctxt.m.b8[62];
  86314. + ctxt->m.b8[62] = tctxt.m.b8[61]; ctxt->m.b8[63] = tctxt.m.b8[60];
  86315. +#endif
  86316. +
  86317. + a = H(0); b = H(1); c = H(2); d = H(3); e = H(4);
  86318. +
  86319. + for (t = 0; t < 20; t++) {
  86320. + s = t & 0x0f;
  86321. + if (t >= 16) {
  86322. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  86323. + }
  86324. + tmp = S(5, a) + F0(b, c, d) + e + W(s) + K(t);
  86325. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  86326. + }
  86327. + for (t = 20; t < 40; t++) {
  86328. + s = t & 0x0f;
  86329. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  86330. + tmp = S(5, a) + F1(b, c, d) + e + W(s) + K(t);
  86331. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  86332. + }
  86333. + for (t = 40; t < 60; t++) {
  86334. + s = t & 0x0f;
  86335. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  86336. + tmp = S(5, a) + F2(b, c, d) + e + W(s) + K(t);
  86337. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  86338. + }
  86339. + for (t = 60; t < 80; t++) {
  86340. + s = t & 0x0f;
  86341. + W(s) = S(1, W((s+13) & 0x0f) ^ W((s+8) & 0x0f) ^ W((s+2) & 0x0f) ^ W(s));
  86342. + tmp = S(5, a) + F3(b, c, d) + e + W(s) + K(t);
  86343. + e = d; d = c; c = S(30, b); b = a; a = tmp;
  86344. + }
  86345. +
  86346. + H(0) = H(0) + a;
  86347. + H(1) = H(1) + b;
  86348. + H(2) = H(2) + c;
  86349. + H(3) = H(3) + d;
  86350. + H(4) = H(4) + e;
  86351. +
  86352. + bzero(&ctxt->m.b8[0], 64);
  86353. +}
  86354. +
  86355. +/*------------------------------------------------------------*/
  86356. +
  86357. +void
  86358. +sha1_init(ctxt)
  86359. + struct sha1_ctxt *ctxt;
  86360. +{
  86361. + bzero(ctxt, sizeof(struct sha1_ctxt));
  86362. + H(0) = 0x67452301;
  86363. + H(1) = 0xefcdab89;
  86364. + H(2) = 0x98badcfe;
  86365. + H(3) = 0x10325476;
  86366. + H(4) = 0xc3d2e1f0;
  86367. +}
  86368. +
  86369. +void
  86370. +sha1_pad(ctxt)
  86371. + struct sha1_ctxt *ctxt;
  86372. +{
  86373. + size_t padlen; /*pad length in bytes*/
  86374. + size_t padstart;
  86375. +
  86376. + PUTPAD(0x80);
  86377. +
  86378. + padstart = COUNT % 64;
  86379. + padlen = 64 - padstart;
  86380. + if (padlen < 8) {
  86381. + bzero(&ctxt->m.b8[padstart], padlen);
  86382. + COUNT += padlen;
  86383. + COUNT %= 64;
  86384. + sha1_step(ctxt);
  86385. + padstart = COUNT % 64; /* should be 0 */
  86386. + padlen = 64 - padstart; /* should be 64 */
  86387. + }
  86388. + bzero(&ctxt->m.b8[padstart], padlen - 8);
  86389. + COUNT += (padlen - 8);
  86390. + COUNT %= 64;
  86391. +#if BYTE_ORDER == BIG_ENDIAN
  86392. + PUTPAD(ctxt->c.b8[0]); PUTPAD(ctxt->c.b8[1]);
  86393. + PUTPAD(ctxt->c.b8[2]); PUTPAD(ctxt->c.b8[3]);
  86394. + PUTPAD(ctxt->c.b8[4]); PUTPAD(ctxt->c.b8[5]);
  86395. + PUTPAD(ctxt->c.b8[6]); PUTPAD(ctxt->c.b8[7]);
  86396. +#else
  86397. + PUTPAD(ctxt->c.b8[7]); PUTPAD(ctxt->c.b8[6]);
  86398. + PUTPAD(ctxt->c.b8[5]); PUTPAD(ctxt->c.b8[4]);
  86399. + PUTPAD(ctxt->c.b8[3]); PUTPAD(ctxt->c.b8[2]);
  86400. + PUTPAD(ctxt->c.b8[1]); PUTPAD(ctxt->c.b8[0]);
  86401. +#endif
  86402. +}
  86403. +
  86404. +void
  86405. +sha1_loop(ctxt, input, len)
  86406. + struct sha1_ctxt *ctxt;
  86407. + const u_int8_t *input;
  86408. + size_t len;
  86409. +{
  86410. + size_t gaplen;
  86411. + size_t gapstart;
  86412. + size_t off;
  86413. + size_t copysiz;
  86414. +
  86415. + off = 0;
  86416. +
  86417. + while (off < len) {
  86418. + gapstart = COUNT % 64;
  86419. + gaplen = 64 - gapstart;
  86420. +
  86421. + copysiz = (gaplen < len - off) ? gaplen : len - off;
  86422. + bcopy(&input[off], &ctxt->m.b8[gapstart], copysiz);
  86423. + COUNT += copysiz;
  86424. + COUNT %= 64;
  86425. + ctxt->c.b64[0] += copysiz * 8;
  86426. + if (COUNT % 64 == 0)
  86427. + sha1_step(ctxt);
  86428. + off += copysiz;
  86429. + }
  86430. +}
  86431. +
  86432. +void
  86433. +sha1_result(ctxt, digest0)
  86434. + struct sha1_ctxt *ctxt;
  86435. + caddr_t digest0;
  86436. +{
  86437. + u_int8_t *digest;
  86438. +
  86439. + digest = (u_int8_t *)digest0;
  86440. + sha1_pad(ctxt);
  86441. +#if BYTE_ORDER == BIG_ENDIAN
  86442. + bcopy(&ctxt->h.b8[0], digest, 20);
  86443. +#else
  86444. + digest[0] = ctxt->h.b8[3]; digest[1] = ctxt->h.b8[2];
  86445. + digest[2] = ctxt->h.b8[1]; digest[3] = ctxt->h.b8[0];
  86446. + digest[4] = ctxt->h.b8[7]; digest[5] = ctxt->h.b8[6];
  86447. + digest[6] = ctxt->h.b8[5]; digest[7] = ctxt->h.b8[4];
  86448. + digest[8] = ctxt->h.b8[11]; digest[9] = ctxt->h.b8[10];
  86449. + digest[10] = ctxt->h.b8[9]; digest[11] = ctxt->h.b8[8];
  86450. + digest[12] = ctxt->h.b8[15]; digest[13] = ctxt->h.b8[14];
  86451. + digest[14] = ctxt->h.b8[13]; digest[15] = ctxt->h.b8[12];
  86452. + digest[16] = ctxt->h.b8[19]; digest[17] = ctxt->h.b8[18];
  86453. + digest[18] = ctxt->h.b8[17]; digest[19] = ctxt->h.b8[16];
  86454. +#endif
  86455. +}
  86456. +
  86457. +#endif /*unsupported*/
  86458. diff -Nur linux-2.6.39.orig/crypto/ocf/safe/sha1.h linux-2.6.39/crypto/ocf/safe/sha1.h
  86459. --- linux-2.6.39.orig/crypto/ocf/safe/sha1.h 1970-01-01 01:00:00.000000000 +0100
  86460. +++ linux-2.6.39/crypto/ocf/safe/sha1.h 2011-08-01 14:38:19.000000000 +0200
  86461. @@ -0,0 +1,72 @@
  86462. +/* $FreeBSD: src/sys/crypto/sha1.h,v 1.8 2002/03/20 05:13:50 alfred Exp $ */
  86463. +/* $KAME: sha1.h,v 1.5 2000/03/27 04:36:23 sumikawa Exp $ */
  86464. +
  86465. +/*
  86466. + * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  86467. + * All rights reserved.
  86468. + *
  86469. + * Redistribution and use in source and binary forms, with or without
  86470. + * modification, are permitted provided that the following conditions
  86471. + * are met:
  86472. + * 1. Redistributions of source code must retain the above copyright
  86473. + * notice, this list of conditions and the following disclaimer.
  86474. + * 2. Redistributions in binary form must reproduce the above copyright
  86475. + * notice, this list of conditions and the following disclaimer in the
  86476. + * documentation and/or other materials provided with the distribution.
  86477. + * 3. Neither the name of the project nor the names of its contributors
  86478. + * may be used to endorse or promote products derived from this software
  86479. + * without specific prior written permission.
  86480. + *
  86481. + * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  86482. + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  86483. + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  86484. + * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  86485. + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  86486. + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  86487. + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  86488. + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  86489. + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  86490. + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  86491. + * SUCH DAMAGE.
  86492. + */
  86493. +/*
  86494. + * FIPS pub 180-1: Secure Hash Algorithm (SHA-1)
  86495. + * based on: http://csrc.nist.gov/fips/fip180-1.txt
  86496. + * implemented by Jun-ichiro itojun Itoh <itojun@itojun.org>
  86497. + */
  86498. +
  86499. +#ifndef _NETINET6_SHA1_H_
  86500. +#define _NETINET6_SHA1_H_
  86501. +
  86502. +struct sha1_ctxt {
  86503. + union {
  86504. + u_int8_t b8[20];
  86505. + u_int32_t b32[5];
  86506. + } h;
  86507. + union {
  86508. + u_int8_t b8[8];
  86509. + u_int64_t b64[1];
  86510. + } c;
  86511. + union {
  86512. + u_int8_t b8[64];
  86513. + u_int32_t b32[16];
  86514. + } m;
  86515. + u_int8_t count;
  86516. +};
  86517. +
  86518. +#ifdef __KERNEL__
  86519. +extern void sha1_init(struct sha1_ctxt *);
  86520. +extern void sha1_pad(struct sha1_ctxt *);
  86521. +extern void sha1_loop(struct sha1_ctxt *, const u_int8_t *, size_t);
  86522. +extern void sha1_result(struct sha1_ctxt *, caddr_t);
  86523. +
  86524. +/* compatibilty with other SHA1 source codes */
  86525. +typedef struct sha1_ctxt SHA1_CTX;
  86526. +#define SHA1Init(x) sha1_init((x))
  86527. +#define SHA1Update(x, y, z) sha1_loop((x), (y), (z))
  86528. +#define SHA1Final(x, y) sha1_result((y), (x))
  86529. +#endif /* __KERNEL__ */
  86530. +
  86531. +#define SHA1_RESULTLEN (160/8)
  86532. +
  86533. +#endif /*_NETINET6_SHA1_H_*/
  86534. diff -Nur linux-2.6.39.orig/crypto/ocf/talitos/Makefile linux-2.6.39/crypto/ocf/talitos/Makefile
  86535. --- linux-2.6.39.orig/crypto/ocf/talitos/Makefile 1970-01-01 01:00:00.000000000 +0100
  86536. +++ linux-2.6.39/crypto/ocf/talitos/Makefile 2011-08-01 14:38:19.000000000 +0200
  86537. @@ -0,0 +1,12 @@
  86538. +# for SGlinux builds
  86539. +-include $(ROOTDIR)/modules/.config
  86540. +
  86541. +obj-$(CONFIG_OCF_TALITOS) += talitos.o
  86542. +
  86543. +obj ?= .
  86544. +EXTRA_CFLAGS += -I$(obj)/.. -I$(obj)/
  86545. +
  86546. +ifdef TOPDIR
  86547. +-include $(TOPDIR)/Rules.make
  86548. +endif
  86549. +
  86550. diff -Nur linux-2.6.39.orig/crypto/ocf/talitos/talitos.c linux-2.6.39/crypto/ocf/talitos/talitos.c
  86551. --- linux-2.6.39.orig/crypto/ocf/talitos/talitos.c 1970-01-01 01:00:00.000000000 +0100
  86552. +++ linux-2.6.39/crypto/ocf/talitos/talitos.c 2011-08-01 14:38:19.000000000 +0200
  86553. @@ -0,0 +1,1359 @@
  86554. +/*
  86555. + * crypto/ocf/talitos/talitos.c
  86556. + *
  86557. + * An OCF-Linux module that uses Freescale's SEC to do the crypto.
  86558. + * Based on crypto/ocf/hifn and crypto/ocf/safe OCF drivers
  86559. + *
  86560. + * Copyright (c) 2006 Freescale Semiconductor, Inc.
  86561. + *
  86562. + * This code written by Kim A. B. Phillips <kim.phillips@freescale.com>
  86563. + * some code copied from files with the following:
  86564. + * Copyright (C) 2004-2007 David McCullough <david_mccullough@mcafee.com>
  86565. + *
  86566. + * Redistribution and use in source and binary forms, with or without
  86567. + * modification, are permitted provided that the following conditions
  86568. + * are met:
  86569. + *
  86570. + * 1. Redistributions of source code must retain the above copyright
  86571. + * notice, this list of conditions and the following disclaimer.
  86572. + * 2. Redistributions in binary form must reproduce the above copyright
  86573. + * notice, this list of conditions and the following disclaimer in the
  86574. + * documentation and/or other materials provided with the distribution.
  86575. + * 3. The name of the author may not be used to endorse or promote products
  86576. + * derived from this software without specific prior written permission.
  86577. + *
  86578. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  86579. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  86580. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  86581. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  86582. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  86583. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  86584. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  86585. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  86586. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  86587. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  86588. + *
  86589. + * ---------------------------------------------------------------------------
  86590. + *
  86591. + * NOTES:
  86592. + *
  86593. + * The Freescale SEC (also known as 'talitos') resides on the
  86594. + * internal bus, and runs asynchronous to the processor core. It has
  86595. + * a wide gamut of cryptographic acceleration features, including single-
  86596. + * pass IPsec (also known as algorithm chaining). To properly utilize
  86597. + * all of the SEC's performance enhancing features, further reworking
  86598. + * of higher level code (framework, applications) will be necessary.
  86599. + *
  86600. + * The following table shows which SEC version is present in which devices:
  86601. + *
  86602. + * Devices SEC version
  86603. + *
  86604. + * 8272, 8248 SEC 1.0
  86605. + * 885, 875 SEC 1.2
  86606. + * 8555E, 8541E SEC 2.0
  86607. + * 8349E SEC 2.01
  86608. + * 8548E SEC 2.1
  86609. + *
  86610. + * The following table shows the features offered by each SEC version:
  86611. + *
  86612. + * Max. chan-
  86613. + * version Bus I/F Clock nels DEU AESU AFEU MDEU PKEU RNG KEU
  86614. + *
  86615. + * SEC 1.0 internal 64b 100MHz 4 1 1 1 1 1 1 0
  86616. + * SEC 1.2 internal 32b 66MHz 1 1 1 0 1 0 0 0
  86617. + * SEC 2.0 internal 64b 166MHz 4 1 1 1 1 1 1 0
  86618. + * SEC 2.01 internal 64b 166MHz 4 1 1 1 1 1 1 0
  86619. + * SEC 2.1 internal 64b 333MHz 4 1 1 1 1 1 1 1
  86620. + *
  86621. + * Each execution unit in the SEC has two modes of execution; channel and
  86622. + * slave/debug. This driver employs the channel infrastructure in the
  86623. + * device for convenience. Only the RNG is directly accessed due to the
  86624. + * convenience of its random fifo pool. The relationship between the
  86625. + * channels and execution units is depicted in the following diagram:
  86626. + *
  86627. + * ------- ------------
  86628. + * ---| ch0 |---| |
  86629. + * ------- | |
  86630. + * | |------+-------+-------+-------+------------
  86631. + * ------- | | | | | | |
  86632. + * ---| ch1 |---| | | | | | |
  86633. + * ------- | | ------ ------ ------ ------ ------
  86634. + * |controller| |DEU | |AESU| |MDEU| |PKEU| ... |RNG |
  86635. + * ------- | | ------ ------ ------ ------ ------
  86636. + * ---| ch2 |---| | | | | | |
  86637. + * ------- | | | | | | |
  86638. + * | |------+-------+-------+-------+------------
  86639. + * ------- | |
  86640. + * ---| ch3 |---| |
  86641. + * ------- ------------
  86642. + *
  86643. + * Channel ch0 may drive an aes operation to the aes unit (AESU),
  86644. + * and, at the same time, ch1 may drive a message digest operation
  86645. + * to the mdeu. Each channel has an input descriptor FIFO, and the
  86646. + * FIFO can contain, e.g. on the 8541E, up to 24 entries, before a
  86647. + * a buffer overrun error is triggered. The controller is responsible
  86648. + * for fetching the data from descriptor pointers, and passing the
  86649. + * data to the appropriate EUs. The controller also writes the
  86650. + * cryptographic operation's result to memory. The SEC notifies
  86651. + * completion by triggering an interrupt and/or setting the 1st byte
  86652. + * of the hdr field to 0xff.
  86653. + *
  86654. + * TODO:
  86655. + * o support more algorithms
  86656. + * o support more versions of the SEC
  86657. + * o add support for linux 2.4
  86658. + * o scatter-gather (sg) support
  86659. + * o add support for public key ops (PKEU)
  86660. + * o add statistics
  86661. + */
  86662. +
  86663. +#ifndef AUTOCONF_INCLUDED
  86664. +#include <linux/config.h>
  86665. +#endif
  86666. +#include <linux/module.h>
  86667. +#include <linux/init.h>
  86668. +#include <linux/interrupt.h>
  86669. +#include <linux/spinlock.h>
  86670. +#include <linux/random.h>
  86671. +#include <linux/skbuff.h>
  86672. +#include <asm/scatterlist.h>
  86673. +#include <linux/dma-mapping.h> /* dma_map_single() */
  86674. +#include <linux/moduleparam.h>
  86675. +
  86676. +#include <linux/version.h>
  86677. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)
  86678. +#include <linux/platform_device.h>
  86679. +#endif
  86680. +
  86681. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  86682. +#include <linux/of_platform.h>
  86683. +#endif
  86684. +
  86685. +#include <cryptodev.h>
  86686. +#include <uio.h>
  86687. +
  86688. +#define DRV_NAME "talitos"
  86689. +
  86690. +#include "talitos_dev.h"
  86691. +#include "talitos_soft.h"
  86692. +
  86693. +#define read_random(p,l) get_random_bytes(p,l)
  86694. +
  86695. +const char talitos_driver_name[] = "Talitos OCF";
  86696. +const char talitos_driver_version[] = "0.2";
  86697. +
  86698. +static int talitos_newsession(device_t dev, u_int32_t *sidp,
  86699. + struct cryptoini *cri);
  86700. +static int talitos_freesession(device_t dev, u_int64_t tid);
  86701. +static int talitos_process(device_t dev, struct cryptop *crp, int hint);
  86702. +static void dump_talitos_status(struct talitos_softc *sc);
  86703. +static int talitos_submit(struct talitos_softc *sc, struct talitos_desc *td,
  86704. + int chsel);
  86705. +static void talitos_doneprocessing(struct talitos_softc *sc);
  86706. +static void talitos_init_device(struct talitos_softc *sc);
  86707. +static void talitos_reset_device_master(struct talitos_softc *sc);
  86708. +static void talitos_reset_device(struct talitos_softc *sc);
  86709. +static void talitos_errorprocessing(struct talitos_softc *sc);
  86710. +#ifdef CONFIG_PPC_MERGE
  86711. +static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match);
  86712. +static int talitos_remove(struct of_device *ofdev);
  86713. +#else
  86714. +static int talitos_probe(struct platform_device *pdev);
  86715. +static int talitos_remove(struct platform_device *pdev);
  86716. +#endif
  86717. +#ifdef CONFIG_OCF_RANDOMHARVEST
  86718. +static int talitos_read_random(void *arg, u_int32_t *buf, int maxwords);
  86719. +static void talitos_rng_init(struct talitos_softc *sc);
  86720. +#endif
  86721. +
  86722. +static device_method_t talitos_methods = {
  86723. + /* crypto device methods */
  86724. + DEVMETHOD(cryptodev_newsession, talitos_newsession),
  86725. + DEVMETHOD(cryptodev_freesession,talitos_freesession),
  86726. + DEVMETHOD(cryptodev_process, talitos_process),
  86727. +};
  86728. +
  86729. +#define debug talitos_debug
  86730. +int talitos_debug = 0;
  86731. +module_param(talitos_debug, int, 0644);
  86732. +MODULE_PARM_DESC(talitos_debug, "Enable debug");
  86733. +
  86734. +static inline void talitos_write(volatile unsigned *addr, u32 val)
  86735. +{
  86736. + out_be32(addr, val);
  86737. +}
  86738. +
  86739. +static inline u32 talitos_read(volatile unsigned *addr)
  86740. +{
  86741. + u32 val;
  86742. + val = in_be32(addr);
  86743. + return val;
  86744. +}
  86745. +
  86746. +static void dump_talitos_status(struct talitos_softc *sc)
  86747. +{
  86748. + unsigned int v, v_hi, i, *ptr;
  86749. + v = talitos_read(sc->sc_base_addr + TALITOS_MCR);
  86750. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_MCR_HI);
  86751. + printk(KERN_INFO "%s: MCR 0x%08x_%08x\n",
  86752. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  86753. + v = talitos_read(sc->sc_base_addr + TALITOS_IMR);
  86754. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);
  86755. + printk(KERN_INFO "%s: IMR 0x%08x_%08x\n",
  86756. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  86757. + v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
  86758. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
  86759. + printk(KERN_INFO "%s: ISR 0x%08x_%08x\n",
  86760. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  86761. + for (i = 0; i < sc->sc_num_channels; i++) {
  86762. + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  86763. + TALITOS_CH_CDPR);
  86764. + v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  86765. + TALITOS_CH_CDPR_HI);
  86766. + printk(KERN_INFO "%s: CDPR ch%d 0x%08x_%08x\n",
  86767. + device_get_nameunit(sc->sc_cdev), i, v, v_hi);
  86768. + }
  86769. + for (i = 0; i < sc->sc_num_channels; i++) {
  86770. + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  86771. + TALITOS_CH_CCPSR);
  86772. + v_hi = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  86773. + TALITOS_CH_CCPSR_HI);
  86774. + printk(KERN_INFO "%s: CCPSR ch%d 0x%08x_%08x\n",
  86775. + device_get_nameunit(sc->sc_cdev), i, v, v_hi);
  86776. + }
  86777. + ptr = sc->sc_base_addr + TALITOS_CH_DESCBUF;
  86778. + for (i = 0; i < 16; i++) {
  86779. + v = talitos_read(ptr++); v_hi = talitos_read(ptr++);
  86780. + printk(KERN_INFO "%s: DESCBUF ch0 0x%08x_%08x (tdp%02d)\n",
  86781. + device_get_nameunit(sc->sc_cdev), v, v_hi, i);
  86782. + }
  86783. + return;
  86784. +}
  86785. +
  86786. +
  86787. +#ifdef CONFIG_OCF_RANDOMHARVEST
  86788. +/*
  86789. + * pull random numbers off the RNG FIFO, not exceeding amount available
  86790. + */
  86791. +static int
  86792. +talitos_read_random(void *arg, u_int32_t *buf, int maxwords)
  86793. +{
  86794. + struct talitos_softc *sc = (struct talitos_softc *) arg;
  86795. + int rc;
  86796. + u_int32_t v;
  86797. +
  86798. + DPRINTF("%s()\n", __FUNCTION__);
  86799. +
  86800. + /* check for things like FIFO underflow */
  86801. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
  86802. + if (unlikely(v)) {
  86803. + printk(KERN_ERR "%s: RNGISR_HI error %08x\n",
  86804. + device_get_nameunit(sc->sc_cdev), v);
  86805. + return 0;
  86806. + }
  86807. + /*
  86808. + * OFL is number of available 64-bit words,
  86809. + * shift and convert to a 32-bit word count
  86810. + */
  86811. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI);
  86812. + v = (v & TALITOS_RNGSR_HI_OFL) >> (16 - 1);
  86813. + if (maxwords > v)
  86814. + maxwords = v;
  86815. + for (rc = 0; rc < maxwords; rc++) {
  86816. + buf[rc] = talitos_read(sc->sc_base_addr +
  86817. + TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
  86818. + }
  86819. + if (maxwords & 1) {
  86820. + /*
  86821. + * RNG will complain with an AE in the RNGISR
  86822. + * if we don't complete the pairs of 32-bit reads
  86823. + * to its 64-bit register based FIFO
  86824. + */
  86825. + v = talitos_read(sc->sc_base_addr +
  86826. + TALITOS_RNG_FIFO + rc*sizeof(u_int32_t));
  86827. + }
  86828. +
  86829. + return rc;
  86830. +}
  86831. +
  86832. +static void
  86833. +talitos_rng_init(struct talitos_softc *sc)
  86834. +{
  86835. + u_int32_t v;
  86836. +
  86837. + DPRINTF("%s()\n", __FUNCTION__);
  86838. + /* reset RNG EU */
  86839. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGRCR_HI);
  86840. + v |= TALITOS_RNGRCR_HI_SR;
  86841. + talitos_write(sc->sc_base_addr + TALITOS_RNGRCR_HI, v);
  86842. + while ((talitos_read(sc->sc_base_addr + TALITOS_RNGSR_HI)
  86843. + & TALITOS_RNGSR_HI_RD) == 0)
  86844. + cpu_relax();
  86845. + /*
  86846. + * we tell the RNG to start filling the RNG FIFO
  86847. + * by writing the RNGDSR
  86848. + */
  86849. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGDSR_HI);
  86850. + talitos_write(sc->sc_base_addr + TALITOS_RNGDSR_HI, v);
  86851. + /*
  86852. + * 64 bits of data will be pushed onto the FIFO every
  86853. + * 256 SEC cycles until the FIFO is full. The RNG then
  86854. + * attempts to keep the FIFO full.
  86855. + */
  86856. + v = talitos_read(sc->sc_base_addr + TALITOS_RNGISR_HI);
  86857. + if (v) {
  86858. + printk(KERN_ERR "%s: RNGISR_HI error %08x\n",
  86859. + device_get_nameunit(sc->sc_cdev), v);
  86860. + return;
  86861. + }
  86862. + /*
  86863. + * n.b. we need to add a FIPS test here - if the RNG is going
  86864. + * to fail, it's going to fail at reset time
  86865. + */
  86866. + return;
  86867. +}
  86868. +#endif /* CONFIG_OCF_RANDOMHARVEST */
  86869. +
  86870. +/*
  86871. + * Generate a new software session.
  86872. + */
  86873. +static int
  86874. +talitos_newsession(device_t dev, u_int32_t *sidp, struct cryptoini *cri)
  86875. +{
  86876. + struct cryptoini *c, *encini = NULL, *macini = NULL;
  86877. + struct talitos_softc *sc = device_get_softc(dev);
  86878. + struct talitos_session *ses = NULL;
  86879. + int sesn;
  86880. +
  86881. + DPRINTF("%s()\n", __FUNCTION__);
  86882. + if (sidp == NULL || cri == NULL || sc == NULL) {
  86883. + DPRINTF("%s,%d - EINVAL\n", __FILE__, __LINE__);
  86884. + return EINVAL;
  86885. + }
  86886. + for (c = cri; c != NULL; c = c->cri_next) {
  86887. + if (c->cri_alg == CRYPTO_MD5 ||
  86888. + c->cri_alg == CRYPTO_MD5_HMAC ||
  86889. + c->cri_alg == CRYPTO_SHA1 ||
  86890. + c->cri_alg == CRYPTO_SHA1_HMAC ||
  86891. + c->cri_alg == CRYPTO_NULL_HMAC) {
  86892. + if (macini)
  86893. + return EINVAL;
  86894. + macini = c;
  86895. + } else if (c->cri_alg == CRYPTO_DES_CBC ||
  86896. + c->cri_alg == CRYPTO_3DES_CBC ||
  86897. + c->cri_alg == CRYPTO_AES_CBC ||
  86898. + c->cri_alg == CRYPTO_NULL_CBC) {
  86899. + if (encini)
  86900. + return EINVAL;
  86901. + encini = c;
  86902. + } else {
  86903. + DPRINTF("UNKNOWN c->cri_alg %d\n", encini->cri_alg);
  86904. + return EINVAL;
  86905. + }
  86906. + }
  86907. + if (encini == NULL && macini == NULL)
  86908. + return EINVAL;
  86909. + if (encini) {
  86910. + /* validate key length */
  86911. + switch (encini->cri_alg) {
  86912. + case CRYPTO_DES_CBC:
  86913. + if (encini->cri_klen != 64)
  86914. + return EINVAL;
  86915. + break;
  86916. + case CRYPTO_3DES_CBC:
  86917. + if (encini->cri_klen != 192) {
  86918. + return EINVAL;
  86919. + }
  86920. + break;
  86921. + case CRYPTO_AES_CBC:
  86922. + if (encini->cri_klen != 128 &&
  86923. + encini->cri_klen != 192 &&
  86924. + encini->cri_klen != 256)
  86925. + return EINVAL;
  86926. + break;
  86927. + default:
  86928. + DPRINTF("UNKNOWN encini->cri_alg %d\n",
  86929. + encini->cri_alg);
  86930. + return EINVAL;
  86931. + }
  86932. + }
  86933. +
  86934. + if (sc->sc_sessions == NULL) {
  86935. + ses = sc->sc_sessions = (struct talitos_session *)
  86936. + kmalloc(sizeof(struct talitos_session), SLAB_ATOMIC);
  86937. + if (ses == NULL)
  86938. + return ENOMEM;
  86939. + memset(ses, 0, sizeof(struct talitos_session));
  86940. + sesn = 0;
  86941. + sc->sc_nsessions = 1;
  86942. + } else {
  86943. + for (sesn = 0; sesn < sc->sc_nsessions; sesn++) {
  86944. + if (sc->sc_sessions[sesn].ses_used == 0) {
  86945. + ses = &sc->sc_sessions[sesn];
  86946. + break;
  86947. + }
  86948. + }
  86949. +
  86950. + if (ses == NULL) {
  86951. + /* allocating session */
  86952. + sesn = sc->sc_nsessions;
  86953. + ses = (struct talitos_session *) kmalloc(
  86954. + (sesn + 1) * sizeof(struct talitos_session),
  86955. + SLAB_ATOMIC);
  86956. + if (ses == NULL)
  86957. + return ENOMEM;
  86958. + memset(ses, 0,
  86959. + (sesn + 1) * sizeof(struct talitos_session));
  86960. + memcpy(ses, sc->sc_sessions,
  86961. + sesn * sizeof(struct talitos_session));
  86962. + memset(sc->sc_sessions, 0,
  86963. + sesn * sizeof(struct talitos_session));
  86964. + kfree(sc->sc_sessions);
  86965. + sc->sc_sessions = ses;
  86966. + ses = &sc->sc_sessions[sesn];
  86967. + sc->sc_nsessions++;
  86968. + }
  86969. + }
  86970. +
  86971. + ses->ses_used = 1;
  86972. +
  86973. + if (encini) {
  86974. + /* get an IV */
  86975. + /* XXX may read fewer than requested */
  86976. + read_random(ses->ses_iv, sizeof(ses->ses_iv));
  86977. +
  86978. + ses->ses_klen = (encini->cri_klen + 7) / 8;
  86979. + memcpy(ses->ses_key, encini->cri_key, ses->ses_klen);
  86980. + if (macini) {
  86981. + /* doing hash on top of cipher */
  86982. + ses->ses_hmac_len = (macini->cri_klen + 7) / 8;
  86983. + memcpy(ses->ses_hmac, macini->cri_key,
  86984. + ses->ses_hmac_len);
  86985. + }
  86986. + } else if (macini) {
  86987. + /* doing hash */
  86988. + ses->ses_klen = (macini->cri_klen + 7) / 8;
  86989. + memcpy(ses->ses_key, macini->cri_key, ses->ses_klen);
  86990. + }
  86991. +
  86992. + /* back compat way of determining MSC result len */
  86993. + if (macini) {
  86994. + ses->ses_mlen = macini->cri_mlen;
  86995. + if (ses->ses_mlen == 0) {
  86996. + if (macini->cri_alg == CRYPTO_MD5_HMAC)
  86997. + ses->ses_mlen = MD5_HASH_LEN;
  86998. + else
  86999. + ses->ses_mlen = SHA1_HASH_LEN;
  87000. + }
  87001. + }
  87002. +
  87003. + /* really should make up a template td here,
  87004. + * and only fill things like i/o and direction in process() */
  87005. +
  87006. + /* assign session ID */
  87007. + *sidp = TALITOS_SID(sc->sc_num, sesn);
  87008. + return 0;
  87009. +}
  87010. +
  87011. +/*
  87012. + * Deallocate a session.
  87013. + */
  87014. +static int
  87015. +talitos_freesession(device_t dev, u_int64_t tid)
  87016. +{
  87017. + struct talitos_softc *sc = device_get_softc(dev);
  87018. + int session, ret;
  87019. + u_int32_t sid = ((u_int32_t) tid) & 0xffffffff;
  87020. +
  87021. + if (sc == NULL)
  87022. + return EINVAL;
  87023. + session = TALITOS_SESSION(sid);
  87024. + if (session < sc->sc_nsessions) {
  87025. + memset(&sc->sc_sessions[session], 0,
  87026. + sizeof(sc->sc_sessions[session]));
  87027. + ret = 0;
  87028. + } else
  87029. + ret = EINVAL;
  87030. + return ret;
  87031. +}
  87032. +
  87033. +/*
  87034. + * launch device processing - it will come back with done notification
  87035. + * in the form of an interrupt and/or HDR_DONE_BITS in header
  87036. + */
  87037. +static int
  87038. +talitos_submit(
  87039. + struct talitos_softc *sc,
  87040. + struct talitos_desc *td,
  87041. + int chsel)
  87042. +{
  87043. + u_int32_t v;
  87044. +
  87045. + v = dma_map_single(NULL, td, sizeof(*td), DMA_TO_DEVICE);
  87046. + talitos_write(sc->sc_base_addr +
  87047. + chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF, 0);
  87048. + talitos_write(sc->sc_base_addr +
  87049. + chsel*TALITOS_CH_OFFSET + TALITOS_CH_FF_HI, v);
  87050. + return 0;
  87051. +}
  87052. +
  87053. +static int
  87054. +talitos_process(device_t dev, struct cryptop *crp, int hint)
  87055. +{
  87056. + int i, err = 0, ivsize;
  87057. + struct talitos_softc *sc = device_get_softc(dev);
  87058. + struct cryptodesc *crd1, *crd2, *maccrd, *enccrd;
  87059. + caddr_t iv;
  87060. + struct talitos_session *ses;
  87061. + struct talitos_desc *td;
  87062. + unsigned long flags;
  87063. + /* descriptor mappings */
  87064. + int hmac_key, hmac_data, cipher_iv, cipher_key,
  87065. + in_fifo, out_fifo, cipher_iv_out;
  87066. + static int chsel = -1;
  87067. +
  87068. + DPRINTF("%s()\n", __FUNCTION__);
  87069. +
  87070. + if (crp == NULL || crp->crp_callback == NULL || sc == NULL) {
  87071. + return EINVAL;
  87072. + }
  87073. + crp->crp_etype = 0;
  87074. + if (TALITOS_SESSION(crp->crp_sid) >= sc->sc_nsessions) {
  87075. + return EINVAL;
  87076. + }
  87077. +
  87078. + ses = &sc->sc_sessions[TALITOS_SESSION(crp->crp_sid)];
  87079. +
  87080. + /* enter the channel scheduler */
  87081. + spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  87082. +
  87083. + /* reuse channel that already had/has requests for the required EU */
  87084. + for (i = 0; i < sc->sc_num_channels; i++) {
  87085. + if (sc->sc_chnlastalg[i] == crp->crp_desc->crd_alg)
  87086. + break;
  87087. + }
  87088. + if (i == sc->sc_num_channels) {
  87089. + /*
  87090. + * haven't seen this algo the last sc_num_channels or more
  87091. + * use round robin in this case
  87092. + * nb: sc->sc_num_channels must be power of 2
  87093. + */
  87094. + chsel = (chsel + 1) & (sc->sc_num_channels - 1);
  87095. + } else {
  87096. + /*
  87097. + * matches channel with same target execution unit;
  87098. + * use same channel in this case
  87099. + */
  87100. + chsel = i;
  87101. + }
  87102. + sc->sc_chnlastalg[chsel] = crp->crp_desc->crd_alg;
  87103. +
  87104. + /* release the channel scheduler lock */
  87105. + spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  87106. +
  87107. + /* acquire the selected channel fifo lock */
  87108. + spin_lock_irqsave(&sc->sc_chnfifolock[chsel], flags);
  87109. +
  87110. + /* find and reserve next available descriptor-cryptop pair */
  87111. + for (i = 0; i < sc->sc_chfifo_len; i++) {
  87112. + if (sc->sc_chnfifo[chsel][i].cf_desc.hdr == 0) {
  87113. + /*
  87114. + * ensure correct descriptor formation by
  87115. + * avoiding inadvertently setting "optional" entries
  87116. + * e.g. not using "optional" dptr2 for MD/HMAC descs
  87117. + */
  87118. + memset(&sc->sc_chnfifo[chsel][i].cf_desc,
  87119. + 0, sizeof(*td));
  87120. + /* reserve it with done notification request bit */
  87121. + sc->sc_chnfifo[chsel][i].cf_desc.hdr |=
  87122. + TALITOS_DONE_NOTIFY;
  87123. + break;
  87124. + }
  87125. + }
  87126. + spin_unlock_irqrestore(&sc->sc_chnfifolock[chsel], flags);
  87127. +
  87128. + if (i == sc->sc_chfifo_len) {
  87129. + /* fifo full */
  87130. + err = ERESTART;
  87131. + goto errout;
  87132. + }
  87133. +
  87134. + td = &sc->sc_chnfifo[chsel][i].cf_desc;
  87135. + sc->sc_chnfifo[chsel][i].cf_crp = crp;
  87136. +
  87137. + crd1 = crp->crp_desc;
  87138. + if (crd1 == NULL) {
  87139. + err = EINVAL;
  87140. + goto errout;
  87141. + }
  87142. + crd2 = crd1->crd_next;
  87143. + /* prevent compiler warning */
  87144. + hmac_key = 0;
  87145. + hmac_data = 0;
  87146. + if (crd2 == NULL) {
  87147. + td->hdr |= TD_TYPE_COMMON_NONSNOOP_NO_AFEU;
  87148. + /* assign descriptor dword ptr mappings for this desc. type */
  87149. + cipher_iv = 1;
  87150. + cipher_key = 2;
  87151. + in_fifo = 3;
  87152. + cipher_iv_out = 5;
  87153. + if (crd1->crd_alg == CRYPTO_MD5_HMAC ||
  87154. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  87155. + crd1->crd_alg == CRYPTO_SHA1 ||
  87156. + crd1->crd_alg == CRYPTO_MD5) {
  87157. + out_fifo = 5;
  87158. + maccrd = crd1;
  87159. + enccrd = NULL;
  87160. + } else if (crd1->crd_alg == CRYPTO_DES_CBC ||
  87161. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  87162. + crd1->crd_alg == CRYPTO_AES_CBC ||
  87163. + crd1->crd_alg == CRYPTO_ARC4) {
  87164. + out_fifo = 4;
  87165. + maccrd = NULL;
  87166. + enccrd = crd1;
  87167. + } else {
  87168. + DPRINTF("UNKNOWN crd1->crd_alg %d\n", crd1->crd_alg);
  87169. + err = EINVAL;
  87170. + goto errout;
  87171. + }
  87172. + } else {
  87173. + if (sc->sc_desc_types & TALITOS_HAS_DT_IPSEC_ESP) {
  87174. + td->hdr |= TD_TYPE_IPSEC_ESP;
  87175. + } else {
  87176. + DPRINTF("unimplemented: multiple descriptor ipsec\n");
  87177. + err = EINVAL;
  87178. + goto errout;
  87179. + }
  87180. + /* assign descriptor dword ptr mappings for this desc. type */
  87181. + hmac_key = 0;
  87182. + hmac_data = 1;
  87183. + cipher_iv = 2;
  87184. + cipher_key = 3;
  87185. + in_fifo = 4;
  87186. + out_fifo = 5;
  87187. + cipher_iv_out = 6;
  87188. + if ((crd1->crd_alg == CRYPTO_MD5_HMAC ||
  87189. + crd1->crd_alg == CRYPTO_SHA1_HMAC ||
  87190. + crd1->crd_alg == CRYPTO_MD5 ||
  87191. + crd1->crd_alg == CRYPTO_SHA1) &&
  87192. + (crd2->crd_alg == CRYPTO_DES_CBC ||
  87193. + crd2->crd_alg == CRYPTO_3DES_CBC ||
  87194. + crd2->crd_alg == CRYPTO_AES_CBC ||
  87195. + crd2->crd_alg == CRYPTO_ARC4) &&
  87196. + ((crd2->crd_flags & CRD_F_ENCRYPT) == 0)) {
  87197. + maccrd = crd1;
  87198. + enccrd = crd2;
  87199. + } else if ((crd1->crd_alg == CRYPTO_DES_CBC ||
  87200. + crd1->crd_alg == CRYPTO_ARC4 ||
  87201. + crd1->crd_alg == CRYPTO_3DES_CBC ||
  87202. + crd1->crd_alg == CRYPTO_AES_CBC) &&
  87203. + (crd2->crd_alg == CRYPTO_MD5_HMAC ||
  87204. + crd2->crd_alg == CRYPTO_SHA1_HMAC ||
  87205. + crd2->crd_alg == CRYPTO_MD5 ||
  87206. + crd2->crd_alg == CRYPTO_SHA1) &&
  87207. + (crd1->crd_flags & CRD_F_ENCRYPT)) {
  87208. + enccrd = crd1;
  87209. + maccrd = crd2;
  87210. + } else {
  87211. + /* We cannot order the SEC as requested */
  87212. + printk("%s: cannot do the order\n",
  87213. + device_get_nameunit(sc->sc_cdev));
  87214. + err = EINVAL;
  87215. + goto errout;
  87216. + }
  87217. + }
  87218. + /* assign in_fifo and out_fifo based on input/output struct type */
  87219. + if (crp->crp_flags & CRYPTO_F_SKBUF) {
  87220. + /* using SKB buffers */
  87221. + struct sk_buff *skb = (struct sk_buff *)crp->crp_buf;
  87222. + if (skb_shinfo(skb)->nr_frags) {
  87223. + printk("%s: skb frags unimplemented\n",
  87224. + device_get_nameunit(sc->sc_cdev));
  87225. + err = EINVAL;
  87226. + goto errout;
  87227. + }
  87228. + td->ptr[in_fifo].ptr = dma_map_single(NULL, skb->data,
  87229. + skb->len, DMA_TO_DEVICE);
  87230. + td->ptr[in_fifo].len = skb->len;
  87231. + td->ptr[out_fifo].ptr = dma_map_single(NULL, skb->data,
  87232. + skb->len, DMA_TO_DEVICE);
  87233. + td->ptr[out_fifo].len = skb->len;
  87234. + td->ptr[hmac_data].ptr = dma_map_single(NULL, skb->data,
  87235. + skb->len, DMA_TO_DEVICE);
  87236. + } else if (crp->crp_flags & CRYPTO_F_IOV) {
  87237. + /* using IOV buffers */
  87238. + struct uio *uiop = (struct uio *)crp->crp_buf;
  87239. + if (uiop->uio_iovcnt > 1) {
  87240. + printk("%s: iov frags unimplemented\n",
  87241. + device_get_nameunit(sc->sc_cdev));
  87242. + err = EINVAL;
  87243. + goto errout;
  87244. + }
  87245. + td->ptr[in_fifo].ptr = dma_map_single(NULL,
  87246. + uiop->uio_iov->iov_base, crp->crp_ilen, DMA_TO_DEVICE);
  87247. + td->ptr[in_fifo].len = crp->crp_ilen;
  87248. + /* crp_olen is never set; always use crp_ilen */
  87249. + td->ptr[out_fifo].ptr = dma_map_single(NULL,
  87250. + uiop->uio_iov->iov_base,
  87251. + crp->crp_ilen, DMA_TO_DEVICE);
  87252. + td->ptr[out_fifo].len = crp->crp_ilen;
  87253. + } else {
  87254. + /* using contig buffers */
  87255. + td->ptr[in_fifo].ptr = dma_map_single(NULL,
  87256. + crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);
  87257. + td->ptr[in_fifo].len = crp->crp_ilen;
  87258. + td->ptr[out_fifo].ptr = dma_map_single(NULL,
  87259. + crp->crp_buf, crp->crp_ilen, DMA_TO_DEVICE);
  87260. + td->ptr[out_fifo].len = crp->crp_ilen;
  87261. + }
  87262. + if (enccrd) {
  87263. + switch (enccrd->crd_alg) {
  87264. + case CRYPTO_3DES_CBC:
  87265. + td->hdr |= TALITOS_MODE0_DEU_3DES;
  87266. + /* FALLTHROUGH */
  87267. + case CRYPTO_DES_CBC:
  87268. + td->hdr |= TALITOS_SEL0_DEU
  87269. + | TALITOS_MODE0_DEU_CBC;
  87270. + if (enccrd->crd_flags & CRD_F_ENCRYPT)
  87271. + td->hdr |= TALITOS_MODE0_DEU_ENC;
  87272. + ivsize = 2*sizeof(u_int32_t);
  87273. + DPRINTF("%cDES ses %d ch %d len %d\n",
  87274. + (td->hdr & TALITOS_MODE0_DEU_3DES)?'3':'1',
  87275. + (u32)TALITOS_SESSION(crp->crp_sid),
  87276. + chsel, td->ptr[in_fifo].len);
  87277. + break;
  87278. + case CRYPTO_AES_CBC:
  87279. + td->hdr |= TALITOS_SEL0_AESU
  87280. + | TALITOS_MODE0_AESU_CBC;
  87281. + if (enccrd->crd_flags & CRD_F_ENCRYPT)
  87282. + td->hdr |= TALITOS_MODE0_AESU_ENC;
  87283. + ivsize = 4*sizeof(u_int32_t);
  87284. + DPRINTF("AES ses %d ch %d len %d\n",
  87285. + (u32)TALITOS_SESSION(crp->crp_sid),
  87286. + chsel, td->ptr[in_fifo].len);
  87287. + break;
  87288. + default:
  87289. + printk("%s: unimplemented enccrd->crd_alg %d\n",
  87290. + device_get_nameunit(sc->sc_cdev), enccrd->crd_alg);
  87291. + err = EINVAL;
  87292. + goto errout;
  87293. + }
  87294. + /*
  87295. + * Setup encrypt/decrypt state. When using basic ops
  87296. + * we can't use an inline IV because hash/crypt offset
  87297. + * must be from the end of the IV to the start of the
  87298. + * crypt data and this leaves out the preceding header
  87299. + * from the hash calculation. Instead we place the IV
  87300. + * in the state record and set the hash/crypt offset to
  87301. + * copy both the header+IV.
  87302. + */
  87303. + if (enccrd->crd_flags & CRD_F_ENCRYPT) {
  87304. + td->hdr |= TALITOS_DIR_OUTBOUND;
  87305. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT)
  87306. + iv = enccrd->crd_iv;
  87307. + else
  87308. + iv = (caddr_t) ses->ses_iv;
  87309. + if ((enccrd->crd_flags & CRD_F_IV_PRESENT) == 0) {
  87310. + crypto_copyback(crp->crp_flags, crp->crp_buf,
  87311. + enccrd->crd_inject, ivsize, iv);
  87312. + }
  87313. + } else {
  87314. + td->hdr |= TALITOS_DIR_INBOUND;
  87315. + if (enccrd->crd_flags & CRD_F_IV_EXPLICIT) {
  87316. + iv = enccrd->crd_iv;
  87317. + bcopy(enccrd->crd_iv, iv, ivsize);
  87318. + } else {
  87319. + iv = (caddr_t) ses->ses_iv;
  87320. + crypto_copydata(crp->crp_flags, crp->crp_buf,
  87321. + enccrd->crd_inject, ivsize, iv);
  87322. + }
  87323. + }
  87324. + td->ptr[cipher_iv].ptr = dma_map_single(NULL, iv, ivsize,
  87325. + DMA_TO_DEVICE);
  87326. + td->ptr[cipher_iv].len = ivsize;
  87327. + /*
  87328. + * we don't need the cipher iv out length/pointer
  87329. + * field to do ESP IPsec. Therefore we set the len field as 0,
  87330. + * which tells the SEC not to do anything with this len/ptr
  87331. + * field. Previously, when length/pointer as pointing to iv,
  87332. + * it gave us corruption of packets.
  87333. + */
  87334. + td->ptr[cipher_iv_out].len = 0;
  87335. + }
  87336. + if (enccrd && maccrd) {
  87337. + /* this is ipsec only for now */
  87338. + td->hdr |= TALITOS_SEL1_MDEU
  87339. + | TALITOS_MODE1_MDEU_INIT
  87340. + | TALITOS_MODE1_MDEU_PAD;
  87341. + switch (maccrd->crd_alg) {
  87342. + case CRYPTO_MD5:
  87343. + td->hdr |= TALITOS_MODE1_MDEU_MD5;
  87344. + break;
  87345. + case CRYPTO_MD5_HMAC:
  87346. + td->hdr |= TALITOS_MODE1_MDEU_MD5_HMAC;
  87347. + break;
  87348. + case CRYPTO_SHA1:
  87349. + td->hdr |= TALITOS_MODE1_MDEU_SHA1;
  87350. + break;
  87351. + case CRYPTO_SHA1_HMAC:
  87352. + td->hdr |= TALITOS_MODE1_MDEU_SHA1_HMAC;
  87353. + break;
  87354. + default:
  87355. + /* We cannot order the SEC as requested */
  87356. + printk("%s: cannot do the order\n",
  87357. + device_get_nameunit(sc->sc_cdev));
  87358. + err = EINVAL;
  87359. + goto errout;
  87360. + }
  87361. + if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
  87362. + (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
  87363. + /*
  87364. + * The offset from hash data to the start of
  87365. + * crypt data is the difference in the skips.
  87366. + */
  87367. + /* ipsec only for now */
  87368. + td->ptr[hmac_key].ptr = dma_map_single(NULL,
  87369. + ses->ses_hmac, ses->ses_hmac_len, DMA_TO_DEVICE);
  87370. + td->ptr[hmac_key].len = ses->ses_hmac_len;
  87371. + td->ptr[in_fifo].ptr += enccrd->crd_skip;
  87372. + td->ptr[in_fifo].len = enccrd->crd_len;
  87373. + td->ptr[out_fifo].ptr += enccrd->crd_skip;
  87374. + td->ptr[out_fifo].len = enccrd->crd_len;
  87375. + /* bytes of HMAC to postpend to ciphertext */
  87376. + td->ptr[out_fifo].extent = ses->ses_mlen;
  87377. + td->ptr[hmac_data].ptr += maccrd->crd_skip;
  87378. + td->ptr[hmac_data].len = enccrd->crd_skip - maccrd->crd_skip;
  87379. + }
  87380. + if (enccrd->crd_flags & CRD_F_KEY_EXPLICIT) {
  87381. + printk("%s: CRD_F_KEY_EXPLICIT unimplemented\n",
  87382. + device_get_nameunit(sc->sc_cdev));
  87383. + }
  87384. + }
  87385. + if (!enccrd && maccrd) {
  87386. + /* single MD5 or SHA */
  87387. + td->hdr |= TALITOS_SEL0_MDEU
  87388. + | TALITOS_MODE0_MDEU_INIT
  87389. + | TALITOS_MODE0_MDEU_PAD;
  87390. + switch (maccrd->crd_alg) {
  87391. + case CRYPTO_MD5:
  87392. + td->hdr |= TALITOS_MODE0_MDEU_MD5;
  87393. + DPRINTF("MD5 ses %d ch %d len %d\n",
  87394. + (u32)TALITOS_SESSION(crp->crp_sid),
  87395. + chsel, td->ptr[in_fifo].len);
  87396. + break;
  87397. + case CRYPTO_MD5_HMAC:
  87398. + td->hdr |= TALITOS_MODE0_MDEU_MD5_HMAC;
  87399. + break;
  87400. + case CRYPTO_SHA1:
  87401. + td->hdr |= TALITOS_MODE0_MDEU_SHA1;
  87402. + DPRINTF("SHA1 ses %d ch %d len %d\n",
  87403. + (u32)TALITOS_SESSION(crp->crp_sid),
  87404. + chsel, td->ptr[in_fifo].len);
  87405. + break;
  87406. + case CRYPTO_SHA1_HMAC:
  87407. + td->hdr |= TALITOS_MODE0_MDEU_SHA1_HMAC;
  87408. + break;
  87409. + default:
  87410. + /* We cannot order the SEC as requested */
  87411. + DPRINTF("cannot do the order\n");
  87412. + err = EINVAL;
  87413. + goto errout;
  87414. + }
  87415. +
  87416. + if (crp->crp_flags & CRYPTO_F_IOV)
  87417. + td->ptr[out_fifo].ptr += maccrd->crd_inject;
  87418. +
  87419. + if ((maccrd->crd_alg == CRYPTO_MD5_HMAC) ||
  87420. + (maccrd->crd_alg == CRYPTO_SHA1_HMAC)) {
  87421. + td->ptr[hmac_key].ptr = dma_map_single(NULL,
  87422. + ses->ses_hmac, ses->ses_hmac_len,
  87423. + DMA_TO_DEVICE);
  87424. + td->ptr[hmac_key].len = ses->ses_hmac_len;
  87425. + }
  87426. + }
  87427. + else {
  87428. + /* using process key (session data has duplicate) */
  87429. + td->ptr[cipher_key].ptr = dma_map_single(NULL,
  87430. + enccrd->crd_key, (enccrd->crd_klen + 7) / 8,
  87431. + DMA_TO_DEVICE);
  87432. + td->ptr[cipher_key].len = (enccrd->crd_klen + 7) / 8;
  87433. + }
  87434. + /* descriptor complete - GO! */
  87435. + return talitos_submit(sc, td, chsel);
  87436. +
  87437. +errout:
  87438. + if (err != ERESTART) {
  87439. + crp->crp_etype = err;
  87440. + crypto_done(crp);
  87441. + }
  87442. + return err;
  87443. +}
  87444. +
  87445. +/* go through all channels descriptors, notifying OCF what has
  87446. + * _and_hasn't_ successfully completed and reset the device
  87447. + * (otherwise it's up to decoding desc hdrs!)
  87448. + */
  87449. +static void talitos_errorprocessing(struct talitos_softc *sc)
  87450. +{
  87451. + unsigned long flags;
  87452. + int i, j;
  87453. +
  87454. + /* disable further scheduling until under control */
  87455. + spin_lock_irqsave(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  87456. +
  87457. + if (debug) dump_talitos_status(sc);
  87458. + /* go through descriptors, try and salvage those successfully done,
  87459. + * and EIO those that weren't
  87460. + */
  87461. + for (i = 0; i < sc->sc_num_channels; i++) {
  87462. + spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
  87463. + for (j = 0; j < sc->sc_chfifo_len; j++) {
  87464. + if (sc->sc_chnfifo[i][j].cf_desc.hdr) {
  87465. + if ((sc->sc_chnfifo[i][j].cf_desc.hdr
  87466. + & TALITOS_HDR_DONE_BITS)
  87467. + != TALITOS_HDR_DONE_BITS) {
  87468. + /* this one didn't finish */
  87469. + /* signify in crp->etype */
  87470. + sc->sc_chnfifo[i][j].cf_crp->crp_etype
  87471. + = EIO;
  87472. + }
  87473. + } else
  87474. + continue; /* free entry */
  87475. + /* either way, notify ocf */
  87476. + crypto_done(sc->sc_chnfifo[i][j].cf_crp);
  87477. + /* and tag it available again
  87478. + *
  87479. + * memset to ensure correct descriptor formation by
  87480. + * avoiding inadvertently setting "optional" entries
  87481. + * e.g. not using "optional" dptr2 MD/HMAC processing
  87482. + */
  87483. + memset(&sc->sc_chnfifo[i][j].cf_desc,
  87484. + 0, sizeof(struct talitos_desc));
  87485. + }
  87486. + spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);
  87487. + }
  87488. + /* reset and initialize the SEC h/w device */
  87489. + talitos_reset_device(sc);
  87490. + talitos_init_device(sc);
  87491. +#ifdef CONFIG_OCF_RANDOMHARVEST
  87492. + if (sc->sc_exec_units & TALITOS_HAS_EU_RNG)
  87493. + talitos_rng_init(sc);
  87494. +#endif
  87495. +
  87496. + /* Okay. Stand by. */
  87497. + spin_unlock_irqrestore(&sc->sc_chnfifolock[sc->sc_num_channels], flags);
  87498. +
  87499. + return;
  87500. +}
  87501. +
  87502. +/* go through all channels descriptors, notifying OCF what's been done */
  87503. +static void talitos_doneprocessing(struct talitos_softc *sc)
  87504. +{
  87505. + unsigned long flags;
  87506. + int i, j;
  87507. +
  87508. + /* go through descriptors looking for done bits */
  87509. + for (i = 0; i < sc->sc_num_channels; i++) {
  87510. + spin_lock_irqsave(&sc->sc_chnfifolock[i], flags);
  87511. + for (j = 0; j < sc->sc_chfifo_len; j++) {
  87512. + /* descriptor has done bits set? */
  87513. + if ((sc->sc_chnfifo[i][j].cf_desc.hdr
  87514. + & TALITOS_HDR_DONE_BITS)
  87515. + == TALITOS_HDR_DONE_BITS) {
  87516. + /* notify ocf */
  87517. + crypto_done(sc->sc_chnfifo[i][j].cf_crp);
  87518. + /* and tag it available again
  87519. + *
  87520. + * memset to ensure correct descriptor formation by
  87521. + * avoiding inadvertently setting "optional" entries
  87522. + * e.g. not using "optional" dptr2 MD/HMAC processing
  87523. + */
  87524. + memset(&sc->sc_chnfifo[i][j].cf_desc,
  87525. + 0, sizeof(struct talitos_desc));
  87526. + }
  87527. + }
  87528. + spin_unlock_irqrestore(&sc->sc_chnfifolock[i], flags);
  87529. + }
  87530. + return;
  87531. +}
  87532. +
  87533. +static irqreturn_t
  87534. +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
  87535. +talitos_intr(int irq, void *arg)
  87536. +#else
  87537. +talitos_intr(int irq, void *arg, struct pt_regs *regs)
  87538. +#endif
  87539. +{
  87540. + struct talitos_softc *sc = arg;
  87541. + u_int32_t v, v_hi;
  87542. +
  87543. + /* ack */
  87544. + v = talitos_read(sc->sc_base_addr + TALITOS_ISR);
  87545. + v_hi = talitos_read(sc->sc_base_addr + TALITOS_ISR_HI);
  87546. + talitos_write(sc->sc_base_addr + TALITOS_ICR, v);
  87547. + talitos_write(sc->sc_base_addr + TALITOS_ICR_HI, v_hi);
  87548. +
  87549. + if (unlikely(v & TALITOS_ISR_ERROR)) {
  87550. + /* Okay, Houston, we've had a problem here. */
  87551. + printk(KERN_DEBUG "%s: got error interrupt - ISR 0x%08x_%08x\n",
  87552. + device_get_nameunit(sc->sc_cdev), v, v_hi);
  87553. + talitos_errorprocessing(sc);
  87554. + } else
  87555. + if (likely(v & TALITOS_ISR_DONE)) {
  87556. + talitos_doneprocessing(sc);
  87557. + }
  87558. + return IRQ_HANDLED;
  87559. +}
  87560. +
  87561. +/*
  87562. + * Initialize registers we need to touch only once.
  87563. + */
  87564. +static void
  87565. +talitos_init_device(struct talitos_softc *sc)
  87566. +{
  87567. + u_int32_t v;
  87568. + int i;
  87569. +
  87570. + DPRINTF("%s()\n", __FUNCTION__);
  87571. +
  87572. + /* init all channels */
  87573. + for (i = 0; i < sc->sc_num_channels; i++) {
  87574. + v = talitos_read(sc->sc_base_addr +
  87575. + i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI);
  87576. + v |= TALITOS_CH_CCCR_HI_CDWE
  87577. + | TALITOS_CH_CCCR_HI_CDIE; /* invoke interrupt if done */
  87578. + talitos_write(sc->sc_base_addr +
  87579. + i*TALITOS_CH_OFFSET + TALITOS_CH_CCCR_HI, v);
  87580. + }
  87581. + /* enable all interrupts */
  87582. + v = talitos_read(sc->sc_base_addr + TALITOS_IMR);
  87583. + v |= TALITOS_IMR_ALL;
  87584. + talitos_write(sc->sc_base_addr + TALITOS_IMR, v);
  87585. + v = talitos_read(sc->sc_base_addr + TALITOS_IMR_HI);
  87586. + v |= TALITOS_IMR_HI_ERRONLY;
  87587. + talitos_write(sc->sc_base_addr + TALITOS_IMR_HI, v);
  87588. + return;
  87589. +}
  87590. +
  87591. +/*
  87592. + * set the master reset bit on the device.
  87593. + */
  87594. +static void
  87595. +talitos_reset_device_master(struct talitos_softc *sc)
  87596. +{
  87597. + u_int32_t v;
  87598. +
  87599. + /* Reset the device by writing 1 to MCR:SWR and waiting 'til cleared */
  87600. + v = talitos_read(sc->sc_base_addr + TALITOS_MCR);
  87601. + talitos_write(sc->sc_base_addr + TALITOS_MCR, v | TALITOS_MCR_SWR);
  87602. +
  87603. + while (talitos_read(sc->sc_base_addr + TALITOS_MCR) & TALITOS_MCR_SWR)
  87604. + cpu_relax();
  87605. +
  87606. + return;
  87607. +}
  87608. +
  87609. +/*
  87610. + * Resets the device. Values in the registers are left as is
  87611. + * from the reset (i.e. initial values are assigned elsewhere).
  87612. + */
  87613. +static void
  87614. +talitos_reset_device(struct talitos_softc *sc)
  87615. +{
  87616. + u_int32_t v;
  87617. + int i;
  87618. +
  87619. + DPRINTF("%s()\n", __FUNCTION__);
  87620. +
  87621. + /*
  87622. + * Master reset
  87623. + * errata documentation: warning: certain SEC interrupts
  87624. + * are not fully cleared by writing the MCR:SWR bit,
  87625. + * set bit twice to completely reset
  87626. + */
  87627. + talitos_reset_device_master(sc); /* once */
  87628. + talitos_reset_device_master(sc); /* and once again */
  87629. +
  87630. + /* reset all channels */
  87631. + for (i = 0; i < sc->sc_num_channels; i++) {
  87632. + v = talitos_read(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  87633. + TALITOS_CH_CCCR);
  87634. + talitos_write(sc->sc_base_addr + i*TALITOS_CH_OFFSET +
  87635. + TALITOS_CH_CCCR, v | TALITOS_CH_CCCR_RESET);
  87636. + }
  87637. +}
  87638. +
  87639. +/* Set up the crypto device structure, private data,
  87640. + * and anything else we need before we start */
  87641. +#ifdef CONFIG_PPC_MERGE
  87642. +static int talitos_probe(struct of_device *ofdev, const struct of_device_id *match)
  87643. +#else
  87644. +static int talitos_probe(struct platform_device *pdev)
  87645. +#endif
  87646. +{
  87647. + struct talitos_softc *sc = NULL;
  87648. + struct resource *r;
  87649. +#ifdef CONFIG_PPC_MERGE
  87650. + struct device *device = &ofdev->dev;
  87651. + struct device_node *np = ofdev->node;
  87652. + const unsigned int *prop;
  87653. + int err;
  87654. + struct resource res;
  87655. +#endif
  87656. + static int num_chips = 0;
  87657. + int rc;
  87658. + int i;
  87659. +
  87660. + DPRINTF("%s()\n", __FUNCTION__);
  87661. +
  87662. + sc = (struct talitos_softc *) kmalloc(sizeof(*sc), GFP_KERNEL);
  87663. + if (!sc)
  87664. + return -ENOMEM;
  87665. + memset(sc, 0, sizeof(*sc));
  87666. +
  87667. + softc_device_init(sc, DRV_NAME, num_chips, talitos_methods);
  87668. +
  87669. + sc->sc_irq = -1;
  87670. + sc->sc_cid = -1;
  87671. +#ifndef CONFIG_PPC_MERGE
  87672. + sc->sc_dev = pdev;
  87673. +#endif
  87674. + sc->sc_num = num_chips++;
  87675. +
  87676. +#ifdef CONFIG_PPC_MERGE
  87677. + dev_set_drvdata(device, sc);
  87678. +#else
  87679. + platform_set_drvdata(sc->sc_dev, sc);
  87680. +#endif
  87681. +
  87682. + /* get the irq line */
  87683. +#ifdef CONFIG_PPC_MERGE
  87684. + err = of_address_to_resource(np, 0, &res);
  87685. + if (err)
  87686. + return -EINVAL;
  87687. + r = &res;
  87688. +
  87689. + sc->sc_irq = irq_of_parse_and_map(np, 0);
  87690. +#else
  87691. + /* get a pointer to the register memory */
  87692. + r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  87693. +
  87694. + sc->sc_irq = platform_get_irq(pdev, 0);
  87695. +#endif
  87696. + rc = request_irq(sc->sc_irq, talitos_intr, 0,
  87697. + device_get_nameunit(sc->sc_cdev), sc);
  87698. + if (rc) {
  87699. + printk(KERN_ERR "%s: failed to hook irq %d\n",
  87700. + device_get_nameunit(sc->sc_cdev), sc->sc_irq);
  87701. + sc->sc_irq = -1;
  87702. + goto out;
  87703. + }
  87704. +
  87705. + sc->sc_base_addr = (ocf_iomem_t) ioremap(r->start, (r->end - r->start));
  87706. + if (!sc->sc_base_addr) {
  87707. + printk(KERN_ERR "%s: failed to ioremap\n",
  87708. + device_get_nameunit(sc->sc_cdev));
  87709. + goto out;
  87710. + }
  87711. +
  87712. + /* figure out our SEC's properties and capabilities */
  87713. + sc->sc_chiprev = (u64)talitos_read(sc->sc_base_addr + TALITOS_ID) << 32
  87714. + | talitos_read(sc->sc_base_addr + TALITOS_ID_HI);
  87715. + DPRINTF("sec id 0x%llx\n", sc->sc_chiprev);
  87716. +
  87717. +#ifdef CONFIG_PPC_MERGE
  87718. + /* get SEC properties from device tree, defaulting to SEC 2.0 */
  87719. +
  87720. + prop = of_get_property(np, "num-channels", NULL);
  87721. + sc->sc_num_channels = prop ? *prop : TALITOS_NCHANNELS_SEC_2_0;
  87722. +
  87723. + prop = of_get_property(np, "channel-fifo-len", NULL);
  87724. + sc->sc_chfifo_len = prop ? *prop : TALITOS_CHFIFOLEN_SEC_2_0;
  87725. +
  87726. + prop = of_get_property(np, "exec-units-mask", NULL);
  87727. + sc->sc_exec_units = prop ? *prop : TALITOS_HAS_EUS_SEC_2_0;
  87728. +
  87729. + prop = of_get_property(np, "descriptor-types-mask", NULL);
  87730. + sc->sc_desc_types = prop ? *prop : TALITOS_HAS_DESCTYPES_SEC_2_0;
  87731. +#else
  87732. + /* bulk should go away with openfirmware flat device tree support */
  87733. + if (sc->sc_chiprev & TALITOS_ID_SEC_2_0) {
  87734. + sc->sc_num_channels = TALITOS_NCHANNELS_SEC_2_0;
  87735. + sc->sc_chfifo_len = TALITOS_CHFIFOLEN_SEC_2_0;
  87736. + sc->sc_exec_units = TALITOS_HAS_EUS_SEC_2_0;
  87737. + sc->sc_desc_types = TALITOS_HAS_DESCTYPES_SEC_2_0;
  87738. + } else {
  87739. + printk(KERN_ERR "%s: failed to id device\n",
  87740. + device_get_nameunit(sc->sc_cdev));
  87741. + goto out;
  87742. + }
  87743. +#endif
  87744. +
  87745. + /* + 1 is for the meta-channel lock used by the channel scheduler */
  87746. + sc->sc_chnfifolock = (spinlock_t *) kmalloc(
  87747. + (sc->sc_num_channels + 1) * sizeof(spinlock_t), GFP_KERNEL);
  87748. + if (!sc->sc_chnfifolock)
  87749. + goto out;
  87750. + for (i = 0; i < sc->sc_num_channels + 1; i++) {
  87751. + spin_lock_init(&sc->sc_chnfifolock[i]);
  87752. + }
  87753. +
  87754. + sc->sc_chnlastalg = (int *) kmalloc(
  87755. + sc->sc_num_channels * sizeof(int), GFP_KERNEL);
  87756. + if (!sc->sc_chnlastalg)
  87757. + goto out;
  87758. + memset(sc->sc_chnlastalg, 0, sc->sc_num_channels * sizeof(int));
  87759. +
  87760. + sc->sc_chnfifo = (struct desc_cryptop_pair **) kmalloc(
  87761. + sc->sc_num_channels * sizeof(struct desc_cryptop_pair *),
  87762. + GFP_KERNEL);
  87763. + if (!sc->sc_chnfifo)
  87764. + goto out;
  87765. + for (i = 0; i < sc->sc_num_channels; i++) {
  87766. + sc->sc_chnfifo[i] = (struct desc_cryptop_pair *) kmalloc(
  87767. + sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair),
  87768. + GFP_KERNEL);
  87769. + if (!sc->sc_chnfifo[i])
  87770. + goto out;
  87771. + memset(sc->sc_chnfifo[i], 0,
  87772. + sc->sc_chfifo_len * sizeof(struct desc_cryptop_pair));
  87773. + }
  87774. +
  87775. + /* reset and initialize the SEC h/w device */
  87776. + talitos_reset_device(sc);
  87777. + talitos_init_device(sc);
  87778. +
  87779. + sc->sc_cid = crypto_get_driverid(softc_get_device(sc),CRYPTOCAP_F_HARDWARE);
  87780. + if (sc->sc_cid < 0) {
  87781. + printk(KERN_ERR "%s: could not get crypto driver id\n",
  87782. + device_get_nameunit(sc->sc_cdev));
  87783. + goto out;
  87784. + }
  87785. +
  87786. + /* register algorithms with the framework */
  87787. + printk("%s:", device_get_nameunit(sc->sc_cdev));
  87788. +
  87789. + if (sc->sc_exec_units & TALITOS_HAS_EU_RNG) {
  87790. + printk(" rng");
  87791. +#ifdef CONFIG_OCF_RANDOMHARVEST
  87792. + talitos_rng_init(sc);
  87793. + crypto_rregister(sc->sc_cid, talitos_read_random, sc);
  87794. +#endif
  87795. + }
  87796. + if (sc->sc_exec_units & TALITOS_HAS_EU_DEU) {
  87797. + printk(" des/3des");
  87798. + crypto_register(sc->sc_cid, CRYPTO_3DES_CBC, 0, 0);
  87799. + crypto_register(sc->sc_cid, CRYPTO_DES_CBC, 0, 0);
  87800. + }
  87801. + if (sc->sc_exec_units & TALITOS_HAS_EU_AESU) {
  87802. + printk(" aes");
  87803. + crypto_register(sc->sc_cid, CRYPTO_AES_CBC, 0, 0);
  87804. + }
  87805. + if (sc->sc_exec_units & TALITOS_HAS_EU_MDEU) {
  87806. + printk(" md5");
  87807. + crypto_register(sc->sc_cid, CRYPTO_MD5, 0, 0);
  87808. + /* HMAC support only with IPsec for now */
  87809. + crypto_register(sc->sc_cid, CRYPTO_MD5_HMAC, 0, 0);
  87810. + printk(" sha1");
  87811. + crypto_register(sc->sc_cid, CRYPTO_SHA1, 0, 0);
  87812. + /* HMAC support only with IPsec for now */
  87813. + crypto_register(sc->sc_cid, CRYPTO_SHA1_HMAC, 0, 0);
  87814. + }
  87815. + printk("\n");
  87816. + return 0;
  87817. +
  87818. +out:
  87819. +#ifndef CONFIG_PPC_MERGE
  87820. + talitos_remove(pdev);
  87821. +#endif
  87822. + return -ENOMEM;
  87823. +}
  87824. +
  87825. +#ifdef CONFIG_PPC_MERGE
  87826. +static int talitos_remove(struct of_device *ofdev)
  87827. +#else
  87828. +static int talitos_remove(struct platform_device *pdev)
  87829. +#endif
  87830. +{
  87831. +#ifdef CONFIG_PPC_MERGE
  87832. + struct talitos_softc *sc = dev_get_drvdata(&ofdev->dev);
  87833. +#else
  87834. + struct talitos_softc *sc = platform_get_drvdata(pdev);
  87835. +#endif
  87836. + int i;
  87837. +
  87838. + DPRINTF("%s()\n", __FUNCTION__);
  87839. + if (sc->sc_cid >= 0)
  87840. + crypto_unregister_all(sc->sc_cid);
  87841. + if (sc->sc_chnfifo) {
  87842. + for (i = 0; i < sc->sc_num_channels; i++)
  87843. + if (sc->sc_chnfifo[i])
  87844. + kfree(sc->sc_chnfifo[i]);
  87845. + kfree(sc->sc_chnfifo);
  87846. + }
  87847. + if (sc->sc_chnlastalg)
  87848. + kfree(sc->sc_chnlastalg);
  87849. + if (sc->sc_chnfifolock)
  87850. + kfree(sc->sc_chnfifolock);
  87851. + if (sc->sc_irq != -1)
  87852. + free_irq(sc->sc_irq, sc);
  87853. + if (sc->sc_base_addr)
  87854. + iounmap((void *) sc->sc_base_addr);
  87855. + kfree(sc);
  87856. + return 0;
  87857. +}
  87858. +
  87859. +#ifdef CONFIG_PPC_MERGE
  87860. +static struct of_device_id talitos_match[] = {
  87861. + {
  87862. + .type = "crypto",
  87863. + .compatible = "talitos",
  87864. + },
  87865. + {},
  87866. +};
  87867. +
  87868. +MODULE_DEVICE_TABLE(of, talitos_match);
  87869. +
  87870. +static struct of_platform_driver talitos_driver = {
  87871. + .name = DRV_NAME,
  87872. + .match_table = talitos_match,
  87873. + .probe = talitos_probe,
  87874. + .remove = talitos_remove,
  87875. +};
  87876. +
  87877. +static int __init talitos_init(void)
  87878. +{
  87879. + return of_register_platform_driver(&talitos_driver);
  87880. +}
  87881. +
  87882. +static void __exit talitos_exit(void)
  87883. +{
  87884. + of_unregister_platform_driver(&talitos_driver);
  87885. +}
  87886. +#else
  87887. +/* Structure for a platform device driver */
  87888. +static struct platform_driver talitos_driver = {
  87889. + .probe = talitos_probe,
  87890. + .remove = talitos_remove,
  87891. + .driver = {
  87892. + .name = "fsl-sec2",
  87893. + }
  87894. +};
  87895. +
  87896. +static int __init talitos_init(void)
  87897. +{
  87898. + return platform_driver_register(&talitos_driver);
  87899. +}
  87900. +
  87901. +static void __exit talitos_exit(void)
  87902. +{
  87903. + platform_driver_unregister(&talitos_driver);
  87904. +}
  87905. +#endif
  87906. +
  87907. +module_init(talitos_init);
  87908. +module_exit(talitos_exit);
  87909. +
  87910. +MODULE_LICENSE("Dual BSD/GPL");
  87911. +MODULE_AUTHOR("kim.phillips@freescale.com");
  87912. +MODULE_DESCRIPTION("OCF driver for Freescale SEC (talitos)");
  87913. diff -Nur linux-2.6.39.orig/crypto/ocf/talitos/talitos_dev.h linux-2.6.39/crypto/ocf/talitos/talitos_dev.h
  87914. --- linux-2.6.39.orig/crypto/ocf/talitos/talitos_dev.h 1970-01-01 01:00:00.000000000 +0100
  87915. +++ linux-2.6.39/crypto/ocf/talitos/talitos_dev.h 2011-08-01 14:38:19.000000000 +0200
  87916. @@ -0,0 +1,277 @@
  87917. +/*
  87918. + * Freescale SEC (talitos) device dependent data structures
  87919. + *
  87920. + * Copyright (c) 2006 Freescale Semiconductor, Inc.
  87921. + *
  87922. + * Redistribution and use in source and binary forms, with or without
  87923. + * modification, are permitted provided that the following conditions
  87924. + * are met:
  87925. + *
  87926. + * 1. Redistributions of source code must retain the above copyright
  87927. + * notice, this list of conditions and the following disclaimer.
  87928. + * 2. Redistributions in binary form must reproduce the above copyright
  87929. + * notice, this list of conditions and the following disclaimer in the
  87930. + * documentation and/or other materials provided with the distribution.
  87931. + * 3. The name of the author may not be used to endorse or promote products
  87932. + * derived from this software without specific prior written permission.
  87933. + *
  87934. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  87935. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  87936. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  87937. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  87938. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  87939. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  87940. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  87941. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  87942. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  87943. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  87944. + *
  87945. + */
  87946. +
  87947. +/* device ID register values */
  87948. +#define TALITOS_ID_SEC_2_0 0x40
  87949. +#define TALITOS_ID_SEC_2_1 0x40 /* cross ref with IP block revision reg */
  87950. +
  87951. +/*
  87952. + * following num_channels, channel-fifo-depth, exec-unit-mask, and
  87953. + * descriptor-types-mask are for forward-compatibility with openfirmware
  87954. + * flat device trees
  87955. + */
  87956. +
  87957. +/*
  87958. + * num_channels : the number of channels available in each SEC version.
  87959. + */
  87960. +
  87961. +/* n.b. this driver requires these values be a power of 2 */
  87962. +#define TALITOS_NCHANNELS_SEC_1_0 4
  87963. +#define TALITOS_NCHANNELS_SEC_1_2 1
  87964. +#define TALITOS_NCHANNELS_SEC_2_0 4
  87965. +#define TALITOS_NCHANNELS_SEC_2_01 4
  87966. +#define TALITOS_NCHANNELS_SEC_2_1 4
  87967. +#define TALITOS_NCHANNELS_SEC_2_4 4
  87968. +
  87969. +/*
  87970. + * channel-fifo-depth : The number of descriptor
  87971. + * pointers a channel fetch fifo can hold.
  87972. + */
  87973. +#define TALITOS_CHFIFOLEN_SEC_1_0 1
  87974. +#define TALITOS_CHFIFOLEN_SEC_1_2 1
  87975. +#define TALITOS_CHFIFOLEN_SEC_2_0 24
  87976. +#define TALITOS_CHFIFOLEN_SEC_2_01 24
  87977. +#define TALITOS_CHFIFOLEN_SEC_2_1 24
  87978. +#define TALITOS_CHFIFOLEN_SEC_2_4 24
  87979. +
  87980. +/*
  87981. + * exec-unit-mask : The bitmask representing what Execution Units (EUs)
  87982. + * are available. EU information should be encoded following the SEC's
  87983. + * EU_SEL0 bitfield documentation, i.e. as follows:
  87984. + *
  87985. + * bit 31 = set if SEC permits no-EU selection (should be always set)
  87986. + * bit 30 = set if SEC has the ARC4 EU (AFEU)
  87987. + * bit 29 = set if SEC has the des/3des EU (DEU)
  87988. + * bit 28 = set if SEC has the message digest EU (MDEU)
  87989. + * bit 27 = set if SEC has the random number generator EU (RNG)
  87990. + * bit 26 = set if SEC has the public key EU (PKEU)
  87991. + * bit 25 = set if SEC has the aes EU (AESU)
  87992. + * bit 24 = set if SEC has the Kasumi EU (KEU)
  87993. + *
  87994. + */
  87995. +#define TALITOS_HAS_EU_NONE (1<<0)
  87996. +#define TALITOS_HAS_EU_AFEU (1<<1)
  87997. +#define TALITOS_HAS_EU_DEU (1<<2)
  87998. +#define TALITOS_HAS_EU_MDEU (1<<3)
  87999. +#define TALITOS_HAS_EU_RNG (1<<4)
  88000. +#define TALITOS_HAS_EU_PKEU (1<<5)
  88001. +#define TALITOS_HAS_EU_AESU (1<<6)
  88002. +#define TALITOS_HAS_EU_KEU (1<<7)
  88003. +
  88004. +/* the corresponding masks for each SEC version */
  88005. +#define TALITOS_HAS_EUS_SEC_1_0 0x7f
  88006. +#define TALITOS_HAS_EUS_SEC_1_2 0x4d
  88007. +#define TALITOS_HAS_EUS_SEC_2_0 0x7f
  88008. +#define TALITOS_HAS_EUS_SEC_2_01 0x7f
  88009. +#define TALITOS_HAS_EUS_SEC_2_1 0xff
  88010. +#define TALITOS_HAS_EUS_SEC_2_4 0x7f
  88011. +
  88012. +/*
  88013. + * descriptor-types-mask : The bitmask representing what descriptors
  88014. + * are available. Descriptor type information should be encoded
  88015. + * following the SEC's Descriptor Header Dword DESC_TYPE field
  88016. + * documentation, i.e. as follows:
  88017. + *
  88018. + * bit 0 = set if SEC supports the aesu_ctr_nonsnoop desc. type
  88019. + * bit 1 = set if SEC supports the ipsec_esp descriptor type
  88020. + * bit 2 = set if SEC supports the common_nonsnoop desc. type
  88021. + * bit 3 = set if SEC supports the 802.11i AES ccmp desc. type
  88022. + * bit 4 = set if SEC supports the hmac_snoop_no_afeu desc. type
  88023. + * bit 5 = set if SEC supports the srtp descriptor type
  88024. + * bit 6 = set if SEC supports the non_hmac_snoop_no_afeu desc.type
  88025. + * bit 7 = set if SEC supports the pkeu_assemble descriptor type
  88026. + * bit 8 = set if SEC supports the aesu_key_expand_output desc.type
  88027. + * bit 9 = set if SEC supports the pkeu_ptmul descriptor type
  88028. + * bit 10 = set if SEC supports the common_nonsnoop_afeu desc. type
  88029. + * bit 11 = set if SEC supports the pkeu_ptadd_dbl descriptor type
  88030. + *
  88031. + * ..and so on and so forth.
  88032. + */
  88033. +#define TALITOS_HAS_DT_AESU_CTR_NONSNOOP (1<<0)
  88034. +#define TALITOS_HAS_DT_IPSEC_ESP (1<<1)
  88035. +#define TALITOS_HAS_DT_COMMON_NONSNOOP (1<<2)
  88036. +
  88037. +/* the corresponding masks for each SEC version */
  88038. +#define TALITOS_HAS_DESCTYPES_SEC_2_0 0x01010ebf
  88039. +#define TALITOS_HAS_DESCTYPES_SEC_2_1 0x012b0ebf
  88040. +
  88041. +/*
  88042. + * a TALITOS_xxx_HI address points to the low data bits (32-63) of the register
  88043. + */
  88044. +
  88045. +/* global register offset addresses */
  88046. +#define TALITOS_ID 0x1020
  88047. +#define TALITOS_ID_HI 0x1024
  88048. +#define TALITOS_MCR 0x1030 /* master control register */
  88049. +#define TALITOS_MCR_HI 0x1038 /* master control register */
  88050. +#define TALITOS_MCR_SWR 0x1
  88051. +#define TALITOS_IMR 0x1008 /* interrupt mask register */
  88052. +#define TALITOS_IMR_ALL 0x00010fff /* enable all interrupts mask */
  88053. +#define TALITOS_IMR_ERRONLY 0x00010aaa /* enable error interrupts */
  88054. +#define TALITOS_IMR_HI 0x100C /* interrupt mask register */
  88055. +#define TALITOS_IMR_HI_ALL 0x00323333 /* enable all interrupts mask */
  88056. +#define TALITOS_IMR_HI_ERRONLY 0x00222222 /* enable error interrupts */
  88057. +#define TALITOS_ISR 0x1010 /* interrupt status register */
  88058. +#define TALITOS_ISR_ERROR 0x00010faa /* errors mask */
  88059. +#define TALITOS_ISR_DONE 0x00000055 /* channel(s) done mask */
  88060. +#define TALITOS_ISR_HI 0x1014 /* interrupt status register */
  88061. +#define TALITOS_ICR 0x1018 /* interrupt clear register */
  88062. +#define TALITOS_ICR_HI 0x101C /* interrupt clear register */
  88063. +
  88064. +/* channel register address stride */
  88065. +#define TALITOS_CH_OFFSET 0x100
  88066. +
  88067. +/* channel register offset addresses and bits */
  88068. +#define TALITOS_CH_CCCR 0x1108 /* Crypto-Channel Config Register */
  88069. +#define TALITOS_CH_CCCR_RESET 0x1 /* Channel Reset bit */
  88070. +#define TALITOS_CH_CCCR_HI 0x110c /* Crypto-Channel Config Register */
  88071. +#define TALITOS_CH_CCCR_HI_CDWE 0x10 /* Channel done writeback enable bit */
  88072. +#define TALITOS_CH_CCCR_HI_NT 0x4 /* Notification type bit */
  88073. +#define TALITOS_CH_CCCR_HI_CDIE 0x2 /* Channel Done Interrupt Enable bit */
  88074. +#define TALITOS_CH_CCPSR 0x1110 /* Crypto-Channel Pointer Status Reg */
  88075. +#define TALITOS_CH_CCPSR_HI 0x1114 /* Crypto-Channel Pointer Status Reg */
  88076. +#define TALITOS_CH_FF 0x1148 /* Fetch FIFO */
  88077. +#define TALITOS_CH_FF_HI 0x114c /* Fetch FIFO's FETCH_ADRS */
  88078. +#define TALITOS_CH_CDPR 0x1140 /* Crypto-Channel Pointer Status Reg */
  88079. +#define TALITOS_CH_CDPR_HI 0x1144 /* Crypto-Channel Pointer Status Reg */
  88080. +#define TALITOS_CH_DESCBUF 0x1180 /* (thru 11bf) Crypto-Channel
  88081. + * Descriptor Buffer (debug) */
  88082. +
  88083. +/* execution unit register offset addresses and bits */
  88084. +#define TALITOS_DEUSR 0x2028 /* DEU status register */
  88085. +#define TALITOS_DEUSR_HI 0x202c /* DEU status register */
  88086. +#define TALITOS_DEUISR 0x2030 /* DEU interrupt status register */
  88087. +#define TALITOS_DEUISR_HI 0x2034 /* DEU interrupt status register */
  88088. +#define TALITOS_DEUICR 0x2038 /* DEU interrupt control register */
  88089. +#define TALITOS_DEUICR_HI 0x203c /* DEU interrupt control register */
  88090. +#define TALITOS_AESUISR 0x4030 /* AESU interrupt status register */
  88091. +#define TALITOS_AESUISR_HI 0x4034 /* AESU interrupt status register */
  88092. +#define TALITOS_AESUICR 0x4038 /* AESU interrupt control register */
  88093. +#define TALITOS_AESUICR_HI 0x403c /* AESU interrupt control register */
  88094. +#define TALITOS_MDEUISR 0x6030 /* MDEU interrupt status register */
  88095. +#define TALITOS_MDEUISR_HI 0x6034 /* MDEU interrupt status register */
  88096. +#define TALITOS_RNGSR 0xa028 /* RNG status register */
  88097. +#define TALITOS_RNGSR_HI 0xa02c /* RNG status register */
  88098. +#define TALITOS_RNGSR_HI_RD 0x1 /* RNG Reset done */
  88099. +#define TALITOS_RNGSR_HI_OFL 0xff0000/* number of dwords in RNG output FIFO*/
  88100. +#define TALITOS_RNGDSR 0xa010 /* RNG data size register */
  88101. +#define TALITOS_RNGDSR_HI 0xa014 /* RNG data size register */
  88102. +#define TALITOS_RNG_FIFO 0xa800 /* RNG FIFO - pool of random numbers */
  88103. +#define TALITOS_RNGISR 0xa030 /* RNG Interrupt status register */
  88104. +#define TALITOS_RNGISR_HI 0xa034 /* RNG Interrupt status register */
  88105. +#define TALITOS_RNGRCR 0xa018 /* RNG Reset control register */
  88106. +#define TALITOS_RNGRCR_HI 0xa01c /* RNG Reset control register */
  88107. +#define TALITOS_RNGRCR_HI_SR 0x1 /* RNG RNGRCR:Software Reset */
  88108. +
  88109. +/* descriptor pointer entry */
  88110. +struct talitos_desc_ptr {
  88111. + u16 len; /* length */
  88112. + u8 extent; /* jump (to s/g link table) and extent */
  88113. + u8 res; /* reserved */
  88114. + u32 ptr; /* pointer */
  88115. +};
  88116. +
  88117. +/* descriptor */
  88118. +struct talitos_desc {
  88119. + u32 hdr; /* header */
  88120. + u32 res; /* reserved */
  88121. + struct talitos_desc_ptr ptr[7]; /* ptr/len pair array */
  88122. +};
  88123. +
  88124. +/* talitos descriptor header (hdr) bits */
  88125. +
  88126. +/* primary execution unit select */
  88127. +#define TALITOS_SEL0_AFEU 0x10000000
  88128. +#define TALITOS_SEL0_DEU 0x20000000
  88129. +#define TALITOS_SEL0_MDEU 0x30000000
  88130. +#define TALITOS_SEL0_RNG 0x40000000
  88131. +#define TALITOS_SEL0_PKEU 0x50000000
  88132. +#define TALITOS_SEL0_AESU 0x60000000
  88133. +
  88134. +/* primary execution unit mode (MODE0) and derivatives */
  88135. +#define TALITOS_MODE0_AESU_CBC 0x00200000
  88136. +#define TALITOS_MODE0_AESU_ENC 0x00100000
  88137. +#define TALITOS_MODE0_DEU_CBC 0x00400000
  88138. +#define TALITOS_MODE0_DEU_3DES 0x00200000
  88139. +#define TALITOS_MODE0_DEU_ENC 0x00100000
  88140. +#define TALITOS_MODE0_MDEU_INIT 0x01000000 /* init starting regs */
  88141. +#define TALITOS_MODE0_MDEU_HMAC 0x00800000
  88142. +#define TALITOS_MODE0_MDEU_PAD 0x00400000 /* PD */
  88143. +#define TALITOS_MODE0_MDEU_MD5 0x00200000
  88144. +#define TALITOS_MODE0_MDEU_SHA256 0x00100000
  88145. +#define TALITOS_MODE0_MDEU_SHA1 0x00000000 /* SHA-160 */
  88146. +#define TALITOS_MODE0_MDEU_MD5_HMAC \
  88147. + (TALITOS_MODE0_MDEU_MD5 | TALITOS_MODE0_MDEU_HMAC)
  88148. +#define TALITOS_MODE0_MDEU_SHA256_HMAC \
  88149. + (TALITOS_MODE0_MDEU_SHA256 | TALITOS_MODE0_MDEU_HMAC)
  88150. +#define TALITOS_MODE0_MDEU_SHA1_HMAC \
  88151. + (TALITOS_MODE0_MDEU_SHA1 | TALITOS_MODE0_MDEU_HMAC)
  88152. +
  88153. +/* secondary execution unit select (SEL1) */
  88154. +/* it's MDEU or nothing */
  88155. +#define TALITOS_SEL1_MDEU 0x00030000
  88156. +
  88157. +/* secondary execution unit mode (MODE1) and derivatives */
  88158. +#define TALITOS_MODE1_MDEU_INIT 0x00001000 /* init starting regs */
  88159. +#define TALITOS_MODE1_MDEU_HMAC 0x00000800
  88160. +#define TALITOS_MODE1_MDEU_PAD 0x00000400 /* PD */
  88161. +#define TALITOS_MODE1_MDEU_MD5 0x00000200
  88162. +#define TALITOS_MODE1_MDEU_SHA256 0x00000100
  88163. +#define TALITOS_MODE1_MDEU_SHA1 0x00000000 /* SHA-160 */
  88164. +#define TALITOS_MODE1_MDEU_MD5_HMAC \
  88165. + (TALITOS_MODE1_MDEU_MD5 | TALITOS_MODE1_MDEU_HMAC)
  88166. +#define TALITOS_MODE1_MDEU_SHA256_HMAC \
  88167. + (TALITOS_MODE1_MDEU_SHA256 | TALITOS_MODE1_MDEU_HMAC)
  88168. +#define TALITOS_MODE1_MDEU_SHA1_HMAC \
  88169. + (TALITOS_MODE1_MDEU_SHA1 | TALITOS_MODE1_MDEU_HMAC)
  88170. +
  88171. +/* direction of overall data flow (DIR) */
  88172. +#define TALITOS_DIR_OUTBOUND 0x00000000
  88173. +#define TALITOS_DIR_INBOUND 0x00000002
  88174. +
  88175. +/* done notification (DN) */
  88176. +#define TALITOS_DONE_NOTIFY 0x00000001
  88177. +
  88178. +/* descriptor types */
  88179. +/* odd numbers here are valid on SEC2 and greater only (e.g. ipsec_esp) */
  88180. +#define TD_TYPE_AESU_CTR_NONSNOOP (0 << 3)
  88181. +#define TD_TYPE_IPSEC_ESP (1 << 3)
  88182. +#define TD_TYPE_COMMON_NONSNOOP_NO_AFEU (2 << 3)
  88183. +#define TD_TYPE_HMAC_SNOOP_NO_AFEU (4 << 3)
  88184. +
  88185. +#define TALITOS_HDR_DONE_BITS 0xff000000
  88186. +
  88187. +#define DPRINTF(a...) do { \
  88188. + if (debug) { \
  88189. + printk("%s: ", sc ? \
  88190. + device_get_nameunit(sc->sc_cdev) : "talitos"); \
  88191. + printk(a); \
  88192. + } \
  88193. + } while (0)
  88194. diff -Nur linux-2.6.39.orig/crypto/ocf/talitos/talitos_soft.h linux-2.6.39/crypto/ocf/talitos/talitos_soft.h
  88195. --- linux-2.6.39.orig/crypto/ocf/talitos/talitos_soft.h 1970-01-01 01:00:00.000000000 +0100
  88196. +++ linux-2.6.39/crypto/ocf/talitos/talitos_soft.h 2011-08-01 14:38:19.000000000 +0200
  88197. @@ -0,0 +1,77 @@
  88198. +/*
  88199. + * Freescale SEC data structures for integration with ocf-linux
  88200. + *
  88201. + * Copyright (c) 2006 Freescale Semiconductor, Inc.
  88202. + *
  88203. + * Redistribution and use in source and binary forms, with or without
  88204. + * modification, are permitted provided that the following conditions
  88205. + * are met:
  88206. + *
  88207. + * 1. Redistributions of source code must retain the above copyright
  88208. + * notice, this list of conditions and the following disclaimer.
  88209. + * 2. Redistributions in binary form must reproduce the above copyright
  88210. + * notice, this list of conditions and the following disclaimer in the
  88211. + * documentation and/or other materials provided with the distribution.
  88212. + * 3. The name of the author may not be used to endorse or promote products
  88213. + * derived from this software without specific prior written permission.
  88214. + *
  88215. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  88216. + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  88217. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  88218. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  88219. + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  88220. + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  88221. + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  88222. + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  88223. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  88224. + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  88225. + */
  88226. +
  88227. +/*
  88228. + * paired descriptor and associated crypto operation
  88229. + */
  88230. +struct desc_cryptop_pair {
  88231. + struct talitos_desc cf_desc; /* descriptor ptr */
  88232. + struct cryptop *cf_crp; /* cryptop ptr */
  88233. +};
  88234. +
  88235. +/*
  88236. + * Holds data specific to a single talitos device.
  88237. + */
  88238. +struct talitos_softc {
  88239. + softc_device_decl sc_cdev;
  88240. + struct platform_device *sc_dev; /* device backpointer */
  88241. + ocf_iomem_t sc_base_addr;
  88242. + int sc_irq;
  88243. + int sc_num; /* if we have multiple chips */
  88244. + int32_t sc_cid; /* crypto tag */
  88245. + u64 sc_chiprev; /* major/minor chip revision */
  88246. + int sc_nsessions;
  88247. + struct talitos_session *sc_sessions;
  88248. + int sc_num_channels;/* number of crypto channels */
  88249. + int sc_chfifo_len; /* channel fetch fifo len */
  88250. + int sc_exec_units; /* execution units mask */
  88251. + int sc_desc_types; /* descriptor types mask */
  88252. + /*
  88253. + * mutual exclusion for intra-channel resources, e.g. fetch fifos
  88254. + * the last entry is a meta-channel lock used by the channel scheduler
  88255. + */
  88256. + spinlock_t *sc_chnfifolock;
  88257. + /* sc_chnlastalgo contains last algorithm for that channel */
  88258. + int *sc_chnlastalg;
  88259. + /* sc_chnfifo holds pending descriptor--crypto operation pairs */
  88260. + struct desc_cryptop_pair **sc_chnfifo;
  88261. +};
  88262. +
  88263. +struct talitos_session {
  88264. + u_int32_t ses_used;
  88265. + u_int32_t ses_klen; /* key length in bits */
  88266. + u_int32_t ses_key[8]; /* DES/3DES/AES key */
  88267. + u_int32_t ses_hmac[5]; /* hmac inner state */
  88268. + u_int32_t ses_hmac_len; /* hmac length */
  88269. + u_int32_t ses_iv[4]; /* DES/3DES/AES iv */
  88270. + u_int32_t ses_mlen; /* desired hash result len (12=ipsec or 16) */
  88271. +};
  88272. +
  88273. +#define TALITOS_SESSION(sid) ((sid) & 0x0fffffff)
  88274. +#define TALITOS_SID(crd, sesn) (((crd) << 28) | ((sesn) & 0x0fffffff))
  88275. diff -Nur linux-2.6.39.orig/crypto/ocf/uio.h linux-2.6.39/crypto/ocf/uio.h
  88276. --- linux-2.6.39.orig/crypto/ocf/uio.h 1970-01-01 01:00:00.000000000 +0100
  88277. +++ linux-2.6.39/crypto/ocf/uio.h 2011-08-01 14:38:19.000000000 +0200
  88278. @@ -0,0 +1,54 @@
  88279. +#ifndef _OCF_UIO_H_
  88280. +#define _OCF_UIO_H_
  88281. +
  88282. +#include <linux/uio.h>
  88283. +
  88284. +/*
  88285. + * The linux uio.h doesn't have all we need. To be fully api compatible
  88286. + * with the BSD cryptodev, we need to keep this around. Perhaps this can
  88287. + * be moved back into the linux/uio.h
  88288. + *
  88289. + * Linux port done by David McCullough <david_mccullough@mcafee.com>
  88290. + * Copyright (C) 2006-2010 David McCullough
  88291. + * Copyright (C) 2004-2005 Intel Corporation.
  88292. + *
  88293. + * LICENSE TERMS
  88294. + *
  88295. + * The free distribution and use of this software in both source and binary
  88296. + * form is allowed (with or without changes) provided that:
  88297. + *
  88298. + * 1. distributions of this source code include the above copyright
  88299. + * notice, this list of conditions and the following disclaimer;
  88300. + *
  88301. + * 2. distributions in binary form include the above copyright
  88302. + * notice, this list of conditions and the following disclaimer
  88303. + * in the documentation and/or other associated materials;
  88304. + *
  88305. + * 3. the copyright holder's name is not used to endorse products
  88306. + * built using this software without specific written permission.
  88307. + *
  88308. + * ALTERNATIVELY, provided that this notice is retained in full, this product
  88309. + * may be distributed under the terms of the GNU General Public License (GPL),
  88310. + * in which case the provisions of the GPL apply INSTEAD OF those given above.
  88311. + *
  88312. + * DISCLAIMER
  88313. + *
  88314. + * This software is provided 'as is' with no explicit or implied warranties
  88315. + * in respect of its properties, including, but not limited to, correctness
  88316. + * and/or fitness for purpose.
  88317. + * ---------------------------------------------------------------------------
  88318. + */
  88319. +
  88320. +struct uio {
  88321. + struct iovec *uio_iov;
  88322. + int uio_iovcnt;
  88323. + off_t uio_offset;
  88324. + int uio_resid;
  88325. +#if 0
  88326. + enum uio_seg uio_segflg;
  88327. + enum uio_rw uio_rw;
  88328. + struct thread *uio_td;
  88329. +#endif
  88330. +};
  88331. +
  88332. +#endif
  88333. diff -Nur linux-2.6.39.orig/drivers/char/random.c linux-2.6.39/drivers/char/random.c
  88334. --- linux-2.6.39.orig/drivers/char/random.c 2011-05-19 06:06:34.000000000 +0200
  88335. +++ linux-2.6.39/drivers/char/random.c 2011-08-01 14:38:19.000000000 +0200
  88336. @@ -130,6 +130,9 @@
  88337. * void add_interrupt_randomness(int irq);
  88338. * void add_disk_randomness(struct gendisk *disk);
  88339. *
  88340. + * void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
  88341. + * int random_input_wait(void);
  88342. + *
  88343. * add_input_randomness() uses the input layer interrupt timing, as well as
  88344. * the event type information from the hardware.
  88345. *
  88346. @@ -147,6 +150,13 @@
  88347. * seek times do not make for good sources of entropy, as their seek
  88348. * times are usually fairly consistent.
  88349. *
  88350. + * random_input_words() just provides a raw block of entropy to the input
  88351. + * pool, such as from a hardware entropy generator.
  88352. + *
  88353. + * random_input_wait() suspends the caller until such time as the
  88354. + * entropy pool falls below the write threshold, and returns a count of how
  88355. + * much entropy (in bits) is needed to sustain the pool.
  88356. + *
  88357. * All of these routines try to estimate how many bits of randomness a
  88358. * particular randomness source. They do this by keeping track of the
  88359. * first and second order deltas of the event timings.
  88360. @@ -266,6 +276,7 @@
  88361. #define SEC_XFER_SIZE 512
  88362. #define EXTRACT_SIZE 10
  88363. +
  88364. /*
  88365. * The minimum number of bits of entropy before we wake up a read on
  88366. * /dev/random. Should be enough to do a significant reseed.
  88367. @@ -559,6 +570,60 @@
  88368. spin_unlock_irqrestore(&r->lock, flags);
  88369. }
  88370. +/*
  88371. + * random_input_words - add bulk entropy to pool
  88372. + *
  88373. + * @buf: buffer to add
  88374. + * @wordcount: number of __u32 words to add
  88375. + * @ent_count: total amount of entropy (in bits) to credit
  88376. + *
  88377. + * this provides bulk input of entropy to the input pool
  88378. + *
  88379. + */
  88380. +void random_input_words(__u32 *buf, size_t wordcount, int ent_count)
  88381. +{
  88382. + mix_pool_bytes(&input_pool, buf, wordcount*4);
  88383. +
  88384. + credit_entropy_bits(&input_pool, ent_count);
  88385. +
  88386. + DEBUG_ENT("crediting %d bits => %d\n",
  88387. + ent_count, input_pool.entropy_count);
  88388. + /*
  88389. + * Wake up waiting processes if we have enough
  88390. + * entropy.
  88391. + */
  88392. + if (input_pool.entropy_count >= random_read_wakeup_thresh)
  88393. + wake_up_interruptible(&random_read_wait);
  88394. +}
  88395. +EXPORT_SYMBOL(random_input_words);
  88396. +
  88397. +/*
  88398. + * random_input_wait - wait until random needs entropy
  88399. + *
  88400. + * this function sleeps until the /dev/random subsystem actually
  88401. + * needs more entropy, and then return the amount of entropy
  88402. + * that it would be nice to have added to the system.
  88403. + */
  88404. +int random_input_wait(void)
  88405. +{
  88406. + int count;
  88407. +
  88408. + wait_event_interruptible(random_write_wait,
  88409. + input_pool.entropy_count < random_write_wakeup_thresh);
  88410. +
  88411. + count = random_write_wakeup_thresh - input_pool.entropy_count;
  88412. +
  88413. + /* likely we got woken up due to a signal */
  88414. + if (count <= 0) count = random_read_wakeup_thresh;
  88415. +
  88416. + DEBUG_ENT("requesting %d bits from input_wait()er %d<%d\n",
  88417. + count,
  88418. + input_pool.entropy_count, random_write_wakeup_thresh);
  88419. +
  88420. + return count;
  88421. +}
  88422. +EXPORT_SYMBOL(random_input_wait);
  88423. +
  88424. /*********************************************************************
  88425. *
  88426. * Entropy input management
  88427. diff -Nur linux-2.6.39.orig/drivers/char/random.c.orig linux-2.6.39/drivers/char/random.c.orig
  88428. --- linux-2.6.39.orig/drivers/char/random.c.orig 1970-01-01 01:00:00.000000000 +0100
  88429. +++ linux-2.6.39/drivers/char/random.c.orig 2011-08-01 14:38:19.000000000 +0200
  88430. @@ -0,0 +1,1667 @@
  88431. +/*
  88432. + * random.c -- A strong random number generator
  88433. + *
  88434. + * Copyright Matt Mackall <mpm@selenic.com>, 2003, 2004, 2005
  88435. + *
  88436. + * Copyright Theodore Ts'o, 1994, 1995, 1996, 1997, 1998, 1999. All
  88437. + * rights reserved.
  88438. + *
  88439. + * Redistribution and use in source and binary forms, with or without
  88440. + * modification, are permitted provided that the following conditions
  88441. + * are met:
  88442. + * 1. Redistributions of source code must retain the above copyright
  88443. + * notice, and the entire permission notice in its entirety,
  88444. + * including the disclaimer of warranties.
  88445. + * 2. Redistributions in binary form must reproduce the above copyright
  88446. + * notice, this list of conditions and the following disclaimer in the
  88447. + * documentation and/or other materials provided with the distribution.
  88448. + * 3. The name of the author may not be used to endorse or promote
  88449. + * products derived from this software without specific prior
  88450. + * written permission.
  88451. + *
  88452. + * ALTERNATIVELY, this product may be distributed under the terms of
  88453. + * the GNU General Public License, in which case the provisions of the GPL are
  88454. + * required INSTEAD OF the above restrictions. (This clause is
  88455. + * necessary due to a potential bad interaction between the GPL and
  88456. + * the restrictions contained in a BSD-style copyright.)
  88457. + *
  88458. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  88459. + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  88460. + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
  88461. + * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE
  88462. + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  88463. + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
  88464. + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
  88465. + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  88466. + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  88467. + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  88468. + * USE OF THIS SOFTWARE, EVEN IF NOT ADVISED OF THE POSSIBILITY OF SUCH
  88469. + * DAMAGE.
  88470. + */
  88471. +
  88472. +/*
  88473. + * (now, with legal B.S. out of the way.....)
  88474. + *
  88475. + * This routine gathers environmental noise from device drivers, etc.,
  88476. + * and returns good random numbers, suitable for cryptographic use.
  88477. + * Besides the obvious cryptographic uses, these numbers are also good
  88478. + * for seeding TCP sequence numbers, and other places where it is
  88479. + * desirable to have numbers which are not only random, but hard to
  88480. + * predict by an attacker.
  88481. + *
  88482. + * Theory of operation
  88483. + * ===================
  88484. + *
  88485. + * Computers are very predictable devices. Hence it is extremely hard
  88486. + * to produce truly random numbers on a computer --- as opposed to
  88487. + * pseudo-random numbers, which can easily generated by using a
  88488. + * algorithm. Unfortunately, it is very easy for attackers to guess
  88489. + * the sequence of pseudo-random number generators, and for some
  88490. + * applications this is not acceptable. So instead, we must try to
  88491. + * gather "environmental noise" from the computer's environment, which
  88492. + * must be hard for outside attackers to observe, and use that to
  88493. + * generate random numbers. In a Unix environment, this is best done
  88494. + * from inside the kernel.
  88495. + *
  88496. + * Sources of randomness from the environment include inter-keyboard
  88497. + * timings, inter-interrupt timings from some interrupts, and other
  88498. + * events which are both (a) non-deterministic and (b) hard for an
  88499. + * outside observer to measure. Randomness from these sources are
  88500. + * added to an "entropy pool", which is mixed using a CRC-like function.
  88501. + * This is not cryptographically strong, but it is adequate assuming
  88502. + * the randomness is not chosen maliciously, and it is fast enough that
  88503. + * the overhead of doing it on every interrupt is very reasonable.
  88504. + * As random bytes are mixed into the entropy pool, the routines keep
  88505. + * an *estimate* of how many bits of randomness have been stored into
  88506. + * the random number generator's internal state.
  88507. + *
  88508. + * When random bytes are desired, they are obtained by taking the SHA
  88509. + * hash of the contents of the "entropy pool". The SHA hash avoids
  88510. + * exposing the internal state of the entropy pool. It is believed to
  88511. + * be computationally infeasible to derive any useful information
  88512. + * about the input of SHA from its output. Even if it is possible to
  88513. + * analyze SHA in some clever way, as long as the amount of data
  88514. + * returned from the generator is less than the inherent entropy in
  88515. + * the pool, the output data is totally unpredictable. For this
  88516. + * reason, the routine decreases its internal estimate of how many
  88517. + * bits of "true randomness" are contained in the entropy pool as it
  88518. + * outputs random numbers.
  88519. + *
  88520. + * If this estimate goes to zero, the routine can still generate
  88521. + * random numbers; however, an attacker may (at least in theory) be
  88522. + * able to infer the future output of the generator from prior
  88523. + * outputs. This requires successful cryptanalysis of SHA, which is
  88524. + * not believed to be feasible, but there is a remote possibility.
  88525. + * Nonetheless, these numbers should be useful for the vast majority
  88526. + * of purposes.
  88527. + *
  88528. + * Exported interfaces ---- output
  88529. + * ===============================
  88530. + *
  88531. + * There are three exported interfaces; the first is one designed to
  88532. + * be used from within the kernel:
  88533. + *
  88534. + * void get_random_bytes(void *buf, int nbytes);
  88535. + *
  88536. + * This interface will return the requested number of random bytes,
  88537. + * and place it in the requested buffer.
  88538. + *
  88539. + * The two other interfaces are two character devices /dev/random and
  88540. + * /dev/urandom. /dev/random is suitable for use when very high
  88541. + * quality randomness is desired (for example, for key generation or
  88542. + * one-time pads), as it will only return a maximum of the number of
  88543. + * bits of randomness (as estimated by the random number generator)
  88544. + * contained in the entropy pool.
  88545. + *
  88546. + * The /dev/urandom device does not have this limit, and will return
  88547. + * as many bytes as are requested. As more and more random bytes are
  88548. + * requested without giving time for the entropy pool to recharge,
  88549. + * this will result in random numbers that are merely cryptographically
  88550. + * strong. For many applications, however, this is acceptable.
  88551. + *
  88552. + * Exported interfaces ---- input
  88553. + * ==============================
  88554. + *
  88555. + * The current exported interfaces for gathering environmental noise
  88556. + * from the devices are:
  88557. + *
  88558. + * void add_input_randomness(unsigned int type, unsigned int code,
  88559. + * unsigned int value);
  88560. + * void add_interrupt_randomness(int irq);
  88561. + * void add_disk_randomness(struct gendisk *disk);
  88562. + *
  88563. + * add_input_randomness() uses the input layer interrupt timing, as well as
  88564. + * the event type information from the hardware.
  88565. + *
  88566. + * add_interrupt_randomness() uses the inter-interrupt timing as random
  88567. + * inputs to the entropy pool. Note that not all interrupts are good
  88568. + * sources of randomness! For example, the timer interrupts is not a
  88569. + * good choice, because the periodicity of the interrupts is too
  88570. + * regular, and hence predictable to an attacker. Network Interface
  88571. + * Controller interrupts are a better measure, since the timing of the
  88572. + * NIC interrupts are more unpredictable.
  88573. + *
  88574. + * add_disk_randomness() uses what amounts to the seek time of block
  88575. + * layer request events, on a per-disk_devt basis, as input to the
  88576. + * entropy pool. Note that high-speed solid state drives with very low
  88577. + * seek times do not make for good sources of entropy, as their seek
  88578. + * times are usually fairly consistent.
  88579. + *
  88580. + * All of these routines try to estimate how many bits of randomness a
  88581. + * particular randomness source. They do this by keeping track of the
  88582. + * first and second order deltas of the event timings.
  88583. + *
  88584. + * Ensuring unpredictability at system startup
  88585. + * ============================================
  88586. + *
  88587. + * When any operating system starts up, it will go through a sequence
  88588. + * of actions that are fairly predictable by an adversary, especially
  88589. + * if the start-up does not involve interaction with a human operator.
  88590. + * This reduces the actual number of bits of unpredictability in the
  88591. + * entropy pool below the value in entropy_count. In order to
  88592. + * counteract this effect, it helps to carry information in the
  88593. + * entropy pool across shut-downs and start-ups. To do this, put the
  88594. + * following lines an appropriate script which is run during the boot
  88595. + * sequence:
  88596. + *
  88597. + * echo "Initializing random number generator..."
  88598. + * random_seed=/var/run/random-seed
  88599. + * # Carry a random seed from start-up to start-up
  88600. + * # Load and then save the whole entropy pool
  88601. + * if [ -f $random_seed ]; then
  88602. + * cat $random_seed >/dev/urandom
  88603. + * else
  88604. + * touch $random_seed
  88605. + * fi
  88606. + * chmod 600 $random_seed
  88607. + * dd if=/dev/urandom of=$random_seed count=1 bs=512
  88608. + *
  88609. + * and the following lines in an appropriate script which is run as
  88610. + * the system is shutdown:
  88611. + *
  88612. + * # Carry a random seed from shut-down to start-up
  88613. + * # Save the whole entropy pool
  88614. + * echo "Saving random seed..."
  88615. + * random_seed=/var/run/random-seed
  88616. + * touch $random_seed
  88617. + * chmod 600 $random_seed
  88618. + * dd if=/dev/urandom of=$random_seed count=1 bs=512
  88619. + *
  88620. + * For example, on most modern systems using the System V init
  88621. + * scripts, such code fragments would be found in
  88622. + * /etc/rc.d/init.d/random. On older Linux systems, the correct script
  88623. + * location might be in /etc/rcb.d/rc.local or /etc/rc.d/rc.0.
  88624. + *
  88625. + * Effectively, these commands cause the contents of the entropy pool
  88626. + * to be saved at shut-down time and reloaded into the entropy pool at
  88627. + * start-up. (The 'dd' in the addition to the bootup script is to
  88628. + * make sure that /etc/random-seed is different for every start-up,
  88629. + * even if the system crashes without executing rc.0.) Even with
  88630. + * complete knowledge of the start-up activities, predicting the state
  88631. + * of the entropy pool requires knowledge of the previous history of
  88632. + * the system.
  88633. + *
  88634. + * Configuring the /dev/random driver under Linux
  88635. + * ==============================================
  88636. + *
  88637. + * The /dev/random driver under Linux uses minor numbers 8 and 9 of
  88638. + * the /dev/mem major number (#1). So if your system does not have
  88639. + * /dev/random and /dev/urandom created already, they can be created
  88640. + * by using the commands:
  88641. + *
  88642. + * mknod /dev/random c 1 8
  88643. + * mknod /dev/urandom c 1 9
  88644. + *
  88645. + * Acknowledgements:
  88646. + * =================
  88647. + *
  88648. + * Ideas for constructing this random number generator were derived
  88649. + * from Pretty Good Privacy's random number generator, and from private
  88650. + * discussions with Phil Karn. Colin Plumb provided a faster random
  88651. + * number generator, which speed up the mixing function of the entropy
  88652. + * pool, taken from PGPfone. Dale Worley has also contributed many
  88653. + * useful ideas and suggestions to improve this driver.
  88654. + *
  88655. + * Any flaws in the design are solely my responsibility, and should
  88656. + * not be attributed to the Phil, Colin, or any of authors of PGP.
  88657. + *
  88658. + * Further background information on this topic may be obtained from
  88659. + * RFC 1750, "Randomness Recommendations for Security", by Donald
  88660. + * Eastlake, Steve Crocker, and Jeff Schiller.
  88661. + */
  88662. +
  88663. +#include <linux/utsname.h>
  88664. +#include <linux/module.h>
  88665. +#include <linux/kernel.h>
  88666. +#include <linux/major.h>
  88667. +#include <linux/string.h>
  88668. +#include <linux/fcntl.h>
  88669. +#include <linux/slab.h>
  88670. +#include <linux/random.h>
  88671. +#include <linux/poll.h>
  88672. +#include <linux/init.h>
  88673. +#include <linux/fs.h>
  88674. +#include <linux/genhd.h>
  88675. +#include <linux/interrupt.h>
  88676. +#include <linux/mm.h>
  88677. +#include <linux/spinlock.h>
  88678. +#include <linux/percpu.h>
  88679. +#include <linux/cryptohash.h>
  88680. +#include <linux/fips.h>
  88681. +
  88682. +#ifdef CONFIG_GENERIC_HARDIRQS
  88683. +# include <linux/irq.h>
  88684. +#endif
  88685. +
  88686. +#include <asm/processor.h>
  88687. +#include <asm/uaccess.h>
  88688. +#include <asm/irq.h>
  88689. +#include <asm/io.h>
  88690. +
  88691. +/*
  88692. + * Configuration information
  88693. + */
  88694. +#define INPUT_POOL_WORDS 128
  88695. +#define OUTPUT_POOL_WORDS 32
  88696. +#define SEC_XFER_SIZE 512
  88697. +#define EXTRACT_SIZE 10
  88698. +
  88699. +/*
  88700. + * The minimum number of bits of entropy before we wake up a read on
  88701. + * /dev/random. Should be enough to do a significant reseed.
  88702. + */
  88703. +static int random_read_wakeup_thresh = 64;
  88704. +
  88705. +/*
  88706. + * If the entropy count falls under this number of bits, then we
  88707. + * should wake up processes which are selecting or polling on write
  88708. + * access to /dev/random.
  88709. + */
  88710. +static int random_write_wakeup_thresh = 128;
  88711. +
  88712. +/*
  88713. + * When the input pool goes over trickle_thresh, start dropping most
  88714. + * samples to avoid wasting CPU time and reduce lock contention.
  88715. + */
  88716. +
  88717. +static int trickle_thresh __read_mostly = INPUT_POOL_WORDS * 28;
  88718. +
  88719. +static DEFINE_PER_CPU(int, trickle_count);
  88720. +
  88721. +/*
  88722. + * A pool of size .poolwords is stirred with a primitive polynomial
  88723. + * of degree .poolwords over GF(2). The taps for various sizes are
  88724. + * defined below. They are chosen to be evenly spaced (minimum RMS
  88725. + * distance from evenly spaced; the numbers in the comments are a
  88726. + * scaled squared error sum) except for the last tap, which is 1 to
  88727. + * get the twisting happening as fast as possible.
  88728. + */
  88729. +static struct poolinfo {
  88730. + int poolwords;
  88731. + int tap1, tap2, tap3, tap4, tap5;
  88732. +} poolinfo_table[] = {
  88733. + /* x^128 + x^103 + x^76 + x^51 +x^25 + x + 1 -- 105 */
  88734. + { 128, 103, 76, 51, 25, 1 },
  88735. + /* x^32 + x^26 + x^20 + x^14 + x^7 + x + 1 -- 15 */
  88736. + { 32, 26, 20, 14, 7, 1 },
  88737. +#if 0
  88738. + /* x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1 -- 115 */
  88739. + { 2048, 1638, 1231, 819, 411, 1 },
  88740. +
  88741. + /* x^1024 + x^817 + x^615 + x^412 + x^204 + x + 1 -- 290 */
  88742. + { 1024, 817, 615, 412, 204, 1 },
  88743. +
  88744. + /* x^1024 + x^819 + x^616 + x^410 + x^207 + x^2 + 1 -- 115 */
  88745. + { 1024, 819, 616, 410, 207, 2 },
  88746. +
  88747. + /* x^512 + x^411 + x^308 + x^208 + x^104 + x + 1 -- 225 */
  88748. + { 512, 411, 308, 208, 104, 1 },
  88749. +
  88750. + /* x^512 + x^409 + x^307 + x^206 + x^102 + x^2 + 1 -- 95 */
  88751. + { 512, 409, 307, 206, 102, 2 },
  88752. + /* x^512 + x^409 + x^309 + x^205 + x^103 + x^2 + 1 -- 95 */
  88753. + { 512, 409, 309, 205, 103, 2 },
  88754. +
  88755. + /* x^256 + x^205 + x^155 + x^101 + x^52 + x + 1 -- 125 */
  88756. + { 256, 205, 155, 101, 52, 1 },
  88757. +
  88758. + /* x^128 + x^103 + x^78 + x^51 + x^27 + x^2 + 1 -- 70 */
  88759. + { 128, 103, 78, 51, 27, 2 },
  88760. +
  88761. + /* x^64 + x^52 + x^39 + x^26 + x^14 + x + 1 -- 15 */
  88762. + { 64, 52, 39, 26, 14, 1 },
  88763. +#endif
  88764. +};
  88765. +
  88766. +#define POOLBITS poolwords*32
  88767. +#define POOLBYTES poolwords*4
  88768. +
  88769. +/*
  88770. + * For the purposes of better mixing, we use the CRC-32 polynomial as
  88771. + * well to make a twisted Generalized Feedback Shift Reigster
  88772. + *
  88773. + * (See M. Matsumoto & Y. Kurita, 1992. Twisted GFSR generators. ACM
  88774. + * Transactions on Modeling and Computer Simulation 2(3):179-194.
  88775. + * Also see M. Matsumoto & Y. Kurita, 1994. Twisted GFSR generators
  88776. + * II. ACM Transactions on Mdeling and Computer Simulation 4:254-266)
  88777. + *
  88778. + * Thanks to Colin Plumb for suggesting this.
  88779. + *
  88780. + * We have not analyzed the resultant polynomial to prove it primitive;
  88781. + * in fact it almost certainly isn't. Nonetheless, the irreducible factors
  88782. + * of a random large-degree polynomial over GF(2) are more than large enough
  88783. + * that periodicity is not a concern.
  88784. + *
  88785. + * The input hash is much less sensitive than the output hash. All
  88786. + * that we want of it is that it be a good non-cryptographic hash;
  88787. + * i.e. it not produce collisions when fed "random" data of the sort
  88788. + * we expect to see. As long as the pool state differs for different
  88789. + * inputs, we have preserved the input entropy and done a good job.
  88790. + * The fact that an intelligent attacker can construct inputs that
  88791. + * will produce controlled alterations to the pool's state is not
  88792. + * important because we don't consider such inputs to contribute any
  88793. + * randomness. The only property we need with respect to them is that
  88794. + * the attacker can't increase his/her knowledge of the pool's state.
  88795. + * Since all additions are reversible (knowing the final state and the
  88796. + * input, you can reconstruct the initial state), if an attacker has
  88797. + * any uncertainty about the initial state, he/she can only shuffle
  88798. + * that uncertainty about, but never cause any collisions (which would
  88799. + * decrease the uncertainty).
  88800. + *
  88801. + * The chosen system lets the state of the pool be (essentially) the input
  88802. + * modulo the generator polymnomial. Now, for random primitive polynomials,
  88803. + * this is a universal class of hash functions, meaning that the chance
  88804. + * of a collision is limited by the attacker's knowledge of the generator
  88805. + * polynomail, so if it is chosen at random, an attacker can never force
  88806. + * a collision. Here, we use a fixed polynomial, but we *can* assume that
  88807. + * ###--> it is unknown to the processes generating the input entropy. <-###
  88808. + * Because of this important property, this is a good, collision-resistant
  88809. + * hash; hash collisions will occur no more often than chance.
  88810. + */
  88811. +
  88812. +/*
  88813. + * Static global variables
  88814. + */
  88815. +static DECLARE_WAIT_QUEUE_HEAD(random_read_wait);
  88816. +static DECLARE_WAIT_QUEUE_HEAD(random_write_wait);
  88817. +static struct fasync_struct *fasync;
  88818. +
  88819. +#if 0
  88820. +static int debug;
  88821. +module_param(debug, bool, 0644);
  88822. +#define DEBUG_ENT(fmt, arg...) do { \
  88823. + if (debug) \
  88824. + printk(KERN_DEBUG "random %04d %04d %04d: " \
  88825. + fmt,\
  88826. + input_pool.entropy_count,\
  88827. + blocking_pool.entropy_count,\
  88828. + nonblocking_pool.entropy_count,\
  88829. + ## arg); } while (0)
  88830. +#else
  88831. +#define DEBUG_ENT(fmt, arg...) do {} while (0)
  88832. +#endif
  88833. +
  88834. +/**********************************************************************
  88835. + *
  88836. + * OS independent entropy store. Here are the functions which handle
  88837. + * storing entropy in an entropy pool.
  88838. + *
  88839. + **********************************************************************/
  88840. +
  88841. +struct entropy_store;
  88842. +struct entropy_store {
  88843. + /* read-only data: */
  88844. + struct poolinfo *poolinfo;
  88845. + __u32 *pool;
  88846. + const char *name;
  88847. + struct entropy_store *pull;
  88848. + int limit;
  88849. +
  88850. + /* read-write data: */
  88851. + spinlock_t lock;
  88852. + unsigned add_ptr;
  88853. + int entropy_count;
  88854. + int input_rotate;
  88855. + __u8 last_data[EXTRACT_SIZE];
  88856. +};
  88857. +
  88858. +static __u32 input_pool_data[INPUT_POOL_WORDS];
  88859. +static __u32 blocking_pool_data[OUTPUT_POOL_WORDS];
  88860. +static __u32 nonblocking_pool_data[OUTPUT_POOL_WORDS];
  88861. +
  88862. +static struct entropy_store input_pool = {
  88863. + .poolinfo = &poolinfo_table[0],
  88864. + .name = "input",
  88865. + .limit = 1,
  88866. + .lock = __SPIN_LOCK_UNLOCKED(&input_pool.lock),
  88867. + .pool = input_pool_data
  88868. +};
  88869. +
  88870. +static struct entropy_store blocking_pool = {
  88871. + .poolinfo = &poolinfo_table[1],
  88872. + .name = "blocking",
  88873. + .limit = 1,
  88874. + .pull = &input_pool,
  88875. + .lock = __SPIN_LOCK_UNLOCKED(&blocking_pool.lock),
  88876. + .pool = blocking_pool_data
  88877. +};
  88878. +
  88879. +static struct entropy_store nonblocking_pool = {
  88880. + .poolinfo = &poolinfo_table[1],
  88881. + .name = "nonblocking",
  88882. + .pull = &input_pool,
  88883. + .lock = __SPIN_LOCK_UNLOCKED(&nonblocking_pool.lock),
  88884. + .pool = nonblocking_pool_data
  88885. +};
  88886. +
  88887. +/*
  88888. + * This function adds bytes into the entropy "pool". It does not
  88889. + * update the entropy estimate. The caller should call
  88890. + * credit_entropy_bits if this is appropriate.
  88891. + *
  88892. + * The pool is stirred with a primitive polynomial of the appropriate
  88893. + * degree, and then twisted. We twist by three bits at a time because
  88894. + * it's cheap to do so and helps slightly in the expected case where
  88895. + * the entropy is concentrated in the low-order bits.
  88896. + */
  88897. +static void mix_pool_bytes_extract(struct entropy_store *r, const void *in,
  88898. + int nbytes, __u8 out[64])
  88899. +{
  88900. + static __u32 const twist_table[8] = {
  88901. + 0x00000000, 0x3b6e20c8, 0x76dc4190, 0x4db26158,
  88902. + 0xedb88320, 0xd6d6a3e8, 0x9b64c2b0, 0xa00ae278 };
  88903. + unsigned long i, j, tap1, tap2, tap3, tap4, tap5;
  88904. + int input_rotate;
  88905. + int wordmask = r->poolinfo->poolwords - 1;
  88906. + const char *bytes = in;
  88907. + __u32 w;
  88908. + unsigned long flags;
  88909. +
  88910. + /* Taps are constant, so we can load them without holding r->lock. */
  88911. + tap1 = r->poolinfo->tap1;
  88912. + tap2 = r->poolinfo->tap2;
  88913. + tap3 = r->poolinfo->tap3;
  88914. + tap4 = r->poolinfo->tap4;
  88915. + tap5 = r->poolinfo->tap5;
  88916. +
  88917. + spin_lock_irqsave(&r->lock, flags);
  88918. + input_rotate = r->input_rotate;
  88919. + i = r->add_ptr;
  88920. +
  88921. + /* mix one byte at a time to simplify size handling and churn faster */
  88922. + while (nbytes--) {
  88923. + w = rol32(*bytes++, input_rotate & 31);
  88924. + i = (i - 1) & wordmask;
  88925. +
  88926. + /* XOR in the various taps */
  88927. + w ^= r->pool[i];
  88928. + w ^= r->pool[(i + tap1) & wordmask];
  88929. + w ^= r->pool[(i + tap2) & wordmask];
  88930. + w ^= r->pool[(i + tap3) & wordmask];
  88931. + w ^= r->pool[(i + tap4) & wordmask];
  88932. + w ^= r->pool[(i + tap5) & wordmask];
  88933. +
  88934. + /* Mix the result back in with a twist */
  88935. + r->pool[i] = (w >> 3) ^ twist_table[w & 7];
  88936. +
  88937. + /*
  88938. + * Normally, we add 7 bits of rotation to the pool.
  88939. + * At the beginning of the pool, add an extra 7 bits
  88940. + * rotation, so that successive passes spread the
  88941. + * input bits across the pool evenly.
  88942. + */
  88943. + input_rotate += i ? 7 : 14;
  88944. + }
  88945. +
  88946. + r->input_rotate = input_rotate;
  88947. + r->add_ptr = i;
  88948. +
  88949. + if (out)
  88950. + for (j = 0; j < 16; j++)
  88951. + ((__u32 *)out)[j] = r->pool[(i - j) & wordmask];
  88952. +
  88953. + spin_unlock_irqrestore(&r->lock, flags);
  88954. +}
  88955. +
  88956. +static void mix_pool_bytes(struct entropy_store *r, const void *in, int bytes)
  88957. +{
  88958. + mix_pool_bytes_extract(r, in, bytes, NULL);
  88959. +}
  88960. +
  88961. +/*
  88962. + * Credit (or debit) the entropy store with n bits of entropy
  88963. + */
  88964. +static void credit_entropy_bits(struct entropy_store *r, int nbits)
  88965. +{
  88966. + unsigned long flags;
  88967. + int entropy_count;
  88968. +
  88969. + if (!nbits)
  88970. + return;
  88971. +
  88972. + spin_lock_irqsave(&r->lock, flags);
  88973. +
  88974. + DEBUG_ENT("added %d entropy credits to %s\n", nbits, r->name);
  88975. + entropy_count = r->entropy_count;
  88976. + entropy_count += nbits;
  88977. + if (entropy_count < 0) {
  88978. + DEBUG_ENT("negative entropy/overflow\n");
  88979. + entropy_count = 0;
  88980. + } else if (entropy_count > r->poolinfo->POOLBITS)
  88981. + entropy_count = r->poolinfo->POOLBITS;
  88982. + r->entropy_count = entropy_count;
  88983. +
  88984. + /* should we wake readers? */
  88985. + if (r == &input_pool && entropy_count >= random_read_wakeup_thresh) {
  88986. + wake_up_interruptible(&random_read_wait);
  88987. + kill_fasync(&fasync, SIGIO, POLL_IN);
  88988. + }
  88989. + spin_unlock_irqrestore(&r->lock, flags);
  88990. +}
  88991. +
  88992. +/*********************************************************************
  88993. + *
  88994. + * Entropy input management
  88995. + *
  88996. + *********************************************************************/
  88997. +
  88998. +/* There is one of these per entropy source */
  88999. +struct timer_rand_state {
  89000. + cycles_t last_time;
  89001. + long last_delta, last_delta2;
  89002. + unsigned dont_count_entropy:1;
  89003. +};
  89004. +
  89005. +#ifndef CONFIG_GENERIC_HARDIRQS
  89006. +
  89007. +static struct timer_rand_state *irq_timer_state[NR_IRQS];
  89008. +
  89009. +static struct timer_rand_state *get_timer_rand_state(unsigned int irq)
  89010. +{
  89011. + return irq_timer_state[irq];
  89012. +}
  89013. +
  89014. +static void set_timer_rand_state(unsigned int irq,
  89015. + struct timer_rand_state *state)
  89016. +{
  89017. + irq_timer_state[irq] = state;
  89018. +}
  89019. +
  89020. +#else
  89021. +
  89022. +static struct timer_rand_state *get_timer_rand_state(unsigned int irq)
  89023. +{
  89024. + struct irq_desc *desc;
  89025. +
  89026. + desc = irq_to_desc(irq);
  89027. +
  89028. + return desc->timer_rand_state;
  89029. +}
  89030. +
  89031. +static void set_timer_rand_state(unsigned int irq,
  89032. + struct timer_rand_state *state)
  89033. +{
  89034. + struct irq_desc *desc;
  89035. +
  89036. + desc = irq_to_desc(irq);
  89037. +
  89038. + desc->timer_rand_state = state;
  89039. +}
  89040. +#endif
  89041. +
  89042. +static struct timer_rand_state input_timer_state;
  89043. +
  89044. +/*
  89045. + * This function adds entropy to the entropy "pool" by using timing
  89046. + * delays. It uses the timer_rand_state structure to make an estimate
  89047. + * of how many bits of entropy this call has added to the pool.
  89048. + *
  89049. + * The number "num" is also added to the pool - it should somehow describe
  89050. + * the type of event which just happened. This is currently 0-255 for
  89051. + * keyboard scan codes, and 256 upwards for interrupts.
  89052. + *
  89053. + */
  89054. +static void add_timer_randomness(struct timer_rand_state *state, unsigned num)
  89055. +{
  89056. + struct {
  89057. + cycles_t cycles;
  89058. + long jiffies;
  89059. + unsigned num;
  89060. + } sample;
  89061. + long delta, delta2, delta3;
  89062. +
  89063. + preempt_disable();
  89064. + /* if over the trickle threshold, use only 1 in 4096 samples */
  89065. + if (input_pool.entropy_count > trickle_thresh &&
  89066. + ((__this_cpu_inc_return(trickle_count) - 1) & 0xfff))
  89067. + goto out;
  89068. +
  89069. + sample.jiffies = jiffies;
  89070. + sample.cycles = get_cycles();
  89071. + sample.num = num;
  89072. + mix_pool_bytes(&input_pool, &sample, sizeof(sample));
  89073. +
  89074. + /*
  89075. + * Calculate number of bits of randomness we probably added.
  89076. + * We take into account the first, second and third-order deltas
  89077. + * in order to make our estimate.
  89078. + */
  89079. +
  89080. + if (!state->dont_count_entropy) {
  89081. + delta = sample.jiffies - state->last_time;
  89082. + state->last_time = sample.jiffies;
  89083. +
  89084. + delta2 = delta - state->last_delta;
  89085. + state->last_delta = delta;
  89086. +
  89087. + delta3 = delta2 - state->last_delta2;
  89088. + state->last_delta2 = delta2;
  89089. +
  89090. + if (delta < 0)
  89091. + delta = -delta;
  89092. + if (delta2 < 0)
  89093. + delta2 = -delta2;
  89094. + if (delta3 < 0)
  89095. + delta3 = -delta3;
  89096. + if (delta > delta2)
  89097. + delta = delta2;
  89098. + if (delta > delta3)
  89099. + delta = delta3;
  89100. +
  89101. + /*
  89102. + * delta is now minimum absolute delta.
  89103. + * Round down by 1 bit on general principles,
  89104. + * and limit entropy entimate to 12 bits.
  89105. + */
  89106. + credit_entropy_bits(&input_pool,
  89107. + min_t(int, fls(delta>>1), 11));
  89108. + }
  89109. +out:
  89110. + preempt_enable();
  89111. +}
  89112. +
  89113. +void add_input_randomness(unsigned int type, unsigned int code,
  89114. + unsigned int value)
  89115. +{
  89116. + static unsigned char last_value;
  89117. +
  89118. + /* ignore autorepeat and the like */
  89119. + if (value == last_value)
  89120. + return;
  89121. +
  89122. + DEBUG_ENT("input event\n");
  89123. + last_value = value;
  89124. + add_timer_randomness(&input_timer_state,
  89125. + (type << 4) ^ code ^ (code >> 4) ^ value);
  89126. +}
  89127. +EXPORT_SYMBOL_GPL(add_input_randomness);
  89128. +
  89129. +void add_interrupt_randomness(int irq)
  89130. +{
  89131. + struct timer_rand_state *state;
  89132. +
  89133. + state = get_timer_rand_state(irq);
  89134. +
  89135. + if (state == NULL)
  89136. + return;
  89137. +
  89138. + DEBUG_ENT("irq event %d\n", irq);
  89139. + add_timer_randomness(state, 0x100 + irq);
  89140. +}
  89141. +
  89142. +#ifdef CONFIG_BLOCK
  89143. +void add_disk_randomness(struct gendisk *disk)
  89144. +{
  89145. + if (!disk || !disk->random)
  89146. + return;
  89147. + /* first major is 1, so we get >= 0x200 here */
  89148. + DEBUG_ENT("disk event %d:%d\n",
  89149. + MAJOR(disk_devt(disk)), MINOR(disk_devt(disk)));
  89150. +
  89151. + add_timer_randomness(disk->random, 0x100 + disk_devt(disk));
  89152. +}
  89153. +#endif
  89154. +
  89155. +/*********************************************************************
  89156. + *
  89157. + * Entropy extraction routines
  89158. + *
  89159. + *********************************************************************/
  89160. +
  89161. +static ssize_t extract_entropy(struct entropy_store *r, void *buf,
  89162. + size_t nbytes, int min, int rsvd);
  89163. +
  89164. +/*
  89165. + * This utility inline function is responsible for transferring entropy
  89166. + * from the primary pool to the secondary extraction pool. We make
  89167. + * sure we pull enough for a 'catastrophic reseed'.
  89168. + */
  89169. +static void xfer_secondary_pool(struct entropy_store *r, size_t nbytes)
  89170. +{
  89171. + __u32 tmp[OUTPUT_POOL_WORDS];
  89172. +
  89173. + if (r->pull && r->entropy_count < nbytes * 8 &&
  89174. + r->entropy_count < r->poolinfo->POOLBITS) {
  89175. + /* If we're limited, always leave two wakeup worth's BITS */
  89176. + int rsvd = r->limit ? 0 : random_read_wakeup_thresh/4;
  89177. + int bytes = nbytes;
  89178. +
  89179. + /* pull at least as many as BYTES as wakeup BITS */
  89180. + bytes = max_t(int, bytes, random_read_wakeup_thresh / 8);
  89181. + /* but never more than the buffer size */
  89182. + bytes = min_t(int, bytes, sizeof(tmp));
  89183. +
  89184. + DEBUG_ENT("going to reseed %s with %d bits "
  89185. + "(%d of %d requested)\n",
  89186. + r->name, bytes * 8, nbytes * 8, r->entropy_count);
  89187. +
  89188. + bytes = extract_entropy(r->pull, tmp, bytes,
  89189. + random_read_wakeup_thresh / 8, rsvd);
  89190. + mix_pool_bytes(r, tmp, bytes);
  89191. + credit_entropy_bits(r, bytes*8);
  89192. + }
  89193. +}
  89194. +
  89195. +/*
  89196. + * These functions extracts randomness from the "entropy pool", and
  89197. + * returns it in a buffer.
  89198. + *
  89199. + * The min parameter specifies the minimum amount we can pull before
  89200. + * failing to avoid races that defeat catastrophic reseeding while the
  89201. + * reserved parameter indicates how much entropy we must leave in the
  89202. + * pool after each pull to avoid starving other readers.
  89203. + *
  89204. + * Note: extract_entropy() assumes that .poolwords is a multiple of 16 words.
  89205. + */
  89206. +
  89207. +static size_t account(struct entropy_store *r, size_t nbytes, int min,
  89208. + int reserved)
  89209. +{
  89210. + unsigned long flags;
  89211. +
  89212. + /* Hold lock while accounting */
  89213. + spin_lock_irqsave(&r->lock, flags);
  89214. +
  89215. + BUG_ON(r->entropy_count > r->poolinfo->POOLBITS);
  89216. + DEBUG_ENT("trying to extract %d bits from %s\n",
  89217. + nbytes * 8, r->name);
  89218. +
  89219. + /* Can we pull enough? */
  89220. + if (r->entropy_count / 8 < min + reserved) {
  89221. + nbytes = 0;
  89222. + } else {
  89223. + /* If limited, never pull more than available */
  89224. + if (r->limit && nbytes + reserved >= r->entropy_count / 8)
  89225. + nbytes = r->entropy_count/8 - reserved;
  89226. +
  89227. + if (r->entropy_count / 8 >= nbytes + reserved)
  89228. + r->entropy_count -= nbytes*8;
  89229. + else
  89230. + r->entropy_count = reserved;
  89231. +
  89232. + if (r->entropy_count < random_write_wakeup_thresh) {
  89233. + wake_up_interruptible(&random_write_wait);
  89234. + kill_fasync(&fasync, SIGIO, POLL_OUT);
  89235. + }
  89236. + }
  89237. +
  89238. + DEBUG_ENT("debiting %d entropy credits from %s%s\n",
  89239. + nbytes * 8, r->name, r->limit ? "" : " (unlimited)");
  89240. +
  89241. + spin_unlock_irqrestore(&r->lock, flags);
  89242. +
  89243. + return nbytes;
  89244. +}
  89245. +
  89246. +static void extract_buf(struct entropy_store *r, __u8 *out)
  89247. +{
  89248. + int i;
  89249. + __u32 hash[5], workspace[SHA_WORKSPACE_WORDS];
  89250. + __u8 extract[64];
  89251. +
  89252. + /* Generate a hash across the pool, 16 words (512 bits) at a time */
  89253. + sha_init(hash);
  89254. + for (i = 0; i < r->poolinfo->poolwords; i += 16)
  89255. + sha_transform(hash, (__u8 *)(r->pool + i), workspace);
  89256. +
  89257. + /*
  89258. + * We mix the hash back into the pool to prevent backtracking
  89259. + * attacks (where the attacker knows the state of the pool
  89260. + * plus the current outputs, and attempts to find previous
  89261. + * ouputs), unless the hash function can be inverted. By
  89262. + * mixing at least a SHA1 worth of hash data back, we make
  89263. + * brute-forcing the feedback as hard as brute-forcing the
  89264. + * hash.
  89265. + */
  89266. + mix_pool_bytes_extract(r, hash, sizeof(hash), extract);
  89267. +
  89268. + /*
  89269. + * To avoid duplicates, we atomically extract a portion of the
  89270. + * pool while mixing, and hash one final time.
  89271. + */
  89272. + sha_transform(hash, extract, workspace);
  89273. + memset(extract, 0, sizeof(extract));
  89274. + memset(workspace, 0, sizeof(workspace));
  89275. +
  89276. + /*
  89277. + * In case the hash function has some recognizable output
  89278. + * pattern, we fold it in half. Thus, we always feed back
  89279. + * twice as much data as we output.
  89280. + */
  89281. + hash[0] ^= hash[3];
  89282. + hash[1] ^= hash[4];
  89283. + hash[2] ^= rol32(hash[2], 16);
  89284. + memcpy(out, hash, EXTRACT_SIZE);
  89285. + memset(hash, 0, sizeof(hash));
  89286. +}
  89287. +
  89288. +static ssize_t extract_entropy(struct entropy_store *r, void *buf,
  89289. + size_t nbytes, int min, int reserved)
  89290. +{
  89291. + ssize_t ret = 0, i;
  89292. + __u8 tmp[EXTRACT_SIZE];
  89293. + unsigned long flags;
  89294. +
  89295. + xfer_secondary_pool(r, nbytes);
  89296. + nbytes = account(r, nbytes, min, reserved);
  89297. +
  89298. + while (nbytes) {
  89299. + extract_buf(r, tmp);
  89300. +
  89301. + if (fips_enabled) {
  89302. + spin_lock_irqsave(&r->lock, flags);
  89303. + if (!memcmp(tmp, r->last_data, EXTRACT_SIZE))
  89304. + panic("Hardware RNG duplicated output!\n");
  89305. + memcpy(r->last_data, tmp, EXTRACT_SIZE);
  89306. + spin_unlock_irqrestore(&r->lock, flags);
  89307. + }
  89308. + i = min_t(int, nbytes, EXTRACT_SIZE);
  89309. + memcpy(buf, tmp, i);
  89310. + nbytes -= i;
  89311. + buf += i;
  89312. + ret += i;
  89313. + }
  89314. +
  89315. + /* Wipe data just returned from memory */
  89316. + memset(tmp, 0, sizeof(tmp));
  89317. +
  89318. + return ret;
  89319. +}
  89320. +
  89321. +static ssize_t extract_entropy_user(struct entropy_store *r, void __user *buf,
  89322. + size_t nbytes)
  89323. +{
  89324. + ssize_t ret = 0, i;
  89325. + __u8 tmp[EXTRACT_SIZE];
  89326. +
  89327. + xfer_secondary_pool(r, nbytes);
  89328. + nbytes = account(r, nbytes, 0, 0);
  89329. +
  89330. + while (nbytes) {
  89331. + if (need_resched()) {
  89332. + if (signal_pending(current)) {
  89333. + if (ret == 0)
  89334. + ret = -ERESTARTSYS;
  89335. + break;
  89336. + }
  89337. + schedule();
  89338. + }
  89339. +
  89340. + extract_buf(r, tmp);
  89341. + i = min_t(int, nbytes, EXTRACT_SIZE);
  89342. + if (copy_to_user(buf, tmp, i)) {
  89343. + ret = -EFAULT;
  89344. + break;
  89345. + }
  89346. +
  89347. + nbytes -= i;
  89348. + buf += i;
  89349. + ret += i;
  89350. + }
  89351. +
  89352. + /* Wipe data just returned from memory */
  89353. + memset(tmp, 0, sizeof(tmp));
  89354. +
  89355. + return ret;
  89356. +}
  89357. +
  89358. +/*
  89359. + * This function is the exported kernel interface. It returns some
  89360. + * number of good random numbers, suitable for seeding TCP sequence
  89361. + * numbers, etc.
  89362. + */
  89363. +void get_random_bytes(void *buf, int nbytes)
  89364. +{
  89365. + extract_entropy(&nonblocking_pool, buf, nbytes, 0, 0);
  89366. +}
  89367. +EXPORT_SYMBOL(get_random_bytes);
  89368. +
  89369. +/*
  89370. + * init_std_data - initialize pool with system data
  89371. + *
  89372. + * @r: pool to initialize
  89373. + *
  89374. + * This function clears the pool's entropy count and mixes some system
  89375. + * data into the pool to prepare it for use. The pool is not cleared
  89376. + * as that can only decrease the entropy in the pool.
  89377. + */
  89378. +static void init_std_data(struct entropy_store *r)
  89379. +{
  89380. + ktime_t now;
  89381. + unsigned long flags;
  89382. +
  89383. + spin_lock_irqsave(&r->lock, flags);
  89384. + r->entropy_count = 0;
  89385. + spin_unlock_irqrestore(&r->lock, flags);
  89386. +
  89387. + now = ktime_get_real();
  89388. + mix_pool_bytes(r, &now, sizeof(now));
  89389. + mix_pool_bytes(r, utsname(), sizeof(*(utsname())));
  89390. +}
  89391. +
  89392. +static int rand_initialize(void)
  89393. +{
  89394. + init_std_data(&input_pool);
  89395. + init_std_data(&blocking_pool);
  89396. + init_std_data(&nonblocking_pool);
  89397. + return 0;
  89398. +}
  89399. +module_init(rand_initialize);
  89400. +
  89401. +void rand_initialize_irq(int irq)
  89402. +{
  89403. + struct timer_rand_state *state;
  89404. +
  89405. + state = get_timer_rand_state(irq);
  89406. +
  89407. + if (state)
  89408. + return;
  89409. +
  89410. + /*
  89411. + * If kzalloc returns null, we just won't use that entropy
  89412. + * source.
  89413. + */
  89414. + state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL);
  89415. + if (state)
  89416. + set_timer_rand_state(irq, state);
  89417. +}
  89418. +
  89419. +#ifdef CONFIG_BLOCK
  89420. +void rand_initialize_disk(struct gendisk *disk)
  89421. +{
  89422. + struct timer_rand_state *state;
  89423. +
  89424. + /*
  89425. + * If kzalloc returns null, we just won't use that entropy
  89426. + * source.
  89427. + */
  89428. + state = kzalloc(sizeof(struct timer_rand_state), GFP_KERNEL);
  89429. + if (state)
  89430. + disk->random = state;
  89431. +}
  89432. +#endif
  89433. +
  89434. +static ssize_t
  89435. +random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
  89436. +{
  89437. + ssize_t n, retval = 0, count = 0;
  89438. +
  89439. + if (nbytes == 0)
  89440. + return 0;
  89441. +
  89442. + while (nbytes > 0) {
  89443. + n = nbytes;
  89444. + if (n > SEC_XFER_SIZE)
  89445. + n = SEC_XFER_SIZE;
  89446. +
  89447. + DEBUG_ENT("reading %d bits\n", n*8);
  89448. +
  89449. + n = extract_entropy_user(&blocking_pool, buf, n);
  89450. +
  89451. + DEBUG_ENT("read got %d bits (%d still needed)\n",
  89452. + n*8, (nbytes-n)*8);
  89453. +
  89454. + if (n == 0) {
  89455. + if (file->f_flags & O_NONBLOCK) {
  89456. + retval = -EAGAIN;
  89457. + break;
  89458. + }
  89459. +
  89460. + DEBUG_ENT("sleeping?\n");
  89461. +
  89462. + wait_event_interruptible(random_read_wait,
  89463. + input_pool.entropy_count >=
  89464. + random_read_wakeup_thresh);
  89465. +
  89466. + DEBUG_ENT("awake\n");
  89467. +
  89468. + if (signal_pending(current)) {
  89469. + retval = -ERESTARTSYS;
  89470. + break;
  89471. + }
  89472. +
  89473. + continue;
  89474. + }
  89475. +
  89476. + if (n < 0) {
  89477. + retval = n;
  89478. + break;
  89479. + }
  89480. + count += n;
  89481. + buf += n;
  89482. + nbytes -= n;
  89483. + break; /* This break makes the device work */
  89484. + /* like a named pipe */
  89485. + }
  89486. +
  89487. + return (count ? count : retval);
  89488. +}
  89489. +
  89490. +static ssize_t
  89491. +urandom_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
  89492. +{
  89493. + return extract_entropy_user(&nonblocking_pool, buf, nbytes);
  89494. +}
  89495. +
  89496. +static unsigned int
  89497. +random_poll(struct file *file, poll_table * wait)
  89498. +{
  89499. + unsigned int mask;
  89500. +
  89501. + poll_wait(file, &random_read_wait, wait);
  89502. + poll_wait(file, &random_write_wait, wait);
  89503. + mask = 0;
  89504. + if (input_pool.entropy_count >= random_read_wakeup_thresh)
  89505. + mask |= POLLIN | POLLRDNORM;
  89506. + if (input_pool.entropy_count < random_write_wakeup_thresh)
  89507. + mask |= POLLOUT | POLLWRNORM;
  89508. + return mask;
  89509. +}
  89510. +
  89511. +static int
  89512. +write_pool(struct entropy_store *r, const char __user *buffer, size_t count)
  89513. +{
  89514. + size_t bytes;
  89515. + __u32 buf[16];
  89516. + const char __user *p = buffer;
  89517. +
  89518. + while (count > 0) {
  89519. + bytes = min(count, sizeof(buf));
  89520. + if (copy_from_user(&buf, p, bytes))
  89521. + return -EFAULT;
  89522. +
  89523. + count -= bytes;
  89524. + p += bytes;
  89525. +
  89526. + mix_pool_bytes(r, buf, bytes);
  89527. + cond_resched();
  89528. + }
  89529. +
  89530. + return 0;
  89531. +}
  89532. +
  89533. +static ssize_t random_write(struct file *file, const char __user *buffer,
  89534. + size_t count, loff_t *ppos)
  89535. +{
  89536. + size_t ret;
  89537. +
  89538. + ret = write_pool(&blocking_pool, buffer, count);
  89539. + if (ret)
  89540. + return ret;
  89541. + ret = write_pool(&nonblocking_pool, buffer, count);
  89542. + if (ret)
  89543. + return ret;
  89544. +
  89545. + return (ssize_t)count;
  89546. +}
  89547. +
  89548. +static long random_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
  89549. +{
  89550. + int size, ent_count;
  89551. + int __user *p = (int __user *)arg;
  89552. + int retval;
  89553. +
  89554. + switch (cmd) {
  89555. + case RNDGETENTCNT:
  89556. + /* inherently racy, no point locking */
  89557. + if (put_user(input_pool.entropy_count, p))
  89558. + return -EFAULT;
  89559. + return 0;
  89560. + case RNDADDTOENTCNT:
  89561. + if (!capable(CAP_SYS_ADMIN))
  89562. + return -EPERM;
  89563. + if (get_user(ent_count, p))
  89564. + return -EFAULT;
  89565. + credit_entropy_bits(&input_pool, ent_count);
  89566. + return 0;
  89567. + case RNDADDENTROPY:
  89568. + if (!capable(CAP_SYS_ADMIN))
  89569. + return -EPERM;
  89570. + if (get_user(ent_count, p++))
  89571. + return -EFAULT;
  89572. + if (ent_count < 0)
  89573. + return -EINVAL;
  89574. + if (get_user(size, p++))
  89575. + return -EFAULT;
  89576. + retval = write_pool(&input_pool, (const char __user *)p,
  89577. + size);
  89578. + if (retval < 0)
  89579. + return retval;
  89580. + credit_entropy_bits(&input_pool, ent_count);
  89581. + return 0;
  89582. + case RNDZAPENTCNT:
  89583. + case RNDCLEARPOOL:
  89584. + /* Clear the entropy pool counters. */
  89585. + if (!capable(CAP_SYS_ADMIN))
  89586. + return -EPERM;
  89587. + rand_initialize();
  89588. + return 0;
  89589. + default:
  89590. + return -EINVAL;
  89591. + }
  89592. +}
  89593. +
  89594. +static int random_fasync(int fd, struct file *filp, int on)
  89595. +{
  89596. + return fasync_helper(fd, filp, on, &fasync);
  89597. +}
  89598. +
  89599. +const struct file_operations random_fops = {
  89600. + .read = random_read,
  89601. + .write = random_write,
  89602. + .poll = random_poll,
  89603. + .unlocked_ioctl = random_ioctl,
  89604. + .fasync = random_fasync,
  89605. + .llseek = noop_llseek,
  89606. +};
  89607. +
  89608. +const struct file_operations urandom_fops = {
  89609. + .read = urandom_read,
  89610. + .write = random_write,
  89611. + .unlocked_ioctl = random_ioctl,
  89612. + .fasync = random_fasync,
  89613. + .llseek = noop_llseek,
  89614. +};
  89615. +
  89616. +/***************************************************************
  89617. + * Random UUID interface
  89618. + *
  89619. + * Used here for a Boot ID, but can be useful for other kernel
  89620. + * drivers.
  89621. + ***************************************************************/
  89622. +
  89623. +/*
  89624. + * Generate random UUID
  89625. + */
  89626. +void generate_random_uuid(unsigned char uuid_out[16])
  89627. +{
  89628. + get_random_bytes(uuid_out, 16);
  89629. + /* Set UUID version to 4 --- truly random generation */
  89630. + uuid_out[6] = (uuid_out[6] & 0x0F) | 0x40;
  89631. + /* Set the UUID variant to DCE */
  89632. + uuid_out[8] = (uuid_out[8] & 0x3F) | 0x80;
  89633. +}
  89634. +EXPORT_SYMBOL(generate_random_uuid);
  89635. +
  89636. +/********************************************************************
  89637. + *
  89638. + * Sysctl interface
  89639. + *
  89640. + ********************************************************************/
  89641. +
  89642. +#ifdef CONFIG_SYSCTL
  89643. +
  89644. +#include <linux/sysctl.h>
  89645. +
  89646. +static int min_read_thresh = 8, min_write_thresh;
  89647. +static int max_read_thresh = INPUT_POOL_WORDS * 32;
  89648. +static int max_write_thresh = INPUT_POOL_WORDS * 32;
  89649. +static char sysctl_bootid[16];
  89650. +
  89651. +/*
  89652. + * These functions is used to return both the bootid UUID, and random
  89653. + * UUID. The difference is in whether table->data is NULL; if it is,
  89654. + * then a new UUID is generated and returned to the user.
  89655. + *
  89656. + * If the user accesses this via the proc interface, it will be returned
  89657. + * as an ASCII string in the standard UUID format. If accesses via the
  89658. + * sysctl system call, it is returned as 16 bytes of binary data.
  89659. + */
  89660. +static int proc_do_uuid(ctl_table *table, int write,
  89661. + void __user *buffer, size_t *lenp, loff_t *ppos)
  89662. +{
  89663. + ctl_table fake_table;
  89664. + unsigned char buf[64], tmp_uuid[16], *uuid;
  89665. +
  89666. + uuid = table->data;
  89667. + if (!uuid) {
  89668. + uuid = tmp_uuid;
  89669. + uuid[8] = 0;
  89670. + }
  89671. + if (uuid[8] == 0)
  89672. + generate_random_uuid(uuid);
  89673. +
  89674. + sprintf(buf, "%pU", uuid);
  89675. +
  89676. + fake_table.data = buf;
  89677. + fake_table.maxlen = sizeof(buf);
  89678. +
  89679. + return proc_dostring(&fake_table, write, buffer, lenp, ppos);
  89680. +}
  89681. +
  89682. +static int sysctl_poolsize = INPUT_POOL_WORDS * 32;
  89683. +ctl_table random_table[] = {
  89684. + {
  89685. + .procname = "poolsize",
  89686. + .data = &sysctl_poolsize,
  89687. + .maxlen = sizeof(int),
  89688. + .mode = 0444,
  89689. + .proc_handler = proc_dointvec,
  89690. + },
  89691. + {
  89692. + .procname = "entropy_avail",
  89693. + .maxlen = sizeof(int),
  89694. + .mode = 0444,
  89695. + .proc_handler = proc_dointvec,
  89696. + .data = &input_pool.entropy_count,
  89697. + },
  89698. + {
  89699. + .procname = "read_wakeup_threshold",
  89700. + .data = &random_read_wakeup_thresh,
  89701. + .maxlen = sizeof(int),
  89702. + .mode = 0644,
  89703. + .proc_handler = proc_dointvec_minmax,
  89704. + .extra1 = &min_read_thresh,
  89705. + .extra2 = &max_read_thresh,
  89706. + },
  89707. + {
  89708. + .procname = "write_wakeup_threshold",
  89709. + .data = &random_write_wakeup_thresh,
  89710. + .maxlen = sizeof(int),
  89711. + .mode = 0644,
  89712. + .proc_handler = proc_dointvec_minmax,
  89713. + .extra1 = &min_write_thresh,
  89714. + .extra2 = &max_write_thresh,
  89715. + },
  89716. + {
  89717. + .procname = "boot_id",
  89718. + .data = &sysctl_bootid,
  89719. + .maxlen = 16,
  89720. + .mode = 0444,
  89721. + .proc_handler = proc_do_uuid,
  89722. + },
  89723. + {
  89724. + .procname = "uuid",
  89725. + .maxlen = 16,
  89726. + .mode = 0444,
  89727. + .proc_handler = proc_do_uuid,
  89728. + },
  89729. + { }
  89730. +};
  89731. +#endif /* CONFIG_SYSCTL */
  89732. +
  89733. +/********************************************************************
  89734. + *
  89735. + * Random functions for networking
  89736. + *
  89737. + ********************************************************************/
  89738. +
  89739. +/*
  89740. + * TCP initial sequence number picking. This uses the random number
  89741. + * generator to pick an initial secret value. This value is hashed
  89742. + * along with the TCP endpoint information to provide a unique
  89743. + * starting point for each pair of TCP endpoints. This defeats
  89744. + * attacks which rely on guessing the initial TCP sequence number.
  89745. + * This algorithm was suggested by Steve Bellovin.
  89746. + *
  89747. + * Using a very strong hash was taking an appreciable amount of the total
  89748. + * TCP connection establishment time, so this is a weaker hash,
  89749. + * compensated for by changing the secret periodically.
  89750. + */
  89751. +
  89752. +/* F, G and H are basic MD4 functions: selection, majority, parity */
  89753. +#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
  89754. +#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
  89755. +#define H(x, y, z) ((x) ^ (y) ^ (z))
  89756. +
  89757. +/*
  89758. + * The generic round function. The application is so specific that
  89759. + * we don't bother protecting all the arguments with parens, as is generally
  89760. + * good macro practice, in favor of extra legibility.
  89761. + * Rotation is separate from addition to prevent recomputation
  89762. + */
  89763. +#define ROUND(f, a, b, c, d, x, s) \
  89764. + (a += f(b, c, d) + x, a = (a << s) | (a >> (32 - s)))
  89765. +#define K1 0
  89766. +#define K2 013240474631UL
  89767. +#define K3 015666365641UL
  89768. +
  89769. +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
  89770. +
  89771. +static __u32 twothirdsMD4Transform(__u32 const buf[4], __u32 const in[12])
  89772. +{
  89773. + __u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3];
  89774. +
  89775. + /* Round 1 */
  89776. + ROUND(F, a, b, c, d, in[ 0] + K1, 3);
  89777. + ROUND(F, d, a, b, c, in[ 1] + K1, 7);
  89778. + ROUND(F, c, d, a, b, in[ 2] + K1, 11);
  89779. + ROUND(F, b, c, d, a, in[ 3] + K1, 19);
  89780. + ROUND(F, a, b, c, d, in[ 4] + K1, 3);
  89781. + ROUND(F, d, a, b, c, in[ 5] + K1, 7);
  89782. + ROUND(F, c, d, a, b, in[ 6] + K1, 11);
  89783. + ROUND(F, b, c, d, a, in[ 7] + K1, 19);
  89784. + ROUND(F, a, b, c, d, in[ 8] + K1, 3);
  89785. + ROUND(F, d, a, b, c, in[ 9] + K1, 7);
  89786. + ROUND(F, c, d, a, b, in[10] + K1, 11);
  89787. + ROUND(F, b, c, d, a, in[11] + K1, 19);
  89788. +
  89789. + /* Round 2 */
  89790. + ROUND(G, a, b, c, d, in[ 1] + K2, 3);
  89791. + ROUND(G, d, a, b, c, in[ 3] + K2, 5);
  89792. + ROUND(G, c, d, a, b, in[ 5] + K2, 9);
  89793. + ROUND(G, b, c, d, a, in[ 7] + K2, 13);
  89794. + ROUND(G, a, b, c, d, in[ 9] + K2, 3);
  89795. + ROUND(G, d, a, b, c, in[11] + K2, 5);
  89796. + ROUND(G, c, d, a, b, in[ 0] + K2, 9);
  89797. + ROUND(G, b, c, d, a, in[ 2] + K2, 13);
  89798. + ROUND(G, a, b, c, d, in[ 4] + K2, 3);
  89799. + ROUND(G, d, a, b, c, in[ 6] + K2, 5);
  89800. + ROUND(G, c, d, a, b, in[ 8] + K2, 9);
  89801. + ROUND(G, b, c, d, a, in[10] + K2, 13);
  89802. +
  89803. + /* Round 3 */
  89804. + ROUND(H, a, b, c, d, in[ 3] + K3, 3);
  89805. + ROUND(H, d, a, b, c, in[ 7] + K3, 9);
  89806. + ROUND(H, c, d, a, b, in[11] + K3, 11);
  89807. + ROUND(H, b, c, d, a, in[ 2] + K3, 15);
  89808. + ROUND(H, a, b, c, d, in[ 6] + K3, 3);
  89809. + ROUND(H, d, a, b, c, in[10] + K3, 9);
  89810. + ROUND(H, c, d, a, b, in[ 1] + K3, 11);
  89811. + ROUND(H, b, c, d, a, in[ 5] + K3, 15);
  89812. + ROUND(H, a, b, c, d, in[ 9] + K3, 3);
  89813. + ROUND(H, d, a, b, c, in[ 0] + K3, 9);
  89814. + ROUND(H, c, d, a, b, in[ 4] + K3, 11);
  89815. + ROUND(H, b, c, d, a, in[ 8] + K3, 15);
  89816. +
  89817. + return buf[1] + b; /* "most hashed" word */
  89818. + /* Alternative: return sum of all words? */
  89819. +}
  89820. +#endif
  89821. +
  89822. +#undef ROUND
  89823. +#undef F
  89824. +#undef G
  89825. +#undef H
  89826. +#undef K1
  89827. +#undef K2
  89828. +#undef K3
  89829. +
  89830. +/* This should not be decreased so low that ISNs wrap too fast. */
  89831. +#define REKEY_INTERVAL (300 * HZ)
  89832. +/*
  89833. + * Bit layout of the tcp sequence numbers (before adding current time):
  89834. + * bit 24-31: increased after every key exchange
  89835. + * bit 0-23: hash(source,dest)
  89836. + *
  89837. + * The implementation is similar to the algorithm described
  89838. + * in the Appendix of RFC 1185, except that
  89839. + * - it uses a 1 MHz clock instead of a 250 kHz clock
  89840. + * - it performs a rekey every 5 minutes, which is equivalent
  89841. + * to a (source,dest) tulple dependent forward jump of the
  89842. + * clock by 0..2^(HASH_BITS+1)
  89843. + *
  89844. + * Thus the average ISN wraparound time is 68 minutes instead of
  89845. + * 4.55 hours.
  89846. + *
  89847. + * SMP cleanup and lock avoidance with poor man's RCU.
  89848. + * Manfred Spraul <manfred@colorfullife.com>
  89849. + *
  89850. + */
  89851. +#define COUNT_BITS 8
  89852. +#define COUNT_MASK ((1 << COUNT_BITS) - 1)
  89853. +#define HASH_BITS 24
  89854. +#define HASH_MASK ((1 << HASH_BITS) - 1)
  89855. +
  89856. +static struct keydata {
  89857. + __u32 count; /* already shifted to the final position */
  89858. + __u32 secret[12];
  89859. +} ____cacheline_aligned ip_keydata[2];
  89860. +
  89861. +static unsigned int ip_cnt;
  89862. +
  89863. +static void rekey_seq_generator(struct work_struct *work);
  89864. +
  89865. +static DECLARE_DELAYED_WORK(rekey_work, rekey_seq_generator);
  89866. +
  89867. +/*
  89868. + * Lock avoidance:
  89869. + * The ISN generation runs lockless - it's just a hash over random data.
  89870. + * State changes happen every 5 minutes when the random key is replaced.
  89871. + * Synchronization is performed by having two copies of the hash function
  89872. + * state and rekey_seq_generator always updates the inactive copy.
  89873. + * The copy is then activated by updating ip_cnt.
  89874. + * The implementation breaks down if someone blocks the thread
  89875. + * that processes SYN requests for more than 5 minutes. Should never
  89876. + * happen, and even if that happens only a not perfectly compliant
  89877. + * ISN is generated, nothing fatal.
  89878. + */
  89879. +static void rekey_seq_generator(struct work_struct *work)
  89880. +{
  89881. + struct keydata *keyptr = &ip_keydata[1 ^ (ip_cnt & 1)];
  89882. +
  89883. + get_random_bytes(keyptr->secret, sizeof(keyptr->secret));
  89884. + keyptr->count = (ip_cnt & COUNT_MASK) << HASH_BITS;
  89885. + smp_wmb();
  89886. + ip_cnt++;
  89887. + schedule_delayed_work(&rekey_work,
  89888. + round_jiffies_relative(REKEY_INTERVAL));
  89889. +}
  89890. +
  89891. +static inline struct keydata *get_keyptr(void)
  89892. +{
  89893. + struct keydata *keyptr = &ip_keydata[ip_cnt & 1];
  89894. +
  89895. + smp_rmb();
  89896. +
  89897. + return keyptr;
  89898. +}
  89899. +
  89900. +static __init int seqgen_init(void)
  89901. +{
  89902. + rekey_seq_generator(NULL);
  89903. + return 0;
  89904. +}
  89905. +late_initcall(seqgen_init);
  89906. +
  89907. +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
  89908. +__u32 secure_tcpv6_sequence_number(__be32 *saddr, __be32 *daddr,
  89909. + __be16 sport, __be16 dport)
  89910. +{
  89911. + __u32 seq;
  89912. + __u32 hash[12];
  89913. + struct keydata *keyptr = get_keyptr();
  89914. +
  89915. + /* The procedure is the same as for IPv4, but addresses are longer.
  89916. + * Thus we must use twothirdsMD4Transform.
  89917. + */
  89918. +
  89919. + memcpy(hash, saddr, 16);
  89920. + hash[4] = ((__force u16)sport << 16) + (__force u16)dport;
  89921. + memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7);
  89922. +
  89923. + seq = twothirdsMD4Transform((const __u32 *)daddr, hash) & HASH_MASK;
  89924. + seq += keyptr->count;
  89925. +
  89926. + seq += ktime_to_ns(ktime_get_real());
  89927. +
  89928. + return seq;
  89929. +}
  89930. +EXPORT_SYMBOL(secure_tcpv6_sequence_number);
  89931. +#endif
  89932. +
  89933. +/* The code below is shamelessly stolen from secure_tcp_sequence_number().
  89934. + * All blames to Andrey V. Savochkin <saw@msu.ru>.
  89935. + */
  89936. +__u32 secure_ip_id(__be32 daddr)
  89937. +{
  89938. + struct keydata *keyptr;
  89939. + __u32 hash[4];
  89940. +
  89941. + keyptr = get_keyptr();
  89942. +
  89943. + /*
  89944. + * Pick a unique starting offset for each IP destination.
  89945. + * The dest ip address is placed in the starting vector,
  89946. + * which is then hashed with random data.
  89947. + */
  89948. + hash[0] = (__force __u32)daddr;
  89949. + hash[1] = keyptr->secret[9];
  89950. + hash[2] = keyptr->secret[10];
  89951. + hash[3] = keyptr->secret[11];
  89952. +
  89953. + return half_md4_transform(hash, keyptr->secret);
  89954. +}
  89955. +
  89956. +#ifdef CONFIG_INET
  89957. +
  89958. +__u32 secure_tcp_sequence_number(__be32 saddr, __be32 daddr,
  89959. + __be16 sport, __be16 dport)
  89960. +{
  89961. + __u32 seq;
  89962. + __u32 hash[4];
  89963. + struct keydata *keyptr = get_keyptr();
  89964. +
  89965. + /*
  89966. + * Pick a unique starting offset for each TCP connection endpoints
  89967. + * (saddr, daddr, sport, dport).
  89968. + * Note that the words are placed into the starting vector, which is
  89969. + * then mixed with a partial MD4 over random data.
  89970. + */
  89971. + hash[0] = (__force u32)saddr;
  89972. + hash[1] = (__force u32)daddr;
  89973. + hash[2] = ((__force u16)sport << 16) + (__force u16)dport;
  89974. + hash[3] = keyptr->secret[11];
  89975. +
  89976. + seq = half_md4_transform(hash, keyptr->secret) & HASH_MASK;
  89977. + seq += keyptr->count;
  89978. + /*
  89979. + * As close as possible to RFC 793, which
  89980. + * suggests using a 250 kHz clock.
  89981. + * Further reading shows this assumes 2 Mb/s networks.
  89982. + * For 10 Mb/s Ethernet, a 1 MHz clock is appropriate.
  89983. + * For 10 Gb/s Ethernet, a 1 GHz clock should be ok, but
  89984. + * we also need to limit the resolution so that the u32 seq
  89985. + * overlaps less than one time per MSL (2 minutes).
  89986. + * Choosing a clock of 64 ns period is OK. (period of 274 s)
  89987. + */
  89988. + seq += ktime_to_ns(ktime_get_real()) >> 6;
  89989. +
  89990. + return seq;
  89991. +}
  89992. +
  89993. +/* Generate secure starting point for ephemeral IPV4 transport port search */
  89994. +u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
  89995. +{
  89996. + struct keydata *keyptr = get_keyptr();
  89997. + u32 hash[4];
  89998. +
  89999. + /*
  90000. + * Pick a unique starting offset for each ephemeral port search
  90001. + * (saddr, daddr, dport) and 48bits of random data.
  90002. + */
  90003. + hash[0] = (__force u32)saddr;
  90004. + hash[1] = (__force u32)daddr;
  90005. + hash[2] = (__force u32)dport ^ keyptr->secret[10];
  90006. + hash[3] = keyptr->secret[11];
  90007. +
  90008. + return half_md4_transform(hash, keyptr->secret);
  90009. +}
  90010. +EXPORT_SYMBOL_GPL(secure_ipv4_port_ephemeral);
  90011. +
  90012. +#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
  90013. +u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
  90014. + __be16 dport)
  90015. +{
  90016. + struct keydata *keyptr = get_keyptr();
  90017. + u32 hash[12];
  90018. +
  90019. + memcpy(hash, saddr, 16);
  90020. + hash[4] = (__force u32)dport;
  90021. + memcpy(&hash[5], keyptr->secret, sizeof(__u32) * 7);
  90022. +
  90023. + return twothirdsMD4Transform((const __u32 *)daddr, hash);
  90024. +}
  90025. +#endif
  90026. +
  90027. +#if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE)
  90028. +/* Similar to secure_tcp_sequence_number but generate a 48 bit value
  90029. + * bit's 32-47 increase every key exchange
  90030. + * 0-31 hash(source, dest)
  90031. + */
  90032. +u64 secure_dccp_sequence_number(__be32 saddr, __be32 daddr,
  90033. + __be16 sport, __be16 dport)
  90034. +{
  90035. + u64 seq;
  90036. + __u32 hash[4];
  90037. + struct keydata *keyptr = get_keyptr();
  90038. +
  90039. + hash[0] = (__force u32)saddr;
  90040. + hash[1] = (__force u32)daddr;
  90041. + hash[2] = ((__force u16)sport << 16) + (__force u16)dport;
  90042. + hash[3] = keyptr->secret[11];
  90043. +
  90044. + seq = half_md4_transform(hash, keyptr->secret);
  90045. + seq |= ((u64)keyptr->count) << (32 - HASH_BITS);
  90046. +
  90047. + seq += ktime_to_ns(ktime_get_real());
  90048. + seq &= (1ull << 48) - 1;
  90049. +
  90050. + return seq;
  90051. +}
  90052. +EXPORT_SYMBOL(secure_dccp_sequence_number);
  90053. +#endif
  90054. +
  90055. +#endif /* CONFIG_INET */
  90056. +
  90057. +
  90058. +/*
  90059. + * Get a random word for internal kernel use only. Similar to urandom but
  90060. + * with the goal of minimal entropy pool depletion. As a result, the random
  90061. + * value is not cryptographically secure but for several uses the cost of
  90062. + * depleting entropy is too high
  90063. + */
  90064. +DEFINE_PER_CPU(__u32 [4], get_random_int_hash);
  90065. +unsigned int get_random_int(void)
  90066. +{
  90067. + struct keydata *keyptr;
  90068. + __u32 *hash = get_cpu_var(get_random_int_hash);
  90069. + int ret;
  90070. +
  90071. + keyptr = get_keyptr();
  90072. + hash[0] += current->pid + jiffies + get_cycles();
  90073. +
  90074. + ret = half_md4_transform(hash, keyptr->secret);
  90075. + put_cpu_var(get_random_int_hash);
  90076. +
  90077. + return ret;
  90078. +}
  90079. +
  90080. +/*
  90081. + * randomize_range() returns a start address such that
  90082. + *
  90083. + * [...... <range> .....]
  90084. + * start end
  90085. + *
  90086. + * a <range> with size "len" starting at the return value is inside in the
  90087. + * area defined by [start, end], but is otherwise randomized.
  90088. + */
  90089. +unsigned long
  90090. +randomize_range(unsigned long start, unsigned long end, unsigned long len)
  90091. +{
  90092. + unsigned long range = end - len - start;
  90093. +
  90094. + if (end <= start + len)
  90095. + return 0;
  90096. + return PAGE_ALIGN(get_random_int() % range + start);
  90097. +}
  90098. diff -Nur linux-2.6.39.orig/fs/fcntl.c linux-2.6.39/fs/fcntl.c
  90099. --- linux-2.6.39.orig/fs/fcntl.c 2011-05-19 06:06:34.000000000 +0200
  90100. +++ linux-2.6.39/fs/fcntl.c 2011-08-01 14:38:19.000000000 +0200
  90101. @@ -142,6 +142,7 @@
  90102. }
  90103. return ret;
  90104. }
  90105. +EXPORT_SYMBOL(sys_dup);
  90106. #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME)
  90107. diff -Nur linux-2.6.39.orig/include/linux/miscdevice.h linux-2.6.39/include/linux/miscdevice.h
  90108. --- linux-2.6.39.orig/include/linux/miscdevice.h 2011-05-19 06:06:34.000000000 +0200
  90109. +++ linux-2.6.39/include/linux/miscdevice.h 2011-08-01 14:38:19.000000000 +0200
  90110. @@ -18,6 +18,7 @@
  90111. #define APOLLO_MOUSE_MINOR 7
  90112. #define PC110PAD_MINOR 9
  90113. /*#define ADB_MOUSE_MINOR 10 FIXME OBSOLETE */
  90114. +#define CRYPTODEV_MINOR 70 /* /dev/crypto */
  90115. #define WATCHDOG_MINOR 130 /* Watchdog timer */
  90116. #define TEMP_MINOR 131 /* Temperature Sensor */
  90117. #define RTC_MINOR 135
  90118. diff -Nur linux-2.6.39.orig/include/linux/random.h linux-2.6.39/include/linux/random.h
  90119. --- linux-2.6.39.orig/include/linux/random.h 2011-05-19 06:06:34.000000000 +0200
  90120. +++ linux-2.6.39/include/linux/random.h 2011-08-01 14:38:19.000000000 +0200
  90121. @@ -9,6 +9,7 @@
  90122. #include <linux/types.h>
  90123. #include <linux/ioctl.h>
  90124. +#include <linux/types.h> /* for __u32 in user space */
  90125. #include <linux/irqnr.h>
  90126. /* ioctl()'s for the random number generator */
  90127. @@ -34,6 +35,30 @@
  90128. /* Clear the entropy pool and associated counters. (Superuser only.) */
  90129. #define RNDCLEARPOOL _IO( 'R', 0x06 )
  90130. +#ifdef CONFIG_FIPS_RNG
  90131. +
  90132. +/* Size of seed value - equal to AES blocksize */
  90133. +#define AES_BLOCK_SIZE_BYTES 16
  90134. +#define SEED_SIZE_BYTES AES_BLOCK_SIZE_BYTES
  90135. +/* Size of AES key */
  90136. +#define KEY_SIZE_BYTES 16
  90137. +
  90138. +/* ioctl() structure used by FIPS 140-2 Tests */
  90139. +struct rand_fips_test {
  90140. + unsigned char key[KEY_SIZE_BYTES]; /* Input */
  90141. + unsigned char datetime[SEED_SIZE_BYTES]; /* Input */
  90142. + unsigned char seed[SEED_SIZE_BYTES]; /* Input */
  90143. + unsigned char result[SEED_SIZE_BYTES]; /* Output */
  90144. +};
  90145. +
  90146. +/* FIPS 140-2 RNG Variable Seed Test. (Superuser only.) */
  90147. +#define RNDFIPSVST _IOWR('R', 0x10, struct rand_fips_test)
  90148. +
  90149. +/* FIPS 140-2 RNG Monte Carlo Test. (Superuser only.) */
  90150. +#define RNDFIPSMCT _IOWR('R', 0x11, struct rand_fips_test)
  90151. +
  90152. +#endif /* #ifdef CONFIG_FIPS_RNG */
  90153. +
  90154. struct rand_pool_info {
  90155. int entropy_count;
  90156. int buf_size;
  90157. @@ -54,6 +79,10 @@
  90158. unsigned int value);
  90159. extern void add_interrupt_randomness(int irq);
  90160. +extern void random_input_words(__u32 *buf, size_t wordcount, int ent_count);
  90161. +extern int random_input_wait(void);
  90162. +#define HAS_RANDOM_INPUT_WAIT 1
  90163. +
  90164. extern void get_random_bytes(void *buf, int nbytes);
  90165. void generate_random_uuid(unsigned char uuid_out[16]);